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