blob: a3163360dfef2049775ef92d1505236acaaa0b97 [file] [log] [blame]
Craig Mautner27084302013-03-25 08:05:25 -07001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
Craig Mautner6170f732013-04-02 13:05:23 -070019import static android.Manifest.permission.START_ANY_ACTIVITY;
Craig Mautner29219d92013-04-16 20:19:12 -070020import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
21import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
Craig Mautner6170f732013-04-02 13:05:23 -070022import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Craig Mautner2420ead2013-04-01 17:13:20 -070023import static com.android.server.am.ActivityManagerService.localLOGV;
Craig Mautner23ac33b2013-04-01 16:26:35 -070024import static com.android.server.am.ActivityManagerService.DEBUG_CONFIGURATION;
Craig Mautnere7c58b62013-06-12 20:19:00 -070025import static com.android.server.am.ActivityManagerService.DEBUG_FOCUS;
Craig Mautner0eea92c2013-05-16 13:35:39 -070026import static com.android.server.am.ActivityManagerService.DEBUG_PAUSE;
Craig Mautner6170f732013-04-02 13:05:23 -070027import static com.android.server.am.ActivityManagerService.DEBUG_RESULTS;
Craig Mautner0eea92c2013-05-16 13:35:39 -070028import static com.android.server.am.ActivityManagerService.DEBUG_STACK;
Craig Mautner2420ead2013-04-01 17:13:20 -070029import static com.android.server.am.ActivityManagerService.DEBUG_SWITCH;
Craig Mautner8849a5e2013-04-02 16:41:03 -070030import static com.android.server.am.ActivityManagerService.DEBUG_TASKS;
31import static com.android.server.am.ActivityManagerService.DEBUG_USER_LEAVING;
Craig Mautner05d29032013-05-03 13:40:13 -070032import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
Craig Mautner8d341ef2013-03-26 09:03:27 -070033import static com.android.server.am.ActivityManagerService.TAG;
34
Craig Mautner2420ead2013-04-01 17:13:20 -070035import android.app.Activity;
Craig Mautner23ac33b2013-04-01 16:26:35 -070036import android.app.ActivityManager;
Craig Mautnerbdc748af2013-12-02 14:08:25 -080037import android.app.ActivityManager.StackInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070038import android.app.ActivityOptions;
39import android.app.AppGlobals;
Craig Mautner4a1cb222013-12-04 16:14:06 -080040import android.app.IActivityContainer;
41import android.app.IActivityContainerCallback;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070042import android.app.IActivityManager;
Craig Mautner23ac33b2013-04-01 16:26:35 -070043import android.app.IApplicationThread;
Craig Mautner20e72272013-04-01 13:45:53 -070044import android.app.IThumbnailReceiver;
Craig Mautner23ac33b2013-04-01 16:26:35 -070045import android.app.PendingIntent;
Craig Mautner20e72272013-04-01 13:45:53 -070046import android.app.ActivityManager.RunningTaskInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070047import android.app.IActivityManager.WaitResult;
Craig Mautner2420ead2013-04-01 17:13:20 -070048import android.app.ResultInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070049import android.content.ComponentName;
Craig Mautner2219a1b2013-03-25 09:44:30 -070050import android.content.Context;
Craig Mautner23ac33b2013-04-01 16:26:35 -070051import android.content.IIntentSender;
Craig Mautner2219a1b2013-03-25 09:44:30 -070052import android.content.Intent;
Craig Mautner23ac33b2013-04-01 16:26:35 -070053import android.content.IntentSender;
Craig Mautner2219a1b2013-03-25 09:44:30 -070054import android.content.pm.ActivityInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070055import android.content.pm.ApplicationInfo;
56import android.content.pm.PackageManager;
57import android.content.pm.ResolveInfo;
58import android.content.res.Configuration;
Craig Mautner4a1cb222013-12-04 16:14:06 -080059import android.graphics.Point;
60import android.hardware.display.DisplayManager;
61import android.hardware.display.DisplayManager.DisplayListener;
Craig Mautner4504de52013-12-20 09:06:56 -080062import android.hardware.display.DisplayManagerGlobal;
63import android.hardware.display.VirtualDisplay;
Jeff Brown38f96e52014-02-11 14:32:56 -080064import android.hardware.input.InputManager;
65import android.hardware.input.InputManagerInternal;
Craig Mautner23ac33b2013-04-01 16:26:35 -070066import android.os.Binder;
Craig Mautner8d341ef2013-03-26 09:03:27 -070067import android.os.Bundle;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -070068import android.os.Debug;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070069import android.os.Handler;
Craig Mautner23ac33b2013-04-01 16:26:35 -070070import android.os.IBinder;
Craig Mautner2219a1b2013-03-25 09:44:30 -070071import android.os.Looper;
Craig Mautner2420ead2013-04-01 17:13:20 -070072import android.os.Message;
Craig Mautner23ac33b2013-04-01 16:26:35 -070073import android.os.ParcelFileDescriptor;
Craig Mautner0eea92c2013-05-16 13:35:39 -070074import android.os.PowerManager;
Craig Mautner7ea5bd42013-07-05 15:27:08 -070075import android.os.Process;
Craig Mautner8d341ef2013-03-26 09:03:27 -070076import android.os.RemoteException;
Craig Mautner23ac33b2013-04-01 16:26:35 -070077import android.os.SystemClock;
Craig Mautner6170f732013-04-02 13:05:23 -070078import android.os.UserHandle;
Craig Mautner2420ead2013-04-01 17:13:20 -070079import android.util.EventLog;
Craig Mautner8d341ef2013-03-26 09:03:27 -070080import android.util.Slog;
Craig Mautner4a1cb222013-12-04 16:14:06 -080081import android.util.SparseArray;
Craig Mautner2219a1b2013-03-25 09:44:30 -070082
Craig Mautner4a1cb222013-12-04 16:14:06 -080083import android.util.SparseIntArray;
Craig Mautnerbdc748af2013-12-02 14:08:25 -080084import android.view.Display;
Craig Mautner4a1cb222013-12-04 16:14:06 -080085import android.view.DisplayInfo;
Jeff Brown38f96e52014-02-11 14:32:56 -080086import android.view.InputEvent;
Craig Mautner4504de52013-12-20 09:06:56 -080087import android.view.Surface;
Craig Mautner23ac33b2013-04-01 16:26:35 -070088import com.android.internal.app.HeavyWeightSwitcherActivity;
Dianne Hackborncbfd23e2013-06-11 14:26:53 -070089import com.android.internal.os.TransferPipe;
Jeff Brown38f96e52014-02-11 14:32:56 -080090import com.android.server.LocalServices;
Craig Mautner6170f732013-04-02 13:05:23 -070091import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
Craig Mautner2420ead2013-04-01 17:13:20 -070092import com.android.server.am.ActivityStack.ActivityState;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070093import com.android.server.wm.WindowManagerService;
Craig Mautner23ac33b2013-04-01 16:26:35 -070094
Craig Mautner8d341ef2013-03-26 09:03:27 -070095import java.io.FileDescriptor;
96import java.io.IOException;
Craig Mautner27084302013-03-25 08:05:25 -070097import java.io.PrintWriter;
Craig Mautner2219a1b2013-03-25 09:44:30 -070098import java.util.ArrayList;
Craig Mautner8d341ef2013-03-26 09:03:27 -070099import java.util.List;
Craig Mautner27084302013-03-25 08:05:25 -0700100
Craig Mautner4a1cb222013-12-04 16:14:06 -0800101public final class ActivityStackSupervisor implements DisplayListener {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700102 static final boolean DEBUG = ActivityManagerService.DEBUG || false;
103 static final boolean DEBUG_ADD_REMOVE = DEBUG || false;
104 static final boolean DEBUG_APP = DEBUG || false;
105 static final boolean DEBUG_SAVED_STATE = DEBUG || false;
Craig Mautnera7f2bd42013-10-15 16:13:50 -0700106 static final boolean DEBUG_STATES = DEBUG || false;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -0700107 static final boolean DEBUG_IDLE = DEBUG || false;
Craig Mautner2420ead2013-04-01 17:13:20 -0700108
Craig Mautner2219a1b2013-03-25 09:44:30 -0700109 public static final int HOME_STACK_ID = 0;
Craig Mautner27084302013-03-25 08:05:25 -0700110
Craig Mautnerf3333272013-04-22 10:55:53 -0700111 /** How long we wait until giving up on the last activity telling us it is idle. */
112 static final int IDLE_TIMEOUT = 10*1000;
113
Craig Mautner0eea92c2013-05-16 13:35:39 -0700114 /** How long we can hold the sleep wake lock before giving up. */
115 static final int SLEEP_TIMEOUT = 5*1000;
116
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700117 // How long we can hold the launch wake lock before giving up.
118 static final int LAUNCH_TIMEOUT = 10*1000;
119
Craig Mautner05d29032013-05-03 13:40:13 -0700120 static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG;
121 static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1;
122 static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2;
Craig Mautner0eea92c2013-05-16 13:35:39 -0700123 static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3;
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700124 static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800125 static final int HANDLE_DISPLAY_ADDED = FIRST_SUPERVISOR_STACK_MSG + 5;
126 static final int HANDLE_DISPLAY_CHANGED = FIRST_SUPERVISOR_STACK_MSG + 6;
127 static final int HANDLE_DISPLAY_REMOVED = FIRST_SUPERVISOR_STACK_MSG + 7;
Craig Mautnere3a00d72014-04-16 08:31:19 -0700128 static final int CONTAINER_CALLBACK_VISIBILITY = FIRST_SUPERVISOR_STACK_MSG + 8;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800129
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 Mautnerf4c909b2014-04-17 18:39:38 -0700226 SparseArray<ActivityContainer> mActivityContainers = new SparseArray<ActivityContainer>();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800227
228 /** Mapping from displayId to display current state */
Craig Mautnerf4c909b2014-04-17 18:39:38 -0700229 private final SparseArray<ActivityDisplay> mActivityDisplays =
230 new SparseArray<ActivityDisplay>();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800231
Jeff Brown38f96e52014-02-11 14:32:56 -0800232 InputManagerInternal mInputManagerInternal;
233
Craig Mautner4a1cb222013-12-04 16:14:06 -0800234 public ActivityStackSupervisor(ActivityManagerService service) {
Craig Mautner27084302013-03-25 08:05:25 -0700235 mService = service;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800236 PowerManager pm = (PowerManager)mService.mContext.getSystemService(Context.POWER_SERVICE);
Craig Mautner0eea92c2013-05-16 13:35:39 -0700237 mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
Craig Mautner4a1cb222013-12-04 16:14:06 -0800238 mHandler = new ActivityStackSupervisorHandler(mService.mHandler.getLooper());
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700239 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
240 throw new IllegalStateException("Calling must be system uid");
241 }
242 mLaunchingActivity =
243 pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
244 mLaunchingActivity.setReferenceCounted(false);
Craig Mautner2219a1b2013-03-25 09:44:30 -0700245 }
246
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700247 void setWindowManager(WindowManagerService wm) {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800248 synchronized (mService) {
249 mWindowManager = wm;
250
251 mDisplayManager =
252 (DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE);
253 mDisplayManager.registerDisplayListener(this, null);
254
255 Display[] displays = mDisplayManager.getDisplays();
256 for (int displayNdx = displays.length - 1; displayNdx >= 0; --displayNdx) {
257 final int displayId = displays[displayNdx].getDisplayId();
Craig Mautnere0a38842013-12-16 16:14:02 -0800258 ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
259 mActivityDisplays.put(displayId, activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -0800260 }
261
Craig Mautnerf4c909b2014-04-17 18:39:38 -0700262 createStackOnDisplay(HOME_STACK_ID, Display.DEFAULT_DISPLAY);
Craig Mautner4a1cb222013-12-04 16:14:06 -0800263 mHomeStack = mFocusedStack = mLastFocusedStack = getStack(HOME_STACK_ID);
Jeff Brown38f96e52014-02-11 14:32:56 -0800264
265 mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
Craig Mautner4a1cb222013-12-04 16:14:06 -0800266 }
Craig Mautner27084302013-03-25 08:05:25 -0700267 }
268
269 void dismissKeyguard() {
Craig Mautner5314a402013-09-26 12:40:16 -0700270 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen("");
Craig Mautner27084302013-03-25 08:05:25 -0700271 if (mDismissKeyguardOnNextActivity) {
272 mDismissKeyguardOnNextActivity = false;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700273 mWindowManager.dismissKeyguard();
Craig Mautner27084302013-03-25 08:05:25 -0700274 }
275 }
276
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700277 ActivityStack getFocusedStack() {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800278 return mFocusedStack;
Craig Mautner20e72272013-04-01 13:45:53 -0700279 }
280
Craig Mautnerde4ef022013-04-07 19:01:33 -0700281 ActivityStack getLastStack() {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800282 return mLastFocusedStack;
Craig Mautner2219a1b2013-03-25 09:44:30 -0700283 }
284
Craig Mautner4a1cb222013-12-04 16:14:06 -0800285 // TODO: Split into two methods isFrontStack for any visible stack and isFrontmostStack for the
286 // top of all visible stacks.
Craig Mautnerde4ef022013-04-07 19:01:33 -0700287 boolean isFrontStack(ActivityStack stack) {
Craig Mautnerdf88d732014-01-27 09:21:32 -0800288 final ActivityRecord parent = stack.mActivityContainer.mParentActivity;
289 if (parent != null) {
290 stack = parent.task.stack;
291 }
Craig Mautnere0a38842013-12-16 16:14:02 -0800292 ArrayList<ActivityStack> stacks = stack.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800293 if (stacks != null && !stacks.isEmpty()) {
294 return stack == stacks.get(stacks.size() - 1);
295 }
296 return false;
Craig Mautner20e72272013-04-01 13:45:53 -0700297 }
298
Craig Mautnerde4ef022013-04-07 19:01:33 -0700299 void moveHomeStack(boolean toFront) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800300 ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800301 int topNdx = stacks.size() - 1;
302 if (topNdx <= 0) {
303 return;
304 }
305 ActivityStack topStack = stacks.get(topNdx);
306 final boolean homeInFront = topStack == mHomeStack;
307 if (homeInFront != toFront) {
308 mLastFocusedStack = topStack;
309 stacks.remove(mHomeStack);
310 stacks.add(toFront ? topNdx : 0, mHomeStack);
311 mFocusedStack = stacks.get(topNdx);
312 if (DEBUG_STACK) Slog.d(TAG, "moveHomeTask: topStack old=" + topStack + " new="
313 + mFocusedStack);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700314 }
315 }
316
Craig Mautner8e569572013-10-11 17:36:59 -0700317 void moveHomeToTop() {
Craig Mautner69ada552013-04-18 13:51:51 -0700318 moveHomeStack(true);
Craig Mautner8e569572013-10-11 17:36:59 -0700319 mHomeStack.moveHomeTaskToTop();
320 }
321
322 boolean resumeHomeActivity(ActivityRecord prev) {
323 moveHomeToTop();
Craig Mautner69ada552013-04-18 13:51:51 -0700324 if (prev != null) {
Craig Mautnerae7ecab2013-09-18 11:48:14 -0700325 prev.task.mOnTopOfHome = false;
Craig Mautner69ada552013-04-18 13:51:51 -0700326 }
Craig Mautnera8a90e02013-06-28 15:24:50 -0700327 ActivityRecord r = mHomeStack.topRunningActivityLocked(null);
Craig Mautner760b2312013-10-11 11:57:07 -0700328 if (r != null && r.isHomeActivity()) {
Craig Mautnera8a90e02013-06-28 15:24:50 -0700329 mService.setFocusedActivityLocked(r);
Craig Mautner05d29032013-05-03 13:40:13 -0700330 return resumeTopActivitiesLocked(mHomeStack, prev, null);
Craig Mautner69ada552013-04-18 13:51:51 -0700331 }
332 return mService.startHomeActivityLocked(mCurrentUser);
333 }
334
Craig Mautner27084302013-03-25 08:05:25 -0700335 void setDismissKeyguard(boolean dismiss) {
Craig Mautner5314a402013-09-26 12:40:16 -0700336 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen(" dismiss=" + dismiss);
Craig Mautner27084302013-03-25 08:05:25 -0700337 mDismissKeyguardOnNextActivity = dismiss;
338 }
339
Craig Mautner8d341ef2013-03-26 09:03:27 -0700340 TaskRecord anyTaskForIdLocked(int id) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800341 int numDisplays = mActivityDisplays.size();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800342 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800343 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800344 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
345 ActivityStack stack = stacks.get(stackNdx);
346 TaskRecord task = stack.taskForIdLocked(id);
347 if (task != null) {
348 return task;
349 }
Craig Mautner8d341ef2013-03-26 09:03:27 -0700350 }
351 }
352 return null;
353 }
354
Craig Mautner6170f732013-04-02 13:05:23 -0700355 ActivityRecord isInAnyStackLocked(IBinder token) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800356 int numDisplays = mActivityDisplays.size();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800357 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800358 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800359 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
360 final ActivityRecord r = stacks.get(stackNdx).isInStackLocked(token);
361 if (r != null) {
362 return r;
363 }
Craig Mautner6170f732013-04-02 13:05:23 -0700364 }
365 }
366 return null;
367 }
368
Craig Mautner8d341ef2013-03-26 09:03:27 -0700369 int getNextTaskId() {
370 do {
371 mCurTaskId++;
372 if (mCurTaskId <= 0) {
373 mCurTaskId = 1;
374 }
375 } while (anyTaskForIdLocked(mCurTaskId) != null);
376 return mCurTaskId;
377 }
378
Craig Mautnerde4ef022013-04-07 19:01:33 -0700379 ActivityRecord resumedAppLocked() {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700380 ActivityStack stack = getFocusedStack();
381 if (stack == null) {
382 return null;
383 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700384 ActivityRecord resumedActivity = stack.mResumedActivity;
385 if (resumedActivity == null || resumedActivity.app == null) {
386 resumedActivity = stack.mPausingActivity;
387 if (resumedActivity == null || resumedActivity.app == null) {
388 resumedActivity = stack.topRunningActivityLocked(null);
389 }
390 }
391 return resumedActivity;
392 }
393
Mike Lockwoode63f6f72013-11-15 11:01:47 -0800394 boolean attachApplicationLocked(ProcessRecord app) throws Exception {
Craig Mautner20e72272013-04-01 13:45:53 -0700395 final String processName = app.processName;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800396 boolean didSomething = false;
Craig Mautnere0a38842013-12-16 16:14:02 -0800397 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
398 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800399 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
400 final ActivityStack stack = stacks.get(stackNdx);
401 if (!isFrontStack(stack)) {
402 continue;
403 }
404 ActivityRecord hr = stack.topRunningActivityLocked(null);
405 if (hr != null) {
406 if (hr.app == null && app.uid == hr.info.applicationInfo.uid
407 && processName.equals(hr.processName)) {
408 try {
409 if (realStartActivityLocked(hr, app, true, true)) {
410 didSomething = true;
411 }
412 } catch (Exception e) {
413 Slog.w(TAG, "Exception in new application when starting activity "
414 + hr.intent.getComponent().flattenToShortString(), e);
415 throw e;
Craig Mautner20e72272013-04-01 13:45:53 -0700416 }
Craig Mautner20e72272013-04-01 13:45:53 -0700417 }
Craig Mautner20e72272013-04-01 13:45:53 -0700418 }
419 }
420 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -0700421 if (!didSomething) {
422 ensureActivitiesVisibleLocked(null, 0);
423 }
Craig Mautner20e72272013-04-01 13:45:53 -0700424 return didSomething;
425 }
426
427 boolean allResumedActivitiesIdle() {
Craig Mautnere0a38842013-12-16 16:14:02 -0800428 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
429 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800430 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
431 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautner34b73df2014-01-12 21:11:08 -0800432 if (!isFrontStack(stack) || stack.numActivities() == 0) {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800433 continue;
434 }
435 final ActivityRecord resumedActivity = stack.mResumedActivity;
436 if (resumedActivity == null || !resumedActivity.idle) {
Craig Mautner34b73df2014-01-12 21:11:08 -0800437 if (DEBUG_STATES) Slog.d(TAG, "allResumedActivitiesIdle: stack="
438 + stack.mStackId + " " + resumedActivity + " not idle");
Craig Mautner4a1cb222013-12-04 16:14:06 -0800439 return false;
440 }
Craig Mautner20e72272013-04-01 13:45:53 -0700441 }
442 }
443 return true;
444 }
445
Craig Mautnerde4ef022013-04-07 19:01:33 -0700446 boolean allResumedActivitiesComplete() {
Craig Mautnere0a38842013-12-16 16:14:02 -0800447 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
448 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800449 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
450 final ActivityStack stack = stacks.get(stackNdx);
451 if (isFrontStack(stack)) {
452 final ActivityRecord r = stack.mResumedActivity;
453 if (r != null && r.state != ActivityState.RESUMED) {
454 return false;
455 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700456 }
457 }
458 }
459 // TODO: Not sure if this should check if all Paused are complete too.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800460 if (DEBUG_STACK) Slog.d(TAG,
461 "allResumedActivitiesComplete: mLastFocusedStack changing from=" +
462 mLastFocusedStack + " to=" + mFocusedStack);
463 mLastFocusedStack = mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700464 return true;
465 }
466
467 boolean allResumedActivitiesVisible() {
Craig Mautnere0a38842013-12-16 16:14:02 -0800468 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
469 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800470 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
471 final ActivityStack stack = stacks.get(stackNdx);
472 final ActivityRecord r = stack.mResumedActivity;
473 if (r != null && (!r.nowVisible || r.waitingVisible)) {
474 return false;
475 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700476 }
477 }
478 return true;
479 }
480
Craig Mautner2acc3892013-09-23 10:28:14 -0700481 /**
482 * Pause all activities in either all of the stacks or just the back stacks.
483 * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving().
Craig Mautner2acc3892013-09-23 10:28:14 -0700484 * @return true if any activity was paused as a result of this call.
485 */
Craig Mautner5314a402013-09-26 12:40:16 -0700486 boolean pauseBackStacks(boolean userLeaving) {
Craig Mautnercf910b02013-04-23 11:23:27 -0700487 boolean someActivityPaused = false;
Craig Mautnere0a38842013-12-16 16:14:02 -0800488 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
489 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800490 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
491 final ActivityStack stack = stacks.get(stackNdx);
492 if (!isFrontStack(stack) && stack.mResumedActivity != null) {
493 if (DEBUG_STATES) Slog.d(TAG, "pauseBackStacks: stack=" + stack +
494 " mResumedActivity=" + stack.mResumedActivity);
495 stack.startPausingLocked(userLeaving, false);
496 someActivityPaused = true;
497 }
Craig Mautnercf910b02013-04-23 11:23:27 -0700498 }
499 }
500 return someActivityPaused;
501 }
502
Craig Mautnerde4ef022013-04-07 19:01:33 -0700503 boolean allPausedActivitiesComplete() {
Craig Mautnerac6f8432013-07-17 13:24:59 -0700504 boolean pausing = true;
Craig Mautnere0a38842013-12-16 16:14:02 -0800505 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
506 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800507 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
508 final ActivityStack stack = stacks.get(stackNdx);
509 final ActivityRecord r = stack.mPausingActivity;
510 if (r != null && r.state != ActivityState.PAUSED
511 && r.state != ActivityState.STOPPED
512 && r.state != ActivityState.STOPPING) {
513 if (DEBUG_STATES) {
514 Slog.d(TAG, "allPausedActivitiesComplete: r=" + r + " state=" + r.state);
515 pausing = false;
516 } else {
517 return false;
518 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700519 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700520 }
521 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700522 return pausing;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700523 }
524
Craig Mautnerdf88d732014-01-27 09:21:32 -0800525 void pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping) {
526 // TODO: Put all stacks in supervisor and iterate through them instead.
527 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
528 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
529 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
530 final ActivityStack stack = stacks.get(stackNdx);
531 if (stack.mResumedActivity != null &&
532 stack.mActivityContainer.mParentActivity == parent) {
533 stack.startPausingLocked(userLeaving, uiSleeping);
534 }
535 }
536 }
537 }
538
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700539 void reportActivityVisibleLocked(ActivityRecord r) {
Craig Mautner858d8a62013-04-23 17:08:34 -0700540 for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700541 WaitResult w = mWaitingActivityVisible.get(i);
542 w.timeout = false;
543 if (r != null) {
544 w.who = new ComponentName(r.info.packageName, r.info.name);
545 }
546 w.totalTime = SystemClock.uptimeMillis() - w.thisTime;
547 w.thisTime = w.totalTime;
548 }
549 mService.notifyAll();
550 dismissKeyguard();
551 }
552
553 void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r,
554 long thisTime, long totalTime) {
555 for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
Craig Mautnerc64f73e2013-04-24 16:44:56 -0700556 WaitResult w = mWaitingActivityLaunched.remove(i);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700557 w.timeout = timeout;
558 if (r != null) {
559 w.who = new ComponentName(r.info.packageName, r.info.name);
560 }
561 w.thisTime = thisTime;
562 w.totalTime = totalTime;
563 }
564 mService.notifyAll();
565 }
566
Craig Mautner29219d92013-04-16 20:19:12 -0700567 ActivityRecord topRunningActivityLocked() {
Craig Mautner1602ec22013-05-12 10:24:27 -0700568 final ActivityStack focusedStack = getFocusedStack();
569 ActivityRecord r = focusedStack.topRunningActivityLocked(null);
570 if (r != null) {
571 return r;
Craig Mautner29219d92013-04-16 20:19:12 -0700572 }
Craig Mautner1602ec22013-05-12 10:24:27 -0700573
Craig Mautner4a1cb222013-12-04 16:14:06 -0800574 // Return to the home stack.
Craig Mautnere0a38842013-12-16 16:14:02 -0800575 final ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800576 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
577 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautnerac6f8432013-07-17 13:24:59 -0700578 if (stack != focusedStack && isFrontStack(stack)) {
Craig Mautner29219d92013-04-16 20:19:12 -0700579 r = stack.topRunningActivityLocked(null);
580 if (r != null) {
581 return r;
582 }
583 }
584 }
585 return null;
586 }
587
Craig Mautner20e72272013-04-01 13:45:53 -0700588 ActivityRecord getTasksLocked(int maxNum, IThumbnailReceiver receiver,
589 PendingThumbnailsRecord pending, List<RunningTaskInfo> list) {
590 ActivityRecord r = null;
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700591
592 // Gather all of the running tasks for each stack into runningTaskLists.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800593 ArrayList<ArrayList<RunningTaskInfo>> runningTaskLists =
594 new ArrayList<ArrayList<RunningTaskInfo>>();
Craig Mautnere0a38842013-12-16 16:14:02 -0800595 final int numDisplays = mActivityDisplays.size();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800596 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800597 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800598 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
599 final ActivityStack stack = stacks.get(stackNdx);
600 ArrayList<RunningTaskInfo> stackTaskList = new ArrayList<RunningTaskInfo>();
601 runningTaskLists.add(stackTaskList);
602 final ActivityRecord ar = stack.getTasksLocked(receiver, pending, stackTaskList);
603 if (r == null && isFrontStack(stack)) {
604 r = ar;
605 }
Craig Mautner20e72272013-04-01 13:45:53 -0700606 }
607 }
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700608
609 // The lists are already sorted from most recent to oldest. Just pull the most recent off
610 // each list and add it to list. Stop when all lists are empty or maxNum reached.
611 while (maxNum > 0) {
612 long mostRecentActiveTime = Long.MIN_VALUE;
613 ArrayList<RunningTaskInfo> selectedStackList = null;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800614 final int numTaskLists = runningTaskLists.size();
615 for (int stackNdx = 0; stackNdx < numTaskLists; ++stackNdx) {
616 ArrayList<RunningTaskInfo> stackTaskList = runningTaskLists.get(stackNdx);
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700617 if (!stackTaskList.isEmpty()) {
618 final long lastActiveTime = stackTaskList.get(0).lastActiveTime;
619 if (lastActiveTime > mostRecentActiveTime) {
620 mostRecentActiveTime = lastActiveTime;
621 selectedStackList = stackTaskList;
622 }
623 }
624 }
625 if (selectedStackList != null) {
626 list.add(selectedStackList.remove(0));
627 --maxNum;
628 } else {
629 break;
630 }
631 }
632
Craig Mautner20e72272013-04-01 13:45:53 -0700633 return r;
634 }
635
Craig Mautner23ac33b2013-04-01 16:26:35 -0700636 ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
637 String profileFile, ParcelFileDescriptor profileFd, int userId) {
638 // Collect information about the target of the Intent.
639 ActivityInfo aInfo;
640 try {
641 ResolveInfo rInfo =
642 AppGlobals.getPackageManager().resolveIntent(
643 intent, resolvedType,
644 PackageManager.MATCH_DEFAULT_ONLY
645 | ActivityManagerService.STOCK_PM_FLAGS, userId);
646 aInfo = rInfo != null ? rInfo.activityInfo : null;
647 } catch (RemoteException e) {
648 aInfo = null;
649 }
650
651 if (aInfo != null) {
652 // Store the found target back into the intent, because now that
653 // we have it we never want to do this again. For example, if the
654 // user navigates back to this point in the history, we should
655 // always restart the exact same activity.
656 intent.setComponent(new ComponentName(
657 aInfo.applicationInfo.packageName, aInfo.name));
658
659 // Don't debug things in the system process
660 if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) {
661 if (!aInfo.processName.equals("system")) {
662 mService.setDebugApp(aInfo.processName, true, false);
663 }
664 }
665
666 if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) {
667 if (!aInfo.processName.equals("system")) {
668 mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName);
669 }
670 }
671
672 if (profileFile != null) {
673 if (!aInfo.processName.equals("system")) {
674 mService.setProfileApp(aInfo.applicationInfo, aInfo.processName,
675 profileFile, profileFd,
676 (startFlags&ActivityManager.START_FLAG_AUTO_STOP_PROFILER) != 0);
677 }
678 }
679 }
680 return aInfo;
681 }
682
Craig Mautner2219a1b2013-03-25 09:44:30 -0700683 void startHomeActivity(Intent intent, ActivityInfo aInfo) {
Craig Mautner8e569572013-10-11 17:36:59 -0700684 moveHomeToTop();
Craig Mautner6170f732013-04-02 13:05:23 -0700685 startActivityLocked(null, intent, null, aInfo, null, null, 0, 0, 0, null, 0,
Craig Mautnere0a38842013-12-16 16:14:02 -0800686 null, false, null, null);
Craig Mautner8d341ef2013-03-26 09:03:27 -0700687 }
688
Craig Mautner23ac33b2013-04-01 16:26:35 -0700689 final int startActivityMayWait(IApplicationThread caller, int callingUid,
690 String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
691 String resultWho, int requestCode, int startFlags, String profileFile,
692 ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config,
Craig Mautnere0a38842013-12-16 16:14:02 -0800693 Bundle options, int userId, IActivityContainer iContainer) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700694 // Refuse possible leaked file descriptors
695 if (intent != null && intent.hasFileDescriptors()) {
696 throw new IllegalArgumentException("File descriptors passed in Intent");
697 }
698 boolean componentSpecified = intent.getComponent() != null;
699
700 // Don't modify the client's object!
701 intent = new Intent(intent);
702
703 // Collect information about the target of the Intent.
704 ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
705 profileFile, profileFd, userId);
706
Craig Mautnere0a38842013-12-16 16:14:02 -0800707 ActivityContainer container = (ActivityContainer)iContainer;
Craig Mautner23ac33b2013-04-01 16:26:35 -0700708 synchronized (mService) {
709 int callingPid;
710 if (callingUid >= 0) {
711 callingPid = -1;
712 } else if (caller == null) {
713 callingPid = Binder.getCallingPid();
714 callingUid = Binder.getCallingUid();
715 } else {
716 callingPid = callingUid = -1;
717 }
718
Craig Mautnere0a38842013-12-16 16:14:02 -0800719 final ActivityStack stack;
720 if (container == null || container.mStack.isOnHomeDisplay()) {
721 stack = getFocusedStack();
722 } else {
723 stack = container.mStack;
724 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700725 stack.mConfigWillChange = config != null
Craig Mautner23ac33b2013-04-01 16:26:35 -0700726 && mService.mConfiguration.diff(config) != 0;
727 if (DEBUG_CONFIGURATION) Slog.v(TAG,
Craig Mautnerde4ef022013-04-07 19:01:33 -0700728 "Starting activity when config will change = " + stack.mConfigWillChange);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700729
730 final long origId = Binder.clearCallingIdentity();
731
732 if (aInfo != null &&
733 (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
734 // This may be a heavy-weight process! Check to see if we already
735 // have another, different heavy-weight process running.
736 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
737 if (mService.mHeavyWeightProcess != null &&
738 (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid ||
739 !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700740 int realCallingUid = callingUid;
741 if (caller != null) {
742 ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
743 if (callerApp != null) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700744 realCallingUid = callerApp.info.uid;
745 } else {
746 Slog.w(TAG, "Unable to find app for caller " + caller
Craig Mautner76ea2242013-05-15 11:40:05 -0700747 + " (pid=" + callingPid + ") when starting: "
Craig Mautner23ac33b2013-04-01 16:26:35 -0700748 + intent.toString());
749 ActivityOptions.abort(options);
750 return ActivityManager.START_PERMISSION_DENIED;
751 }
752 }
753
754 IIntentSender target = mService.getIntentSenderLocked(
755 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
756 realCallingUid, userId, null, null, 0, new Intent[] { intent },
757 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
758 | PendingIntent.FLAG_ONE_SHOT, null);
759
760 Intent newIntent = new Intent();
761 if (requestCode >= 0) {
762 // Caller is requesting a result.
763 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
764 }
765 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
766 new IntentSender(target));
767 if (mService.mHeavyWeightProcess.activities.size() > 0) {
768 ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0);
769 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
770 hist.packageName);
771 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
772 hist.task.taskId);
773 }
774 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
775 aInfo.packageName);
776 newIntent.setFlags(intent.getFlags());
777 newIntent.setClassName("android",
778 HeavyWeightSwitcherActivity.class.getName());
779 intent = newIntent;
780 resolvedType = null;
781 caller = null;
782 callingUid = Binder.getCallingUid();
783 callingPid = Binder.getCallingPid();
784 componentSpecified = true;
785 try {
786 ResolveInfo rInfo =
787 AppGlobals.getPackageManager().resolveIntent(
788 intent, null,
789 PackageManager.MATCH_DEFAULT_ONLY
790 | ActivityManagerService.STOCK_PM_FLAGS, userId);
791 aInfo = rInfo != null ? rInfo.activityInfo : null;
792 aInfo = mService.getActivityInfoForUser(aInfo, userId);
793 } catch (RemoteException e) {
794 aInfo = null;
795 }
796 }
797 }
798 }
799
Craig Mautnere0a38842013-12-16 16:14:02 -0800800 int res = startActivityLocked(caller, intent, resolvedType, aInfo, resultTo, resultWho,
801 requestCode, callingPid, callingUid, callingPackage, startFlags, options,
802 componentSpecified, null, container);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700803
Craig Mautnerde4ef022013-04-07 19:01:33 -0700804 if (stack.mConfigWillChange) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700805 // If the caller also wants to switch to a new configuration,
806 // do so now. This allows a clean switch, as we are waiting
807 // for the current activity to pause (so we will not destroy
808 // it), and have not yet started the next activity.
809 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
810 "updateConfiguration()");
Craig Mautnerde4ef022013-04-07 19:01:33 -0700811 stack.mConfigWillChange = false;
Craig Mautner23ac33b2013-04-01 16:26:35 -0700812 if (DEBUG_CONFIGURATION) Slog.v(TAG,
813 "Updating to new configuration after starting activity.");
814 mService.updateConfigurationLocked(config, null, false, false);
815 }
816
817 Binder.restoreCallingIdentity(origId);
818
819 if (outResult != null) {
820 outResult.result = res;
821 if (res == ActivityManager.START_SUCCESS) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700822 mWaitingActivityLaunched.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700823 do {
824 try {
825 mService.wait();
826 } catch (InterruptedException e) {
827 }
828 } while (!outResult.timeout && outResult.who == null);
829 } else if (res == ActivityManager.START_TASK_TO_FRONT) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700830 ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700831 if (r.nowVisible) {
832 outResult.timeout = false;
833 outResult.who = new ComponentName(r.info.packageName, r.info.name);
834 outResult.totalTime = 0;
835 outResult.thisTime = 0;
836 } else {
837 outResult.thisTime = SystemClock.uptimeMillis();
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700838 mWaitingActivityVisible.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700839 do {
840 try {
841 mService.wait();
842 } catch (InterruptedException e) {
843 }
844 } while (!outResult.timeout && outResult.who == null);
845 }
846 }
847 }
848
849 return res;
850 }
851 }
852
853 final int startActivities(IApplicationThread caller, int callingUid, String callingPackage,
854 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
855 Bundle options, int userId) {
856 if (intents == null) {
857 throw new NullPointerException("intents is null");
858 }
859 if (resolvedTypes == null) {
860 throw new NullPointerException("resolvedTypes is null");
861 }
862 if (intents.length != resolvedTypes.length) {
863 throw new IllegalArgumentException("intents are length different than resolvedTypes");
864 }
865
Craig Mautner23ac33b2013-04-01 16:26:35 -0700866
867 int callingPid;
868 if (callingUid >= 0) {
869 callingPid = -1;
870 } else if (caller == null) {
871 callingPid = Binder.getCallingPid();
872 callingUid = Binder.getCallingUid();
873 } else {
874 callingPid = callingUid = -1;
875 }
876 final long origId = Binder.clearCallingIdentity();
877 try {
878 synchronized (mService) {
Craig Mautner76ea2242013-05-15 11:40:05 -0700879 ActivityRecord[] outActivity = new ActivityRecord[1];
Craig Mautner23ac33b2013-04-01 16:26:35 -0700880 for (int i=0; i<intents.length; i++) {
881 Intent intent = intents[i];
882 if (intent == null) {
883 continue;
884 }
885
886 // Refuse possible leaked file descriptors
887 if (intent != null && intent.hasFileDescriptors()) {
888 throw new IllegalArgumentException("File descriptors passed in Intent");
889 }
890
891 boolean componentSpecified = intent.getComponent() != null;
892
893 // Don't modify the client's object!
894 intent = new Intent(intent);
895
896 // Collect information about the target of the Intent.
897 ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i],
898 0, null, null, userId);
899 // TODO: New, check if this is correct
900 aInfo = mService.getActivityInfoForUser(aInfo, userId);
901
902 if (aInfo != null &&
903 (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE)
904 != 0) {
905 throw new IllegalArgumentException(
906 "FLAG_CANT_SAVE_STATE not supported here");
907 }
908
909 Bundle theseOptions;
910 if (options != null && i == intents.length-1) {
911 theseOptions = options;
912 } else {
913 theseOptions = null;
914 }
Craig Mautner6170f732013-04-02 13:05:23 -0700915 int res = startActivityLocked(caller, intent, resolvedTypes[i],
Craig Mautner23ac33b2013-04-01 16:26:35 -0700916 aInfo, resultTo, null, -1, callingPid, callingUid, callingPackage,
Craig Mautnere0a38842013-12-16 16:14:02 -0800917 0, theseOptions, componentSpecified, outActivity, null);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700918 if (res < 0) {
919 return res;
920 }
921
922 resultTo = outActivity[0] != null ? outActivity[0].appToken : null;
923 }
924 }
925 } finally {
926 Binder.restoreCallingIdentity(origId);
927 }
928
929 return ActivityManager.START_SUCCESS;
930 }
931
Craig Mautner2420ead2013-04-01 17:13:20 -0700932 final boolean realStartActivityLocked(ActivityRecord r,
933 ProcessRecord app, boolean andResume, boolean checkConfig)
934 throws RemoteException {
935
936 r.startFreezingScreenLocked(app, 0);
Craig Mautnera7f2bd42013-10-15 16:13:50 -0700937 if (false) Slog.d(TAG, "realStartActivity: setting app visibility true");
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700938 mWindowManager.setAppVisibility(r.appToken, true);
Craig Mautner2420ead2013-04-01 17:13:20 -0700939
940 // schedule launch ticks to collect information about slow apps.
941 r.startLaunchTickingLocked();
942
943 // Have the window manager re-evaluate the orientation of
944 // the screen based on the new activity order. Note that
945 // as a result of this, it can call back into the activity
946 // manager with a new orientation. We don't care about that,
947 // because the activity is not currently running so we are
948 // just restarting it anyway.
949 if (checkConfig) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700950 Configuration config = mWindowManager.updateOrientationFromAppTokens(
Craig Mautner2420ead2013-04-01 17:13:20 -0700951 mService.mConfiguration,
952 r.mayFreezeScreenLocked(app) ? r.appToken : null);
953 mService.updateConfigurationLocked(config, r, false, false);
954 }
955
956 r.app = app;
957 app.waitingToKill = null;
958 r.launchCount++;
959 r.lastLaunchTime = SystemClock.uptimeMillis();
960
961 if (localLOGV) Slog.v(TAG, "Launching: " + r);
962
963 int idx = app.activities.indexOf(r);
964 if (idx < 0) {
965 app.activities.add(r);
966 }
Dianne Hackborndb926082013-10-31 16:32:44 -0700967 mService.updateLruProcessLocked(app, true, null);
968 mService.updateOomAdjLocked();
Craig Mautner2420ead2013-04-01 17:13:20 -0700969
970 final ActivityStack stack = r.task.stack;
971 try {
972 if (app.thread == null) {
973 throw new RemoteException();
974 }
975 List<ResultInfo> results = null;
976 List<Intent> newIntents = null;
977 if (andResume) {
978 results = r.results;
979 newIntents = r.newIntents;
980 }
981 if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r
982 + " icicle=" + r.icicle
983 + " with results=" + results + " newIntents=" + newIntents
984 + " andResume=" + andResume);
985 if (andResume) {
986 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
987 r.userId, System.identityHashCode(r),
988 r.task.taskId, r.shortComponentName);
989 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700990 if (r.isHomeActivity() && r.isNotResolverActivity()) {
Craig Mautner4ef26932013-09-18 15:15:52 -0700991 // Home process is the root process of the task.
992 mService.mHomeProcess = r.task.mActivities.get(0).app;
Craig Mautner2420ead2013-04-01 17:13:20 -0700993 }
994 mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
995 r.sleeping = false;
996 r.forceNewConfig = false;
997 mService.showAskCompatModeDialogLocked(r);
998 r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
999 String profileFile = null;
1000 ParcelFileDescriptor profileFd = null;
1001 boolean profileAutoStop = false;
1002 if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
1003 if (mService.mProfileProc == null || mService.mProfileProc == app) {
1004 mService.mProfileProc = app;
1005 profileFile = mService.mProfileFile;
1006 profileFd = mService.mProfileFd;
1007 profileAutoStop = mService.mAutoStopProfiler;
1008 }
1009 }
1010 app.hasShownUi = true;
1011 app.pendingUiClean = true;
1012 if (profileFd != null) {
1013 try {
1014 profileFd = profileFd.dup();
1015 } catch (IOException e) {
1016 if (profileFd != null) {
1017 try {
1018 profileFd.close();
1019 } catch (IOException o) {
1020 }
1021 profileFd = null;
1022 }
1023 }
1024 }
Dianne Hackborna413dc02013-07-12 12:02:55 -07001025 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
Craig Mautner2420ead2013-04-01 17:13:20 -07001026 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
1027 System.identityHashCode(r), r.info,
Dianne Hackborna413dc02013-07-12 12:02:55 -07001028 new Configuration(mService.mConfiguration), r.compat,
1029 app.repProcState, r.icicle, results, newIntents, !andResume,
Craig Mautner2420ead2013-04-01 17:13:20 -07001030 mService.isNextTransitionForward(), profileFile, profileFd,
1031 profileAutoStop);
1032
1033 if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
1034 // This may be a heavy-weight process! Note that the package
1035 // manager will ensure that only activity can run in the main
1036 // process of the .apk, which is the only thing that will be
1037 // considered heavy-weight.
1038 if (app.processName.equals(app.info.packageName)) {
1039 if (mService.mHeavyWeightProcess != null
1040 && mService.mHeavyWeightProcess != app) {
1041 Slog.w(TAG, "Starting new heavy weight process " + app
1042 + " when already running "
1043 + mService.mHeavyWeightProcess);
1044 }
1045 mService.mHeavyWeightProcess = app;
1046 Message msg = mService.mHandler.obtainMessage(
1047 ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
1048 msg.obj = r;
1049 mService.mHandler.sendMessage(msg);
1050 }
1051 }
1052
1053 } catch (RemoteException e) {
1054 if (r.launchFailed) {
1055 // This is the second time we failed -- finish activity
1056 // and give up.
1057 Slog.e(TAG, "Second failure launching "
1058 + r.intent.getComponent().flattenToShortString()
1059 + ", giving up", e);
1060 mService.appDiedLocked(app, app.pid, app.thread);
1061 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
1062 "2nd-crash", false);
1063 return false;
1064 }
1065
1066 // This is the first time we failed -- restart process and
1067 // retry.
1068 app.activities.remove(r);
1069 throw e;
1070 }
1071
1072 r.launchFailed = false;
1073 if (stack.updateLRUListLocked(r)) {
1074 Slog.w(TAG, "Activity " + r
1075 + " being launched, but already in LRU list");
1076 }
1077
1078 if (andResume) {
1079 // As part of the process of launching, ActivityThread also performs
1080 // a resume.
1081 stack.minimalResumeActivityLocked(r);
1082 } else {
1083 // This activity is not starting in the resumed state... which
1084 // should look like we asked it to pause+stop (but remain visible),
1085 // and it has done so and reported back the current icicle and
1086 // other state.
1087 if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r
1088 + " (starting in stopped state)");
1089 r.state = ActivityState.STOPPED;
1090 r.stopped = true;
1091 }
1092
1093 // Launch the new version setup screen if needed. We do this -after-
1094 // launching the initial activity (that is, home), so that it can have
1095 // a chance to initialize itself while in the background, making the
1096 // switch back to it faster and look better.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001097 if (isFrontStack(stack)) {
Craig Mautner2420ead2013-04-01 17:13:20 -07001098 mService.startSetupActivityLocked();
1099 }
1100
1101 return true;
1102 }
1103
Craig Mautnere79d42682013-04-01 19:01:53 -07001104 void startSpecificActivityLocked(ActivityRecord r,
1105 boolean andResume, boolean checkConfig) {
1106 // Is this activity's application already running?
1107 ProcessRecord app = mService.getProcessRecordLocked(r.processName,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001108 r.info.applicationInfo.uid, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001109
1110 r.task.stack.setLaunchTime(r);
1111
1112 if (app != null && app.thread != null) {
1113 try {
Dianne Hackborn237cefb2013-10-22 18:45:27 -07001114 if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
1115 || !"android".equals(r.info.packageName)) {
1116 // Don't add this if it is a platform component that is marked
1117 // to run in multiple processes, because this is actually
1118 // part of the framework so doesn't make sense to track as a
1119 // separate apk in the process.
1120 app.addPackage(r.info.packageName, mService.mProcessStats);
1121 }
Craig Mautnere79d42682013-04-01 19:01:53 -07001122 realStartActivityLocked(r, app, andResume, checkConfig);
1123 return;
1124 } catch (RemoteException e) {
1125 Slog.w(TAG, "Exception when starting activity "
1126 + r.intent.getComponent().flattenToShortString(), e);
1127 }
1128
1129 // If a dead object exception was thrown -- fall through to
1130 // restart the application.
1131 }
1132
1133 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001134 "activity", r.intent.getComponent(), false, false, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001135 }
1136
Craig Mautner6170f732013-04-02 13:05:23 -07001137 final int startActivityLocked(IApplicationThread caller,
1138 Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
1139 String resultWho, int requestCode,
1140 int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
Craig Mautnere0a38842013-12-16 16:14:02 -08001141 boolean componentSpecified, ActivityRecord[] outActivity, ActivityContainer container) {
Craig Mautner6170f732013-04-02 13:05:23 -07001142 int err = ActivityManager.START_SUCCESS;
1143
1144 ProcessRecord callerApp = null;
1145 if (caller != null) {
1146 callerApp = mService.getRecordForAppLocked(caller);
1147 if (callerApp != null) {
1148 callingPid = callerApp.pid;
1149 callingUid = callerApp.info.uid;
1150 } else {
1151 Slog.w(TAG, "Unable to find app for caller " + caller
1152 + " (pid=" + callingPid + ") when starting: "
1153 + intent.toString());
1154 err = ActivityManager.START_PERMISSION_DENIED;
1155 }
1156 }
1157
1158 if (err == ActivityManager.START_SUCCESS) {
1159 final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
1160 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
Craig Mautner9ef471f2014-02-07 13:11:47 -08001161 + "} from pid " + (callerApp != null ? callerApp.pid : callingPid)
1162 + " on display " + (container == null ? (mFocusedStack == null ?
1163 Display.DEFAULT_DISPLAY : mFocusedStack.mDisplayId) :
1164 (container.mActivityDisplay == null ? Display.DEFAULT_DISPLAY :
1165 container.mActivityDisplay.mDisplayId)));
Craig Mautner6170f732013-04-02 13:05:23 -07001166 }
1167
1168 ActivityRecord sourceRecord = null;
1169 ActivityRecord resultRecord = null;
1170 if (resultTo != null) {
1171 sourceRecord = isInAnyStackLocked(resultTo);
1172 if (DEBUG_RESULTS) Slog.v(
1173 TAG, "Will send result to " + resultTo + " " + sourceRecord);
1174 if (sourceRecord != null) {
1175 if (requestCode >= 0 && !sourceRecord.finishing) {
1176 resultRecord = sourceRecord;
1177 }
1178 }
1179 }
1180 ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
1181
1182 int launchFlags = intent.getFlags();
1183
1184 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
1185 && sourceRecord != null) {
1186 // Transfer the result target from the source activity to the new
1187 // one being started, including any failures.
1188 if (requestCode >= 0) {
1189 ActivityOptions.abort(options);
1190 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
1191 }
1192 resultRecord = sourceRecord.resultTo;
1193 resultWho = sourceRecord.resultWho;
1194 requestCode = sourceRecord.requestCode;
1195 sourceRecord.resultTo = null;
1196 if (resultRecord != null) {
1197 resultRecord.removeResultsLocked(
1198 sourceRecord, resultWho, requestCode);
1199 }
Dianne Hackbornd4981012014-03-14 16:27:40 +00001200 if (sourceRecord.launchedFromUid == callingUid) {
1201 // The new activity is being launched from the same uid as the previous
1202 // activity in the flow, and asking to forward its result back to the
1203 // previous. In this case the activity is serving as a trampoline between
1204 // the two, so we also want to update its launchedFromPackage to be the
1205 // same as the previous activity. Note that this is safe, since we know
1206 // these two packages come from the same uid; the caller could just as
1207 // well have supplied that same package name itself. This specifially
1208 // deals with the case of an intent picker/chooser being launched in the app
1209 // flow to redirect to an activity picked by the user, where we want the final
1210 // activity to consider it to have been launched by the previous app activity.
1211 callingPackage = sourceRecord.launchedFromPackage;
1212 }
Craig Mautner6170f732013-04-02 13:05:23 -07001213 }
1214
1215 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
1216 // We couldn't find a class that can handle the given Intent.
1217 // That's the end of that!
1218 err = ActivityManager.START_INTENT_NOT_RESOLVED;
1219 }
1220
1221 if (err == ActivityManager.START_SUCCESS && aInfo == null) {
1222 // We couldn't find the specific class specified in the Intent.
1223 // Also the end of the line.
1224 err = ActivityManager.START_CLASS_NOT_FOUND;
1225 }
1226
1227 if (err != ActivityManager.START_SUCCESS) {
1228 if (resultRecord != null) {
1229 resultStack.sendActivityResultLocked(-1,
1230 resultRecord, resultWho, requestCode,
1231 Activity.RESULT_CANCELED, null);
1232 }
1233 setDismissKeyguard(false);
1234 ActivityOptions.abort(options);
1235 return err;
1236 }
1237
1238 final int startAnyPerm = mService.checkPermission(
1239 START_ANY_ACTIVITY, callingPid, callingUid);
1240 final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
1241 callingUid, aInfo.applicationInfo.uid, aInfo.exported);
1242 if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
1243 if (resultRecord != null) {
1244 resultStack.sendActivityResultLocked(-1,
1245 resultRecord, resultWho, requestCode,
1246 Activity.RESULT_CANCELED, null);
1247 }
1248 setDismissKeyguard(false);
1249 String msg;
1250 if (!aInfo.exported) {
1251 msg = "Permission Denial: starting " + intent.toString()
1252 + " from " + callerApp + " (pid=" + callingPid
1253 + ", uid=" + callingUid + ")"
1254 + " not exported from uid " + aInfo.applicationInfo.uid;
1255 } else {
1256 msg = "Permission Denial: starting " + intent.toString()
1257 + " from " + callerApp + " (pid=" + callingPid
1258 + ", uid=" + callingUid + ")"
1259 + " requires " + aInfo.permission;
1260 }
1261 Slog.w(TAG, msg);
1262 throw new SecurityException(msg);
1263 }
1264
Ben Gruverdd72c9e2013-08-06 12:34:17 -07001265 boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
Ben Gruverb6223792013-07-29 16:35:40 -07001266 callingPid, resolvedType, aInfo.applicationInfo);
Ben Gruver5e207332013-04-03 17:41:37 -07001267
Craig Mautner6170f732013-04-02 13:05:23 -07001268 if (mService.mController != null) {
Craig Mautner6170f732013-04-02 13:05:23 -07001269 try {
1270 // The Intent we give to the watcher has the extra data
1271 // stripped off, since it can contain private information.
1272 Intent watchIntent = intent.cloneFilter();
Ben Gruver5e207332013-04-03 17:41:37 -07001273 abort |= !mService.mController.activityStarting(watchIntent,
Craig Mautner6170f732013-04-02 13:05:23 -07001274 aInfo.applicationInfo.packageName);
1275 } catch (RemoteException e) {
1276 mService.mController = null;
1277 }
Ben Gruver5e207332013-04-03 17:41:37 -07001278 }
Craig Mautner6170f732013-04-02 13:05:23 -07001279
Ben Gruver5e207332013-04-03 17:41:37 -07001280 if (abort) {
1281 if (resultRecord != null) {
1282 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
Craig Mautner6170f732013-04-02 13:05:23 -07001283 Activity.RESULT_CANCELED, null);
Craig Mautner6170f732013-04-02 13:05:23 -07001284 }
Ben Gruver5e207332013-04-03 17:41:37 -07001285 // We pretend to the caller that it was really started, but
1286 // they will just get a cancel result.
1287 setDismissKeyguard(false);
1288 ActivityOptions.abort(options);
1289 return ActivityManager.START_SUCCESS;
Craig Mautner6170f732013-04-02 13:05:23 -07001290 }
1291
1292 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
Craig Mautnere0a38842013-12-16 16:14:02 -08001293 intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
1294 requestCode, componentSpecified, this, container);
Craig Mautner6170f732013-04-02 13:05:23 -07001295 if (outActivity != null) {
1296 outActivity[0] = r;
1297 }
1298
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001299 final ActivityStack stack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001300 if (stack.mResumedActivity == null
1301 || stack.mResumedActivity.info.applicationInfo.uid != callingUid) {
Craig Mautner6170f732013-04-02 13:05:23 -07001302 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
1303 PendingActivityLaunch pal =
Craig Mautnerde4ef022013-04-07 19:01:33 -07001304 new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
Craig Mautner6170f732013-04-02 13:05:23 -07001305 mService.mPendingActivityLaunches.add(pal);
1306 setDismissKeyguard(false);
1307 ActivityOptions.abort(options);
1308 return ActivityManager.START_SWITCHES_CANCELED;
1309 }
1310 }
1311
1312 if (mService.mDidAppSwitch) {
1313 // This is the second allowed switch since we stopped switches,
1314 // so now just generally allow switches. Use case: user presses
1315 // home (switches disabled, switch to home, mDidAppSwitch now true);
1316 // user taps a home icon (coming from home so allowed, we hit here
1317 // and now allow anyone to switch again).
1318 mService.mAppSwitchesAllowedTime = 0;
1319 } else {
1320 mService.mDidAppSwitch = true;
1321 }
1322
1323 mService.doPendingActivityLaunchesLocked(false);
1324
Craig Mautner8849a5e2013-04-02 16:41:03 -07001325 err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
Craig Mautner10385a12013-09-22 21:08:32 -07001326
1327 if (allPausedActivitiesComplete()) {
1328 // If someone asked to have the keyguard dismissed on the next
Craig Mautner6170f732013-04-02 13:05:23 -07001329 // activity start, but we are not actually doing an activity
1330 // switch... just dismiss the keyguard now, because we
1331 // probably want to see whatever is behind it.
1332 dismissKeyguard();
1333 }
1334 return err;
1335 }
1336
Craig Mautnerac6f8432013-07-17 13:24:59 -07001337 ActivityStack adjustStackFocus(ActivityRecord r) {
Craig Mautner1d001b62013-06-18 16:52:43 -07001338 final TaskRecord task = r.task;
1339 if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001340 if (task != null) {
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07001341 final ActivityStack taskStack = task.stack;
Craig Mautnere0a38842013-12-16 16:14:02 -08001342 if (taskStack.isOnHomeDisplay()) {
1343 if (mFocusedStack != taskStack) {
1344 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: Setting " +
1345 "focused stack to r=" + r + " task=" + task);
1346 mFocusedStack = taskStack;
1347 } else {
1348 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1349 "adjustStackFocus: Focused stack already=" + mFocusedStack);
1350 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001351 }
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07001352 return taskStack;
Craig Mautnerac6f8432013-07-17 13:24:59 -07001353 }
1354
Craig Mautnere0a38842013-12-16 16:14:02 -08001355 final ActivityContainer container = r.mInitialActivityContainer;
1356 if (container != null) {
1357 // The first time put it on the desired stack, after this put on task stack.
1358 r.mInitialActivityContainer = null;
1359 return container.mStack;
1360 }
1361
Craig Mautner4a1cb222013-12-04 16:14:06 -08001362 if (mFocusedStack != mHomeStack) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001363 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1364 "adjustStackFocus: Have a focused stack=" + mFocusedStack);
1365 return mFocusedStack;
1366 }
1367
Craig Mautnere0a38842013-12-16 16:14:02 -08001368 final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks;
1369 for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1370 final ActivityStack stack = homeDisplayStacks.get(stackNdx);
1371 if (!stack.isHomeStack()) {
1372 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1373 "adjustStackFocus: Setting focused stack=" + stack);
1374 mFocusedStack = stack;
1375 return mFocusedStack;
Craig Mautner858d8a62013-04-23 17:08:34 -07001376 }
1377 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001378
Craig Mautner4a1cb222013-12-04 16:14:06 -08001379 // Need to create an app stack for this user.
Craig Mautnerf4c909b2014-04-17 18:39:38 -07001380 int stackId = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY);
Craig Mautnerac6f8432013-07-17 13:24:59 -07001381 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r +
1382 " stackId=" + stackId);
1383 mFocusedStack = getStack(stackId);
Craig Mautner29219d92013-04-16 20:19:12 -07001384 return mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001385 }
1386 return mHomeStack;
1387 }
1388
Craig Mautner29219d92013-04-16 20:19:12 -07001389 void setFocusedStack(ActivityRecord r) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08001390 if (r != null) {
Craig Mautner12ff7392014-02-21 21:08:00 -08001391 final TaskRecord task = r.task;
1392 boolean isHomeActivity = !r.isApplicationActivity();
1393 if (!isHomeActivity && task != null) {
1394 isHomeActivity = !task.isApplicationTask();
1395 }
1396 if (!isHomeActivity && task != null) {
1397 final ActivityRecord parent = task.stack.mActivityContainer.mParentActivity;
1398 isHomeActivity = parent != null && parent.isHomeActivity();
1399 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08001400 moveHomeStack(isHomeActivity);
Craig Mautner29219d92013-04-16 20:19:12 -07001401 }
1402 }
1403
Craig Mautner8849a5e2013-04-02 16:41:03 -07001404 final int startActivityUncheckedLocked(ActivityRecord r,
1405 ActivityRecord sourceRecord, int startFlags, boolean doResume,
1406 Bundle options) {
1407 final Intent intent = r.intent;
1408 final int callingUid = r.launchedFromUid;
1409
1410 int launchFlags = intent.getFlags();
1411
Craig Mautner8849a5e2013-04-02 16:41:03 -07001412 // We'll invoke onUserLeaving before onPause only if the launching
1413 // activity did not explicitly state that this is an automated launch.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001414 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1415 if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001416
1417 // If the caller has asked not to resume at this point, we make note
1418 // of this in the record so that we can skip it when trying to find
1419 // the top running activity.
1420 if (!doResume) {
1421 r.delayedResume = true;
1422 }
1423
1424 ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1425
1426 // If the onlyIfNeeded flag is set, then we can do this if the activity
1427 // being launched is the same as the one making the call... or, as
1428 // a special case, if we do not know the caller then we count the
1429 // current top activity as the caller.
1430 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1431 ActivityRecord checkedCaller = sourceRecord;
1432 if (checkedCaller == null) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001433 checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001434 }
1435 if (!checkedCaller.realActivity.equals(r.realActivity)) {
1436 // Caller is not the same as launcher, so always needed.
1437 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
1438 }
1439 }
1440
1441 if (sourceRecord == null) {
1442 // This activity is not being started from another... in this
1443 // case we -always- start a new task.
1444 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
Craig Mautner29219d92013-04-16 20:19:12 -07001445 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1446 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001447 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1448 }
1449 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1450 // The original activity who is starting us is running as a single
1451 // instance... this new activity it is starting must go on its
1452 // own task.
1453 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1454 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
1455 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1456 // The activity being started is a single instance... it always
1457 // gets launched into its own task.
1458 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1459 }
1460
Craig Mautner88629292013-11-10 20:39:05 -08001461 ActivityInfo newTaskInfo = null;
1462 Intent newTaskIntent = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001463 final ActivityStack sourceStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001464 if (sourceRecord != null) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001465 if (sourceRecord.finishing) {
1466 // If the source is finishing, we can't further count it as our source. This
1467 // is because the task it is associated with may now be empty and on its way out,
1468 // so we don't want to blindly throw it in to that task. Instead we will take
Craig Mautner88629292013-11-10 20:39:05 -08001469 // the NEW_TASK flow and try to find a task for it. But save the task information
1470 // so it can be used when creating the new task.
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001471 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
1472 Slog.w(TAG, "startActivity called from finishing " + sourceRecord
1473 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
1474 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
Craig Mautner88629292013-11-10 20:39:05 -08001475 newTaskInfo = sourceRecord.info;
1476 newTaskIntent = sourceRecord.task.intent;
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001477 }
1478 sourceRecord = null;
1479 sourceStack = null;
1480 } else {
1481 sourceStack = sourceRecord.task.stack;
1482 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07001483 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001484 sourceStack = null;
1485 }
1486
Craig Mautner8849a5e2013-04-02 16:41:03 -07001487 if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1488 // For whatever reason this activity is being launched into a new
1489 // task... yet the caller has requested a result back. Well, that
1490 // is pretty messed up, so instead immediately send back a cancel
1491 // and let the new task continue launched as normal without a
1492 // dependency on its originator.
1493 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1494 r.resultTo.task.stack.sendActivityResultLocked(-1,
1495 r.resultTo, r.resultWho, r.requestCode,
1496 Activity.RESULT_CANCELED, null);
1497 r.resultTo = null;
1498 }
1499
1500 boolean addingToTask = false;
1501 boolean movedHome = false;
1502 TaskRecord reuseTask = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001503 ActivityStack targetStack;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001504 if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
1505 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
1506 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1507 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1508 // If bring to front is requested, and no result is requested, and
1509 // we can find a task that was started with this same
1510 // component, then instead of launching bring that one to the front.
1511 if (r.resultTo == null) {
1512 // See if there is a task to bring to the front. If this is
1513 // a SINGLE_INSTANCE activity, there can be one and only one
1514 // instance of it in the history, and it is always in its own
1515 // unique task, so we do a special search.
1516 ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
Craig Mautnerac6f8432013-07-17 13:24:59 -07001517 ? findTaskLocked(r)
Craig Mautner8849a5e2013-04-02 16:41:03 -07001518 : findActivityLocked(intent, r.info);
1519 if (intentActivity != null) {
Craig Mautner29219d92013-04-16 20:19:12 -07001520 if (r.task == null) {
1521 r.task = intentActivity.task;
1522 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001523 targetStack = intentActivity.task.stack;
Craig Mautner0f922742013-08-06 08:44:42 -07001524 targetStack.mLastPausedActivity = null;
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001525 if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack
1526 + " from " + intentActivity);
Craig Mautnere0a38842013-12-16 16:14:02 -08001527 targetStack.moveToFront();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001528 if (intentActivity.task.intent == null) {
1529 // This task was started because of movement of
1530 // the activity based on affinity... now that we
1531 // are actually launching it, we can assign the
1532 // base intent.
1533 intentActivity.task.setIntent(intent, r.info);
1534 }
1535 // If the target task is not in the front, then we need
1536 // to bring it to the front... except... well, with
1537 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like
1538 // to have the same behavior as if a new instance was
1539 // being started, which means not bringing it to the front
1540 // if the caller is not itself in the front.
Craig Mautner165640b2013-04-20 10:34:33 -07001541 final ActivityStack lastStack = getLastStack();
1542 ActivityRecord curTop = lastStack == null?
1543 null : lastStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner7504d7b2013-09-17 10:50:53 -07001544 if (curTop != null && (curTop.task != intentActivity.task ||
1545 curTop.task != lastStack.topTask())) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001546 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Craig Mautnerd0f964f2013-08-07 11:16:33 -07001547 if (sourceRecord == null || (sourceStack.topActivity() != null &&
1548 sourceStack.topActivity().task == sourceRecord.task)) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001549 // We really do want to push this one into the
1550 // user's face, right now.
1551 movedHome = true;
Craig Mautnerb53d97c2013-10-25 11:54:37 -07001552 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001553 if ((launchFlags &
Craig Mautner29219d92013-04-16 20:19:12 -07001554 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1555 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
Craig Mautnere12a4a62013-08-29 12:24:56 -07001556 // Caller wants to appear on home activity.
Craig Mautnerae7ecab2013-09-18 11:48:14 -07001557 intentActivity.task.mOnTopOfHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001558 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001559 options = null;
1560 }
1561 }
1562 // If the caller has requested that the target task be
1563 // reset, then do so.
1564 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1565 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
1566 }
1567 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1568 // We don't need to start a new activity, and
1569 // the client said not to do anything if that
1570 // is the case, so this is it! And for paranoia, make
1571 // sure we have correctly resumed the top activity.
1572 if (doResume) {
Craig Mautner05d29032013-05-03 13:40:13 -07001573 resumeTopActivitiesLocked(targetStack, null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001574 } else {
1575 ActivityOptions.abort(options);
1576 }
1577 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1578 }
1579 if ((launchFlags &
1580 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
1581 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
1582 // The caller has requested to completely replace any
1583 // existing task with its new activity. Well that should
1584 // not be too hard...
1585 reuseTask = intentActivity.task;
1586 reuseTask.performClearTaskLocked();
1587 reuseTask.setIntent(r.intent, r.info);
1588 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
1589 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1590 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1591 // In this situation we want to remove all activities
1592 // from the task up to the one being started. In most
1593 // cases this means we are resetting the task to its
1594 // initial state.
1595 ActivityRecord top =
1596 intentActivity.task.performClearTaskLocked(r, launchFlags);
1597 if (top != null) {
1598 if (top.frontOfTask) {
1599 // Activity aliases may mean we use different
1600 // intents for the top activity, so make sure
1601 // the task now has the identity of the new
1602 // intent.
1603 top.task.setIntent(r.intent, r.info);
1604 }
1605 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
1606 r, top.task);
1607 top.deliverNewIntentLocked(callingUid, r.intent);
1608 } else {
1609 // A special case: we need to
1610 // start the activity because it is not currently
1611 // running, and the caller has asked to clear the
1612 // current task to have this activity at the top.
1613 addingToTask = true;
1614 // Now pretend like this activity is being started
1615 // by the top of its task, so it is put in the
1616 // right place.
1617 sourceRecord = intentActivity;
1618 }
1619 } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
1620 // In this case the top activity on the task is the
1621 // same as the one being launched, so we take that
1622 // as a request to bring the task to the foreground.
1623 // If the top activity in the task is the root
1624 // activity, deliver this new intent to it if it
1625 // desires.
1626 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1627 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
1628 && intentActivity.realActivity.equals(r.realActivity)) {
1629 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
1630 intentActivity.task);
1631 if (intentActivity.frontOfTask) {
1632 intentActivity.task.setIntent(r.intent, r.info);
1633 }
1634 intentActivity.deliverNewIntentLocked(callingUid, r.intent);
1635 } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
1636 // In this case we are launching the root activity
1637 // of the task, but with a different intent. We
1638 // should start a new instance on top.
1639 addingToTask = true;
1640 sourceRecord = intentActivity;
1641 }
1642 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1643 // In this case an activity is being launched in to an
1644 // existing task, without resetting that task. This
1645 // is typically the situation of launching an activity
1646 // from a notification or shortcut. We want to place
1647 // the new activity on top of the current task.
1648 addingToTask = true;
1649 sourceRecord = intentActivity;
1650 } else if (!intentActivity.task.rootWasReset) {
1651 // In this case we are launching in to an existing task
1652 // that has not yet been started from its front door.
1653 // The current task has been brought to the front.
1654 // Ideally, we'd probably like to place this new task
1655 // at the bottom of its stack, but that's a little hard
1656 // to do with the current organization of the code so
1657 // for now we'll just drop it.
1658 intentActivity.task.setIntent(r.intent, r.info);
1659 }
1660 if (!addingToTask && reuseTask == null) {
1661 // We didn't do anything... but it was needed (a.k.a., client
1662 // don't use that intent!) And for paranoia, make
1663 // sure we have correctly resumed the top activity.
1664 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001665 targetStack.resumeTopActivityLocked(null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001666 } else {
1667 ActivityOptions.abort(options);
1668 }
1669 return ActivityManager.START_TASK_TO_FRONT;
1670 }
1671 }
1672 }
1673 }
1674
1675 //String uri = r.intent.toURI();
1676 //Intent intent2 = new Intent(uri);
1677 //Slog.i(TAG, "Given intent: " + r.intent);
1678 //Slog.i(TAG, "URI is: " + uri);
1679 //Slog.i(TAG, "To intent: " + intent2);
1680
1681 if (r.packageName != null) {
1682 // If the activity being launched is the same as the one currently
1683 // at the top, then we need to check if it should only be launched
1684 // once.
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001685 ActivityStack topStack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001686 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001687 if (top != null && r.resultTo == null) {
1688 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
1689 if (top.app != null && top.app.thread != null) {
1690 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1691 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
1692 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1693 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
1694 top.task);
1695 // For paranoia, make sure we have correctly
1696 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001697 topStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001698 if (doResume) {
Craig Mautner05d29032013-05-03 13:40:13 -07001699 resumeTopActivitiesLocked();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001700 }
1701 ActivityOptions.abort(options);
1702 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1703 // We don't need to start a new activity, and
1704 // the client said not to do anything if that
1705 // is the case, so this is it!
1706 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1707 }
1708 top.deliverNewIntentLocked(callingUid, r.intent);
1709 return ActivityManager.START_DELIVERED_TO_TOP;
1710 }
1711 }
1712 }
1713 }
1714
1715 } else {
1716 if (r.resultTo != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001717 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
1718 r.requestCode, Activity.RESULT_CANCELED, null);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001719 }
1720 ActivityOptions.abort(options);
1721 return ActivityManager.START_CLASS_NOT_FOUND;
1722 }
1723
1724 boolean newTask = false;
1725 boolean keepCurTransition = false;
1726
1727 // Should this be considered a new task?
1728 if (r.resultTo == null && !addingToTask
1729 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001730 targetStack = adjustStackFocus(r);
Craig Mautnere0a38842013-12-16 16:14:02 -08001731 targetStack.moveToFront();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001732 if (reuseTask == null) {
Craig Mautner88629292013-11-10 20:39:05 -08001733 r.setTask(targetStack.createTaskRecord(getNextTaskId(),
1734 newTaskInfo != null ? newTaskInfo : r.info,
1735 newTaskIntent != null ? newTaskIntent : intent,
1736 true), null, true);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001737 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
1738 r.task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001739 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001740 r.setTask(reuseTask, reuseTask, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001741 }
1742 newTask = true;
1743 if (!movedHome) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001744 if ((launchFlags &
1745 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
1746 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
1747 // Caller wants to appear on home activity, so before starting
1748 // their own activity we will bring home to the front.
Craig Mautnere0a38842013-12-16 16:14:02 -08001749 r.task.mOnTopOfHome = r.task.stack.isOnHomeDisplay();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001750 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001751 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001752 } else if (sourceRecord != null) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001753 TaskRecord sourceTask = sourceRecord.task;
Craig Mautner525f3d92013-05-07 14:01:50 -07001754 targetStack = sourceTask.stack;
Craig Mautnere0a38842013-12-16 16:14:02 -08001755 targetStack.moveToFront();
Craig Mautnerf32b22e2014-03-25 11:04:16 -07001756 mWindowManager.moveTaskToTop(sourceTask.taskId);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001757 if (!addingToTask &&
1758 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
1759 // In this case, we are adding the activity to an existing
1760 // task, but the caller has asked to clear that task if the
1761 // activity is already running.
Craig Mautner525f3d92013-05-07 14:01:50 -07001762 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001763 keepCurTransition = true;
1764 if (top != null) {
1765 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
1766 top.deliverNewIntentLocked(callingUid, r.intent);
1767 // For paranoia, make sure we have correctly
1768 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001769 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001770 if (doResume) {
1771 targetStack.resumeTopActivityLocked(null);
1772 }
1773 ActivityOptions.abort(options);
1774 return ActivityManager.START_DELIVERED_TO_TOP;
1775 }
1776 } else if (!addingToTask &&
1777 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1778 // In this case, we are launching an activity in our own task
1779 // that may already be running somewhere in the history, and
1780 // we want to shuffle it to the front of the stack if so.
Craig Mautner525f3d92013-05-07 14:01:50 -07001781 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001782 if (top != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001783 final TaskRecord task = top.task;
1784 task.moveActivityToFrontLocked(top);
1785 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001786 top.updateOptionsLocked(options);
1787 top.deliverNewIntentLocked(callingUid, r.intent);
Craig Mautner0f922742013-08-06 08:44:42 -07001788 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001789 if (doResume) {
1790 targetStack.resumeTopActivityLocked(null);
1791 }
1792 return ActivityManager.START_DELIVERED_TO_TOP;
1793 }
1794 }
1795 // An existing activity is starting this new activity, so we want
1796 // to keep the new one in the same task as the one that is starting
1797 // it.
Craig Mautner525f3d92013-05-07 14:01:50 -07001798 r.setTask(sourceTask, sourceRecord.thumbHolder, false);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001799 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001800 + " in existing task " + r.task + " from source " + sourceRecord);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001801
1802 } else {
1803 // This not being started from an existing activity, and not part
1804 // of a new task... just put it in the top task, though these days
1805 // this case should never happen.
Craig Mautnerac6f8432013-07-17 13:24:59 -07001806 targetStack = adjustStackFocus(r);
Craig Mautnere0a38842013-12-16 16:14:02 -08001807 targetStack.moveToFront();
Craig Mautner1602ec22013-05-12 10:24:27 -07001808 ActivityRecord prev = targetStack.topActivity();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001809 r.setTask(prev != null ? prev.task
1810 : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1811 null, true);
Craig Mautnerf32b22e2014-03-25 11:04:16 -07001812 mWindowManager.moveTaskToTop(r.task.taskId);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001813 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1814 + " in new guessed " + r.task);
1815 }
1816
1817 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
1818 intent, r.getUriPermissionsLocked());
1819
1820 if (newTask) {
1821 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
1822 }
1823 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
Craig Mautner0f922742013-08-06 08:44:42 -07001824 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001825 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
Craig Mautner1d001b62013-06-18 16:52:43 -07001826 mService.setFocusedActivityLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001827 return ActivityManager.START_SUCCESS;
1828 }
1829
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001830 void acquireLaunchWakelock() {
1831 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
1832 throw new IllegalStateException("Calling must be system uid");
1833 }
1834 mLaunchingActivity.acquire();
1835 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
1836 // To be safe, don't allow the wake lock to be held for too long.
1837 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
1838 }
1839 }
1840
Craig Mautnerf3333272013-04-22 10:55:53 -07001841 // Checked.
1842 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
1843 Configuration config) {
1844 if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
1845
Craig Mautnerf3333272013-04-22 10:55:53 -07001846 ArrayList<ActivityRecord> stops = null;
1847 ArrayList<ActivityRecord> finishes = null;
1848 ArrayList<UserStartedState> startingUsers = null;
1849 int NS = 0;
1850 int NF = 0;
1851 IApplicationThread sendThumbnail = null;
1852 boolean booting = false;
1853 boolean enableScreen = false;
1854 boolean activityRemoved = false;
1855
1856 ActivityRecord r = ActivityRecord.forToken(token);
1857 if (r != null) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07001858 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
1859 Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07001860 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
1861 r.finishLaunchTickingLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001862 if (fromTimeout) {
1863 reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
Craig Mautnerf3333272013-04-22 10:55:53 -07001864 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001865
1866 // This is a hack to semi-deal with a race condition
1867 // in the client where it can be constructed with a
1868 // newer configuration from when we asked it to launch.
1869 // We'll update with whatever configuration it now says
1870 // it used to launch.
1871 if (config != null) {
1872 r.configuration = config;
1873 }
1874
1875 // We are now idle. If someone is waiting for a thumbnail from
1876 // us, we can now deliver.
1877 r.idle = true;
1878
1879 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
1880 sendThumbnail = r.app.thread;
1881 r.thumbnailNeeded = false;
1882 }
1883
1884 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
1885 if (!mService.mBooted && isFrontStack(r.task.stack)) {
1886 mService.mBooted = true;
1887 enableScreen = true;
1888 }
1889 }
1890
1891 if (allResumedActivitiesIdle()) {
1892 if (r != null) {
1893 mService.scheduleAppGcsLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001894 }
1895
1896 if (mLaunchingActivity.isHeld()) {
1897 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
1898 if (VALIDATE_WAKE_LOCK_CALLER &&
1899 Binder.getCallingUid() != Process.myUid()) {
1900 throw new IllegalStateException("Calling must be system uid");
1901 }
1902 mLaunchingActivity.release();
1903 }
1904 ensureActivitiesVisibleLocked(null, 0);
Craig Mautnerf3333272013-04-22 10:55:53 -07001905 }
1906
1907 // Atomically retrieve all of the other things to do.
1908 stops = processStoppingActivitiesLocked(true);
1909 NS = stops != null ? stops.size() : 0;
1910 if ((NF=mFinishingActivities.size()) > 0) {
1911 finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
1912 mFinishingActivities.clear();
1913 }
1914
1915 final ArrayList<ActivityRecord> thumbnails;
1916 final int NT = mCancelledThumbnails.size();
1917 if (NT > 0) {
1918 thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
1919 mCancelledThumbnails.clear();
1920 } else {
1921 thumbnails = null;
1922 }
1923
1924 if (isFrontStack(mHomeStack)) {
1925 booting = mService.mBooting;
1926 mService.mBooting = false;
1927 }
1928
1929 if (mStartingUsers.size() > 0) {
1930 startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
1931 mStartingUsers.clear();
1932 }
1933
1934 // Perform the following actions from unsynchronized state.
1935 final IApplicationThread thumbnailThread = sendThumbnail;
1936 mHandler.post(new Runnable() {
1937 @Override
1938 public void run() {
1939 if (thumbnailThread != null) {
1940 try {
1941 thumbnailThread.requestThumbnail(token);
1942 } catch (Exception e) {
1943 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
1944 mService.sendPendingThumbnail(null, token, null, null, true);
1945 }
1946 }
1947
1948 // Report back to any thumbnail receivers.
1949 for (int i = 0; i < NT; i++) {
1950 ActivityRecord r = thumbnails.get(i);
1951 mService.sendPendingThumbnail(r, null, null, null, true);
1952 }
1953 }
1954 });
1955
1956 // Stop any activities that are scheduled to do so but have been
1957 // waiting for the next one to start.
1958 for (int i = 0; i < NS; i++) {
1959 r = stops.get(i);
1960 final ActivityStack stack = r.task.stack;
1961 if (r.finishing) {
1962 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
1963 } else {
1964 stack.stopActivityLocked(r);
1965 }
1966 }
1967
1968 // Finish any activities that are scheduled to do so but have been
1969 // waiting for the next one to start.
1970 for (int i = 0; i < NF; i++) {
1971 r = finishes.get(i);
1972 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
1973 }
1974
1975 if (booting) {
1976 mService.finishBooting();
1977 } else if (startingUsers != null) {
1978 for (int i = 0; i < startingUsers.size(); i++) {
1979 mService.finishUserSwitch(startingUsers.get(i));
1980 }
1981 }
1982
1983 mService.trimApplications();
1984 //dump();
1985 //mWindowManager.dump();
1986
1987 if (enableScreen) {
1988 mService.enableScreenAfterBoot();
1989 }
1990
1991 if (activityRemoved) {
Craig Mautner05d29032013-05-03 13:40:13 -07001992 resumeTopActivitiesLocked();
Craig Mautnerf3333272013-04-22 10:55:53 -07001993 }
1994
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001995 return r;
Craig Mautnerf3333272013-04-22 10:55:53 -07001996 }
1997
Craig Mautner8e569572013-10-11 17:36:59 -07001998 boolean handleAppDiedLocked(ProcessRecord app) {
Craig Mautner19091252013-10-05 00:03:53 -07001999 boolean hasVisibleActivities = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002000 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2001 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002002 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2003 hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app);
2004 }
Craig Mautner6b74cb52013-09-27 17:02:21 -07002005 }
Craig Mautner19091252013-10-05 00:03:53 -07002006 return hasVisibleActivities;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002007 }
2008
2009 void closeSystemDialogsLocked() {
Craig Mautnere0a38842013-12-16 16:14:02 -08002010 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2011 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002012 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2013 stacks.get(stackNdx).closeSystemDialogsLocked();
2014 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002015 }
2016 }
2017
Craig Mautner93529a42013-10-04 15:03:13 -07002018 void removeUserLocked(int userId) {
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002019 mUserStackInFront.delete(userId);
Craig Mautner93529a42013-10-04 15:03:13 -07002020 }
2021
Craig Mautner8d341ef2013-03-26 09:03:27 -07002022 /**
2023 * @return true if some activity was finished (or would have finished if doit were true).
2024 */
2025 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
2026 boolean didSomething = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002027 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2028 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002029 final int numStacks = stacks.size();
2030 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2031 final ActivityStack stack = stacks.get(stackNdx);
2032 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
2033 didSomething = true;
2034 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002035 }
2036 }
2037 return didSomething;
2038 }
2039
Dianne Hackborna413dc02013-07-12 12:02:55 -07002040 void updatePreviousProcessLocked(ActivityRecord r) {
2041 // Now that this process has stopped, we may want to consider
2042 // it to be the previous app to try to keep around in case
2043 // the user wants to return to it.
2044
2045 // First, found out what is currently the foreground app, so that
2046 // we don't blow away the previous app if this activity is being
2047 // hosted by the process that is actually still the foreground.
2048 ProcessRecord fgApp = null;
Craig Mautnere0a38842013-12-16 16:14:02 -08002049 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2050 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002051 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2052 final ActivityStack stack = stacks.get(stackNdx);
2053 if (isFrontStack(stack)) {
2054 if (stack.mResumedActivity != null) {
2055 fgApp = stack.mResumedActivity.app;
2056 } else if (stack.mPausingActivity != null) {
2057 fgApp = stack.mPausingActivity.app;
2058 }
2059 break;
Dianne Hackborna413dc02013-07-12 12:02:55 -07002060 }
Dianne Hackborna413dc02013-07-12 12:02:55 -07002061 }
2062 }
2063
2064 // Now set this one as the previous process, only if that really
2065 // makes sense to.
2066 if (r.app != null && fgApp != null && r.app != fgApp
2067 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
Craig Mautner4ef26932013-09-18 15:15:52 -07002068 && r.app != mService.mHomeProcess) {
Dianne Hackborna413dc02013-07-12 12:02:55 -07002069 mService.mPreviousProcess = r.app;
2070 mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
2071 }
2072 }
2073
Craig Mautner05d29032013-05-03 13:40:13 -07002074 boolean resumeTopActivitiesLocked() {
2075 return resumeTopActivitiesLocked(null, null, null);
2076 }
2077
2078 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
2079 Bundle targetOptions) {
2080 if (targetStack == null) {
2081 targetStack = getFocusedStack();
2082 }
Craig Mautner12ff7392014-02-21 21:08:00 -08002083 // Do targetStack first.
Craig Mautner05d29032013-05-03 13:40:13 -07002084 boolean result = false;
Craig Mautner12ff7392014-02-21 21:08:00 -08002085 if (isFrontStack(targetStack)) {
2086 result = targetStack.resumeTopActivityLocked(target, targetOptions);
2087 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002088 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2089 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002090 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2091 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautner12ff7392014-02-21 21:08:00 -08002092 if (stack == targetStack) {
2093 // Already started above.
2094 continue;
2095 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002096 if (isFrontStack(stack)) {
Craig Mautner12ff7392014-02-21 21:08:00 -08002097 stack.resumeTopActivityLocked(null);
Craig Mautner05d29032013-05-03 13:40:13 -07002098 }
Craig Mautnerf88c50f2013-04-18 19:25:12 -07002099 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002100 }
Craig Mautner05d29032013-05-03 13:40:13 -07002101 return result;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002102 }
2103
2104 void finishTopRunningActivityLocked(ProcessRecord app) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002105 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2106 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002107 final int numStacks = stacks.size();
2108 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2109 final ActivityStack stack = stacks.get(stackNdx);
2110 stack.finishTopRunningActivityLocked(app);
2111 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002112 }
2113 }
2114
Craig Mautner8d341ef2013-03-26 09:03:27 -07002115 void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002116 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2117 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002118 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2119 if (stacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) {
2120 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack="
2121 + stacks.get(stackNdx));
2122 return;
2123 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002124 }
2125 }
2126 }
2127
Craig Mautner967212c2013-04-13 21:10:58 -07002128 ActivityStack getStack(int stackId) {
Craig Mautnerf4c909b2014-04-17 18:39:38 -07002129 ActivityContainer activityContainer = mActivityContainers.get(stackId);
2130 if (activityContainer != null) {
2131 return activityContainer.mStack;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002132 }
2133 return null;
2134 }
2135
Craig Mautner967212c2013-04-13 21:10:58 -07002136 ArrayList<ActivityStack> getStacks() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002137 ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>();
Craig Mautnere0a38842013-12-16 16:14:02 -08002138 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2139 allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002140 }
2141 return allStacks;
Craig Mautner967212c2013-04-13 21:10:58 -07002142 }
2143
Craig Mautner4a1cb222013-12-04 16:14:06 -08002144 IBinder getHomeActivityToken() {
2145 final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
2146 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
2147 final TaskRecord task = tasks.get(taskNdx);
2148 if (task.isHomeTask()) {
2149 final ArrayList<ActivityRecord> activities = task.mActivities;
2150 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2151 final ActivityRecord r = activities.get(activityNdx);
2152 if (r.isHomeActivity()) {
2153 return r.appToken;
2154 }
2155 }
2156 }
2157 }
2158 return null;
2159 }
2160
Craig Mautnerf4c909b2014-04-17 18:39:38 -07002161 ActivityContainer createActivityContainer(ActivityRecord parentActivity,
Craig Mautner4a1cb222013-12-04 16:14:06 -08002162 IActivityContainerCallback callback) {
Craig Mautnerf4c909b2014-04-17 18:39:38 -07002163 ActivityContainer activityContainer = new VirtualActivityContainer(parentActivity, callback);
2164 mActivityContainers.put(activityContainer.mStackId, activityContainer);
2165 parentActivity.mChildContainers.add(activityContainer);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002166 return activityContainer;
2167 }
2168
Craig Mautner34b73df2014-01-12 21:11:08 -08002169 void removeChildActivityContainers(ActivityRecord parentActivity) {
Craig Mautnerf4c909b2014-04-17 18:39:38 -07002170 final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers;
2171 for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) {
2172 ActivityContainer container = childStacks.remove(containerNdx);
2173 container.release();
Craig Mautner34b73df2014-01-12 21:11:08 -08002174 }
2175 }
2176
Craig Mautner95da1082014-02-24 17:54:35 -08002177 void deleteActivityContainer(IActivityContainer container) {
2178 ActivityContainer activityContainer = (ActivityContainer)container;
2179 if (activityContainer != null) {
Craig Mautnerf4c909b2014-04-17 18:39:38 -07002180 activityContainer.mStack.finishAllActivitiesLocked();
Craig Mautner95da1082014-02-24 17:54:35 -08002181 final ActivityRecord parent = activityContainer.mParentActivity;
2182 if (parent != null) {
2183 parent.mChildContainers.remove(activityContainer);
2184 }
2185 final int stackId = activityContainer.mStackId;
2186 mActivityContainers.remove(stackId);
2187 mWindowManager.removeStack(stackId);
2188 }
2189 }
2190
Craig Mautnerf4c909b2014-04-17 18:39:38 -07002191 private int createStackOnDisplay(int stackId, int displayId) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002192 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2193 if (activityDisplay == null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002194 return -1;
2195 }
2196
Craig Mautnerf4c909b2014-04-17 18:39:38 -07002197 ActivityContainer activityContainer = new ActivityContainer(stackId);
2198 mActivityContainers.put(stackId, activityContainer);
Craig Mautnere0a38842013-12-16 16:14:02 -08002199 activityContainer.attachToDisplayLocked(activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002200 return stackId;
2201 }
2202
2203 int getNextStackId() {
Craig Mautner858d8a62013-04-23 17:08:34 -07002204 while (true) {
2205 if (++mLastStackId <= HOME_STACK_ID) {
2206 mLastStackId = HOME_STACK_ID + 1;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002207 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002208 if (getStack(mLastStackId) == null) {
2209 break;
2210 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002211 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002212 return mLastStackId;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002213 }
2214
2215 void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002216 final TaskRecord task = anyTaskForIdLocked(taskId);
2217 if (task == null) {
2218 return;
2219 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002220 final ActivityStack stack = getStack(stackId);
2221 if (stack == null) {
2222 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
2223 return;
2224 }
Craig Mautner04a0ea62014-01-13 12:51:26 -08002225 task.stack.removeTask(task);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002226 stack.addTask(task, toTop);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002227 mWindowManager.addTask(taskId, stackId, toTop);
Craig Mautner05d29032013-05-03 13:40:13 -07002228 resumeTopActivitiesLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002229 }
2230
Craig Mautnerac6f8432013-07-17 13:24:59 -07002231 ActivityRecord findTaskLocked(ActivityRecord r) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07002232 if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r);
Craig Mautnere0a38842013-12-16 16:14:02 -08002233 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2234 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002235 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2236 final ActivityStack stack = stacks.get(stackNdx);
2237 if (!r.isApplicationActivity() && !stack.isHomeStack()) {
2238 if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: " + stack);
2239 continue;
2240 }
2241 final ActivityRecord ar = stack.findTaskLocked(r);
2242 if (ar != null) {
2243 return ar;
2244 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07002245 }
2246 }
Dianne Hackborn2a272d42013-10-16 13:34:33 -07002247 if (DEBUG_TASKS) Slog.d(TAG, "No task found");
Craig Mautner8849a5e2013-04-02 16:41:03 -07002248 return null;
2249 }
2250
2251 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002252 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2253 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002254 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2255 final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info);
2256 if (ar != null) {
2257 return ar;
2258 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07002259 }
2260 }
2261 return null;
2262 }
2263
Craig Mautner8d341ef2013-03-26 09:03:27 -07002264 void goingToSleepLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002265 scheduleSleepTimeout();
2266 if (!mGoingToSleep.isHeld()) {
2267 mGoingToSleep.acquire();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002268 if (mLaunchingActivity.isHeld()) {
2269 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2270 throw new IllegalStateException("Calling must be system uid");
Craig Mautner0eea92c2013-05-16 13:35:39 -07002271 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002272 mLaunchingActivity.release();
2273 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
Craig Mautner0eea92c2013-05-16 13:35:39 -07002274 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002275 }
Amith Yamasanice15e152013-09-19 12:30:32 -07002276 checkReadyForSleepLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002277 }
2278
2279 boolean shutdownLocked(int timeout) {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002280 goingToSleepLocked();
Craig Mautner0eea92c2013-05-16 13:35:39 -07002281
Craig Mautnerf4c909b2014-04-17 18:39:38 -07002282 boolean timedout = false;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002283 final long endTime = System.currentTimeMillis() + timeout;
2284 while (true) {
2285 boolean cantShutdown = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002286 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2287 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002288 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2289 cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
2290 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002291 }
2292 if (cantShutdown) {
2293 long timeRemaining = endTime - System.currentTimeMillis();
2294 if (timeRemaining > 0) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002295 try {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002296 mService.wait(timeRemaining);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002297 } catch (InterruptedException e) {
2298 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002299 } else {
2300 Slog.w(TAG, "Activity manager shutdown timed out");
2301 timedout = true;
2302 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002303 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002304 } else {
2305 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002306 }
2307 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002308
2309 // Force checkReadyForSleep to complete.
2310 mSleepTimeout = true;
2311 checkReadyForSleepLocked();
2312
Craig Mautner8d341ef2013-03-26 09:03:27 -07002313 return timedout;
2314 }
2315
2316 void comeOutOfSleepIfNeededLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002317 removeSleepTimeouts();
2318 if (mGoingToSleep.isHeld()) {
2319 mGoingToSleep.release();
2320 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002321 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2322 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002323 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2324 final ActivityStack stack = stacks.get(stackNdx);
2325 stack.awakeFromSleepingLocked();
2326 if (isFrontStack(stack)) {
2327 resumeTopActivitiesLocked();
2328 }
Craig Mautner5314a402013-09-26 12:40:16 -07002329 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002330 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002331 mGoingToSleepActivities.clear();
2332 }
2333
2334 void activitySleptLocked(ActivityRecord r) {
2335 mGoingToSleepActivities.remove(r);
2336 checkReadyForSleepLocked();
2337 }
2338
2339 void checkReadyForSleepLocked() {
2340 if (!mService.isSleepingOrShuttingDown()) {
2341 // Do not care.
2342 return;
2343 }
2344
2345 if (!mSleepTimeout) {
2346 boolean dontSleep = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002347 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2348 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002349 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2350 dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
2351 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002352 }
2353
2354 if (mStoppingActivities.size() > 0) {
2355 // Still need to tell some activities to stop; can't sleep yet.
2356 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2357 + mStoppingActivities.size() + " activities");
2358 scheduleIdleLocked();
2359 dontSleep = true;
2360 }
2361
2362 if (mGoingToSleepActivities.size() > 0) {
2363 // Still need to tell some activities to sleep; can't sleep yet.
2364 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2365 + mGoingToSleepActivities.size() + " activities");
2366 dontSleep = true;
2367 }
2368
2369 if (dontSleep) {
2370 return;
2371 }
2372 }
2373
Craig Mautnere0a38842013-12-16 16:14:02 -08002374 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2375 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002376 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2377 stacks.get(stackNdx).goToSleep();
2378 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002379 }
2380
2381 removeSleepTimeouts();
2382
2383 if (mGoingToSleep.isHeld()) {
2384 mGoingToSleep.release();
2385 }
2386 if (mService.mShuttingDown) {
2387 mService.notifyAll();
2388 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002389 }
2390
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002391 boolean reportResumedActivityLocked(ActivityRecord r) {
2392 final ActivityStack stack = r.task.stack;
2393 if (isFrontStack(stack)) {
Jeff Sharkey5782da72013-04-25 14:32:30 -07002394 mService.updateUsageStats(r, true);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002395 }
2396 if (allResumedActivitiesComplete()) {
2397 ensureActivitiesVisibleLocked(null, 0);
2398 mWindowManager.executeAppTransition();
2399 return true;
2400 }
2401 return false;
2402 }
2403
Craig Mautner8d341ef2013-03-26 09:03:27 -07002404 void handleAppCrashLocked(ProcessRecord app) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002405 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2406 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002407 final int numStacks = stacks.size();
2408 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2409 final ActivityStack stack = stacks.get(stackNdx);
2410 stack.handleAppCrashLocked(app);
2411 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002412 }
2413 }
2414
Craig Mautnerde4ef022013-04-07 19:01:33 -07002415 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
Craig Mautner580ea812013-04-25 12:58:38 -07002416 // First the front stacks. In case any are not fullscreen and are in front of home.
2417 boolean showHomeBehindStack = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002418 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2419 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002420 final int topStackNdx = stacks.size() - 1;
2421 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
2422 final ActivityStack stack = stacks.get(stackNdx);
2423 if (stackNdx == topStackNdx) {
2424 // Top stack.
2425 showHomeBehindStack =
2426 stack.ensureActivitiesVisibleLocked(starting, configChanges);
2427 } else {
2428 // Back stack.
2429 stack.ensureActivitiesVisibleLocked(starting, configChanges,
2430 showHomeBehindStack);
2431 }
Craig Mautner580ea812013-04-25 12:58:38 -07002432 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002433 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002434 }
2435
2436 void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002437 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2438 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002439 final int numStacks = stacks.size();
2440 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2441 final ActivityStack stack = stacks.get(stackNdx);
2442 stack.scheduleDestroyActivities(app, false, reason);
2443 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002444 }
2445 }
2446
2447 boolean switchUserLocked(int userId, UserStartedState uss) {
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002448 mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId());
2449 final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
Craig Mautner2420ead2013-04-01 17:13:20 -07002450 mCurrentUser = userId;
Craig Mautnerac6f8432013-07-17 13:24:59 -07002451
Craig Mautner858d8a62013-04-23 17:08:34 -07002452 mStartingUsers.add(uss);
Craig Mautnere0a38842013-12-16 16:14:02 -08002453 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2454 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002455 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002456 final ActivityStack stack = stacks.get(stackNdx);
2457 stack.switchUserLocked(userId);
2458 mWindowManager.moveTaskToTop(stack.topTask().taskId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002459 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07002460 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002461
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002462 ActivityStack stack = getStack(restoreStackId);
2463 if (stack == null) {
2464 stack = mHomeStack;
2465 }
2466 final boolean homeInFront = stack.isHomeStack();
Craig Mautnere0a38842013-12-16 16:14:02 -08002467 if (stack.isOnHomeDisplay()) {
2468 moveHomeStack(homeInFront);
2469 mWindowManager.moveTaskToTop(stack.topTask().taskId);
2470 } else {
2471 // Stack was moved to another display while user was swapped out.
2472 resumeHomeActivity(null);
2473 }
Craig Mautner93529a42013-10-04 15:03:13 -07002474 return homeInFront;
Craig Mautner2219a1b2013-03-25 09:44:30 -07002475 }
2476
Craig Mautnerde4ef022013-04-07 19:01:33 -07002477 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2478 int N = mStoppingActivities.size();
2479 if (N <= 0) return null;
2480
2481 ArrayList<ActivityRecord> stops = null;
2482
2483 final boolean nowVisible = allResumedActivitiesVisible();
2484 for (int i=0; i<N; i++) {
2485 ActivityRecord s = mStoppingActivities.get(i);
Craig Mautnera7f2bd42013-10-15 16:13:50 -07002486 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
Craig Mautnerde4ef022013-04-07 19:01:33 -07002487 + nowVisible + " waitingVisible=" + s.waitingVisible
2488 + " finishing=" + s.finishing);
2489 if (s.waitingVisible && nowVisible) {
2490 mWaitingVisibleActivities.remove(s);
2491 s.waitingVisible = false;
2492 if (s.finishing) {
2493 // If this activity is finishing, it is sitting on top of
2494 // everyone else but we now know it is no longer needed...
2495 // so get rid of it. Otherwise, we need to go through the
2496 // normal flow and hide it once we determine that it is
2497 // hidden by the activities in front of it.
2498 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002499 mWindowManager.setAppVisibility(s.appToken, false);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002500 }
2501 }
2502 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2503 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2504 if (stops == null) {
2505 stops = new ArrayList<ActivityRecord>();
2506 }
2507 stops.add(s);
2508 mStoppingActivities.remove(i);
2509 N--;
2510 i--;
2511 }
2512 }
2513
2514 return stops;
2515 }
2516
Craig Mautnercf910b02013-04-23 11:23:27 -07002517 void validateTopActivitiesLocked() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002518 // FIXME
2519/* for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2520 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautnercf910b02013-04-23 11:23:27 -07002521 final ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002522 final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
Craig Mautnercf910b02013-04-23 11:23:27 -07002523 if (isFrontStack(stack)) {
2524 if (r == null) {
2525 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2526 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002527 final ActivityRecord pausing = stack.mPausingActivity;
2528 if (pausing != null && pausing == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002529 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002530 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002531 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002532 if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002533 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002534 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002535 }
2536 }
2537 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002538 final ActivityRecord resumed = stack.mResumedActivity;
2539 if (resumed != null && resumed == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002540 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002541 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002542 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002543 if (r != null && (state == ActivityState.INITIALIZING
2544 || state == ActivityState.RESUMED)) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002545 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002546 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002547 }
2548 }
2549 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002550*/
Craig Mautner76ea2242013-05-15 11:40:05 -07002551 }
2552
Craig Mautner27084302013-03-25 08:05:25 -07002553 public void dump(PrintWriter pw, String prefix) {
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002554 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity=");
Craig Mautner27084302013-03-25 08:05:25 -07002555 pw.println(mDismissKeyguardOnNextActivity);
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002556 pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002557 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002558 pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
2559 pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
2560 pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
Craig Mautner95da1082014-02-24 17:54:35 -08002561 pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
Craig Mautner27084302013-03-25 08:05:25 -07002562 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002563
Craig Mautner20e72272013-04-01 13:45:53 -07002564 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002565 return getFocusedStack().getDumpActivitiesLocked(name);
Craig Mautner20e72272013-04-01 13:45:53 -07002566 }
2567
Dianne Hackborn390517b2013-05-30 15:03:32 -07002568 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2569 boolean needSep, String prefix) {
2570 if (activity != null) {
2571 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2572 if (needSep) {
2573 pw.println();
Dianne Hackborn390517b2013-05-30 15:03:32 -07002574 }
2575 pw.print(prefix);
2576 pw.println(activity);
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002577 return true;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002578 }
2579 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002580 return false;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002581 }
2582
Craig Mautner8d341ef2013-03-26 09:03:27 -07002583 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2584 boolean dumpClient, String dumpPackage) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002585 boolean printed = false;
2586 boolean needSep = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002587 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2588 ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
2589 pw.print("Display #"); pw.println(activityDisplay.mDisplayId);
2590 ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002591 final int numStacks = stacks.size();
2592 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2593 final ActivityStack stack = stacks.get(stackNdx);
2594 StringBuilder stackHeader = new StringBuilder(128);
2595 stackHeader.append(" Stack #");
2596 stackHeader.append(stack.mStackId);
2597 stackHeader.append(":");
2598 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
2599 needSep, stackHeader.toString());
2600 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false,
2601 !dumpAll, false, dumpPackage, true,
2602 " Running activities (most recent first):", null);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002603
Craig Mautner4a1cb222013-12-04 16:14:06 -08002604 needSep = printed;
2605 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
2606 " mPausingActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002607 if (pr) {
2608 printed = true;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002609 needSep = false;
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002610 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002611 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
2612 " mResumedActivity: ");
2613 if (pr) {
2614 printed = true;
2615 needSep = false;
2616 }
2617 if (dumpAll) {
2618 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
2619 " mLastPausedActivity: ");
2620 if (pr) {
2621 printed = true;
2622 needSep = true;
2623 }
2624 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
2625 needSep, " mLastNoHistoryActivity: ");
2626 }
2627 needSep = printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002628 }
2629 }
2630
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002631 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll,
2632 false, dumpPackage, true, " Activities waiting to finish:", null);
2633 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll,
2634 false, dumpPackage, true, " Activities waiting to stop:", null);
2635 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll,
2636 false, dumpPackage, true, " Activities waiting for another to become visible:",
2637 null);
2638 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2639 false, dumpPackage, true, " Activities waiting to sleep:", null);
2640 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2641 false, dumpPackage, true, " Activities waiting to sleep:", null);
Craig Mautnerf3333272013-04-22 10:55:53 -07002642
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002643 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002644 }
2645
Dianne Hackborn390517b2013-05-30 15:03:32 -07002646 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
Craig Mautner8d341ef2013-03-26 09:03:27 -07002647 String prefix, String label, boolean complete, boolean brief, boolean client,
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002648 String dumpPackage, boolean needNL, String header1, String header2) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002649 TaskRecord lastTask = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002650 String innerPrefix = null;
2651 String[] args = null;
2652 boolean printed = false;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002653 for (int i=list.size()-1; i>=0; i--) {
2654 final ActivityRecord r = list.get(i);
2655 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2656 continue;
2657 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002658 if (innerPrefix == null) {
2659 innerPrefix = prefix + " ";
2660 args = new String[0];
2661 }
2662 printed = true;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002663 final boolean full = !brief && (complete || !r.isInHistory());
2664 if (needNL) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07002665 pw.println("");
Craig Mautner8d341ef2013-03-26 09:03:27 -07002666 needNL = false;
2667 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002668 if (header1 != null) {
2669 pw.println(header1);
2670 header1 = null;
2671 }
2672 if (header2 != null) {
2673 pw.println(header2);
2674 header2 = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002675 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002676 if (lastTask != r.task) {
2677 lastTask = r.task;
2678 pw.print(prefix);
2679 pw.print(full ? "* " : " ");
2680 pw.println(lastTask);
2681 if (full) {
2682 lastTask.dump(pw, prefix + " ");
2683 } else if (complete) {
2684 // Complete + brief == give a summary. Isn't that obvious?!?
2685 if (lastTask.intent != null) {
2686 pw.print(prefix); pw.print(" ");
2687 pw.println(lastTask.intent.toInsecureStringWithClip());
2688 }
2689 }
2690 }
2691 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
2692 pw.print(" #"); pw.print(i); pw.print(": ");
2693 pw.println(r);
2694 if (full) {
2695 r.dump(pw, innerPrefix);
2696 } else if (complete) {
2697 // Complete + brief == give a summary. Isn't that obvious?!?
2698 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2699 if (r.app != null) {
2700 pw.print(innerPrefix); pw.println(r.app);
2701 }
2702 }
2703 if (client && r.app != null && r.app.thread != null) {
2704 // flush anything that is already in the PrintWriter since the thread is going
2705 // to write to the file descriptor directly
2706 pw.flush();
2707 try {
2708 TransferPipe tp = new TransferPipe();
2709 try {
2710 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2711 r.appToken, innerPrefix, args);
2712 // Short timeout, since blocking here can
2713 // deadlock with the application.
2714 tp.go(fd, 2000);
2715 } finally {
2716 tp.kill();
2717 }
2718 } catch (IOException e) {
2719 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2720 } catch (RemoteException e) {
2721 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2722 }
2723 needNL = true;
2724 }
2725 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002726 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002727 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002728
Craig Mautnerf3333272013-04-22 10:55:53 -07002729 void scheduleIdleTimeoutLocked(ActivityRecord next) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002730 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
Craig Mautnerc64f73e2013-04-24 16:44:56 -07002731 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2732 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
Craig Mautnerf3333272013-04-22 10:55:53 -07002733 }
2734
2735 final void scheduleIdleLocked() {
Craig Mautner05d29032013-05-03 13:40:13 -07002736 mHandler.sendEmptyMessage(IDLE_NOW_MSG);
Craig Mautnerf3333272013-04-22 10:55:53 -07002737 }
2738
2739 void removeTimeoutsForActivityLocked(ActivityRecord r) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002740 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07002741 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2742 }
2743
Craig Mautner05d29032013-05-03 13:40:13 -07002744 final void scheduleResumeTopActivities() {
Craig Mautner34b73df2014-01-12 21:11:08 -08002745 if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
2746 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2747 }
Craig Mautner05d29032013-05-03 13:40:13 -07002748 }
2749
Craig Mautner0eea92c2013-05-16 13:35:39 -07002750 void removeSleepTimeouts() {
2751 mSleepTimeout = false;
2752 mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2753 }
2754
2755 final void scheduleSleepTimeout() {
2756 removeSleepTimeouts();
2757 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2758 }
2759
Craig Mautner4a1cb222013-12-04 16:14:06 -08002760 @Override
2761 public void onDisplayAdded(int displayId) {
2762 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
2763 }
2764
2765 @Override
2766 public void onDisplayRemoved(int displayId) {
2767 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
2768 }
2769
2770 @Override
2771 public void onDisplayChanged(int displayId) {
2772 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
2773 }
2774
2775 public void handleDisplayAddedLocked(int displayId) {
Craig Mautner4504de52013-12-20 09:06:56 -08002776 boolean newDisplay;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002777 synchronized (mService) {
Craig Mautner4504de52013-12-20 09:06:56 -08002778 newDisplay = mActivityDisplays.get(displayId) == null;
2779 if (newDisplay) {
2780 ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
2781 mActivityDisplays.put(displayId, activityDisplay);
2782 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002783 }
Craig Mautner4504de52013-12-20 09:06:56 -08002784 if (newDisplay) {
2785 mWindowManager.onDisplayAdded(displayId);
2786 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002787 }
2788
2789 public void handleDisplayRemovedLocked(int displayId) {
2790 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002791 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2792 if (activityDisplay != null) {
2793 ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002794 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner34b73df2014-01-12 21:11:08 -08002795 stacks.get(stackNdx).mActivityContainer.detachLocked();
Craig Mautner4a1cb222013-12-04 16:14:06 -08002796 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002797 mActivityDisplays.remove(displayId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002798 }
2799 }
2800 mWindowManager.onDisplayRemoved(displayId);
2801 }
2802
2803 public void handleDisplayChangedLocked(int displayId) {
2804 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002805 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2806 if (activityDisplay != null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002807 // TODO: Update the bounds.
2808 }
2809 }
2810 mWindowManager.onDisplayChanged(displayId);
2811 }
2812
2813 StackInfo getStackInfo(ActivityStack stack) {
2814 StackInfo info = new StackInfo();
2815 mWindowManager.getStackBounds(stack.mStackId, info.bounds);
2816 info.displayId = Display.DEFAULT_DISPLAY;
2817 info.stackId = stack.mStackId;
2818
2819 ArrayList<TaskRecord> tasks = stack.getAllTasks();
2820 final int numTasks = tasks.size();
2821 int[] taskIds = new int[numTasks];
2822 String[] taskNames = new String[numTasks];
2823 for (int i = 0; i < numTasks; ++i) {
2824 final TaskRecord task = tasks.get(i);
2825 taskIds[i] = task.taskId;
2826 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
2827 : task.realActivity != null ? task.realActivity.flattenToString()
2828 : task.getTopActivity() != null ? task.getTopActivity().packageName
2829 : "unknown";
2830 }
2831 info.taskIds = taskIds;
2832 info.taskNames = taskNames;
2833 return info;
2834 }
2835
2836 StackInfo getStackInfoLocked(int stackId) {
2837 ActivityStack stack = getStack(stackId);
2838 if (stack != null) {
2839 return getStackInfo(stack);
2840 }
2841 return null;
2842 }
2843
2844 ArrayList<StackInfo> getAllStackInfosLocked() {
2845 ArrayList<StackInfo> list = new ArrayList<StackInfo>();
Craig Mautnere0a38842013-12-16 16:14:02 -08002846 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2847 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002848 for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
2849 list.add(getStackInfo(stacks.get(ndx)));
2850 }
2851 }
2852 return list;
2853 }
2854
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002855 private final class ActivityStackSupervisorHandler extends Handler {
Craig Mautnerf3333272013-04-22 10:55:53 -07002856
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002857 public ActivityStackSupervisorHandler(Looper looper) {
2858 super(looper);
2859 }
2860
Craig Mautnerf3333272013-04-22 10:55:53 -07002861 void activityIdleInternal(ActivityRecord r) {
2862 synchronized (mService) {
2863 activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
2864 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002865 }
2866
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002867 @Override
2868 public void handleMessage(Message msg) {
2869 switch (msg.what) {
Craig Mautnerf3333272013-04-22 10:55:53 -07002870 case IDLE_TIMEOUT_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002871 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002872 if (mService.mDidDexOpt) {
2873 mService.mDidDexOpt = false;
2874 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2875 nmsg.obj = msg.obj;
2876 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
2877 return;
2878 }
2879 // We don't at this point know if the activity is fullscreen,
2880 // so we need to be conservative and assume it isn't.
2881 activityIdleInternal((ActivityRecord)msg.obj);
2882 } break;
2883 case IDLE_NOW_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002884 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002885 activityIdleInternal((ActivityRecord)msg.obj);
2886 } break;
Craig Mautner05d29032013-05-03 13:40:13 -07002887 case RESUME_TOP_ACTIVITY_MSG: {
2888 synchronized (mService) {
2889 resumeTopActivitiesLocked();
2890 }
2891 } break;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002892 case SLEEP_TIMEOUT_MSG: {
2893 synchronized (mService) {
2894 if (mService.isSleepingOrShuttingDown()) {
2895 Slog.w(TAG, "Sleep timeout! Sleeping now.");
2896 mSleepTimeout = true;
2897 checkReadyForSleepLocked();
2898 }
2899 }
2900 } break;
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002901 case LAUNCH_TIMEOUT_MSG: {
2902 if (mService.mDidDexOpt) {
2903 mService.mDidDexOpt = false;
2904 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
2905 return;
2906 }
2907 synchronized (mService) {
2908 if (mLaunchingActivity.isHeld()) {
2909 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
2910 if (VALIDATE_WAKE_LOCK_CALLER
2911 && Binder.getCallingUid() != Process.myUid()) {
2912 throw new IllegalStateException("Calling must be system uid");
2913 }
2914 mLaunchingActivity.release();
2915 }
2916 }
2917 } break;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002918 case HANDLE_DISPLAY_ADDED: {
2919 handleDisplayAddedLocked(msg.arg1);
2920 } break;
2921 case HANDLE_DISPLAY_CHANGED: {
2922 handleDisplayChangedLocked(msg.arg1);
2923 } break;
2924 case HANDLE_DISPLAY_REMOVED: {
2925 handleDisplayRemovedLocked(msg.arg1);
2926 } break;
Craig Mautnere3a00d72014-04-16 08:31:19 -07002927 case CONTAINER_CALLBACK_VISIBILITY: {
2928 final ActivityContainer container = (ActivityContainer) msg.obj;
2929 try {
2930 // We only send this message if mCallback is non-null.
2931 container.mCallback.setVisible(container.asBinder(), msg.arg1 == 1);
2932 } catch (RemoteException e) {
2933 }
2934 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002935 }
2936 }
2937 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08002938
Craig Mautner4a1cb222013-12-04 16:14:06 -08002939 class ActivityContainer extends IActivityContainer.Stub {
2940 final int mStackId;
Craig Mautnerf4c909b2014-04-17 18:39:38 -07002941 IActivityContainerCallback mCallback = null;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002942 final ActivityStack mStack;
Craig Mautnerf4c909b2014-04-17 18:39:38 -07002943 ActivityRecord mParentActivity = null;
2944 String mIdString;
Craig Mautnerbdc748af2013-12-02 14:08:25 -08002945
Craig Mautnere3a00d72014-04-16 08:31:19 -07002946 boolean mVisible = true;
2947
Craig Mautner4a1cb222013-12-04 16:14:06 -08002948 /** Display this ActivityStack is currently on. Null if not attached to a Display. */
Craig Mautnere0a38842013-12-16 16:14:02 -08002949 ActivityDisplay mActivityDisplay;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002950
Craig Mautnerf4c909b2014-04-17 18:39:38 -07002951 final static int CONTAINER_STATE_HAS_SURFACE = 0;
2952 final static int CONTAINER_STATE_NO_SURFACE = 1;
2953 final static int CONTAINER_STATE_FINISHING = 2;
2954 int mContainerState = CONTAINER_STATE_HAS_SURFACE;
2955
2956 ActivityContainer(int stackId) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002957 synchronized (mService) {
2958 mStackId = stackId;
2959 mStack = new ActivityStack(this);
Craig Mautnerf4c909b2014-04-17 18:39:38 -07002960 mIdString = "ActivtyContainer{" + mStackId + "}";
Craig Mautner34b73df2014-01-12 21:11:08 -08002961 if (DEBUG_STACK) Slog.d(TAG, "Creating " + this);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002962 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08002963 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002964
Craig Mautnere0a38842013-12-16 16:14:02 -08002965 void attachToDisplayLocked(ActivityDisplay activityDisplay) {
Craig Mautner34b73df2014-01-12 21:11:08 -08002966 if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this
2967 + " to display=" + activityDisplay);
Craig Mautnere0a38842013-12-16 16:14:02 -08002968 mActivityDisplay = activityDisplay;
2969 mStack.mDisplayId = activityDisplay.mDisplayId;
2970 mStack.mStacks = activityDisplay.mStacks;
2971
2972 activityDisplay.attachActivities(mStack);
Craig Mautnerdf88d732014-01-27 09:21:32 -08002973 mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002974 }
2975
2976 @Override
Jeff Brown38f96e52014-02-11 14:32:56 -08002977 public void attachToDisplay(int displayId) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002978 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002979 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2980 if (activityDisplay == null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002981 return;
2982 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002983 attachToDisplayLocked(activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002984 }
2985 }
2986
2987 @Override
Jeff Brown38f96e52014-02-11 14:32:56 -08002988 public int getDisplayId() {
Craig Mautnere0a38842013-12-16 16:14:02 -08002989 if (mActivityDisplay != null) {
2990 return mActivityDisplay.mDisplayId;
2991 }
2992 return -1;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002993 }
2994
Jeff Brown38f96e52014-02-11 14:32:56 -08002995 @Override
2996 public boolean injectEvent(InputEvent event) {
2997 final long origId = Binder.clearCallingIdentity();
2998 try {
2999 if (mActivityDisplay != null) {
3000 return mInputManagerInternal.injectInputEvent(event,
3001 mActivityDisplay.mDisplayId,
3002 InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
3003 }
3004 return false;
3005 } finally {
3006 Binder.restoreCallingIdentity(origId);
3007 }
3008 }
3009
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003010 @Override
3011 public void release() {
3012 mContainerState = CONTAINER_STATE_FINISHING;
3013 mStack.finishAllActivitiesLocked();
3014 detachLocked();
3015 mWindowManager.removeStack(mStackId);
3016 }
3017
Craig Mautner34b73df2014-01-12 21:11:08 -08003018 private void detachLocked() {
3019 if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display="
3020 + mActivityDisplay + " Callers=" + Debug.getCallers(2));
Craig Mautnere0a38842013-12-16 16:14:02 -08003021 if (mActivityDisplay != null) {
3022 mActivityDisplay.detachActivitiesLocked(mStack);
3023 mActivityDisplay = null;
3024 mStack.mDisplayId = -1;
3025 mStack.mStacks = null;
Craig Mautnerdf88d732014-01-27 09:21:32 -08003026 mWindowManager.detachStack(mStackId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003027 }
3028 }
3029
3030 @Override
Craig Mautnere0a38842013-12-16 16:14:02 -08003031 public final int startActivity(Intent intent) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08003032 mService.enforceNotIsolatedCaller("ActivityContainer.startActivity");
Craig Mautnere0a38842013-12-16 16:14:02 -08003033 int userId = mService.handleIncomingUser(Binder.getCallingPid(),
3034 Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null);
3035 // TODO: Switch to user app stacks here.
3036 String mimeType = intent.getType();
3037 if (mimeType == null && intent.getData() != null
3038 && "content".equals(intent.getData().getScheme())) {
3039 mimeType = mService.getProviderMimeType(intent.getData(), userId);
3040 }
3041 return startActivityMayWait(null, -1, null, intent, mimeType, null, null, 0, 0, null,
3042 null, null, null, null, userId, this);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003043 }
3044
3045 @Override
Craig Mautnerdf88d732014-01-27 09:21:32 -08003046 public final int startActivityIntentSender(IIntentSender intentSender) {
3047 mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
3048
3049 if (!(intentSender instanceof PendingIntentRecord)) {
3050 throw new IllegalArgumentException("Bad PendingIntent object");
3051 }
3052
3053 return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null,
3054 null, 0, 0, 0, null, this);
3055 }
3056
3057 @Override
Craig Mautner4a1cb222013-12-04 16:14:06 -08003058 public IBinder asBinder() {
3059 return this;
3060 }
3061
Craig Mautner4504de52013-12-20 09:06:56 -08003062 @Override
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003063 public void setSurface(Surface surface, int width, int height, int density) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08003064 mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
Craig Mautner4504de52013-12-20 09:06:56 -08003065 }
3066
Craig Mautner4a1cb222013-12-04 16:14:06 -08003067 ActivityStackSupervisor getOuter() {
3068 return ActivityStackSupervisor.this;
3069 }
3070
3071 boolean isAttached() {
Craig Mautnere0a38842013-12-16 16:14:02 -08003072 return mActivityDisplay != null;
Craig Mautner4a1cb222013-12-04 16:14:06 -08003073 }
3074
3075 void getBounds(Point outBounds) {
Craig Mautnere0a38842013-12-16 16:14:02 -08003076 if (mActivityDisplay != null) {
3077 mActivityDisplay.getBounds(outBounds);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003078 } else {
3079 outBounds.set(0, 0);
3080 }
3081 }
Craig Mautner34b73df2014-01-12 21:11:08 -08003082
Craig Mautnere3a00d72014-04-16 08:31:19 -07003083 void setVisible(boolean visible) {
3084 if (mVisible != visible) {
3085 mVisible = visible;
3086 if (mCallback != null) {
3087 mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0,
3088 0 /* unused */, this).sendToTarget();
3089 }
3090 }
3091 }
3092
Craig Mautner34b73df2014-01-12 21:11:08 -08003093 @Override
3094 public String toString() {
3095 return mIdString + (mActivityDisplay == null ? "N" : "A");
3096 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003097 }
3098
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003099 private class VirtualActivityContainer extends ActivityContainer {
3100 Surface mSurface;
3101
3102 VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) {
3103 super(getNextStackId());
3104 mParentActivity = parent;
3105 mCallback = callback;
3106 mContainerState = CONTAINER_STATE_NO_SURFACE;
3107 mIdString = "VirtualActivtyContainer{" + mStackId + ", parent=" + mParentActivity + "}";
3108 }
3109
3110 @Override
3111 public void setSurface(Surface surface, int width, int height, int density) {
3112 super.setSurface(surface, width, height, density);
3113
3114 synchronized (mService) {
3115 final long origId = Binder.clearCallingIdentity();
3116 try {
3117 setSurfaceLocked(surface, width, height, density);
3118 } finally {
3119 Binder.restoreCallingIdentity(origId);
3120 }
3121 }
3122 }
3123
3124 private void setSurfaceLocked(Surface surface, int width, int height, int density) {
3125 if (mContainerState == CONTAINER_STATE_FINISHING) {
3126 return;
3127 }
3128 VirtualActivityDisplay virtualActivityDisplay =
3129 (VirtualActivityDisplay) mActivityDisplay;
3130 if (virtualActivityDisplay == null) {
3131 virtualActivityDisplay =
3132 new VirtualActivityDisplay(surface, width, height, density);
3133 mActivityDisplay = virtualActivityDisplay;
3134 mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay);
3135 attachToDisplayLocked(virtualActivityDisplay);
3136 }
3137
3138 if (mSurface != null) {
3139 mSurface.release();
3140 mSurface = null;
3141 }
3142
3143 if (surface != null) {
3144 mContainerState = CONTAINER_STATE_HAS_SURFACE;
3145 mSurface = surface;
3146 mStack.resumeTopActivityLocked(null);
3147 } else {
3148 mContainerState = CONTAINER_STATE_NO_SURFACE;
3149 if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) {
3150 mStack.startPausingLocked(false, true);
3151 }
3152 }
3153 if (DEBUG_STACK) Slog.d(TAG, "setSurface: " + this + " to display="
3154 + virtualActivityDisplay);
3155
3156 virtualActivityDisplay.setSurface(surface);
3157 }
3158 }
3159
Craig Mautner4a1cb222013-12-04 16:14:06 -08003160 /** Exactly one of these classes per Display in the system. Capable of holding zero or more
3161 * attached {@link ActivityStack}s */
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003162 class ActivityDisplay {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003163 /** Actual Display this object tracks. */
Craig Mautner34b73df2014-01-12 21:11:08 -08003164 int mDisplayId;
3165 Display mDisplay;
3166 DisplayInfo mDisplayInfo = new DisplayInfo();
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003167
Craig Mautner4a1cb222013-12-04 16:14:06 -08003168 /** All of the stacks on this display. Order matters, topmost stack is in front of all other
3169 * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
Craig Mautnere0a38842013-12-16 16:14:02 -08003170 final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003171
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003172 ActivityDisplay() {
3173 }
Craig Mautner4504de52013-12-20 09:06:56 -08003174
Craig Mautnere0a38842013-12-16 16:14:02 -08003175 ActivityDisplay(int displayId) {
Craig Mautner34b73df2014-01-12 21:11:08 -08003176 init(mDisplayManager.getDisplay(displayId));
Craig Mautner4504de52013-12-20 09:06:56 -08003177 }
3178
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003179 void init(Display display) {
Craig Mautner4504de52013-12-20 09:06:56 -08003180 mDisplay = display;
3181 mDisplayId = display.getDisplayId();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003182 mDisplay.getDisplayInfo(mDisplayInfo);
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003183 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08003184
3185 void attachActivities(ActivityStack stack) {
Craig Mautnere0a38842013-12-16 16:14:02 -08003186 if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId="
3187 + mDisplayId);
3188 mStacks.add(stack);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003189 }
3190
Craig Mautnere0a38842013-12-16 16:14:02 -08003191 void detachActivitiesLocked(ActivityStack stack) {
Craig Mautner34b73df2014-01-12 21:11:08 -08003192 if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack
Craig Mautnere0a38842013-12-16 16:14:02 -08003193 + " from displayId=" + mDisplayId);
3194 mStacks.remove(stack);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003195 }
3196
3197 void getBounds(Point bounds) {
3198 mDisplay.getDisplayInfo(mDisplayInfo);
3199 bounds.x = mDisplayInfo.appWidth;
3200 bounds.y = mDisplayInfo.appHeight;
3201 }
Craig Mautner34b73df2014-01-12 21:11:08 -08003202
3203 @Override
3204 public String toString() {
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003205 return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}";
3206 }
3207 }
3208
3209 class VirtualActivityDisplay extends ActivityDisplay {
3210 VirtualDisplay mVirtualDisplay;
3211
3212 VirtualActivityDisplay(Surface surface, int width, int height, int density) {
3213 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
3214 mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, VIRTUAL_DISPLAY_BASE_NAME,
3215 width, height, density, surface, DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
3216 DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY);
3217
3218 init(mVirtualDisplay.getDisplay());
3219
3220 mWindowManager.handleDisplayAdded(mDisplayId);
3221 }
3222
3223 void setSurface(Surface surface) {
3224 if (mVirtualDisplay != null) {
3225 mVirtualDisplay.setSurface(surface);
3226 }
3227 }
3228
3229 @Override
3230 void detachActivitiesLocked(ActivityStack stack) {
3231 super.detachActivitiesLocked(stack);
3232 if (mVirtualDisplay != null) {
3233 mVirtualDisplay.release();
3234 mVirtualDisplay = null;
3235 }
3236 }
3237
3238 @Override
3239 public String toString() {
3240 return "VirtualActivityDisplay={" + mDisplayId + "}";
Craig Mautner34b73df2014-01-12 21:11:08 -08003241 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003242 }
Craig Mautner27084302013-03-25 08:05:25 -07003243}