blob: f609e7e6dfca5d2a076020a027d929a1cc3cd45f [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;
Craig Mautner23ac33b2013-04-01 16:26:35 -070064import android.os.Binder;
Craig Mautner8d341ef2013-03-26 09:03:27 -070065import android.os.Bundle;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -070066import android.os.Debug;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070067import android.os.Handler;
Craig Mautner23ac33b2013-04-01 16:26:35 -070068import android.os.IBinder;
Craig Mautner2219a1b2013-03-25 09:44:30 -070069import android.os.Looper;
Craig Mautner2420ead2013-04-01 17:13:20 -070070import android.os.Message;
Craig Mautner23ac33b2013-04-01 16:26:35 -070071import android.os.ParcelFileDescriptor;
Craig Mautner0eea92c2013-05-16 13:35:39 -070072import android.os.PowerManager;
Craig Mautner7ea5bd42013-07-05 15:27:08 -070073import android.os.Process;
Craig Mautner8d341ef2013-03-26 09:03:27 -070074import android.os.RemoteException;
Craig Mautner23ac33b2013-04-01 16:26:35 -070075import android.os.SystemClock;
Craig Mautner6170f732013-04-02 13:05:23 -070076import android.os.UserHandle;
Craig Mautner2420ead2013-04-01 17:13:20 -070077import android.util.EventLog;
Craig Mautner8d341ef2013-03-26 09:03:27 -070078import android.util.Slog;
Craig Mautner4a1cb222013-12-04 16:14:06 -080079import android.util.SparseArray;
Craig Mautner2219a1b2013-03-25 09:44:30 -070080
Craig Mautner4a1cb222013-12-04 16:14:06 -080081import android.util.SparseIntArray;
Craig Mautnerbdc748af2013-12-02 14:08:25 -080082import android.view.Display;
Craig Mautner4a1cb222013-12-04 16:14:06 -080083import android.view.DisplayInfo;
Craig Mautner4504de52013-12-20 09:06:56 -080084import android.view.Surface;
Craig Mautner23ac33b2013-04-01 16:26:35 -070085import com.android.internal.app.HeavyWeightSwitcherActivity;
Dianne Hackborncbfd23e2013-06-11 14:26:53 -070086import com.android.internal.os.TransferPipe;
Craig Mautner6170f732013-04-02 13:05:23 -070087import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
Craig Mautner2420ead2013-04-01 17:13:20 -070088import com.android.server.am.ActivityStack.ActivityState;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070089import com.android.server.wm.WindowManagerService;
Craig Mautner23ac33b2013-04-01 16:26:35 -070090
Craig Mautner8d341ef2013-03-26 09:03:27 -070091import java.io.FileDescriptor;
92import java.io.IOException;
Craig Mautner27084302013-03-25 08:05:25 -070093import java.io.PrintWriter;
Craig Mautner4504de52013-12-20 09:06:56 -080094import java.lang.ref.WeakReference;
Craig Mautner2219a1b2013-03-25 09:44:30 -070095import java.util.ArrayList;
Craig Mautner8d341ef2013-03-26 09:03:27 -070096import java.util.List;
Craig Mautner27084302013-03-25 08:05:25 -070097
Craig Mautner4a1cb222013-12-04 16:14:06 -080098public final class ActivityStackSupervisor implements DisplayListener {
Craig Mautnerde4ef022013-04-07 19:01:33 -070099 static final boolean DEBUG = ActivityManagerService.DEBUG || false;
100 static final boolean DEBUG_ADD_REMOVE = DEBUG || false;
101 static final boolean DEBUG_APP = DEBUG || false;
102 static final boolean DEBUG_SAVED_STATE = DEBUG || false;
Craig Mautnera7f2bd42013-10-15 16:13:50 -0700103 static final boolean DEBUG_STATES = DEBUG || false;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -0700104 static final boolean DEBUG_IDLE = DEBUG || false;
Craig Mautner2420ead2013-04-01 17:13:20 -0700105
Craig Mautner2219a1b2013-03-25 09:44:30 -0700106 public static final int HOME_STACK_ID = 0;
Craig Mautner27084302013-03-25 08:05:25 -0700107
Craig Mautnerf3333272013-04-22 10:55:53 -0700108 /** How long we wait until giving up on the last activity telling us it is idle. */
109 static final int IDLE_TIMEOUT = 10*1000;
110
Craig Mautner0eea92c2013-05-16 13:35:39 -0700111 /** How long we can hold the sleep wake lock before giving up. */
112 static final int SLEEP_TIMEOUT = 5*1000;
113
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700114 // How long we can hold the launch wake lock before giving up.
115 static final int LAUNCH_TIMEOUT = 10*1000;
116
Craig Mautner05d29032013-05-03 13:40:13 -0700117 static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG;
118 static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1;
119 static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2;
Craig Mautner0eea92c2013-05-16 13:35:39 -0700120 static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3;
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700121 static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800122 static final int HANDLE_DISPLAY_ADDED = FIRST_SUPERVISOR_STACK_MSG + 5;
123 static final int HANDLE_DISPLAY_CHANGED = FIRST_SUPERVISOR_STACK_MSG + 6;
124 static final int HANDLE_DISPLAY_REMOVED = FIRST_SUPERVISOR_STACK_MSG + 7;
125
Craig Mautner4504de52013-12-20 09:06:56 -0800126 private final static String VIRTUAL_DISPLAY_BASE_NAME = "ActivityViewVirtualDisplay";
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700127
128 // For debugging to make sure the caller when acquiring/releasing our
129 // wake lock is the system process.
130 static final boolean VALIDATE_WAKE_LOCK_CALLER = false;
Craig Mautnerf3333272013-04-22 10:55:53 -0700131
Craig Mautner27084302013-03-25 08:05:25 -0700132 final ActivityManagerService mService;
133
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700134 final ActivityStackSupervisorHandler mHandler;
135
136 /** Short cut */
137 WindowManagerService mWindowManager;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800138 DisplayManager mDisplayManager;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700139
Craig Mautner27084302013-03-25 08:05:25 -0700140 /** Dismiss the keyguard after the next activity is displayed? */
Craig Mautner5314a402013-09-26 12:40:16 -0700141 boolean mDismissKeyguardOnNextActivity = false;
Craig Mautner27084302013-03-25 08:05:25 -0700142
Craig Mautner8d341ef2013-03-26 09:03:27 -0700143 /** Identifier counter for all ActivityStacks */
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -0700144 private int mLastStackId = HOME_STACK_ID;
Craig Mautner8d341ef2013-03-26 09:03:27 -0700145
146 /** Task identifier that activities are currently being started in. Incremented each time a
147 * new task is created. */
148 private int mCurTaskId = 0;
149
Craig Mautner2420ead2013-04-01 17:13:20 -0700150 /** The current user */
151 private int mCurrentUser;
152
Craig Mautnere0a38842013-12-16 16:14:02 -0800153 /** The stack containing the launcher app. Assumed to always be attached to
154 * Display.DEFAULT_DISPLAY. */
Craig Mautner2219a1b2013-03-25 09:44:30 -0700155 private ActivityStack mHomeStack;
Craig Mautner20e72272013-04-01 13:45:53 -0700156
Craig Mautnere0a38842013-12-16 16:14:02 -0800157 /** The stack currently receiving input or launching the next activity. */
Craig Mautner29219d92013-04-16 20:19:12 -0700158 private ActivityStack mFocusedStack;
Craig Mautner8d341ef2013-03-26 09:03:27 -0700159
Craig Mautner4a1cb222013-12-04 16:14:06 -0800160 /** If this is the same as mFocusedStack then the activity on the top of the focused stack has
161 * been resumed. If stacks are changing position this will hold the old stack until the new
Craig Mautnere0a38842013-12-16 16:14:02 -0800162 * stack becomes resumed after which it will be set to mFocusedStack. */
Craig Mautner4a1cb222013-12-04 16:14:06 -0800163 private ActivityStack mLastFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700164
165 /** List of activities that are waiting for a new activity to become visible before completing
166 * whatever operation they are supposed to do. */
167 final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<ActivityRecord>();
168
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700169 /** List of processes waiting to find out about the next visible activity. */
170 final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible =
171 new ArrayList<IActivityManager.WaitResult>();
172
173 /** List of processes waiting to find out about the next launched activity. */
174 final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched =
175 new ArrayList<IActivityManager.WaitResult>();
176
Craig Mautnerde4ef022013-04-07 19:01:33 -0700177 /** List of activities that are ready to be stopped, but waiting for the next activity to
178 * settle down before doing so. */
179 final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<ActivityRecord>();
180
Craig Mautnerf3333272013-04-22 10:55:53 -0700181 /** List of activities that are ready to be finished, but waiting for the previous activity to
182 * settle down before doing so. It contains ActivityRecord objects. */
183 final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<ActivityRecord>();
184
Craig Mautner0eea92c2013-05-16 13:35:39 -0700185 /** List of activities that are in the process of going to sleep. */
186 final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<ActivityRecord>();
187
Craig Mautnerf3333272013-04-22 10:55:53 -0700188 /** List of ActivityRecord objects that have been finished and must still report back to a
189 * pending thumbnail receiver. */
190 final ArrayList<ActivityRecord> mCancelledThumbnails = new ArrayList<ActivityRecord>();
191
192 /** Used on user changes */
193 final ArrayList<UserStartedState> mStartingUsers = new ArrayList<UserStartedState>();
194
Craig Mautnerde4ef022013-04-07 19:01:33 -0700195 /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity
196 * is being brought in front of us. */
197 boolean mUserLeaving = false;
198
Craig Mautner0eea92c2013-05-16 13:35:39 -0700199 /** Set when we have taken too long waiting to go to sleep. */
200 boolean mSleepTimeout = false;
201
202 /**
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700203 * We don't want to allow the device to go to sleep while in the process
204 * of launching an activity. This is primarily to allow alarm intent
205 * receivers to launch an activity and get that to run before the device
206 * goes back to sleep.
207 */
208 final PowerManager.WakeLock mLaunchingActivity;
209
210 /**
Craig Mautner0eea92c2013-05-16 13:35:39 -0700211 * Set when the system is going to sleep, until we have
212 * successfully paused the current activity and released our wake lock.
213 * At that point the system is allowed to actually sleep.
214 */
215 final PowerManager.WakeLock mGoingToSleep;
216
Craig Mautner4f1df4f2013-10-15 15:44:14 -0700217 /** Stack id of the front stack when user switched, indexed by userId. */
218 SparseIntArray mUserStackInFront = new SparseIntArray(2);
Craig Mautner93529a42013-10-04 15:03:13 -0700219
Craig Mautner4504de52013-12-20 09:06:56 -0800220 // TODO: Add listener for removal of references.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800221 /** Mapping from (ActivityStack/TaskStack).mStackId to their current state */
Craig Mautner4504de52013-12-20 09:06:56 -0800222 SparseArray<WeakReference<ActivityContainer>> mActivityContainers =
223 new SparseArray<WeakReference<ActivityContainer>>();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800224
225 /** Mapping from displayId to display current state */
Craig Mautner4504de52013-12-20 09:06:56 -0800226 private SparseArray<ActivityDisplay> mActivityDisplays = new SparseArray<ActivityDisplay>();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800227
228 public ActivityStackSupervisor(ActivityManagerService service) {
Craig Mautner27084302013-03-25 08:05:25 -0700229 mService = service;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800230 PowerManager pm = (PowerManager)mService.mContext.getSystemService(Context.POWER_SERVICE);
Craig Mautner0eea92c2013-05-16 13:35:39 -0700231 mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
Craig Mautner4a1cb222013-12-04 16:14:06 -0800232 mHandler = new ActivityStackSupervisorHandler(mService.mHandler.getLooper());
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700233 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
234 throw new IllegalStateException("Calling must be system uid");
235 }
236 mLaunchingActivity =
237 pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
238 mLaunchingActivity.setReferenceCounted(false);
Craig Mautner2219a1b2013-03-25 09:44:30 -0700239 }
240
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700241 void setWindowManager(WindowManagerService wm) {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800242 synchronized (mService) {
243 mWindowManager = wm;
244
245 mDisplayManager =
246 (DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE);
247 mDisplayManager.registerDisplayListener(this, null);
248
249 Display[] displays = mDisplayManager.getDisplays();
250 for (int displayNdx = displays.length - 1; displayNdx >= 0; --displayNdx) {
251 final int displayId = displays[displayNdx].getDisplayId();
Craig Mautnere0a38842013-12-16 16:14:02 -0800252 ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
253 mActivityDisplays.put(displayId, activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -0800254 }
255
256 createStackOnDisplay(null, HOME_STACK_ID, Display.DEFAULT_DISPLAY);
257 mHomeStack = mFocusedStack = mLastFocusedStack = getStack(HOME_STACK_ID);
258 }
Craig Mautner27084302013-03-25 08:05:25 -0700259 }
260
261 void dismissKeyguard() {
Craig Mautner5314a402013-09-26 12:40:16 -0700262 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen("");
Craig Mautner27084302013-03-25 08:05:25 -0700263 if (mDismissKeyguardOnNextActivity) {
264 mDismissKeyguardOnNextActivity = false;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700265 mWindowManager.dismissKeyguard();
Craig Mautner27084302013-03-25 08:05:25 -0700266 }
267 }
268
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700269 ActivityStack getFocusedStack() {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800270 return mFocusedStack;
Craig Mautner20e72272013-04-01 13:45:53 -0700271 }
272
Craig Mautnerde4ef022013-04-07 19:01:33 -0700273 ActivityStack getLastStack() {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800274 return mLastFocusedStack;
Craig Mautner2219a1b2013-03-25 09:44:30 -0700275 }
276
Craig Mautner4a1cb222013-12-04 16:14:06 -0800277 // TODO: Split into two methods isFrontStack for any visible stack and isFrontmostStack for the
278 // top of all visible stacks.
Craig Mautnerde4ef022013-04-07 19:01:33 -0700279 boolean isFrontStack(ActivityStack stack) {
Craig Mautnerdf88d732014-01-27 09:21:32 -0800280 final ActivityRecord parent = stack.mActivityContainer.mParentActivity;
281 if (parent != null) {
282 stack = parent.task.stack;
283 }
Craig Mautnere0a38842013-12-16 16:14:02 -0800284 ArrayList<ActivityStack> stacks = stack.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800285 if (stacks != null && !stacks.isEmpty()) {
286 return stack == stacks.get(stacks.size() - 1);
287 }
288 return false;
Craig Mautner20e72272013-04-01 13:45:53 -0700289 }
290
Craig Mautnerde4ef022013-04-07 19:01:33 -0700291 void moveHomeStack(boolean toFront) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800292 ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800293 int topNdx = stacks.size() - 1;
294 if (topNdx <= 0) {
295 return;
296 }
297 ActivityStack topStack = stacks.get(topNdx);
298 final boolean homeInFront = topStack == mHomeStack;
299 if (homeInFront != toFront) {
300 mLastFocusedStack = topStack;
301 stacks.remove(mHomeStack);
302 stacks.add(toFront ? topNdx : 0, mHomeStack);
303 mFocusedStack = stacks.get(topNdx);
304 if (DEBUG_STACK) Slog.d(TAG, "moveHomeTask: topStack old=" + topStack + " new="
305 + mFocusedStack);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700306 }
307 }
308
Craig Mautner8e569572013-10-11 17:36:59 -0700309 void moveHomeToTop() {
Craig Mautner69ada552013-04-18 13:51:51 -0700310 moveHomeStack(true);
Craig Mautner8e569572013-10-11 17:36:59 -0700311 mHomeStack.moveHomeTaskToTop();
312 }
313
314 boolean resumeHomeActivity(ActivityRecord prev) {
315 moveHomeToTop();
Craig Mautner69ada552013-04-18 13:51:51 -0700316 if (prev != null) {
Craig Mautnerae7ecab2013-09-18 11:48:14 -0700317 prev.task.mOnTopOfHome = false;
Craig Mautner69ada552013-04-18 13:51:51 -0700318 }
Craig Mautnera8a90e02013-06-28 15:24:50 -0700319 ActivityRecord r = mHomeStack.topRunningActivityLocked(null);
Craig Mautner760b2312013-10-11 11:57:07 -0700320 if (r != null && r.isHomeActivity()) {
Craig Mautnera8a90e02013-06-28 15:24:50 -0700321 mService.setFocusedActivityLocked(r);
Craig Mautner05d29032013-05-03 13:40:13 -0700322 return resumeTopActivitiesLocked(mHomeStack, prev, null);
Craig Mautner69ada552013-04-18 13:51:51 -0700323 }
324 return mService.startHomeActivityLocked(mCurrentUser);
325 }
326
Craig Mautner27084302013-03-25 08:05:25 -0700327 void setDismissKeyguard(boolean dismiss) {
Craig Mautner5314a402013-09-26 12:40:16 -0700328 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen(" dismiss=" + dismiss);
Craig Mautner27084302013-03-25 08:05:25 -0700329 mDismissKeyguardOnNextActivity = dismiss;
330 }
331
Craig Mautner8d341ef2013-03-26 09:03:27 -0700332 TaskRecord anyTaskForIdLocked(int id) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800333 int numDisplays = mActivityDisplays.size();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800334 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800335 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800336 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
337 ActivityStack stack = stacks.get(stackNdx);
338 TaskRecord task = stack.taskForIdLocked(id);
339 if (task != null) {
340 return task;
341 }
Craig Mautner8d341ef2013-03-26 09:03:27 -0700342 }
343 }
344 return null;
345 }
346
Craig Mautner6170f732013-04-02 13:05:23 -0700347 ActivityRecord isInAnyStackLocked(IBinder token) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800348 int numDisplays = mActivityDisplays.size();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800349 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800350 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800351 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
352 final ActivityRecord r = stacks.get(stackNdx).isInStackLocked(token);
353 if (r != null) {
354 return r;
355 }
Craig Mautner6170f732013-04-02 13:05:23 -0700356 }
357 }
358 return null;
359 }
360
Craig Mautner8d341ef2013-03-26 09:03:27 -0700361 int getNextTaskId() {
362 do {
363 mCurTaskId++;
364 if (mCurTaskId <= 0) {
365 mCurTaskId = 1;
366 }
367 } while (anyTaskForIdLocked(mCurTaskId) != null);
368 return mCurTaskId;
369 }
370
Craig Mautnerde4ef022013-04-07 19:01:33 -0700371 ActivityRecord resumedAppLocked() {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700372 ActivityStack stack = getFocusedStack();
373 if (stack == null) {
374 return null;
375 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700376 ActivityRecord resumedActivity = stack.mResumedActivity;
377 if (resumedActivity == null || resumedActivity.app == null) {
378 resumedActivity = stack.mPausingActivity;
379 if (resumedActivity == null || resumedActivity.app == null) {
380 resumedActivity = stack.topRunningActivityLocked(null);
381 }
382 }
383 return resumedActivity;
384 }
385
Mike Lockwoode63f6f72013-11-15 11:01:47 -0800386 boolean attachApplicationLocked(ProcessRecord app) throws Exception {
Craig Mautner20e72272013-04-01 13:45:53 -0700387 final String processName = app.processName;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800388 boolean didSomething = false;
Craig Mautnere0a38842013-12-16 16:14:02 -0800389 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
390 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800391 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
392 final ActivityStack stack = stacks.get(stackNdx);
393 if (!isFrontStack(stack)) {
394 continue;
395 }
396 ActivityRecord hr = stack.topRunningActivityLocked(null);
397 if (hr != null) {
398 if (hr.app == null && app.uid == hr.info.applicationInfo.uid
399 && processName.equals(hr.processName)) {
400 try {
401 if (realStartActivityLocked(hr, app, true, true)) {
402 didSomething = true;
403 }
404 } catch (Exception e) {
405 Slog.w(TAG, "Exception in new application when starting activity "
406 + hr.intent.getComponent().flattenToShortString(), e);
407 throw e;
Craig Mautner20e72272013-04-01 13:45:53 -0700408 }
Craig Mautner20e72272013-04-01 13:45:53 -0700409 }
Craig Mautner20e72272013-04-01 13:45:53 -0700410 }
411 }
412 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -0700413 if (!didSomething) {
414 ensureActivitiesVisibleLocked(null, 0);
415 }
Craig Mautner20e72272013-04-01 13:45:53 -0700416 return didSomething;
417 }
418
419 boolean allResumedActivitiesIdle() {
Craig Mautnere0a38842013-12-16 16:14:02 -0800420 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
421 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800422 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
423 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautner34b73df2014-01-12 21:11:08 -0800424 if (!isFrontStack(stack) || stack.numActivities() == 0) {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800425 continue;
426 }
427 final ActivityRecord resumedActivity = stack.mResumedActivity;
428 if (resumedActivity == null || !resumedActivity.idle) {
Craig Mautner34b73df2014-01-12 21:11:08 -0800429 if (DEBUG_STATES) Slog.d(TAG, "allResumedActivitiesIdle: stack="
430 + stack.mStackId + " " + resumedActivity + " not idle");
Craig Mautner4a1cb222013-12-04 16:14:06 -0800431 return false;
432 }
Craig Mautner20e72272013-04-01 13:45:53 -0700433 }
434 }
435 return true;
436 }
437
Craig Mautnerde4ef022013-04-07 19:01:33 -0700438 boolean allResumedActivitiesComplete() {
Craig Mautnere0a38842013-12-16 16:14:02 -0800439 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
440 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800441 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
442 final ActivityStack stack = stacks.get(stackNdx);
443 if (isFrontStack(stack)) {
444 final ActivityRecord r = stack.mResumedActivity;
445 if (r != null && r.state != ActivityState.RESUMED) {
446 return false;
447 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700448 }
449 }
450 }
451 // TODO: Not sure if this should check if all Paused are complete too.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800452 if (DEBUG_STACK) Slog.d(TAG,
453 "allResumedActivitiesComplete: mLastFocusedStack changing from=" +
454 mLastFocusedStack + " to=" + mFocusedStack);
455 mLastFocusedStack = mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700456 return true;
457 }
458
459 boolean allResumedActivitiesVisible() {
Craig Mautnere0a38842013-12-16 16:14:02 -0800460 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
461 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800462 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
463 final ActivityStack stack = stacks.get(stackNdx);
464 final ActivityRecord r = stack.mResumedActivity;
465 if (r != null && (!r.nowVisible || r.waitingVisible)) {
466 return false;
467 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700468 }
469 }
470 return true;
471 }
472
Craig Mautner2acc3892013-09-23 10:28:14 -0700473 /**
474 * Pause all activities in either all of the stacks or just the back stacks.
475 * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving().
Craig Mautner2acc3892013-09-23 10:28:14 -0700476 * @return true if any activity was paused as a result of this call.
477 */
Craig Mautner5314a402013-09-26 12:40:16 -0700478 boolean pauseBackStacks(boolean userLeaving) {
Craig Mautnercf910b02013-04-23 11:23:27 -0700479 boolean someActivityPaused = false;
Craig Mautnere0a38842013-12-16 16:14:02 -0800480 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
481 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800482 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
483 final ActivityStack stack = stacks.get(stackNdx);
484 if (!isFrontStack(stack) && stack.mResumedActivity != null) {
485 if (DEBUG_STATES) Slog.d(TAG, "pauseBackStacks: stack=" + stack +
486 " mResumedActivity=" + stack.mResumedActivity);
487 stack.startPausingLocked(userLeaving, false);
488 someActivityPaused = true;
489 }
Craig Mautnercf910b02013-04-23 11:23:27 -0700490 }
491 }
492 return someActivityPaused;
493 }
494
Craig Mautnerde4ef022013-04-07 19:01:33 -0700495 boolean allPausedActivitiesComplete() {
Craig Mautnerac6f8432013-07-17 13:24:59 -0700496 boolean pausing = true;
Craig Mautnere0a38842013-12-16 16:14:02 -0800497 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
498 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800499 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
500 final ActivityStack stack = stacks.get(stackNdx);
501 final ActivityRecord r = stack.mPausingActivity;
502 if (r != null && r.state != ActivityState.PAUSED
503 && r.state != ActivityState.STOPPED
504 && r.state != ActivityState.STOPPING) {
505 if (DEBUG_STATES) {
506 Slog.d(TAG, "allPausedActivitiesComplete: r=" + r + " state=" + r.state);
507 pausing = false;
508 } else {
509 return false;
510 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700511 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700512 }
513 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700514 return pausing;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700515 }
516
Craig Mautnerdf88d732014-01-27 09:21:32 -0800517 void pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping) {
518 // TODO: Put all stacks in supervisor and iterate through them instead.
519 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
520 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
521 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
522 final ActivityStack stack = stacks.get(stackNdx);
523 if (stack.mResumedActivity != null &&
524 stack.mActivityContainer.mParentActivity == parent) {
525 stack.startPausingLocked(userLeaving, uiSleeping);
526 }
527 }
528 }
529 }
530
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700531 void reportActivityVisibleLocked(ActivityRecord r) {
Craig Mautner858d8a62013-04-23 17:08:34 -0700532 for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700533 WaitResult w = mWaitingActivityVisible.get(i);
534 w.timeout = false;
535 if (r != null) {
536 w.who = new ComponentName(r.info.packageName, r.info.name);
537 }
538 w.totalTime = SystemClock.uptimeMillis() - w.thisTime;
539 w.thisTime = w.totalTime;
540 }
541 mService.notifyAll();
542 dismissKeyguard();
543 }
544
545 void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r,
546 long thisTime, long totalTime) {
547 for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
Craig Mautnerc64f73e2013-04-24 16:44:56 -0700548 WaitResult w = mWaitingActivityLaunched.remove(i);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700549 w.timeout = timeout;
550 if (r != null) {
551 w.who = new ComponentName(r.info.packageName, r.info.name);
552 }
553 w.thisTime = thisTime;
554 w.totalTime = totalTime;
555 }
556 mService.notifyAll();
557 }
558
Craig Mautner29219d92013-04-16 20:19:12 -0700559 ActivityRecord topRunningActivityLocked() {
Craig Mautner1602ec22013-05-12 10:24:27 -0700560 final ActivityStack focusedStack = getFocusedStack();
561 ActivityRecord r = focusedStack.topRunningActivityLocked(null);
562 if (r != null) {
563 return r;
Craig Mautner29219d92013-04-16 20:19:12 -0700564 }
Craig Mautner1602ec22013-05-12 10:24:27 -0700565
Craig Mautner4a1cb222013-12-04 16:14:06 -0800566 // Return to the home stack.
Craig Mautnere0a38842013-12-16 16:14:02 -0800567 final ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800568 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
569 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautnerac6f8432013-07-17 13:24:59 -0700570 if (stack != focusedStack && isFrontStack(stack)) {
Craig Mautner29219d92013-04-16 20:19:12 -0700571 r = stack.topRunningActivityLocked(null);
572 if (r != null) {
573 return r;
574 }
575 }
576 }
577 return null;
578 }
579
Craig Mautner20e72272013-04-01 13:45:53 -0700580 ActivityRecord getTasksLocked(int maxNum, IThumbnailReceiver receiver,
581 PendingThumbnailsRecord pending, List<RunningTaskInfo> list) {
582 ActivityRecord r = null;
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700583
584 // Gather all of the running tasks for each stack into runningTaskLists.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800585 ArrayList<ArrayList<RunningTaskInfo>> runningTaskLists =
586 new ArrayList<ArrayList<RunningTaskInfo>>();
Craig Mautnere0a38842013-12-16 16:14:02 -0800587 final int numDisplays = mActivityDisplays.size();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800588 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800589 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800590 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
591 final ActivityStack stack = stacks.get(stackNdx);
592 ArrayList<RunningTaskInfo> stackTaskList = new ArrayList<RunningTaskInfo>();
593 runningTaskLists.add(stackTaskList);
594 final ActivityRecord ar = stack.getTasksLocked(receiver, pending, stackTaskList);
595 if (r == null && isFrontStack(stack)) {
596 r = ar;
597 }
Craig Mautner20e72272013-04-01 13:45:53 -0700598 }
599 }
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700600
601 // The lists are already sorted from most recent to oldest. Just pull the most recent off
602 // each list and add it to list. Stop when all lists are empty or maxNum reached.
603 while (maxNum > 0) {
604 long mostRecentActiveTime = Long.MIN_VALUE;
605 ArrayList<RunningTaskInfo> selectedStackList = null;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800606 final int numTaskLists = runningTaskLists.size();
607 for (int stackNdx = 0; stackNdx < numTaskLists; ++stackNdx) {
608 ArrayList<RunningTaskInfo> stackTaskList = runningTaskLists.get(stackNdx);
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700609 if (!stackTaskList.isEmpty()) {
610 final long lastActiveTime = stackTaskList.get(0).lastActiveTime;
611 if (lastActiveTime > mostRecentActiveTime) {
612 mostRecentActiveTime = lastActiveTime;
613 selectedStackList = stackTaskList;
614 }
615 }
616 }
617 if (selectedStackList != null) {
618 list.add(selectedStackList.remove(0));
619 --maxNum;
620 } else {
621 break;
622 }
623 }
624
Craig Mautner20e72272013-04-01 13:45:53 -0700625 return r;
626 }
627
Craig Mautner23ac33b2013-04-01 16:26:35 -0700628 ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
629 String profileFile, ParcelFileDescriptor profileFd, int userId) {
630 // Collect information about the target of the Intent.
631 ActivityInfo aInfo;
632 try {
633 ResolveInfo rInfo =
634 AppGlobals.getPackageManager().resolveIntent(
635 intent, resolvedType,
636 PackageManager.MATCH_DEFAULT_ONLY
637 | ActivityManagerService.STOCK_PM_FLAGS, userId);
638 aInfo = rInfo != null ? rInfo.activityInfo : null;
639 } catch (RemoteException e) {
640 aInfo = null;
641 }
642
643 if (aInfo != null) {
644 // Store the found target back into the intent, because now that
645 // we have it we never want to do this again. For example, if the
646 // user navigates back to this point in the history, we should
647 // always restart the exact same activity.
648 intent.setComponent(new ComponentName(
649 aInfo.applicationInfo.packageName, aInfo.name));
650
651 // Don't debug things in the system process
652 if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) {
653 if (!aInfo.processName.equals("system")) {
654 mService.setDebugApp(aInfo.processName, true, false);
655 }
656 }
657
658 if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) {
659 if (!aInfo.processName.equals("system")) {
660 mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName);
661 }
662 }
663
664 if (profileFile != null) {
665 if (!aInfo.processName.equals("system")) {
666 mService.setProfileApp(aInfo.applicationInfo, aInfo.processName,
667 profileFile, profileFd,
668 (startFlags&ActivityManager.START_FLAG_AUTO_STOP_PROFILER) != 0);
669 }
670 }
671 }
672 return aInfo;
673 }
674
Craig Mautner2219a1b2013-03-25 09:44:30 -0700675 void startHomeActivity(Intent intent, ActivityInfo aInfo) {
Craig Mautner8e569572013-10-11 17:36:59 -0700676 moveHomeToTop();
Craig Mautner6170f732013-04-02 13:05:23 -0700677 startActivityLocked(null, intent, null, aInfo, null, null, 0, 0, 0, null, 0,
Craig Mautnere0a38842013-12-16 16:14:02 -0800678 null, false, null, null);
Craig Mautner8d341ef2013-03-26 09:03:27 -0700679 }
680
Craig Mautner23ac33b2013-04-01 16:26:35 -0700681 final int startActivityMayWait(IApplicationThread caller, int callingUid,
682 String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
683 String resultWho, int requestCode, int startFlags, String profileFile,
684 ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config,
Craig Mautnere0a38842013-12-16 16:14:02 -0800685 Bundle options, int userId, IActivityContainer iContainer) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700686 // Refuse possible leaked file descriptors
687 if (intent != null && intent.hasFileDescriptors()) {
688 throw new IllegalArgumentException("File descriptors passed in Intent");
689 }
690 boolean componentSpecified = intent.getComponent() != null;
691
692 // Don't modify the client's object!
693 intent = new Intent(intent);
694
695 // Collect information about the target of the Intent.
696 ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
697 profileFile, profileFd, userId);
698
Craig Mautnere0a38842013-12-16 16:14:02 -0800699 ActivityContainer container = (ActivityContainer)iContainer;
Craig Mautner23ac33b2013-04-01 16:26:35 -0700700 synchronized (mService) {
701 int callingPid;
702 if (callingUid >= 0) {
703 callingPid = -1;
704 } else if (caller == null) {
705 callingPid = Binder.getCallingPid();
706 callingUid = Binder.getCallingUid();
707 } else {
708 callingPid = callingUid = -1;
709 }
710
Craig Mautnere0a38842013-12-16 16:14:02 -0800711 final ActivityStack stack;
712 if (container == null || container.mStack.isOnHomeDisplay()) {
713 stack = getFocusedStack();
714 } else {
715 stack = container.mStack;
716 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700717 stack.mConfigWillChange = config != null
Craig Mautner23ac33b2013-04-01 16:26:35 -0700718 && mService.mConfiguration.diff(config) != 0;
719 if (DEBUG_CONFIGURATION) Slog.v(TAG,
Craig Mautnerde4ef022013-04-07 19:01:33 -0700720 "Starting activity when config will change = " + stack.mConfigWillChange);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700721
722 final long origId = Binder.clearCallingIdentity();
723
724 if (aInfo != null &&
725 (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
726 // This may be a heavy-weight process! Check to see if we already
727 // have another, different heavy-weight process running.
728 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
729 if (mService.mHeavyWeightProcess != null &&
730 (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid ||
731 !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700732 int realCallingUid = callingUid;
733 if (caller != null) {
734 ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
735 if (callerApp != null) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700736 realCallingUid = callerApp.info.uid;
737 } else {
738 Slog.w(TAG, "Unable to find app for caller " + caller
Craig Mautner76ea2242013-05-15 11:40:05 -0700739 + " (pid=" + callingPid + ") when starting: "
Craig Mautner23ac33b2013-04-01 16:26:35 -0700740 + intent.toString());
741 ActivityOptions.abort(options);
742 return ActivityManager.START_PERMISSION_DENIED;
743 }
744 }
745
746 IIntentSender target = mService.getIntentSenderLocked(
747 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
748 realCallingUid, userId, null, null, 0, new Intent[] { intent },
749 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
750 | PendingIntent.FLAG_ONE_SHOT, null);
751
752 Intent newIntent = new Intent();
753 if (requestCode >= 0) {
754 // Caller is requesting a result.
755 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
756 }
757 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
758 new IntentSender(target));
759 if (mService.mHeavyWeightProcess.activities.size() > 0) {
760 ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0);
761 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
762 hist.packageName);
763 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
764 hist.task.taskId);
765 }
766 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
767 aInfo.packageName);
768 newIntent.setFlags(intent.getFlags());
769 newIntent.setClassName("android",
770 HeavyWeightSwitcherActivity.class.getName());
771 intent = newIntent;
772 resolvedType = null;
773 caller = null;
774 callingUid = Binder.getCallingUid();
775 callingPid = Binder.getCallingPid();
776 componentSpecified = true;
777 try {
778 ResolveInfo rInfo =
779 AppGlobals.getPackageManager().resolveIntent(
780 intent, null,
781 PackageManager.MATCH_DEFAULT_ONLY
782 | ActivityManagerService.STOCK_PM_FLAGS, userId);
783 aInfo = rInfo != null ? rInfo.activityInfo : null;
784 aInfo = mService.getActivityInfoForUser(aInfo, userId);
785 } catch (RemoteException e) {
786 aInfo = null;
787 }
788 }
789 }
790 }
791
Craig Mautnere0a38842013-12-16 16:14:02 -0800792 int res = startActivityLocked(caller, intent, resolvedType, aInfo, resultTo, resultWho,
793 requestCode, callingPid, callingUid, callingPackage, startFlags, options,
794 componentSpecified, null, container);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700795
Craig Mautnerde4ef022013-04-07 19:01:33 -0700796 if (stack.mConfigWillChange) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700797 // If the caller also wants to switch to a new configuration,
798 // do so now. This allows a clean switch, as we are waiting
799 // for the current activity to pause (so we will not destroy
800 // it), and have not yet started the next activity.
801 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
802 "updateConfiguration()");
Craig Mautnerde4ef022013-04-07 19:01:33 -0700803 stack.mConfigWillChange = false;
Craig Mautner23ac33b2013-04-01 16:26:35 -0700804 if (DEBUG_CONFIGURATION) Slog.v(TAG,
805 "Updating to new configuration after starting activity.");
806 mService.updateConfigurationLocked(config, null, false, false);
807 }
808
809 Binder.restoreCallingIdentity(origId);
810
811 if (outResult != null) {
812 outResult.result = res;
813 if (res == ActivityManager.START_SUCCESS) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700814 mWaitingActivityLaunched.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700815 do {
816 try {
817 mService.wait();
818 } catch (InterruptedException e) {
819 }
820 } while (!outResult.timeout && outResult.who == null);
821 } else if (res == ActivityManager.START_TASK_TO_FRONT) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700822 ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700823 if (r.nowVisible) {
824 outResult.timeout = false;
825 outResult.who = new ComponentName(r.info.packageName, r.info.name);
826 outResult.totalTime = 0;
827 outResult.thisTime = 0;
828 } else {
829 outResult.thisTime = SystemClock.uptimeMillis();
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700830 mWaitingActivityVisible.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700831 do {
832 try {
833 mService.wait();
834 } catch (InterruptedException e) {
835 }
836 } while (!outResult.timeout && outResult.who == null);
837 }
838 }
839 }
840
841 return res;
842 }
843 }
844
845 final int startActivities(IApplicationThread caller, int callingUid, String callingPackage,
846 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
847 Bundle options, int userId) {
848 if (intents == null) {
849 throw new NullPointerException("intents is null");
850 }
851 if (resolvedTypes == null) {
852 throw new NullPointerException("resolvedTypes is null");
853 }
854 if (intents.length != resolvedTypes.length) {
855 throw new IllegalArgumentException("intents are length different than resolvedTypes");
856 }
857
Craig Mautner23ac33b2013-04-01 16:26:35 -0700858
859 int callingPid;
860 if (callingUid >= 0) {
861 callingPid = -1;
862 } else if (caller == null) {
863 callingPid = Binder.getCallingPid();
864 callingUid = Binder.getCallingUid();
865 } else {
866 callingPid = callingUid = -1;
867 }
868 final long origId = Binder.clearCallingIdentity();
869 try {
870 synchronized (mService) {
Craig Mautner76ea2242013-05-15 11:40:05 -0700871 ActivityRecord[] outActivity = new ActivityRecord[1];
Craig Mautner23ac33b2013-04-01 16:26:35 -0700872 for (int i=0; i<intents.length; i++) {
873 Intent intent = intents[i];
874 if (intent == null) {
875 continue;
876 }
877
878 // Refuse possible leaked file descriptors
879 if (intent != null && intent.hasFileDescriptors()) {
880 throw new IllegalArgumentException("File descriptors passed in Intent");
881 }
882
883 boolean componentSpecified = intent.getComponent() != null;
884
885 // Don't modify the client's object!
886 intent = new Intent(intent);
887
888 // Collect information about the target of the Intent.
889 ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i],
890 0, null, null, userId);
891 // TODO: New, check if this is correct
892 aInfo = mService.getActivityInfoForUser(aInfo, userId);
893
894 if (aInfo != null &&
895 (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE)
896 != 0) {
897 throw new IllegalArgumentException(
898 "FLAG_CANT_SAVE_STATE not supported here");
899 }
900
901 Bundle theseOptions;
902 if (options != null && i == intents.length-1) {
903 theseOptions = options;
904 } else {
905 theseOptions = null;
906 }
Craig Mautner6170f732013-04-02 13:05:23 -0700907 int res = startActivityLocked(caller, intent, resolvedTypes[i],
Craig Mautner23ac33b2013-04-01 16:26:35 -0700908 aInfo, resultTo, null, -1, callingPid, callingUid, callingPackage,
Craig Mautnere0a38842013-12-16 16:14:02 -0800909 0, theseOptions, componentSpecified, outActivity, null);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700910 if (res < 0) {
911 return res;
912 }
913
914 resultTo = outActivity[0] != null ? outActivity[0].appToken : null;
915 }
916 }
917 } finally {
918 Binder.restoreCallingIdentity(origId);
919 }
920
921 return ActivityManager.START_SUCCESS;
922 }
923
Craig Mautner2420ead2013-04-01 17:13:20 -0700924 final boolean realStartActivityLocked(ActivityRecord r,
925 ProcessRecord app, boolean andResume, boolean checkConfig)
926 throws RemoteException {
927
928 r.startFreezingScreenLocked(app, 0);
Craig Mautnera7f2bd42013-10-15 16:13:50 -0700929 if (false) Slog.d(TAG, "realStartActivity: setting app visibility true");
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700930 mWindowManager.setAppVisibility(r.appToken, true);
Craig Mautner2420ead2013-04-01 17:13:20 -0700931
932 // schedule launch ticks to collect information about slow apps.
933 r.startLaunchTickingLocked();
934
935 // Have the window manager re-evaluate the orientation of
936 // the screen based on the new activity order. Note that
937 // as a result of this, it can call back into the activity
938 // manager with a new orientation. We don't care about that,
939 // because the activity is not currently running so we are
940 // just restarting it anyway.
941 if (checkConfig) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700942 Configuration config = mWindowManager.updateOrientationFromAppTokens(
Craig Mautner2420ead2013-04-01 17:13:20 -0700943 mService.mConfiguration,
944 r.mayFreezeScreenLocked(app) ? r.appToken : null);
945 mService.updateConfigurationLocked(config, r, false, false);
946 }
947
948 r.app = app;
949 app.waitingToKill = null;
950 r.launchCount++;
951 r.lastLaunchTime = SystemClock.uptimeMillis();
952
953 if (localLOGV) Slog.v(TAG, "Launching: " + r);
954
955 int idx = app.activities.indexOf(r);
956 if (idx < 0) {
957 app.activities.add(r);
958 }
Dianne Hackborndb926082013-10-31 16:32:44 -0700959 mService.updateLruProcessLocked(app, true, null);
960 mService.updateOomAdjLocked();
Craig Mautner2420ead2013-04-01 17:13:20 -0700961
962 final ActivityStack stack = r.task.stack;
963 try {
964 if (app.thread == null) {
965 throw new RemoteException();
966 }
967 List<ResultInfo> results = null;
968 List<Intent> newIntents = null;
969 if (andResume) {
970 results = r.results;
971 newIntents = r.newIntents;
972 }
973 if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r
974 + " icicle=" + r.icicle
975 + " with results=" + results + " newIntents=" + newIntents
976 + " andResume=" + andResume);
977 if (andResume) {
978 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
979 r.userId, System.identityHashCode(r),
980 r.task.taskId, r.shortComponentName);
981 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700982 if (r.isHomeActivity() && r.isNotResolverActivity()) {
Craig Mautner4ef26932013-09-18 15:15:52 -0700983 // Home process is the root process of the task.
984 mService.mHomeProcess = r.task.mActivities.get(0).app;
Craig Mautner2420ead2013-04-01 17:13:20 -0700985 }
986 mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
987 r.sleeping = false;
988 r.forceNewConfig = false;
989 mService.showAskCompatModeDialogLocked(r);
990 r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
991 String profileFile = null;
992 ParcelFileDescriptor profileFd = null;
993 boolean profileAutoStop = false;
994 if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
995 if (mService.mProfileProc == null || mService.mProfileProc == app) {
996 mService.mProfileProc = app;
997 profileFile = mService.mProfileFile;
998 profileFd = mService.mProfileFd;
999 profileAutoStop = mService.mAutoStopProfiler;
1000 }
1001 }
1002 app.hasShownUi = true;
1003 app.pendingUiClean = true;
1004 if (profileFd != null) {
1005 try {
1006 profileFd = profileFd.dup();
1007 } catch (IOException e) {
1008 if (profileFd != null) {
1009 try {
1010 profileFd.close();
1011 } catch (IOException o) {
1012 }
1013 profileFd = null;
1014 }
1015 }
1016 }
Dianne Hackborna413dc02013-07-12 12:02:55 -07001017 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
Craig Mautner2420ead2013-04-01 17:13:20 -07001018 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
1019 System.identityHashCode(r), r.info,
Dianne Hackborna413dc02013-07-12 12:02:55 -07001020 new Configuration(mService.mConfiguration), r.compat,
1021 app.repProcState, r.icicle, results, newIntents, !andResume,
Craig Mautner2420ead2013-04-01 17:13:20 -07001022 mService.isNextTransitionForward(), profileFile, profileFd,
1023 profileAutoStop);
1024
1025 if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
1026 // This may be a heavy-weight process! Note that the package
1027 // manager will ensure that only activity can run in the main
1028 // process of the .apk, which is the only thing that will be
1029 // considered heavy-weight.
1030 if (app.processName.equals(app.info.packageName)) {
1031 if (mService.mHeavyWeightProcess != null
1032 && mService.mHeavyWeightProcess != app) {
1033 Slog.w(TAG, "Starting new heavy weight process " + app
1034 + " when already running "
1035 + mService.mHeavyWeightProcess);
1036 }
1037 mService.mHeavyWeightProcess = app;
1038 Message msg = mService.mHandler.obtainMessage(
1039 ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
1040 msg.obj = r;
1041 mService.mHandler.sendMessage(msg);
1042 }
1043 }
1044
1045 } catch (RemoteException e) {
1046 if (r.launchFailed) {
1047 // This is the second time we failed -- finish activity
1048 // and give up.
1049 Slog.e(TAG, "Second failure launching "
1050 + r.intent.getComponent().flattenToShortString()
1051 + ", giving up", e);
1052 mService.appDiedLocked(app, app.pid, app.thread);
1053 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
1054 "2nd-crash", false);
1055 return false;
1056 }
1057
1058 // This is the first time we failed -- restart process and
1059 // retry.
1060 app.activities.remove(r);
1061 throw e;
1062 }
1063
1064 r.launchFailed = false;
1065 if (stack.updateLRUListLocked(r)) {
1066 Slog.w(TAG, "Activity " + r
1067 + " being launched, but already in LRU list");
1068 }
1069
1070 if (andResume) {
1071 // As part of the process of launching, ActivityThread also performs
1072 // a resume.
1073 stack.minimalResumeActivityLocked(r);
1074 } else {
1075 // This activity is not starting in the resumed state... which
1076 // should look like we asked it to pause+stop (but remain visible),
1077 // and it has done so and reported back the current icicle and
1078 // other state.
1079 if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r
1080 + " (starting in stopped state)");
1081 r.state = ActivityState.STOPPED;
1082 r.stopped = true;
1083 }
1084
1085 // Launch the new version setup screen if needed. We do this -after-
1086 // launching the initial activity (that is, home), so that it can have
1087 // a chance to initialize itself while in the background, making the
1088 // switch back to it faster and look better.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001089 if (isFrontStack(stack)) {
Craig Mautner2420ead2013-04-01 17:13:20 -07001090 mService.startSetupActivityLocked();
1091 }
1092
1093 return true;
1094 }
1095
Craig Mautnere79d42682013-04-01 19:01:53 -07001096 void startSpecificActivityLocked(ActivityRecord r,
1097 boolean andResume, boolean checkConfig) {
1098 // Is this activity's application already running?
1099 ProcessRecord app = mService.getProcessRecordLocked(r.processName,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001100 r.info.applicationInfo.uid, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001101
1102 r.task.stack.setLaunchTime(r);
1103
1104 if (app != null && app.thread != null) {
1105 try {
Dianne Hackborn237cefb2013-10-22 18:45:27 -07001106 if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
1107 || !"android".equals(r.info.packageName)) {
1108 // Don't add this if it is a platform component that is marked
1109 // to run in multiple processes, because this is actually
1110 // part of the framework so doesn't make sense to track as a
1111 // separate apk in the process.
1112 app.addPackage(r.info.packageName, mService.mProcessStats);
1113 }
Craig Mautnere79d42682013-04-01 19:01:53 -07001114 realStartActivityLocked(r, app, andResume, checkConfig);
1115 return;
1116 } catch (RemoteException e) {
1117 Slog.w(TAG, "Exception when starting activity "
1118 + r.intent.getComponent().flattenToShortString(), e);
1119 }
1120
1121 // If a dead object exception was thrown -- fall through to
1122 // restart the application.
1123 }
1124
1125 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001126 "activity", r.intent.getComponent(), false, false, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001127 }
1128
Craig Mautner6170f732013-04-02 13:05:23 -07001129 final int startActivityLocked(IApplicationThread caller,
1130 Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
1131 String resultWho, int requestCode,
1132 int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
Craig Mautnere0a38842013-12-16 16:14:02 -08001133 boolean componentSpecified, ActivityRecord[] outActivity, ActivityContainer container) {
Craig Mautner6170f732013-04-02 13:05:23 -07001134 int err = ActivityManager.START_SUCCESS;
1135
1136 ProcessRecord callerApp = null;
1137 if (caller != null) {
1138 callerApp = mService.getRecordForAppLocked(caller);
1139 if (callerApp != null) {
1140 callingPid = callerApp.pid;
1141 callingUid = callerApp.info.uid;
1142 } else {
1143 Slog.w(TAG, "Unable to find app for caller " + caller
1144 + " (pid=" + callingPid + ") when starting: "
1145 + intent.toString());
1146 err = ActivityManager.START_PERMISSION_DENIED;
1147 }
1148 }
1149
1150 if (err == ActivityManager.START_SUCCESS) {
1151 final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
1152 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
Craig Mautner9ef471f2014-02-07 13:11:47 -08001153 + "} from pid " + (callerApp != null ? callerApp.pid : callingPid)
1154 + " on display " + (container == null ? (mFocusedStack == null ?
1155 Display.DEFAULT_DISPLAY : mFocusedStack.mDisplayId) :
1156 (container.mActivityDisplay == null ? Display.DEFAULT_DISPLAY :
1157 container.mActivityDisplay.mDisplayId)));
Craig Mautner6170f732013-04-02 13:05:23 -07001158 }
1159
1160 ActivityRecord sourceRecord = null;
1161 ActivityRecord resultRecord = null;
1162 if (resultTo != null) {
1163 sourceRecord = isInAnyStackLocked(resultTo);
1164 if (DEBUG_RESULTS) Slog.v(
1165 TAG, "Will send result to " + resultTo + " " + sourceRecord);
1166 if (sourceRecord != null) {
1167 if (requestCode >= 0 && !sourceRecord.finishing) {
1168 resultRecord = sourceRecord;
1169 }
1170 }
1171 }
1172 ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
1173
1174 int launchFlags = intent.getFlags();
1175
1176 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
1177 && sourceRecord != null) {
1178 // Transfer the result target from the source activity to the new
1179 // one being started, including any failures.
1180 if (requestCode >= 0) {
1181 ActivityOptions.abort(options);
1182 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
1183 }
1184 resultRecord = sourceRecord.resultTo;
1185 resultWho = sourceRecord.resultWho;
1186 requestCode = sourceRecord.requestCode;
1187 sourceRecord.resultTo = null;
1188 if (resultRecord != null) {
1189 resultRecord.removeResultsLocked(
1190 sourceRecord, resultWho, requestCode);
1191 }
1192 }
1193
1194 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
1195 // We couldn't find a class that can handle the given Intent.
1196 // That's the end of that!
1197 err = ActivityManager.START_INTENT_NOT_RESOLVED;
1198 }
1199
1200 if (err == ActivityManager.START_SUCCESS && aInfo == null) {
1201 // We couldn't find the specific class specified in the Intent.
1202 // Also the end of the line.
1203 err = ActivityManager.START_CLASS_NOT_FOUND;
1204 }
1205
1206 if (err != ActivityManager.START_SUCCESS) {
1207 if (resultRecord != null) {
1208 resultStack.sendActivityResultLocked(-1,
1209 resultRecord, resultWho, requestCode,
1210 Activity.RESULT_CANCELED, null);
1211 }
1212 setDismissKeyguard(false);
1213 ActivityOptions.abort(options);
1214 return err;
1215 }
1216
1217 final int startAnyPerm = mService.checkPermission(
1218 START_ANY_ACTIVITY, callingPid, callingUid);
1219 final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
1220 callingUid, aInfo.applicationInfo.uid, aInfo.exported);
1221 if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
1222 if (resultRecord != null) {
1223 resultStack.sendActivityResultLocked(-1,
1224 resultRecord, resultWho, requestCode,
1225 Activity.RESULT_CANCELED, null);
1226 }
1227 setDismissKeyguard(false);
1228 String msg;
1229 if (!aInfo.exported) {
1230 msg = "Permission Denial: starting " + intent.toString()
1231 + " from " + callerApp + " (pid=" + callingPid
1232 + ", uid=" + callingUid + ")"
1233 + " not exported from uid " + aInfo.applicationInfo.uid;
1234 } else {
1235 msg = "Permission Denial: starting " + intent.toString()
1236 + " from " + callerApp + " (pid=" + callingPid
1237 + ", uid=" + callingUid + ")"
1238 + " requires " + aInfo.permission;
1239 }
1240 Slog.w(TAG, msg);
1241 throw new SecurityException(msg);
1242 }
1243
Ben Gruverdd72c9e2013-08-06 12:34:17 -07001244 boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
Ben Gruverb6223792013-07-29 16:35:40 -07001245 callingPid, resolvedType, aInfo.applicationInfo);
Ben Gruver5e207332013-04-03 17:41:37 -07001246
Craig Mautner6170f732013-04-02 13:05:23 -07001247 if (mService.mController != null) {
Craig Mautner6170f732013-04-02 13:05:23 -07001248 try {
1249 // The Intent we give to the watcher has the extra data
1250 // stripped off, since it can contain private information.
1251 Intent watchIntent = intent.cloneFilter();
Ben Gruver5e207332013-04-03 17:41:37 -07001252 abort |= !mService.mController.activityStarting(watchIntent,
Craig Mautner6170f732013-04-02 13:05:23 -07001253 aInfo.applicationInfo.packageName);
1254 } catch (RemoteException e) {
1255 mService.mController = null;
1256 }
Ben Gruver5e207332013-04-03 17:41:37 -07001257 }
Craig Mautner6170f732013-04-02 13:05:23 -07001258
Ben Gruver5e207332013-04-03 17:41:37 -07001259 if (abort) {
1260 if (resultRecord != null) {
1261 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
Craig Mautner6170f732013-04-02 13:05:23 -07001262 Activity.RESULT_CANCELED, null);
Craig Mautner6170f732013-04-02 13:05:23 -07001263 }
Ben Gruver5e207332013-04-03 17:41:37 -07001264 // We pretend to the caller that it was really started, but
1265 // they will just get a cancel result.
1266 setDismissKeyguard(false);
1267 ActivityOptions.abort(options);
1268 return ActivityManager.START_SUCCESS;
Craig Mautner6170f732013-04-02 13:05:23 -07001269 }
1270
1271 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
Craig Mautnere0a38842013-12-16 16:14:02 -08001272 intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
1273 requestCode, componentSpecified, this, container);
Craig Mautner6170f732013-04-02 13:05:23 -07001274 if (outActivity != null) {
1275 outActivity[0] = r;
1276 }
1277
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001278 final ActivityStack stack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001279 if (stack.mResumedActivity == null
1280 || stack.mResumedActivity.info.applicationInfo.uid != callingUid) {
Craig Mautner6170f732013-04-02 13:05:23 -07001281 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
1282 PendingActivityLaunch pal =
Craig Mautnerde4ef022013-04-07 19:01:33 -07001283 new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
Craig Mautner6170f732013-04-02 13:05:23 -07001284 mService.mPendingActivityLaunches.add(pal);
1285 setDismissKeyguard(false);
1286 ActivityOptions.abort(options);
1287 return ActivityManager.START_SWITCHES_CANCELED;
1288 }
1289 }
1290
1291 if (mService.mDidAppSwitch) {
1292 // This is the second allowed switch since we stopped switches,
1293 // so now just generally allow switches. Use case: user presses
1294 // home (switches disabled, switch to home, mDidAppSwitch now true);
1295 // user taps a home icon (coming from home so allowed, we hit here
1296 // and now allow anyone to switch again).
1297 mService.mAppSwitchesAllowedTime = 0;
1298 } else {
1299 mService.mDidAppSwitch = true;
1300 }
1301
1302 mService.doPendingActivityLaunchesLocked(false);
1303
Craig Mautner8849a5e2013-04-02 16:41:03 -07001304 err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
Craig Mautner10385a12013-09-22 21:08:32 -07001305
1306 if (allPausedActivitiesComplete()) {
1307 // If someone asked to have the keyguard dismissed on the next
Craig Mautner6170f732013-04-02 13:05:23 -07001308 // activity start, but we are not actually doing an activity
1309 // switch... just dismiss the keyguard now, because we
1310 // probably want to see whatever is behind it.
1311 dismissKeyguard();
1312 }
1313 return err;
1314 }
1315
Craig Mautnerac6f8432013-07-17 13:24:59 -07001316 ActivityStack adjustStackFocus(ActivityRecord r) {
Craig Mautner1d001b62013-06-18 16:52:43 -07001317 final TaskRecord task = r.task;
1318 if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001319 if (task != null) {
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07001320 final ActivityStack taskStack = task.stack;
Craig Mautnere0a38842013-12-16 16:14:02 -08001321 if (taskStack.isOnHomeDisplay()) {
1322 if (mFocusedStack != taskStack) {
1323 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: Setting " +
1324 "focused stack to r=" + r + " task=" + task);
1325 mFocusedStack = taskStack;
1326 } else {
1327 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1328 "adjustStackFocus: Focused stack already=" + mFocusedStack);
1329 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001330 }
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07001331 return taskStack;
Craig Mautnerac6f8432013-07-17 13:24:59 -07001332 }
1333
Craig Mautnere0a38842013-12-16 16:14:02 -08001334 final ActivityContainer container = r.mInitialActivityContainer;
1335 if (container != null) {
1336 // The first time put it on the desired stack, after this put on task stack.
1337 r.mInitialActivityContainer = null;
1338 return container.mStack;
1339 }
1340
Craig Mautner4a1cb222013-12-04 16:14:06 -08001341 if (mFocusedStack != mHomeStack) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001342 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1343 "adjustStackFocus: Have a focused stack=" + mFocusedStack);
1344 return mFocusedStack;
1345 }
1346
Craig Mautnere0a38842013-12-16 16:14:02 -08001347 final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks;
1348 for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1349 final ActivityStack stack = homeDisplayStacks.get(stackNdx);
1350 if (!stack.isHomeStack()) {
1351 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1352 "adjustStackFocus: Setting focused stack=" + stack);
1353 mFocusedStack = stack;
1354 return mFocusedStack;
Craig Mautner858d8a62013-04-23 17:08:34 -07001355 }
1356 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001357
Craig Mautner4a1cb222013-12-04 16:14:06 -08001358 // Need to create an app stack for this user.
1359 int stackId = createStackOnDisplay(null, getNextStackId(), Display.DEFAULT_DISPLAY);
Craig Mautnerac6f8432013-07-17 13:24:59 -07001360 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r +
1361 " stackId=" + stackId);
1362 mFocusedStack = getStack(stackId);
Craig Mautner29219d92013-04-16 20:19:12 -07001363 return mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001364 }
1365 return mHomeStack;
1366 }
1367
Craig Mautner29219d92013-04-16 20:19:12 -07001368 void setFocusedStack(ActivityRecord r) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08001369 if (r != null) {
1370 final boolean isHomeActivity =
1371 !r.isApplicationActivity() || (r.task != null && !r.task.isApplicationTask());
1372 moveHomeStack(isHomeActivity);
Craig Mautner29219d92013-04-16 20:19:12 -07001373 }
1374 }
1375
Craig Mautner8849a5e2013-04-02 16:41:03 -07001376 final int startActivityUncheckedLocked(ActivityRecord r,
1377 ActivityRecord sourceRecord, int startFlags, boolean doResume,
1378 Bundle options) {
1379 final Intent intent = r.intent;
1380 final int callingUid = r.launchedFromUid;
1381
1382 int launchFlags = intent.getFlags();
1383
Craig Mautner8849a5e2013-04-02 16:41:03 -07001384 // We'll invoke onUserLeaving before onPause only if the launching
1385 // activity did not explicitly state that this is an automated launch.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001386 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1387 if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001388
1389 // If the caller has asked not to resume at this point, we make note
1390 // of this in the record so that we can skip it when trying to find
1391 // the top running activity.
1392 if (!doResume) {
1393 r.delayedResume = true;
1394 }
1395
1396 ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1397
1398 // If the onlyIfNeeded flag is set, then we can do this if the activity
1399 // being launched is the same as the one making the call... or, as
1400 // a special case, if we do not know the caller then we count the
1401 // current top activity as the caller.
1402 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1403 ActivityRecord checkedCaller = sourceRecord;
1404 if (checkedCaller == null) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001405 checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001406 }
1407 if (!checkedCaller.realActivity.equals(r.realActivity)) {
1408 // Caller is not the same as launcher, so always needed.
1409 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
1410 }
1411 }
1412
1413 if (sourceRecord == null) {
1414 // This activity is not being started from another... in this
1415 // case we -always- start a new task.
1416 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
Craig Mautner29219d92013-04-16 20:19:12 -07001417 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1418 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001419 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1420 }
1421 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1422 // The original activity who is starting us is running as a single
1423 // instance... this new activity it is starting must go on its
1424 // own task.
1425 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1426 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
1427 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1428 // The activity being started is a single instance... it always
1429 // gets launched into its own task.
1430 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1431 }
1432
Craig Mautner88629292013-11-10 20:39:05 -08001433 ActivityInfo newTaskInfo = null;
1434 Intent newTaskIntent = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001435 final ActivityStack sourceStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001436 if (sourceRecord != null) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001437 if (sourceRecord.finishing) {
1438 // If the source is finishing, we can't further count it as our source. This
1439 // is because the task it is associated with may now be empty and on its way out,
1440 // so we don't want to blindly throw it in to that task. Instead we will take
Craig Mautner88629292013-11-10 20:39:05 -08001441 // the NEW_TASK flow and try to find a task for it. But save the task information
1442 // so it can be used when creating the new task.
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001443 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
1444 Slog.w(TAG, "startActivity called from finishing " + sourceRecord
1445 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
1446 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
Craig Mautner88629292013-11-10 20:39:05 -08001447 newTaskInfo = sourceRecord.info;
1448 newTaskIntent = sourceRecord.task.intent;
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001449 }
1450 sourceRecord = null;
1451 sourceStack = null;
1452 } else {
1453 sourceStack = sourceRecord.task.stack;
1454 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07001455 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001456 sourceStack = null;
1457 }
1458
Craig Mautner8849a5e2013-04-02 16:41:03 -07001459 if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1460 // For whatever reason this activity is being launched into a new
1461 // task... yet the caller has requested a result back. Well, that
1462 // is pretty messed up, so instead immediately send back a cancel
1463 // and let the new task continue launched as normal without a
1464 // dependency on its originator.
1465 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1466 r.resultTo.task.stack.sendActivityResultLocked(-1,
1467 r.resultTo, r.resultWho, r.requestCode,
1468 Activity.RESULT_CANCELED, null);
1469 r.resultTo = null;
1470 }
1471
1472 boolean addingToTask = false;
1473 boolean movedHome = false;
1474 TaskRecord reuseTask = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001475 ActivityStack targetStack;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001476 if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
1477 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
1478 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1479 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1480 // If bring to front is requested, and no result is requested, and
1481 // we can find a task that was started with this same
1482 // component, then instead of launching bring that one to the front.
1483 if (r.resultTo == null) {
1484 // See if there is a task to bring to the front. If this is
1485 // a SINGLE_INSTANCE activity, there can be one and only one
1486 // instance of it in the history, and it is always in its own
1487 // unique task, so we do a special search.
1488 ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
Craig Mautnerac6f8432013-07-17 13:24:59 -07001489 ? findTaskLocked(r)
Craig Mautner8849a5e2013-04-02 16:41:03 -07001490 : findActivityLocked(intent, r.info);
1491 if (intentActivity != null) {
Craig Mautner29219d92013-04-16 20:19:12 -07001492 if (r.task == null) {
1493 r.task = intentActivity.task;
1494 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001495 targetStack = intentActivity.task.stack;
Craig Mautner0f922742013-08-06 08:44:42 -07001496 targetStack.mLastPausedActivity = null;
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001497 if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack
1498 + " from " + intentActivity);
Craig Mautnere0a38842013-12-16 16:14:02 -08001499 targetStack.moveToFront();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001500 if (intentActivity.task.intent == null) {
1501 // This task was started because of movement of
1502 // the activity based on affinity... now that we
1503 // are actually launching it, we can assign the
1504 // base intent.
1505 intentActivity.task.setIntent(intent, r.info);
1506 }
1507 // If the target task is not in the front, then we need
1508 // to bring it to the front... except... well, with
1509 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like
1510 // to have the same behavior as if a new instance was
1511 // being started, which means not bringing it to the front
1512 // if the caller is not itself in the front.
Craig Mautner165640b2013-04-20 10:34:33 -07001513 final ActivityStack lastStack = getLastStack();
1514 ActivityRecord curTop = lastStack == null?
1515 null : lastStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner7504d7b2013-09-17 10:50:53 -07001516 if (curTop != null && (curTop.task != intentActivity.task ||
1517 curTop.task != lastStack.topTask())) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001518 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Craig Mautnerd0f964f2013-08-07 11:16:33 -07001519 if (sourceRecord == null || (sourceStack.topActivity() != null &&
1520 sourceStack.topActivity().task == sourceRecord.task)) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001521 // We really do want to push this one into the
1522 // user's face, right now.
1523 movedHome = true;
Craig Mautnerb53d97c2013-10-25 11:54:37 -07001524 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001525 if ((launchFlags &
Craig Mautner29219d92013-04-16 20:19:12 -07001526 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1527 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
Craig Mautnere12a4a62013-08-29 12:24:56 -07001528 // Caller wants to appear on home activity.
Craig Mautnerae7ecab2013-09-18 11:48:14 -07001529 intentActivity.task.mOnTopOfHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001530 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001531 options = null;
1532 }
1533 }
1534 // If the caller has requested that the target task be
1535 // reset, then do so.
1536 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1537 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
1538 }
1539 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1540 // We don't need to start a new activity, and
1541 // the client said not to do anything if that
1542 // is the case, so this is it! And for paranoia, make
1543 // sure we have correctly resumed the top activity.
1544 if (doResume) {
Craig Mautner05d29032013-05-03 13:40:13 -07001545 resumeTopActivitiesLocked(targetStack, null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001546 } else {
1547 ActivityOptions.abort(options);
1548 }
1549 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1550 }
1551 if ((launchFlags &
1552 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
1553 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
1554 // The caller has requested to completely replace any
1555 // existing task with its new activity. Well that should
1556 // not be too hard...
1557 reuseTask = intentActivity.task;
1558 reuseTask.performClearTaskLocked();
1559 reuseTask.setIntent(r.intent, r.info);
1560 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
1561 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1562 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1563 // In this situation we want to remove all activities
1564 // from the task up to the one being started. In most
1565 // cases this means we are resetting the task to its
1566 // initial state.
1567 ActivityRecord top =
1568 intentActivity.task.performClearTaskLocked(r, launchFlags);
1569 if (top != null) {
1570 if (top.frontOfTask) {
1571 // Activity aliases may mean we use different
1572 // intents for the top activity, so make sure
1573 // the task now has the identity of the new
1574 // intent.
1575 top.task.setIntent(r.intent, r.info);
1576 }
1577 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
1578 r, top.task);
1579 top.deliverNewIntentLocked(callingUid, r.intent);
1580 } else {
1581 // A special case: we need to
1582 // start the activity because it is not currently
1583 // running, and the caller has asked to clear the
1584 // current task to have this activity at the top.
1585 addingToTask = true;
1586 // Now pretend like this activity is being started
1587 // by the top of its task, so it is put in the
1588 // right place.
1589 sourceRecord = intentActivity;
1590 }
1591 } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
1592 // In this case the top activity on the task is the
1593 // same as the one being launched, so we take that
1594 // as a request to bring the task to the foreground.
1595 // If the top activity in the task is the root
1596 // activity, deliver this new intent to it if it
1597 // desires.
1598 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1599 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
1600 && intentActivity.realActivity.equals(r.realActivity)) {
1601 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
1602 intentActivity.task);
1603 if (intentActivity.frontOfTask) {
1604 intentActivity.task.setIntent(r.intent, r.info);
1605 }
1606 intentActivity.deliverNewIntentLocked(callingUid, r.intent);
1607 } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
1608 // In this case we are launching the root activity
1609 // of the task, but with a different intent. We
1610 // should start a new instance on top.
1611 addingToTask = true;
1612 sourceRecord = intentActivity;
1613 }
1614 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1615 // In this case an activity is being launched in to an
1616 // existing task, without resetting that task. This
1617 // is typically the situation of launching an activity
1618 // from a notification or shortcut. We want to place
1619 // the new activity on top of the current task.
1620 addingToTask = true;
1621 sourceRecord = intentActivity;
1622 } else if (!intentActivity.task.rootWasReset) {
1623 // In this case we are launching in to an existing task
1624 // that has not yet been started from its front door.
1625 // The current task has been brought to the front.
1626 // Ideally, we'd probably like to place this new task
1627 // at the bottom of its stack, but that's a little hard
1628 // to do with the current organization of the code so
1629 // for now we'll just drop it.
1630 intentActivity.task.setIntent(r.intent, r.info);
1631 }
1632 if (!addingToTask && reuseTask == null) {
1633 // We didn't do anything... but it was needed (a.k.a., client
1634 // don't use that intent!) And for paranoia, make
1635 // sure we have correctly resumed the top activity.
1636 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001637 targetStack.resumeTopActivityLocked(null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001638 } else {
1639 ActivityOptions.abort(options);
1640 }
1641 return ActivityManager.START_TASK_TO_FRONT;
1642 }
1643 }
1644 }
1645 }
1646
1647 //String uri = r.intent.toURI();
1648 //Intent intent2 = new Intent(uri);
1649 //Slog.i(TAG, "Given intent: " + r.intent);
1650 //Slog.i(TAG, "URI is: " + uri);
1651 //Slog.i(TAG, "To intent: " + intent2);
1652
1653 if (r.packageName != null) {
1654 // If the activity being launched is the same as the one currently
1655 // at the top, then we need to check if it should only be launched
1656 // once.
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001657 ActivityStack topStack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001658 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001659 if (top != null && r.resultTo == null) {
1660 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
1661 if (top.app != null && top.app.thread != null) {
1662 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1663 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
1664 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1665 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
1666 top.task);
1667 // For paranoia, make sure we have correctly
1668 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001669 topStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001670 if (doResume) {
Craig Mautner05d29032013-05-03 13:40:13 -07001671 resumeTopActivitiesLocked();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001672 }
1673 ActivityOptions.abort(options);
1674 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1675 // We don't need to start a new activity, and
1676 // the client said not to do anything if that
1677 // is the case, so this is it!
1678 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1679 }
1680 top.deliverNewIntentLocked(callingUid, r.intent);
1681 return ActivityManager.START_DELIVERED_TO_TOP;
1682 }
1683 }
1684 }
1685 }
1686
1687 } else {
1688 if (r.resultTo != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001689 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
1690 r.requestCode, Activity.RESULT_CANCELED, null);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001691 }
1692 ActivityOptions.abort(options);
1693 return ActivityManager.START_CLASS_NOT_FOUND;
1694 }
1695
1696 boolean newTask = false;
1697 boolean keepCurTransition = false;
1698
1699 // Should this be considered a new task?
1700 if (r.resultTo == null && !addingToTask
1701 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001702 targetStack = adjustStackFocus(r);
Craig Mautnere0a38842013-12-16 16:14:02 -08001703 targetStack.moveToFront();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001704 if (reuseTask == null) {
Craig Mautner88629292013-11-10 20:39:05 -08001705 r.setTask(targetStack.createTaskRecord(getNextTaskId(),
1706 newTaskInfo != null ? newTaskInfo : r.info,
1707 newTaskIntent != null ? newTaskIntent : intent,
1708 true), null, true);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001709 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
1710 r.task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001711 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001712 r.setTask(reuseTask, reuseTask, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001713 }
1714 newTask = true;
1715 if (!movedHome) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001716 if ((launchFlags &
1717 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
1718 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
1719 // Caller wants to appear on home activity, so before starting
1720 // their own activity we will bring home to the front.
Craig Mautnere0a38842013-12-16 16:14:02 -08001721 r.task.mOnTopOfHome = r.task.stack.isOnHomeDisplay();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001722 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001723 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001724 } else if (sourceRecord != null) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001725 TaskRecord sourceTask = sourceRecord.task;
Craig Mautner525f3d92013-05-07 14:01:50 -07001726 targetStack = sourceTask.stack;
Craig Mautnere0a38842013-12-16 16:14:02 -08001727 targetStack.moveToFront();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001728 if (!addingToTask &&
1729 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
1730 // In this case, we are adding the activity to an existing
1731 // task, but the caller has asked to clear that task if the
1732 // activity is already running.
Craig Mautner525f3d92013-05-07 14:01:50 -07001733 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001734 keepCurTransition = true;
1735 if (top != null) {
1736 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
1737 top.deliverNewIntentLocked(callingUid, r.intent);
1738 // For paranoia, make sure we have correctly
1739 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001740 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001741 if (doResume) {
1742 targetStack.resumeTopActivityLocked(null);
1743 }
1744 ActivityOptions.abort(options);
1745 return ActivityManager.START_DELIVERED_TO_TOP;
1746 }
1747 } else if (!addingToTask &&
1748 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1749 // In this case, we are launching an activity in our own task
1750 // that may already be running somewhere in the history, and
1751 // we want to shuffle it to the front of the stack if so.
Craig Mautner525f3d92013-05-07 14:01:50 -07001752 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001753 if (top != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001754 final TaskRecord task = top.task;
1755 task.moveActivityToFrontLocked(top);
1756 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001757 top.updateOptionsLocked(options);
1758 top.deliverNewIntentLocked(callingUid, r.intent);
Craig Mautner0f922742013-08-06 08:44:42 -07001759 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001760 if (doResume) {
1761 targetStack.resumeTopActivityLocked(null);
1762 }
1763 return ActivityManager.START_DELIVERED_TO_TOP;
1764 }
1765 }
1766 // An existing activity is starting this new activity, so we want
1767 // to keep the new one in the same task as the one that is starting
1768 // it.
Craig Mautner525f3d92013-05-07 14:01:50 -07001769 r.setTask(sourceTask, sourceRecord.thumbHolder, false);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001770 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001771 + " in existing task " + r.task + " from source " + sourceRecord);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001772
1773 } else {
1774 // This not being started from an existing activity, and not part
1775 // of a new task... just put it in the top task, though these days
1776 // this case should never happen.
Craig Mautnerac6f8432013-07-17 13:24:59 -07001777 targetStack = adjustStackFocus(r);
Craig Mautnere0a38842013-12-16 16:14:02 -08001778 targetStack.moveToFront();
Craig Mautner1602ec22013-05-12 10:24:27 -07001779 ActivityRecord prev = targetStack.topActivity();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001780 r.setTask(prev != null ? prev.task
1781 : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1782 null, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001783 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1784 + " in new guessed " + r.task);
1785 }
1786
1787 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
1788 intent, r.getUriPermissionsLocked());
1789
1790 if (newTask) {
1791 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
1792 }
1793 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
Craig Mautner0f922742013-08-06 08:44:42 -07001794 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001795 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
Craig Mautner1d001b62013-06-18 16:52:43 -07001796 mService.setFocusedActivityLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001797 return ActivityManager.START_SUCCESS;
1798 }
1799
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001800 void acquireLaunchWakelock() {
1801 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
1802 throw new IllegalStateException("Calling must be system uid");
1803 }
1804 mLaunchingActivity.acquire();
1805 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
1806 // To be safe, don't allow the wake lock to be held for too long.
1807 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
1808 }
1809 }
1810
Craig Mautnerf3333272013-04-22 10:55:53 -07001811 // Checked.
1812 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
1813 Configuration config) {
1814 if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
1815
Craig Mautnerf3333272013-04-22 10:55:53 -07001816 ArrayList<ActivityRecord> stops = null;
1817 ArrayList<ActivityRecord> finishes = null;
1818 ArrayList<UserStartedState> startingUsers = null;
1819 int NS = 0;
1820 int NF = 0;
1821 IApplicationThread sendThumbnail = null;
1822 boolean booting = false;
1823 boolean enableScreen = false;
1824 boolean activityRemoved = false;
1825
1826 ActivityRecord r = ActivityRecord.forToken(token);
1827 if (r != null) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07001828 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
1829 Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07001830 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
1831 r.finishLaunchTickingLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001832 if (fromTimeout) {
1833 reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
Craig Mautnerf3333272013-04-22 10:55:53 -07001834 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001835
1836 // This is a hack to semi-deal with a race condition
1837 // in the client where it can be constructed with a
1838 // newer configuration from when we asked it to launch.
1839 // We'll update with whatever configuration it now says
1840 // it used to launch.
1841 if (config != null) {
1842 r.configuration = config;
1843 }
1844
1845 // We are now idle. If someone is waiting for a thumbnail from
1846 // us, we can now deliver.
1847 r.idle = true;
1848
1849 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
1850 sendThumbnail = r.app.thread;
1851 r.thumbnailNeeded = false;
1852 }
1853
1854 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
1855 if (!mService.mBooted && isFrontStack(r.task.stack)) {
1856 mService.mBooted = true;
1857 enableScreen = true;
1858 }
1859 }
1860
1861 if (allResumedActivitiesIdle()) {
1862 if (r != null) {
1863 mService.scheduleAppGcsLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001864 }
1865
1866 if (mLaunchingActivity.isHeld()) {
1867 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
1868 if (VALIDATE_WAKE_LOCK_CALLER &&
1869 Binder.getCallingUid() != Process.myUid()) {
1870 throw new IllegalStateException("Calling must be system uid");
1871 }
1872 mLaunchingActivity.release();
1873 }
1874 ensureActivitiesVisibleLocked(null, 0);
Craig Mautnerf3333272013-04-22 10:55:53 -07001875 }
1876
1877 // Atomically retrieve all of the other things to do.
1878 stops = processStoppingActivitiesLocked(true);
1879 NS = stops != null ? stops.size() : 0;
1880 if ((NF=mFinishingActivities.size()) > 0) {
1881 finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
1882 mFinishingActivities.clear();
1883 }
1884
1885 final ArrayList<ActivityRecord> thumbnails;
1886 final int NT = mCancelledThumbnails.size();
1887 if (NT > 0) {
1888 thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
1889 mCancelledThumbnails.clear();
1890 } else {
1891 thumbnails = null;
1892 }
1893
1894 if (isFrontStack(mHomeStack)) {
1895 booting = mService.mBooting;
1896 mService.mBooting = false;
1897 }
1898
1899 if (mStartingUsers.size() > 0) {
1900 startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
1901 mStartingUsers.clear();
1902 }
1903
1904 // Perform the following actions from unsynchronized state.
1905 final IApplicationThread thumbnailThread = sendThumbnail;
1906 mHandler.post(new Runnable() {
1907 @Override
1908 public void run() {
1909 if (thumbnailThread != null) {
1910 try {
1911 thumbnailThread.requestThumbnail(token);
1912 } catch (Exception e) {
1913 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
1914 mService.sendPendingThumbnail(null, token, null, null, true);
1915 }
1916 }
1917
1918 // Report back to any thumbnail receivers.
1919 for (int i = 0; i < NT; i++) {
1920 ActivityRecord r = thumbnails.get(i);
1921 mService.sendPendingThumbnail(r, null, null, null, true);
1922 }
1923 }
1924 });
1925
1926 // Stop any activities that are scheduled to do so but have been
1927 // waiting for the next one to start.
1928 for (int i = 0; i < NS; i++) {
1929 r = stops.get(i);
1930 final ActivityStack stack = r.task.stack;
1931 if (r.finishing) {
1932 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
1933 } else {
1934 stack.stopActivityLocked(r);
1935 }
1936 }
1937
1938 // Finish any activities that are scheduled to do so but have been
1939 // waiting for the next one to start.
1940 for (int i = 0; i < NF; i++) {
1941 r = finishes.get(i);
1942 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
1943 }
1944
1945 if (booting) {
1946 mService.finishBooting();
1947 } else if (startingUsers != null) {
1948 for (int i = 0; i < startingUsers.size(); i++) {
1949 mService.finishUserSwitch(startingUsers.get(i));
1950 }
1951 }
1952
1953 mService.trimApplications();
1954 //dump();
1955 //mWindowManager.dump();
1956
1957 if (enableScreen) {
1958 mService.enableScreenAfterBoot();
1959 }
1960
1961 if (activityRemoved) {
Craig Mautner05d29032013-05-03 13:40:13 -07001962 resumeTopActivitiesLocked();
Craig Mautnerf3333272013-04-22 10:55:53 -07001963 }
1964
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001965 return r;
Craig Mautnerf3333272013-04-22 10:55:53 -07001966 }
1967
Craig Mautner8e569572013-10-11 17:36:59 -07001968 boolean handleAppDiedLocked(ProcessRecord app) {
Craig Mautner19091252013-10-05 00:03:53 -07001969 boolean hasVisibleActivities = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08001970 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1971 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08001972 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1973 hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app);
1974 }
Craig Mautner6b74cb52013-09-27 17:02:21 -07001975 }
Craig Mautner19091252013-10-05 00:03:53 -07001976 return hasVisibleActivities;
Craig Mautner8d341ef2013-03-26 09:03:27 -07001977 }
1978
1979 void closeSystemDialogsLocked() {
Craig Mautnere0a38842013-12-16 16:14:02 -08001980 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1981 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08001982 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1983 stacks.get(stackNdx).closeSystemDialogsLocked();
1984 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07001985 }
1986 }
1987
Craig Mautner93529a42013-10-04 15:03:13 -07001988 void removeUserLocked(int userId) {
Craig Mautner4f1df4f2013-10-15 15:44:14 -07001989 mUserStackInFront.delete(userId);
Craig Mautner93529a42013-10-04 15:03:13 -07001990 }
1991
Craig Mautner8d341ef2013-03-26 09:03:27 -07001992 /**
1993 * @return true if some activity was finished (or would have finished if doit were true).
1994 */
1995 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
1996 boolean didSomething = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08001997 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1998 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08001999 final int numStacks = stacks.size();
2000 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2001 final ActivityStack stack = stacks.get(stackNdx);
2002 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
2003 didSomething = true;
2004 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002005 }
2006 }
2007 return didSomething;
2008 }
2009
Dianne Hackborna413dc02013-07-12 12:02:55 -07002010 void updatePreviousProcessLocked(ActivityRecord r) {
2011 // Now that this process has stopped, we may want to consider
2012 // it to be the previous app to try to keep around in case
2013 // the user wants to return to it.
2014
2015 // First, found out what is currently the foreground app, so that
2016 // we don't blow away the previous app if this activity is being
2017 // hosted by the process that is actually still the foreground.
2018 ProcessRecord fgApp = null;
Craig Mautnere0a38842013-12-16 16:14:02 -08002019 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2020 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002021 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2022 final ActivityStack stack = stacks.get(stackNdx);
2023 if (isFrontStack(stack)) {
2024 if (stack.mResumedActivity != null) {
2025 fgApp = stack.mResumedActivity.app;
2026 } else if (stack.mPausingActivity != null) {
2027 fgApp = stack.mPausingActivity.app;
2028 }
2029 break;
Dianne Hackborna413dc02013-07-12 12:02:55 -07002030 }
Dianne Hackborna413dc02013-07-12 12:02:55 -07002031 }
2032 }
2033
2034 // Now set this one as the previous process, only if that really
2035 // makes sense to.
2036 if (r.app != null && fgApp != null && r.app != fgApp
2037 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
Craig Mautner4ef26932013-09-18 15:15:52 -07002038 && r.app != mService.mHomeProcess) {
Dianne Hackborna413dc02013-07-12 12:02:55 -07002039 mService.mPreviousProcess = r.app;
2040 mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
2041 }
2042 }
2043
Craig Mautner05d29032013-05-03 13:40:13 -07002044 boolean resumeTopActivitiesLocked() {
2045 return resumeTopActivitiesLocked(null, null, null);
2046 }
2047
2048 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
2049 Bundle targetOptions) {
2050 if (targetStack == null) {
2051 targetStack = getFocusedStack();
2052 }
2053 boolean result = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002054 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2055 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002056 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2057 final ActivityStack stack = stacks.get(stackNdx);
2058 if (isFrontStack(stack)) {
2059 if (stack == targetStack) {
2060 result = stack.resumeTopActivityLocked(target, targetOptions);
2061 } else {
2062 stack.resumeTopActivityLocked(null);
2063 }
Craig Mautner05d29032013-05-03 13:40:13 -07002064 }
Craig Mautnerf88c50f2013-04-18 19:25:12 -07002065 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002066 }
Craig Mautner05d29032013-05-03 13:40:13 -07002067 return result;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002068 }
2069
2070 void finishTopRunningActivityLocked(ProcessRecord app) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002071 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2072 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002073 final int numStacks = stacks.size();
2074 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2075 final ActivityStack stack = stacks.get(stackNdx);
2076 stack.finishTopRunningActivityLocked(app);
2077 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002078 }
2079 }
2080
Craig Mautner8d341ef2013-03-26 09:03:27 -07002081 void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002082 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2083 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002084 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2085 if (stacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) {
2086 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack="
2087 + stacks.get(stackNdx));
2088 return;
2089 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002090 }
2091 }
2092 }
2093
Craig Mautner967212c2013-04-13 21:10:58 -07002094 ActivityStack getStack(int stackId) {
Craig Mautner4504de52013-12-20 09:06:56 -08002095 WeakReference<ActivityContainer> weakReference = mActivityContainers.get(stackId);
2096 if (weakReference != null) {
2097 ActivityContainer activityContainer = weakReference.get();
2098 if (activityContainer != null) {
2099 return activityContainer.mStack;
2100 } else {
2101 mActivityContainers.remove(stackId);
2102 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002103 }
2104 return null;
2105 }
2106
Craig Mautner967212c2013-04-13 21:10:58 -07002107 ArrayList<ActivityStack> getStacks() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002108 ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>();
Craig Mautnere0a38842013-12-16 16:14:02 -08002109 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2110 allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002111 }
2112 return allStacks;
Craig Mautner967212c2013-04-13 21:10:58 -07002113 }
2114
Craig Mautner4a1cb222013-12-04 16:14:06 -08002115 IBinder getHomeActivityToken() {
2116 final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
2117 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
2118 final TaskRecord task = tasks.get(taskNdx);
2119 if (task.isHomeTask()) {
2120 final ArrayList<ActivityRecord> activities = task.mActivities;
2121 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2122 final ActivityRecord r = activities.get(activityNdx);
2123 if (r.isHomeActivity()) {
2124 return r.appToken;
2125 }
2126 }
2127 }
2128 }
2129 return null;
2130 }
2131
2132 ActivityContainer createActivityContainer(ActivityRecord parentActivity, int stackId,
2133 IActivityContainerCallback callback) {
2134 ActivityContainer activityContainer = new ActivityContainer(parentActivity, stackId,
2135 callback);
Craig Mautner4504de52013-12-20 09:06:56 -08002136 mActivityContainers.put(stackId, new WeakReference<ActivityContainer>(activityContainer));
Craig Mautner4a1cb222013-12-04 16:14:06 -08002137 if (parentActivity != null) {
2138 parentActivity.mChildContainers.add(activityContainer.mStack);
2139 }
2140 return activityContainer;
2141 }
2142
2143 ActivityContainer createActivityContainer(ActivityRecord parentActivity,
2144 IActivityContainerCallback callback) {
2145 return createActivityContainer(parentActivity, getNextStackId(), callback);
2146 }
2147
Craig Mautner34b73df2014-01-12 21:11:08 -08002148 void removeChildActivityContainers(ActivityRecord parentActivity) {
2149 for (int ndx = mActivityContainers.size() - 1; ndx >= 0; --ndx) {
2150 final ActivityContainer container = mActivityContainers.valueAt(ndx).get();
2151 if (container == null) {
2152 mActivityContainers.removeAt(ndx);
2153 continue;
2154 }
2155 if (container.mParentActivity != parentActivity) {
2156 continue;
2157 }
2158
2159 ActivityStack stack = container.mStack;
2160 ActivityRecord top = stack.topRunningNonDelayedActivityLocked(null);
2161 if (top != null) {
2162 // TODO: Make sure the next activity doesn't start up when top is destroyed.
2163 stack.destroyActivityLocked(top, true, true, "stack removal");
2164 }
2165 mActivityContainers.removeAt(ndx);
2166 container.detachLocked();
2167 }
2168 }
2169
Craig Mautner4a1cb222013-12-04 16:14:06 -08002170 private int createStackOnDisplay(ActivityRecord parentActivity, int stackId, int displayId) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002171 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2172 if (activityDisplay == null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002173 return -1;
2174 }
2175
2176 ActivityContainer activityContainer =
2177 createActivityContainer(parentActivity, stackId, null);
Craig Mautnere0a38842013-12-16 16:14:02 -08002178 activityContainer.attachToDisplayLocked(activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002179 return stackId;
2180 }
2181
2182 int getNextStackId() {
Craig Mautner858d8a62013-04-23 17:08:34 -07002183 while (true) {
2184 if (++mLastStackId <= HOME_STACK_ID) {
2185 mLastStackId = HOME_STACK_ID + 1;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002186 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002187 if (getStack(mLastStackId) == null) {
2188 break;
2189 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002190 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002191 return mLastStackId;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002192 }
2193
2194 void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002195 final TaskRecord task = anyTaskForIdLocked(taskId);
2196 if (task == null) {
2197 return;
2198 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002199 final ActivityStack stack = getStack(stackId);
2200 if (stack == null) {
2201 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
2202 return;
2203 }
Craig Mautner04a0ea62014-01-13 12:51:26 -08002204 task.stack.removeTask(task);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002205 stack.addTask(task, toTop);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002206 mWindowManager.addTask(taskId, stackId, toTop);
Craig Mautner05d29032013-05-03 13:40:13 -07002207 resumeTopActivitiesLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002208 }
2209
Craig Mautnerac6f8432013-07-17 13:24:59 -07002210 ActivityRecord findTaskLocked(ActivityRecord r) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07002211 if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r);
Craig Mautnere0a38842013-12-16 16:14:02 -08002212 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2213 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002214 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2215 final ActivityStack stack = stacks.get(stackNdx);
2216 if (!r.isApplicationActivity() && !stack.isHomeStack()) {
2217 if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: " + stack);
2218 continue;
2219 }
2220 final ActivityRecord ar = stack.findTaskLocked(r);
2221 if (ar != null) {
2222 return ar;
2223 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07002224 }
2225 }
Dianne Hackborn2a272d42013-10-16 13:34:33 -07002226 if (DEBUG_TASKS) Slog.d(TAG, "No task found");
Craig Mautner8849a5e2013-04-02 16:41:03 -07002227 return null;
2228 }
2229
2230 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002231 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2232 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002233 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2234 final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info);
2235 if (ar != null) {
2236 return ar;
2237 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07002238 }
2239 }
2240 return null;
2241 }
2242
Craig Mautner8d341ef2013-03-26 09:03:27 -07002243 void goingToSleepLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002244 scheduleSleepTimeout();
2245 if (!mGoingToSleep.isHeld()) {
2246 mGoingToSleep.acquire();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002247 if (mLaunchingActivity.isHeld()) {
2248 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2249 throw new IllegalStateException("Calling must be system uid");
Craig Mautner0eea92c2013-05-16 13:35:39 -07002250 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002251 mLaunchingActivity.release();
2252 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
Craig Mautner0eea92c2013-05-16 13:35:39 -07002253 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002254 }
Amith Yamasanice15e152013-09-19 12:30:32 -07002255 checkReadyForSleepLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002256 }
2257
2258 boolean shutdownLocked(int timeout) {
2259 boolean timedout = false;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002260 goingToSleepLocked();
Craig Mautner0eea92c2013-05-16 13:35:39 -07002261
2262 final long endTime = System.currentTimeMillis() + timeout;
2263 while (true) {
2264 boolean cantShutdown = false;
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 cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
2269 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002270 }
2271 if (cantShutdown) {
2272 long timeRemaining = endTime - System.currentTimeMillis();
2273 if (timeRemaining > 0) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002274 try {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002275 mService.wait(timeRemaining);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002276 } catch (InterruptedException e) {
2277 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002278 } else {
2279 Slog.w(TAG, "Activity manager shutdown timed out");
2280 timedout = true;
2281 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002282 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002283 } else {
2284 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002285 }
2286 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002287
2288 // Force checkReadyForSleep to complete.
2289 mSleepTimeout = true;
2290 checkReadyForSleepLocked();
2291
Craig Mautner8d341ef2013-03-26 09:03:27 -07002292 return timedout;
2293 }
2294
2295 void comeOutOfSleepIfNeededLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002296 removeSleepTimeouts();
2297 if (mGoingToSleep.isHeld()) {
2298 mGoingToSleep.release();
2299 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002300 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2301 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002302 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2303 final ActivityStack stack = stacks.get(stackNdx);
2304 stack.awakeFromSleepingLocked();
2305 if (isFrontStack(stack)) {
2306 resumeTopActivitiesLocked();
2307 }
Craig Mautner5314a402013-09-26 12:40:16 -07002308 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002309 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002310 mGoingToSleepActivities.clear();
2311 }
2312
2313 void activitySleptLocked(ActivityRecord r) {
2314 mGoingToSleepActivities.remove(r);
2315 checkReadyForSleepLocked();
2316 }
2317
2318 void checkReadyForSleepLocked() {
2319 if (!mService.isSleepingOrShuttingDown()) {
2320 // Do not care.
2321 return;
2322 }
2323
2324 if (!mSleepTimeout) {
2325 boolean dontSleep = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002326 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2327 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002328 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2329 dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
2330 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002331 }
2332
2333 if (mStoppingActivities.size() > 0) {
2334 // Still need to tell some activities to stop; can't sleep yet.
2335 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2336 + mStoppingActivities.size() + " activities");
2337 scheduleIdleLocked();
2338 dontSleep = true;
2339 }
2340
2341 if (mGoingToSleepActivities.size() > 0) {
2342 // Still need to tell some activities to sleep; can't sleep yet.
2343 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2344 + mGoingToSleepActivities.size() + " activities");
2345 dontSleep = true;
2346 }
2347
2348 if (dontSleep) {
2349 return;
2350 }
2351 }
2352
Craig Mautnere0a38842013-12-16 16:14:02 -08002353 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2354 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002355 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2356 stacks.get(stackNdx).goToSleep();
2357 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002358 }
2359
2360 removeSleepTimeouts();
2361
2362 if (mGoingToSleep.isHeld()) {
2363 mGoingToSleep.release();
2364 }
2365 if (mService.mShuttingDown) {
2366 mService.notifyAll();
2367 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002368 }
2369
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002370 boolean reportResumedActivityLocked(ActivityRecord r) {
2371 final ActivityStack stack = r.task.stack;
2372 if (isFrontStack(stack)) {
Jeff Sharkey5782da72013-04-25 14:32:30 -07002373 mService.updateUsageStats(r, true);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002374 }
2375 if (allResumedActivitiesComplete()) {
2376 ensureActivitiesVisibleLocked(null, 0);
2377 mWindowManager.executeAppTransition();
2378 return true;
2379 }
2380 return false;
2381 }
2382
Craig Mautner8d341ef2013-03-26 09:03:27 -07002383 void handleAppCrashLocked(ProcessRecord app) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002384 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2385 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002386 final int numStacks = stacks.size();
2387 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2388 final ActivityStack stack = stacks.get(stackNdx);
2389 stack.handleAppCrashLocked(app);
2390 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002391 }
2392 }
2393
Craig Mautnerde4ef022013-04-07 19:01:33 -07002394 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
Craig Mautner580ea812013-04-25 12:58:38 -07002395 // First the front stacks. In case any are not fullscreen and are in front of home.
2396 boolean showHomeBehindStack = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002397 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2398 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002399 final int topStackNdx = stacks.size() - 1;
2400 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
2401 final ActivityStack stack = stacks.get(stackNdx);
2402 if (stackNdx == topStackNdx) {
2403 // Top stack.
2404 showHomeBehindStack =
2405 stack.ensureActivitiesVisibleLocked(starting, configChanges);
2406 } else {
2407 // Back stack.
2408 stack.ensureActivitiesVisibleLocked(starting, configChanges,
2409 showHomeBehindStack);
2410 }
Craig Mautner580ea812013-04-25 12:58:38 -07002411 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002412 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002413 }
2414
2415 void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002416 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2417 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002418 final int numStacks = stacks.size();
2419 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2420 final ActivityStack stack = stacks.get(stackNdx);
2421 stack.scheduleDestroyActivities(app, false, reason);
2422 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002423 }
2424 }
2425
2426 boolean switchUserLocked(int userId, UserStartedState uss) {
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002427 mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId());
2428 final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
Craig Mautner2420ead2013-04-01 17:13:20 -07002429 mCurrentUser = userId;
Craig Mautnerac6f8432013-07-17 13:24:59 -07002430
Craig Mautner858d8a62013-04-23 17:08:34 -07002431 mStartingUsers.add(uss);
Craig Mautnere0a38842013-12-16 16:14:02 -08002432 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2433 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002434 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002435 final ActivityStack stack = stacks.get(stackNdx);
2436 stack.switchUserLocked(userId);
2437 mWindowManager.moveTaskToTop(stack.topTask().taskId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002438 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07002439 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002440
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002441 ActivityStack stack = getStack(restoreStackId);
2442 if (stack == null) {
2443 stack = mHomeStack;
2444 }
2445 final boolean homeInFront = stack.isHomeStack();
Craig Mautnere0a38842013-12-16 16:14:02 -08002446 if (stack.isOnHomeDisplay()) {
2447 moveHomeStack(homeInFront);
2448 mWindowManager.moveTaskToTop(stack.topTask().taskId);
2449 } else {
2450 // Stack was moved to another display while user was swapped out.
2451 resumeHomeActivity(null);
2452 }
Craig Mautner93529a42013-10-04 15:03:13 -07002453 return homeInFront;
Craig Mautner2219a1b2013-03-25 09:44:30 -07002454 }
2455
Craig Mautnerde4ef022013-04-07 19:01:33 -07002456 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2457 int N = mStoppingActivities.size();
2458 if (N <= 0) return null;
2459
2460 ArrayList<ActivityRecord> stops = null;
2461
2462 final boolean nowVisible = allResumedActivitiesVisible();
2463 for (int i=0; i<N; i++) {
2464 ActivityRecord s = mStoppingActivities.get(i);
Craig Mautnera7f2bd42013-10-15 16:13:50 -07002465 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
Craig Mautnerde4ef022013-04-07 19:01:33 -07002466 + nowVisible + " waitingVisible=" + s.waitingVisible
2467 + " finishing=" + s.finishing);
2468 if (s.waitingVisible && nowVisible) {
2469 mWaitingVisibleActivities.remove(s);
2470 s.waitingVisible = false;
2471 if (s.finishing) {
2472 // If this activity is finishing, it is sitting on top of
2473 // everyone else but we now know it is no longer needed...
2474 // so get rid of it. Otherwise, we need to go through the
2475 // normal flow and hide it once we determine that it is
2476 // hidden by the activities in front of it.
2477 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002478 mWindowManager.setAppVisibility(s.appToken, false);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002479 }
2480 }
2481 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2482 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2483 if (stops == null) {
2484 stops = new ArrayList<ActivityRecord>();
2485 }
2486 stops.add(s);
2487 mStoppingActivities.remove(i);
2488 N--;
2489 i--;
2490 }
2491 }
2492
2493 return stops;
2494 }
2495
Craig Mautnercf910b02013-04-23 11:23:27 -07002496 void validateTopActivitiesLocked() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002497 // FIXME
2498/* for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2499 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautnercf910b02013-04-23 11:23:27 -07002500 final ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002501 final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
Craig Mautnercf910b02013-04-23 11:23:27 -07002502 if (isFrontStack(stack)) {
2503 if (r == null) {
2504 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2505 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002506 final ActivityRecord pausing = stack.mPausingActivity;
2507 if (pausing != null && pausing == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002508 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002509 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002510 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002511 if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002512 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002513 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002514 }
2515 }
2516 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002517 final ActivityRecord resumed = stack.mResumedActivity;
2518 if (resumed != null && resumed == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002519 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002520 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002521 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002522 if (r != null && (state == ActivityState.INITIALIZING
2523 || state == ActivityState.RESUMED)) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002524 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002525 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002526 }
2527 }
2528 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002529*/
Craig Mautner76ea2242013-05-15 11:40:05 -07002530 }
2531
Craig Mautner27084302013-03-25 08:05:25 -07002532 public void dump(PrintWriter pw, String prefix) {
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002533 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity=");
Craig Mautner27084302013-03-25 08:05:25 -07002534 pw.println(mDismissKeyguardOnNextActivity);
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002535 pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002536 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002537 pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
2538 pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
2539 pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
Craig Mautner27084302013-03-25 08:05:25 -07002540 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002541
Craig Mautner20e72272013-04-01 13:45:53 -07002542 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002543 return getFocusedStack().getDumpActivitiesLocked(name);
Craig Mautner20e72272013-04-01 13:45:53 -07002544 }
2545
Dianne Hackborn390517b2013-05-30 15:03:32 -07002546 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2547 boolean needSep, String prefix) {
2548 if (activity != null) {
2549 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2550 if (needSep) {
2551 pw.println();
Dianne Hackborn390517b2013-05-30 15:03:32 -07002552 }
2553 pw.print(prefix);
2554 pw.println(activity);
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002555 return true;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002556 }
2557 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002558 return false;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002559 }
2560
Craig Mautner8d341ef2013-03-26 09:03:27 -07002561 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2562 boolean dumpClient, String dumpPackage) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002563 boolean printed = false;
2564 boolean needSep = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002565 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2566 ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
2567 pw.print("Display #"); pw.println(activityDisplay.mDisplayId);
2568 ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002569 final int numStacks = stacks.size();
2570 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2571 final ActivityStack stack = stacks.get(stackNdx);
2572 StringBuilder stackHeader = new StringBuilder(128);
2573 stackHeader.append(" Stack #");
2574 stackHeader.append(stack.mStackId);
2575 stackHeader.append(":");
2576 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
2577 needSep, stackHeader.toString());
2578 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false,
2579 !dumpAll, false, dumpPackage, true,
2580 " Running activities (most recent first):", null);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002581
Craig Mautner4a1cb222013-12-04 16:14:06 -08002582 needSep = printed;
2583 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
2584 " mPausingActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002585 if (pr) {
2586 printed = true;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002587 needSep = false;
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002588 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002589 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
2590 " mResumedActivity: ");
2591 if (pr) {
2592 printed = true;
2593 needSep = false;
2594 }
2595 if (dumpAll) {
2596 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
2597 " mLastPausedActivity: ");
2598 if (pr) {
2599 printed = true;
2600 needSep = true;
2601 }
2602 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
2603 needSep, " mLastNoHistoryActivity: ");
2604 }
2605 needSep = printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002606 }
2607 }
2608
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002609 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll,
2610 false, dumpPackage, true, " Activities waiting to finish:", null);
2611 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll,
2612 false, dumpPackage, true, " Activities waiting to stop:", null);
2613 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll,
2614 false, dumpPackage, true, " Activities waiting for another to become visible:",
2615 null);
2616 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2617 false, dumpPackage, true, " Activities waiting to sleep:", null);
2618 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2619 false, dumpPackage, true, " Activities waiting to sleep:", null);
Craig Mautnerf3333272013-04-22 10:55:53 -07002620
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002621 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002622 }
2623
Dianne Hackborn390517b2013-05-30 15:03:32 -07002624 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
Craig Mautner8d341ef2013-03-26 09:03:27 -07002625 String prefix, String label, boolean complete, boolean brief, boolean client,
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002626 String dumpPackage, boolean needNL, String header1, String header2) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002627 TaskRecord lastTask = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002628 String innerPrefix = null;
2629 String[] args = null;
2630 boolean printed = false;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002631 for (int i=list.size()-1; i>=0; i--) {
2632 final ActivityRecord r = list.get(i);
2633 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2634 continue;
2635 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002636 if (innerPrefix == null) {
2637 innerPrefix = prefix + " ";
2638 args = new String[0];
2639 }
2640 printed = true;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002641 final boolean full = !brief && (complete || !r.isInHistory());
2642 if (needNL) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07002643 pw.println("");
Craig Mautner8d341ef2013-03-26 09:03:27 -07002644 needNL = false;
2645 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002646 if (header1 != null) {
2647 pw.println(header1);
2648 header1 = null;
2649 }
2650 if (header2 != null) {
2651 pw.println(header2);
2652 header2 = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002653 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002654 if (lastTask != r.task) {
2655 lastTask = r.task;
2656 pw.print(prefix);
2657 pw.print(full ? "* " : " ");
2658 pw.println(lastTask);
2659 if (full) {
2660 lastTask.dump(pw, prefix + " ");
2661 } else if (complete) {
2662 // Complete + brief == give a summary. Isn't that obvious?!?
2663 if (lastTask.intent != null) {
2664 pw.print(prefix); pw.print(" ");
2665 pw.println(lastTask.intent.toInsecureStringWithClip());
2666 }
2667 }
2668 }
2669 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
2670 pw.print(" #"); pw.print(i); pw.print(": ");
2671 pw.println(r);
2672 if (full) {
2673 r.dump(pw, innerPrefix);
2674 } else if (complete) {
2675 // Complete + brief == give a summary. Isn't that obvious?!?
2676 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2677 if (r.app != null) {
2678 pw.print(innerPrefix); pw.println(r.app);
2679 }
2680 }
2681 if (client && r.app != null && r.app.thread != null) {
2682 // flush anything that is already in the PrintWriter since the thread is going
2683 // to write to the file descriptor directly
2684 pw.flush();
2685 try {
2686 TransferPipe tp = new TransferPipe();
2687 try {
2688 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2689 r.appToken, innerPrefix, args);
2690 // Short timeout, since blocking here can
2691 // deadlock with the application.
2692 tp.go(fd, 2000);
2693 } finally {
2694 tp.kill();
2695 }
2696 } catch (IOException e) {
2697 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2698 } catch (RemoteException e) {
2699 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2700 }
2701 needNL = true;
2702 }
2703 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002704 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002705 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002706
Craig Mautnerf3333272013-04-22 10:55:53 -07002707 void scheduleIdleTimeoutLocked(ActivityRecord next) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002708 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
Craig Mautnerc64f73e2013-04-24 16:44:56 -07002709 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2710 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
Craig Mautnerf3333272013-04-22 10:55:53 -07002711 }
2712
2713 final void scheduleIdleLocked() {
Craig Mautner05d29032013-05-03 13:40:13 -07002714 mHandler.sendEmptyMessage(IDLE_NOW_MSG);
Craig Mautnerf3333272013-04-22 10:55:53 -07002715 }
2716
2717 void removeTimeoutsForActivityLocked(ActivityRecord r) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002718 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07002719 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2720 }
2721
Craig Mautner05d29032013-05-03 13:40:13 -07002722 final void scheduleResumeTopActivities() {
Craig Mautner34b73df2014-01-12 21:11:08 -08002723 if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
2724 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2725 }
Craig Mautner05d29032013-05-03 13:40:13 -07002726 }
2727
Craig Mautner0eea92c2013-05-16 13:35:39 -07002728 void removeSleepTimeouts() {
2729 mSleepTimeout = false;
2730 mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2731 }
2732
2733 final void scheduleSleepTimeout() {
2734 removeSleepTimeouts();
2735 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2736 }
2737
Craig Mautner4a1cb222013-12-04 16:14:06 -08002738 @Override
2739 public void onDisplayAdded(int displayId) {
2740 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
2741 }
2742
2743 @Override
2744 public void onDisplayRemoved(int displayId) {
2745 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
2746 }
2747
2748 @Override
2749 public void onDisplayChanged(int displayId) {
2750 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
2751 }
2752
2753 public void handleDisplayAddedLocked(int displayId) {
Craig Mautner4504de52013-12-20 09:06:56 -08002754 boolean newDisplay;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002755 synchronized (mService) {
Craig Mautner4504de52013-12-20 09:06:56 -08002756 newDisplay = mActivityDisplays.get(displayId) == null;
2757 if (newDisplay) {
2758 ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
2759 mActivityDisplays.put(displayId, activityDisplay);
2760 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002761 }
Craig Mautner4504de52013-12-20 09:06:56 -08002762 if (newDisplay) {
2763 mWindowManager.onDisplayAdded(displayId);
2764 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002765 }
2766
2767 public void handleDisplayRemovedLocked(int displayId) {
2768 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002769 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2770 if (activityDisplay != null) {
2771 ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002772 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner34b73df2014-01-12 21:11:08 -08002773 stacks.get(stackNdx).mActivityContainer.detachLocked();
Craig Mautner4a1cb222013-12-04 16:14:06 -08002774 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002775 mActivityDisplays.remove(displayId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002776 }
2777 }
2778 mWindowManager.onDisplayRemoved(displayId);
2779 }
2780
2781 public void handleDisplayChangedLocked(int displayId) {
2782 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002783 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2784 if (activityDisplay != null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002785 // TODO: Update the bounds.
2786 }
2787 }
2788 mWindowManager.onDisplayChanged(displayId);
2789 }
2790
2791 StackInfo getStackInfo(ActivityStack stack) {
2792 StackInfo info = new StackInfo();
2793 mWindowManager.getStackBounds(stack.mStackId, info.bounds);
2794 info.displayId = Display.DEFAULT_DISPLAY;
2795 info.stackId = stack.mStackId;
2796
2797 ArrayList<TaskRecord> tasks = stack.getAllTasks();
2798 final int numTasks = tasks.size();
2799 int[] taskIds = new int[numTasks];
2800 String[] taskNames = new String[numTasks];
2801 for (int i = 0; i < numTasks; ++i) {
2802 final TaskRecord task = tasks.get(i);
2803 taskIds[i] = task.taskId;
2804 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
2805 : task.realActivity != null ? task.realActivity.flattenToString()
2806 : task.getTopActivity() != null ? task.getTopActivity().packageName
2807 : "unknown";
2808 }
2809 info.taskIds = taskIds;
2810 info.taskNames = taskNames;
2811 return info;
2812 }
2813
2814 StackInfo getStackInfoLocked(int stackId) {
2815 ActivityStack stack = getStack(stackId);
2816 if (stack != null) {
2817 return getStackInfo(stack);
2818 }
2819 return null;
2820 }
2821
2822 ArrayList<StackInfo> getAllStackInfosLocked() {
2823 ArrayList<StackInfo> list = new ArrayList<StackInfo>();
Craig Mautnere0a38842013-12-16 16:14:02 -08002824 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2825 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002826 for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
2827 list.add(getStackInfo(stacks.get(ndx)));
2828 }
2829 }
2830 return list;
2831 }
2832
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002833 private final class ActivityStackSupervisorHandler extends Handler {
Craig Mautnerf3333272013-04-22 10:55:53 -07002834
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002835 public ActivityStackSupervisorHandler(Looper looper) {
2836 super(looper);
2837 }
2838
Craig Mautnerf3333272013-04-22 10:55:53 -07002839 void activityIdleInternal(ActivityRecord r) {
2840 synchronized (mService) {
2841 activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
2842 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002843 }
2844
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002845 @Override
2846 public void handleMessage(Message msg) {
2847 switch (msg.what) {
Craig Mautnerf3333272013-04-22 10:55:53 -07002848 case IDLE_TIMEOUT_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002849 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002850 if (mService.mDidDexOpt) {
2851 mService.mDidDexOpt = false;
2852 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2853 nmsg.obj = msg.obj;
2854 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
2855 return;
2856 }
2857 // We don't at this point know if the activity is fullscreen,
2858 // so we need to be conservative and assume it isn't.
2859 activityIdleInternal((ActivityRecord)msg.obj);
2860 } break;
2861 case IDLE_NOW_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002862 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002863 activityIdleInternal((ActivityRecord)msg.obj);
2864 } break;
Craig Mautner05d29032013-05-03 13:40:13 -07002865 case RESUME_TOP_ACTIVITY_MSG: {
2866 synchronized (mService) {
2867 resumeTopActivitiesLocked();
2868 }
2869 } break;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002870 case SLEEP_TIMEOUT_MSG: {
2871 synchronized (mService) {
2872 if (mService.isSleepingOrShuttingDown()) {
2873 Slog.w(TAG, "Sleep timeout! Sleeping now.");
2874 mSleepTimeout = true;
2875 checkReadyForSleepLocked();
2876 }
2877 }
2878 } break;
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002879 case LAUNCH_TIMEOUT_MSG: {
2880 if (mService.mDidDexOpt) {
2881 mService.mDidDexOpt = false;
2882 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
2883 return;
2884 }
2885 synchronized (mService) {
2886 if (mLaunchingActivity.isHeld()) {
2887 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
2888 if (VALIDATE_WAKE_LOCK_CALLER
2889 && Binder.getCallingUid() != Process.myUid()) {
2890 throw new IllegalStateException("Calling must be system uid");
2891 }
2892 mLaunchingActivity.release();
2893 }
2894 }
2895 } break;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002896 case HANDLE_DISPLAY_ADDED: {
2897 handleDisplayAddedLocked(msg.arg1);
2898 } break;
2899 case HANDLE_DISPLAY_CHANGED: {
2900 handleDisplayChangedLocked(msg.arg1);
2901 } break;
2902 case HANDLE_DISPLAY_REMOVED: {
2903 handleDisplayRemovedLocked(msg.arg1);
2904 } break;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002905 }
2906 }
2907 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08002908
Craig Mautner4a1cb222013-12-04 16:14:06 -08002909 class ActivityContainer extends IActivityContainer.Stub {
2910 final int mStackId;
2911 final IActivityContainerCallback mCallback;
2912 final ActivityStack mStack;
2913 final ActivityRecord mParentActivity;
Craig Mautner34b73df2014-01-12 21:11:08 -08002914 final String mIdString;
Craig Mautnerbdc748af2013-12-02 14:08:25 -08002915
Craig Mautner4a1cb222013-12-04 16:14:06 -08002916 /** Display this ActivityStack is currently on. Null if not attached to a Display. */
Craig Mautnere0a38842013-12-16 16:14:02 -08002917 ActivityDisplay mActivityDisplay;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002918
2919 ActivityContainer(ActivityRecord parentActivity, int stackId,
2920 IActivityContainerCallback callback) {
2921 synchronized (mService) {
2922 mStackId = stackId;
2923 mStack = new ActivityStack(this);
2924 mParentActivity = parentActivity;
2925 mCallback = callback;
Craig Mautner34b73df2014-01-12 21:11:08 -08002926 mIdString = "ActivtyContainer{" + mStackId + ", parent=" + mParentActivity + "}";
2927 if (DEBUG_STACK) Slog.d(TAG, "Creating " + this);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002928 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08002929 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002930
Craig Mautnere0a38842013-12-16 16:14:02 -08002931 void attachToDisplayLocked(ActivityDisplay activityDisplay) {
Craig Mautner34b73df2014-01-12 21:11:08 -08002932 if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this
2933 + " to display=" + activityDisplay);
Craig Mautnere0a38842013-12-16 16:14:02 -08002934 mActivityDisplay = activityDisplay;
2935 mStack.mDisplayId = activityDisplay.mDisplayId;
2936 mStack.mStacks = activityDisplay.mStacks;
2937
2938 activityDisplay.attachActivities(mStack);
Craig Mautnerdf88d732014-01-27 09:21:32 -08002939 mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002940 }
2941
2942 @Override
2943 public void attachToDisplay(int displayId) throws RemoteException {
2944 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002945 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2946 if (activityDisplay == null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002947 return;
2948 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002949 attachToDisplayLocked(activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002950 }
2951 }
2952
2953 @Override
Craig Mautnere0a38842013-12-16 16:14:02 -08002954 public int getDisplayId() throws RemoteException {
2955 if (mActivityDisplay != null) {
2956 return mActivityDisplay.mDisplayId;
2957 }
2958 return -1;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002959 }
2960
Craig Mautner34b73df2014-01-12 21:11:08 -08002961 private void detachLocked() {
2962 if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display="
2963 + mActivityDisplay + " Callers=" + Debug.getCallers(2));
Craig Mautnere0a38842013-12-16 16:14:02 -08002964 if (mActivityDisplay != null) {
2965 mActivityDisplay.detachActivitiesLocked(mStack);
2966 mActivityDisplay = null;
2967 mStack.mDisplayId = -1;
2968 mStack.mStacks = null;
Craig Mautnerdf88d732014-01-27 09:21:32 -08002969 mWindowManager.detachStack(mStackId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002970 }
2971 }
2972
2973 @Override
2974 public void detachFromDisplay() throws RemoteException {
2975 synchronized (mService) {
2976 detachLocked();
2977 }
2978 }
2979
2980 @Override
Craig Mautnere0a38842013-12-16 16:14:02 -08002981 public final int startActivity(Intent intent) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08002982 mService.enforceNotIsolatedCaller("ActivityContainer.startActivity");
Craig Mautnere0a38842013-12-16 16:14:02 -08002983 int userId = mService.handleIncomingUser(Binder.getCallingPid(),
2984 Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null);
2985 // TODO: Switch to user app stacks here.
2986 String mimeType = intent.getType();
2987 if (mimeType == null && intent.getData() != null
2988 && "content".equals(intent.getData().getScheme())) {
2989 mimeType = mService.getProviderMimeType(intent.getData(), userId);
2990 }
2991 return startActivityMayWait(null, -1, null, intent, mimeType, null, null, 0, 0, null,
2992 null, null, null, null, userId, this);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002993 }
2994
2995 @Override
Craig Mautnerdf88d732014-01-27 09:21:32 -08002996 public final int startActivityIntentSender(IIntentSender intentSender) {
2997 mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
2998
2999 if (!(intentSender instanceof PendingIntentRecord)) {
3000 throw new IllegalArgumentException("Bad PendingIntent object");
3001 }
3002
3003 return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null,
3004 null, 0, 0, 0, null, this);
3005 }
3006
3007 @Override
Craig Mautner4a1cb222013-12-04 16:14:06 -08003008 public IBinder asBinder() {
3009 return this;
3010 }
3011
Craig Mautner4504de52013-12-20 09:06:56 -08003012 @Override
Craig Mautner34b73df2014-01-12 21:11:08 -08003013 public void attachToSurface(Surface surface, int width, int height, int density) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08003014 mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
3015
3016 final long origId = Binder.clearCallingIdentity();
3017 try {
3018 synchronized (mService) {
3019 ActivityDisplay activityDisplay =
3020 new ActivityDisplay(surface, width, height, density);
3021 mActivityDisplays.put(activityDisplay.mDisplayId, activityDisplay);
3022 attachToDisplayLocked(activityDisplay);
3023 mStack.resumeTopActivityLocked(null);
3024 }
3025 if (DEBUG_STACK) Slog.d(TAG, "attachToSurface: " + this + " to display="
3026 + mActivityDisplay);
3027 } finally {
3028 Binder.restoreCallingIdentity(origId);
Craig Mautner4504de52013-12-20 09:06:56 -08003029 }
Craig Mautner4504de52013-12-20 09:06:56 -08003030 }
3031
Craig Mautner4a1cb222013-12-04 16:14:06 -08003032 ActivityStackSupervisor getOuter() {
3033 return ActivityStackSupervisor.this;
3034 }
3035
3036 boolean isAttached() {
Craig Mautnere0a38842013-12-16 16:14:02 -08003037 return mActivityDisplay != null;
Craig Mautner4a1cb222013-12-04 16:14:06 -08003038 }
3039
3040 void getBounds(Point outBounds) {
Craig Mautnere0a38842013-12-16 16:14:02 -08003041 if (mActivityDisplay != null) {
3042 mActivityDisplay.getBounds(outBounds);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003043 } else {
3044 outBounds.set(0, 0);
3045 }
3046 }
Craig Mautner34b73df2014-01-12 21:11:08 -08003047
3048 @Override
3049 public String toString() {
3050 return mIdString + (mActivityDisplay == null ? "N" : "A");
3051 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003052 }
3053
Craig Mautner4a1cb222013-12-04 16:14:06 -08003054 /** Exactly one of these classes per Display in the system. Capable of holding zero or more
3055 * attached {@link ActivityStack}s */
Craig Mautnere0a38842013-12-16 16:14:02 -08003056 final class ActivityDisplay {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003057 /** Actual Display this object tracks. */
Craig Mautner34b73df2014-01-12 21:11:08 -08003058 int mDisplayId;
3059 Display mDisplay;
3060 DisplayInfo mDisplayInfo = new DisplayInfo();
3061 Surface mSurface;
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003062
Craig Mautner4a1cb222013-12-04 16:14:06 -08003063 /** All of the stacks on this display. Order matters, topmost stack is in front of all other
3064 * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
Craig Mautnere0a38842013-12-16 16:14:02 -08003065 final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003066
Craig Mautner4504de52013-12-20 09:06:56 -08003067 /** If this display is for an ActivityView then the VirtualDisplay created for it is stored
3068 * here. */
3069 VirtualDisplay mVirtualDisplay;
3070
Craig Mautnere0a38842013-12-16 16:14:02 -08003071 ActivityDisplay(int displayId) {
Craig Mautner34b73df2014-01-12 21:11:08 -08003072 init(mDisplayManager.getDisplay(displayId));
Craig Mautner4504de52013-12-20 09:06:56 -08003073 }
3074
Craig Mautner34b73df2014-01-12 21:11:08 -08003075 ActivityDisplay(Surface surface, int width, int height, int density) {
3076 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
3077 long ident = Binder.clearCallingIdentity();
3078 try {
3079 mVirtualDisplay = dm.createVirtualDisplay(mService.mContext,
3080 VIRTUAL_DISPLAY_BASE_NAME, width, height, density, surface,
3081 DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
3082 DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY);
3083 } finally {
3084 Binder.restoreCallingIdentity(ident);
3085 }
3086
3087 init(mVirtualDisplay.getDisplay());
3088 mSurface = surface;
3089
3090 mWindowManager.handleDisplayAdded(mDisplayId);
3091 }
3092
3093 private void init(Display display) {
Craig Mautner4504de52013-12-20 09:06:56 -08003094 mDisplay = display;
3095 mDisplayId = display.getDisplayId();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003096 mDisplay.getDisplayInfo(mDisplayInfo);
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003097 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08003098
3099 void attachActivities(ActivityStack stack) {
Craig Mautnere0a38842013-12-16 16:14:02 -08003100 if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId="
3101 + mDisplayId);
3102 mStacks.add(stack);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003103 }
3104
Craig Mautnere0a38842013-12-16 16:14:02 -08003105 void detachActivitiesLocked(ActivityStack stack) {
Craig Mautner34b73df2014-01-12 21:11:08 -08003106 if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack
Craig Mautnere0a38842013-12-16 16:14:02 -08003107 + " from displayId=" + mDisplayId);
3108 mStacks.remove(stack);
Craig Mautner34b73df2014-01-12 21:11:08 -08003109 if (mStacks.isEmpty() && mVirtualDisplay != null) {
3110 mVirtualDisplay.release();
3111 mVirtualDisplay = null;
3112 }
3113 mSurface.release();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003114 }
3115
3116 void getBounds(Point bounds) {
3117 mDisplay.getDisplayInfo(mDisplayInfo);
3118 bounds.x = mDisplayInfo.appWidth;
3119 bounds.y = mDisplayInfo.appHeight;
3120 }
Craig Mautner34b73df2014-01-12 21:11:08 -08003121
3122 @Override
3123 public String toString() {
3124 return "ActivityDisplay={" + mDisplayId + (mVirtualDisplay == null ? "" : "V")
3125 + " numStacks=" + mStacks.size() + "}";
3126 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003127 }
Craig Mautner27084302013-03-25 08:05:25 -07003128}