blob: 8f8b2a27ad6ac1cc543651884dcc48fd57eccd0f [file] [log] [blame]
Craig Mautner27084302013-03-25 08:05:25 -07001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
Craig Mautner6170f732013-04-02 13:05:23 -070019import static android.Manifest.permission.START_ANY_ACTIVITY;
Craig Mautner29219d92013-04-16 20:19:12 -070020import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
21import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
Craig Mautner6170f732013-04-02 13:05:23 -070022import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Craig Mautner2420ead2013-04-01 17:13:20 -070023import static com.android.server.am.ActivityManagerService.localLOGV;
Craig Mautner23ac33b2013-04-01 16:26:35 -070024import static com.android.server.am.ActivityManagerService.DEBUG_CONFIGURATION;
Craig Mautnere7c58b62013-06-12 20:19:00 -070025import static com.android.server.am.ActivityManagerService.DEBUG_FOCUS;
Craig Mautner0eea92c2013-05-16 13:35:39 -070026import static com.android.server.am.ActivityManagerService.DEBUG_PAUSE;
Craig Mautner6170f732013-04-02 13:05:23 -070027import static com.android.server.am.ActivityManagerService.DEBUG_RESULTS;
Craig Mautner0eea92c2013-05-16 13:35:39 -070028import static com.android.server.am.ActivityManagerService.DEBUG_STACK;
Craig Mautner2420ead2013-04-01 17:13:20 -070029import static com.android.server.am.ActivityManagerService.DEBUG_SWITCH;
Craig Mautner8849a5e2013-04-02 16:41:03 -070030import static com.android.server.am.ActivityManagerService.DEBUG_TASKS;
31import static com.android.server.am.ActivityManagerService.DEBUG_USER_LEAVING;
Craig Mautner05d29032013-05-03 13:40:13 -070032import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
Craig Mautner8d341ef2013-03-26 09:03:27 -070033import static com.android.server.am.ActivityManagerService.TAG;
34
Craig Mautner2420ead2013-04-01 17:13:20 -070035import android.app.Activity;
Craig Mautner23ac33b2013-04-01 16:26:35 -070036import android.app.ActivityManager;
Craig Mautnered6649f2013-12-02 14:08:25 -080037import android.app.ActivityManager.StackInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070038import android.app.ActivityOptions;
39import android.app.AppGlobals;
Craig Mautner4a1cb222013-12-04 16:14:06 -080040import android.app.IActivityContainer;
41import android.app.IActivityContainerCallback;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070042import android.app.IActivityManager;
Craig Mautner23ac33b2013-04-01 16:26:35 -070043import android.app.IApplicationThread;
Craig Mautner20e72272013-04-01 13:45:53 -070044import android.app.IThumbnailReceiver;
Craig Mautner23ac33b2013-04-01 16:26:35 -070045import android.app.PendingIntent;
Craig Mautner20e72272013-04-01 13:45:53 -070046import android.app.ActivityManager.RunningTaskInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070047import android.app.IActivityManager.WaitResult;
Craig Mautner2420ead2013-04-01 17:13:20 -070048import android.app.ResultInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070049import android.content.ComponentName;
Craig Mautner2219a1b2013-03-25 09:44:30 -070050import android.content.Context;
Craig Mautner23ac33b2013-04-01 16:26:35 -070051import android.content.IIntentSender;
Craig Mautner2219a1b2013-03-25 09:44:30 -070052import android.content.Intent;
Craig Mautner23ac33b2013-04-01 16:26:35 -070053import android.content.IntentSender;
Craig Mautner2219a1b2013-03-25 09:44:30 -070054import android.content.pm.ActivityInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070055import android.content.pm.ApplicationInfo;
56import android.content.pm.PackageManager;
57import android.content.pm.ResolveInfo;
58import android.content.res.Configuration;
Craig Mautner4a1cb222013-12-04 16:14:06 -080059import android.graphics.Point;
60import android.hardware.display.DisplayManager;
61import android.hardware.display.DisplayManager.DisplayListener;
Craig Mautner4504de52013-12-20 09:06:56 -080062import android.hardware.display.DisplayManagerGlobal;
63import android.hardware.display.VirtualDisplay;
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 Mautnered6649f2013-12-02 14:08:25 -080082import android.view.Display;
Craig Mautner4a1cb222013-12-04 16:14:06 -080083import android.view.DisplayInfo;
Craig Mautner4504de52013-12-20 09:06:56 -080084import android.view.Surface;
Craig Mautner23ac33b2013-04-01 16:26:35 -070085import com.android.internal.app.HeavyWeightSwitcherActivity;
Dianne Hackborncbfd23e2013-06-11 14:26:53 -070086import com.android.internal.os.TransferPipe;
Craig Mautner6170f732013-04-02 13:05:23 -070087import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
Craig Mautner2420ead2013-04-01 17:13:20 -070088import com.android.server.am.ActivityStack.ActivityState;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070089import com.android.server.wm.WindowManagerService;
Craig Mautner23ac33b2013-04-01 16:26:35 -070090
Craig Mautner8d341ef2013-03-26 09:03:27 -070091import java.io.FileDescriptor;
92import java.io.IOException;
Craig Mautner27084302013-03-25 08:05:25 -070093import java.io.PrintWriter;
Craig Mautner4504de52013-12-20 09:06:56 -080094import java.lang.ref.WeakReference;
Craig Mautner2219a1b2013-03-25 09:44:30 -070095import java.util.ArrayList;
Craig Mautner8d341ef2013-03-26 09:03:27 -070096import java.util.List;
Craig Mautner27084302013-03-25 08:05:25 -070097
Craig Mautner4a1cb222013-12-04 16:14:06 -080098public final class ActivityStackSupervisor implements DisplayListener {
Craig Mautnerde4ef022013-04-07 19:01:33 -070099 static final boolean DEBUG = ActivityManagerService.DEBUG || false;
100 static final boolean DEBUG_ADD_REMOVE = DEBUG || false;
101 static final boolean DEBUG_APP = DEBUG || false;
102 static final boolean DEBUG_SAVED_STATE = DEBUG || false;
Craig Mautnera7f2bd42013-10-15 16:13:50 -0700103 static final boolean DEBUG_STATES = DEBUG || false;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -0700104 static final boolean DEBUG_IDLE = DEBUG || false;
Craig Mautner2420ead2013-04-01 17:13:20 -0700105
Craig Mautner2219a1b2013-03-25 09:44:30 -0700106 public static final int HOME_STACK_ID = 0;
Craig Mautner27084302013-03-25 08:05:25 -0700107
Craig Mautnerf3333272013-04-22 10:55:53 -0700108 /** How long we wait until giving up on the last activity telling us it is idle. */
109 static final int IDLE_TIMEOUT = 10*1000;
110
Craig Mautner0eea92c2013-05-16 13:35:39 -0700111 /** How long we can hold the sleep wake lock before giving up. */
112 static final int SLEEP_TIMEOUT = 5*1000;
113
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700114 // How long we can hold the launch wake lock before giving up.
115 static final int LAUNCH_TIMEOUT = 10*1000;
116
Craig Mautner05d29032013-05-03 13:40:13 -0700117 static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG;
118 static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1;
119 static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2;
Craig Mautner0eea92c2013-05-16 13:35:39 -0700120 static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3;
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700121 static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800122 static final int HANDLE_DISPLAY_ADDED = FIRST_SUPERVISOR_STACK_MSG + 5;
123 static final int HANDLE_DISPLAY_CHANGED = FIRST_SUPERVISOR_STACK_MSG + 6;
124 static final int HANDLE_DISPLAY_REMOVED = FIRST_SUPERVISOR_STACK_MSG + 7;
125
Craig Mautner4504de52013-12-20 09:06:56 -0800126 private final static String VIRTUAL_DISPLAY_BASE_NAME = "ActivityViewVirtualDisplay";
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700127
128 // For debugging to make sure the caller when acquiring/releasing our
129 // wake lock is the system process.
130 static final boolean VALIDATE_WAKE_LOCK_CALLER = false;
Craig Mautnerf3333272013-04-22 10:55:53 -0700131
Craig Mautner27084302013-03-25 08:05:25 -0700132 final ActivityManagerService mService;
133
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700134 final ActivityStackSupervisorHandler mHandler;
135
136 /** Short cut */
137 WindowManagerService mWindowManager;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800138 DisplayManager mDisplayManager;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700139
Craig Mautner27084302013-03-25 08:05:25 -0700140 /** Dismiss the keyguard after the next activity is displayed? */
Craig Mautner5314a402013-09-26 12:40:16 -0700141 boolean mDismissKeyguardOnNextActivity = false;
Craig Mautner27084302013-03-25 08:05:25 -0700142
Craig Mautner8d341ef2013-03-26 09:03:27 -0700143 /** Identifier counter for all ActivityStacks */
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -0700144 private int mLastStackId = HOME_STACK_ID;
Craig Mautner8d341ef2013-03-26 09:03:27 -0700145
146 /** Task identifier that activities are currently being started in. Incremented each time a
147 * new task is created. */
148 private int mCurTaskId = 0;
149
Craig Mautner2420ead2013-04-01 17:13:20 -0700150 /** The current user */
151 private int mCurrentUser;
152
Craig Mautnere0a38842013-12-16 16:14:02 -0800153 /** The stack containing the launcher app. Assumed to always be attached to
154 * Display.DEFAULT_DISPLAY. */
Craig Mautner2219a1b2013-03-25 09:44:30 -0700155 private ActivityStack mHomeStack;
Craig Mautner20e72272013-04-01 13:45:53 -0700156
Craig Mautnere0a38842013-12-16 16:14:02 -0800157 /** The stack currently receiving input or launching the next activity. */
Craig Mautner29219d92013-04-16 20:19:12 -0700158 private ActivityStack mFocusedStack;
Craig Mautner8d341ef2013-03-26 09:03:27 -0700159
Craig Mautner4a1cb222013-12-04 16:14:06 -0800160 /** If this is the same as mFocusedStack then the activity on the top of the focused stack has
161 * been resumed. If stacks are changing position this will hold the old stack until the new
Craig Mautnere0a38842013-12-16 16:14:02 -0800162 * stack becomes resumed after which it will be set to mFocusedStack. */
Craig Mautner4a1cb222013-12-04 16:14:06 -0800163 private ActivityStack mLastFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700164
165 /** List of activities that are waiting for a new activity to become visible before completing
166 * whatever operation they are supposed to do. */
167 final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<ActivityRecord>();
168
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700169 /** List of processes waiting to find out about the next visible activity. */
170 final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible =
171 new ArrayList<IActivityManager.WaitResult>();
172
173 /** List of processes waiting to find out about the next launched activity. */
174 final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched =
175 new ArrayList<IActivityManager.WaitResult>();
176
Craig Mautnerde4ef022013-04-07 19:01:33 -0700177 /** List of activities that are ready to be stopped, but waiting for the next activity to
178 * settle down before doing so. */
179 final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<ActivityRecord>();
180
Craig Mautnerf3333272013-04-22 10:55:53 -0700181 /** List of activities that are ready to be finished, but waiting for the previous activity to
182 * settle down before doing so. It contains ActivityRecord objects. */
183 final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<ActivityRecord>();
184
Craig Mautner0eea92c2013-05-16 13:35:39 -0700185 /** List of activities that are in the process of going to sleep. */
186 final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<ActivityRecord>();
187
Craig Mautnerf3333272013-04-22 10:55:53 -0700188 /** List of ActivityRecord objects that have been finished and must still report back to a
189 * pending thumbnail receiver. */
190 final ArrayList<ActivityRecord> mCancelledThumbnails = new ArrayList<ActivityRecord>();
191
192 /** Used on user changes */
193 final ArrayList<UserStartedState> mStartingUsers = new ArrayList<UserStartedState>();
194
Craig Mautnerde4ef022013-04-07 19:01:33 -0700195 /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity
196 * is being brought in front of us. */
197 boolean mUserLeaving = false;
198
Craig Mautner0eea92c2013-05-16 13:35:39 -0700199 /** Set when we have taken too long waiting to go to sleep. */
200 boolean mSleepTimeout = false;
201
202 /**
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700203 * We don't want to allow the device to go to sleep while in the process
204 * of launching an activity. This is primarily to allow alarm intent
205 * receivers to launch an activity and get that to run before the device
206 * goes back to sleep.
207 */
208 final PowerManager.WakeLock mLaunchingActivity;
209
210 /**
Craig Mautner0eea92c2013-05-16 13:35:39 -0700211 * Set when the system is going to sleep, until we have
212 * successfully paused the current activity and released our wake lock.
213 * At that point the system is allowed to actually sleep.
214 */
215 final PowerManager.WakeLock mGoingToSleep;
216
Craig Mautner4f1df4f2013-10-15 15:44:14 -0700217 /** Stack id of the front stack when user switched, indexed by userId. */
218 SparseIntArray mUserStackInFront = new SparseIntArray(2);
Craig Mautner93529a42013-10-04 15:03:13 -0700219
Craig Mautner4504de52013-12-20 09:06:56 -0800220 // TODO: Add listener for removal of references.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800221 /** Mapping from (ActivityStack/TaskStack).mStackId to their current state */
Craig Mautner4504de52013-12-20 09:06:56 -0800222 SparseArray<WeakReference<ActivityContainer>> mActivityContainers =
223 new SparseArray<WeakReference<ActivityContainer>>();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800224
225 /** Mapping from displayId to display current state */
Craig Mautner4504de52013-12-20 09:06:56 -0800226 private SparseArray<ActivityDisplay> mActivityDisplays = new SparseArray<ActivityDisplay>();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800227
228 public ActivityStackSupervisor(ActivityManagerService service) {
Craig Mautner27084302013-03-25 08:05:25 -0700229 mService = service;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800230 PowerManager pm = (PowerManager)mService.mContext.getSystemService(Context.POWER_SERVICE);
Craig Mautner0eea92c2013-05-16 13:35:39 -0700231 mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
Craig Mautner4a1cb222013-12-04 16:14:06 -0800232 mHandler = new ActivityStackSupervisorHandler(mService.mHandler.getLooper());
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700233 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
234 throw new IllegalStateException("Calling must be system uid");
235 }
236 mLaunchingActivity =
237 pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
238 mLaunchingActivity.setReferenceCounted(false);
Craig Mautner2219a1b2013-03-25 09:44:30 -0700239 }
240
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700241 void setWindowManager(WindowManagerService wm) {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800242 synchronized (mService) {
243 mWindowManager = wm;
244
245 mDisplayManager =
246 (DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE);
247 mDisplayManager.registerDisplayListener(this, null);
248
249 Display[] displays = mDisplayManager.getDisplays();
250 for (int displayNdx = displays.length - 1; displayNdx >= 0; --displayNdx) {
251 final int displayId = displays[displayNdx].getDisplayId();
Craig Mautnere0a38842013-12-16 16:14:02 -0800252 ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
253 mActivityDisplays.put(displayId, activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -0800254 }
255
256 createStackOnDisplay(null, HOME_STACK_ID, Display.DEFAULT_DISPLAY);
257 mHomeStack = mFocusedStack = mLastFocusedStack = getStack(HOME_STACK_ID);
258 }
Craig Mautner27084302013-03-25 08:05:25 -0700259 }
260
261 void dismissKeyguard() {
Craig Mautner5314a402013-09-26 12:40:16 -0700262 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen("");
Craig Mautner27084302013-03-25 08:05:25 -0700263 if (mDismissKeyguardOnNextActivity) {
264 mDismissKeyguardOnNextActivity = false;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700265 mWindowManager.dismissKeyguard();
Craig Mautner27084302013-03-25 08:05:25 -0700266 }
267 }
268
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700269 ActivityStack getFocusedStack() {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800270 return mFocusedStack;
Craig Mautner20e72272013-04-01 13:45:53 -0700271 }
272
Craig Mautnerde4ef022013-04-07 19:01:33 -0700273 ActivityStack getLastStack() {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800274 return mLastFocusedStack;
Craig Mautner2219a1b2013-03-25 09:44:30 -0700275 }
276
Craig Mautner4a1cb222013-12-04 16:14:06 -0800277 // TODO: Split into two methods isFrontStack for any visible stack and isFrontmostStack for the
278 // top of all visible stacks.
Craig Mautnerde4ef022013-04-07 19:01:33 -0700279 boolean isFrontStack(ActivityStack stack) {
Craig Mautnerdf88d732014-01-27 09:21:32 -0800280 final ActivityRecord parent = stack.mActivityContainer.mParentActivity;
281 if (parent != null) {
282 stack = parent.task.stack;
283 }
Craig Mautnere0a38842013-12-16 16:14:02 -0800284 ArrayList<ActivityStack> stacks = stack.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800285 if (stacks != null && !stacks.isEmpty()) {
286 return stack == stacks.get(stacks.size() - 1);
287 }
288 return false;
Craig Mautner20e72272013-04-01 13:45:53 -0700289 }
290
Craig Mautnerde4ef022013-04-07 19:01:33 -0700291 void moveHomeStack(boolean toFront) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800292 ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800293 int topNdx = stacks.size() - 1;
294 if (topNdx <= 0) {
295 return;
296 }
297 ActivityStack topStack = stacks.get(topNdx);
298 final boolean homeInFront = topStack == mHomeStack;
299 if (homeInFront != toFront) {
300 mLastFocusedStack = topStack;
301 stacks.remove(mHomeStack);
302 stacks.add(toFront ? topNdx : 0, mHomeStack);
303 mFocusedStack = stacks.get(topNdx);
304 if (DEBUG_STACK) Slog.d(TAG, "moveHomeTask: topStack old=" + topStack + " new="
305 + mFocusedStack);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700306 }
307 }
308
Craig Mautner8e569572013-10-11 17:36:59 -0700309 void moveHomeToTop() {
Craig Mautner69ada552013-04-18 13:51:51 -0700310 moveHomeStack(true);
Craig Mautner8e569572013-10-11 17:36:59 -0700311 mHomeStack.moveHomeTaskToTop();
312 }
313
314 boolean resumeHomeActivity(ActivityRecord prev) {
315 moveHomeToTop();
Craig Mautner69ada552013-04-18 13:51:51 -0700316 if (prev != null) {
Craig Mautnerae7ecab2013-09-18 11:48:14 -0700317 prev.task.mOnTopOfHome = false;
Craig Mautner69ada552013-04-18 13:51:51 -0700318 }
Craig Mautnera8a90e02013-06-28 15:24:50 -0700319 ActivityRecord r = mHomeStack.topRunningActivityLocked(null);
Craig Mautner760b2312013-10-11 11:57:07 -0700320 if (r != null && r.isHomeActivity()) {
Craig Mautnera8a90e02013-06-28 15:24:50 -0700321 mService.setFocusedActivityLocked(r);
Craig Mautner05d29032013-05-03 13:40:13 -0700322 return resumeTopActivitiesLocked(mHomeStack, prev, null);
Craig Mautner69ada552013-04-18 13:51:51 -0700323 }
324 return mService.startHomeActivityLocked(mCurrentUser);
325 }
326
Craig Mautner27084302013-03-25 08:05:25 -0700327 void setDismissKeyguard(boolean dismiss) {
Craig Mautner5314a402013-09-26 12:40:16 -0700328 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen(" dismiss=" + dismiss);
Craig Mautner27084302013-03-25 08:05:25 -0700329 mDismissKeyguardOnNextActivity = dismiss;
330 }
331
Craig Mautner8d341ef2013-03-26 09:03:27 -0700332 TaskRecord anyTaskForIdLocked(int id) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800333 int numDisplays = mActivityDisplays.size();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800334 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800335 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800336 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
337 ActivityStack stack = stacks.get(stackNdx);
338 TaskRecord task = stack.taskForIdLocked(id);
339 if (task != null) {
340 return task;
341 }
Craig Mautner8d341ef2013-03-26 09:03:27 -0700342 }
343 }
344 return null;
345 }
346
Craig Mautner6170f732013-04-02 13:05:23 -0700347 ActivityRecord isInAnyStackLocked(IBinder token) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800348 int numDisplays = mActivityDisplays.size();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800349 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800350 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800351 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
352 final ActivityRecord r = stacks.get(stackNdx).isInStackLocked(token);
353 if (r != null) {
354 return r;
355 }
Craig Mautner6170f732013-04-02 13:05:23 -0700356 }
357 }
358 return null;
359 }
360
Craig Mautner8d341ef2013-03-26 09:03:27 -0700361 int getNextTaskId() {
362 do {
363 mCurTaskId++;
364 if (mCurTaskId <= 0) {
365 mCurTaskId = 1;
366 }
367 } while (anyTaskForIdLocked(mCurTaskId) != null);
368 return mCurTaskId;
369 }
370
Craig Mautnerde4ef022013-04-07 19:01:33 -0700371 ActivityRecord resumedAppLocked() {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700372 ActivityStack stack = getFocusedStack();
373 if (stack == null) {
374 return null;
375 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700376 ActivityRecord resumedActivity = stack.mResumedActivity;
377 if (resumedActivity == null || resumedActivity.app == null) {
378 resumedActivity = stack.mPausingActivity;
379 if (resumedActivity == null || resumedActivity.app == null) {
380 resumedActivity = stack.topRunningActivityLocked(null);
381 }
382 }
383 return resumedActivity;
384 }
385
Mike Lockwooded8902d2013-11-15 11:01:47 -0800386 boolean attachApplicationLocked(ProcessRecord app) throws Exception {
Craig Mautner20e72272013-04-01 13:45:53 -0700387 final String processName = app.processName;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800388 boolean didSomething = false;
Craig Mautnere0a38842013-12-16 16:14:02 -0800389 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
390 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800391 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
392 final ActivityStack stack = stacks.get(stackNdx);
393 if (!isFrontStack(stack)) {
394 continue;
395 }
396 ActivityRecord hr = stack.topRunningActivityLocked(null);
397 if (hr != null) {
398 if (hr.app == null && app.uid == hr.info.applicationInfo.uid
399 && processName.equals(hr.processName)) {
400 try {
Craig Mautner74266842013-12-19 13:02:30 -0800401 if (realStartActivityLocked(hr, app, true, true, null)) {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800402 didSomething = true;
403 }
404 } catch (Exception e) {
405 Slog.w(TAG, "Exception in new application when starting activity "
406 + hr.intent.getComponent().flattenToShortString(), e);
407 throw e;
Craig Mautner20e72272013-04-01 13:45:53 -0700408 }
Craig Mautner20e72272013-04-01 13:45:53 -0700409 }
Craig Mautner20e72272013-04-01 13:45:53 -0700410 }
411 }
412 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -0700413 if (!didSomething) {
414 ensureActivitiesVisibleLocked(null, 0);
415 }
Craig Mautner20e72272013-04-01 13:45:53 -0700416 return didSomething;
417 }
418
419 boolean allResumedActivitiesIdle() {
Craig Mautnere0a38842013-12-16 16:14:02 -0800420 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
421 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800422 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
423 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautner34b73df2014-01-12 21:11:08 -0800424 if (!isFrontStack(stack) || stack.numActivities() == 0) {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800425 continue;
426 }
427 final ActivityRecord resumedActivity = stack.mResumedActivity;
428 if (resumedActivity == null || !resumedActivity.idle) {
Craig Mautner34b73df2014-01-12 21:11:08 -0800429 if (DEBUG_STATES) Slog.d(TAG, "allResumedActivitiesIdle: stack="
430 + stack.mStackId + " " + resumedActivity + " not idle");
Craig Mautner4a1cb222013-12-04 16:14:06 -0800431 return false;
432 }
Craig Mautner20e72272013-04-01 13:45:53 -0700433 }
434 }
435 return true;
436 }
437
Craig Mautnerde4ef022013-04-07 19:01:33 -0700438 boolean allResumedActivitiesComplete() {
Craig Mautnere0a38842013-12-16 16:14:02 -0800439 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
440 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800441 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
442 final ActivityStack stack = stacks.get(stackNdx);
443 if (isFrontStack(stack)) {
444 final ActivityRecord r = stack.mResumedActivity;
445 if (r != null && r.state != ActivityState.RESUMED) {
446 return false;
447 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700448 }
449 }
450 }
451 // TODO: Not sure if this should check if all Paused are complete too.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800452 if (DEBUG_STACK) Slog.d(TAG,
453 "allResumedActivitiesComplete: mLastFocusedStack changing from=" +
454 mLastFocusedStack + " to=" + mFocusedStack);
455 mLastFocusedStack = mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700456 return true;
457 }
458
459 boolean allResumedActivitiesVisible() {
Craig Mautnere0a38842013-12-16 16:14:02 -0800460 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
461 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800462 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
463 final ActivityStack stack = stacks.get(stackNdx);
464 final ActivityRecord r = stack.mResumedActivity;
465 if (r != null && (!r.nowVisible || r.waitingVisible)) {
466 return false;
467 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700468 }
469 }
470 return true;
471 }
472
Craig Mautner2acc3892013-09-23 10:28:14 -0700473 /**
474 * Pause all activities in either all of the stacks or just the back stacks.
475 * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving().
Craig Mautner2acc3892013-09-23 10:28:14 -0700476 * @return true if any activity was paused as a result of this call.
477 */
Craig Mautner5314a402013-09-26 12:40:16 -0700478 boolean pauseBackStacks(boolean userLeaving) {
Craig Mautnercf910b02013-04-23 11:23:27 -0700479 boolean someActivityPaused = false;
Craig Mautnere0a38842013-12-16 16:14:02 -0800480 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
481 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800482 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
483 final ActivityStack stack = stacks.get(stackNdx);
484 if (!isFrontStack(stack) && stack.mResumedActivity != null) {
485 if (DEBUG_STATES) Slog.d(TAG, "pauseBackStacks: stack=" + stack +
486 " mResumedActivity=" + stack.mResumedActivity);
487 stack.startPausingLocked(userLeaving, false);
488 someActivityPaused = true;
489 }
Craig Mautnercf910b02013-04-23 11:23:27 -0700490 }
491 }
492 return someActivityPaused;
493 }
494
Craig Mautnerde4ef022013-04-07 19:01:33 -0700495 boolean allPausedActivitiesComplete() {
Craig Mautnerac6f8432013-07-17 13:24:59 -0700496 boolean pausing = true;
Craig Mautnere0a38842013-12-16 16:14:02 -0800497 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
498 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800499 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
500 final ActivityStack stack = stacks.get(stackNdx);
501 final ActivityRecord r = stack.mPausingActivity;
502 if (r != null && r.state != ActivityState.PAUSED
503 && r.state != ActivityState.STOPPED
504 && r.state != ActivityState.STOPPING) {
505 if (DEBUG_STATES) {
506 Slog.d(TAG, "allPausedActivitiesComplete: r=" + r + " state=" + r.state);
507 pausing = false;
508 } else {
509 return false;
510 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700511 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700512 }
513 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700514 return pausing;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700515 }
516
Craig Mautnerdf88d732014-01-27 09:21:32 -0800517 void pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping) {
518 // TODO: Put all stacks in supervisor and iterate through them instead.
519 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
520 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
521 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
522 final ActivityStack stack = stacks.get(stackNdx);
523 if (stack.mResumedActivity != null &&
524 stack.mActivityContainer.mParentActivity == parent) {
525 stack.startPausingLocked(userLeaving, uiSleeping);
526 }
527 }
528 }
529 }
530
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700531 void reportActivityVisibleLocked(ActivityRecord r) {
Craig Mautner858d8a62013-04-23 17:08:34 -0700532 for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700533 WaitResult w = mWaitingActivityVisible.get(i);
534 w.timeout = false;
535 if (r != null) {
536 w.who = new ComponentName(r.info.packageName, r.info.name);
537 }
538 w.totalTime = SystemClock.uptimeMillis() - w.thisTime;
539 w.thisTime = w.totalTime;
540 }
541 mService.notifyAll();
542 dismissKeyguard();
543 }
544
545 void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r,
546 long thisTime, long totalTime) {
547 for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
Craig Mautnerc64f73e2013-04-24 16:44:56 -0700548 WaitResult w = mWaitingActivityLaunched.remove(i);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700549 w.timeout = timeout;
550 if (r != null) {
551 w.who = new ComponentName(r.info.packageName, r.info.name);
552 }
553 w.thisTime = thisTime;
554 w.totalTime = totalTime;
555 }
556 mService.notifyAll();
557 }
558
Craig Mautner29219d92013-04-16 20:19:12 -0700559 ActivityRecord topRunningActivityLocked() {
Craig Mautner1602ec22013-05-12 10:24:27 -0700560 final ActivityStack focusedStack = getFocusedStack();
561 ActivityRecord r = focusedStack.topRunningActivityLocked(null);
562 if (r != null) {
563 return r;
Craig Mautner29219d92013-04-16 20:19:12 -0700564 }
Craig Mautner1602ec22013-05-12 10:24:27 -0700565
Craig Mautner4a1cb222013-12-04 16:14:06 -0800566 // Return to the home stack.
Craig Mautnere0a38842013-12-16 16:14:02 -0800567 final ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800568 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
569 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautnerac6f8432013-07-17 13:24:59 -0700570 if (stack != focusedStack && isFrontStack(stack)) {
Craig Mautner29219d92013-04-16 20:19:12 -0700571 r = stack.topRunningActivityLocked(null);
572 if (r != null) {
573 return r;
574 }
575 }
576 }
577 return null;
578 }
579
Craig Mautner20e72272013-04-01 13:45:53 -0700580 ActivityRecord getTasksLocked(int maxNum, IThumbnailReceiver receiver,
581 PendingThumbnailsRecord pending, List<RunningTaskInfo> list) {
582 ActivityRecord r = null;
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700583
584 // Gather all of the running tasks for each stack into runningTaskLists.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800585 ArrayList<ArrayList<RunningTaskInfo>> runningTaskLists =
586 new ArrayList<ArrayList<RunningTaskInfo>>();
Craig Mautnere0a38842013-12-16 16:14:02 -0800587 final int numDisplays = mActivityDisplays.size();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800588 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800589 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800590 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
591 final ActivityStack stack = stacks.get(stackNdx);
592 ArrayList<RunningTaskInfo> stackTaskList = new ArrayList<RunningTaskInfo>();
593 runningTaskLists.add(stackTaskList);
594 final ActivityRecord ar = stack.getTasksLocked(receiver, pending, stackTaskList);
595 if (r == null && isFrontStack(stack)) {
596 r = ar;
597 }
Craig Mautner20e72272013-04-01 13:45:53 -0700598 }
599 }
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700600
601 // The lists are already sorted from most recent to oldest. Just pull the most recent off
602 // each list and add it to list. Stop when all lists are empty or maxNum reached.
603 while (maxNum > 0) {
604 long mostRecentActiveTime = Long.MIN_VALUE;
605 ArrayList<RunningTaskInfo> selectedStackList = null;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800606 final int numTaskLists = runningTaskLists.size();
607 for (int stackNdx = 0; stackNdx < numTaskLists; ++stackNdx) {
608 ArrayList<RunningTaskInfo> stackTaskList = runningTaskLists.get(stackNdx);
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700609 if (!stackTaskList.isEmpty()) {
610 final long lastActiveTime = stackTaskList.get(0).lastActiveTime;
611 if (lastActiveTime > mostRecentActiveTime) {
612 mostRecentActiveTime = lastActiveTime;
613 selectedStackList = stackTaskList;
614 }
615 }
616 }
617 if (selectedStackList != null) {
618 list.add(selectedStackList.remove(0));
619 --maxNum;
620 } else {
621 break;
622 }
623 }
624
Craig Mautner20e72272013-04-01 13:45:53 -0700625 return r;
626 }
627
Craig Mautner23ac33b2013-04-01 16:26:35 -0700628 ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
629 String profileFile, ParcelFileDescriptor profileFd, int userId) {
630 // Collect information about the target of the Intent.
631 ActivityInfo aInfo;
632 try {
633 ResolveInfo rInfo =
634 AppGlobals.getPackageManager().resolveIntent(
635 intent, resolvedType,
636 PackageManager.MATCH_DEFAULT_ONLY
637 | ActivityManagerService.STOCK_PM_FLAGS, userId);
638 aInfo = rInfo != null ? rInfo.activityInfo : null;
639 } catch (RemoteException e) {
640 aInfo = null;
641 }
642
643 if (aInfo != null) {
644 // Store the found target back into the intent, because now that
645 // we have it we never want to do this again. For example, if the
646 // user navigates back to this point in the history, we should
647 // always restart the exact same activity.
648 intent.setComponent(new ComponentName(
649 aInfo.applicationInfo.packageName, aInfo.name));
650
651 // Don't debug things in the system process
652 if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) {
653 if (!aInfo.processName.equals("system")) {
654 mService.setDebugApp(aInfo.processName, true, false);
655 }
656 }
657
658 if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) {
659 if (!aInfo.processName.equals("system")) {
660 mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName);
661 }
662 }
663
664 if (profileFile != null) {
665 if (!aInfo.processName.equals("system")) {
666 mService.setProfileApp(aInfo.applicationInfo, aInfo.processName,
667 profileFile, profileFd,
668 (startFlags&ActivityManager.START_FLAG_AUTO_STOP_PROFILER) != 0);
669 }
670 }
671 }
672 return aInfo;
673 }
674
Craig Mautner2219a1b2013-03-25 09:44:30 -0700675 void startHomeActivity(Intent intent, ActivityInfo aInfo) {
Craig Mautner8e569572013-10-11 17:36:59 -0700676 moveHomeToTop();
Craig Mautner6170f732013-04-02 13:05:23 -0700677 startActivityLocked(null, intent, null, aInfo, null, null, 0, 0, 0, null, 0,
Craig Mautnere0a38842013-12-16 16:14:02 -0800678 null, false, null, null);
Craig Mautner8d341ef2013-03-26 09:03:27 -0700679 }
680
Craig Mautner23ac33b2013-04-01 16:26:35 -0700681 final int startActivityMayWait(IApplicationThread caller, int callingUid,
682 String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
683 String resultWho, int requestCode, int startFlags, String profileFile,
684 ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config,
Craig Mautnere0a38842013-12-16 16:14:02 -0800685 Bundle options, int userId, IActivityContainer iContainer) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700686 // Refuse possible leaked file descriptors
687 if (intent != null && intent.hasFileDescriptors()) {
688 throw new IllegalArgumentException("File descriptors passed in Intent");
689 }
690 boolean componentSpecified = intent.getComponent() != null;
691
692 // Don't modify the client's object!
693 intent = new Intent(intent);
694
695 // Collect information about the target of the Intent.
696 ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
697 profileFile, profileFd, userId);
698
Craig Mautnere0a38842013-12-16 16:14:02 -0800699 ActivityContainer container = (ActivityContainer)iContainer;
Craig Mautner23ac33b2013-04-01 16:26:35 -0700700 synchronized (mService) {
701 int callingPid;
702 if (callingUid >= 0) {
703 callingPid = -1;
704 } else if (caller == null) {
705 callingPid = Binder.getCallingPid();
706 callingUid = Binder.getCallingUid();
707 } else {
708 callingPid = callingUid = -1;
709 }
710
Craig Mautnere0a38842013-12-16 16:14:02 -0800711 final ActivityStack stack;
712 if (container == null || container.mStack.isOnHomeDisplay()) {
713 stack = getFocusedStack();
714 } else {
715 stack = container.mStack;
716 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700717 stack.mConfigWillChange = config != null
Craig Mautner23ac33b2013-04-01 16:26:35 -0700718 && mService.mConfiguration.diff(config) != 0;
719 if (DEBUG_CONFIGURATION) Slog.v(TAG,
Craig Mautnerde4ef022013-04-07 19:01:33 -0700720 "Starting activity when config will change = " + stack.mConfigWillChange);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700721
722 final long origId = Binder.clearCallingIdentity();
723
724 if (aInfo != null &&
725 (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
726 // This may be a heavy-weight process! Check to see if we already
727 // have another, different heavy-weight process running.
728 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
729 if (mService.mHeavyWeightProcess != null &&
730 (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid ||
731 !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700732 int realCallingUid = callingUid;
733 if (caller != null) {
734 ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
735 if (callerApp != null) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700736 realCallingUid = callerApp.info.uid;
737 } else {
738 Slog.w(TAG, "Unable to find app for caller " + caller
Craig Mautner76ea2242013-05-15 11:40:05 -0700739 + " (pid=" + callingPid + ") when starting: "
Craig Mautner23ac33b2013-04-01 16:26:35 -0700740 + intent.toString());
741 ActivityOptions.abort(options);
742 return ActivityManager.START_PERMISSION_DENIED;
743 }
744 }
745
746 IIntentSender target = mService.getIntentSenderLocked(
747 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
748 realCallingUid, userId, null, null, 0, new Intent[] { intent },
749 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
750 | PendingIntent.FLAG_ONE_SHOT, null);
751
752 Intent newIntent = new Intent();
753 if (requestCode >= 0) {
754 // Caller is requesting a result.
755 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
756 }
757 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
758 new IntentSender(target));
759 if (mService.mHeavyWeightProcess.activities.size() > 0) {
760 ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0);
761 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
762 hist.packageName);
763 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
764 hist.task.taskId);
765 }
766 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
767 aInfo.packageName);
768 newIntent.setFlags(intent.getFlags());
769 newIntent.setClassName("android",
770 HeavyWeightSwitcherActivity.class.getName());
771 intent = newIntent;
772 resolvedType = null;
773 caller = null;
774 callingUid = Binder.getCallingUid();
775 callingPid = Binder.getCallingPid();
776 componentSpecified = true;
777 try {
778 ResolveInfo rInfo =
779 AppGlobals.getPackageManager().resolveIntent(
780 intent, null,
781 PackageManager.MATCH_DEFAULT_ONLY
782 | ActivityManagerService.STOCK_PM_FLAGS, userId);
783 aInfo = rInfo != null ? rInfo.activityInfo : null;
784 aInfo = mService.getActivityInfoForUser(aInfo, userId);
785 } catch (RemoteException e) {
786 aInfo = null;
787 }
788 }
789 }
790 }
791
Craig Mautnere0a38842013-12-16 16:14:02 -0800792 int res = startActivityLocked(caller, intent, resolvedType, aInfo, resultTo, resultWho,
793 requestCode, callingPid, callingUid, callingPackage, startFlags, options,
794 componentSpecified, null, container);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700795
Craig Mautnerde4ef022013-04-07 19:01:33 -0700796 if (stack.mConfigWillChange) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700797 // If the caller also wants to switch to a new configuration,
798 // do so now. This allows a clean switch, as we are waiting
799 // for the current activity to pause (so we will not destroy
800 // it), and have not yet started the next activity.
801 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
802 "updateConfiguration()");
Craig Mautnerde4ef022013-04-07 19:01:33 -0700803 stack.mConfigWillChange = false;
Craig Mautner23ac33b2013-04-01 16:26:35 -0700804 if (DEBUG_CONFIGURATION) Slog.v(TAG,
805 "Updating to new configuration after starting activity.");
806 mService.updateConfigurationLocked(config, null, false, false);
807 }
808
809 Binder.restoreCallingIdentity(origId);
810
811 if (outResult != null) {
812 outResult.result = res;
813 if (res == ActivityManager.START_SUCCESS) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700814 mWaitingActivityLaunched.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700815 do {
816 try {
817 mService.wait();
818 } catch (InterruptedException e) {
819 }
820 } while (!outResult.timeout && outResult.who == null);
821 } else if (res == ActivityManager.START_TASK_TO_FRONT) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700822 ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700823 if (r.nowVisible) {
824 outResult.timeout = false;
825 outResult.who = new ComponentName(r.info.packageName, r.info.name);
826 outResult.totalTime = 0;
827 outResult.thisTime = 0;
828 } else {
829 outResult.thisTime = SystemClock.uptimeMillis();
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700830 mWaitingActivityVisible.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700831 do {
832 try {
833 mService.wait();
834 } catch (InterruptedException e) {
835 }
836 } while (!outResult.timeout && outResult.who == null);
837 }
838 }
839 }
840
841 return res;
842 }
843 }
844
845 final int startActivities(IApplicationThread caller, int callingUid, String callingPackage,
846 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
847 Bundle options, int userId) {
848 if (intents == null) {
849 throw new NullPointerException("intents is null");
850 }
851 if (resolvedTypes == null) {
852 throw new NullPointerException("resolvedTypes is null");
853 }
854 if (intents.length != resolvedTypes.length) {
855 throw new IllegalArgumentException("intents are length different than resolvedTypes");
856 }
857
Craig Mautner23ac33b2013-04-01 16:26:35 -0700858
859 int callingPid;
860 if (callingUid >= 0) {
861 callingPid = -1;
862 } else if (caller == null) {
863 callingPid = Binder.getCallingPid();
864 callingUid = Binder.getCallingUid();
865 } else {
866 callingPid = callingUid = -1;
867 }
868 final long origId = Binder.clearCallingIdentity();
869 try {
870 synchronized (mService) {
Craig Mautner76ea2242013-05-15 11:40:05 -0700871 ActivityRecord[] outActivity = new ActivityRecord[1];
Craig Mautner23ac33b2013-04-01 16:26:35 -0700872 for (int i=0; i<intents.length; i++) {
873 Intent intent = intents[i];
874 if (intent == null) {
875 continue;
876 }
877
878 // Refuse possible leaked file descriptors
879 if (intent != null && intent.hasFileDescriptors()) {
880 throw new IllegalArgumentException("File descriptors passed in Intent");
881 }
882
883 boolean componentSpecified = intent.getComponent() != null;
884
885 // Don't modify the client's object!
886 intent = new Intent(intent);
887
888 // Collect information about the target of the Intent.
889 ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i],
890 0, null, null, userId);
891 // TODO: New, check if this is correct
892 aInfo = mService.getActivityInfoForUser(aInfo, userId);
893
894 if (aInfo != null &&
895 (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE)
896 != 0) {
897 throw new IllegalArgumentException(
898 "FLAG_CANT_SAVE_STATE not supported here");
899 }
900
901 Bundle theseOptions;
902 if (options != null && i == intents.length-1) {
903 theseOptions = options;
904 } else {
905 theseOptions = null;
906 }
Craig Mautner6170f732013-04-02 13:05:23 -0700907 int res = startActivityLocked(caller, intent, resolvedTypes[i],
Craig Mautner23ac33b2013-04-01 16:26:35 -0700908 aInfo, resultTo, null, -1, callingPid, callingUid, callingPackage,
Craig Mautnere0a38842013-12-16 16:14:02 -0800909 0, theseOptions, componentSpecified, outActivity, null);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700910 if (res < 0) {
911 return res;
912 }
913
914 resultTo = outActivity[0] != null ? outActivity[0].appToken : null;
915 }
916 }
917 } finally {
918 Binder.restoreCallingIdentity(origId);
919 }
920
921 return ActivityManager.START_SUCCESS;
922 }
923
Craig Mautner2420ead2013-04-01 17:13:20 -0700924 final boolean realStartActivityLocked(ActivityRecord r,
Adam Powellcfbe9be2013-11-06 14:58:58 -0800925 ProcessRecord app, boolean andResume, boolean checkConfig, Bundle resumeArgs)
Craig Mautner2420ead2013-04-01 17:13:20 -0700926 throws RemoteException {
927
928 r.startFreezingScreenLocked(app, 0);
Craig Mautnera7f2bd42013-10-15 16:13:50 -0700929 if (false) Slog.d(TAG, "realStartActivity: setting app visibility true");
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700930 mWindowManager.setAppVisibility(r.appToken, true);
Craig Mautner2420ead2013-04-01 17:13:20 -0700931
932 // schedule launch ticks to collect information about slow apps.
933 r.startLaunchTickingLocked();
934
935 // Have the window manager re-evaluate the orientation of
936 // the screen based on the new activity order. Note that
937 // as a result of this, it can call back into the activity
938 // manager with a new orientation. We don't care about that,
939 // because the activity is not currently running so we are
940 // just restarting it anyway.
941 if (checkConfig) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700942 Configuration config = mWindowManager.updateOrientationFromAppTokens(
Craig Mautner2420ead2013-04-01 17:13:20 -0700943 mService.mConfiguration,
944 r.mayFreezeScreenLocked(app) ? r.appToken : null);
945 mService.updateConfigurationLocked(config, r, false, false);
946 }
947
948 r.app = app;
949 app.waitingToKill = null;
950 r.launchCount++;
951 r.lastLaunchTime = SystemClock.uptimeMillis();
952
953 if (localLOGV) Slog.v(TAG, "Launching: " + r);
954
955 int idx = app.activities.indexOf(r);
956 if (idx < 0) {
957 app.activities.add(r);
958 }
Dianne Hackborndb926082013-10-31 16:32:44 -0700959 mService.updateLruProcessLocked(app, true, null);
960 mService.updateOomAdjLocked();
Craig Mautner2420ead2013-04-01 17:13:20 -0700961
962 final ActivityStack stack = r.task.stack;
963 try {
964 if (app.thread == null) {
965 throw new RemoteException();
966 }
967 List<ResultInfo> results = null;
968 List<Intent> newIntents = null;
969 if (andResume) {
970 results = r.results;
971 newIntents = r.newIntents;
972 }
973 if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r
974 + " icicle=" + r.icicle
975 + " with results=" + results + " newIntents=" + newIntents
976 + " andResume=" + andResume);
977 if (andResume) {
978 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
979 r.userId, System.identityHashCode(r),
980 r.task.taskId, r.shortComponentName);
981 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700982 if (r.isHomeActivity() && r.isNotResolverActivity()) {
Craig Mautner4ef26932013-09-18 15:15:52 -0700983 // Home process is the root process of the task.
984 mService.mHomeProcess = r.task.mActivities.get(0).app;
Craig Mautner2420ead2013-04-01 17:13:20 -0700985 }
986 mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
987 r.sleeping = false;
988 r.forceNewConfig = false;
989 mService.showAskCompatModeDialogLocked(r);
990 r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
991 String profileFile = null;
992 ParcelFileDescriptor profileFd = null;
993 boolean profileAutoStop = false;
994 if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
995 if (mService.mProfileProc == null || mService.mProfileProc == app) {
996 mService.mProfileProc = app;
997 profileFile = mService.mProfileFile;
998 profileFd = mService.mProfileFd;
999 profileAutoStop = mService.mAutoStopProfiler;
1000 }
1001 }
1002 app.hasShownUi = true;
1003 app.pendingUiClean = true;
1004 if (profileFd != null) {
1005 try {
1006 profileFd = profileFd.dup();
1007 } catch (IOException e) {
1008 if (profileFd != null) {
1009 try {
1010 profileFd.close();
1011 } catch (IOException o) {
1012 }
1013 profileFd = null;
1014 }
1015 }
1016 }
Adam Powellcfbe9be2013-11-06 14:58:58 -08001017
Dianne Hackborna413dc02013-07-12 12:02:55 -07001018 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
Craig Mautner2420ead2013-04-01 17:13:20 -07001019 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
1020 System.identityHashCode(r), r.info,
Dianne Hackborna413dc02013-07-12 12:02:55 -07001021 new Configuration(mService.mConfiguration), r.compat,
1022 app.repProcState, r.icicle, results, newIntents, !andResume,
Craig Mautner2420ead2013-04-01 17:13:20 -07001023 mService.isNextTransitionForward(), profileFile, profileFd,
Adam Powellcfbe9be2013-11-06 14:58:58 -08001024 profileAutoStop, resumeArgs);
Craig Mautner2420ead2013-04-01 17:13:20 -07001025
1026 if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
1027 // This may be a heavy-weight process! Note that the package
1028 // manager will ensure that only activity can run in the main
1029 // process of the .apk, which is the only thing that will be
1030 // considered heavy-weight.
1031 if (app.processName.equals(app.info.packageName)) {
1032 if (mService.mHeavyWeightProcess != null
1033 && mService.mHeavyWeightProcess != app) {
1034 Slog.w(TAG, "Starting new heavy weight process " + app
1035 + " when already running "
1036 + mService.mHeavyWeightProcess);
1037 }
1038 mService.mHeavyWeightProcess = app;
1039 Message msg = mService.mHandler.obtainMessage(
1040 ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
1041 msg.obj = r;
1042 mService.mHandler.sendMessage(msg);
1043 }
1044 }
1045
1046 } catch (RemoteException e) {
1047 if (r.launchFailed) {
1048 // This is the second time we failed -- finish activity
1049 // and give up.
1050 Slog.e(TAG, "Second failure launching "
1051 + r.intent.getComponent().flattenToShortString()
1052 + ", giving up", e);
1053 mService.appDiedLocked(app, app.pid, app.thread);
1054 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
1055 "2nd-crash", false);
1056 return false;
1057 }
1058
1059 // This is the first time we failed -- restart process and
1060 // retry.
1061 app.activities.remove(r);
1062 throw e;
1063 }
1064
1065 r.launchFailed = false;
1066 if (stack.updateLRUListLocked(r)) {
1067 Slog.w(TAG, "Activity " + r
1068 + " being launched, but already in LRU list");
1069 }
1070
1071 if (andResume) {
1072 // As part of the process of launching, ActivityThread also performs
1073 // a resume.
1074 stack.minimalResumeActivityLocked(r);
1075 } else {
1076 // This activity is not starting in the resumed state... which
1077 // should look like we asked it to pause+stop (but remain visible),
1078 // and it has done so and reported back the current icicle and
1079 // other state.
1080 if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r
1081 + " (starting in stopped state)");
1082 r.state = ActivityState.STOPPED;
1083 r.stopped = true;
1084 }
1085
1086 // Launch the new version setup screen if needed. We do this -after-
1087 // launching the initial activity (that is, home), so that it can have
1088 // a chance to initialize itself while in the background, making the
1089 // switch back to it faster and look better.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001090 if (isFrontStack(stack)) {
Craig Mautner2420ead2013-04-01 17:13:20 -07001091 mService.startSetupActivityLocked();
1092 }
1093
1094 return true;
1095 }
1096
Craig Mautnere79d42682013-04-01 19:01:53 -07001097 void startSpecificActivityLocked(ActivityRecord r,
Adam Powellcfbe9be2013-11-06 14:58:58 -08001098 boolean andResume, boolean checkConfig, Bundle resumeArgs) {
Craig Mautnere79d42682013-04-01 19:01:53 -07001099 // Is this activity's application already running?
1100 ProcessRecord app = mService.getProcessRecordLocked(r.processName,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001101 r.info.applicationInfo.uid, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001102
1103 r.task.stack.setLaunchTime(r);
1104
1105 if (app != null && app.thread != null) {
1106 try {
Dianne Hackborn237cefb2013-10-22 18:45:27 -07001107 if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
1108 || !"android".equals(r.info.packageName)) {
1109 // Don't add this if it is a platform component that is marked
1110 // to run in multiple processes, because this is actually
1111 // part of the framework so doesn't make sense to track as a
1112 // separate apk in the process.
1113 app.addPackage(r.info.packageName, mService.mProcessStats);
1114 }
Adam Powellcfbe9be2013-11-06 14:58:58 -08001115 realStartActivityLocked(r, app, andResume, checkConfig, resumeArgs);
Craig Mautnere79d42682013-04-01 19:01:53 -07001116 return;
1117 } catch (RemoteException e) {
1118 Slog.w(TAG, "Exception when starting activity "
1119 + r.intent.getComponent().flattenToShortString(), e);
1120 }
1121
1122 // If a dead object exception was thrown -- fall through to
1123 // restart the application.
1124 }
1125
1126 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001127 "activity", r.intent.getComponent(), false, false, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001128 }
1129
Craig Mautner6170f732013-04-02 13:05:23 -07001130 final int startActivityLocked(IApplicationThread caller,
1131 Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
1132 String resultWho, int requestCode,
1133 int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
Craig Mautnere0a38842013-12-16 16:14:02 -08001134 boolean componentSpecified, ActivityRecord[] outActivity, ActivityContainer container) {
Craig Mautner6170f732013-04-02 13:05:23 -07001135 int err = ActivityManager.START_SUCCESS;
1136
1137 ProcessRecord callerApp = null;
1138 if (caller != null) {
1139 callerApp = mService.getRecordForAppLocked(caller);
1140 if (callerApp != null) {
1141 callingPid = callerApp.pid;
1142 callingUid = callerApp.info.uid;
1143 } else {
1144 Slog.w(TAG, "Unable to find app for caller " + caller
1145 + " (pid=" + callingPid + ") when starting: "
1146 + intent.toString());
1147 err = ActivityManager.START_PERMISSION_DENIED;
1148 }
1149 }
1150
1151 if (err == ActivityManager.START_SUCCESS) {
1152 final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
1153 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
Craig Mautner9ef471f2014-02-07 13:11:47 -08001154 + "} from pid " + (callerApp != null ? callerApp.pid : callingPid)
1155 + " on display " + (container == null ? (mFocusedStack == null ?
1156 Display.DEFAULT_DISPLAY : mFocusedStack.mDisplayId) :
1157 (container.mActivityDisplay == null ? Display.DEFAULT_DISPLAY :
1158 container.mActivityDisplay.mDisplayId)));
Craig Mautner6170f732013-04-02 13:05:23 -07001159 }
1160
1161 ActivityRecord sourceRecord = null;
1162 ActivityRecord resultRecord = null;
1163 if (resultTo != null) {
1164 sourceRecord = isInAnyStackLocked(resultTo);
1165 if (DEBUG_RESULTS) Slog.v(
1166 TAG, "Will send result to " + resultTo + " " + sourceRecord);
1167 if (sourceRecord != null) {
1168 if (requestCode >= 0 && !sourceRecord.finishing) {
1169 resultRecord = sourceRecord;
1170 }
1171 }
1172 }
1173 ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
1174
1175 int launchFlags = intent.getFlags();
1176
1177 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
1178 && sourceRecord != null) {
1179 // Transfer the result target from the source activity to the new
1180 // one being started, including any failures.
1181 if (requestCode >= 0) {
1182 ActivityOptions.abort(options);
1183 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
1184 }
1185 resultRecord = sourceRecord.resultTo;
1186 resultWho = sourceRecord.resultWho;
1187 requestCode = sourceRecord.requestCode;
1188 sourceRecord.resultTo = null;
1189 if (resultRecord != null) {
1190 resultRecord.removeResultsLocked(
1191 sourceRecord, resultWho, requestCode);
1192 }
1193 }
1194
1195 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
1196 // We couldn't find a class that can handle the given Intent.
1197 // That's the end of that!
1198 err = ActivityManager.START_INTENT_NOT_RESOLVED;
1199 }
1200
1201 if (err == ActivityManager.START_SUCCESS && aInfo == null) {
1202 // We couldn't find the specific class specified in the Intent.
1203 // Also the end of the line.
1204 err = ActivityManager.START_CLASS_NOT_FOUND;
1205 }
1206
1207 if (err != ActivityManager.START_SUCCESS) {
1208 if (resultRecord != null) {
1209 resultStack.sendActivityResultLocked(-1,
1210 resultRecord, resultWho, requestCode,
1211 Activity.RESULT_CANCELED, null);
1212 }
1213 setDismissKeyguard(false);
1214 ActivityOptions.abort(options);
1215 return err;
1216 }
1217
1218 final int startAnyPerm = mService.checkPermission(
1219 START_ANY_ACTIVITY, callingPid, callingUid);
1220 final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
1221 callingUid, aInfo.applicationInfo.uid, aInfo.exported);
1222 if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
1223 if (resultRecord != null) {
1224 resultStack.sendActivityResultLocked(-1,
1225 resultRecord, resultWho, requestCode,
1226 Activity.RESULT_CANCELED, null);
1227 }
1228 setDismissKeyguard(false);
1229 String msg;
1230 if (!aInfo.exported) {
1231 msg = "Permission Denial: starting " + intent.toString()
1232 + " from " + callerApp + " (pid=" + callingPid
1233 + ", uid=" + callingUid + ")"
1234 + " not exported from uid " + aInfo.applicationInfo.uid;
1235 } else {
1236 msg = "Permission Denial: starting " + intent.toString()
1237 + " from " + callerApp + " (pid=" + callingPid
1238 + ", uid=" + callingUid + ")"
1239 + " requires " + aInfo.permission;
1240 }
1241 Slog.w(TAG, msg);
1242 throw new SecurityException(msg);
1243 }
1244
Ben Gruverdd72c9e2013-08-06 12:34:17 -07001245 boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
Ben Gruverb6223792013-07-29 16:35:40 -07001246 callingPid, resolvedType, aInfo.applicationInfo);
Ben Gruver5e207332013-04-03 17:41:37 -07001247
Craig Mautner6170f732013-04-02 13:05:23 -07001248 if (mService.mController != null) {
Craig Mautner6170f732013-04-02 13:05:23 -07001249 try {
1250 // The Intent we give to the watcher has the extra data
1251 // stripped off, since it can contain private information.
1252 Intent watchIntent = intent.cloneFilter();
Ben Gruver5e207332013-04-03 17:41:37 -07001253 abort |= !mService.mController.activityStarting(watchIntent,
Craig Mautner6170f732013-04-02 13:05:23 -07001254 aInfo.applicationInfo.packageName);
1255 } catch (RemoteException e) {
1256 mService.mController = null;
1257 }
Ben Gruver5e207332013-04-03 17:41:37 -07001258 }
Craig Mautner6170f732013-04-02 13:05:23 -07001259
Ben Gruver5e207332013-04-03 17:41:37 -07001260 if (abort) {
1261 if (resultRecord != null) {
1262 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
Craig Mautner6170f732013-04-02 13:05:23 -07001263 Activity.RESULT_CANCELED, null);
Craig Mautner6170f732013-04-02 13:05:23 -07001264 }
Ben Gruver5e207332013-04-03 17:41:37 -07001265 // We pretend to the caller that it was really started, but
1266 // they will just get a cancel result.
1267 setDismissKeyguard(false);
1268 ActivityOptions.abort(options);
1269 return ActivityManager.START_SUCCESS;
Craig Mautner6170f732013-04-02 13:05:23 -07001270 }
1271
1272 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
Craig Mautnere0a38842013-12-16 16:14:02 -08001273 intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
1274 requestCode, componentSpecified, this, container);
Craig Mautner6170f732013-04-02 13:05:23 -07001275 if (outActivity != null) {
1276 outActivity[0] = r;
1277 }
1278
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001279 final ActivityStack stack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001280 if (stack.mResumedActivity == null
1281 || stack.mResumedActivity.info.applicationInfo.uid != callingUid) {
Craig Mautner6170f732013-04-02 13:05:23 -07001282 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
1283 PendingActivityLaunch pal =
Craig Mautnerde4ef022013-04-07 19:01:33 -07001284 new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
Craig Mautner6170f732013-04-02 13:05:23 -07001285 mService.mPendingActivityLaunches.add(pal);
1286 setDismissKeyguard(false);
1287 ActivityOptions.abort(options);
1288 return ActivityManager.START_SWITCHES_CANCELED;
1289 }
1290 }
1291
1292 if (mService.mDidAppSwitch) {
1293 // This is the second allowed switch since we stopped switches,
1294 // so now just generally allow switches. Use case: user presses
1295 // home (switches disabled, switch to home, mDidAppSwitch now true);
1296 // user taps a home icon (coming from home so allowed, we hit here
1297 // and now allow anyone to switch again).
1298 mService.mAppSwitchesAllowedTime = 0;
1299 } else {
1300 mService.mDidAppSwitch = true;
1301 }
1302
1303 mService.doPendingActivityLaunchesLocked(false);
1304
Craig Mautner8849a5e2013-04-02 16:41:03 -07001305 err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
Craig Mautner10385a12013-09-22 21:08:32 -07001306
1307 if (allPausedActivitiesComplete()) {
1308 // If someone asked to have the keyguard dismissed on the next
Craig Mautner6170f732013-04-02 13:05:23 -07001309 // activity start, but we are not actually doing an activity
1310 // switch... just dismiss the keyguard now, because we
1311 // probably want to see whatever is behind it.
1312 dismissKeyguard();
1313 }
1314 return err;
1315 }
1316
Craig Mautnerac6f8432013-07-17 13:24:59 -07001317 ActivityStack adjustStackFocus(ActivityRecord r) {
Craig Mautner1d001b62013-06-18 16:52:43 -07001318 final TaskRecord task = r.task;
1319 if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001320 if (task != null) {
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07001321 final ActivityStack taskStack = task.stack;
Craig Mautnere0a38842013-12-16 16:14:02 -08001322 if (taskStack.isOnHomeDisplay()) {
1323 if (mFocusedStack != taskStack) {
1324 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: Setting " +
1325 "focused stack to r=" + r + " task=" + task);
1326 mFocusedStack = taskStack;
1327 } else {
1328 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1329 "adjustStackFocus: Focused stack already=" + mFocusedStack);
1330 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001331 }
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07001332 return taskStack;
Craig Mautnerac6f8432013-07-17 13:24:59 -07001333 }
1334
Craig Mautnere0a38842013-12-16 16:14:02 -08001335 final ActivityContainer container = r.mInitialActivityContainer;
1336 if (container != null) {
1337 // The first time put it on the desired stack, after this put on task stack.
1338 r.mInitialActivityContainer = null;
1339 return container.mStack;
1340 }
1341
Craig Mautner4a1cb222013-12-04 16:14:06 -08001342 if (mFocusedStack != mHomeStack) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001343 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1344 "adjustStackFocus: Have a focused stack=" + mFocusedStack);
1345 return mFocusedStack;
1346 }
1347
Craig Mautnere0a38842013-12-16 16:14:02 -08001348 final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks;
1349 for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1350 final ActivityStack stack = homeDisplayStacks.get(stackNdx);
1351 if (!stack.isHomeStack()) {
1352 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1353 "adjustStackFocus: Setting focused stack=" + stack);
1354 mFocusedStack = stack;
1355 return mFocusedStack;
Craig Mautner858d8a62013-04-23 17:08:34 -07001356 }
1357 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001358
Craig Mautner4a1cb222013-12-04 16:14:06 -08001359 // Need to create an app stack for this user.
1360 int stackId = createStackOnDisplay(null, getNextStackId(), Display.DEFAULT_DISPLAY);
Craig Mautnerac6f8432013-07-17 13:24:59 -07001361 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r +
1362 " stackId=" + stackId);
1363 mFocusedStack = getStack(stackId);
Craig Mautner29219d92013-04-16 20:19:12 -07001364 return mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001365 }
1366 return mHomeStack;
1367 }
1368
Craig Mautner29219d92013-04-16 20:19:12 -07001369 void setFocusedStack(ActivityRecord r) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08001370 if (r != null) {
1371 final boolean isHomeActivity =
1372 !r.isApplicationActivity() || (r.task != null && !r.task.isApplicationTask());
1373 moveHomeStack(isHomeActivity);
Craig Mautner29219d92013-04-16 20:19:12 -07001374 }
1375 }
1376
Craig Mautner8849a5e2013-04-02 16:41:03 -07001377 final int startActivityUncheckedLocked(ActivityRecord r,
1378 ActivityRecord sourceRecord, int startFlags, boolean doResume,
1379 Bundle options) {
1380 final Intent intent = r.intent;
1381 final int callingUid = r.launchedFromUid;
1382
1383 int launchFlags = intent.getFlags();
1384
Craig Mautner8849a5e2013-04-02 16:41:03 -07001385 // We'll invoke onUserLeaving before onPause only if the launching
1386 // activity did not explicitly state that this is an automated launch.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001387 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1388 if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001389
1390 // If the caller has asked not to resume at this point, we make note
1391 // of this in the record so that we can skip it when trying to find
1392 // the top running activity.
1393 if (!doResume) {
1394 r.delayedResume = true;
1395 }
1396
1397 ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1398
1399 // If the onlyIfNeeded flag is set, then we can do this if the activity
1400 // being launched is the same as the one making the call... or, as
1401 // a special case, if we do not know the caller then we count the
1402 // current top activity as the caller.
1403 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1404 ActivityRecord checkedCaller = sourceRecord;
1405 if (checkedCaller == null) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001406 checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001407 }
1408 if (!checkedCaller.realActivity.equals(r.realActivity)) {
1409 // Caller is not the same as launcher, so always needed.
1410 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
1411 }
1412 }
1413
1414 if (sourceRecord == null) {
1415 // This activity is not being started from another... in this
1416 // case we -always- start a new task.
1417 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
Craig Mautner29219d92013-04-16 20:19:12 -07001418 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1419 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001420 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1421 }
1422 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1423 // The original activity who is starting us is running as a single
1424 // instance... this new activity it is starting must go on its
1425 // own task.
1426 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1427 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
1428 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1429 // The activity being started is a single instance... it always
1430 // gets launched into its own task.
1431 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1432 }
1433
Craig Mautner88629292013-11-10 20:39:05 -08001434 ActivityInfo newTaskInfo = null;
1435 Intent newTaskIntent = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001436 final ActivityStack sourceStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001437 if (sourceRecord != null) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001438 if (sourceRecord.finishing) {
1439 // If the source is finishing, we can't further count it as our source. This
1440 // is because the task it is associated with may now be empty and on its way out,
1441 // so we don't want to blindly throw it in to that task. Instead we will take
Craig Mautner88629292013-11-10 20:39:05 -08001442 // the NEW_TASK flow and try to find a task for it. But save the task information
1443 // so it can be used when creating the new task.
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001444 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
1445 Slog.w(TAG, "startActivity called from finishing " + sourceRecord
1446 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
1447 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
Craig Mautner88629292013-11-10 20:39:05 -08001448 newTaskInfo = sourceRecord.info;
1449 newTaskIntent = sourceRecord.task.intent;
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001450 }
1451 sourceRecord = null;
1452 sourceStack = null;
1453 } else {
1454 sourceStack = sourceRecord.task.stack;
1455 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07001456 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001457 sourceStack = null;
1458 }
1459
Craig Mautner8849a5e2013-04-02 16:41:03 -07001460 if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1461 // For whatever reason this activity is being launched into a new
1462 // task... yet the caller has requested a result back. Well, that
1463 // is pretty messed up, so instead immediately send back a cancel
1464 // and let the new task continue launched as normal without a
1465 // dependency on its originator.
1466 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1467 r.resultTo.task.stack.sendActivityResultLocked(-1,
1468 r.resultTo, r.resultWho, r.requestCode,
1469 Activity.RESULT_CANCELED, null);
1470 r.resultTo = null;
1471 }
1472
1473 boolean addingToTask = false;
1474 boolean movedHome = false;
1475 TaskRecord reuseTask = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001476 ActivityStack targetStack;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001477 if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
1478 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
1479 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1480 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1481 // If bring to front is requested, and no result is requested, and
1482 // we can find a task that was started with this same
1483 // component, then instead of launching bring that one to the front.
1484 if (r.resultTo == null) {
1485 // See if there is a task to bring to the front. If this is
1486 // a SINGLE_INSTANCE activity, there can be one and only one
1487 // instance of it in the history, and it is always in its own
1488 // unique task, so we do a special search.
1489 ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
Craig Mautnerac6f8432013-07-17 13:24:59 -07001490 ? findTaskLocked(r)
Craig Mautner8849a5e2013-04-02 16:41:03 -07001491 : findActivityLocked(intent, r.info);
1492 if (intentActivity != null) {
Craig Mautner29219d92013-04-16 20:19:12 -07001493 if (r.task == null) {
1494 r.task = intentActivity.task;
1495 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001496 targetStack = intentActivity.task.stack;
Craig Mautner0f922742013-08-06 08:44:42 -07001497 targetStack.mLastPausedActivity = null;
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001498 if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack
1499 + " from " + intentActivity);
Craig Mautnere0a38842013-12-16 16:14:02 -08001500 targetStack.moveToFront();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001501 if (intentActivity.task.intent == null) {
1502 // This task was started because of movement of
1503 // the activity based on affinity... now that we
1504 // are actually launching it, we can assign the
1505 // base intent.
1506 intentActivity.task.setIntent(intent, r.info);
1507 }
1508 // If the target task is not in the front, then we need
1509 // to bring it to the front... except... well, with
1510 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like
1511 // to have the same behavior as if a new instance was
1512 // being started, which means not bringing it to the front
1513 // if the caller is not itself in the front.
Craig Mautner165640b2013-04-20 10:34:33 -07001514 final ActivityStack lastStack = getLastStack();
1515 ActivityRecord curTop = lastStack == null?
1516 null : lastStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner7504d7b2013-09-17 10:50:53 -07001517 if (curTop != null && (curTop.task != intentActivity.task ||
1518 curTop.task != lastStack.topTask())) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001519 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Craig Mautnerd0f964f2013-08-07 11:16:33 -07001520 if (sourceRecord == null || (sourceStack.topActivity() != null &&
1521 sourceStack.topActivity().task == sourceRecord.task)) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001522 // We really do want to push this one into the
1523 // user's face, right now.
1524 movedHome = true;
Craig Mautnerb53d97c2013-10-25 11:54:37 -07001525 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001526 if ((launchFlags &
Craig Mautner29219d92013-04-16 20:19:12 -07001527 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1528 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
Craig Mautnere12a4a62013-08-29 12:24:56 -07001529 // Caller wants to appear on home activity.
Craig Mautnerae7ecab2013-09-18 11:48:14 -07001530 intentActivity.task.mOnTopOfHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001531 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001532 options = null;
1533 }
1534 }
1535 // If the caller has requested that the target task be
1536 // reset, then do so.
1537 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1538 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
1539 }
1540 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1541 // We don't need to start a new activity, and
1542 // the client said not to do anything if that
1543 // is the case, so this is it! And for paranoia, make
1544 // sure we have correctly resumed the top activity.
1545 if (doResume) {
Craig Mautner05d29032013-05-03 13:40:13 -07001546 resumeTopActivitiesLocked(targetStack, null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001547 } else {
1548 ActivityOptions.abort(options);
1549 }
1550 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1551 }
1552 if ((launchFlags &
1553 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
1554 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
1555 // The caller has requested to completely replace any
1556 // existing task with its new activity. Well that should
1557 // not be too hard...
1558 reuseTask = intentActivity.task;
1559 reuseTask.performClearTaskLocked();
1560 reuseTask.setIntent(r.intent, r.info);
1561 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
1562 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1563 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1564 // In this situation we want to remove all activities
1565 // from the task up to the one being started. In most
1566 // cases this means we are resetting the task to its
1567 // initial state.
1568 ActivityRecord top =
1569 intentActivity.task.performClearTaskLocked(r, launchFlags);
1570 if (top != null) {
1571 if (top.frontOfTask) {
1572 // Activity aliases may mean we use different
1573 // intents for the top activity, so make sure
1574 // the task now has the identity of the new
1575 // intent.
1576 top.task.setIntent(r.intent, r.info);
1577 }
1578 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
1579 r, top.task);
1580 top.deliverNewIntentLocked(callingUid, r.intent);
1581 } else {
1582 // A special case: we need to
1583 // start the activity because it is not currently
1584 // running, and the caller has asked to clear the
1585 // current task to have this activity at the top.
1586 addingToTask = true;
1587 // Now pretend like this activity is being started
1588 // by the top of its task, so it is put in the
1589 // right place.
1590 sourceRecord = intentActivity;
1591 }
1592 } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
1593 // In this case the top activity on the task is the
1594 // same as the one being launched, so we take that
1595 // as a request to bring the task to the foreground.
1596 // If the top activity in the task is the root
1597 // activity, deliver this new intent to it if it
1598 // desires.
1599 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1600 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
1601 && intentActivity.realActivity.equals(r.realActivity)) {
1602 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
1603 intentActivity.task);
1604 if (intentActivity.frontOfTask) {
1605 intentActivity.task.setIntent(r.intent, r.info);
1606 }
1607 intentActivity.deliverNewIntentLocked(callingUid, r.intent);
1608 } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
1609 // In this case we are launching the root activity
1610 // of the task, but with a different intent. We
1611 // should start a new instance on top.
1612 addingToTask = true;
1613 sourceRecord = intentActivity;
1614 }
1615 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1616 // In this case an activity is being launched in to an
1617 // existing task, without resetting that task. This
1618 // is typically the situation of launching an activity
1619 // from a notification or shortcut. We want to place
1620 // the new activity on top of the current task.
1621 addingToTask = true;
1622 sourceRecord = intentActivity;
1623 } else if (!intentActivity.task.rootWasReset) {
1624 // In this case we are launching in to an existing task
1625 // that has not yet been started from its front door.
1626 // The current task has been brought to the front.
1627 // Ideally, we'd probably like to place this new task
1628 // at the bottom of its stack, but that's a little hard
1629 // to do with the current organization of the code so
1630 // for now we'll just drop it.
1631 intentActivity.task.setIntent(r.intent, r.info);
1632 }
1633 if (!addingToTask && reuseTask == null) {
1634 // We didn't do anything... but it was needed (a.k.a., client
1635 // don't use that intent!) And for paranoia, make
1636 // sure we have correctly resumed the top activity.
1637 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001638 targetStack.resumeTopActivityLocked(null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001639 } else {
1640 ActivityOptions.abort(options);
1641 }
1642 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!
1679 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1680 }
1681 top.deliverNewIntentLocked(callingUid, r.intent);
1682 return ActivityManager.START_DELIVERED_TO_TOP;
1683 }
1684 }
1685 }
1686 }
1687
1688 } else {
1689 if (r.resultTo != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001690 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
1691 r.requestCode, Activity.RESULT_CANCELED, null);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001692 }
1693 ActivityOptions.abort(options);
1694 return ActivityManager.START_CLASS_NOT_FOUND;
1695 }
1696
1697 boolean newTask = false;
1698 boolean keepCurTransition = false;
1699
1700 // Should this be considered a new task?
1701 if (r.resultTo == null && !addingToTask
1702 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001703 targetStack = adjustStackFocus(r);
Craig Mautnere0a38842013-12-16 16:14:02 -08001704 targetStack.moveToFront();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001705 if (reuseTask == null) {
Craig Mautner88629292013-11-10 20:39:05 -08001706 r.setTask(targetStack.createTaskRecord(getNextTaskId(),
1707 newTaskInfo != null ? newTaskInfo : r.info,
1708 newTaskIntent != null ? newTaskIntent : intent,
1709 true), null, true);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001710 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
1711 r.task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001712 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001713 r.setTask(reuseTask, reuseTask, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001714 }
1715 newTask = true;
1716 if (!movedHome) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001717 if ((launchFlags &
1718 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
1719 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
1720 // Caller wants to appear on home activity, so before starting
1721 // their own activity we will bring home to the front.
Craig Mautnere0a38842013-12-16 16:14:02 -08001722 r.task.mOnTopOfHome = r.task.stack.isOnHomeDisplay();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001723 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001724 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001725 } else if (sourceRecord != null) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001726 TaskRecord sourceTask = sourceRecord.task;
Craig Mautner525f3d92013-05-07 14:01:50 -07001727 targetStack = sourceTask.stack;
Craig Mautnere0a38842013-12-16 16:14:02 -08001728 targetStack.moveToFront();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001729 if (!addingToTask &&
1730 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
1731 // In this case, we are adding the activity to an existing
1732 // task, but the caller has asked to clear that task if the
1733 // activity is already running.
Craig Mautner525f3d92013-05-07 14:01:50 -07001734 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001735 keepCurTransition = true;
1736 if (top != null) {
1737 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
1738 top.deliverNewIntentLocked(callingUid, r.intent);
1739 // For paranoia, make sure we have correctly
1740 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001741 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001742 if (doResume) {
1743 targetStack.resumeTopActivityLocked(null);
1744 }
1745 ActivityOptions.abort(options);
1746 return ActivityManager.START_DELIVERED_TO_TOP;
1747 }
1748 } else if (!addingToTask &&
1749 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1750 // In this case, we are launching an activity in our own task
1751 // that may already be running somewhere in the history, and
1752 // we want to shuffle it to the front of the stack if so.
Craig Mautner525f3d92013-05-07 14:01:50 -07001753 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001754 if (top != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001755 final TaskRecord task = top.task;
1756 task.moveActivityToFrontLocked(top);
1757 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001758 top.updateOptionsLocked(options);
1759 top.deliverNewIntentLocked(callingUid, r.intent);
Craig Mautner0f922742013-08-06 08:44:42 -07001760 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001761 if (doResume) {
1762 targetStack.resumeTopActivityLocked(null);
1763 }
1764 return ActivityManager.START_DELIVERED_TO_TOP;
1765 }
1766 }
1767 // An existing activity is starting this new activity, so we want
1768 // to keep the new one in the same task as the one that is starting
1769 // it.
Craig Mautner525f3d92013-05-07 14:01:50 -07001770 r.setTask(sourceTask, sourceRecord.thumbHolder, false);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001771 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001772 + " in existing task " + r.task + " from source " + sourceRecord);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001773
1774 } else {
1775 // This not being started from an existing activity, and not part
1776 // of a new task... just put it in the top task, though these days
1777 // this case should never happen.
Craig Mautnerac6f8432013-07-17 13:24:59 -07001778 targetStack = adjustStackFocus(r);
Craig Mautnere0a38842013-12-16 16:14:02 -08001779 targetStack.moveToFront();
Craig Mautner1602ec22013-05-12 10:24:27 -07001780 ActivityRecord prev = targetStack.topActivity();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001781 r.setTask(prev != null ? prev.task
1782 : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1783 null, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001784 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1785 + " in new guessed " + r.task);
1786 }
1787
1788 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
1789 intent, r.getUriPermissionsLocked());
1790
1791 if (newTask) {
1792 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
1793 }
1794 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
Craig Mautner0f922742013-08-06 08:44:42 -07001795 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001796 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
Craig Mautner1d001b62013-06-18 16:52:43 -07001797 mService.setFocusedActivityLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001798 return ActivityManager.START_SUCCESS;
1799 }
1800
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001801 void acquireLaunchWakelock() {
1802 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
1803 throw new IllegalStateException("Calling must be system uid");
1804 }
1805 mLaunchingActivity.acquire();
1806 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
1807 // To be safe, don't allow the wake lock to be held for too long.
1808 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
1809 }
1810 }
1811
Craig Mautnerf3333272013-04-22 10:55:53 -07001812 // Checked.
1813 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
1814 Configuration config) {
1815 if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
1816
Craig Mautnerf3333272013-04-22 10:55:53 -07001817 ArrayList<ActivityRecord> stops = null;
1818 ArrayList<ActivityRecord> finishes = null;
1819 ArrayList<UserStartedState> startingUsers = null;
1820 int NS = 0;
1821 int NF = 0;
1822 IApplicationThread sendThumbnail = null;
1823 boolean booting = false;
1824 boolean enableScreen = false;
1825 boolean activityRemoved = false;
1826
1827 ActivityRecord r = ActivityRecord.forToken(token);
1828 if (r != null) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07001829 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
1830 Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07001831 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
1832 r.finishLaunchTickingLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001833 if (fromTimeout) {
1834 reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
Craig Mautnerf3333272013-04-22 10:55:53 -07001835 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001836
1837 // This is a hack to semi-deal with a race condition
1838 // in the client where it can be constructed with a
1839 // newer configuration from when we asked it to launch.
1840 // We'll update with whatever configuration it now says
1841 // it used to launch.
1842 if (config != null) {
1843 r.configuration = config;
1844 }
1845
1846 // We are now idle. If someone is waiting for a thumbnail from
1847 // us, we can now deliver.
1848 r.idle = true;
1849
1850 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
1851 sendThumbnail = r.app.thread;
1852 r.thumbnailNeeded = false;
1853 }
1854
1855 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
1856 if (!mService.mBooted && isFrontStack(r.task.stack)) {
1857 mService.mBooted = true;
1858 enableScreen = true;
1859 }
1860 }
1861
1862 if (allResumedActivitiesIdle()) {
1863 if (r != null) {
1864 mService.scheduleAppGcsLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001865 }
1866
1867 if (mLaunchingActivity.isHeld()) {
1868 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
1869 if (VALIDATE_WAKE_LOCK_CALLER &&
1870 Binder.getCallingUid() != Process.myUid()) {
1871 throw new IllegalStateException("Calling must be system uid");
1872 }
1873 mLaunchingActivity.release();
1874 }
1875 ensureActivitiesVisibleLocked(null, 0);
Craig Mautnerf3333272013-04-22 10:55:53 -07001876 }
1877
1878 // Atomically retrieve all of the other things to do.
1879 stops = processStoppingActivitiesLocked(true);
1880 NS = stops != null ? stops.size() : 0;
1881 if ((NF=mFinishingActivities.size()) > 0) {
1882 finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
1883 mFinishingActivities.clear();
1884 }
1885
1886 final ArrayList<ActivityRecord> thumbnails;
1887 final int NT = mCancelledThumbnails.size();
1888 if (NT > 0) {
1889 thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
1890 mCancelledThumbnails.clear();
1891 } else {
1892 thumbnails = null;
1893 }
1894
1895 if (isFrontStack(mHomeStack)) {
1896 booting = mService.mBooting;
1897 mService.mBooting = false;
1898 }
1899
1900 if (mStartingUsers.size() > 0) {
1901 startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
1902 mStartingUsers.clear();
1903 }
1904
1905 // Perform the following actions from unsynchronized state.
1906 final IApplicationThread thumbnailThread = sendThumbnail;
1907 mHandler.post(new Runnable() {
1908 @Override
1909 public void run() {
1910 if (thumbnailThread != null) {
1911 try {
1912 thumbnailThread.requestThumbnail(token);
1913 } catch (Exception e) {
1914 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
1915 mService.sendPendingThumbnail(null, token, null, null, true);
1916 }
1917 }
1918
1919 // Report back to any thumbnail receivers.
1920 for (int i = 0; i < NT; i++) {
1921 ActivityRecord r = thumbnails.get(i);
1922 mService.sendPendingThumbnail(r, null, null, null, true);
1923 }
1924 }
1925 });
1926
1927 // Stop any activities that are scheduled to do so but have been
1928 // waiting for the next one to start.
1929 for (int i = 0; i < NS; i++) {
1930 r = stops.get(i);
1931 final ActivityStack stack = r.task.stack;
1932 if (r.finishing) {
1933 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
1934 } else {
1935 stack.stopActivityLocked(r);
1936 }
1937 }
1938
1939 // Finish 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 < NF; i++) {
1942 r = finishes.get(i);
1943 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
1944 }
1945
1946 if (booting) {
1947 mService.finishBooting();
1948 } else if (startingUsers != null) {
1949 for (int i = 0; i < startingUsers.size(); i++) {
1950 mService.finishUserSwitch(startingUsers.get(i));
1951 }
1952 }
1953
1954 mService.trimApplications();
1955 //dump();
1956 //mWindowManager.dump();
1957
1958 if (enableScreen) {
1959 mService.enableScreenAfterBoot();
1960 }
1961
1962 if (activityRemoved) {
Craig Mautner05d29032013-05-03 13:40:13 -07001963 resumeTopActivitiesLocked();
Craig Mautnerf3333272013-04-22 10:55:53 -07001964 }
1965
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001966 return r;
Craig Mautnerf3333272013-04-22 10:55:53 -07001967 }
1968
Craig Mautner8e569572013-10-11 17:36:59 -07001969 boolean handleAppDiedLocked(ProcessRecord app) {
Craig Mautner19091252013-10-05 00:03:53 -07001970 boolean hasVisibleActivities = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08001971 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1972 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08001973 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1974 hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app);
1975 }
Craig Mautner6b74cb52013-09-27 17:02:21 -07001976 }
Craig Mautner19091252013-10-05 00:03:53 -07001977 return hasVisibleActivities;
Craig Mautner8d341ef2013-03-26 09:03:27 -07001978 }
1979
1980 void closeSystemDialogsLocked() {
Craig Mautnere0a38842013-12-16 16:14:02 -08001981 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1982 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08001983 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1984 stacks.get(stackNdx).closeSystemDialogsLocked();
1985 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07001986 }
1987 }
1988
Craig Mautner93529a42013-10-04 15:03:13 -07001989 void removeUserLocked(int userId) {
Craig Mautner4f1df4f2013-10-15 15:44:14 -07001990 mUserStackInFront.delete(userId);
Craig Mautner93529a42013-10-04 15:03:13 -07001991 }
1992
Craig Mautner8d341ef2013-03-26 09:03:27 -07001993 /**
1994 * @return true if some activity was finished (or would have finished if doit were true).
1995 */
1996 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
1997 boolean didSomething = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08001998 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1999 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002000 final int numStacks = stacks.size();
2001 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2002 final ActivityStack stack = stacks.get(stackNdx);
2003 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
2004 didSomething = true;
2005 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002006 }
2007 }
2008 return didSomething;
2009 }
2010
Dianne Hackborna413dc02013-07-12 12:02:55 -07002011 void updatePreviousProcessLocked(ActivityRecord r) {
2012 // Now that this process has stopped, we may want to consider
2013 // it to be the previous app to try to keep around in case
2014 // the user wants to return to it.
2015
2016 // First, found out what is currently the foreground app, so that
2017 // we don't blow away the previous app if this activity is being
2018 // hosted by the process that is actually still the foreground.
2019 ProcessRecord fgApp = null;
Craig Mautnere0a38842013-12-16 16:14:02 -08002020 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2021 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002022 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2023 final ActivityStack stack = stacks.get(stackNdx);
2024 if (isFrontStack(stack)) {
2025 if (stack.mResumedActivity != null) {
2026 fgApp = stack.mResumedActivity.app;
2027 } else if (stack.mPausingActivity != null) {
2028 fgApp = stack.mPausingActivity.app;
2029 }
2030 break;
Dianne Hackborna413dc02013-07-12 12:02:55 -07002031 }
Dianne Hackborna413dc02013-07-12 12:02:55 -07002032 }
2033 }
2034
2035 // Now set this one as the previous process, only if that really
2036 // makes sense to.
2037 if (r.app != null && fgApp != null && r.app != fgApp
2038 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
Craig Mautner4ef26932013-09-18 15:15:52 -07002039 && r.app != mService.mHomeProcess) {
Dianne Hackborna413dc02013-07-12 12:02:55 -07002040 mService.mPreviousProcess = r.app;
2041 mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
2042 }
2043 }
2044
Craig Mautner05d29032013-05-03 13:40:13 -07002045 boolean resumeTopActivitiesLocked() {
2046 return resumeTopActivitiesLocked(null, null, null);
2047 }
2048
2049 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
2050 Bundle targetOptions) {
2051 if (targetStack == null) {
2052 targetStack = getFocusedStack();
2053 }
2054 boolean result = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002055 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2056 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002057 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2058 final ActivityStack stack = stacks.get(stackNdx);
2059 if (isFrontStack(stack)) {
2060 if (stack == targetStack) {
2061 result = stack.resumeTopActivityLocked(target, targetOptions);
2062 } else {
2063 stack.resumeTopActivityLocked(null);
2064 }
Craig Mautner05d29032013-05-03 13:40:13 -07002065 }
Craig Mautnerf88c50f2013-04-18 19:25:12 -07002066 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002067 }
Craig Mautner05d29032013-05-03 13:40:13 -07002068 return result;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002069 }
2070
2071 void finishTopRunningActivityLocked(ProcessRecord app) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002072 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2073 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002074 final int numStacks = stacks.size();
2075 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2076 final ActivityStack stack = stacks.get(stackNdx);
2077 stack.finishTopRunningActivityLocked(app);
2078 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002079 }
2080 }
2081
Craig Mautner8d341ef2013-03-26 09:03:27 -07002082 void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002083 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2084 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002085 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2086 if (stacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) {
2087 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack="
2088 + stacks.get(stackNdx));
2089 return;
2090 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002091 }
2092 }
2093 }
2094
Craig Mautner967212c2013-04-13 21:10:58 -07002095 ActivityStack getStack(int stackId) {
Craig Mautner4504de52013-12-20 09:06:56 -08002096 WeakReference<ActivityContainer> weakReference = mActivityContainers.get(stackId);
2097 if (weakReference != null) {
2098 ActivityContainer activityContainer = weakReference.get();
2099 if (activityContainer != null) {
2100 return activityContainer.mStack;
2101 } else {
2102 mActivityContainers.remove(stackId);
2103 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002104 }
2105 return null;
2106 }
2107
Craig Mautner967212c2013-04-13 21:10:58 -07002108 ArrayList<ActivityStack> getStacks() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002109 ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>();
Craig Mautnere0a38842013-12-16 16:14:02 -08002110 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2111 allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002112 }
2113 return allStacks;
Craig Mautner967212c2013-04-13 21:10:58 -07002114 }
2115
Craig Mautner4a1cb222013-12-04 16:14:06 -08002116 IBinder getHomeActivityToken() {
2117 final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
2118 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
2119 final TaskRecord task = tasks.get(taskNdx);
2120 if (task.isHomeTask()) {
2121 final ArrayList<ActivityRecord> activities = task.mActivities;
2122 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2123 final ActivityRecord r = activities.get(activityNdx);
2124 if (r.isHomeActivity()) {
2125 return r.appToken;
2126 }
2127 }
2128 }
2129 }
2130 return null;
2131 }
2132
2133 ActivityContainer createActivityContainer(ActivityRecord parentActivity, int stackId,
2134 IActivityContainerCallback callback) {
2135 ActivityContainer activityContainer = new ActivityContainer(parentActivity, stackId,
2136 callback);
Craig Mautner4504de52013-12-20 09:06:56 -08002137 mActivityContainers.put(stackId, new WeakReference<ActivityContainer>(activityContainer));
Craig Mautner4a1cb222013-12-04 16:14:06 -08002138 if (parentActivity != null) {
2139 parentActivity.mChildContainers.add(activityContainer.mStack);
2140 }
2141 return activityContainer;
2142 }
2143
2144 ActivityContainer createActivityContainer(ActivityRecord parentActivity,
2145 IActivityContainerCallback callback) {
2146 return createActivityContainer(parentActivity, getNextStackId(), callback);
2147 }
2148
Craig Mautner34b73df2014-01-12 21:11:08 -08002149 void removeChildActivityContainers(ActivityRecord parentActivity) {
2150 for (int ndx = mActivityContainers.size() - 1; ndx >= 0; --ndx) {
2151 final ActivityContainer container = mActivityContainers.valueAt(ndx).get();
2152 if (container == null) {
2153 mActivityContainers.removeAt(ndx);
2154 continue;
2155 }
2156 if (container.mParentActivity != parentActivity) {
2157 continue;
2158 }
2159
2160 ActivityStack stack = container.mStack;
2161 ActivityRecord top = stack.topRunningNonDelayedActivityLocked(null);
2162 if (top != null) {
2163 // TODO: Make sure the next activity doesn't start up when top is destroyed.
2164 stack.destroyActivityLocked(top, true, true, "stack removal");
2165 }
2166 mActivityContainers.removeAt(ndx);
2167 container.detachLocked();
2168 }
2169 }
2170
Craig Mautner4a1cb222013-12-04 16:14:06 -08002171 private int createStackOnDisplay(ActivityRecord parentActivity, int stackId, int displayId) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002172 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2173 if (activityDisplay == null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002174 return -1;
2175 }
2176
2177 ActivityContainer activityContainer =
2178 createActivityContainer(parentActivity, stackId, null);
Craig Mautnere0a38842013-12-16 16:14:02 -08002179 activityContainer.attachToDisplayLocked(activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002180 return stackId;
2181 }
2182
2183 int getNextStackId() {
Craig Mautner858d8a62013-04-23 17:08:34 -07002184 while (true) {
2185 if (++mLastStackId <= HOME_STACK_ID) {
2186 mLastStackId = HOME_STACK_ID + 1;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002187 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002188 if (getStack(mLastStackId) == null) {
2189 break;
2190 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002191 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002192 return mLastStackId;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002193 }
2194
2195 void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002196 final TaskRecord task = anyTaskForIdLocked(taskId);
2197 if (task == null) {
2198 return;
2199 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002200 final ActivityStack stack = getStack(stackId);
2201 if (stack == null) {
2202 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
2203 return;
2204 }
Craig Mautner04a0ea62014-01-13 12:51:26 -08002205 task.stack.removeTask(task);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002206 stack.addTask(task, toTop);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002207 mWindowManager.addTask(taskId, stackId, toTop);
Craig Mautner05d29032013-05-03 13:40:13 -07002208 resumeTopActivitiesLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002209 }
2210
Craig Mautnerac6f8432013-07-17 13:24:59 -07002211 ActivityRecord findTaskLocked(ActivityRecord r) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07002212 if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r);
Craig Mautnere0a38842013-12-16 16:14:02 -08002213 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2214 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002215 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2216 final ActivityStack stack = stacks.get(stackNdx);
2217 if (!r.isApplicationActivity() && !stack.isHomeStack()) {
2218 if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: " + stack);
2219 continue;
2220 }
2221 final ActivityRecord ar = stack.findTaskLocked(r);
2222 if (ar != null) {
2223 return ar;
2224 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07002225 }
2226 }
Dianne Hackborn2a272d42013-10-16 13:34:33 -07002227 if (DEBUG_TASKS) Slog.d(TAG, "No task found");
Craig Mautner8849a5e2013-04-02 16:41:03 -07002228 return null;
2229 }
2230
2231 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002232 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2233 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002234 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2235 final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info);
2236 if (ar != null) {
2237 return ar;
2238 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07002239 }
2240 }
2241 return null;
2242 }
2243
Craig Mautner8d341ef2013-03-26 09:03:27 -07002244 void goingToSleepLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002245 scheduleSleepTimeout();
2246 if (!mGoingToSleep.isHeld()) {
2247 mGoingToSleep.acquire();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002248 if (mLaunchingActivity.isHeld()) {
2249 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2250 throw new IllegalStateException("Calling must be system uid");
Craig Mautner0eea92c2013-05-16 13:35:39 -07002251 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002252 mLaunchingActivity.release();
2253 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
Craig Mautner0eea92c2013-05-16 13:35:39 -07002254 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002255 }
Amith Yamasanice15e152013-09-19 12:30:32 -07002256 checkReadyForSleepLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002257 }
2258
2259 boolean shutdownLocked(int timeout) {
2260 boolean timedout = false;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002261 goingToSleepLocked();
Craig Mautner0eea92c2013-05-16 13:35:39 -07002262
2263 final long endTime = System.currentTimeMillis() + timeout;
2264 while (true) {
2265 boolean cantShutdown = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002266 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2267 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002268 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2269 cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
2270 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002271 }
2272 if (cantShutdown) {
2273 long timeRemaining = endTime - System.currentTimeMillis();
2274 if (timeRemaining > 0) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002275 try {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002276 mService.wait(timeRemaining);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002277 } catch (InterruptedException e) {
2278 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002279 } else {
2280 Slog.w(TAG, "Activity manager shutdown timed out");
2281 timedout = true;
2282 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002283 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002284 } else {
2285 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002286 }
2287 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002288
2289 // Force checkReadyForSleep to complete.
2290 mSleepTimeout = true;
2291 checkReadyForSleepLocked();
2292
Craig Mautner8d341ef2013-03-26 09:03:27 -07002293 return timedout;
2294 }
2295
2296 void comeOutOfSleepIfNeededLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002297 removeSleepTimeouts();
2298 if (mGoingToSleep.isHeld()) {
2299 mGoingToSleep.release();
2300 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002301 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2302 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002303 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2304 final ActivityStack stack = stacks.get(stackNdx);
2305 stack.awakeFromSleepingLocked();
2306 if (isFrontStack(stack)) {
2307 resumeTopActivitiesLocked();
2308 }
Craig Mautner5314a402013-09-26 12:40:16 -07002309 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002310 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002311 mGoingToSleepActivities.clear();
2312 }
2313
2314 void activitySleptLocked(ActivityRecord r) {
2315 mGoingToSleepActivities.remove(r);
2316 checkReadyForSleepLocked();
2317 }
2318
2319 void checkReadyForSleepLocked() {
2320 if (!mService.isSleepingOrShuttingDown()) {
2321 // Do not care.
2322 return;
2323 }
2324
2325 if (!mSleepTimeout) {
2326 boolean dontSleep = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002327 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2328 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002329 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2330 dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
2331 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002332 }
2333
2334 if (mStoppingActivities.size() > 0) {
2335 // Still need to tell some activities to stop; can't sleep yet.
2336 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2337 + mStoppingActivities.size() + " activities");
2338 scheduleIdleLocked();
2339 dontSleep = true;
2340 }
2341
2342 if (mGoingToSleepActivities.size() > 0) {
2343 // Still need to tell some activities to sleep; can't sleep yet.
2344 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2345 + mGoingToSleepActivities.size() + " activities");
2346 dontSleep = true;
2347 }
2348
2349 if (dontSleep) {
2350 return;
2351 }
2352 }
2353
Craig Mautnere0a38842013-12-16 16:14:02 -08002354 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2355 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002356 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2357 stacks.get(stackNdx).goToSleep();
2358 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002359 }
2360
2361 removeSleepTimeouts();
2362
2363 if (mGoingToSleep.isHeld()) {
2364 mGoingToSleep.release();
2365 }
2366 if (mService.mShuttingDown) {
2367 mService.notifyAll();
2368 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002369 }
2370
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002371 boolean reportResumedActivityLocked(ActivityRecord r) {
2372 final ActivityStack stack = r.task.stack;
2373 if (isFrontStack(stack)) {
Jeff Sharkey5782da72013-04-25 14:32:30 -07002374 mService.updateUsageStats(r, true);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002375 }
2376 if (allResumedActivitiesComplete()) {
2377 ensureActivitiesVisibleLocked(null, 0);
2378 mWindowManager.executeAppTransition();
2379 return true;
2380 }
2381 return false;
2382 }
2383
Craig Mautner8d341ef2013-03-26 09:03:27 -07002384 void handleAppCrashLocked(ProcessRecord app) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002385 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2386 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002387 final int numStacks = stacks.size();
2388 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2389 final ActivityStack stack = stacks.get(stackNdx);
2390 stack.handleAppCrashLocked(app);
2391 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002392 }
2393 }
2394
Craig Mautnerde4ef022013-04-07 19:01:33 -07002395 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
Craig Mautner580ea812013-04-25 12:58:38 -07002396 // First the front stacks. In case any are not fullscreen and are in front of home.
2397 boolean showHomeBehindStack = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002398 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2399 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002400 final int topStackNdx = stacks.size() - 1;
2401 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
2402 final ActivityStack stack = stacks.get(stackNdx);
2403 if (stackNdx == topStackNdx) {
2404 // Top stack.
2405 showHomeBehindStack =
2406 stack.ensureActivitiesVisibleLocked(starting, configChanges);
2407 } else {
2408 // Back stack.
2409 stack.ensureActivitiesVisibleLocked(starting, configChanges,
2410 showHomeBehindStack);
2411 }
Craig Mautner580ea812013-04-25 12:58:38 -07002412 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002413 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002414 }
2415
2416 void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002417 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2418 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002419 final int numStacks = stacks.size();
2420 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2421 final ActivityStack stack = stacks.get(stackNdx);
2422 stack.scheduleDestroyActivities(app, false, reason);
2423 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002424 }
2425 }
2426
2427 boolean switchUserLocked(int userId, UserStartedState uss) {
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002428 mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId());
2429 final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
Craig Mautner2420ead2013-04-01 17:13:20 -07002430 mCurrentUser = userId;
Craig Mautnerac6f8432013-07-17 13:24:59 -07002431
Craig Mautner858d8a62013-04-23 17:08:34 -07002432 mStartingUsers.add(uss);
Craig Mautnere0a38842013-12-16 16:14:02 -08002433 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2434 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002435 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002436 final ActivityStack stack = stacks.get(stackNdx);
2437 stack.switchUserLocked(userId);
2438 mWindowManager.moveTaskToTop(stack.topTask().taskId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002439 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07002440 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002441
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002442 ActivityStack stack = getStack(restoreStackId);
2443 if (stack == null) {
2444 stack = mHomeStack;
2445 }
2446 final boolean homeInFront = stack.isHomeStack();
Craig Mautnere0a38842013-12-16 16:14:02 -08002447 if (stack.isOnHomeDisplay()) {
2448 moveHomeStack(homeInFront);
2449 mWindowManager.moveTaskToTop(stack.topTask().taskId);
2450 } else {
2451 // Stack was moved to another display while user was swapped out.
2452 resumeHomeActivity(null);
2453 }
Craig Mautner93529a42013-10-04 15:03:13 -07002454 return homeInFront;
Craig Mautner2219a1b2013-03-25 09:44:30 -07002455 }
2456
Craig Mautnerde4ef022013-04-07 19:01:33 -07002457 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2458 int N = mStoppingActivities.size();
2459 if (N <= 0) return null;
2460
2461 ArrayList<ActivityRecord> stops = null;
2462
2463 final boolean nowVisible = allResumedActivitiesVisible();
2464 for (int i=0; i<N; i++) {
2465 ActivityRecord s = mStoppingActivities.get(i);
Craig Mautnera7f2bd42013-10-15 16:13:50 -07002466 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
Craig Mautnerde4ef022013-04-07 19:01:33 -07002467 + nowVisible + " waitingVisible=" + s.waitingVisible
2468 + " finishing=" + s.finishing);
2469 if (s.waitingVisible && nowVisible) {
2470 mWaitingVisibleActivities.remove(s);
2471 s.waitingVisible = false;
2472 if (s.finishing) {
2473 // If this activity is finishing, it is sitting on top of
2474 // everyone else but we now know it is no longer needed...
2475 // so get rid of it. Otherwise, we need to go through the
2476 // normal flow and hide it once we determine that it is
2477 // hidden by the activities in front of it.
2478 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002479 mWindowManager.setAppVisibility(s.appToken, false);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002480 }
2481 }
2482 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2483 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2484 if (stops == null) {
2485 stops = new ArrayList<ActivityRecord>();
2486 }
2487 stops.add(s);
2488 mStoppingActivities.remove(i);
2489 N--;
2490 i--;
2491 }
2492 }
2493
2494 return stops;
2495 }
2496
Craig Mautnercf910b02013-04-23 11:23:27 -07002497 void validateTopActivitiesLocked() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002498 // FIXME
2499/* for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2500 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautnercf910b02013-04-23 11:23:27 -07002501 final ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002502 final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
Craig Mautnercf910b02013-04-23 11:23:27 -07002503 if (isFrontStack(stack)) {
2504 if (r == null) {
2505 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2506 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002507 final ActivityRecord pausing = stack.mPausingActivity;
2508 if (pausing != null && pausing == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002509 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002510 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002511 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002512 if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002513 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002514 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002515 }
2516 }
2517 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002518 final ActivityRecord resumed = stack.mResumedActivity;
2519 if (resumed != null && resumed == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002520 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002521 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002522 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002523 if (r != null && (state == ActivityState.INITIALIZING
2524 || state == ActivityState.RESUMED)) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002525 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002526 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002527 }
2528 }
2529 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002530*/
Craig Mautner76ea2242013-05-15 11:40:05 -07002531 }
2532
Craig Mautner27084302013-03-25 08:05:25 -07002533 public void dump(PrintWriter pw, String prefix) {
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002534 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity=");
Craig Mautner27084302013-03-25 08:05:25 -07002535 pw.println(mDismissKeyguardOnNextActivity);
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002536 pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002537 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002538 pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
2539 pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
2540 pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
Craig Mautner27084302013-03-25 08:05:25 -07002541 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002542
Craig Mautner20e72272013-04-01 13:45:53 -07002543 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002544 return getFocusedStack().getDumpActivitiesLocked(name);
Craig Mautner20e72272013-04-01 13:45:53 -07002545 }
2546
Dianne Hackborn390517b2013-05-30 15:03:32 -07002547 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2548 boolean needSep, String prefix) {
2549 if (activity != null) {
2550 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2551 if (needSep) {
2552 pw.println();
Dianne Hackborn390517b2013-05-30 15:03:32 -07002553 }
2554 pw.print(prefix);
2555 pw.println(activity);
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002556 return true;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002557 }
2558 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002559 return false;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002560 }
2561
Craig Mautner8d341ef2013-03-26 09:03:27 -07002562 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2563 boolean dumpClient, String dumpPackage) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002564 boolean printed = false;
2565 boolean needSep = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002566 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2567 ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
2568 pw.print("Display #"); pw.println(activityDisplay.mDisplayId);
2569 ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002570 final int numStacks = stacks.size();
2571 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2572 final ActivityStack stack = stacks.get(stackNdx);
2573 StringBuilder stackHeader = new StringBuilder(128);
2574 stackHeader.append(" Stack #");
2575 stackHeader.append(stack.mStackId);
2576 stackHeader.append(":");
2577 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
2578 needSep, stackHeader.toString());
2579 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false,
2580 !dumpAll, false, dumpPackage, true,
2581 " Running activities (most recent first):", null);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002582
Craig Mautner4a1cb222013-12-04 16:14:06 -08002583 needSep = printed;
2584 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
2585 " mPausingActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002586 if (pr) {
2587 printed = true;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002588 needSep = false;
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002589 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002590 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
2591 " mResumedActivity: ");
2592 if (pr) {
2593 printed = true;
2594 needSep = false;
2595 }
2596 if (dumpAll) {
2597 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
2598 " mLastPausedActivity: ");
2599 if (pr) {
2600 printed = true;
2601 needSep = true;
2602 }
2603 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
2604 needSep, " mLastNoHistoryActivity: ");
2605 }
2606 needSep = printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002607 }
2608 }
2609
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002610 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll,
2611 false, dumpPackage, true, " Activities waiting to finish:", null);
2612 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll,
2613 false, dumpPackage, true, " Activities waiting to stop:", null);
2614 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll,
2615 false, dumpPackage, true, " Activities waiting for another to become visible:",
2616 null);
2617 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2618 false, dumpPackage, true, " Activities waiting to sleep:", null);
2619 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2620 false, dumpPackage, true, " Activities waiting to sleep:", null);
Craig Mautnerf3333272013-04-22 10:55:53 -07002621
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002622 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002623 }
2624
Dianne Hackborn390517b2013-05-30 15:03:32 -07002625 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
Craig Mautner8d341ef2013-03-26 09:03:27 -07002626 String prefix, String label, boolean complete, boolean brief, boolean client,
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002627 String dumpPackage, boolean needNL, String header1, String header2) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002628 TaskRecord lastTask = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002629 String innerPrefix = null;
2630 String[] args = null;
2631 boolean printed = false;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002632 for (int i=list.size()-1; i>=0; i--) {
2633 final ActivityRecord r = list.get(i);
2634 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2635 continue;
2636 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002637 if (innerPrefix == null) {
2638 innerPrefix = prefix + " ";
2639 args = new String[0];
2640 }
2641 printed = true;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002642 final boolean full = !brief && (complete || !r.isInHistory());
2643 if (needNL) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07002644 pw.println("");
Craig Mautner8d341ef2013-03-26 09:03:27 -07002645 needNL = false;
2646 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002647 if (header1 != null) {
2648 pw.println(header1);
2649 header1 = null;
2650 }
2651 if (header2 != null) {
2652 pw.println(header2);
2653 header2 = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002654 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002655 if (lastTask != r.task) {
2656 lastTask = r.task;
2657 pw.print(prefix);
2658 pw.print(full ? "* " : " ");
2659 pw.println(lastTask);
2660 if (full) {
2661 lastTask.dump(pw, prefix + " ");
2662 } else if (complete) {
2663 // Complete + brief == give a summary. Isn't that obvious?!?
2664 if (lastTask.intent != null) {
2665 pw.print(prefix); pw.print(" ");
2666 pw.println(lastTask.intent.toInsecureStringWithClip());
2667 }
2668 }
2669 }
2670 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
2671 pw.print(" #"); pw.print(i); pw.print(": ");
2672 pw.println(r);
2673 if (full) {
2674 r.dump(pw, innerPrefix);
2675 } else if (complete) {
2676 // Complete + brief == give a summary. Isn't that obvious?!?
2677 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2678 if (r.app != null) {
2679 pw.print(innerPrefix); pw.println(r.app);
2680 }
2681 }
2682 if (client && r.app != null && r.app.thread != null) {
2683 // flush anything that is already in the PrintWriter since the thread is going
2684 // to write to the file descriptor directly
2685 pw.flush();
2686 try {
2687 TransferPipe tp = new TransferPipe();
2688 try {
2689 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2690 r.appToken, innerPrefix, args);
2691 // Short timeout, since blocking here can
2692 // deadlock with the application.
2693 tp.go(fd, 2000);
2694 } finally {
2695 tp.kill();
2696 }
2697 } catch (IOException e) {
2698 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2699 } catch (RemoteException e) {
2700 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2701 }
2702 needNL = true;
2703 }
2704 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002705 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002706 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002707
Craig Mautnerf3333272013-04-22 10:55:53 -07002708 void scheduleIdleTimeoutLocked(ActivityRecord next) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002709 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
Craig Mautnerc64f73e2013-04-24 16:44:56 -07002710 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2711 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
Craig Mautnerf3333272013-04-22 10:55:53 -07002712 }
2713
2714 final void scheduleIdleLocked() {
Craig Mautner05d29032013-05-03 13:40:13 -07002715 mHandler.sendEmptyMessage(IDLE_NOW_MSG);
Craig Mautnerf3333272013-04-22 10:55:53 -07002716 }
2717
2718 void removeTimeoutsForActivityLocked(ActivityRecord r) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002719 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07002720 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2721 }
2722
Craig Mautner05d29032013-05-03 13:40:13 -07002723 final void scheduleResumeTopActivities() {
Craig Mautner34b73df2014-01-12 21:11:08 -08002724 if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
2725 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2726 }
Craig Mautner05d29032013-05-03 13:40:13 -07002727 }
2728
Craig Mautner0eea92c2013-05-16 13:35:39 -07002729 void removeSleepTimeouts() {
2730 mSleepTimeout = false;
2731 mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2732 }
2733
2734 final void scheduleSleepTimeout() {
2735 removeSleepTimeouts();
2736 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2737 }
2738
Craig Mautner4a1cb222013-12-04 16:14:06 -08002739 @Override
2740 public void onDisplayAdded(int displayId) {
2741 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
2742 }
2743
2744 @Override
2745 public void onDisplayRemoved(int displayId) {
2746 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
2747 }
2748
2749 @Override
2750 public void onDisplayChanged(int displayId) {
2751 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
2752 }
2753
2754 public void handleDisplayAddedLocked(int displayId) {
Craig Mautner4504de52013-12-20 09:06:56 -08002755 boolean newDisplay;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002756 synchronized (mService) {
Craig Mautner4504de52013-12-20 09:06:56 -08002757 newDisplay = mActivityDisplays.get(displayId) == null;
2758 if (newDisplay) {
2759 ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
2760 mActivityDisplays.put(displayId, activityDisplay);
2761 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002762 }
Craig Mautner4504de52013-12-20 09:06:56 -08002763 if (newDisplay) {
2764 mWindowManager.onDisplayAdded(displayId);
2765 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002766 }
2767
2768 public void handleDisplayRemovedLocked(int displayId) {
2769 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002770 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2771 if (activityDisplay != null) {
2772 ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002773 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner34b73df2014-01-12 21:11:08 -08002774 stacks.get(stackNdx).mActivityContainer.detachLocked();
Craig Mautner4a1cb222013-12-04 16:14:06 -08002775 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002776 mActivityDisplays.remove(displayId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002777 }
2778 }
2779 mWindowManager.onDisplayRemoved(displayId);
2780 }
2781
2782 public void handleDisplayChangedLocked(int displayId) {
2783 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002784 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2785 if (activityDisplay != null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002786 // TODO: Update the bounds.
2787 }
2788 }
2789 mWindowManager.onDisplayChanged(displayId);
2790 }
2791
2792 StackInfo getStackInfo(ActivityStack stack) {
2793 StackInfo info = new StackInfo();
2794 mWindowManager.getStackBounds(stack.mStackId, info.bounds);
2795 info.displayId = Display.DEFAULT_DISPLAY;
2796 info.stackId = stack.mStackId;
2797
2798 ArrayList<TaskRecord> tasks = stack.getAllTasks();
2799 final int numTasks = tasks.size();
2800 int[] taskIds = new int[numTasks];
2801 String[] taskNames = new String[numTasks];
2802 for (int i = 0; i < numTasks; ++i) {
2803 final TaskRecord task = tasks.get(i);
2804 taskIds[i] = task.taskId;
2805 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
2806 : task.realActivity != null ? task.realActivity.flattenToString()
2807 : task.getTopActivity() != null ? task.getTopActivity().packageName
2808 : "unknown";
2809 }
2810 info.taskIds = taskIds;
2811 info.taskNames = taskNames;
2812 return info;
2813 }
2814
2815 StackInfo getStackInfoLocked(int stackId) {
2816 ActivityStack stack = getStack(stackId);
2817 if (stack != null) {
2818 return getStackInfo(stack);
2819 }
2820 return null;
2821 }
2822
2823 ArrayList<StackInfo> getAllStackInfosLocked() {
2824 ArrayList<StackInfo> list = new ArrayList<StackInfo>();
Craig Mautnere0a38842013-12-16 16:14:02 -08002825 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2826 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002827 for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
2828 list.add(getStackInfo(stacks.get(ndx)));
2829 }
2830 }
2831 return list;
2832 }
2833
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002834 private final class ActivityStackSupervisorHandler extends Handler {
Craig Mautnerf3333272013-04-22 10:55:53 -07002835
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002836 public ActivityStackSupervisorHandler(Looper looper) {
2837 super(looper);
2838 }
2839
Craig Mautnerf3333272013-04-22 10:55:53 -07002840 void activityIdleInternal(ActivityRecord r) {
2841 synchronized (mService) {
2842 activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
2843 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002844 }
2845
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002846 @Override
2847 public void handleMessage(Message msg) {
2848 switch (msg.what) {
Craig Mautnerf3333272013-04-22 10:55:53 -07002849 case IDLE_TIMEOUT_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002850 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002851 if (mService.mDidDexOpt) {
2852 mService.mDidDexOpt = false;
2853 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2854 nmsg.obj = msg.obj;
2855 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
2856 return;
2857 }
2858 // We don't at this point know if the activity is fullscreen,
2859 // so we need to be conservative and assume it isn't.
2860 activityIdleInternal((ActivityRecord)msg.obj);
2861 } break;
2862 case IDLE_NOW_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002863 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002864 activityIdleInternal((ActivityRecord)msg.obj);
2865 } break;
Craig Mautner05d29032013-05-03 13:40:13 -07002866 case RESUME_TOP_ACTIVITY_MSG: {
2867 synchronized (mService) {
2868 resumeTopActivitiesLocked();
2869 }
2870 } break;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002871 case SLEEP_TIMEOUT_MSG: {
2872 synchronized (mService) {
2873 if (mService.isSleepingOrShuttingDown()) {
2874 Slog.w(TAG, "Sleep timeout! Sleeping now.");
2875 mSleepTimeout = true;
2876 checkReadyForSleepLocked();
2877 }
2878 }
2879 } break;
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002880 case LAUNCH_TIMEOUT_MSG: {
2881 if (mService.mDidDexOpt) {
2882 mService.mDidDexOpt = false;
2883 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
2884 return;
2885 }
2886 synchronized (mService) {
2887 if (mLaunchingActivity.isHeld()) {
2888 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
2889 if (VALIDATE_WAKE_LOCK_CALLER
2890 && Binder.getCallingUid() != Process.myUid()) {
2891 throw new IllegalStateException("Calling must be system uid");
2892 }
2893 mLaunchingActivity.release();
2894 }
2895 }
2896 } break;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002897 case HANDLE_DISPLAY_ADDED: {
2898 handleDisplayAddedLocked(msg.arg1);
2899 } break;
2900 case HANDLE_DISPLAY_CHANGED: {
2901 handleDisplayChangedLocked(msg.arg1);
2902 } break;
2903 case HANDLE_DISPLAY_REMOVED: {
2904 handleDisplayRemovedLocked(msg.arg1);
2905 } break;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002906 }
2907 }
2908 }
Craig Mautnered6649f2013-12-02 14:08:25 -08002909
Craig Mautner4a1cb222013-12-04 16:14:06 -08002910 class ActivityContainer extends IActivityContainer.Stub {
2911 final int mStackId;
2912 final IActivityContainerCallback mCallback;
2913 final ActivityStack mStack;
2914 final ActivityRecord mParentActivity;
Craig Mautner34b73df2014-01-12 21:11:08 -08002915 final String mIdString;
Craig Mautnered6649f2013-12-02 14:08:25 -08002916
Craig Mautner4a1cb222013-12-04 16:14:06 -08002917 /** Display this ActivityStack is currently on. Null if not attached to a Display. */
Craig Mautnere0a38842013-12-16 16:14:02 -08002918 ActivityDisplay mActivityDisplay;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002919
2920 ActivityContainer(ActivityRecord parentActivity, int stackId,
2921 IActivityContainerCallback callback) {
2922 synchronized (mService) {
2923 mStackId = stackId;
2924 mStack = new ActivityStack(this);
2925 mParentActivity = parentActivity;
2926 mCallback = callback;
Craig Mautner34b73df2014-01-12 21:11:08 -08002927 mIdString = "ActivtyContainer{" + mStackId + ", parent=" + mParentActivity + "}";
2928 if (DEBUG_STACK) Slog.d(TAG, "Creating " + this);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002929 }
Craig Mautnered6649f2013-12-02 14:08:25 -08002930 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002931
Craig Mautnere0a38842013-12-16 16:14:02 -08002932 void attachToDisplayLocked(ActivityDisplay activityDisplay) {
Craig Mautner34b73df2014-01-12 21:11:08 -08002933 if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this
2934 + " to display=" + activityDisplay);
Craig Mautnere0a38842013-12-16 16:14:02 -08002935 mActivityDisplay = activityDisplay;
2936 mStack.mDisplayId = activityDisplay.mDisplayId;
2937 mStack.mStacks = activityDisplay.mStacks;
2938
2939 activityDisplay.attachActivities(mStack);
Craig Mautnerdf88d732014-01-27 09:21:32 -08002940 mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002941 }
2942
2943 @Override
2944 public void attachToDisplay(int displayId) throws RemoteException {
2945 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002946 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2947 if (activityDisplay == null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002948 return;
2949 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002950 attachToDisplayLocked(activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002951 }
2952 }
2953
2954 @Override
Craig Mautnere0a38842013-12-16 16:14:02 -08002955 public int getDisplayId() throws RemoteException {
2956 if (mActivityDisplay != null) {
2957 return mActivityDisplay.mDisplayId;
2958 }
2959 return -1;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002960 }
2961
Craig Mautner34b73df2014-01-12 21:11:08 -08002962 private void detachLocked() {
2963 if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display="
2964 + mActivityDisplay + " Callers=" + Debug.getCallers(2));
Craig Mautnere0a38842013-12-16 16:14:02 -08002965 if (mActivityDisplay != null) {
2966 mActivityDisplay.detachActivitiesLocked(mStack);
2967 mActivityDisplay = null;
2968 mStack.mDisplayId = -1;
2969 mStack.mStacks = null;
Craig Mautnerdf88d732014-01-27 09:21:32 -08002970 mWindowManager.detachStack(mStackId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002971 }
2972 }
2973
2974 @Override
2975 public void detachFromDisplay() throws RemoteException {
2976 synchronized (mService) {
2977 detachLocked();
2978 }
2979 }
2980
2981 @Override
Craig Mautnere0a38842013-12-16 16:14:02 -08002982 public final int startActivity(Intent intent) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08002983 mService.enforceNotIsolatedCaller("ActivityContainer.startActivity");
Craig Mautnere0a38842013-12-16 16:14:02 -08002984 int userId = mService.handleIncomingUser(Binder.getCallingPid(),
2985 Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null);
2986 // TODO: Switch to user app stacks here.
2987 String mimeType = intent.getType();
2988 if (mimeType == null && intent.getData() != null
2989 && "content".equals(intent.getData().getScheme())) {
2990 mimeType = mService.getProviderMimeType(intent.getData(), userId);
2991 }
2992 return startActivityMayWait(null, -1, null, intent, mimeType, null, null, 0, 0, null,
2993 null, null, null, null, userId, this);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002994 }
2995
2996 @Override
Craig Mautnerdf88d732014-01-27 09:21:32 -08002997 public final int startActivityIntentSender(IIntentSender intentSender) {
2998 mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
2999
3000 if (!(intentSender instanceof PendingIntentRecord)) {
3001 throw new IllegalArgumentException("Bad PendingIntent object");
3002 }
3003
3004 return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null,
3005 null, 0, 0, 0, null, this);
3006 }
3007
3008 @Override
Craig Mautner4a1cb222013-12-04 16:14:06 -08003009 public IBinder asBinder() {
3010 return this;
3011 }
3012
Craig Mautner4504de52013-12-20 09:06:56 -08003013 @Override
Craig Mautner34b73df2014-01-12 21:11:08 -08003014 public void attachToSurface(Surface surface, int width, int height, int density) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08003015 mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
3016
3017 final long origId = Binder.clearCallingIdentity();
3018 try {
3019 synchronized (mService) {
3020 ActivityDisplay activityDisplay =
3021 new ActivityDisplay(surface, width, height, density);
3022 mActivityDisplays.put(activityDisplay.mDisplayId, activityDisplay);
3023 attachToDisplayLocked(activityDisplay);
3024 mStack.resumeTopActivityLocked(null);
3025 }
3026 if (DEBUG_STACK) Slog.d(TAG, "attachToSurface: " + this + " to display="
3027 + mActivityDisplay);
3028 } finally {
3029 Binder.restoreCallingIdentity(origId);
Craig Mautner4504de52013-12-20 09:06:56 -08003030 }
Craig Mautner4504de52013-12-20 09:06:56 -08003031 }
3032
Craig Mautner4a1cb222013-12-04 16:14:06 -08003033 ActivityStackSupervisor getOuter() {
3034 return ActivityStackSupervisor.this;
3035 }
3036
3037 boolean isAttached() {
Craig Mautnere0a38842013-12-16 16:14:02 -08003038 return mActivityDisplay != null;
Craig Mautner4a1cb222013-12-04 16:14:06 -08003039 }
3040
3041 void getBounds(Point outBounds) {
Craig Mautnere0a38842013-12-16 16:14:02 -08003042 if (mActivityDisplay != null) {
3043 mActivityDisplay.getBounds(outBounds);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003044 } else {
3045 outBounds.set(0, 0);
3046 }
3047 }
Craig Mautner34b73df2014-01-12 21:11:08 -08003048
3049 @Override
3050 public String toString() {
3051 return mIdString + (mActivityDisplay == null ? "N" : "A");
3052 }
Craig Mautnered6649f2013-12-02 14:08:25 -08003053 }
3054
Craig Mautner4a1cb222013-12-04 16:14:06 -08003055 /** Exactly one of these classes per Display in the system. Capable of holding zero or more
3056 * attached {@link ActivityStack}s */
Craig Mautnere0a38842013-12-16 16:14:02 -08003057 final class ActivityDisplay {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003058 /** Actual Display this object tracks. */
Craig Mautner34b73df2014-01-12 21:11:08 -08003059 int mDisplayId;
3060 Display mDisplay;
3061 DisplayInfo mDisplayInfo = new DisplayInfo();
3062 Surface mSurface;
Craig Mautnered6649f2013-12-02 14:08:25 -08003063
Craig Mautner4a1cb222013-12-04 16:14:06 -08003064 /** All of the stacks on this display. Order matters, topmost stack is in front of all other
3065 * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
Craig Mautnere0a38842013-12-16 16:14:02 -08003066 final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003067
Craig Mautner4504de52013-12-20 09:06:56 -08003068 /** If this display is for an ActivityView then the VirtualDisplay created for it is stored
3069 * here. */
3070 VirtualDisplay mVirtualDisplay;
3071
Craig Mautnere0a38842013-12-16 16:14:02 -08003072 ActivityDisplay(int displayId) {
Craig Mautner34b73df2014-01-12 21:11:08 -08003073 init(mDisplayManager.getDisplay(displayId));
Craig Mautner4504de52013-12-20 09:06:56 -08003074 }
3075
Craig Mautner34b73df2014-01-12 21:11:08 -08003076 ActivityDisplay(Surface surface, int width, int height, int density) {
3077 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
3078 long ident = Binder.clearCallingIdentity();
3079 try {
3080 mVirtualDisplay = dm.createVirtualDisplay(mService.mContext,
3081 VIRTUAL_DISPLAY_BASE_NAME, width, height, density, surface,
3082 DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
3083 DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY);
3084 } finally {
3085 Binder.restoreCallingIdentity(ident);
3086 }
3087
3088 init(mVirtualDisplay.getDisplay());
3089 mSurface = surface;
3090
3091 mWindowManager.handleDisplayAdded(mDisplayId);
3092 }
3093
3094 private void init(Display display) {
Craig Mautner4504de52013-12-20 09:06:56 -08003095 mDisplay = display;
3096 mDisplayId = display.getDisplayId();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003097 mDisplay.getDisplayInfo(mDisplayInfo);
Craig Mautnered6649f2013-12-02 14:08:25 -08003098 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08003099
3100 void attachActivities(ActivityStack stack) {
Craig Mautnere0a38842013-12-16 16:14:02 -08003101 if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId="
3102 + mDisplayId);
3103 mStacks.add(stack);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003104 }
3105
Craig Mautnere0a38842013-12-16 16:14:02 -08003106 void detachActivitiesLocked(ActivityStack stack) {
Craig Mautner34b73df2014-01-12 21:11:08 -08003107 if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack
Craig Mautnere0a38842013-12-16 16:14:02 -08003108 + " from displayId=" + mDisplayId);
3109 mStacks.remove(stack);
Craig Mautner34b73df2014-01-12 21:11:08 -08003110 if (mStacks.isEmpty() && mVirtualDisplay != null) {
3111 mVirtualDisplay.release();
3112 mVirtualDisplay = null;
3113 }
3114 mSurface.release();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003115 }
3116
3117 void getBounds(Point bounds) {
3118 mDisplay.getDisplayInfo(mDisplayInfo);
3119 bounds.x = mDisplayInfo.appWidth;
3120 bounds.y = mDisplayInfo.appHeight;
3121 }
Craig Mautner34b73df2014-01-12 21:11:08 -08003122
3123 @Override
3124 public String toString() {
3125 return "ActivityDisplay={" + mDisplayId + (mVirtualDisplay == null ? "" : "V")
3126 + " numStacks=" + mStacks.size() + "}";
3127 }
Craig Mautnered6649f2013-12-02 14:08:25 -08003128 }
Craig Mautner27084302013-03-25 08:05:25 -07003129}