blob: ed11470f2b3fdadc48b6cae055288f2b11345042 [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 Mautnere0a38842013-12-16 16:14:02 -0800280 ArrayList<ActivityStack> stacks = stack.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800281 if (stacks != null && !stacks.isEmpty()) {
282 return stack == stacks.get(stacks.size() - 1);
283 }
284 return false;
Craig Mautner20e72272013-04-01 13:45:53 -0700285 }
286
Craig Mautnerde4ef022013-04-07 19:01:33 -0700287 void moveHomeStack(boolean toFront) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800288 ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800289 int topNdx = stacks.size() - 1;
290 if (topNdx <= 0) {
291 return;
292 }
293 ActivityStack topStack = stacks.get(topNdx);
294 final boolean homeInFront = topStack == mHomeStack;
295 if (homeInFront != toFront) {
296 mLastFocusedStack = topStack;
297 stacks.remove(mHomeStack);
298 stacks.add(toFront ? topNdx : 0, mHomeStack);
299 mFocusedStack = stacks.get(topNdx);
300 if (DEBUG_STACK) Slog.d(TAG, "moveHomeTask: topStack old=" + topStack + " new="
301 + mFocusedStack);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700302 }
303 }
304
Craig Mautner8e569572013-10-11 17:36:59 -0700305 void moveHomeToTop() {
Craig Mautner69ada552013-04-18 13:51:51 -0700306 moveHomeStack(true);
Craig Mautner8e569572013-10-11 17:36:59 -0700307 mHomeStack.moveHomeTaskToTop();
308 }
309
310 boolean resumeHomeActivity(ActivityRecord prev) {
311 moveHomeToTop();
Craig Mautner69ada552013-04-18 13:51:51 -0700312 if (prev != null) {
Craig Mautnerae7ecab2013-09-18 11:48:14 -0700313 prev.task.mOnTopOfHome = false;
Craig Mautner69ada552013-04-18 13:51:51 -0700314 }
Craig Mautnera8a90e02013-06-28 15:24:50 -0700315 ActivityRecord r = mHomeStack.topRunningActivityLocked(null);
Craig Mautner760b2312013-10-11 11:57:07 -0700316 if (r != null && r.isHomeActivity()) {
Craig Mautnera8a90e02013-06-28 15:24:50 -0700317 mService.setFocusedActivityLocked(r);
Craig Mautner05d29032013-05-03 13:40:13 -0700318 return resumeTopActivitiesLocked(mHomeStack, prev, null);
Craig Mautner69ada552013-04-18 13:51:51 -0700319 }
320 return mService.startHomeActivityLocked(mCurrentUser);
321 }
322
Craig Mautner27084302013-03-25 08:05:25 -0700323 void setDismissKeyguard(boolean dismiss) {
Craig Mautner5314a402013-09-26 12:40:16 -0700324 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen(" dismiss=" + dismiss);
Craig Mautner27084302013-03-25 08:05:25 -0700325 mDismissKeyguardOnNextActivity = dismiss;
326 }
327
Craig Mautner8d341ef2013-03-26 09:03:27 -0700328 TaskRecord anyTaskForIdLocked(int id) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800329 int numDisplays = mActivityDisplays.size();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800330 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800331 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800332 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
333 ActivityStack stack = stacks.get(stackNdx);
334 TaskRecord task = stack.taskForIdLocked(id);
335 if (task != null) {
336 return task;
337 }
Craig Mautner8d341ef2013-03-26 09:03:27 -0700338 }
339 }
340 return null;
341 }
342
Craig Mautner6170f732013-04-02 13:05:23 -0700343 ActivityRecord isInAnyStackLocked(IBinder token) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800344 int numDisplays = mActivityDisplays.size();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800345 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800346 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800347 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
348 final ActivityRecord r = stacks.get(stackNdx).isInStackLocked(token);
349 if (r != null) {
350 return r;
351 }
Craig Mautner6170f732013-04-02 13:05:23 -0700352 }
353 }
354 return null;
355 }
356
Craig Mautner8d341ef2013-03-26 09:03:27 -0700357 int getNextTaskId() {
358 do {
359 mCurTaskId++;
360 if (mCurTaskId <= 0) {
361 mCurTaskId = 1;
362 }
363 } while (anyTaskForIdLocked(mCurTaskId) != null);
364 return mCurTaskId;
365 }
366
Craig Mautnerde4ef022013-04-07 19:01:33 -0700367 void removeTask(TaskRecord task) {
Craig Mautnerb3b36ba2013-05-20 13:21:10 -0700368 mWindowManager.removeTask(task.taskId);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700369 final ActivityStack stack = task.stack;
Craig Mautnerb3b36ba2013-05-20 13:21:10 -0700370 final ActivityRecord r = stack.mResumedActivity;
371 if (r != null && r.task == task) {
372 stack.mResumedActivity = null;
373 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700374 if (stack.removeTask(task) && !stack.isHomeStack()) {
Craig Mautnera9a3fb12013-04-18 10:01:00 -0700375 if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing stack " + stack);
Craig Mautner4a1cb222013-12-04 16:14:06 -0800376 stack.mActivityContainer.detachLocked();
Craig Mautner4cd0c13f2013-04-16 15:55:52 -0700377 final int stackId = stack.mStackId;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700378 final int nextStackId = mWindowManager.removeStack(stackId);
Craig Mautnera9a3fb12013-04-18 10:01:00 -0700379 // TODO: Perhaps we need to let the ActivityManager determine the next focus...
Craig Mautnere0a38842013-12-16 16:14:02 -0800380 if (stack.isOnHomeDisplay()) {
381 mFocusedStack = getStack(nextStackId);
382 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700383 }
384 }
385
386 ActivityRecord resumedAppLocked() {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700387 ActivityStack stack = getFocusedStack();
388 if (stack == null) {
389 return null;
390 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700391 ActivityRecord resumedActivity = stack.mResumedActivity;
392 if (resumedActivity == null || resumedActivity.app == null) {
393 resumedActivity = stack.mPausingActivity;
394 if (resumedActivity == null || resumedActivity.app == null) {
395 resumedActivity = stack.topRunningActivityLocked(null);
396 }
397 }
398 return resumedActivity;
399 }
400
Mike Lockwoode63f6f72013-11-15 11:01:47 -0800401 boolean attachApplicationLocked(ProcessRecord app) throws Exception {
Craig Mautner20e72272013-04-01 13:45:53 -0700402 final String processName = app.processName;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800403 boolean didSomething = false;
Craig Mautnere0a38842013-12-16 16:14:02 -0800404 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
405 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800406 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
407 final ActivityStack stack = stacks.get(stackNdx);
408 if (!isFrontStack(stack)) {
409 continue;
410 }
411 ActivityRecord hr = stack.topRunningActivityLocked(null);
412 if (hr != null) {
413 if (hr.app == null && app.uid == hr.info.applicationInfo.uid
414 && processName.equals(hr.processName)) {
415 try {
416 if (realStartActivityLocked(hr, app, true, true)) {
417 didSomething = true;
418 }
419 } catch (Exception e) {
420 Slog.w(TAG, "Exception in new application when starting activity "
421 + hr.intent.getComponent().flattenToShortString(), e);
422 throw e;
Craig Mautner20e72272013-04-01 13:45:53 -0700423 }
Craig Mautner20e72272013-04-01 13:45:53 -0700424 }
Craig Mautner20e72272013-04-01 13:45:53 -0700425 }
426 }
427 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -0700428 if (!didSomething) {
429 ensureActivitiesVisibleLocked(null, 0);
430 }
Craig Mautner20e72272013-04-01 13:45:53 -0700431 return didSomething;
432 }
433
434 boolean allResumedActivitiesIdle() {
Craig Mautnere0a38842013-12-16 16:14:02 -0800435 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
436 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800437 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
438 final ActivityStack stack = stacks.get(stackNdx);
439 if (!isFrontStack(stack)) {
440 continue;
441 }
442 final ActivityRecord resumedActivity = stack.mResumedActivity;
443 if (resumedActivity == null || !resumedActivity.idle) {
444 return false;
445 }
Craig Mautner20e72272013-04-01 13:45:53 -0700446 }
447 }
448 return true;
449 }
450
Craig Mautnerde4ef022013-04-07 19:01:33 -0700451 boolean allResumedActivitiesComplete() {
Craig Mautnere0a38842013-12-16 16:14:02 -0800452 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
453 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800454 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
455 final ActivityStack stack = stacks.get(stackNdx);
456 if (isFrontStack(stack)) {
457 final ActivityRecord r = stack.mResumedActivity;
458 if (r != null && r.state != ActivityState.RESUMED) {
459 return false;
460 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700461 }
462 }
463 }
464 // TODO: Not sure if this should check if all Paused are complete too.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800465 if (DEBUG_STACK) Slog.d(TAG,
466 "allResumedActivitiesComplete: mLastFocusedStack changing from=" +
467 mLastFocusedStack + " to=" + mFocusedStack);
468 mLastFocusedStack = mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700469 return true;
470 }
471
472 boolean allResumedActivitiesVisible() {
Craig Mautnere0a38842013-12-16 16:14:02 -0800473 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
474 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800475 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
476 final ActivityStack stack = stacks.get(stackNdx);
477 final ActivityRecord r = stack.mResumedActivity;
478 if (r != null && (!r.nowVisible || r.waitingVisible)) {
479 return false;
480 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700481 }
482 }
483 return true;
484 }
485
Craig Mautner2acc3892013-09-23 10:28:14 -0700486 /**
487 * Pause all activities in either all of the stacks or just the back stacks.
488 * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving().
Craig Mautner2acc3892013-09-23 10:28:14 -0700489 * @return true if any activity was paused as a result of this call.
490 */
Craig Mautner5314a402013-09-26 12:40:16 -0700491 boolean pauseBackStacks(boolean userLeaving) {
Craig Mautnercf910b02013-04-23 11:23:27 -0700492 boolean someActivityPaused = false;
Craig Mautnere0a38842013-12-16 16:14:02 -0800493 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
494 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800495 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
496 final ActivityStack stack = stacks.get(stackNdx);
497 if (!isFrontStack(stack) && stack.mResumedActivity != null) {
498 if (DEBUG_STATES) Slog.d(TAG, "pauseBackStacks: stack=" + stack +
499 " mResumedActivity=" + stack.mResumedActivity);
500 stack.startPausingLocked(userLeaving, false);
501 someActivityPaused = true;
502 }
Craig Mautnercf910b02013-04-23 11:23:27 -0700503 }
504 }
505 return someActivityPaused;
506 }
507
Craig Mautnerde4ef022013-04-07 19:01:33 -0700508 boolean allPausedActivitiesComplete() {
Craig Mautnerac6f8432013-07-17 13:24:59 -0700509 boolean pausing = true;
Craig Mautnere0a38842013-12-16 16:14:02 -0800510 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
511 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800512 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
513 final ActivityStack stack = stacks.get(stackNdx);
514 final ActivityRecord r = stack.mPausingActivity;
515 if (r != null && r.state != ActivityState.PAUSED
516 && r.state != ActivityState.STOPPED
517 && r.state != ActivityState.STOPPING) {
518 if (DEBUG_STATES) {
519 Slog.d(TAG, "allPausedActivitiesComplete: r=" + r + " state=" + r.state);
520 pausing = false;
521 } else {
522 return false;
523 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700524 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700525 }
526 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700527 return pausing;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700528 }
529
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700530 void reportActivityVisibleLocked(ActivityRecord r) {
Craig Mautner858d8a62013-04-23 17:08:34 -0700531 for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700532 WaitResult w = mWaitingActivityVisible.get(i);
533 w.timeout = false;
534 if (r != null) {
535 w.who = new ComponentName(r.info.packageName, r.info.name);
536 }
537 w.totalTime = SystemClock.uptimeMillis() - w.thisTime;
538 w.thisTime = w.totalTime;
539 }
540 mService.notifyAll();
541 dismissKeyguard();
542 }
543
544 void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r,
545 long thisTime, long totalTime) {
546 for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
Craig Mautnerc64f73e2013-04-24 16:44:56 -0700547 WaitResult w = mWaitingActivityLaunched.remove(i);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700548 w.timeout = timeout;
549 if (r != null) {
550 w.who = new ComponentName(r.info.packageName, r.info.name);
551 }
552 w.thisTime = thisTime;
553 w.totalTime = totalTime;
554 }
555 mService.notifyAll();
556 }
557
Craig Mautner29219d92013-04-16 20:19:12 -0700558 ActivityRecord topRunningActivityLocked() {
Craig Mautner1602ec22013-05-12 10:24:27 -0700559 final ActivityStack focusedStack = getFocusedStack();
560 ActivityRecord r = focusedStack.topRunningActivityLocked(null);
561 if (r != null) {
562 return r;
Craig Mautner29219d92013-04-16 20:19:12 -0700563 }
Craig Mautner1602ec22013-05-12 10:24:27 -0700564
Craig Mautner4a1cb222013-12-04 16:14:06 -0800565 // Return to the home stack.
Craig Mautnere0a38842013-12-16 16:14:02 -0800566 final ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800567 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
568 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautnerac6f8432013-07-17 13:24:59 -0700569 if (stack != focusedStack && isFrontStack(stack)) {
Craig Mautner29219d92013-04-16 20:19:12 -0700570 r = stack.topRunningActivityLocked(null);
571 if (r != null) {
572 return r;
573 }
574 }
575 }
576 return null;
577 }
578
Craig Mautner20e72272013-04-01 13:45:53 -0700579 ActivityRecord getTasksLocked(int maxNum, IThumbnailReceiver receiver,
580 PendingThumbnailsRecord pending, List<RunningTaskInfo> list) {
581 ActivityRecord r = null;
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700582
583 // Gather all of the running tasks for each stack into runningTaskLists.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800584 ArrayList<ArrayList<RunningTaskInfo>> runningTaskLists =
585 new ArrayList<ArrayList<RunningTaskInfo>>();
Craig Mautnere0a38842013-12-16 16:14:02 -0800586 final int numDisplays = mActivityDisplays.size();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800587 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800588 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800589 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
590 final ActivityStack stack = stacks.get(stackNdx);
591 ArrayList<RunningTaskInfo> stackTaskList = new ArrayList<RunningTaskInfo>();
592 runningTaskLists.add(stackTaskList);
593 final ActivityRecord ar = stack.getTasksLocked(receiver, pending, stackTaskList);
594 if (r == null && isFrontStack(stack)) {
595 r = ar;
596 }
Craig Mautner20e72272013-04-01 13:45:53 -0700597 }
598 }
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700599
600 // The lists are already sorted from most recent to oldest. Just pull the most recent off
601 // each list and add it to list. Stop when all lists are empty or maxNum reached.
602 while (maxNum > 0) {
603 long mostRecentActiveTime = Long.MIN_VALUE;
604 ArrayList<RunningTaskInfo> selectedStackList = null;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800605 final int numTaskLists = runningTaskLists.size();
606 for (int stackNdx = 0; stackNdx < numTaskLists; ++stackNdx) {
607 ArrayList<RunningTaskInfo> stackTaskList = runningTaskLists.get(stackNdx);
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700608 if (!stackTaskList.isEmpty()) {
609 final long lastActiveTime = stackTaskList.get(0).lastActiveTime;
610 if (lastActiveTime > mostRecentActiveTime) {
611 mostRecentActiveTime = lastActiveTime;
612 selectedStackList = stackTaskList;
613 }
614 }
615 }
616 if (selectedStackList != null) {
617 list.add(selectedStackList.remove(0));
618 --maxNum;
619 } else {
620 break;
621 }
622 }
623
Craig Mautner20e72272013-04-01 13:45:53 -0700624 return r;
625 }
626
Craig Mautner23ac33b2013-04-01 16:26:35 -0700627 ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
628 String profileFile, ParcelFileDescriptor profileFd, int userId) {
629 // Collect information about the target of the Intent.
630 ActivityInfo aInfo;
631 try {
632 ResolveInfo rInfo =
633 AppGlobals.getPackageManager().resolveIntent(
634 intent, resolvedType,
635 PackageManager.MATCH_DEFAULT_ONLY
636 | ActivityManagerService.STOCK_PM_FLAGS, userId);
637 aInfo = rInfo != null ? rInfo.activityInfo : null;
638 } catch (RemoteException e) {
639 aInfo = null;
640 }
641
642 if (aInfo != null) {
643 // Store the found target back into the intent, because now that
644 // we have it we never want to do this again. For example, if the
645 // user navigates back to this point in the history, we should
646 // always restart the exact same activity.
647 intent.setComponent(new ComponentName(
648 aInfo.applicationInfo.packageName, aInfo.name));
649
650 // Don't debug things in the system process
651 if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) {
652 if (!aInfo.processName.equals("system")) {
653 mService.setDebugApp(aInfo.processName, true, false);
654 }
655 }
656
657 if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) {
658 if (!aInfo.processName.equals("system")) {
659 mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName);
660 }
661 }
662
663 if (profileFile != null) {
664 if (!aInfo.processName.equals("system")) {
665 mService.setProfileApp(aInfo.applicationInfo, aInfo.processName,
666 profileFile, profileFd,
667 (startFlags&ActivityManager.START_FLAG_AUTO_STOP_PROFILER) != 0);
668 }
669 }
670 }
671 return aInfo;
672 }
673
Craig Mautner2219a1b2013-03-25 09:44:30 -0700674 void startHomeActivity(Intent intent, ActivityInfo aInfo) {
Craig Mautner8e569572013-10-11 17:36:59 -0700675 moveHomeToTop();
Craig Mautner6170f732013-04-02 13:05:23 -0700676 startActivityLocked(null, intent, null, aInfo, null, null, 0, 0, 0, null, 0,
Craig Mautnere0a38842013-12-16 16:14:02 -0800677 null, false, null, null);
Craig Mautner8d341ef2013-03-26 09:03:27 -0700678 }
679
Craig Mautner23ac33b2013-04-01 16:26:35 -0700680 final int startActivityMayWait(IApplicationThread caller, int callingUid,
681 String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
682 String resultWho, int requestCode, int startFlags, String profileFile,
683 ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config,
Craig Mautnere0a38842013-12-16 16:14:02 -0800684 Bundle options, int userId, IActivityContainer iContainer) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700685 // Refuse possible leaked file descriptors
686 if (intent != null && intent.hasFileDescriptors()) {
687 throw new IllegalArgumentException("File descriptors passed in Intent");
688 }
689 boolean componentSpecified = intent.getComponent() != null;
690
691 // Don't modify the client's object!
692 intent = new Intent(intent);
693
694 // Collect information about the target of the Intent.
695 ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
696 profileFile, profileFd, userId);
697
Craig Mautnere0a38842013-12-16 16:14:02 -0800698 ActivityContainer container = (ActivityContainer)iContainer;
Craig Mautner23ac33b2013-04-01 16:26:35 -0700699 synchronized (mService) {
700 int callingPid;
701 if (callingUid >= 0) {
702 callingPid = -1;
703 } else if (caller == null) {
704 callingPid = Binder.getCallingPid();
705 callingUid = Binder.getCallingUid();
706 } else {
707 callingPid = callingUid = -1;
708 }
709
Craig Mautnere0a38842013-12-16 16:14:02 -0800710 final ActivityStack stack;
711 if (container == null || container.mStack.isOnHomeDisplay()) {
712 stack = getFocusedStack();
713 } else {
714 stack = container.mStack;
715 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700716 stack.mConfigWillChange = config != null
Craig Mautner23ac33b2013-04-01 16:26:35 -0700717 && mService.mConfiguration.diff(config) != 0;
718 if (DEBUG_CONFIGURATION) Slog.v(TAG,
Craig Mautnerde4ef022013-04-07 19:01:33 -0700719 "Starting activity when config will change = " + stack.mConfigWillChange);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700720
721 final long origId = Binder.clearCallingIdentity();
722
723 if (aInfo != null &&
724 (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
725 // This may be a heavy-weight process! Check to see if we already
726 // have another, different heavy-weight process running.
727 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
728 if (mService.mHeavyWeightProcess != null &&
729 (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid ||
730 !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700731 int realCallingUid = callingUid;
732 if (caller != null) {
733 ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
734 if (callerApp != null) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700735 realCallingUid = callerApp.info.uid;
736 } else {
737 Slog.w(TAG, "Unable to find app for caller " + caller
Craig Mautner76ea2242013-05-15 11:40:05 -0700738 + " (pid=" + callingPid + ") when starting: "
Craig Mautner23ac33b2013-04-01 16:26:35 -0700739 + intent.toString());
740 ActivityOptions.abort(options);
741 return ActivityManager.START_PERMISSION_DENIED;
742 }
743 }
744
745 IIntentSender target = mService.getIntentSenderLocked(
746 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
747 realCallingUid, userId, null, null, 0, new Intent[] { intent },
748 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
749 | PendingIntent.FLAG_ONE_SHOT, null);
750
751 Intent newIntent = new Intent();
752 if (requestCode >= 0) {
753 // Caller is requesting a result.
754 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
755 }
756 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
757 new IntentSender(target));
758 if (mService.mHeavyWeightProcess.activities.size() > 0) {
759 ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0);
760 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
761 hist.packageName);
762 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
763 hist.task.taskId);
764 }
765 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
766 aInfo.packageName);
767 newIntent.setFlags(intent.getFlags());
768 newIntent.setClassName("android",
769 HeavyWeightSwitcherActivity.class.getName());
770 intent = newIntent;
771 resolvedType = null;
772 caller = null;
773 callingUid = Binder.getCallingUid();
774 callingPid = Binder.getCallingPid();
775 componentSpecified = true;
776 try {
777 ResolveInfo rInfo =
778 AppGlobals.getPackageManager().resolveIntent(
779 intent, null,
780 PackageManager.MATCH_DEFAULT_ONLY
781 | ActivityManagerService.STOCK_PM_FLAGS, userId);
782 aInfo = rInfo != null ? rInfo.activityInfo : null;
783 aInfo = mService.getActivityInfoForUser(aInfo, userId);
784 } catch (RemoteException e) {
785 aInfo = null;
786 }
787 }
788 }
789 }
790
Craig Mautnere0a38842013-12-16 16:14:02 -0800791 int res = startActivityLocked(caller, intent, resolvedType, aInfo, resultTo, resultWho,
792 requestCode, callingPid, callingUid, callingPackage, startFlags, options,
793 componentSpecified, null, container);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700794
Craig Mautnerde4ef022013-04-07 19:01:33 -0700795 if (stack.mConfigWillChange) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700796 // If the caller also wants to switch to a new configuration,
797 // do so now. This allows a clean switch, as we are waiting
798 // for the current activity to pause (so we will not destroy
799 // it), and have not yet started the next activity.
800 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
801 "updateConfiguration()");
Craig Mautnerde4ef022013-04-07 19:01:33 -0700802 stack.mConfigWillChange = false;
Craig Mautner23ac33b2013-04-01 16:26:35 -0700803 if (DEBUG_CONFIGURATION) Slog.v(TAG,
804 "Updating to new configuration after starting activity.");
805 mService.updateConfigurationLocked(config, null, false, false);
806 }
807
808 Binder.restoreCallingIdentity(origId);
809
810 if (outResult != null) {
811 outResult.result = res;
812 if (res == ActivityManager.START_SUCCESS) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700813 mWaitingActivityLaunched.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700814 do {
815 try {
816 mService.wait();
817 } catch (InterruptedException e) {
818 }
819 } while (!outResult.timeout && outResult.who == null);
820 } else if (res == ActivityManager.START_TASK_TO_FRONT) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700821 ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700822 if (r.nowVisible) {
823 outResult.timeout = false;
824 outResult.who = new ComponentName(r.info.packageName, r.info.name);
825 outResult.totalTime = 0;
826 outResult.thisTime = 0;
827 } else {
828 outResult.thisTime = SystemClock.uptimeMillis();
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700829 mWaitingActivityVisible.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700830 do {
831 try {
832 mService.wait();
833 } catch (InterruptedException e) {
834 }
835 } while (!outResult.timeout && outResult.who == null);
836 }
837 }
838 }
839
840 return res;
841 }
842 }
843
844 final int startActivities(IApplicationThread caller, int callingUid, String callingPackage,
845 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
846 Bundle options, int userId) {
847 if (intents == null) {
848 throw new NullPointerException("intents is null");
849 }
850 if (resolvedTypes == null) {
851 throw new NullPointerException("resolvedTypes is null");
852 }
853 if (intents.length != resolvedTypes.length) {
854 throw new IllegalArgumentException("intents are length different than resolvedTypes");
855 }
856
Craig Mautner23ac33b2013-04-01 16:26:35 -0700857
858 int callingPid;
859 if (callingUid >= 0) {
860 callingPid = -1;
861 } else if (caller == null) {
862 callingPid = Binder.getCallingPid();
863 callingUid = Binder.getCallingUid();
864 } else {
865 callingPid = callingUid = -1;
866 }
867 final long origId = Binder.clearCallingIdentity();
868 try {
869 synchronized (mService) {
Craig Mautner76ea2242013-05-15 11:40:05 -0700870 ActivityRecord[] outActivity = new ActivityRecord[1];
Craig Mautner23ac33b2013-04-01 16:26:35 -0700871 for (int i=0; i<intents.length; i++) {
872 Intent intent = intents[i];
873 if (intent == null) {
874 continue;
875 }
876
877 // Refuse possible leaked file descriptors
878 if (intent != null && intent.hasFileDescriptors()) {
879 throw new IllegalArgumentException("File descriptors passed in Intent");
880 }
881
882 boolean componentSpecified = intent.getComponent() != null;
883
884 // Don't modify the client's object!
885 intent = new Intent(intent);
886
887 // Collect information about the target of the Intent.
888 ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i],
889 0, null, null, userId);
890 // TODO: New, check if this is correct
891 aInfo = mService.getActivityInfoForUser(aInfo, userId);
892
893 if (aInfo != null &&
894 (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE)
895 != 0) {
896 throw new IllegalArgumentException(
897 "FLAG_CANT_SAVE_STATE not supported here");
898 }
899
900 Bundle theseOptions;
901 if (options != null && i == intents.length-1) {
902 theseOptions = options;
903 } else {
904 theseOptions = null;
905 }
Craig Mautner6170f732013-04-02 13:05:23 -0700906 int res = startActivityLocked(caller, intent, resolvedTypes[i],
Craig Mautner23ac33b2013-04-01 16:26:35 -0700907 aInfo, resultTo, null, -1, callingPid, callingUid, callingPackage,
Craig Mautnere0a38842013-12-16 16:14:02 -0800908 0, theseOptions, componentSpecified, outActivity, null);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700909 if (res < 0) {
910 return res;
911 }
912
913 resultTo = outActivity[0] != null ? outActivity[0].appToken : null;
914 }
915 }
916 } finally {
917 Binder.restoreCallingIdentity(origId);
918 }
919
920 return ActivityManager.START_SUCCESS;
921 }
922
Craig Mautner2420ead2013-04-01 17:13:20 -0700923 final boolean realStartActivityLocked(ActivityRecord r,
924 ProcessRecord app, boolean andResume, boolean checkConfig)
925 throws RemoteException {
926
927 r.startFreezingScreenLocked(app, 0);
Craig Mautnera7f2bd42013-10-15 16:13:50 -0700928 if (false) Slog.d(TAG, "realStartActivity: setting app visibility true");
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700929 mWindowManager.setAppVisibility(r.appToken, true);
Craig Mautner2420ead2013-04-01 17:13:20 -0700930
931 // schedule launch ticks to collect information about slow apps.
932 r.startLaunchTickingLocked();
933
934 // Have the window manager re-evaluate the orientation of
935 // the screen based on the new activity order. Note that
936 // as a result of this, it can call back into the activity
937 // manager with a new orientation. We don't care about that,
938 // because the activity is not currently running so we are
939 // just restarting it anyway.
940 if (checkConfig) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700941 Configuration config = mWindowManager.updateOrientationFromAppTokens(
Craig Mautner2420ead2013-04-01 17:13:20 -0700942 mService.mConfiguration,
943 r.mayFreezeScreenLocked(app) ? r.appToken : null);
944 mService.updateConfigurationLocked(config, r, false, false);
945 }
946
947 r.app = app;
948 app.waitingToKill = null;
949 r.launchCount++;
950 r.lastLaunchTime = SystemClock.uptimeMillis();
951
952 if (localLOGV) Slog.v(TAG, "Launching: " + r);
953
954 int idx = app.activities.indexOf(r);
955 if (idx < 0) {
956 app.activities.add(r);
957 }
Dianne Hackborndb926082013-10-31 16:32:44 -0700958 mService.updateLruProcessLocked(app, true, null);
959 mService.updateOomAdjLocked();
Craig Mautner2420ead2013-04-01 17:13:20 -0700960
961 final ActivityStack stack = r.task.stack;
962 try {
963 if (app.thread == null) {
964 throw new RemoteException();
965 }
966 List<ResultInfo> results = null;
967 List<Intent> newIntents = null;
968 if (andResume) {
969 results = r.results;
970 newIntents = r.newIntents;
971 }
972 if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r
973 + " icicle=" + r.icicle
974 + " with results=" + results + " newIntents=" + newIntents
975 + " andResume=" + andResume);
976 if (andResume) {
977 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
978 r.userId, System.identityHashCode(r),
979 r.task.taskId, r.shortComponentName);
980 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700981 if (r.isHomeActivity() && r.isNotResolverActivity()) {
Craig Mautner4ef26932013-09-18 15:15:52 -0700982 // Home process is the root process of the task.
983 mService.mHomeProcess = r.task.mActivities.get(0).app;
Craig Mautner2420ead2013-04-01 17:13:20 -0700984 }
985 mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
986 r.sleeping = false;
987 r.forceNewConfig = false;
988 mService.showAskCompatModeDialogLocked(r);
989 r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
990 String profileFile = null;
991 ParcelFileDescriptor profileFd = null;
992 boolean profileAutoStop = false;
993 if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
994 if (mService.mProfileProc == null || mService.mProfileProc == app) {
995 mService.mProfileProc = app;
996 profileFile = mService.mProfileFile;
997 profileFd = mService.mProfileFd;
998 profileAutoStop = mService.mAutoStopProfiler;
999 }
1000 }
1001 app.hasShownUi = true;
1002 app.pendingUiClean = true;
1003 if (profileFd != null) {
1004 try {
1005 profileFd = profileFd.dup();
1006 } catch (IOException e) {
1007 if (profileFd != null) {
1008 try {
1009 profileFd.close();
1010 } catch (IOException o) {
1011 }
1012 profileFd = null;
1013 }
1014 }
1015 }
Dianne Hackborna413dc02013-07-12 12:02:55 -07001016 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
Craig Mautner2420ead2013-04-01 17:13:20 -07001017 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
1018 System.identityHashCode(r), r.info,
Dianne Hackborna413dc02013-07-12 12:02:55 -07001019 new Configuration(mService.mConfiguration), r.compat,
1020 app.repProcState, r.icicle, results, newIntents, !andResume,
Craig Mautner2420ead2013-04-01 17:13:20 -07001021 mService.isNextTransitionForward(), profileFile, profileFd,
1022 profileAutoStop);
1023
1024 if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
1025 // This may be a heavy-weight process! Note that the package
1026 // manager will ensure that only activity can run in the main
1027 // process of the .apk, which is the only thing that will be
1028 // considered heavy-weight.
1029 if (app.processName.equals(app.info.packageName)) {
1030 if (mService.mHeavyWeightProcess != null
1031 && mService.mHeavyWeightProcess != app) {
1032 Slog.w(TAG, "Starting new heavy weight process " + app
1033 + " when already running "
1034 + mService.mHeavyWeightProcess);
1035 }
1036 mService.mHeavyWeightProcess = app;
1037 Message msg = mService.mHandler.obtainMessage(
1038 ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
1039 msg.obj = r;
1040 mService.mHandler.sendMessage(msg);
1041 }
1042 }
1043
1044 } catch (RemoteException e) {
1045 if (r.launchFailed) {
1046 // This is the second time we failed -- finish activity
1047 // and give up.
1048 Slog.e(TAG, "Second failure launching "
1049 + r.intent.getComponent().flattenToShortString()
1050 + ", giving up", e);
1051 mService.appDiedLocked(app, app.pid, app.thread);
1052 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
1053 "2nd-crash", false);
1054 return false;
1055 }
1056
1057 // This is the first time we failed -- restart process and
1058 // retry.
1059 app.activities.remove(r);
1060 throw e;
1061 }
1062
1063 r.launchFailed = false;
1064 if (stack.updateLRUListLocked(r)) {
1065 Slog.w(TAG, "Activity " + r
1066 + " being launched, but already in LRU list");
1067 }
1068
1069 if (andResume) {
1070 // As part of the process of launching, ActivityThread also performs
1071 // a resume.
1072 stack.minimalResumeActivityLocked(r);
1073 } else {
1074 // This activity is not starting in the resumed state... which
1075 // should look like we asked it to pause+stop (but remain visible),
1076 // and it has done so and reported back the current icicle and
1077 // other state.
1078 if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r
1079 + " (starting in stopped state)");
1080 r.state = ActivityState.STOPPED;
1081 r.stopped = true;
1082 }
1083
1084 // Launch the new version setup screen if needed. We do this -after-
1085 // launching the initial activity (that is, home), so that it can have
1086 // a chance to initialize itself while in the background, making the
1087 // switch back to it faster and look better.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001088 if (isFrontStack(stack)) {
Craig Mautner2420ead2013-04-01 17:13:20 -07001089 mService.startSetupActivityLocked();
1090 }
1091
1092 return true;
1093 }
1094
Craig Mautnere79d42682013-04-01 19:01:53 -07001095 void startSpecificActivityLocked(ActivityRecord r,
1096 boolean andResume, boolean checkConfig) {
1097 // Is this activity's application already running?
1098 ProcessRecord app = mService.getProcessRecordLocked(r.processName,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001099 r.info.applicationInfo.uid, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001100
1101 r.task.stack.setLaunchTime(r);
1102
1103 if (app != null && app.thread != null) {
1104 try {
Dianne Hackborn237cefb2013-10-22 18:45:27 -07001105 if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
1106 || !"android".equals(r.info.packageName)) {
1107 // Don't add this if it is a platform component that is marked
1108 // to run in multiple processes, because this is actually
1109 // part of the framework so doesn't make sense to track as a
1110 // separate apk in the process.
1111 app.addPackage(r.info.packageName, mService.mProcessStats);
1112 }
Craig Mautnere79d42682013-04-01 19:01:53 -07001113 realStartActivityLocked(r, app, andResume, checkConfig);
1114 return;
1115 } catch (RemoteException e) {
1116 Slog.w(TAG, "Exception when starting activity "
1117 + r.intent.getComponent().flattenToShortString(), e);
1118 }
1119
1120 // If a dead object exception was thrown -- fall through to
1121 // restart the application.
1122 }
1123
1124 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001125 "activity", r.intent.getComponent(), false, false, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001126 }
1127
Craig Mautner6170f732013-04-02 13:05:23 -07001128 final int startActivityLocked(IApplicationThread caller,
1129 Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
1130 String resultWho, int requestCode,
1131 int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
Craig Mautnere0a38842013-12-16 16:14:02 -08001132 boolean componentSpecified, ActivityRecord[] outActivity, ActivityContainer container) {
Craig Mautner6170f732013-04-02 13:05:23 -07001133 int err = ActivityManager.START_SUCCESS;
1134
1135 ProcessRecord callerApp = null;
1136 if (caller != null) {
1137 callerApp = mService.getRecordForAppLocked(caller);
1138 if (callerApp != null) {
1139 callingPid = callerApp.pid;
1140 callingUid = callerApp.info.uid;
1141 } else {
1142 Slog.w(TAG, "Unable to find app for caller " + caller
1143 + " (pid=" + callingPid + ") when starting: "
1144 + intent.toString());
1145 err = ActivityManager.START_PERMISSION_DENIED;
1146 }
1147 }
1148
1149 if (err == ActivityManager.START_SUCCESS) {
1150 final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
1151 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
1152 + "} from pid " + (callerApp != null ? callerApp.pid : callingPid));
1153 }
1154
1155 ActivityRecord sourceRecord = null;
1156 ActivityRecord resultRecord = null;
1157 if (resultTo != null) {
1158 sourceRecord = isInAnyStackLocked(resultTo);
1159 if (DEBUG_RESULTS) Slog.v(
1160 TAG, "Will send result to " + resultTo + " " + sourceRecord);
1161 if (sourceRecord != null) {
1162 if (requestCode >= 0 && !sourceRecord.finishing) {
1163 resultRecord = sourceRecord;
1164 }
1165 }
1166 }
1167 ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
1168
1169 int launchFlags = intent.getFlags();
1170
1171 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
1172 && sourceRecord != null) {
1173 // Transfer the result target from the source activity to the new
1174 // one being started, including any failures.
1175 if (requestCode >= 0) {
1176 ActivityOptions.abort(options);
1177 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
1178 }
1179 resultRecord = sourceRecord.resultTo;
1180 resultWho = sourceRecord.resultWho;
1181 requestCode = sourceRecord.requestCode;
1182 sourceRecord.resultTo = null;
1183 if (resultRecord != null) {
1184 resultRecord.removeResultsLocked(
1185 sourceRecord, resultWho, requestCode);
1186 }
1187 }
1188
1189 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
1190 // We couldn't find a class that can handle the given Intent.
1191 // That's the end of that!
1192 err = ActivityManager.START_INTENT_NOT_RESOLVED;
1193 }
1194
1195 if (err == ActivityManager.START_SUCCESS && aInfo == null) {
1196 // We couldn't find the specific class specified in the Intent.
1197 // Also the end of the line.
1198 err = ActivityManager.START_CLASS_NOT_FOUND;
1199 }
1200
1201 if (err != ActivityManager.START_SUCCESS) {
1202 if (resultRecord != null) {
1203 resultStack.sendActivityResultLocked(-1,
1204 resultRecord, resultWho, requestCode,
1205 Activity.RESULT_CANCELED, null);
1206 }
1207 setDismissKeyguard(false);
1208 ActivityOptions.abort(options);
1209 return err;
1210 }
1211
1212 final int startAnyPerm = mService.checkPermission(
1213 START_ANY_ACTIVITY, callingPid, callingUid);
1214 final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
1215 callingUid, aInfo.applicationInfo.uid, aInfo.exported);
1216 if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
1217 if (resultRecord != null) {
1218 resultStack.sendActivityResultLocked(-1,
1219 resultRecord, resultWho, requestCode,
1220 Activity.RESULT_CANCELED, null);
1221 }
1222 setDismissKeyguard(false);
1223 String msg;
1224 if (!aInfo.exported) {
1225 msg = "Permission Denial: starting " + intent.toString()
1226 + " from " + callerApp + " (pid=" + callingPid
1227 + ", uid=" + callingUid + ")"
1228 + " not exported from uid " + aInfo.applicationInfo.uid;
1229 } else {
1230 msg = "Permission Denial: starting " + intent.toString()
1231 + " from " + callerApp + " (pid=" + callingPid
1232 + ", uid=" + callingUid + ")"
1233 + " requires " + aInfo.permission;
1234 }
1235 Slog.w(TAG, msg);
1236 throw new SecurityException(msg);
1237 }
1238
Ben Gruverdd72c9e2013-08-06 12:34:17 -07001239 boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
Ben Gruverb6223792013-07-29 16:35:40 -07001240 callingPid, resolvedType, aInfo.applicationInfo);
Ben Gruver5e207332013-04-03 17:41:37 -07001241
Craig Mautner6170f732013-04-02 13:05:23 -07001242 if (mService.mController != null) {
Craig Mautner6170f732013-04-02 13:05:23 -07001243 try {
1244 // The Intent we give to the watcher has the extra data
1245 // stripped off, since it can contain private information.
1246 Intent watchIntent = intent.cloneFilter();
Ben Gruver5e207332013-04-03 17:41:37 -07001247 abort |= !mService.mController.activityStarting(watchIntent,
Craig Mautner6170f732013-04-02 13:05:23 -07001248 aInfo.applicationInfo.packageName);
1249 } catch (RemoteException e) {
1250 mService.mController = null;
1251 }
Ben Gruver5e207332013-04-03 17:41:37 -07001252 }
Craig Mautner6170f732013-04-02 13:05:23 -07001253
Ben Gruver5e207332013-04-03 17:41:37 -07001254 if (abort) {
1255 if (resultRecord != null) {
1256 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
Craig Mautner6170f732013-04-02 13:05:23 -07001257 Activity.RESULT_CANCELED, null);
Craig Mautner6170f732013-04-02 13:05:23 -07001258 }
Ben Gruver5e207332013-04-03 17:41:37 -07001259 // We pretend to the caller that it was really started, but
1260 // they will just get a cancel result.
1261 setDismissKeyguard(false);
1262 ActivityOptions.abort(options);
1263 return ActivityManager.START_SUCCESS;
Craig Mautner6170f732013-04-02 13:05:23 -07001264 }
1265
1266 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
Craig Mautnere0a38842013-12-16 16:14:02 -08001267 intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
1268 requestCode, componentSpecified, this, container);
Craig Mautner6170f732013-04-02 13:05:23 -07001269 if (outActivity != null) {
1270 outActivity[0] = r;
1271 }
1272
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001273 final ActivityStack stack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001274 if (stack.mResumedActivity == null
1275 || stack.mResumedActivity.info.applicationInfo.uid != callingUid) {
Craig Mautner6170f732013-04-02 13:05:23 -07001276 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
1277 PendingActivityLaunch pal =
Craig Mautnerde4ef022013-04-07 19:01:33 -07001278 new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
Craig Mautner6170f732013-04-02 13:05:23 -07001279 mService.mPendingActivityLaunches.add(pal);
1280 setDismissKeyguard(false);
1281 ActivityOptions.abort(options);
1282 return ActivityManager.START_SWITCHES_CANCELED;
1283 }
1284 }
1285
1286 if (mService.mDidAppSwitch) {
1287 // This is the second allowed switch since we stopped switches,
1288 // so now just generally allow switches. Use case: user presses
1289 // home (switches disabled, switch to home, mDidAppSwitch now true);
1290 // user taps a home icon (coming from home so allowed, we hit here
1291 // and now allow anyone to switch again).
1292 mService.mAppSwitchesAllowedTime = 0;
1293 } else {
1294 mService.mDidAppSwitch = true;
1295 }
1296
1297 mService.doPendingActivityLaunchesLocked(false);
1298
Craig Mautner8849a5e2013-04-02 16:41:03 -07001299 err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
Craig Mautner10385a12013-09-22 21:08:32 -07001300
1301 if (allPausedActivitiesComplete()) {
1302 // If someone asked to have the keyguard dismissed on the next
Craig Mautner6170f732013-04-02 13:05:23 -07001303 // activity start, but we are not actually doing an activity
1304 // switch... just dismiss the keyguard now, because we
1305 // probably want to see whatever is behind it.
1306 dismissKeyguard();
1307 }
1308 return err;
1309 }
1310
Craig Mautnerac6f8432013-07-17 13:24:59 -07001311 ActivityStack adjustStackFocus(ActivityRecord r) {
Craig Mautner1d001b62013-06-18 16:52:43 -07001312 final TaskRecord task = r.task;
1313 if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001314 if (task != null) {
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07001315 final ActivityStack taskStack = task.stack;
Craig Mautnere0a38842013-12-16 16:14:02 -08001316 if (taskStack.isOnHomeDisplay()) {
1317 if (mFocusedStack != taskStack) {
1318 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: Setting " +
1319 "focused stack to r=" + r + " task=" + task);
1320 mFocusedStack = taskStack;
1321 } else {
1322 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1323 "adjustStackFocus: Focused stack already=" + mFocusedStack);
1324 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001325 }
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07001326 return taskStack;
Craig Mautnerac6f8432013-07-17 13:24:59 -07001327 }
1328
Craig Mautnere0a38842013-12-16 16:14:02 -08001329 final ActivityContainer container = r.mInitialActivityContainer;
1330 if (container != null) {
1331 // The first time put it on the desired stack, after this put on task stack.
1332 r.mInitialActivityContainer = null;
1333 return container.mStack;
1334 }
1335
Craig Mautner4a1cb222013-12-04 16:14:06 -08001336 if (mFocusedStack != mHomeStack) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001337 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1338 "adjustStackFocus: Have a focused stack=" + mFocusedStack);
1339 return mFocusedStack;
1340 }
1341
Craig Mautnere0a38842013-12-16 16:14:02 -08001342 final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks;
1343 for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1344 final ActivityStack stack = homeDisplayStacks.get(stackNdx);
1345 if (!stack.isHomeStack()) {
1346 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1347 "adjustStackFocus: Setting focused stack=" + stack);
1348 mFocusedStack = stack;
1349 return mFocusedStack;
Craig Mautner858d8a62013-04-23 17:08:34 -07001350 }
1351 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001352
Craig Mautner4a1cb222013-12-04 16:14:06 -08001353 // Need to create an app stack for this user.
1354 int stackId = createStackOnDisplay(null, getNextStackId(), Display.DEFAULT_DISPLAY);
Craig Mautnerac6f8432013-07-17 13:24:59 -07001355 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r +
1356 " stackId=" + stackId);
1357 mFocusedStack = getStack(stackId);
Craig Mautner29219d92013-04-16 20:19:12 -07001358 return mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001359 }
1360 return mHomeStack;
1361 }
1362
Craig Mautner29219d92013-04-16 20:19:12 -07001363 void setFocusedStack(ActivityRecord r) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08001364 if (r != null) {
1365 final boolean isHomeActivity =
1366 !r.isApplicationActivity() || (r.task != null && !r.task.isApplicationTask());
1367 moveHomeStack(isHomeActivity);
Craig Mautner29219d92013-04-16 20:19:12 -07001368 }
1369 }
1370
Craig Mautner8849a5e2013-04-02 16:41:03 -07001371 final int startActivityUncheckedLocked(ActivityRecord r,
1372 ActivityRecord sourceRecord, int startFlags, boolean doResume,
1373 Bundle options) {
1374 final Intent intent = r.intent;
1375 final int callingUid = r.launchedFromUid;
1376
1377 int launchFlags = intent.getFlags();
1378
Craig Mautner8849a5e2013-04-02 16:41:03 -07001379 // We'll invoke onUserLeaving before onPause only if the launching
1380 // activity did not explicitly state that this is an automated launch.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001381 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1382 if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001383
1384 // If the caller has asked not to resume at this point, we make note
1385 // of this in the record so that we can skip it when trying to find
1386 // the top running activity.
1387 if (!doResume) {
1388 r.delayedResume = true;
1389 }
1390
1391 ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1392
1393 // If the onlyIfNeeded flag is set, then we can do this if the activity
1394 // being launched is the same as the one making the call... or, as
1395 // a special case, if we do not know the caller then we count the
1396 // current top activity as the caller.
1397 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1398 ActivityRecord checkedCaller = sourceRecord;
1399 if (checkedCaller == null) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001400 checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001401 }
1402 if (!checkedCaller.realActivity.equals(r.realActivity)) {
1403 // Caller is not the same as launcher, so always needed.
1404 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
1405 }
1406 }
1407
1408 if (sourceRecord == null) {
1409 // This activity is not being started from another... in this
1410 // case we -always- start a new task.
1411 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
Craig Mautner29219d92013-04-16 20:19:12 -07001412 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1413 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001414 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1415 }
1416 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1417 // The original activity who is starting us is running as a single
1418 // instance... this new activity it is starting must go on its
1419 // own task.
1420 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1421 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
1422 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1423 // The activity being started is a single instance... it always
1424 // gets launched into its own task.
1425 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1426 }
1427
Craig Mautner88629292013-11-10 20:39:05 -08001428 ActivityInfo newTaskInfo = null;
1429 Intent newTaskIntent = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001430 final ActivityStack sourceStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001431 if (sourceRecord != null) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001432 if (sourceRecord.finishing) {
1433 // If the source is finishing, we can't further count it as our source. This
1434 // is because the task it is associated with may now be empty and on its way out,
1435 // so we don't want to blindly throw it in to that task. Instead we will take
Craig Mautner88629292013-11-10 20:39:05 -08001436 // the NEW_TASK flow and try to find a task for it. But save the task information
1437 // so it can be used when creating the new task.
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001438 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
1439 Slog.w(TAG, "startActivity called from finishing " + sourceRecord
1440 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
1441 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
Craig Mautner88629292013-11-10 20:39:05 -08001442 newTaskInfo = sourceRecord.info;
1443 newTaskIntent = sourceRecord.task.intent;
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001444 }
1445 sourceRecord = null;
1446 sourceStack = null;
1447 } else {
1448 sourceStack = sourceRecord.task.stack;
1449 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07001450 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001451 sourceStack = null;
1452 }
1453
Craig Mautner8849a5e2013-04-02 16:41:03 -07001454 if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1455 // For whatever reason this activity is being launched into a new
1456 // task... yet the caller has requested a result back. Well, that
1457 // is pretty messed up, so instead immediately send back a cancel
1458 // and let the new task continue launched as normal without a
1459 // dependency on its originator.
1460 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1461 r.resultTo.task.stack.sendActivityResultLocked(-1,
1462 r.resultTo, r.resultWho, r.requestCode,
1463 Activity.RESULT_CANCELED, null);
1464 r.resultTo = null;
1465 }
1466
1467 boolean addingToTask = false;
1468 boolean movedHome = false;
1469 TaskRecord reuseTask = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001470 ActivityStack targetStack;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001471 if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
1472 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
1473 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1474 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1475 // If bring to front is requested, and no result is requested, and
1476 // we can find a task that was started with this same
1477 // component, then instead of launching bring that one to the front.
1478 if (r.resultTo == null) {
1479 // See if there is a task to bring to the front. If this is
1480 // a SINGLE_INSTANCE activity, there can be one and only one
1481 // instance of it in the history, and it is always in its own
1482 // unique task, so we do a special search.
1483 ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
Craig Mautnerac6f8432013-07-17 13:24:59 -07001484 ? findTaskLocked(r)
Craig Mautner8849a5e2013-04-02 16:41:03 -07001485 : findActivityLocked(intent, r.info);
1486 if (intentActivity != null) {
Craig Mautner29219d92013-04-16 20:19:12 -07001487 if (r.task == null) {
1488 r.task = intentActivity.task;
1489 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001490 targetStack = intentActivity.task.stack;
Craig Mautner0f922742013-08-06 08:44:42 -07001491 targetStack.mLastPausedActivity = null;
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001492 if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack
1493 + " from " + intentActivity);
Craig Mautnere0a38842013-12-16 16:14:02 -08001494 targetStack.moveToFront();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001495 if (intentActivity.task.intent == null) {
1496 // This task was started because of movement of
1497 // the activity based on affinity... now that we
1498 // are actually launching it, we can assign the
1499 // base intent.
1500 intentActivity.task.setIntent(intent, r.info);
1501 }
1502 // If the target task is not in the front, then we need
1503 // to bring it to the front... except... well, with
1504 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like
1505 // to have the same behavior as if a new instance was
1506 // being started, which means not bringing it to the front
1507 // if the caller is not itself in the front.
Craig Mautner165640b2013-04-20 10:34:33 -07001508 final ActivityStack lastStack = getLastStack();
1509 ActivityRecord curTop = lastStack == null?
1510 null : lastStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner7504d7b2013-09-17 10:50:53 -07001511 if (curTop != null && (curTop.task != intentActivity.task ||
1512 curTop.task != lastStack.topTask())) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001513 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Craig Mautnerd0f964f2013-08-07 11:16:33 -07001514 if (sourceRecord == null || (sourceStack.topActivity() != null &&
1515 sourceStack.topActivity().task == sourceRecord.task)) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001516 // We really do want to push this one into the
1517 // user's face, right now.
1518 movedHome = true;
Craig Mautnerb53d97c2013-10-25 11:54:37 -07001519 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001520 if ((launchFlags &
Craig Mautner29219d92013-04-16 20:19:12 -07001521 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1522 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
Craig Mautnere12a4a62013-08-29 12:24:56 -07001523 // Caller wants to appear on home activity.
Craig Mautnerae7ecab2013-09-18 11:48:14 -07001524 intentActivity.task.mOnTopOfHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001525 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001526 options = null;
1527 }
1528 }
1529 // If the caller has requested that the target task be
1530 // reset, then do so.
1531 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1532 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
1533 }
1534 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1535 // We don't need to start a new activity, and
1536 // the client said not to do anything if that
1537 // is the case, so this is it! And for paranoia, make
1538 // sure we have correctly resumed the top activity.
1539 if (doResume) {
Craig Mautner05d29032013-05-03 13:40:13 -07001540 resumeTopActivitiesLocked(targetStack, null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001541 } else {
1542 ActivityOptions.abort(options);
1543 }
Craig Mautner29219d92013-04-16 20:19:12 -07001544 if (r.task == null) Slog.v(TAG,
1545 "startActivityUncheckedLocked: task left null",
1546 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001547 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1548 }
1549 if ((launchFlags &
1550 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
1551 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
1552 // The caller has requested to completely replace any
1553 // existing task with its new activity. Well that should
1554 // not be too hard...
1555 reuseTask = intentActivity.task;
1556 reuseTask.performClearTaskLocked();
1557 reuseTask.setIntent(r.intent, r.info);
1558 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
1559 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1560 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1561 // In this situation we want to remove all activities
1562 // from the task up to the one being started. In most
1563 // cases this means we are resetting the task to its
1564 // initial state.
1565 ActivityRecord top =
1566 intentActivity.task.performClearTaskLocked(r, launchFlags);
1567 if (top != null) {
1568 if (top.frontOfTask) {
1569 // Activity aliases may mean we use different
1570 // intents for the top activity, so make sure
1571 // the task now has the identity of the new
1572 // intent.
1573 top.task.setIntent(r.intent, r.info);
1574 }
1575 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
1576 r, top.task);
1577 top.deliverNewIntentLocked(callingUid, r.intent);
1578 } else {
1579 // A special case: we need to
1580 // start the activity because it is not currently
1581 // running, and the caller has asked to clear the
1582 // current task to have this activity at the top.
1583 addingToTask = true;
1584 // Now pretend like this activity is being started
1585 // by the top of its task, so it is put in the
1586 // right place.
1587 sourceRecord = intentActivity;
1588 }
1589 } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
1590 // In this case the top activity on the task is the
1591 // same as the one being launched, so we take that
1592 // as a request to bring the task to the foreground.
1593 // If the top activity in the task is the root
1594 // activity, deliver this new intent to it if it
1595 // desires.
1596 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1597 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
1598 && intentActivity.realActivity.equals(r.realActivity)) {
1599 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
1600 intentActivity.task);
1601 if (intentActivity.frontOfTask) {
1602 intentActivity.task.setIntent(r.intent, r.info);
1603 }
1604 intentActivity.deliverNewIntentLocked(callingUid, r.intent);
1605 } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
1606 // In this case we are launching the root activity
1607 // of the task, but with a different intent. We
1608 // should start a new instance on top.
1609 addingToTask = true;
1610 sourceRecord = intentActivity;
1611 }
1612 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1613 // In this case an activity is being launched in to an
1614 // existing task, without resetting that task. This
1615 // is typically the situation of launching an activity
1616 // from a notification or shortcut. We want to place
1617 // the new activity on top of the current task.
1618 addingToTask = true;
1619 sourceRecord = intentActivity;
1620 } else if (!intentActivity.task.rootWasReset) {
1621 // In this case we are launching in to an existing task
1622 // that has not yet been started from its front door.
1623 // The current task has been brought to the front.
1624 // Ideally, we'd probably like to place this new task
1625 // at the bottom of its stack, but that's a little hard
1626 // to do with the current organization of the code so
1627 // for now we'll just drop it.
1628 intentActivity.task.setIntent(r.intent, r.info);
1629 }
1630 if (!addingToTask && reuseTask == null) {
1631 // We didn't do anything... but it was needed (a.k.a., client
1632 // don't use that intent!) And for paranoia, make
1633 // sure we have correctly resumed the top activity.
1634 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001635 targetStack.resumeTopActivityLocked(null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001636 } else {
1637 ActivityOptions.abort(options);
1638 }
Craig Mautner29219d92013-04-16 20:19:12 -07001639 if (r.task == null) Slog.v(TAG,
1640 "startActivityUncheckedLocked: task left null",
1641 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001642 return ActivityManager.START_TASK_TO_FRONT;
1643 }
1644 }
1645 }
1646 }
1647
1648 //String uri = r.intent.toURI();
1649 //Intent intent2 = new Intent(uri);
1650 //Slog.i(TAG, "Given intent: " + r.intent);
1651 //Slog.i(TAG, "URI is: " + uri);
1652 //Slog.i(TAG, "To intent: " + intent2);
1653
1654 if (r.packageName != null) {
1655 // If the activity being launched is the same as the one currently
1656 // at the top, then we need to check if it should only be launched
1657 // once.
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001658 ActivityStack topStack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001659 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001660 if (top != null && r.resultTo == null) {
1661 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
1662 if (top.app != null && top.app.thread != null) {
1663 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1664 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
1665 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1666 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
1667 top.task);
1668 // For paranoia, make sure we have correctly
1669 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001670 topStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001671 if (doResume) {
Craig Mautner05d29032013-05-03 13:40:13 -07001672 resumeTopActivitiesLocked();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001673 }
1674 ActivityOptions.abort(options);
1675 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1676 // We don't need to start a new activity, and
1677 // the client said not to do anything if that
1678 // is the case, so this is it!
Craig Mautner29219d92013-04-16 20:19:12 -07001679 if (r.task == null) Slog.v(TAG,
1680 "startActivityUncheckedLocked: task left null",
1681 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001682 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1683 }
1684 top.deliverNewIntentLocked(callingUid, r.intent);
Craig Mautner29219d92013-04-16 20:19:12 -07001685 if (r.task == null) Slog.v(TAG,
1686 "startActivityUncheckedLocked: task left null",
1687 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001688 return ActivityManager.START_DELIVERED_TO_TOP;
1689 }
1690 }
1691 }
1692 }
1693
1694 } else {
1695 if (r.resultTo != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001696 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
1697 r.requestCode, Activity.RESULT_CANCELED, null);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001698 }
1699 ActivityOptions.abort(options);
Craig Mautner29219d92013-04-16 20:19:12 -07001700 if (r.task == null) Slog.v(TAG,
1701 "startActivityUncheckedLocked: task left null",
1702 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001703 return ActivityManager.START_CLASS_NOT_FOUND;
1704 }
1705
1706 boolean newTask = false;
1707 boolean keepCurTransition = false;
1708
1709 // Should this be considered a new task?
1710 if (r.resultTo == null && !addingToTask
1711 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001712 targetStack = adjustStackFocus(r);
Craig Mautnere0a38842013-12-16 16:14:02 -08001713 targetStack.moveToFront();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001714 if (reuseTask == null) {
Craig Mautner88629292013-11-10 20:39:05 -08001715 r.setTask(targetStack.createTaskRecord(getNextTaskId(),
1716 newTaskInfo != null ? newTaskInfo : r.info,
1717 newTaskIntent != null ? newTaskIntent : intent,
1718 true), null, true);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001719 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
1720 r.task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001721 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001722 r.setTask(reuseTask, reuseTask, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001723 }
1724 newTask = true;
1725 if (!movedHome) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001726 if ((launchFlags &
1727 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
1728 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
1729 // Caller wants to appear on home activity, so before starting
1730 // their own activity we will bring home to the front.
Craig Mautnere0a38842013-12-16 16:14:02 -08001731 r.task.mOnTopOfHome = r.task.stack.isOnHomeDisplay();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001732 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001733 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001734 } else if (sourceRecord != null) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001735 TaskRecord sourceTask = sourceRecord.task;
Craig Mautner525f3d92013-05-07 14:01:50 -07001736 targetStack = sourceTask.stack;
Craig Mautnere0a38842013-12-16 16:14:02 -08001737 targetStack.moveToFront();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001738 if (!addingToTask &&
1739 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
1740 // In this case, we are adding the activity to an existing
1741 // task, but the caller has asked to clear that task if the
1742 // activity is already running.
Craig Mautner525f3d92013-05-07 14:01:50 -07001743 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001744 keepCurTransition = true;
1745 if (top != null) {
1746 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
1747 top.deliverNewIntentLocked(callingUid, r.intent);
1748 // For paranoia, make sure we have correctly
1749 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001750 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001751 if (doResume) {
1752 targetStack.resumeTopActivityLocked(null);
1753 }
1754 ActivityOptions.abort(options);
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001755 if (r.task == null) Slog.w(TAG,
Craig Mautner29219d92013-04-16 20:19:12 -07001756 "startActivityUncheckedLocked: task left null",
1757 new RuntimeException("here").fillInStackTrace());
Craig Mautner8849a5e2013-04-02 16:41:03 -07001758 return ActivityManager.START_DELIVERED_TO_TOP;
1759 }
1760 } else if (!addingToTask &&
1761 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1762 // In this case, we are launching an activity in our own task
1763 // that may already be running somewhere in the history, and
1764 // we want to shuffle it to the front of the stack if so.
Craig Mautner525f3d92013-05-07 14:01:50 -07001765 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001766 if (top != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001767 final TaskRecord task = top.task;
1768 task.moveActivityToFrontLocked(top);
1769 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001770 top.updateOptionsLocked(options);
1771 top.deliverNewIntentLocked(callingUid, r.intent);
Craig Mautner0f922742013-08-06 08:44:42 -07001772 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001773 if (doResume) {
1774 targetStack.resumeTopActivityLocked(null);
1775 }
1776 return ActivityManager.START_DELIVERED_TO_TOP;
1777 }
1778 }
1779 // An existing activity is starting this new activity, so we want
1780 // to keep the new one in the same task as the one that is starting
1781 // it.
Craig Mautner525f3d92013-05-07 14:01:50 -07001782 r.setTask(sourceTask, sourceRecord.thumbHolder, false);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001783 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001784 + " in existing task " + r.task + " from source " + sourceRecord);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001785
1786 } else {
1787 // This not being started from an existing activity, and not part
1788 // of a new task... just put it in the top task, though these days
1789 // this case should never happen.
Craig Mautnerac6f8432013-07-17 13:24:59 -07001790 targetStack = adjustStackFocus(r);
Craig Mautnere0a38842013-12-16 16:14:02 -08001791 targetStack.moveToFront();
Craig Mautner1602ec22013-05-12 10:24:27 -07001792 ActivityRecord prev = targetStack.topActivity();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001793 r.setTask(prev != null ? prev.task
1794 : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1795 null, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001796 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1797 + " in new guessed " + r.task);
1798 }
1799
1800 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
1801 intent, r.getUriPermissionsLocked());
1802
1803 if (newTask) {
1804 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
1805 }
1806 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
Craig Mautner0f922742013-08-06 08:44:42 -07001807 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001808 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
Craig Mautner1d001b62013-06-18 16:52:43 -07001809 mService.setFocusedActivityLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001810 return ActivityManager.START_SUCCESS;
1811 }
1812
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001813 void acquireLaunchWakelock() {
1814 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
1815 throw new IllegalStateException("Calling must be system uid");
1816 }
1817 mLaunchingActivity.acquire();
1818 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
1819 // To be safe, don't allow the wake lock to be held for too long.
1820 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
1821 }
1822 }
1823
Craig Mautnerf3333272013-04-22 10:55:53 -07001824 // Checked.
1825 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
1826 Configuration config) {
1827 if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
1828
Craig Mautnerf3333272013-04-22 10:55:53 -07001829 ArrayList<ActivityRecord> stops = null;
1830 ArrayList<ActivityRecord> finishes = null;
1831 ArrayList<UserStartedState> startingUsers = null;
1832 int NS = 0;
1833 int NF = 0;
1834 IApplicationThread sendThumbnail = null;
1835 boolean booting = false;
1836 boolean enableScreen = false;
1837 boolean activityRemoved = false;
1838
1839 ActivityRecord r = ActivityRecord.forToken(token);
1840 if (r != null) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07001841 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
1842 Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07001843 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
1844 r.finishLaunchTickingLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001845 if (fromTimeout) {
1846 reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
Craig Mautnerf3333272013-04-22 10:55:53 -07001847 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001848
1849 // This is a hack to semi-deal with a race condition
1850 // in the client where it can be constructed with a
1851 // newer configuration from when we asked it to launch.
1852 // We'll update with whatever configuration it now says
1853 // it used to launch.
1854 if (config != null) {
1855 r.configuration = config;
1856 }
1857
1858 // We are now idle. If someone is waiting for a thumbnail from
1859 // us, we can now deliver.
1860 r.idle = true;
1861
1862 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
1863 sendThumbnail = r.app.thread;
1864 r.thumbnailNeeded = false;
1865 }
1866
1867 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
1868 if (!mService.mBooted && isFrontStack(r.task.stack)) {
1869 mService.mBooted = true;
1870 enableScreen = true;
1871 }
1872 }
1873
1874 if (allResumedActivitiesIdle()) {
1875 if (r != null) {
1876 mService.scheduleAppGcsLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001877 }
1878
1879 if (mLaunchingActivity.isHeld()) {
1880 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
1881 if (VALIDATE_WAKE_LOCK_CALLER &&
1882 Binder.getCallingUid() != Process.myUid()) {
1883 throw new IllegalStateException("Calling must be system uid");
1884 }
1885 mLaunchingActivity.release();
1886 }
1887 ensureActivitiesVisibleLocked(null, 0);
Craig Mautnerf3333272013-04-22 10:55:53 -07001888 }
1889
1890 // Atomically retrieve all of the other things to do.
1891 stops = processStoppingActivitiesLocked(true);
1892 NS = stops != null ? stops.size() : 0;
1893 if ((NF=mFinishingActivities.size()) > 0) {
1894 finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
1895 mFinishingActivities.clear();
1896 }
1897
1898 final ArrayList<ActivityRecord> thumbnails;
1899 final int NT = mCancelledThumbnails.size();
1900 if (NT > 0) {
1901 thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
1902 mCancelledThumbnails.clear();
1903 } else {
1904 thumbnails = null;
1905 }
1906
1907 if (isFrontStack(mHomeStack)) {
1908 booting = mService.mBooting;
1909 mService.mBooting = false;
1910 }
1911
1912 if (mStartingUsers.size() > 0) {
1913 startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
1914 mStartingUsers.clear();
1915 }
1916
1917 // Perform the following actions from unsynchronized state.
1918 final IApplicationThread thumbnailThread = sendThumbnail;
1919 mHandler.post(new Runnable() {
1920 @Override
1921 public void run() {
1922 if (thumbnailThread != null) {
1923 try {
1924 thumbnailThread.requestThumbnail(token);
1925 } catch (Exception e) {
1926 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
1927 mService.sendPendingThumbnail(null, token, null, null, true);
1928 }
1929 }
1930
1931 // Report back to any thumbnail receivers.
1932 for (int i = 0; i < NT; i++) {
1933 ActivityRecord r = thumbnails.get(i);
1934 mService.sendPendingThumbnail(r, null, null, null, true);
1935 }
1936 }
1937 });
1938
1939 // Stop any activities that are scheduled to do so but have been
1940 // waiting for the next one to start.
1941 for (int i = 0; i < NS; i++) {
1942 r = stops.get(i);
1943 final ActivityStack stack = r.task.stack;
1944 if (r.finishing) {
1945 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
1946 } else {
1947 stack.stopActivityLocked(r);
1948 }
1949 }
1950
1951 // Finish any activities that are scheduled to do so but have been
1952 // waiting for the next one to start.
1953 for (int i = 0; i < NF; i++) {
1954 r = finishes.get(i);
1955 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
1956 }
1957
1958 if (booting) {
1959 mService.finishBooting();
1960 } else if (startingUsers != null) {
1961 for (int i = 0; i < startingUsers.size(); i++) {
1962 mService.finishUserSwitch(startingUsers.get(i));
1963 }
1964 }
1965
1966 mService.trimApplications();
1967 //dump();
1968 //mWindowManager.dump();
1969
1970 if (enableScreen) {
1971 mService.enableScreenAfterBoot();
1972 }
1973
1974 if (activityRemoved) {
Craig Mautner05d29032013-05-03 13:40:13 -07001975 resumeTopActivitiesLocked();
Craig Mautnerf3333272013-04-22 10:55:53 -07001976 }
1977
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001978 return r;
Craig Mautnerf3333272013-04-22 10:55:53 -07001979 }
1980
Craig Mautner8e569572013-10-11 17:36:59 -07001981 boolean handleAppDiedLocked(ProcessRecord app) {
Craig Mautner19091252013-10-05 00:03:53 -07001982 boolean hasVisibleActivities = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08001983 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1984 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08001985 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1986 hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app);
1987 }
Craig Mautner6b74cb52013-09-27 17:02:21 -07001988 }
Craig Mautner19091252013-10-05 00:03:53 -07001989 return hasVisibleActivities;
Craig Mautner8d341ef2013-03-26 09:03:27 -07001990 }
1991
1992 void closeSystemDialogsLocked() {
Craig Mautnere0a38842013-12-16 16:14:02 -08001993 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1994 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08001995 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1996 stacks.get(stackNdx).closeSystemDialogsLocked();
1997 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07001998 }
1999 }
2000
Craig Mautner93529a42013-10-04 15:03:13 -07002001 void removeUserLocked(int userId) {
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002002 mUserStackInFront.delete(userId);
Craig Mautner93529a42013-10-04 15:03:13 -07002003 }
2004
Craig Mautner8d341ef2013-03-26 09:03:27 -07002005 /**
2006 * @return true if some activity was finished (or would have finished if doit were true).
2007 */
2008 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
2009 boolean didSomething = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002010 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2011 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002012 final int numStacks = stacks.size();
2013 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2014 final ActivityStack stack = stacks.get(stackNdx);
2015 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
2016 didSomething = true;
2017 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002018 }
2019 }
2020 return didSomething;
2021 }
2022
Dianne Hackborna413dc02013-07-12 12:02:55 -07002023 void updatePreviousProcessLocked(ActivityRecord r) {
2024 // Now that this process has stopped, we may want to consider
2025 // it to be the previous app to try to keep around in case
2026 // the user wants to return to it.
2027
2028 // First, found out what is currently the foreground app, so that
2029 // we don't blow away the previous app if this activity is being
2030 // hosted by the process that is actually still the foreground.
2031 ProcessRecord fgApp = null;
Craig Mautnere0a38842013-12-16 16:14:02 -08002032 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2033 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002034 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2035 final ActivityStack stack = stacks.get(stackNdx);
2036 if (isFrontStack(stack)) {
2037 if (stack.mResumedActivity != null) {
2038 fgApp = stack.mResumedActivity.app;
2039 } else if (stack.mPausingActivity != null) {
2040 fgApp = stack.mPausingActivity.app;
2041 }
2042 break;
Dianne Hackborna413dc02013-07-12 12:02:55 -07002043 }
Dianne Hackborna413dc02013-07-12 12:02:55 -07002044 }
2045 }
2046
2047 // Now set this one as the previous process, only if that really
2048 // makes sense to.
2049 if (r.app != null && fgApp != null && r.app != fgApp
2050 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
Craig Mautner4ef26932013-09-18 15:15:52 -07002051 && r.app != mService.mHomeProcess) {
Dianne Hackborna413dc02013-07-12 12:02:55 -07002052 mService.mPreviousProcess = r.app;
2053 mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
2054 }
2055 }
2056
Craig Mautner05d29032013-05-03 13:40:13 -07002057 boolean resumeTopActivitiesLocked() {
2058 return resumeTopActivitiesLocked(null, null, null);
2059 }
2060
2061 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
2062 Bundle targetOptions) {
2063 if (targetStack == null) {
2064 targetStack = getFocusedStack();
2065 }
2066 boolean result = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002067 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2068 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002069 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2070 final ActivityStack stack = stacks.get(stackNdx);
2071 if (isFrontStack(stack)) {
2072 if (stack == targetStack) {
2073 result = stack.resumeTopActivityLocked(target, targetOptions);
2074 } else {
2075 stack.resumeTopActivityLocked(null);
2076 }
Craig Mautner05d29032013-05-03 13:40:13 -07002077 }
Craig Mautnerf88c50f2013-04-18 19:25:12 -07002078 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002079 }
Craig Mautner05d29032013-05-03 13:40:13 -07002080 return result;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002081 }
2082
2083 void finishTopRunningActivityLocked(ProcessRecord app) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002084 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2085 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002086 final int numStacks = stacks.size();
2087 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2088 final ActivityStack stack = stacks.get(stackNdx);
2089 stack.finishTopRunningActivityLocked(app);
2090 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002091 }
2092 }
2093
Craig Mautner8d341ef2013-03-26 09:03:27 -07002094 void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002095 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2096 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002097 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2098 if (stacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) {
2099 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack="
2100 + stacks.get(stackNdx));
2101 return;
2102 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002103 }
2104 }
2105 }
2106
Craig Mautner967212c2013-04-13 21:10:58 -07002107 ActivityStack getStack(int stackId) {
Craig Mautner4504de52013-12-20 09:06:56 -08002108 WeakReference<ActivityContainer> weakReference = mActivityContainers.get(stackId);
2109 if (weakReference != null) {
2110 ActivityContainer activityContainer = weakReference.get();
2111 if (activityContainer != null) {
2112 return activityContainer.mStack;
2113 } else {
2114 mActivityContainers.remove(stackId);
2115 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002116 }
2117 return null;
2118 }
2119
Craig Mautner967212c2013-04-13 21:10:58 -07002120 ArrayList<ActivityStack> getStacks() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002121 ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>();
Craig Mautnere0a38842013-12-16 16:14:02 -08002122 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2123 allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002124 }
2125 return allStacks;
Craig Mautner967212c2013-04-13 21:10:58 -07002126 }
2127
Craig Mautner4a1cb222013-12-04 16:14:06 -08002128 IBinder getHomeActivityToken() {
2129 final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
2130 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
2131 final TaskRecord task = tasks.get(taskNdx);
2132 if (task.isHomeTask()) {
2133 final ArrayList<ActivityRecord> activities = task.mActivities;
2134 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2135 final ActivityRecord r = activities.get(activityNdx);
2136 if (r.isHomeActivity()) {
2137 return r.appToken;
2138 }
2139 }
2140 }
2141 }
2142 return null;
2143 }
2144
2145 ActivityContainer createActivityContainer(ActivityRecord parentActivity, int stackId,
2146 IActivityContainerCallback callback) {
2147 ActivityContainer activityContainer = new ActivityContainer(parentActivity, stackId,
2148 callback);
Craig Mautner4504de52013-12-20 09:06:56 -08002149 mActivityContainers.put(stackId, new WeakReference<ActivityContainer>(activityContainer));
Craig Mautner4a1cb222013-12-04 16:14:06 -08002150 if (parentActivity != null) {
2151 parentActivity.mChildContainers.add(activityContainer.mStack);
2152 }
2153 return activityContainer;
2154 }
2155
2156 ActivityContainer createActivityContainer(ActivityRecord parentActivity,
2157 IActivityContainerCallback callback) {
2158 return createActivityContainer(parentActivity, getNextStackId(), callback);
2159 }
2160
2161 private int createStackOnDisplay(ActivityRecord parentActivity, int stackId, int displayId) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002162 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2163 if (activityDisplay == null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002164 return -1;
2165 }
2166
2167 ActivityContainer activityContainer =
2168 createActivityContainer(parentActivity, stackId, null);
Craig Mautnere0a38842013-12-16 16:14:02 -08002169 activityContainer.attachToDisplayLocked(activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002170 return stackId;
2171 }
2172
2173 int getNextStackId() {
Craig Mautner858d8a62013-04-23 17:08:34 -07002174 while (true) {
2175 if (++mLastStackId <= HOME_STACK_ID) {
2176 mLastStackId = HOME_STACK_ID + 1;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002177 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002178 if (getStack(mLastStackId) == null) {
2179 break;
2180 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002181 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002182 return mLastStackId;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002183 }
2184
2185 void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002186 final TaskRecord task = anyTaskForIdLocked(taskId);
2187 if (task == null) {
2188 return;
2189 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002190 final ActivityStack stack = getStack(stackId);
2191 if (stack == null) {
2192 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
2193 return;
2194 }
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002195 removeTask(task);
2196 stack.addTask(task, toTop);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002197 mWindowManager.addTask(taskId, stackId, toTop);
Craig Mautner05d29032013-05-03 13:40:13 -07002198 resumeTopActivitiesLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002199 }
2200
Craig Mautnerac6f8432013-07-17 13:24:59 -07002201 ActivityRecord findTaskLocked(ActivityRecord r) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07002202 if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r);
Craig Mautnere0a38842013-12-16 16:14:02 -08002203 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2204 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002205 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2206 final ActivityStack stack = stacks.get(stackNdx);
2207 if (!r.isApplicationActivity() && !stack.isHomeStack()) {
2208 if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: " + stack);
2209 continue;
2210 }
2211 final ActivityRecord ar = stack.findTaskLocked(r);
2212 if (ar != null) {
2213 return ar;
2214 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07002215 }
2216 }
Dianne Hackborn2a272d42013-10-16 13:34:33 -07002217 if (DEBUG_TASKS) Slog.d(TAG, "No task found");
Craig Mautner8849a5e2013-04-02 16:41:03 -07002218 return null;
2219 }
2220
2221 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002222 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2223 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002224 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2225 final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info);
2226 if (ar != null) {
2227 return ar;
2228 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07002229 }
2230 }
2231 return null;
2232 }
2233
Craig Mautner8d341ef2013-03-26 09:03:27 -07002234 void goingToSleepLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002235 scheduleSleepTimeout();
2236 if (!mGoingToSleep.isHeld()) {
2237 mGoingToSleep.acquire();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002238 if (mLaunchingActivity.isHeld()) {
2239 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2240 throw new IllegalStateException("Calling must be system uid");
Craig Mautner0eea92c2013-05-16 13:35:39 -07002241 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002242 mLaunchingActivity.release();
2243 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
Craig Mautner0eea92c2013-05-16 13:35:39 -07002244 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002245 }
Amith Yamasanice15e152013-09-19 12:30:32 -07002246 checkReadyForSleepLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002247 }
2248
2249 boolean shutdownLocked(int timeout) {
2250 boolean timedout = false;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002251 goingToSleepLocked();
Craig Mautner0eea92c2013-05-16 13:35:39 -07002252
2253 final long endTime = System.currentTimeMillis() + timeout;
2254 while (true) {
2255 boolean cantShutdown = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002256 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2257 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002258 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2259 cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
2260 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002261 }
2262 if (cantShutdown) {
2263 long timeRemaining = endTime - System.currentTimeMillis();
2264 if (timeRemaining > 0) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002265 try {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002266 mService.wait(timeRemaining);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002267 } catch (InterruptedException e) {
2268 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002269 } else {
2270 Slog.w(TAG, "Activity manager shutdown timed out");
2271 timedout = true;
2272 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002273 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002274 } else {
2275 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002276 }
2277 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002278
2279 // Force checkReadyForSleep to complete.
2280 mSleepTimeout = true;
2281 checkReadyForSleepLocked();
2282
Craig Mautner8d341ef2013-03-26 09:03:27 -07002283 return timedout;
2284 }
2285
2286 void comeOutOfSleepIfNeededLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002287 removeSleepTimeouts();
2288 if (mGoingToSleep.isHeld()) {
2289 mGoingToSleep.release();
2290 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002291 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2292 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002293 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2294 final ActivityStack stack = stacks.get(stackNdx);
2295 stack.awakeFromSleepingLocked();
2296 if (isFrontStack(stack)) {
2297 resumeTopActivitiesLocked();
2298 }
Craig Mautner5314a402013-09-26 12:40:16 -07002299 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002300 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002301 mGoingToSleepActivities.clear();
2302 }
2303
2304 void activitySleptLocked(ActivityRecord r) {
2305 mGoingToSleepActivities.remove(r);
2306 checkReadyForSleepLocked();
2307 }
2308
2309 void checkReadyForSleepLocked() {
2310 if (!mService.isSleepingOrShuttingDown()) {
2311 // Do not care.
2312 return;
2313 }
2314
2315 if (!mSleepTimeout) {
2316 boolean dontSleep = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002317 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2318 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002319 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2320 dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
2321 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002322 }
2323
2324 if (mStoppingActivities.size() > 0) {
2325 // Still need to tell some activities to stop; can't sleep yet.
2326 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2327 + mStoppingActivities.size() + " activities");
2328 scheduleIdleLocked();
2329 dontSleep = true;
2330 }
2331
2332 if (mGoingToSleepActivities.size() > 0) {
2333 // Still need to tell some activities to sleep; can't sleep yet.
2334 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2335 + mGoingToSleepActivities.size() + " activities");
2336 dontSleep = true;
2337 }
2338
2339 if (dontSleep) {
2340 return;
2341 }
2342 }
2343
Craig Mautnere0a38842013-12-16 16:14:02 -08002344 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2345 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002346 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2347 stacks.get(stackNdx).goToSleep();
2348 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002349 }
2350
2351 removeSleepTimeouts();
2352
2353 if (mGoingToSleep.isHeld()) {
2354 mGoingToSleep.release();
2355 }
2356 if (mService.mShuttingDown) {
2357 mService.notifyAll();
2358 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002359 }
2360
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002361 boolean reportResumedActivityLocked(ActivityRecord r) {
2362 final ActivityStack stack = r.task.stack;
2363 if (isFrontStack(stack)) {
Jeff Sharkey5782da72013-04-25 14:32:30 -07002364 mService.updateUsageStats(r, true);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002365 }
2366 if (allResumedActivitiesComplete()) {
2367 ensureActivitiesVisibleLocked(null, 0);
2368 mWindowManager.executeAppTransition();
2369 return true;
2370 }
2371 return false;
2372 }
2373
Craig Mautner8d341ef2013-03-26 09:03:27 -07002374 void handleAppCrashLocked(ProcessRecord app) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002375 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2376 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002377 final int numStacks = stacks.size();
2378 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2379 final ActivityStack stack = stacks.get(stackNdx);
2380 stack.handleAppCrashLocked(app);
2381 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002382 }
2383 }
2384
Craig Mautnerde4ef022013-04-07 19:01:33 -07002385 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
Craig Mautner580ea812013-04-25 12:58:38 -07002386 // First the front stacks. In case any are not fullscreen and are in front of home.
2387 boolean showHomeBehindStack = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002388 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2389 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002390 final int topStackNdx = stacks.size() - 1;
2391 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
2392 final ActivityStack stack = stacks.get(stackNdx);
2393 if (stackNdx == topStackNdx) {
2394 // Top stack.
2395 showHomeBehindStack =
2396 stack.ensureActivitiesVisibleLocked(starting, configChanges);
2397 } else {
2398 // Back stack.
2399 stack.ensureActivitiesVisibleLocked(starting, configChanges,
2400 showHomeBehindStack);
2401 }
Craig Mautner580ea812013-04-25 12:58:38 -07002402 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002403 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002404 }
2405
2406 void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002407 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2408 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002409 final int numStacks = stacks.size();
2410 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2411 final ActivityStack stack = stacks.get(stackNdx);
2412 stack.scheduleDestroyActivities(app, false, reason);
2413 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002414 }
2415 }
2416
2417 boolean switchUserLocked(int userId, UserStartedState uss) {
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002418 mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId());
2419 final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
Craig Mautner2420ead2013-04-01 17:13:20 -07002420 mCurrentUser = userId;
Craig Mautnerac6f8432013-07-17 13:24:59 -07002421
Craig Mautner858d8a62013-04-23 17:08:34 -07002422 mStartingUsers.add(uss);
Craig Mautnere0a38842013-12-16 16:14:02 -08002423 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2424 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002425 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002426 final ActivityStack stack = stacks.get(stackNdx);
2427 stack.switchUserLocked(userId);
2428 mWindowManager.moveTaskToTop(stack.topTask().taskId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002429 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07002430 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002431
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002432 ActivityStack stack = getStack(restoreStackId);
2433 if (stack == null) {
2434 stack = mHomeStack;
2435 }
2436 final boolean homeInFront = stack.isHomeStack();
Craig Mautnere0a38842013-12-16 16:14:02 -08002437 if (stack.isOnHomeDisplay()) {
2438 moveHomeStack(homeInFront);
2439 mWindowManager.moveTaskToTop(stack.topTask().taskId);
2440 } else {
2441 // Stack was moved to another display while user was swapped out.
2442 resumeHomeActivity(null);
2443 }
Craig Mautner93529a42013-10-04 15:03:13 -07002444 return homeInFront;
Craig Mautner2219a1b2013-03-25 09:44:30 -07002445 }
2446
Craig Mautnerde4ef022013-04-07 19:01:33 -07002447 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2448 int N = mStoppingActivities.size();
2449 if (N <= 0) return null;
2450
2451 ArrayList<ActivityRecord> stops = null;
2452
2453 final boolean nowVisible = allResumedActivitiesVisible();
2454 for (int i=0; i<N; i++) {
2455 ActivityRecord s = mStoppingActivities.get(i);
Craig Mautnera7f2bd42013-10-15 16:13:50 -07002456 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
Craig Mautnerde4ef022013-04-07 19:01:33 -07002457 + nowVisible + " waitingVisible=" + s.waitingVisible
2458 + " finishing=" + s.finishing);
2459 if (s.waitingVisible && nowVisible) {
2460 mWaitingVisibleActivities.remove(s);
2461 s.waitingVisible = false;
2462 if (s.finishing) {
2463 // If this activity is finishing, it is sitting on top of
2464 // everyone else but we now know it is no longer needed...
2465 // so get rid of it. Otherwise, we need to go through the
2466 // normal flow and hide it once we determine that it is
2467 // hidden by the activities in front of it.
2468 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002469 mWindowManager.setAppVisibility(s.appToken, false);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002470 }
2471 }
2472 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2473 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2474 if (stops == null) {
2475 stops = new ArrayList<ActivityRecord>();
2476 }
2477 stops.add(s);
2478 mStoppingActivities.remove(i);
2479 N--;
2480 i--;
2481 }
2482 }
2483
2484 return stops;
2485 }
2486
Craig Mautnercf910b02013-04-23 11:23:27 -07002487 void validateTopActivitiesLocked() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002488 // FIXME
2489/* for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2490 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautnercf910b02013-04-23 11:23:27 -07002491 final ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002492 final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
Craig Mautnercf910b02013-04-23 11:23:27 -07002493 if (isFrontStack(stack)) {
2494 if (r == null) {
2495 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2496 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002497 final ActivityRecord pausing = stack.mPausingActivity;
2498 if (pausing != null && pausing == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002499 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002500 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002501 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002502 if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002503 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002504 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002505 }
2506 }
2507 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002508 final ActivityRecord resumed = stack.mResumedActivity;
2509 if (resumed != null && resumed == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002510 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002511 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002512 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002513 if (r != null && (state == ActivityState.INITIALIZING
2514 || state == ActivityState.RESUMED)) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002515 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002516 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002517 }
2518 }
2519 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002520*/
Craig Mautner76ea2242013-05-15 11:40:05 -07002521 }
2522
Craig Mautner27084302013-03-25 08:05:25 -07002523 public void dump(PrintWriter pw, String prefix) {
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002524 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity=");
Craig Mautner27084302013-03-25 08:05:25 -07002525 pw.println(mDismissKeyguardOnNextActivity);
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002526 pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002527 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002528 pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
2529 pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
2530 pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
Craig Mautner27084302013-03-25 08:05:25 -07002531 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002532
Craig Mautner20e72272013-04-01 13:45:53 -07002533 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002534 return getFocusedStack().getDumpActivitiesLocked(name);
Craig Mautner20e72272013-04-01 13:45:53 -07002535 }
2536
Dianne Hackborn390517b2013-05-30 15:03:32 -07002537 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2538 boolean needSep, String prefix) {
2539 if (activity != null) {
2540 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2541 if (needSep) {
2542 pw.println();
Dianne Hackborn390517b2013-05-30 15:03:32 -07002543 }
2544 pw.print(prefix);
2545 pw.println(activity);
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002546 return true;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002547 }
2548 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002549 return false;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002550 }
2551
Craig Mautner8d341ef2013-03-26 09:03:27 -07002552 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2553 boolean dumpClient, String dumpPackage) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002554 boolean printed = false;
2555 boolean needSep = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002556 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2557 ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
2558 pw.print("Display #"); pw.println(activityDisplay.mDisplayId);
2559 ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002560 final int numStacks = stacks.size();
2561 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2562 final ActivityStack stack = stacks.get(stackNdx);
2563 StringBuilder stackHeader = new StringBuilder(128);
2564 stackHeader.append(" Stack #");
2565 stackHeader.append(stack.mStackId);
2566 stackHeader.append(":");
2567 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
2568 needSep, stackHeader.toString());
2569 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false,
2570 !dumpAll, false, dumpPackage, true,
2571 " Running activities (most recent first):", null);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002572
Craig Mautner4a1cb222013-12-04 16:14:06 -08002573 needSep = printed;
2574 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
2575 " mPausingActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002576 if (pr) {
2577 printed = true;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002578 needSep = false;
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002579 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002580 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
2581 " mResumedActivity: ");
2582 if (pr) {
2583 printed = true;
2584 needSep = false;
2585 }
2586 if (dumpAll) {
2587 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
2588 " mLastPausedActivity: ");
2589 if (pr) {
2590 printed = true;
2591 needSep = true;
2592 }
2593 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
2594 needSep, " mLastNoHistoryActivity: ");
2595 }
2596 needSep = printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002597 }
2598 }
2599
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002600 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll,
2601 false, dumpPackage, true, " Activities waiting to finish:", null);
2602 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll,
2603 false, dumpPackage, true, " Activities waiting to stop:", null);
2604 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll,
2605 false, dumpPackage, true, " Activities waiting for another to become visible:",
2606 null);
2607 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2608 false, dumpPackage, true, " Activities waiting to sleep:", null);
2609 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2610 false, dumpPackage, true, " Activities waiting to sleep:", null);
Craig Mautnerf3333272013-04-22 10:55:53 -07002611
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002612 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002613 }
2614
Dianne Hackborn390517b2013-05-30 15:03:32 -07002615 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
Craig Mautner8d341ef2013-03-26 09:03:27 -07002616 String prefix, String label, boolean complete, boolean brief, boolean client,
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002617 String dumpPackage, boolean needNL, String header1, String header2) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002618 TaskRecord lastTask = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002619 String innerPrefix = null;
2620 String[] args = null;
2621 boolean printed = false;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002622 for (int i=list.size()-1; i>=0; i--) {
2623 final ActivityRecord r = list.get(i);
2624 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2625 continue;
2626 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002627 if (innerPrefix == null) {
2628 innerPrefix = prefix + " ";
2629 args = new String[0];
2630 }
2631 printed = true;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002632 final boolean full = !brief && (complete || !r.isInHistory());
2633 if (needNL) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07002634 pw.println("");
Craig Mautner8d341ef2013-03-26 09:03:27 -07002635 needNL = false;
2636 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002637 if (header1 != null) {
2638 pw.println(header1);
2639 header1 = null;
2640 }
2641 if (header2 != null) {
2642 pw.println(header2);
2643 header2 = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002644 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002645 if (lastTask != r.task) {
2646 lastTask = r.task;
2647 pw.print(prefix);
2648 pw.print(full ? "* " : " ");
2649 pw.println(lastTask);
2650 if (full) {
2651 lastTask.dump(pw, prefix + " ");
2652 } else if (complete) {
2653 // Complete + brief == give a summary. Isn't that obvious?!?
2654 if (lastTask.intent != null) {
2655 pw.print(prefix); pw.print(" ");
2656 pw.println(lastTask.intent.toInsecureStringWithClip());
2657 }
2658 }
2659 }
2660 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
2661 pw.print(" #"); pw.print(i); pw.print(": ");
2662 pw.println(r);
2663 if (full) {
2664 r.dump(pw, innerPrefix);
2665 } else if (complete) {
2666 // Complete + brief == give a summary. Isn't that obvious?!?
2667 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2668 if (r.app != null) {
2669 pw.print(innerPrefix); pw.println(r.app);
2670 }
2671 }
2672 if (client && r.app != null && r.app.thread != null) {
2673 // flush anything that is already in the PrintWriter since the thread is going
2674 // to write to the file descriptor directly
2675 pw.flush();
2676 try {
2677 TransferPipe tp = new TransferPipe();
2678 try {
2679 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2680 r.appToken, innerPrefix, args);
2681 // Short timeout, since blocking here can
2682 // deadlock with the application.
2683 tp.go(fd, 2000);
2684 } finally {
2685 tp.kill();
2686 }
2687 } catch (IOException e) {
2688 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2689 } catch (RemoteException e) {
2690 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2691 }
2692 needNL = true;
2693 }
2694 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002695 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002696 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002697
Craig Mautnerf3333272013-04-22 10:55:53 -07002698 void scheduleIdleTimeoutLocked(ActivityRecord next) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002699 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
Craig Mautnerc64f73e2013-04-24 16:44:56 -07002700 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2701 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
Craig Mautnerf3333272013-04-22 10:55:53 -07002702 }
2703
2704 final void scheduleIdleLocked() {
Craig Mautner05d29032013-05-03 13:40:13 -07002705 mHandler.sendEmptyMessage(IDLE_NOW_MSG);
Craig Mautnerf3333272013-04-22 10:55:53 -07002706 }
2707
2708 void removeTimeoutsForActivityLocked(ActivityRecord r) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002709 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07002710 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2711 }
2712
Craig Mautner05d29032013-05-03 13:40:13 -07002713 final void scheduleResumeTopActivities() {
2714 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2715 }
2716
Craig Mautner0eea92c2013-05-16 13:35:39 -07002717 void removeSleepTimeouts() {
2718 mSleepTimeout = false;
2719 mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2720 }
2721
2722 final void scheduleSleepTimeout() {
2723 removeSleepTimeouts();
2724 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2725 }
2726
Craig Mautner4a1cb222013-12-04 16:14:06 -08002727 @Override
2728 public void onDisplayAdded(int displayId) {
2729 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
2730 }
2731
2732 @Override
2733 public void onDisplayRemoved(int displayId) {
2734 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
2735 }
2736
2737 @Override
2738 public void onDisplayChanged(int displayId) {
2739 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
2740 }
2741
2742 public void handleDisplayAddedLocked(int displayId) {
Craig Mautner4504de52013-12-20 09:06:56 -08002743 boolean newDisplay;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002744 synchronized (mService) {
Craig Mautner4504de52013-12-20 09:06:56 -08002745 newDisplay = mActivityDisplays.get(displayId) == null;
2746 if (newDisplay) {
2747 ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
2748 mActivityDisplays.put(displayId, activityDisplay);
2749 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002750 }
Craig Mautner4504de52013-12-20 09:06:56 -08002751 if (newDisplay) {
2752 mWindowManager.onDisplayAdded(displayId);
2753 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002754 }
2755
2756 public void handleDisplayRemovedLocked(int displayId) {
2757 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002758 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2759 if (activityDisplay != null) {
2760 ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002761 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002762 activityDisplay.detachActivitiesLocked(stacks.get(stackNdx));
Craig Mautner4a1cb222013-12-04 16:14:06 -08002763 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002764 mActivityDisplays.remove(displayId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002765 }
2766 }
2767 mWindowManager.onDisplayRemoved(displayId);
2768 }
2769
2770 public void handleDisplayChangedLocked(int displayId) {
2771 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002772 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2773 if (activityDisplay != null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002774 // TODO: Update the bounds.
2775 }
2776 }
2777 mWindowManager.onDisplayChanged(displayId);
2778 }
2779
2780 StackInfo getStackInfo(ActivityStack stack) {
2781 StackInfo info = new StackInfo();
2782 mWindowManager.getStackBounds(stack.mStackId, info.bounds);
2783 info.displayId = Display.DEFAULT_DISPLAY;
2784 info.stackId = stack.mStackId;
2785
2786 ArrayList<TaskRecord> tasks = stack.getAllTasks();
2787 final int numTasks = tasks.size();
2788 int[] taskIds = new int[numTasks];
2789 String[] taskNames = new String[numTasks];
2790 for (int i = 0; i < numTasks; ++i) {
2791 final TaskRecord task = tasks.get(i);
2792 taskIds[i] = task.taskId;
2793 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
2794 : task.realActivity != null ? task.realActivity.flattenToString()
2795 : task.getTopActivity() != null ? task.getTopActivity().packageName
2796 : "unknown";
2797 }
2798 info.taskIds = taskIds;
2799 info.taskNames = taskNames;
2800 return info;
2801 }
2802
2803 StackInfo getStackInfoLocked(int stackId) {
2804 ActivityStack stack = getStack(stackId);
2805 if (stack != null) {
2806 return getStackInfo(stack);
2807 }
2808 return null;
2809 }
2810
2811 ArrayList<StackInfo> getAllStackInfosLocked() {
2812 ArrayList<StackInfo> list = new ArrayList<StackInfo>();
Craig Mautnere0a38842013-12-16 16:14:02 -08002813 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2814 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002815 for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
2816 list.add(getStackInfo(stacks.get(ndx)));
2817 }
2818 }
2819 return list;
2820 }
2821
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002822 private final class ActivityStackSupervisorHandler extends Handler {
Craig Mautnerf3333272013-04-22 10:55:53 -07002823
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002824 public ActivityStackSupervisorHandler(Looper looper) {
2825 super(looper);
2826 }
2827
Craig Mautnerf3333272013-04-22 10:55:53 -07002828 void activityIdleInternal(ActivityRecord r) {
2829 synchronized (mService) {
2830 activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
2831 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002832 }
2833
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002834 @Override
2835 public void handleMessage(Message msg) {
2836 switch (msg.what) {
Craig Mautnerf3333272013-04-22 10:55:53 -07002837 case IDLE_TIMEOUT_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002838 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002839 if (mService.mDidDexOpt) {
2840 mService.mDidDexOpt = false;
2841 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2842 nmsg.obj = msg.obj;
2843 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
2844 return;
2845 }
2846 // We don't at this point know if the activity is fullscreen,
2847 // so we need to be conservative and assume it isn't.
2848 activityIdleInternal((ActivityRecord)msg.obj);
2849 } break;
2850 case IDLE_NOW_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002851 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002852 activityIdleInternal((ActivityRecord)msg.obj);
2853 } break;
Craig Mautner05d29032013-05-03 13:40:13 -07002854 case RESUME_TOP_ACTIVITY_MSG: {
2855 synchronized (mService) {
2856 resumeTopActivitiesLocked();
2857 }
2858 } break;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002859 case SLEEP_TIMEOUT_MSG: {
2860 synchronized (mService) {
2861 if (mService.isSleepingOrShuttingDown()) {
2862 Slog.w(TAG, "Sleep timeout! Sleeping now.");
2863 mSleepTimeout = true;
2864 checkReadyForSleepLocked();
2865 }
2866 }
2867 } break;
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002868 case LAUNCH_TIMEOUT_MSG: {
2869 if (mService.mDidDexOpt) {
2870 mService.mDidDexOpt = false;
2871 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
2872 return;
2873 }
2874 synchronized (mService) {
2875 if (mLaunchingActivity.isHeld()) {
2876 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
2877 if (VALIDATE_WAKE_LOCK_CALLER
2878 && Binder.getCallingUid() != Process.myUid()) {
2879 throw new IllegalStateException("Calling must be system uid");
2880 }
2881 mLaunchingActivity.release();
2882 }
2883 }
2884 } break;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002885 case HANDLE_DISPLAY_ADDED: {
2886 handleDisplayAddedLocked(msg.arg1);
2887 } break;
2888 case HANDLE_DISPLAY_CHANGED: {
2889 handleDisplayChangedLocked(msg.arg1);
2890 } break;
2891 case HANDLE_DISPLAY_REMOVED: {
2892 handleDisplayRemovedLocked(msg.arg1);
2893 } break;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002894 }
2895 }
2896 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08002897
Craig Mautner4a1cb222013-12-04 16:14:06 -08002898 class ActivityContainer extends IActivityContainer.Stub {
2899 final int mStackId;
2900 final IActivityContainerCallback mCallback;
2901 final ActivityStack mStack;
2902 final ActivityRecord mParentActivity;
Craig Mautnerbdc748af2013-12-02 14:08:25 -08002903
Craig Mautner4a1cb222013-12-04 16:14:06 -08002904 /** Display this ActivityStack is currently on. Null if not attached to a Display. */
Craig Mautnere0a38842013-12-16 16:14:02 -08002905 ActivityDisplay mActivityDisplay;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002906
2907 ActivityContainer(ActivityRecord parentActivity, int stackId,
2908 IActivityContainerCallback callback) {
2909 synchronized (mService) {
2910 mStackId = stackId;
2911 mStack = new ActivityStack(this);
2912 mParentActivity = parentActivity;
2913 mCallback = callback;
2914 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08002915 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002916
Craig Mautnere0a38842013-12-16 16:14:02 -08002917 void attachToDisplayLocked(ActivityDisplay activityDisplay) {
2918 mActivityDisplay = activityDisplay;
2919 mStack.mDisplayId = activityDisplay.mDisplayId;
2920 mStack.mStacks = activityDisplay.mStacks;
2921
2922 activityDisplay.attachActivities(mStack);
2923 mWindowManager.createStack(mStackId, activityDisplay.mDisplayId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002924 }
2925
2926 @Override
2927 public void attachToDisplay(int displayId) throws RemoteException {
2928 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002929 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2930 if (activityDisplay == null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002931 return;
2932 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002933 attachToDisplayLocked(activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002934 }
2935 }
2936
2937 @Override
Craig Mautnere0a38842013-12-16 16:14:02 -08002938 public int getDisplayId() throws RemoteException {
2939 if (mActivityDisplay != null) {
2940 return mActivityDisplay.mDisplayId;
2941 }
2942 return -1;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002943 }
2944
2945 void detachLocked() {
Craig Mautnere0a38842013-12-16 16:14:02 -08002946 if (mActivityDisplay != null) {
2947 mActivityDisplay.detachActivitiesLocked(mStack);
2948 mActivityDisplay = null;
2949 mStack.mDisplayId = -1;
2950 mStack.mStacks = null;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002951 }
2952 }
2953
2954 @Override
2955 public void detachFromDisplay() throws RemoteException {
2956 synchronized (mService) {
2957 detachLocked();
2958 }
2959 }
2960
2961 @Override
Craig Mautnere0a38842013-12-16 16:14:02 -08002962 public final int startActivity(Intent intent) {
2963 mService.enforceNotIsolatedCaller("ActivityContainer");
2964 int userId = mService.handleIncomingUser(Binder.getCallingPid(),
2965 Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null);
2966 // TODO: Switch to user app stacks here.
2967 String mimeType = intent.getType();
2968 if (mimeType == null && intent.getData() != null
2969 && "content".equals(intent.getData().getScheme())) {
2970 mimeType = mService.getProviderMimeType(intent.getData(), userId);
2971 }
2972 return startActivityMayWait(null, -1, null, intent, mimeType, null, null, 0, 0, null,
2973 null, null, null, null, userId, this);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002974 }
2975
2976 @Override
2977 public IBinder asBinder() {
2978 return this;
2979 }
2980
Craig Mautner4504de52013-12-20 09:06:56 -08002981 @Override
2982 public void createActivityView(Surface surface, int width, int height, int density) {
2983 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
2984 VirtualDisplay virtualDisplay;
2985 long ident = Binder.clearCallingIdentity();
2986 try {
2987 virtualDisplay = dm.createVirtualDisplay(mService.mContext,
2988 VIRTUAL_DISPLAY_BASE_NAME, width, height, density, surface,
2989 // TODO: Add VIRTUAL_DISPLAY_FLAG_DISABLE_MIRRORING when it is available.
2990 DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC);
2991 } finally {
2992 Binder.restoreCallingIdentity(ident);
2993 }
2994
2995 final Display display = virtualDisplay.getDisplay();
2996 final int displayId = display.getDisplayId();
2997
2998 // Do WindowManager operation first so that it is ahead of CREATE_STACK in the H queue.
2999 mWindowManager.onDisplayAdded(displayId);
3000
3001 synchronized (mService) {
3002 ActivityDisplay activityDisplay = new ActivityDisplay(display);
3003 mActivityDisplays.put(displayId, activityDisplay);
3004 attachToDisplayLocked(activityDisplay);
3005 activityDisplay.mVirtualDisplay = virtualDisplay;
3006 }
3007 }
3008
3009 @Override
3010 public void deleteActivityView() {
3011 synchronized (mService) {
3012 if (!isAttached()) {
3013 return;
3014 }
3015 VirtualDisplay virtualDisplay = mActivityDisplay.mVirtualDisplay;
3016 if (virtualDisplay != null) {
3017 virtualDisplay.release();
3018 mActivityDisplay.mVirtualDisplay = null;
3019 }
3020 detachLocked();
3021 }
3022 }
3023
Craig Mautner4a1cb222013-12-04 16:14:06 -08003024 ActivityStackSupervisor getOuter() {
3025 return ActivityStackSupervisor.this;
3026 }
3027
3028 boolean isAttached() {
Craig Mautnere0a38842013-12-16 16:14:02 -08003029 return mActivityDisplay != null;
Craig Mautner4a1cb222013-12-04 16:14:06 -08003030 }
3031
3032 void getBounds(Point outBounds) {
Craig Mautnere0a38842013-12-16 16:14:02 -08003033 if (mActivityDisplay != null) {
3034 mActivityDisplay.getBounds(outBounds);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003035 } else {
3036 outBounds.set(0, 0);
3037 }
3038 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003039 }
3040
Craig Mautner4a1cb222013-12-04 16:14:06 -08003041 /** Exactly one of these classes per Display in the system. Capable of holding zero or more
3042 * attached {@link ActivityStack}s */
Craig Mautnere0a38842013-12-16 16:14:02 -08003043 final class ActivityDisplay {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003044 /** Actual Display this object tracks. */
3045 final int mDisplayId;
3046 final Display mDisplay;
3047 final DisplayInfo mDisplayInfo = new DisplayInfo();
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003048
Craig Mautner4a1cb222013-12-04 16:14:06 -08003049 /** All of the stacks on this display. Order matters, topmost stack is in front of all other
3050 * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
Craig Mautnere0a38842013-12-16 16:14:02 -08003051 final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003052
Craig Mautner4504de52013-12-20 09:06:56 -08003053 /** If this display is for an ActivityView then the VirtualDisplay created for it is stored
3054 * here. */
3055 VirtualDisplay mVirtualDisplay;
3056
Craig Mautnere0a38842013-12-16 16:14:02 -08003057 ActivityDisplay(int displayId) {
Craig Mautner4504de52013-12-20 09:06:56 -08003058 this(mDisplayManager.getDisplay(displayId));
3059 }
3060
3061 ActivityDisplay(Display display) {
3062 mDisplay = display;
3063 mDisplayId = display.getDisplayId();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003064 mDisplay.getDisplayInfo(mDisplayInfo);
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003065 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08003066
3067 void attachActivities(ActivityStack stack) {
Craig Mautnere0a38842013-12-16 16:14:02 -08003068 if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId="
3069 + mDisplayId);
3070 mStacks.add(stack);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003071 }
3072
Craig Mautnere0a38842013-12-16 16:14:02 -08003073 void detachActivitiesLocked(ActivityStack stack) {
3074 if (DEBUG_STACK) Slog.v(TAG, "attachActivities: detaching " + stack
3075 + " from displayId=" + mDisplayId);
3076 mStacks.remove(stack);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003077 }
3078
3079 void getBounds(Point bounds) {
3080 mDisplay.getDisplayInfo(mDisplayInfo);
3081 bounds.x = mDisplayInfo.appWidth;
3082 bounds.y = mDisplayInfo.appHeight;
3083 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003084 }
Craig Mautner27084302013-03-25 08:05:25 -07003085}