blob: efa3ad495fcf4d69a57c1da61fc3cab26e019d1b [file] [log] [blame]
Craig Mautner27084302013-03-25 08:05:25 -07001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
Craig Mautner6170f732013-04-02 13:05:23 -070019import static android.Manifest.permission.START_ANY_ACTIVITY;
Craig Mautner29219d92013-04-16 20:19:12 -070020import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
21import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
Craig Mautner6170f732013-04-02 13:05:23 -070022import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Craig Mautner2420ead2013-04-01 17:13:20 -070023import static com.android.server.am.ActivityManagerService.localLOGV;
Craig Mautner23ac33b2013-04-01 16:26:35 -070024import static com.android.server.am.ActivityManagerService.DEBUG_CONFIGURATION;
Craig Mautnere7c58b62013-06-12 20:19:00 -070025import static com.android.server.am.ActivityManagerService.DEBUG_FOCUS;
Craig Mautner0eea92c2013-05-16 13:35:39 -070026import static com.android.server.am.ActivityManagerService.DEBUG_PAUSE;
Craig Mautner6170f732013-04-02 13:05:23 -070027import static com.android.server.am.ActivityManagerService.DEBUG_RESULTS;
Craig Mautner0eea92c2013-05-16 13:35:39 -070028import static com.android.server.am.ActivityManagerService.DEBUG_STACK;
Craig Mautner2420ead2013-04-01 17:13:20 -070029import static com.android.server.am.ActivityManagerService.DEBUG_SWITCH;
Craig Mautner8849a5e2013-04-02 16:41:03 -070030import static com.android.server.am.ActivityManagerService.DEBUG_TASKS;
31import static com.android.server.am.ActivityManagerService.DEBUG_USER_LEAVING;
Craig Mautner05d29032013-05-03 13:40:13 -070032import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
Craig Mautner8d341ef2013-03-26 09:03:27 -070033import static com.android.server.am.ActivityManagerService.TAG;
34
Craig Mautner2420ead2013-04-01 17:13:20 -070035import android.app.Activity;
Craig Mautner23ac33b2013-04-01 16:26:35 -070036import android.app.ActivityManager;
Craig Mautnerbdc748af2013-12-02 14:08:25 -080037import android.app.ActivityManager.StackInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070038import android.app.ActivityOptions;
39import android.app.AppGlobals;
Craig Mautner4a1cb222013-12-04 16:14:06 -080040import android.app.IActivityContainer;
41import android.app.IActivityContainerCallback;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070042import android.app.IActivityManager;
Craig Mautner23ac33b2013-04-01 16:26:35 -070043import android.app.IApplicationThread;
Craig Mautner20e72272013-04-01 13:45:53 -070044import android.app.IThumbnailReceiver;
Craig Mautner23ac33b2013-04-01 16:26:35 -070045import android.app.PendingIntent;
Craig Mautner20e72272013-04-01 13:45:53 -070046import android.app.ActivityManager.RunningTaskInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070047import android.app.IActivityManager.WaitResult;
Craig Mautner2420ead2013-04-01 17:13:20 -070048import android.app.ResultInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070049import android.content.ComponentName;
Craig Mautner2219a1b2013-03-25 09:44:30 -070050import android.content.Context;
Craig Mautner23ac33b2013-04-01 16:26:35 -070051import android.content.IIntentSender;
Craig Mautner2219a1b2013-03-25 09:44:30 -070052import android.content.Intent;
Craig Mautner23ac33b2013-04-01 16:26:35 -070053import android.content.IntentSender;
Craig Mautner2219a1b2013-03-25 09:44:30 -070054import android.content.pm.ActivityInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070055import android.content.pm.ApplicationInfo;
56import android.content.pm.PackageManager;
57import android.content.pm.ResolveInfo;
58import android.content.res.Configuration;
Craig Mautner4a1cb222013-12-04 16:14:06 -080059import android.graphics.Point;
60import android.hardware.display.DisplayManager;
61import android.hardware.display.DisplayManager.DisplayListener;
Craig Mautner4504de52013-12-20 09:06:56 -080062import android.hardware.display.DisplayManagerGlobal;
63import android.hardware.display.VirtualDisplay;
Jeff Brown38f96e52014-02-11 14:32:56 -080064import android.hardware.input.InputManager;
65import android.hardware.input.InputManagerInternal;
Craig Mautner23ac33b2013-04-01 16:26:35 -070066import android.os.Binder;
Craig Mautner8d341ef2013-03-26 09:03:27 -070067import android.os.Bundle;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -070068import android.os.Debug;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070069import android.os.Handler;
Craig Mautner23ac33b2013-04-01 16:26:35 -070070import android.os.IBinder;
Craig Mautner2219a1b2013-03-25 09:44:30 -070071import android.os.Looper;
Craig Mautner2420ead2013-04-01 17:13:20 -070072import android.os.Message;
Craig Mautner23ac33b2013-04-01 16:26:35 -070073import android.os.ParcelFileDescriptor;
Craig Mautner0eea92c2013-05-16 13:35:39 -070074import android.os.PowerManager;
Craig Mautner7ea5bd42013-07-05 15:27:08 -070075import android.os.Process;
Craig Mautner8d341ef2013-03-26 09:03:27 -070076import android.os.RemoteException;
Craig Mautner23ac33b2013-04-01 16:26:35 -070077import android.os.SystemClock;
Craig Mautner6170f732013-04-02 13:05:23 -070078import android.os.UserHandle;
Craig Mautner2420ead2013-04-01 17:13:20 -070079import android.util.EventLog;
Craig Mautner8d341ef2013-03-26 09:03:27 -070080import android.util.Slog;
Craig Mautner4a1cb222013-12-04 16:14:06 -080081import android.util.SparseArray;
Craig Mautner2219a1b2013-03-25 09:44:30 -070082
Craig Mautner4a1cb222013-12-04 16:14:06 -080083import android.util.SparseIntArray;
Craig Mautnerbdc748af2013-12-02 14:08:25 -080084import android.view.Display;
Craig Mautner4a1cb222013-12-04 16:14:06 -080085import android.view.DisplayInfo;
Jeff Brown38f96e52014-02-11 14:32:56 -080086import android.view.InputEvent;
Craig Mautner4504de52013-12-20 09:06:56 -080087import android.view.Surface;
Craig Mautner23ac33b2013-04-01 16:26:35 -070088import com.android.internal.app.HeavyWeightSwitcherActivity;
Dianne Hackborncbfd23e2013-06-11 14:26:53 -070089import com.android.internal.os.TransferPipe;
Jeff Brown38f96e52014-02-11 14:32:56 -080090import com.android.server.LocalServices;
Craig Mautner6170f732013-04-02 13:05:23 -070091import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
Craig Mautner2420ead2013-04-01 17:13:20 -070092import com.android.server.am.ActivityStack.ActivityState;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070093import com.android.server.wm.WindowManagerService;
Craig Mautner23ac33b2013-04-01 16:26:35 -070094
Craig Mautner8d341ef2013-03-26 09:03:27 -070095import java.io.FileDescriptor;
96import java.io.IOException;
Craig Mautner27084302013-03-25 08:05:25 -070097import java.io.PrintWriter;
Craig Mautner4504de52013-12-20 09:06:56 -080098import java.lang.ref.WeakReference;
Craig Mautner2219a1b2013-03-25 09:44:30 -070099import java.util.ArrayList;
Craig Mautner8d341ef2013-03-26 09:03:27 -0700100import java.util.List;
Craig Mautner27084302013-03-25 08:05:25 -0700101
Craig Mautner4a1cb222013-12-04 16:14:06 -0800102public final class ActivityStackSupervisor implements DisplayListener {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700103 static final boolean DEBUG = ActivityManagerService.DEBUG || false;
104 static final boolean DEBUG_ADD_REMOVE = DEBUG || false;
105 static final boolean DEBUG_APP = DEBUG || false;
106 static final boolean DEBUG_SAVED_STATE = DEBUG || false;
Craig Mautnera7f2bd42013-10-15 16:13:50 -0700107 static final boolean DEBUG_STATES = DEBUG || false;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -0700108 static final boolean DEBUG_IDLE = DEBUG || false;
Craig Mautner2420ead2013-04-01 17:13:20 -0700109
Craig Mautner2219a1b2013-03-25 09:44:30 -0700110 public static final int HOME_STACK_ID = 0;
Craig Mautner27084302013-03-25 08:05:25 -0700111
Craig Mautnerf3333272013-04-22 10:55:53 -0700112 /** How long we wait until giving up on the last activity telling us it is idle. */
113 static final int IDLE_TIMEOUT = 10*1000;
114
Craig Mautner0eea92c2013-05-16 13:35:39 -0700115 /** How long we can hold the sleep wake lock before giving up. */
116 static final int SLEEP_TIMEOUT = 5*1000;
117
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700118 // How long we can hold the launch wake lock before giving up.
119 static final int LAUNCH_TIMEOUT = 10*1000;
120
Craig Mautner05d29032013-05-03 13:40:13 -0700121 static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG;
122 static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1;
123 static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2;
Craig Mautner0eea92c2013-05-16 13:35:39 -0700124 static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3;
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700125 static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800126 static final int HANDLE_DISPLAY_ADDED = FIRST_SUPERVISOR_STACK_MSG + 5;
127 static final int HANDLE_DISPLAY_CHANGED = FIRST_SUPERVISOR_STACK_MSG + 6;
128 static final int HANDLE_DISPLAY_REMOVED = FIRST_SUPERVISOR_STACK_MSG + 7;
Craig Mautnere3a00d72014-04-16 08:31:19 -0700129 static final int CONTAINER_CALLBACK_VISIBILITY = FIRST_SUPERVISOR_STACK_MSG + 8;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800130
Craig Mautner4504de52013-12-20 09:06:56 -0800131 private final static String VIRTUAL_DISPLAY_BASE_NAME = "ActivityViewVirtualDisplay";
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700132
133 // For debugging to make sure the caller when acquiring/releasing our
134 // wake lock is the system process.
135 static final boolean VALIDATE_WAKE_LOCK_CALLER = false;
Craig Mautnerf3333272013-04-22 10:55:53 -0700136
Craig Mautner27084302013-03-25 08:05:25 -0700137 final ActivityManagerService mService;
138
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700139 final ActivityStackSupervisorHandler mHandler;
140
141 /** Short cut */
142 WindowManagerService mWindowManager;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800143 DisplayManager mDisplayManager;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700144
Craig Mautner27084302013-03-25 08:05:25 -0700145 /** Dismiss the keyguard after the next activity is displayed? */
Craig Mautner5314a402013-09-26 12:40:16 -0700146 boolean mDismissKeyguardOnNextActivity = false;
Craig Mautner27084302013-03-25 08:05:25 -0700147
Craig Mautner8d341ef2013-03-26 09:03:27 -0700148 /** Identifier counter for all ActivityStacks */
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -0700149 private int mLastStackId = HOME_STACK_ID;
Craig Mautner8d341ef2013-03-26 09:03:27 -0700150
151 /** Task identifier that activities are currently being started in. Incremented each time a
152 * new task is created. */
153 private int mCurTaskId = 0;
154
Craig Mautner2420ead2013-04-01 17:13:20 -0700155 /** The current user */
156 private int mCurrentUser;
157
Craig Mautnere0a38842013-12-16 16:14:02 -0800158 /** The stack containing the launcher app. Assumed to always be attached to
159 * Display.DEFAULT_DISPLAY. */
Craig Mautner2219a1b2013-03-25 09:44:30 -0700160 private ActivityStack mHomeStack;
Craig Mautner20e72272013-04-01 13:45:53 -0700161
Craig Mautnere0a38842013-12-16 16:14:02 -0800162 /** The stack currently receiving input or launching the next activity. */
Craig Mautner29219d92013-04-16 20:19:12 -0700163 private ActivityStack mFocusedStack;
Craig Mautner8d341ef2013-03-26 09:03:27 -0700164
Craig Mautner4a1cb222013-12-04 16:14:06 -0800165 /** If this is the same as mFocusedStack then the activity on the top of the focused stack has
166 * been resumed. If stacks are changing position this will hold the old stack until the new
Craig Mautnere0a38842013-12-16 16:14:02 -0800167 * stack becomes resumed after which it will be set to mFocusedStack. */
Craig Mautner4a1cb222013-12-04 16:14:06 -0800168 private ActivityStack mLastFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700169
170 /** List of activities that are waiting for a new activity to become visible before completing
171 * whatever operation they are supposed to do. */
172 final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<ActivityRecord>();
173
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700174 /** List of processes waiting to find out about the next visible activity. */
175 final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible =
176 new ArrayList<IActivityManager.WaitResult>();
177
178 /** List of processes waiting to find out about the next launched activity. */
179 final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched =
180 new ArrayList<IActivityManager.WaitResult>();
181
Craig Mautnerde4ef022013-04-07 19:01:33 -0700182 /** List of activities that are ready to be stopped, but waiting for the next activity to
183 * settle down before doing so. */
184 final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<ActivityRecord>();
185
Craig Mautnerf3333272013-04-22 10:55:53 -0700186 /** List of activities that are ready to be finished, but waiting for the previous activity to
187 * settle down before doing so. It contains ActivityRecord objects. */
188 final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<ActivityRecord>();
189
Craig Mautner0eea92c2013-05-16 13:35:39 -0700190 /** List of activities that are in the process of going to sleep. */
191 final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<ActivityRecord>();
192
Craig Mautnerf3333272013-04-22 10:55:53 -0700193 /** List of ActivityRecord objects that have been finished and must still report back to a
194 * pending thumbnail receiver. */
195 final ArrayList<ActivityRecord> mCancelledThumbnails = new ArrayList<ActivityRecord>();
196
197 /** Used on user changes */
198 final ArrayList<UserStartedState> mStartingUsers = new ArrayList<UserStartedState>();
199
Craig Mautnerde4ef022013-04-07 19:01:33 -0700200 /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity
201 * is being brought in front of us. */
202 boolean mUserLeaving = false;
203
Craig Mautner0eea92c2013-05-16 13:35:39 -0700204 /** Set when we have taken too long waiting to go to sleep. */
205 boolean mSleepTimeout = false;
206
207 /**
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700208 * We don't want to allow the device to go to sleep while in the process
209 * of launching an activity. This is primarily to allow alarm intent
210 * receivers to launch an activity and get that to run before the device
211 * goes back to sleep.
212 */
213 final PowerManager.WakeLock mLaunchingActivity;
214
215 /**
Craig Mautner0eea92c2013-05-16 13:35:39 -0700216 * Set when the system is going to sleep, until we have
217 * successfully paused the current activity and released our wake lock.
218 * At that point the system is allowed to actually sleep.
219 */
220 final PowerManager.WakeLock mGoingToSleep;
221
Craig Mautner4f1df4f2013-10-15 15:44:14 -0700222 /** Stack id of the front stack when user switched, indexed by userId. */
223 SparseIntArray mUserStackInFront = new SparseIntArray(2);
Craig Mautner93529a42013-10-04 15:03:13 -0700224
Craig Mautner4504de52013-12-20 09:06:56 -0800225 // TODO: Add listener for removal of references.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800226 /** Mapping from (ActivityStack/TaskStack).mStackId to their current state */
Craig Mautner4504de52013-12-20 09:06:56 -0800227 SparseArray<WeakReference<ActivityContainer>> mActivityContainers =
228 new SparseArray<WeakReference<ActivityContainer>>();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800229
230 /** Mapping from displayId to display current state */
Craig Mautner4504de52013-12-20 09:06:56 -0800231 private SparseArray<ActivityDisplay> mActivityDisplays = new SparseArray<ActivityDisplay>();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800232
Jeff Brown38f96e52014-02-11 14:32:56 -0800233 InputManagerInternal mInputManagerInternal;
234
Craig Mautner4a1cb222013-12-04 16:14:06 -0800235 public ActivityStackSupervisor(ActivityManagerService service) {
Craig Mautner27084302013-03-25 08:05:25 -0700236 mService = service;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800237 PowerManager pm = (PowerManager)mService.mContext.getSystemService(Context.POWER_SERVICE);
Craig Mautner0eea92c2013-05-16 13:35:39 -0700238 mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
Craig Mautner4a1cb222013-12-04 16:14:06 -0800239 mHandler = new ActivityStackSupervisorHandler(mService.mHandler.getLooper());
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700240 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
241 throw new IllegalStateException("Calling must be system uid");
242 }
243 mLaunchingActivity =
244 pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
245 mLaunchingActivity.setReferenceCounted(false);
Craig Mautner2219a1b2013-03-25 09:44:30 -0700246 }
247
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700248 void setWindowManager(WindowManagerService wm) {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800249 synchronized (mService) {
250 mWindowManager = wm;
251
252 mDisplayManager =
253 (DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE);
254 mDisplayManager.registerDisplayListener(this, null);
255
256 Display[] displays = mDisplayManager.getDisplays();
257 for (int displayNdx = displays.length - 1; displayNdx >= 0; --displayNdx) {
258 final int displayId = displays[displayNdx].getDisplayId();
Craig Mautnere0a38842013-12-16 16:14:02 -0800259 ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
260 mActivityDisplays.put(displayId, activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -0800261 }
262
263 createStackOnDisplay(null, HOME_STACK_ID, Display.DEFAULT_DISPLAY);
264 mHomeStack = mFocusedStack = mLastFocusedStack = getStack(HOME_STACK_ID);
Jeff Brown38f96e52014-02-11 14:32:56 -0800265
266 mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
Craig Mautner4a1cb222013-12-04 16:14:06 -0800267 }
Craig Mautner27084302013-03-25 08:05:25 -0700268 }
269
270 void dismissKeyguard() {
Craig Mautner5314a402013-09-26 12:40:16 -0700271 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen("");
Craig Mautner27084302013-03-25 08:05:25 -0700272 if (mDismissKeyguardOnNextActivity) {
273 mDismissKeyguardOnNextActivity = false;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700274 mWindowManager.dismissKeyguard();
Craig Mautner27084302013-03-25 08:05:25 -0700275 }
276 }
277
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700278 ActivityStack getFocusedStack() {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800279 return mFocusedStack;
Craig Mautner20e72272013-04-01 13:45:53 -0700280 }
281
Craig Mautnerde4ef022013-04-07 19:01:33 -0700282 ActivityStack getLastStack() {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800283 return mLastFocusedStack;
Craig Mautner2219a1b2013-03-25 09:44:30 -0700284 }
285
Craig Mautner4a1cb222013-12-04 16:14:06 -0800286 // TODO: Split into two methods isFrontStack for any visible stack and isFrontmostStack for the
287 // top of all visible stacks.
Craig Mautnerde4ef022013-04-07 19:01:33 -0700288 boolean isFrontStack(ActivityStack stack) {
Craig Mautnerdf88d732014-01-27 09:21:32 -0800289 final ActivityRecord parent = stack.mActivityContainer.mParentActivity;
290 if (parent != null) {
291 stack = parent.task.stack;
292 }
Craig Mautnere0a38842013-12-16 16:14:02 -0800293 ArrayList<ActivityStack> stacks = stack.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800294 if (stacks != null && !stacks.isEmpty()) {
295 return stack == stacks.get(stacks.size() - 1);
296 }
297 return false;
Craig Mautner20e72272013-04-01 13:45:53 -0700298 }
299
Craig Mautnerde4ef022013-04-07 19:01:33 -0700300 void moveHomeStack(boolean toFront) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800301 ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800302 int topNdx = stacks.size() - 1;
303 if (topNdx <= 0) {
304 return;
305 }
306 ActivityStack topStack = stacks.get(topNdx);
307 final boolean homeInFront = topStack == mHomeStack;
308 if (homeInFront != toFront) {
309 mLastFocusedStack = topStack;
310 stacks.remove(mHomeStack);
311 stacks.add(toFront ? topNdx : 0, mHomeStack);
312 mFocusedStack = stacks.get(topNdx);
313 if (DEBUG_STACK) Slog.d(TAG, "moveHomeTask: topStack old=" + topStack + " new="
314 + mFocusedStack);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700315 }
316 }
317
Craig Mautner8e569572013-10-11 17:36:59 -0700318 void moveHomeToTop() {
Craig Mautner69ada552013-04-18 13:51:51 -0700319 moveHomeStack(true);
Craig Mautner8e569572013-10-11 17:36:59 -0700320 mHomeStack.moveHomeTaskToTop();
321 }
322
323 boolean resumeHomeActivity(ActivityRecord prev) {
324 moveHomeToTop();
Craig Mautner69ada552013-04-18 13:51:51 -0700325 if (prev != null) {
Craig Mautnerae7ecab2013-09-18 11:48:14 -0700326 prev.task.mOnTopOfHome = false;
Craig Mautner69ada552013-04-18 13:51:51 -0700327 }
Craig Mautnera8a90e02013-06-28 15:24:50 -0700328 ActivityRecord r = mHomeStack.topRunningActivityLocked(null);
Craig Mautner760b2312013-10-11 11:57:07 -0700329 if (r != null && r.isHomeActivity()) {
Craig Mautnera8a90e02013-06-28 15:24:50 -0700330 mService.setFocusedActivityLocked(r);
Craig Mautner05d29032013-05-03 13:40:13 -0700331 return resumeTopActivitiesLocked(mHomeStack, prev, null);
Craig Mautner69ada552013-04-18 13:51:51 -0700332 }
333 return mService.startHomeActivityLocked(mCurrentUser);
334 }
335
Craig Mautner27084302013-03-25 08:05:25 -0700336 void setDismissKeyguard(boolean dismiss) {
Craig Mautner5314a402013-09-26 12:40:16 -0700337 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen(" dismiss=" + dismiss);
Craig Mautner27084302013-03-25 08:05:25 -0700338 mDismissKeyguardOnNextActivity = dismiss;
339 }
340
Craig Mautner8d341ef2013-03-26 09:03:27 -0700341 TaskRecord anyTaskForIdLocked(int id) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800342 int numDisplays = mActivityDisplays.size();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800343 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800344 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800345 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
346 ActivityStack stack = stacks.get(stackNdx);
347 TaskRecord task = stack.taskForIdLocked(id);
348 if (task != null) {
349 return task;
350 }
Craig Mautner8d341ef2013-03-26 09:03:27 -0700351 }
352 }
353 return null;
354 }
355
Craig Mautner6170f732013-04-02 13:05:23 -0700356 ActivityRecord isInAnyStackLocked(IBinder token) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800357 int numDisplays = mActivityDisplays.size();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800358 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800359 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800360 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
361 final ActivityRecord r = stacks.get(stackNdx).isInStackLocked(token);
362 if (r != null) {
363 return r;
364 }
Craig Mautner6170f732013-04-02 13:05:23 -0700365 }
366 }
367 return null;
368 }
369
Craig Mautner8d341ef2013-03-26 09:03:27 -0700370 int getNextTaskId() {
371 do {
372 mCurTaskId++;
373 if (mCurTaskId <= 0) {
374 mCurTaskId = 1;
375 }
376 } while (anyTaskForIdLocked(mCurTaskId) != null);
377 return mCurTaskId;
378 }
379
Craig Mautnerde4ef022013-04-07 19:01:33 -0700380 ActivityRecord resumedAppLocked() {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700381 ActivityStack stack = getFocusedStack();
382 if (stack == null) {
383 return null;
384 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700385 ActivityRecord resumedActivity = stack.mResumedActivity;
386 if (resumedActivity == null || resumedActivity.app == null) {
387 resumedActivity = stack.mPausingActivity;
388 if (resumedActivity == null || resumedActivity.app == null) {
389 resumedActivity = stack.topRunningActivityLocked(null);
390 }
391 }
392 return resumedActivity;
393 }
394
Mike Lockwoode63f6f72013-11-15 11:01:47 -0800395 boolean attachApplicationLocked(ProcessRecord app) throws Exception {
Craig Mautner20e72272013-04-01 13:45:53 -0700396 final String processName = app.processName;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800397 boolean didSomething = false;
Craig Mautnere0a38842013-12-16 16:14:02 -0800398 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
399 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800400 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
401 final ActivityStack stack = stacks.get(stackNdx);
402 if (!isFrontStack(stack)) {
403 continue;
404 }
405 ActivityRecord hr = stack.topRunningActivityLocked(null);
406 if (hr != null) {
407 if (hr.app == null && app.uid == hr.info.applicationInfo.uid
408 && processName.equals(hr.processName)) {
409 try {
410 if (realStartActivityLocked(hr, app, true, true)) {
411 didSomething = true;
412 }
413 } catch (Exception e) {
414 Slog.w(TAG, "Exception in new application when starting activity "
415 + hr.intent.getComponent().flattenToShortString(), e);
416 throw e;
Craig Mautner20e72272013-04-01 13:45:53 -0700417 }
Craig Mautner20e72272013-04-01 13:45:53 -0700418 }
Craig Mautner20e72272013-04-01 13:45:53 -0700419 }
420 }
421 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -0700422 if (!didSomething) {
423 ensureActivitiesVisibleLocked(null, 0);
424 }
Craig Mautner20e72272013-04-01 13:45:53 -0700425 return didSomething;
426 }
427
428 boolean allResumedActivitiesIdle() {
Craig Mautnere0a38842013-12-16 16:14:02 -0800429 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
430 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800431 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
432 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautner34b73df2014-01-12 21:11:08 -0800433 if (!isFrontStack(stack) || stack.numActivities() == 0) {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800434 continue;
435 }
436 final ActivityRecord resumedActivity = stack.mResumedActivity;
437 if (resumedActivity == null || !resumedActivity.idle) {
Craig Mautner34b73df2014-01-12 21:11:08 -0800438 if (DEBUG_STATES) Slog.d(TAG, "allResumedActivitiesIdle: stack="
439 + stack.mStackId + " " + resumedActivity + " not idle");
Craig Mautner4a1cb222013-12-04 16:14:06 -0800440 return false;
441 }
Craig Mautner20e72272013-04-01 13:45:53 -0700442 }
443 }
444 return true;
445 }
446
Craig Mautnerde4ef022013-04-07 19:01:33 -0700447 boolean allResumedActivitiesComplete() {
Craig Mautnere0a38842013-12-16 16:14:02 -0800448 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
449 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800450 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
451 final ActivityStack stack = stacks.get(stackNdx);
452 if (isFrontStack(stack)) {
453 final ActivityRecord r = stack.mResumedActivity;
454 if (r != null && r.state != ActivityState.RESUMED) {
455 return false;
456 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700457 }
458 }
459 }
460 // TODO: Not sure if this should check if all Paused are complete too.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800461 if (DEBUG_STACK) Slog.d(TAG,
462 "allResumedActivitiesComplete: mLastFocusedStack changing from=" +
463 mLastFocusedStack + " to=" + mFocusedStack);
464 mLastFocusedStack = mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700465 return true;
466 }
467
468 boolean allResumedActivitiesVisible() {
Craig Mautnere0a38842013-12-16 16:14:02 -0800469 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
470 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800471 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
472 final ActivityStack stack = stacks.get(stackNdx);
473 final ActivityRecord r = stack.mResumedActivity;
474 if (r != null && (!r.nowVisible || r.waitingVisible)) {
475 return false;
476 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700477 }
478 }
479 return true;
480 }
481
Craig Mautner2acc3892013-09-23 10:28:14 -0700482 /**
483 * Pause all activities in either all of the stacks or just the back stacks.
484 * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving().
Craig Mautner2acc3892013-09-23 10:28:14 -0700485 * @return true if any activity was paused as a result of this call.
486 */
Craig Mautner5314a402013-09-26 12:40:16 -0700487 boolean pauseBackStacks(boolean userLeaving) {
Craig Mautnercf910b02013-04-23 11:23:27 -0700488 boolean someActivityPaused = false;
Craig Mautnere0a38842013-12-16 16:14:02 -0800489 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
490 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800491 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
492 final ActivityStack stack = stacks.get(stackNdx);
493 if (!isFrontStack(stack) && stack.mResumedActivity != null) {
494 if (DEBUG_STATES) Slog.d(TAG, "pauseBackStacks: stack=" + stack +
495 " mResumedActivity=" + stack.mResumedActivity);
496 stack.startPausingLocked(userLeaving, false);
497 someActivityPaused = true;
498 }
Craig Mautnercf910b02013-04-23 11:23:27 -0700499 }
500 }
501 return someActivityPaused;
502 }
503
Craig Mautnerde4ef022013-04-07 19:01:33 -0700504 boolean allPausedActivitiesComplete() {
Craig Mautnerac6f8432013-07-17 13:24:59 -0700505 boolean pausing = true;
Craig Mautnere0a38842013-12-16 16:14:02 -0800506 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
507 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800508 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
509 final ActivityStack stack = stacks.get(stackNdx);
510 final ActivityRecord r = stack.mPausingActivity;
511 if (r != null && r.state != ActivityState.PAUSED
512 && r.state != ActivityState.STOPPED
513 && r.state != ActivityState.STOPPING) {
514 if (DEBUG_STATES) {
515 Slog.d(TAG, "allPausedActivitiesComplete: r=" + r + " state=" + r.state);
516 pausing = false;
517 } else {
518 return false;
519 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700520 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700521 }
522 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700523 return pausing;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700524 }
525
Craig Mautnerdf88d732014-01-27 09:21:32 -0800526 void pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping) {
527 // TODO: Put all stacks in supervisor and iterate through them instead.
528 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
529 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
530 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
531 final ActivityStack stack = stacks.get(stackNdx);
532 if (stack.mResumedActivity != null &&
533 stack.mActivityContainer.mParentActivity == parent) {
534 stack.startPausingLocked(userLeaving, uiSleeping);
535 }
536 }
537 }
538 }
539
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700540 void reportActivityVisibleLocked(ActivityRecord r) {
Craig Mautner858d8a62013-04-23 17:08:34 -0700541 for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700542 WaitResult w = mWaitingActivityVisible.get(i);
543 w.timeout = false;
544 if (r != null) {
545 w.who = new ComponentName(r.info.packageName, r.info.name);
546 }
547 w.totalTime = SystemClock.uptimeMillis() - w.thisTime;
548 w.thisTime = w.totalTime;
549 }
550 mService.notifyAll();
551 dismissKeyguard();
552 }
553
554 void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r,
555 long thisTime, long totalTime) {
556 for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
Craig Mautnerc64f73e2013-04-24 16:44:56 -0700557 WaitResult w = mWaitingActivityLaunched.remove(i);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700558 w.timeout = timeout;
559 if (r != null) {
560 w.who = new ComponentName(r.info.packageName, r.info.name);
561 }
562 w.thisTime = thisTime;
563 w.totalTime = totalTime;
564 }
565 mService.notifyAll();
566 }
567
Craig Mautner29219d92013-04-16 20:19:12 -0700568 ActivityRecord topRunningActivityLocked() {
Craig Mautner1602ec22013-05-12 10:24:27 -0700569 final ActivityStack focusedStack = getFocusedStack();
570 ActivityRecord r = focusedStack.topRunningActivityLocked(null);
571 if (r != null) {
572 return r;
Craig Mautner29219d92013-04-16 20:19:12 -0700573 }
Craig Mautner1602ec22013-05-12 10:24:27 -0700574
Craig Mautner4a1cb222013-12-04 16:14:06 -0800575 // Return to the home stack.
Craig Mautnere0a38842013-12-16 16:14:02 -0800576 final ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800577 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
578 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautnerac6f8432013-07-17 13:24:59 -0700579 if (stack != focusedStack && isFrontStack(stack)) {
Craig Mautner29219d92013-04-16 20:19:12 -0700580 r = stack.topRunningActivityLocked(null);
581 if (r != null) {
582 return r;
583 }
584 }
585 }
586 return null;
587 }
588
Craig Mautner20e72272013-04-01 13:45:53 -0700589 ActivityRecord getTasksLocked(int maxNum, IThumbnailReceiver receiver,
590 PendingThumbnailsRecord pending, List<RunningTaskInfo> list) {
591 ActivityRecord r = null;
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700592
593 // Gather all of the running tasks for each stack into runningTaskLists.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800594 ArrayList<ArrayList<RunningTaskInfo>> runningTaskLists =
595 new ArrayList<ArrayList<RunningTaskInfo>>();
Craig Mautnere0a38842013-12-16 16:14:02 -0800596 final int numDisplays = mActivityDisplays.size();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800597 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800598 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800599 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
600 final ActivityStack stack = stacks.get(stackNdx);
601 ArrayList<RunningTaskInfo> stackTaskList = new ArrayList<RunningTaskInfo>();
602 runningTaskLists.add(stackTaskList);
603 final ActivityRecord ar = stack.getTasksLocked(receiver, pending, stackTaskList);
604 if (r == null && isFrontStack(stack)) {
605 r = ar;
606 }
Craig Mautner20e72272013-04-01 13:45:53 -0700607 }
608 }
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700609
610 // The lists are already sorted from most recent to oldest. Just pull the most recent off
611 // each list and add it to list. Stop when all lists are empty or maxNum reached.
612 while (maxNum > 0) {
613 long mostRecentActiveTime = Long.MIN_VALUE;
614 ArrayList<RunningTaskInfo> selectedStackList = null;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800615 final int numTaskLists = runningTaskLists.size();
616 for (int stackNdx = 0; stackNdx < numTaskLists; ++stackNdx) {
617 ArrayList<RunningTaskInfo> stackTaskList = runningTaskLists.get(stackNdx);
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700618 if (!stackTaskList.isEmpty()) {
619 final long lastActiveTime = stackTaskList.get(0).lastActiveTime;
620 if (lastActiveTime > mostRecentActiveTime) {
621 mostRecentActiveTime = lastActiveTime;
622 selectedStackList = stackTaskList;
623 }
624 }
625 }
626 if (selectedStackList != null) {
627 list.add(selectedStackList.remove(0));
628 --maxNum;
629 } else {
630 break;
631 }
632 }
633
Craig Mautner20e72272013-04-01 13:45:53 -0700634 return r;
635 }
636
Craig Mautner23ac33b2013-04-01 16:26:35 -0700637 ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
638 String profileFile, ParcelFileDescriptor profileFd, int userId) {
639 // Collect information about the target of the Intent.
640 ActivityInfo aInfo;
641 try {
642 ResolveInfo rInfo =
643 AppGlobals.getPackageManager().resolveIntent(
644 intent, resolvedType,
645 PackageManager.MATCH_DEFAULT_ONLY
646 | ActivityManagerService.STOCK_PM_FLAGS, userId);
647 aInfo = rInfo != null ? rInfo.activityInfo : null;
648 } catch (RemoteException e) {
649 aInfo = null;
650 }
651
652 if (aInfo != null) {
653 // Store the found target back into the intent, because now that
654 // we have it we never want to do this again. For example, if the
655 // user navigates back to this point in the history, we should
656 // always restart the exact same activity.
657 intent.setComponent(new ComponentName(
658 aInfo.applicationInfo.packageName, aInfo.name));
659
660 // Don't debug things in the system process
661 if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) {
662 if (!aInfo.processName.equals("system")) {
663 mService.setDebugApp(aInfo.processName, true, false);
664 }
665 }
666
667 if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) {
668 if (!aInfo.processName.equals("system")) {
669 mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName);
670 }
671 }
672
673 if (profileFile != null) {
674 if (!aInfo.processName.equals("system")) {
675 mService.setProfileApp(aInfo.applicationInfo, aInfo.processName,
676 profileFile, profileFd,
677 (startFlags&ActivityManager.START_FLAG_AUTO_STOP_PROFILER) != 0);
678 }
679 }
680 }
681 return aInfo;
682 }
683
Craig Mautner2219a1b2013-03-25 09:44:30 -0700684 void startHomeActivity(Intent intent, ActivityInfo aInfo) {
Craig Mautner8e569572013-10-11 17:36:59 -0700685 moveHomeToTop();
Craig Mautner6170f732013-04-02 13:05:23 -0700686 startActivityLocked(null, intent, null, aInfo, null, null, 0, 0, 0, null, 0,
Craig Mautnere0a38842013-12-16 16:14:02 -0800687 null, false, null, null);
Craig Mautner8d341ef2013-03-26 09:03:27 -0700688 }
689
Craig Mautner23ac33b2013-04-01 16:26:35 -0700690 final int startActivityMayWait(IApplicationThread caller, int callingUid,
691 String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
692 String resultWho, int requestCode, int startFlags, String profileFile,
693 ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config,
Craig Mautnere0a38842013-12-16 16:14:02 -0800694 Bundle options, int userId, IActivityContainer iContainer) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700695 // Refuse possible leaked file descriptors
696 if (intent != null && intent.hasFileDescriptors()) {
697 throw new IllegalArgumentException("File descriptors passed in Intent");
698 }
699 boolean componentSpecified = intent.getComponent() != null;
700
701 // Don't modify the client's object!
702 intent = new Intent(intent);
703
704 // Collect information about the target of the Intent.
705 ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
706 profileFile, profileFd, userId);
707
Craig Mautnere0a38842013-12-16 16:14:02 -0800708 ActivityContainer container = (ActivityContainer)iContainer;
Craig Mautner23ac33b2013-04-01 16:26:35 -0700709 synchronized (mService) {
710 int callingPid;
711 if (callingUid >= 0) {
712 callingPid = -1;
713 } else if (caller == null) {
714 callingPid = Binder.getCallingPid();
715 callingUid = Binder.getCallingUid();
716 } else {
717 callingPid = callingUid = -1;
718 }
719
Craig Mautnere0a38842013-12-16 16:14:02 -0800720 final ActivityStack stack;
721 if (container == null || container.mStack.isOnHomeDisplay()) {
722 stack = getFocusedStack();
723 } else {
724 stack = container.mStack;
725 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700726 stack.mConfigWillChange = config != null
Craig Mautner23ac33b2013-04-01 16:26:35 -0700727 && mService.mConfiguration.diff(config) != 0;
728 if (DEBUG_CONFIGURATION) Slog.v(TAG,
Craig Mautnerde4ef022013-04-07 19:01:33 -0700729 "Starting activity when config will change = " + stack.mConfigWillChange);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700730
731 final long origId = Binder.clearCallingIdentity();
732
733 if (aInfo != null &&
734 (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
735 // This may be a heavy-weight process! Check to see if we already
736 // have another, different heavy-weight process running.
737 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
738 if (mService.mHeavyWeightProcess != null &&
739 (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid ||
740 !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700741 int realCallingUid = callingUid;
742 if (caller != null) {
743 ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
744 if (callerApp != null) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700745 realCallingUid = callerApp.info.uid;
746 } else {
747 Slog.w(TAG, "Unable to find app for caller " + caller
Craig Mautner76ea2242013-05-15 11:40:05 -0700748 + " (pid=" + callingPid + ") when starting: "
Craig Mautner23ac33b2013-04-01 16:26:35 -0700749 + intent.toString());
750 ActivityOptions.abort(options);
751 return ActivityManager.START_PERMISSION_DENIED;
752 }
753 }
754
755 IIntentSender target = mService.getIntentSenderLocked(
756 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
757 realCallingUid, userId, null, null, 0, new Intent[] { intent },
758 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
759 | PendingIntent.FLAG_ONE_SHOT, null);
760
761 Intent newIntent = new Intent();
762 if (requestCode >= 0) {
763 // Caller is requesting a result.
764 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
765 }
766 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
767 new IntentSender(target));
768 if (mService.mHeavyWeightProcess.activities.size() > 0) {
769 ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0);
770 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
771 hist.packageName);
772 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
773 hist.task.taskId);
774 }
775 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
776 aInfo.packageName);
777 newIntent.setFlags(intent.getFlags());
778 newIntent.setClassName("android",
779 HeavyWeightSwitcherActivity.class.getName());
780 intent = newIntent;
781 resolvedType = null;
782 caller = null;
783 callingUid = Binder.getCallingUid();
784 callingPid = Binder.getCallingPid();
785 componentSpecified = true;
786 try {
787 ResolveInfo rInfo =
788 AppGlobals.getPackageManager().resolveIntent(
789 intent, null,
790 PackageManager.MATCH_DEFAULT_ONLY
791 | ActivityManagerService.STOCK_PM_FLAGS, userId);
792 aInfo = rInfo != null ? rInfo.activityInfo : null;
793 aInfo = mService.getActivityInfoForUser(aInfo, userId);
794 } catch (RemoteException e) {
795 aInfo = null;
796 }
797 }
798 }
799 }
800
Craig Mautnere0a38842013-12-16 16:14:02 -0800801 int res = startActivityLocked(caller, intent, resolvedType, aInfo, resultTo, resultWho,
802 requestCode, callingPid, callingUid, callingPackage, startFlags, options,
803 componentSpecified, null, container);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700804
Craig Mautnerde4ef022013-04-07 19:01:33 -0700805 if (stack.mConfigWillChange) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700806 // If the caller also wants to switch to a new configuration,
807 // do so now. This allows a clean switch, as we are waiting
808 // for the current activity to pause (so we will not destroy
809 // it), and have not yet started the next activity.
810 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
811 "updateConfiguration()");
Craig Mautnerde4ef022013-04-07 19:01:33 -0700812 stack.mConfigWillChange = false;
Craig Mautner23ac33b2013-04-01 16:26:35 -0700813 if (DEBUG_CONFIGURATION) Slog.v(TAG,
814 "Updating to new configuration after starting activity.");
815 mService.updateConfigurationLocked(config, null, false, false);
816 }
817
818 Binder.restoreCallingIdentity(origId);
819
820 if (outResult != null) {
821 outResult.result = res;
822 if (res == ActivityManager.START_SUCCESS) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700823 mWaitingActivityLaunched.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700824 do {
825 try {
826 mService.wait();
827 } catch (InterruptedException e) {
828 }
829 } while (!outResult.timeout && outResult.who == null);
830 } else if (res == ActivityManager.START_TASK_TO_FRONT) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700831 ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700832 if (r.nowVisible) {
833 outResult.timeout = false;
834 outResult.who = new ComponentName(r.info.packageName, r.info.name);
835 outResult.totalTime = 0;
836 outResult.thisTime = 0;
837 } else {
838 outResult.thisTime = SystemClock.uptimeMillis();
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700839 mWaitingActivityVisible.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700840 do {
841 try {
842 mService.wait();
843 } catch (InterruptedException e) {
844 }
845 } while (!outResult.timeout && outResult.who == null);
846 }
847 }
848 }
849
850 return res;
851 }
852 }
853
854 final int startActivities(IApplicationThread caller, int callingUid, String callingPackage,
855 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
856 Bundle options, int userId) {
857 if (intents == null) {
858 throw new NullPointerException("intents is null");
859 }
860 if (resolvedTypes == null) {
861 throw new NullPointerException("resolvedTypes is null");
862 }
863 if (intents.length != resolvedTypes.length) {
864 throw new IllegalArgumentException("intents are length different than resolvedTypes");
865 }
866
Craig Mautner23ac33b2013-04-01 16:26:35 -0700867
868 int callingPid;
869 if (callingUid >= 0) {
870 callingPid = -1;
871 } else if (caller == null) {
872 callingPid = Binder.getCallingPid();
873 callingUid = Binder.getCallingUid();
874 } else {
875 callingPid = callingUid = -1;
876 }
877 final long origId = Binder.clearCallingIdentity();
878 try {
879 synchronized (mService) {
Craig Mautner76ea2242013-05-15 11:40:05 -0700880 ActivityRecord[] outActivity = new ActivityRecord[1];
Craig Mautner23ac33b2013-04-01 16:26:35 -0700881 for (int i=0; i<intents.length; i++) {
882 Intent intent = intents[i];
883 if (intent == null) {
884 continue;
885 }
886
887 // Refuse possible leaked file descriptors
888 if (intent != null && intent.hasFileDescriptors()) {
889 throw new IllegalArgumentException("File descriptors passed in Intent");
890 }
891
892 boolean componentSpecified = intent.getComponent() != null;
893
894 // Don't modify the client's object!
895 intent = new Intent(intent);
896
897 // Collect information about the target of the Intent.
898 ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i],
899 0, null, null, userId);
900 // TODO: New, check if this is correct
901 aInfo = mService.getActivityInfoForUser(aInfo, userId);
902
903 if (aInfo != null &&
904 (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE)
905 != 0) {
906 throw new IllegalArgumentException(
907 "FLAG_CANT_SAVE_STATE not supported here");
908 }
909
910 Bundle theseOptions;
911 if (options != null && i == intents.length-1) {
912 theseOptions = options;
913 } else {
914 theseOptions = null;
915 }
Craig Mautner6170f732013-04-02 13:05:23 -0700916 int res = startActivityLocked(caller, intent, resolvedTypes[i],
Craig Mautner23ac33b2013-04-01 16:26:35 -0700917 aInfo, resultTo, null, -1, callingPid, callingUid, callingPackage,
Craig Mautnere0a38842013-12-16 16:14:02 -0800918 0, theseOptions, componentSpecified, outActivity, null);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700919 if (res < 0) {
920 return res;
921 }
922
923 resultTo = outActivity[0] != null ? outActivity[0].appToken : null;
924 }
925 }
926 } finally {
927 Binder.restoreCallingIdentity(origId);
928 }
929
930 return ActivityManager.START_SUCCESS;
931 }
932
Craig Mautner2420ead2013-04-01 17:13:20 -0700933 final boolean realStartActivityLocked(ActivityRecord r,
934 ProcessRecord app, boolean andResume, boolean checkConfig)
935 throws RemoteException {
936
937 r.startFreezingScreenLocked(app, 0);
Craig Mautnera7f2bd42013-10-15 16:13:50 -0700938 if (false) Slog.d(TAG, "realStartActivity: setting app visibility true");
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700939 mWindowManager.setAppVisibility(r.appToken, true);
Craig Mautner2420ead2013-04-01 17:13:20 -0700940
941 // schedule launch ticks to collect information about slow apps.
942 r.startLaunchTickingLocked();
943
944 // Have the window manager re-evaluate the orientation of
945 // the screen based on the new activity order. Note that
946 // as a result of this, it can call back into the activity
947 // manager with a new orientation. We don't care about that,
948 // because the activity is not currently running so we are
949 // just restarting it anyway.
950 if (checkConfig) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700951 Configuration config = mWindowManager.updateOrientationFromAppTokens(
Craig Mautner2420ead2013-04-01 17:13:20 -0700952 mService.mConfiguration,
953 r.mayFreezeScreenLocked(app) ? r.appToken : null);
954 mService.updateConfigurationLocked(config, r, false, false);
955 }
956
957 r.app = app;
958 app.waitingToKill = null;
959 r.launchCount++;
960 r.lastLaunchTime = SystemClock.uptimeMillis();
961
962 if (localLOGV) Slog.v(TAG, "Launching: " + r);
963
964 int idx = app.activities.indexOf(r);
965 if (idx < 0) {
966 app.activities.add(r);
967 }
Dianne Hackborndb926082013-10-31 16:32:44 -0700968 mService.updateLruProcessLocked(app, true, null);
969 mService.updateOomAdjLocked();
Craig Mautner2420ead2013-04-01 17:13:20 -0700970
971 final ActivityStack stack = r.task.stack;
972 try {
973 if (app.thread == null) {
974 throw new RemoteException();
975 }
976 List<ResultInfo> results = null;
977 List<Intent> newIntents = null;
978 if (andResume) {
979 results = r.results;
980 newIntents = r.newIntents;
981 }
982 if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r
983 + " icicle=" + r.icicle
984 + " with results=" + results + " newIntents=" + newIntents
985 + " andResume=" + andResume);
986 if (andResume) {
987 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
988 r.userId, System.identityHashCode(r),
989 r.task.taskId, r.shortComponentName);
990 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700991 if (r.isHomeActivity() && r.isNotResolverActivity()) {
Craig Mautner4ef26932013-09-18 15:15:52 -0700992 // Home process is the root process of the task.
993 mService.mHomeProcess = r.task.mActivities.get(0).app;
Craig Mautner2420ead2013-04-01 17:13:20 -0700994 }
995 mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
996 r.sleeping = false;
997 r.forceNewConfig = false;
998 mService.showAskCompatModeDialogLocked(r);
999 r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
1000 String profileFile = null;
1001 ParcelFileDescriptor profileFd = null;
1002 boolean profileAutoStop = false;
1003 if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
1004 if (mService.mProfileProc == null || mService.mProfileProc == app) {
1005 mService.mProfileProc = app;
1006 profileFile = mService.mProfileFile;
1007 profileFd = mService.mProfileFd;
1008 profileAutoStop = mService.mAutoStopProfiler;
1009 }
1010 }
1011 app.hasShownUi = true;
1012 app.pendingUiClean = true;
1013 if (profileFd != null) {
1014 try {
1015 profileFd = profileFd.dup();
1016 } catch (IOException e) {
1017 if (profileFd != null) {
1018 try {
1019 profileFd.close();
1020 } catch (IOException o) {
1021 }
1022 profileFd = null;
1023 }
1024 }
1025 }
Dianne Hackborna413dc02013-07-12 12:02:55 -07001026 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
Craig Mautner2420ead2013-04-01 17:13:20 -07001027 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
1028 System.identityHashCode(r), r.info,
Dianne Hackborna413dc02013-07-12 12:02:55 -07001029 new Configuration(mService.mConfiguration), r.compat,
1030 app.repProcState, r.icicle, results, newIntents, !andResume,
Craig Mautner2420ead2013-04-01 17:13:20 -07001031 mService.isNextTransitionForward(), profileFile, profileFd,
1032 profileAutoStop);
1033
1034 if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
1035 // This may be a heavy-weight process! Note that the package
1036 // manager will ensure that only activity can run in the main
1037 // process of the .apk, which is the only thing that will be
1038 // considered heavy-weight.
1039 if (app.processName.equals(app.info.packageName)) {
1040 if (mService.mHeavyWeightProcess != null
1041 && mService.mHeavyWeightProcess != app) {
1042 Slog.w(TAG, "Starting new heavy weight process " + app
1043 + " when already running "
1044 + mService.mHeavyWeightProcess);
1045 }
1046 mService.mHeavyWeightProcess = app;
1047 Message msg = mService.mHandler.obtainMessage(
1048 ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
1049 msg.obj = r;
1050 mService.mHandler.sendMessage(msg);
1051 }
1052 }
1053
1054 } catch (RemoteException e) {
1055 if (r.launchFailed) {
1056 // This is the second time we failed -- finish activity
1057 // and give up.
1058 Slog.e(TAG, "Second failure launching "
1059 + r.intent.getComponent().flattenToShortString()
1060 + ", giving up", e);
1061 mService.appDiedLocked(app, app.pid, app.thread);
1062 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
1063 "2nd-crash", false);
1064 return false;
1065 }
1066
1067 // This is the first time we failed -- restart process and
1068 // retry.
1069 app.activities.remove(r);
1070 throw e;
1071 }
1072
1073 r.launchFailed = false;
1074 if (stack.updateLRUListLocked(r)) {
1075 Slog.w(TAG, "Activity " + r
1076 + " being launched, but already in LRU list");
1077 }
1078
1079 if (andResume) {
1080 // As part of the process of launching, ActivityThread also performs
1081 // a resume.
1082 stack.minimalResumeActivityLocked(r);
1083 } else {
1084 // This activity is not starting in the resumed state... which
1085 // should look like we asked it to pause+stop (but remain visible),
1086 // and it has done so and reported back the current icicle and
1087 // other state.
1088 if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r
1089 + " (starting in stopped state)");
1090 r.state = ActivityState.STOPPED;
1091 r.stopped = true;
1092 }
1093
1094 // Launch the new version setup screen if needed. We do this -after-
1095 // launching the initial activity (that is, home), so that it can have
1096 // a chance to initialize itself while in the background, making the
1097 // switch back to it faster and look better.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001098 if (isFrontStack(stack)) {
Craig Mautner2420ead2013-04-01 17:13:20 -07001099 mService.startSetupActivityLocked();
1100 }
1101
1102 return true;
1103 }
1104
Craig Mautnere79d42682013-04-01 19:01:53 -07001105 void startSpecificActivityLocked(ActivityRecord r,
1106 boolean andResume, boolean checkConfig) {
1107 // Is this activity's application already running?
1108 ProcessRecord app = mService.getProcessRecordLocked(r.processName,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001109 r.info.applicationInfo.uid, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001110
1111 r.task.stack.setLaunchTime(r);
1112
1113 if (app != null && app.thread != null) {
1114 try {
Dianne Hackborn237cefb2013-10-22 18:45:27 -07001115 if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
1116 || !"android".equals(r.info.packageName)) {
1117 // Don't add this if it is a platform component that is marked
1118 // to run in multiple processes, because this is actually
1119 // part of the framework so doesn't make sense to track as a
1120 // separate apk in the process.
1121 app.addPackage(r.info.packageName, mService.mProcessStats);
1122 }
Craig Mautnere79d42682013-04-01 19:01:53 -07001123 realStartActivityLocked(r, app, andResume, checkConfig);
1124 return;
1125 } catch (RemoteException e) {
1126 Slog.w(TAG, "Exception when starting activity "
1127 + r.intent.getComponent().flattenToShortString(), e);
1128 }
1129
1130 // If a dead object exception was thrown -- fall through to
1131 // restart the application.
1132 }
1133
1134 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001135 "activity", r.intent.getComponent(), false, false, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001136 }
1137
Craig Mautner6170f732013-04-02 13:05:23 -07001138 final int startActivityLocked(IApplicationThread caller,
1139 Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
1140 String resultWho, int requestCode,
1141 int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
Craig Mautnere0a38842013-12-16 16:14:02 -08001142 boolean componentSpecified, ActivityRecord[] outActivity, ActivityContainer container) {
Craig Mautner6170f732013-04-02 13:05:23 -07001143 int err = ActivityManager.START_SUCCESS;
1144
1145 ProcessRecord callerApp = null;
1146 if (caller != null) {
1147 callerApp = mService.getRecordForAppLocked(caller);
1148 if (callerApp != null) {
1149 callingPid = callerApp.pid;
1150 callingUid = callerApp.info.uid;
1151 } else {
1152 Slog.w(TAG, "Unable to find app for caller " + caller
1153 + " (pid=" + callingPid + ") when starting: "
1154 + intent.toString());
1155 err = ActivityManager.START_PERMISSION_DENIED;
1156 }
1157 }
1158
1159 if (err == ActivityManager.START_SUCCESS) {
1160 final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
1161 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
Craig Mautner9ef471f2014-02-07 13:11:47 -08001162 + "} from pid " + (callerApp != null ? callerApp.pid : callingPid)
1163 + " on display " + (container == null ? (mFocusedStack == null ?
1164 Display.DEFAULT_DISPLAY : mFocusedStack.mDisplayId) :
1165 (container.mActivityDisplay == null ? Display.DEFAULT_DISPLAY :
1166 container.mActivityDisplay.mDisplayId)));
Craig Mautner6170f732013-04-02 13:05:23 -07001167 }
1168
1169 ActivityRecord sourceRecord = null;
1170 ActivityRecord resultRecord = null;
1171 if (resultTo != null) {
1172 sourceRecord = isInAnyStackLocked(resultTo);
1173 if (DEBUG_RESULTS) Slog.v(
1174 TAG, "Will send result to " + resultTo + " " + sourceRecord);
1175 if (sourceRecord != null) {
1176 if (requestCode >= 0 && !sourceRecord.finishing) {
1177 resultRecord = sourceRecord;
1178 }
1179 }
1180 }
1181 ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
1182
1183 int launchFlags = intent.getFlags();
1184
1185 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
1186 && sourceRecord != null) {
1187 // Transfer the result target from the source activity to the new
1188 // one being started, including any failures.
1189 if (requestCode >= 0) {
1190 ActivityOptions.abort(options);
1191 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
1192 }
1193 resultRecord = sourceRecord.resultTo;
1194 resultWho = sourceRecord.resultWho;
1195 requestCode = sourceRecord.requestCode;
1196 sourceRecord.resultTo = null;
1197 if (resultRecord != null) {
1198 resultRecord.removeResultsLocked(
1199 sourceRecord, resultWho, requestCode);
1200 }
Dianne Hackbornd4981012014-03-14 16:27:40 +00001201 if (sourceRecord.launchedFromUid == callingUid) {
1202 // The new activity is being launched from the same uid as the previous
1203 // activity in the flow, and asking to forward its result back to the
1204 // previous. In this case the activity is serving as a trampoline between
1205 // the two, so we also want to update its launchedFromPackage to be the
1206 // same as the previous activity. Note that this is safe, since we know
1207 // these two packages come from the same uid; the caller could just as
1208 // well have supplied that same package name itself. This specifially
1209 // deals with the case of an intent picker/chooser being launched in the app
1210 // flow to redirect to an activity picked by the user, where we want the final
1211 // activity to consider it to have been launched by the previous app activity.
1212 callingPackage = sourceRecord.launchedFromPackage;
1213 }
Craig Mautner6170f732013-04-02 13:05:23 -07001214 }
1215
1216 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
1217 // We couldn't find a class that can handle the given Intent.
1218 // That's the end of that!
1219 err = ActivityManager.START_INTENT_NOT_RESOLVED;
1220 }
1221
1222 if (err == ActivityManager.START_SUCCESS && aInfo == null) {
1223 // We couldn't find the specific class specified in the Intent.
1224 // Also the end of the line.
1225 err = ActivityManager.START_CLASS_NOT_FOUND;
1226 }
1227
1228 if (err != ActivityManager.START_SUCCESS) {
1229 if (resultRecord != null) {
1230 resultStack.sendActivityResultLocked(-1,
1231 resultRecord, resultWho, requestCode,
1232 Activity.RESULT_CANCELED, null);
1233 }
1234 setDismissKeyguard(false);
1235 ActivityOptions.abort(options);
1236 return err;
1237 }
1238
1239 final int startAnyPerm = mService.checkPermission(
1240 START_ANY_ACTIVITY, callingPid, callingUid);
1241 final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
1242 callingUid, aInfo.applicationInfo.uid, aInfo.exported);
1243 if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
1244 if (resultRecord != null) {
1245 resultStack.sendActivityResultLocked(-1,
1246 resultRecord, resultWho, requestCode,
1247 Activity.RESULT_CANCELED, null);
1248 }
1249 setDismissKeyguard(false);
1250 String msg;
1251 if (!aInfo.exported) {
1252 msg = "Permission Denial: starting " + intent.toString()
1253 + " from " + callerApp + " (pid=" + callingPid
1254 + ", uid=" + callingUid + ")"
1255 + " not exported from uid " + aInfo.applicationInfo.uid;
1256 } else {
1257 msg = "Permission Denial: starting " + intent.toString()
1258 + " from " + callerApp + " (pid=" + callingPid
1259 + ", uid=" + callingUid + ")"
1260 + " requires " + aInfo.permission;
1261 }
1262 Slog.w(TAG, msg);
1263 throw new SecurityException(msg);
1264 }
1265
Ben Gruverdd72c9e2013-08-06 12:34:17 -07001266 boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
Ben Gruverb6223792013-07-29 16:35:40 -07001267 callingPid, resolvedType, aInfo.applicationInfo);
Ben Gruver5e207332013-04-03 17:41:37 -07001268
Craig Mautner6170f732013-04-02 13:05:23 -07001269 if (mService.mController != null) {
Craig Mautner6170f732013-04-02 13:05:23 -07001270 try {
1271 // The Intent we give to the watcher has the extra data
1272 // stripped off, since it can contain private information.
1273 Intent watchIntent = intent.cloneFilter();
Ben Gruver5e207332013-04-03 17:41:37 -07001274 abort |= !mService.mController.activityStarting(watchIntent,
Craig Mautner6170f732013-04-02 13:05:23 -07001275 aInfo.applicationInfo.packageName);
1276 } catch (RemoteException e) {
1277 mService.mController = null;
1278 }
Ben Gruver5e207332013-04-03 17:41:37 -07001279 }
Craig Mautner6170f732013-04-02 13:05:23 -07001280
Ben Gruver5e207332013-04-03 17:41:37 -07001281 if (abort) {
1282 if (resultRecord != null) {
1283 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
Craig Mautner6170f732013-04-02 13:05:23 -07001284 Activity.RESULT_CANCELED, null);
Craig Mautner6170f732013-04-02 13:05:23 -07001285 }
Ben Gruver5e207332013-04-03 17:41:37 -07001286 // We pretend to the caller that it was really started, but
1287 // they will just get a cancel result.
1288 setDismissKeyguard(false);
1289 ActivityOptions.abort(options);
1290 return ActivityManager.START_SUCCESS;
Craig Mautner6170f732013-04-02 13:05:23 -07001291 }
1292
1293 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
Craig Mautnere0a38842013-12-16 16:14:02 -08001294 intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
1295 requestCode, componentSpecified, this, container);
Craig Mautner6170f732013-04-02 13:05:23 -07001296 if (outActivity != null) {
1297 outActivity[0] = r;
1298 }
1299
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001300 final ActivityStack stack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001301 if (stack.mResumedActivity == null
1302 || stack.mResumedActivity.info.applicationInfo.uid != callingUid) {
Craig Mautner6170f732013-04-02 13:05:23 -07001303 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
1304 PendingActivityLaunch pal =
Craig Mautnerde4ef022013-04-07 19:01:33 -07001305 new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
Craig Mautner6170f732013-04-02 13:05:23 -07001306 mService.mPendingActivityLaunches.add(pal);
1307 setDismissKeyguard(false);
1308 ActivityOptions.abort(options);
1309 return ActivityManager.START_SWITCHES_CANCELED;
1310 }
1311 }
1312
1313 if (mService.mDidAppSwitch) {
1314 // This is the second allowed switch since we stopped switches,
1315 // so now just generally allow switches. Use case: user presses
1316 // home (switches disabled, switch to home, mDidAppSwitch now true);
1317 // user taps a home icon (coming from home so allowed, we hit here
1318 // and now allow anyone to switch again).
1319 mService.mAppSwitchesAllowedTime = 0;
1320 } else {
1321 mService.mDidAppSwitch = true;
1322 }
1323
1324 mService.doPendingActivityLaunchesLocked(false);
1325
Craig Mautner8849a5e2013-04-02 16:41:03 -07001326 err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
Craig Mautner10385a12013-09-22 21:08:32 -07001327
1328 if (allPausedActivitiesComplete()) {
1329 // If someone asked to have the keyguard dismissed on the next
Craig Mautner6170f732013-04-02 13:05:23 -07001330 // activity start, but we are not actually doing an activity
1331 // switch... just dismiss the keyguard now, because we
1332 // probably want to see whatever is behind it.
1333 dismissKeyguard();
1334 }
1335 return err;
1336 }
1337
Craig Mautnerac6f8432013-07-17 13:24:59 -07001338 ActivityStack adjustStackFocus(ActivityRecord r) {
Craig Mautner1d001b62013-06-18 16:52:43 -07001339 final TaskRecord task = r.task;
1340 if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001341 if (task != null) {
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07001342 final ActivityStack taskStack = task.stack;
Craig Mautnere0a38842013-12-16 16:14:02 -08001343 if (taskStack.isOnHomeDisplay()) {
1344 if (mFocusedStack != taskStack) {
1345 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: Setting " +
1346 "focused stack to r=" + r + " task=" + task);
1347 mFocusedStack = taskStack;
1348 } else {
1349 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1350 "adjustStackFocus: Focused stack already=" + mFocusedStack);
1351 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001352 }
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07001353 return taskStack;
Craig Mautnerac6f8432013-07-17 13:24:59 -07001354 }
1355
Craig Mautnere0a38842013-12-16 16:14:02 -08001356 final ActivityContainer container = r.mInitialActivityContainer;
1357 if (container != null) {
1358 // The first time put it on the desired stack, after this put on task stack.
1359 r.mInitialActivityContainer = null;
1360 return container.mStack;
1361 }
1362
Craig Mautner4a1cb222013-12-04 16:14:06 -08001363 if (mFocusedStack != mHomeStack) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001364 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1365 "adjustStackFocus: Have a focused stack=" + mFocusedStack);
1366 return mFocusedStack;
1367 }
1368
Craig Mautnere0a38842013-12-16 16:14:02 -08001369 final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks;
1370 for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1371 final ActivityStack stack = homeDisplayStacks.get(stackNdx);
1372 if (!stack.isHomeStack()) {
1373 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1374 "adjustStackFocus: Setting focused stack=" + stack);
1375 mFocusedStack = stack;
1376 return mFocusedStack;
Craig Mautner858d8a62013-04-23 17:08:34 -07001377 }
1378 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001379
Craig Mautner4a1cb222013-12-04 16:14:06 -08001380 // Need to create an app stack for this user.
1381 int stackId = createStackOnDisplay(null, getNextStackId(), Display.DEFAULT_DISPLAY);
Craig Mautnerac6f8432013-07-17 13:24:59 -07001382 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r +
1383 " stackId=" + stackId);
1384 mFocusedStack = getStack(stackId);
Craig Mautner29219d92013-04-16 20:19:12 -07001385 return mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001386 }
1387 return mHomeStack;
1388 }
1389
Craig Mautner29219d92013-04-16 20:19:12 -07001390 void setFocusedStack(ActivityRecord r) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08001391 if (r != null) {
Craig Mautner12ff7392014-02-21 21:08:00 -08001392 final TaskRecord task = r.task;
1393 boolean isHomeActivity = !r.isApplicationActivity();
1394 if (!isHomeActivity && task != null) {
1395 isHomeActivity = !task.isApplicationTask();
1396 }
1397 if (!isHomeActivity && task != null) {
1398 final ActivityRecord parent = task.stack.mActivityContainer.mParentActivity;
1399 isHomeActivity = parent != null && parent.isHomeActivity();
1400 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08001401 moveHomeStack(isHomeActivity);
Craig Mautner29219d92013-04-16 20:19:12 -07001402 }
1403 }
1404
Craig Mautner8849a5e2013-04-02 16:41:03 -07001405 final int startActivityUncheckedLocked(ActivityRecord r,
1406 ActivityRecord sourceRecord, int startFlags, boolean doResume,
1407 Bundle options) {
1408 final Intent intent = r.intent;
1409 final int callingUid = r.launchedFromUid;
1410
1411 int launchFlags = intent.getFlags();
1412
Craig Mautner8849a5e2013-04-02 16:41:03 -07001413 // We'll invoke onUserLeaving before onPause only if the launching
1414 // activity did not explicitly state that this is an automated launch.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001415 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1416 if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001417
1418 // If the caller has asked not to resume at this point, we make note
1419 // of this in the record so that we can skip it when trying to find
1420 // the top running activity.
1421 if (!doResume) {
1422 r.delayedResume = true;
1423 }
1424
1425 ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1426
1427 // If the onlyIfNeeded flag is set, then we can do this if the activity
1428 // being launched is the same as the one making the call... or, as
1429 // a special case, if we do not know the caller then we count the
1430 // current top activity as the caller.
1431 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1432 ActivityRecord checkedCaller = sourceRecord;
1433 if (checkedCaller == null) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001434 checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001435 }
1436 if (!checkedCaller.realActivity.equals(r.realActivity)) {
1437 // Caller is not the same as launcher, so always needed.
1438 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
1439 }
1440 }
1441
1442 if (sourceRecord == null) {
1443 // This activity is not being started from another... in this
1444 // case we -always- start a new task.
1445 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
Craig Mautner29219d92013-04-16 20:19:12 -07001446 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1447 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001448 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1449 }
1450 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1451 // The original activity who is starting us is running as a single
1452 // instance... this new activity it is starting must go on its
1453 // own task.
1454 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1455 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
1456 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1457 // The activity being started is a single instance... it always
1458 // gets launched into its own task.
1459 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1460 }
1461
Craig Mautner88629292013-11-10 20:39:05 -08001462 ActivityInfo newTaskInfo = null;
1463 Intent newTaskIntent = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001464 final ActivityStack sourceStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001465 if (sourceRecord != null) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001466 if (sourceRecord.finishing) {
1467 // If the source is finishing, we can't further count it as our source. This
1468 // is because the task it is associated with may now be empty and on its way out,
1469 // so we don't want to blindly throw it in to that task. Instead we will take
Craig Mautner88629292013-11-10 20:39:05 -08001470 // the NEW_TASK flow and try to find a task for it. But save the task information
1471 // so it can be used when creating the new task.
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001472 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
1473 Slog.w(TAG, "startActivity called from finishing " + sourceRecord
1474 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
1475 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
Craig Mautner88629292013-11-10 20:39:05 -08001476 newTaskInfo = sourceRecord.info;
1477 newTaskIntent = sourceRecord.task.intent;
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001478 }
1479 sourceRecord = null;
1480 sourceStack = null;
1481 } else {
1482 sourceStack = sourceRecord.task.stack;
1483 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07001484 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001485 sourceStack = null;
1486 }
1487
Craig Mautner8849a5e2013-04-02 16:41:03 -07001488 if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1489 // For whatever reason this activity is being launched into a new
1490 // task... yet the caller has requested a result back. Well, that
1491 // is pretty messed up, so instead immediately send back a cancel
1492 // and let the new task continue launched as normal without a
1493 // dependency on its originator.
1494 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1495 r.resultTo.task.stack.sendActivityResultLocked(-1,
1496 r.resultTo, r.resultWho, r.requestCode,
1497 Activity.RESULT_CANCELED, null);
1498 r.resultTo = null;
1499 }
1500
1501 boolean addingToTask = false;
1502 boolean movedHome = false;
1503 TaskRecord reuseTask = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001504 ActivityStack targetStack;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001505 if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
1506 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
1507 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1508 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1509 // If bring to front is requested, and no result is requested, and
1510 // we can find a task that was started with this same
1511 // component, then instead of launching bring that one to the front.
1512 if (r.resultTo == null) {
1513 // See if there is a task to bring to the front. If this is
1514 // a SINGLE_INSTANCE activity, there can be one and only one
1515 // instance of it in the history, and it is always in its own
1516 // unique task, so we do a special search.
1517 ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
Craig Mautnerac6f8432013-07-17 13:24:59 -07001518 ? findTaskLocked(r)
Craig Mautner8849a5e2013-04-02 16:41:03 -07001519 : findActivityLocked(intent, r.info);
1520 if (intentActivity != null) {
Craig Mautner29219d92013-04-16 20:19:12 -07001521 if (r.task == null) {
1522 r.task = intentActivity.task;
1523 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001524 targetStack = intentActivity.task.stack;
Craig Mautner0f922742013-08-06 08:44:42 -07001525 targetStack.mLastPausedActivity = null;
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001526 if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack
1527 + " from " + intentActivity);
Craig Mautnere0a38842013-12-16 16:14:02 -08001528 targetStack.moveToFront();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001529 if (intentActivity.task.intent == null) {
1530 // This task was started because of movement of
1531 // the activity based on affinity... now that we
1532 // are actually launching it, we can assign the
1533 // base intent.
1534 intentActivity.task.setIntent(intent, r.info);
1535 }
1536 // If the target task is not in the front, then we need
1537 // to bring it to the front... except... well, with
1538 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like
1539 // to have the same behavior as if a new instance was
1540 // being started, which means not bringing it to the front
1541 // if the caller is not itself in the front.
Craig Mautner165640b2013-04-20 10:34:33 -07001542 final ActivityStack lastStack = getLastStack();
1543 ActivityRecord curTop = lastStack == null?
1544 null : lastStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner7504d7b2013-09-17 10:50:53 -07001545 if (curTop != null && (curTop.task != intentActivity.task ||
1546 curTop.task != lastStack.topTask())) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001547 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Craig Mautnerd0f964f2013-08-07 11:16:33 -07001548 if (sourceRecord == null || (sourceStack.topActivity() != null &&
1549 sourceStack.topActivity().task == sourceRecord.task)) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001550 // We really do want to push this one into the
1551 // user's face, right now.
1552 movedHome = true;
Craig Mautnerb53d97c2013-10-25 11:54:37 -07001553 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001554 if ((launchFlags &
Craig Mautner29219d92013-04-16 20:19:12 -07001555 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1556 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
Craig Mautnere12a4a62013-08-29 12:24:56 -07001557 // Caller wants to appear on home activity.
Craig Mautnerae7ecab2013-09-18 11:48:14 -07001558 intentActivity.task.mOnTopOfHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001559 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001560 options = null;
1561 }
1562 }
1563 // If the caller has requested that the target task be
1564 // reset, then do so.
1565 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1566 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
1567 }
1568 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1569 // We don't need to start a new activity, and
1570 // the client said not to do anything if that
1571 // is the case, so this is it! And for paranoia, make
1572 // sure we have correctly resumed the top activity.
1573 if (doResume) {
Craig Mautner05d29032013-05-03 13:40:13 -07001574 resumeTopActivitiesLocked(targetStack, null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001575 } else {
1576 ActivityOptions.abort(options);
1577 }
1578 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1579 }
1580 if ((launchFlags &
1581 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
1582 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
1583 // The caller has requested to completely replace any
1584 // existing task with its new activity. Well that should
1585 // not be too hard...
1586 reuseTask = intentActivity.task;
1587 reuseTask.performClearTaskLocked();
1588 reuseTask.setIntent(r.intent, r.info);
1589 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
1590 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1591 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1592 // In this situation we want to remove all activities
1593 // from the task up to the one being started. In most
1594 // cases this means we are resetting the task to its
1595 // initial state.
1596 ActivityRecord top =
1597 intentActivity.task.performClearTaskLocked(r, launchFlags);
1598 if (top != null) {
1599 if (top.frontOfTask) {
1600 // Activity aliases may mean we use different
1601 // intents for the top activity, so make sure
1602 // the task now has the identity of the new
1603 // intent.
1604 top.task.setIntent(r.intent, r.info);
1605 }
1606 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
1607 r, top.task);
1608 top.deliverNewIntentLocked(callingUid, r.intent);
1609 } else {
1610 // A special case: we need to
1611 // start the activity because it is not currently
1612 // running, and the caller has asked to clear the
1613 // current task to have this activity at the top.
1614 addingToTask = true;
1615 // Now pretend like this activity is being started
1616 // by the top of its task, so it is put in the
1617 // right place.
1618 sourceRecord = intentActivity;
1619 }
1620 } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
1621 // In this case the top activity on the task is the
1622 // same as the one being launched, so we take that
1623 // as a request to bring the task to the foreground.
1624 // If the top activity in the task is the root
1625 // activity, deliver this new intent to it if it
1626 // desires.
1627 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1628 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
1629 && intentActivity.realActivity.equals(r.realActivity)) {
1630 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
1631 intentActivity.task);
1632 if (intentActivity.frontOfTask) {
1633 intentActivity.task.setIntent(r.intent, r.info);
1634 }
1635 intentActivity.deliverNewIntentLocked(callingUid, r.intent);
1636 } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
1637 // In this case we are launching the root activity
1638 // of the task, but with a different intent. We
1639 // should start a new instance on top.
1640 addingToTask = true;
1641 sourceRecord = intentActivity;
1642 }
1643 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1644 // In this case an activity is being launched in to an
1645 // existing task, without resetting that task. This
1646 // is typically the situation of launching an activity
1647 // from a notification or shortcut. We want to place
1648 // the new activity on top of the current task.
1649 addingToTask = true;
1650 sourceRecord = intentActivity;
1651 } else if (!intentActivity.task.rootWasReset) {
1652 // In this case we are launching in to an existing task
1653 // that has not yet been started from its front door.
1654 // The current task has been brought to the front.
1655 // Ideally, we'd probably like to place this new task
1656 // at the bottom of its stack, but that's a little hard
1657 // to do with the current organization of the code so
1658 // for now we'll just drop it.
1659 intentActivity.task.setIntent(r.intent, r.info);
1660 }
1661 if (!addingToTask && reuseTask == null) {
1662 // We didn't do anything... but it was needed (a.k.a., client
1663 // don't use that intent!) And for paranoia, make
1664 // sure we have correctly resumed the top activity.
1665 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001666 targetStack.resumeTopActivityLocked(null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001667 } else {
1668 ActivityOptions.abort(options);
1669 }
1670 return ActivityManager.START_TASK_TO_FRONT;
1671 }
1672 }
1673 }
1674 }
1675
1676 //String uri = r.intent.toURI();
1677 //Intent intent2 = new Intent(uri);
1678 //Slog.i(TAG, "Given intent: " + r.intent);
1679 //Slog.i(TAG, "URI is: " + uri);
1680 //Slog.i(TAG, "To intent: " + intent2);
1681
1682 if (r.packageName != null) {
1683 // If the activity being launched is the same as the one currently
1684 // at the top, then we need to check if it should only be launched
1685 // once.
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001686 ActivityStack topStack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001687 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001688 if (top != null && r.resultTo == null) {
1689 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
1690 if (top.app != null && top.app.thread != null) {
1691 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1692 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
1693 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1694 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
1695 top.task);
1696 // For paranoia, make sure we have correctly
1697 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001698 topStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001699 if (doResume) {
Craig Mautner05d29032013-05-03 13:40:13 -07001700 resumeTopActivitiesLocked();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001701 }
1702 ActivityOptions.abort(options);
1703 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1704 // We don't need to start a new activity, and
1705 // the client said not to do anything if that
1706 // is the case, so this is it!
1707 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1708 }
1709 top.deliverNewIntentLocked(callingUid, r.intent);
1710 return ActivityManager.START_DELIVERED_TO_TOP;
1711 }
1712 }
1713 }
1714 }
1715
1716 } else {
1717 if (r.resultTo != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001718 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
1719 r.requestCode, Activity.RESULT_CANCELED, null);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001720 }
1721 ActivityOptions.abort(options);
1722 return ActivityManager.START_CLASS_NOT_FOUND;
1723 }
1724
1725 boolean newTask = false;
1726 boolean keepCurTransition = false;
1727
1728 // Should this be considered a new task?
1729 if (r.resultTo == null && !addingToTask
1730 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001731 targetStack = adjustStackFocus(r);
Craig Mautnere0a38842013-12-16 16:14:02 -08001732 targetStack.moveToFront();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001733 if (reuseTask == null) {
Craig Mautner88629292013-11-10 20:39:05 -08001734 r.setTask(targetStack.createTaskRecord(getNextTaskId(),
1735 newTaskInfo != null ? newTaskInfo : r.info,
1736 newTaskIntent != null ? newTaskIntent : intent,
1737 true), null, true);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001738 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
1739 r.task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001740 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001741 r.setTask(reuseTask, reuseTask, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001742 }
1743 newTask = true;
1744 if (!movedHome) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001745 if ((launchFlags &
1746 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
1747 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
1748 // Caller wants to appear on home activity, so before starting
1749 // their own activity we will bring home to the front.
Craig Mautnere0a38842013-12-16 16:14:02 -08001750 r.task.mOnTopOfHome = r.task.stack.isOnHomeDisplay();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001751 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001752 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001753 } else if (sourceRecord != null) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001754 TaskRecord sourceTask = sourceRecord.task;
Craig Mautner525f3d92013-05-07 14:01:50 -07001755 targetStack = sourceTask.stack;
Craig Mautnere0a38842013-12-16 16:14:02 -08001756 targetStack.moveToFront();
Craig Mautnerf32b22e2014-03-25 11:04:16 -07001757 mWindowManager.moveTaskToTop(sourceTask.taskId);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001758 if (!addingToTask &&
1759 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
1760 // In this case, we are adding the activity to an existing
1761 // task, but the caller has asked to clear that task if the
1762 // activity is already running.
Craig Mautner525f3d92013-05-07 14:01:50 -07001763 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001764 keepCurTransition = true;
1765 if (top != null) {
1766 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
1767 top.deliverNewIntentLocked(callingUid, r.intent);
1768 // For paranoia, make sure we have correctly
1769 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001770 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001771 if (doResume) {
1772 targetStack.resumeTopActivityLocked(null);
1773 }
1774 ActivityOptions.abort(options);
1775 return ActivityManager.START_DELIVERED_TO_TOP;
1776 }
1777 } else if (!addingToTask &&
1778 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1779 // In this case, we are launching an activity in our own task
1780 // that may already be running somewhere in the history, and
1781 // we want to shuffle it to the front of the stack if so.
Craig Mautner525f3d92013-05-07 14:01:50 -07001782 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001783 if (top != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001784 final TaskRecord task = top.task;
1785 task.moveActivityToFrontLocked(top);
1786 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001787 top.updateOptionsLocked(options);
1788 top.deliverNewIntentLocked(callingUid, r.intent);
Craig Mautner0f922742013-08-06 08:44:42 -07001789 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001790 if (doResume) {
1791 targetStack.resumeTopActivityLocked(null);
1792 }
1793 return ActivityManager.START_DELIVERED_TO_TOP;
1794 }
1795 }
1796 // An existing activity is starting this new activity, so we want
1797 // to keep the new one in the same task as the one that is starting
1798 // it.
Craig Mautner525f3d92013-05-07 14:01:50 -07001799 r.setTask(sourceTask, sourceRecord.thumbHolder, false);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001800 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001801 + " in existing task " + r.task + " from source " + sourceRecord);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001802
1803 } else {
1804 // This not being started from an existing activity, and not part
1805 // of a new task... just put it in the top task, though these days
1806 // this case should never happen.
Craig Mautnerac6f8432013-07-17 13:24:59 -07001807 targetStack = adjustStackFocus(r);
Craig Mautnere0a38842013-12-16 16:14:02 -08001808 targetStack.moveToFront();
Craig Mautner1602ec22013-05-12 10:24:27 -07001809 ActivityRecord prev = targetStack.topActivity();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001810 r.setTask(prev != null ? prev.task
1811 : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1812 null, true);
Craig Mautnerf32b22e2014-03-25 11:04:16 -07001813 mWindowManager.moveTaskToTop(r.task.taskId);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001814 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1815 + " in new guessed " + r.task);
1816 }
1817
1818 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
1819 intent, r.getUriPermissionsLocked());
1820
1821 if (newTask) {
1822 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
1823 }
1824 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
Craig Mautner0f922742013-08-06 08:44:42 -07001825 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001826 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
Craig Mautner1d001b62013-06-18 16:52:43 -07001827 mService.setFocusedActivityLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001828 return ActivityManager.START_SUCCESS;
1829 }
1830
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001831 void acquireLaunchWakelock() {
1832 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
1833 throw new IllegalStateException("Calling must be system uid");
1834 }
1835 mLaunchingActivity.acquire();
1836 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
1837 // To be safe, don't allow the wake lock to be held for too long.
1838 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
1839 }
1840 }
1841
Craig Mautnerf3333272013-04-22 10:55:53 -07001842 // Checked.
1843 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
1844 Configuration config) {
1845 if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
1846
Craig Mautnerf3333272013-04-22 10:55:53 -07001847 ArrayList<ActivityRecord> stops = null;
1848 ArrayList<ActivityRecord> finishes = null;
1849 ArrayList<UserStartedState> startingUsers = null;
1850 int NS = 0;
1851 int NF = 0;
1852 IApplicationThread sendThumbnail = null;
1853 boolean booting = false;
1854 boolean enableScreen = false;
1855 boolean activityRemoved = false;
1856
1857 ActivityRecord r = ActivityRecord.forToken(token);
1858 if (r != null) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07001859 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
1860 Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07001861 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
1862 r.finishLaunchTickingLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001863 if (fromTimeout) {
1864 reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
Craig Mautnerf3333272013-04-22 10:55:53 -07001865 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001866
1867 // This is a hack to semi-deal with a race condition
1868 // in the client where it can be constructed with a
1869 // newer configuration from when we asked it to launch.
1870 // We'll update with whatever configuration it now says
1871 // it used to launch.
1872 if (config != null) {
1873 r.configuration = config;
1874 }
1875
1876 // We are now idle. If someone is waiting for a thumbnail from
1877 // us, we can now deliver.
1878 r.idle = true;
1879
1880 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
1881 sendThumbnail = r.app.thread;
1882 r.thumbnailNeeded = false;
1883 }
1884
1885 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
1886 if (!mService.mBooted && isFrontStack(r.task.stack)) {
1887 mService.mBooted = true;
1888 enableScreen = true;
1889 }
1890 }
1891
1892 if (allResumedActivitiesIdle()) {
1893 if (r != null) {
1894 mService.scheduleAppGcsLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001895 }
1896
1897 if (mLaunchingActivity.isHeld()) {
1898 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
1899 if (VALIDATE_WAKE_LOCK_CALLER &&
1900 Binder.getCallingUid() != Process.myUid()) {
1901 throw new IllegalStateException("Calling must be system uid");
1902 }
1903 mLaunchingActivity.release();
1904 }
1905 ensureActivitiesVisibleLocked(null, 0);
Craig Mautnerf3333272013-04-22 10:55:53 -07001906 }
1907
1908 // Atomically retrieve all of the other things to do.
1909 stops = processStoppingActivitiesLocked(true);
1910 NS = stops != null ? stops.size() : 0;
1911 if ((NF=mFinishingActivities.size()) > 0) {
1912 finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
1913 mFinishingActivities.clear();
1914 }
1915
1916 final ArrayList<ActivityRecord> thumbnails;
1917 final int NT = mCancelledThumbnails.size();
1918 if (NT > 0) {
1919 thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
1920 mCancelledThumbnails.clear();
1921 } else {
1922 thumbnails = null;
1923 }
1924
1925 if (isFrontStack(mHomeStack)) {
1926 booting = mService.mBooting;
1927 mService.mBooting = false;
1928 }
1929
1930 if (mStartingUsers.size() > 0) {
1931 startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
1932 mStartingUsers.clear();
1933 }
1934
1935 // Perform the following actions from unsynchronized state.
1936 final IApplicationThread thumbnailThread = sendThumbnail;
1937 mHandler.post(new Runnable() {
1938 @Override
1939 public void run() {
1940 if (thumbnailThread != null) {
1941 try {
1942 thumbnailThread.requestThumbnail(token);
1943 } catch (Exception e) {
1944 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
1945 mService.sendPendingThumbnail(null, token, null, null, true);
1946 }
1947 }
1948
1949 // Report back to any thumbnail receivers.
1950 for (int i = 0; i < NT; i++) {
1951 ActivityRecord r = thumbnails.get(i);
1952 mService.sendPendingThumbnail(r, null, null, null, true);
1953 }
1954 }
1955 });
1956
1957 // Stop any activities that are scheduled to do so but have been
1958 // waiting for the next one to start.
1959 for (int i = 0; i < NS; i++) {
1960 r = stops.get(i);
1961 final ActivityStack stack = r.task.stack;
1962 if (r.finishing) {
1963 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
1964 } else {
1965 stack.stopActivityLocked(r);
1966 }
1967 }
1968
1969 // Finish any activities that are scheduled to do so but have been
1970 // waiting for the next one to start.
1971 for (int i = 0; i < NF; i++) {
1972 r = finishes.get(i);
1973 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
1974 }
1975
1976 if (booting) {
1977 mService.finishBooting();
1978 } else if (startingUsers != null) {
1979 for (int i = 0; i < startingUsers.size(); i++) {
1980 mService.finishUserSwitch(startingUsers.get(i));
1981 }
1982 }
1983
1984 mService.trimApplications();
1985 //dump();
1986 //mWindowManager.dump();
1987
1988 if (enableScreen) {
1989 mService.enableScreenAfterBoot();
1990 }
1991
1992 if (activityRemoved) {
Craig Mautner05d29032013-05-03 13:40:13 -07001993 resumeTopActivitiesLocked();
Craig Mautnerf3333272013-04-22 10:55:53 -07001994 }
1995
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001996 return r;
Craig Mautnerf3333272013-04-22 10:55:53 -07001997 }
1998
Craig Mautner8e569572013-10-11 17:36:59 -07001999 boolean handleAppDiedLocked(ProcessRecord app) {
Craig Mautner19091252013-10-05 00:03:53 -07002000 boolean hasVisibleActivities = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002001 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2002 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002003 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2004 hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app);
2005 }
Craig Mautner6b74cb52013-09-27 17:02:21 -07002006 }
Craig Mautner19091252013-10-05 00:03:53 -07002007 return hasVisibleActivities;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002008 }
2009
2010 void closeSystemDialogsLocked() {
Craig Mautnere0a38842013-12-16 16:14:02 -08002011 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2012 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002013 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2014 stacks.get(stackNdx).closeSystemDialogsLocked();
2015 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002016 }
2017 }
2018
Craig Mautner93529a42013-10-04 15:03:13 -07002019 void removeUserLocked(int userId) {
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002020 mUserStackInFront.delete(userId);
Craig Mautner93529a42013-10-04 15:03:13 -07002021 }
2022
Craig Mautner8d341ef2013-03-26 09:03:27 -07002023 /**
2024 * @return true if some activity was finished (or would have finished if doit were true).
2025 */
2026 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
2027 boolean didSomething = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002028 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2029 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002030 final int numStacks = stacks.size();
2031 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2032 final ActivityStack stack = stacks.get(stackNdx);
2033 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
2034 didSomething = true;
2035 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002036 }
2037 }
2038 return didSomething;
2039 }
2040
Dianne Hackborna413dc02013-07-12 12:02:55 -07002041 void updatePreviousProcessLocked(ActivityRecord r) {
2042 // Now that this process has stopped, we may want to consider
2043 // it to be the previous app to try to keep around in case
2044 // the user wants to return to it.
2045
2046 // First, found out what is currently the foreground app, so that
2047 // we don't blow away the previous app if this activity is being
2048 // hosted by the process that is actually still the foreground.
2049 ProcessRecord fgApp = null;
Craig Mautnere0a38842013-12-16 16:14:02 -08002050 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2051 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002052 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2053 final ActivityStack stack = stacks.get(stackNdx);
2054 if (isFrontStack(stack)) {
2055 if (stack.mResumedActivity != null) {
2056 fgApp = stack.mResumedActivity.app;
2057 } else if (stack.mPausingActivity != null) {
2058 fgApp = stack.mPausingActivity.app;
2059 }
2060 break;
Dianne Hackborna413dc02013-07-12 12:02:55 -07002061 }
Dianne Hackborna413dc02013-07-12 12:02:55 -07002062 }
2063 }
2064
2065 // Now set this one as the previous process, only if that really
2066 // makes sense to.
2067 if (r.app != null && fgApp != null && r.app != fgApp
2068 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
Craig Mautner4ef26932013-09-18 15:15:52 -07002069 && r.app != mService.mHomeProcess) {
Dianne Hackborna413dc02013-07-12 12:02:55 -07002070 mService.mPreviousProcess = r.app;
2071 mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
2072 }
2073 }
2074
Craig Mautner05d29032013-05-03 13:40:13 -07002075 boolean resumeTopActivitiesLocked() {
2076 return resumeTopActivitiesLocked(null, null, null);
2077 }
2078
2079 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
2080 Bundle targetOptions) {
2081 if (targetStack == null) {
2082 targetStack = getFocusedStack();
2083 }
Craig Mautner12ff7392014-02-21 21:08:00 -08002084 // Do targetStack first.
Craig Mautner05d29032013-05-03 13:40:13 -07002085 boolean result = false;
Craig Mautner12ff7392014-02-21 21:08:00 -08002086 if (isFrontStack(targetStack)) {
2087 result = targetStack.resumeTopActivityLocked(target, targetOptions);
2088 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002089 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2090 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002091 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2092 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautner12ff7392014-02-21 21:08:00 -08002093 if (stack == targetStack) {
2094 // Already started above.
2095 continue;
2096 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002097 if (isFrontStack(stack)) {
Craig Mautner12ff7392014-02-21 21:08:00 -08002098 stack.resumeTopActivityLocked(null);
Craig Mautner05d29032013-05-03 13:40:13 -07002099 }
Craig Mautnerf88c50f2013-04-18 19:25:12 -07002100 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002101 }
Craig Mautner05d29032013-05-03 13:40:13 -07002102 return result;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002103 }
2104
2105 void finishTopRunningActivityLocked(ProcessRecord app) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002106 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2107 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002108 final int numStacks = stacks.size();
2109 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2110 final ActivityStack stack = stacks.get(stackNdx);
2111 stack.finishTopRunningActivityLocked(app);
2112 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002113 }
2114 }
2115
Craig Mautner8d341ef2013-03-26 09:03:27 -07002116 void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002117 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2118 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002119 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2120 if (stacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) {
2121 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack="
2122 + stacks.get(stackNdx));
2123 return;
2124 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002125 }
2126 }
2127 }
2128
Craig Mautner967212c2013-04-13 21:10:58 -07002129 ActivityStack getStack(int stackId) {
Craig Mautner4504de52013-12-20 09:06:56 -08002130 WeakReference<ActivityContainer> weakReference = mActivityContainers.get(stackId);
2131 if (weakReference != null) {
2132 ActivityContainer activityContainer = weakReference.get();
2133 if (activityContainer != null) {
2134 return activityContainer.mStack;
2135 } else {
2136 mActivityContainers.remove(stackId);
2137 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002138 }
2139 return null;
2140 }
2141
Craig Mautner967212c2013-04-13 21:10:58 -07002142 ArrayList<ActivityStack> getStacks() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002143 ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>();
Craig Mautnere0a38842013-12-16 16:14:02 -08002144 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2145 allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002146 }
2147 return allStacks;
Craig Mautner967212c2013-04-13 21:10:58 -07002148 }
2149
Craig Mautner4a1cb222013-12-04 16:14:06 -08002150 IBinder getHomeActivityToken() {
2151 final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
2152 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
2153 final TaskRecord task = tasks.get(taskNdx);
2154 if (task.isHomeTask()) {
2155 final ArrayList<ActivityRecord> activities = task.mActivities;
2156 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2157 final ActivityRecord r = activities.get(activityNdx);
2158 if (r.isHomeActivity()) {
2159 return r.appToken;
2160 }
2161 }
2162 }
2163 }
2164 return null;
2165 }
2166
2167 ActivityContainer createActivityContainer(ActivityRecord parentActivity, int stackId,
2168 IActivityContainerCallback callback) {
2169 ActivityContainer activityContainer = new ActivityContainer(parentActivity, stackId,
2170 callback);
Craig Mautner4504de52013-12-20 09:06:56 -08002171 mActivityContainers.put(stackId, new WeakReference<ActivityContainer>(activityContainer));
Craig Mautner4a1cb222013-12-04 16:14:06 -08002172 if (parentActivity != null) {
2173 parentActivity.mChildContainers.add(activityContainer.mStack);
2174 }
2175 return activityContainer;
2176 }
2177
2178 ActivityContainer createActivityContainer(ActivityRecord parentActivity,
2179 IActivityContainerCallback callback) {
2180 return createActivityContainer(parentActivity, getNextStackId(), callback);
2181 }
2182
Craig Mautner34b73df2014-01-12 21:11:08 -08002183 void removeChildActivityContainers(ActivityRecord parentActivity) {
2184 for (int ndx = mActivityContainers.size() - 1; ndx >= 0; --ndx) {
2185 final ActivityContainer container = mActivityContainers.valueAt(ndx).get();
2186 if (container == null) {
2187 mActivityContainers.removeAt(ndx);
2188 continue;
2189 }
2190 if (container.mParentActivity != parentActivity) {
2191 continue;
2192 }
2193
2194 ActivityStack stack = container.mStack;
2195 ActivityRecord top = stack.topRunningNonDelayedActivityLocked(null);
2196 if (top != null) {
2197 // TODO: Make sure the next activity doesn't start up when top is destroyed.
Craig Mautner95da1082014-02-24 17:54:35 -08002198 stack.destroyActivityLocked(top, true, true, "stack parent destroyed");
Craig Mautner34b73df2014-01-12 21:11:08 -08002199 }
2200 mActivityContainers.removeAt(ndx);
2201 container.detachLocked();
2202 }
2203 }
2204
Craig Mautner95da1082014-02-24 17:54:35 -08002205 void deleteActivityContainer(IActivityContainer container) {
2206 ActivityContainer activityContainer = (ActivityContainer)container;
2207 if (activityContainer != null) {
2208 activityContainer.mStack.destroyActivitiesLocked(null, true,
2209 "deleteActivityContainer");
2210 final ActivityRecord parent = activityContainer.mParentActivity;
2211 if (parent != null) {
2212 parent.mChildContainers.remove(activityContainer);
2213 }
2214 final int stackId = activityContainer.mStackId;
2215 mActivityContainers.remove(stackId);
2216 mWindowManager.removeStack(stackId);
2217 }
2218 }
2219
Craig Mautner4a1cb222013-12-04 16:14:06 -08002220 private int createStackOnDisplay(ActivityRecord parentActivity, int stackId, int displayId) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002221 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2222 if (activityDisplay == null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002223 return -1;
2224 }
2225
2226 ActivityContainer activityContainer =
2227 createActivityContainer(parentActivity, stackId, null);
Craig Mautnere0a38842013-12-16 16:14:02 -08002228 activityContainer.attachToDisplayLocked(activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002229 return stackId;
2230 }
2231
2232 int getNextStackId() {
Craig Mautner858d8a62013-04-23 17:08:34 -07002233 while (true) {
2234 if (++mLastStackId <= HOME_STACK_ID) {
2235 mLastStackId = HOME_STACK_ID + 1;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002236 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002237 if (getStack(mLastStackId) == null) {
2238 break;
2239 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002240 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002241 return mLastStackId;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002242 }
2243
2244 void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002245 final TaskRecord task = anyTaskForIdLocked(taskId);
2246 if (task == null) {
2247 return;
2248 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002249 final ActivityStack stack = getStack(stackId);
2250 if (stack == null) {
2251 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
2252 return;
2253 }
Craig Mautner04a0ea62014-01-13 12:51:26 -08002254 task.stack.removeTask(task);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002255 stack.addTask(task, toTop);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002256 mWindowManager.addTask(taskId, stackId, toTop);
Craig Mautner05d29032013-05-03 13:40:13 -07002257 resumeTopActivitiesLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002258 }
2259
Craig Mautnerac6f8432013-07-17 13:24:59 -07002260 ActivityRecord findTaskLocked(ActivityRecord r) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07002261 if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r);
Craig Mautnere0a38842013-12-16 16:14:02 -08002262 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2263 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002264 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2265 final ActivityStack stack = stacks.get(stackNdx);
2266 if (!r.isApplicationActivity() && !stack.isHomeStack()) {
2267 if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: " + stack);
2268 continue;
2269 }
2270 final ActivityRecord ar = stack.findTaskLocked(r);
2271 if (ar != null) {
2272 return ar;
2273 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07002274 }
2275 }
Dianne Hackborn2a272d42013-10-16 13:34:33 -07002276 if (DEBUG_TASKS) Slog.d(TAG, "No task found");
Craig Mautner8849a5e2013-04-02 16:41:03 -07002277 return null;
2278 }
2279
2280 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002281 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2282 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002283 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2284 final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info);
2285 if (ar != null) {
2286 return ar;
2287 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07002288 }
2289 }
2290 return null;
2291 }
2292
Craig Mautner8d341ef2013-03-26 09:03:27 -07002293 void goingToSleepLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002294 scheduleSleepTimeout();
2295 if (!mGoingToSleep.isHeld()) {
2296 mGoingToSleep.acquire();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002297 if (mLaunchingActivity.isHeld()) {
2298 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2299 throw new IllegalStateException("Calling must be system uid");
Craig Mautner0eea92c2013-05-16 13:35:39 -07002300 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002301 mLaunchingActivity.release();
2302 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
Craig Mautner0eea92c2013-05-16 13:35:39 -07002303 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002304 }
Amith Yamasanice15e152013-09-19 12:30:32 -07002305 checkReadyForSleepLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002306 }
2307
2308 boolean shutdownLocked(int timeout) {
2309 boolean timedout = false;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002310 goingToSleepLocked();
Craig Mautner0eea92c2013-05-16 13:35:39 -07002311
2312 final long endTime = System.currentTimeMillis() + timeout;
2313 while (true) {
2314 boolean cantShutdown = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002315 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2316 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002317 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2318 cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
2319 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002320 }
2321 if (cantShutdown) {
2322 long timeRemaining = endTime - System.currentTimeMillis();
2323 if (timeRemaining > 0) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002324 try {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002325 mService.wait(timeRemaining);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002326 } catch (InterruptedException e) {
2327 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002328 } else {
2329 Slog.w(TAG, "Activity manager shutdown timed out");
2330 timedout = true;
2331 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002332 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002333 } else {
2334 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002335 }
2336 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002337
2338 // Force checkReadyForSleep to complete.
2339 mSleepTimeout = true;
2340 checkReadyForSleepLocked();
2341
Craig Mautner8d341ef2013-03-26 09:03:27 -07002342 return timedout;
2343 }
2344
2345 void comeOutOfSleepIfNeededLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002346 removeSleepTimeouts();
2347 if (mGoingToSleep.isHeld()) {
2348 mGoingToSleep.release();
2349 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002350 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2351 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002352 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2353 final ActivityStack stack = stacks.get(stackNdx);
2354 stack.awakeFromSleepingLocked();
2355 if (isFrontStack(stack)) {
2356 resumeTopActivitiesLocked();
2357 }
Craig Mautner5314a402013-09-26 12:40:16 -07002358 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002359 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002360 mGoingToSleepActivities.clear();
2361 }
2362
2363 void activitySleptLocked(ActivityRecord r) {
2364 mGoingToSleepActivities.remove(r);
2365 checkReadyForSleepLocked();
2366 }
2367
2368 void checkReadyForSleepLocked() {
2369 if (!mService.isSleepingOrShuttingDown()) {
2370 // Do not care.
2371 return;
2372 }
2373
2374 if (!mSleepTimeout) {
2375 boolean dontSleep = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002376 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2377 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002378 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2379 dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
2380 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002381 }
2382
2383 if (mStoppingActivities.size() > 0) {
2384 // Still need to tell some activities to stop; can't sleep yet.
2385 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2386 + mStoppingActivities.size() + " activities");
2387 scheduleIdleLocked();
2388 dontSleep = true;
2389 }
2390
2391 if (mGoingToSleepActivities.size() > 0) {
2392 // Still need to tell some activities to sleep; can't sleep yet.
2393 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2394 + mGoingToSleepActivities.size() + " activities");
2395 dontSleep = true;
2396 }
2397
2398 if (dontSleep) {
2399 return;
2400 }
2401 }
2402
Craig Mautnere0a38842013-12-16 16:14:02 -08002403 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2404 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002405 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2406 stacks.get(stackNdx).goToSleep();
2407 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002408 }
2409
2410 removeSleepTimeouts();
2411
2412 if (mGoingToSleep.isHeld()) {
2413 mGoingToSleep.release();
2414 }
2415 if (mService.mShuttingDown) {
2416 mService.notifyAll();
2417 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002418 }
2419
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002420 boolean reportResumedActivityLocked(ActivityRecord r) {
2421 final ActivityStack stack = r.task.stack;
2422 if (isFrontStack(stack)) {
Jeff Sharkey5782da72013-04-25 14:32:30 -07002423 mService.updateUsageStats(r, true);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002424 }
2425 if (allResumedActivitiesComplete()) {
2426 ensureActivitiesVisibleLocked(null, 0);
2427 mWindowManager.executeAppTransition();
2428 return true;
2429 }
2430 return false;
2431 }
2432
Craig Mautner8d341ef2013-03-26 09:03:27 -07002433 void handleAppCrashLocked(ProcessRecord app) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002434 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2435 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002436 final int numStacks = stacks.size();
2437 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2438 final ActivityStack stack = stacks.get(stackNdx);
2439 stack.handleAppCrashLocked(app);
2440 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002441 }
2442 }
2443
Craig Mautnerde4ef022013-04-07 19:01:33 -07002444 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
Craig Mautner580ea812013-04-25 12:58:38 -07002445 // First the front stacks. In case any are not fullscreen and are in front of home.
2446 boolean showHomeBehindStack = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002447 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2448 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002449 final int topStackNdx = stacks.size() - 1;
2450 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
2451 final ActivityStack stack = stacks.get(stackNdx);
2452 if (stackNdx == topStackNdx) {
2453 // Top stack.
2454 showHomeBehindStack =
2455 stack.ensureActivitiesVisibleLocked(starting, configChanges);
2456 } else {
2457 // Back stack.
2458 stack.ensureActivitiesVisibleLocked(starting, configChanges,
2459 showHomeBehindStack);
2460 }
Craig Mautner580ea812013-04-25 12:58:38 -07002461 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002462 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002463 }
2464
2465 void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002466 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2467 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002468 final int numStacks = stacks.size();
2469 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2470 final ActivityStack stack = stacks.get(stackNdx);
2471 stack.scheduleDestroyActivities(app, false, reason);
2472 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002473 }
2474 }
2475
2476 boolean switchUserLocked(int userId, UserStartedState uss) {
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002477 mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId());
2478 final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
Craig Mautner2420ead2013-04-01 17:13:20 -07002479 mCurrentUser = userId;
Craig Mautnerac6f8432013-07-17 13:24:59 -07002480
Craig Mautner858d8a62013-04-23 17:08:34 -07002481 mStartingUsers.add(uss);
Craig Mautnere0a38842013-12-16 16:14:02 -08002482 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2483 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002484 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002485 final ActivityStack stack = stacks.get(stackNdx);
2486 stack.switchUserLocked(userId);
2487 mWindowManager.moveTaskToTop(stack.topTask().taskId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002488 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07002489 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002490
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002491 ActivityStack stack = getStack(restoreStackId);
2492 if (stack == null) {
2493 stack = mHomeStack;
2494 }
2495 final boolean homeInFront = stack.isHomeStack();
Craig Mautnere0a38842013-12-16 16:14:02 -08002496 if (stack.isOnHomeDisplay()) {
2497 moveHomeStack(homeInFront);
2498 mWindowManager.moveTaskToTop(stack.topTask().taskId);
2499 } else {
2500 // Stack was moved to another display while user was swapped out.
2501 resumeHomeActivity(null);
2502 }
Craig Mautner93529a42013-10-04 15:03:13 -07002503 return homeInFront;
Craig Mautner2219a1b2013-03-25 09:44:30 -07002504 }
2505
Craig Mautnerde4ef022013-04-07 19:01:33 -07002506 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2507 int N = mStoppingActivities.size();
2508 if (N <= 0) return null;
2509
2510 ArrayList<ActivityRecord> stops = null;
2511
2512 final boolean nowVisible = allResumedActivitiesVisible();
2513 for (int i=0; i<N; i++) {
2514 ActivityRecord s = mStoppingActivities.get(i);
Craig Mautnera7f2bd42013-10-15 16:13:50 -07002515 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
Craig Mautnerde4ef022013-04-07 19:01:33 -07002516 + nowVisible + " waitingVisible=" + s.waitingVisible
2517 + " finishing=" + s.finishing);
2518 if (s.waitingVisible && nowVisible) {
2519 mWaitingVisibleActivities.remove(s);
2520 s.waitingVisible = false;
2521 if (s.finishing) {
2522 // If this activity is finishing, it is sitting on top of
2523 // everyone else but we now know it is no longer needed...
2524 // so get rid of it. Otherwise, we need to go through the
2525 // normal flow and hide it once we determine that it is
2526 // hidden by the activities in front of it.
2527 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002528 mWindowManager.setAppVisibility(s.appToken, false);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002529 }
2530 }
2531 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2532 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2533 if (stops == null) {
2534 stops = new ArrayList<ActivityRecord>();
2535 }
2536 stops.add(s);
2537 mStoppingActivities.remove(i);
2538 N--;
2539 i--;
2540 }
2541 }
2542
2543 return stops;
2544 }
2545
Craig Mautnercf910b02013-04-23 11:23:27 -07002546 void validateTopActivitiesLocked() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002547 // FIXME
2548/* for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2549 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautnercf910b02013-04-23 11:23:27 -07002550 final ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002551 final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
Craig Mautnercf910b02013-04-23 11:23:27 -07002552 if (isFrontStack(stack)) {
2553 if (r == null) {
2554 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2555 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002556 final ActivityRecord pausing = stack.mPausingActivity;
2557 if (pausing != null && pausing == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002558 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002559 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002560 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002561 if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002562 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002563 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002564 }
2565 }
2566 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002567 final ActivityRecord resumed = stack.mResumedActivity;
2568 if (resumed != null && resumed == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002569 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002570 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002571 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002572 if (r != null && (state == ActivityState.INITIALIZING
2573 || state == ActivityState.RESUMED)) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002574 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002575 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002576 }
2577 }
2578 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002579*/
Craig Mautner76ea2242013-05-15 11:40:05 -07002580 }
2581
Craig Mautner27084302013-03-25 08:05:25 -07002582 public void dump(PrintWriter pw, String prefix) {
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002583 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity=");
Craig Mautner27084302013-03-25 08:05:25 -07002584 pw.println(mDismissKeyguardOnNextActivity);
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002585 pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002586 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002587 pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
2588 pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
2589 pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
Craig Mautner95da1082014-02-24 17:54:35 -08002590 pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
Craig Mautner27084302013-03-25 08:05:25 -07002591 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002592
Craig Mautner20e72272013-04-01 13:45:53 -07002593 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002594 return getFocusedStack().getDumpActivitiesLocked(name);
Craig Mautner20e72272013-04-01 13:45:53 -07002595 }
2596
Dianne Hackborn390517b2013-05-30 15:03:32 -07002597 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2598 boolean needSep, String prefix) {
2599 if (activity != null) {
2600 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2601 if (needSep) {
2602 pw.println();
Dianne Hackborn390517b2013-05-30 15:03:32 -07002603 }
2604 pw.print(prefix);
2605 pw.println(activity);
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002606 return true;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002607 }
2608 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002609 return false;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002610 }
2611
Craig Mautner8d341ef2013-03-26 09:03:27 -07002612 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2613 boolean dumpClient, String dumpPackage) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002614 boolean printed = false;
2615 boolean needSep = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002616 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2617 ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
2618 pw.print("Display #"); pw.println(activityDisplay.mDisplayId);
2619 ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002620 final int numStacks = stacks.size();
2621 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2622 final ActivityStack stack = stacks.get(stackNdx);
2623 StringBuilder stackHeader = new StringBuilder(128);
2624 stackHeader.append(" Stack #");
2625 stackHeader.append(stack.mStackId);
2626 stackHeader.append(":");
2627 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
2628 needSep, stackHeader.toString());
2629 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false,
2630 !dumpAll, false, dumpPackage, true,
2631 " Running activities (most recent first):", null);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002632
Craig Mautner4a1cb222013-12-04 16:14:06 -08002633 needSep = printed;
2634 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
2635 " mPausingActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002636 if (pr) {
2637 printed = true;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002638 needSep = false;
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002639 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002640 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
2641 " mResumedActivity: ");
2642 if (pr) {
2643 printed = true;
2644 needSep = false;
2645 }
2646 if (dumpAll) {
2647 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
2648 " mLastPausedActivity: ");
2649 if (pr) {
2650 printed = true;
2651 needSep = true;
2652 }
2653 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
2654 needSep, " mLastNoHistoryActivity: ");
2655 }
2656 needSep = printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002657 }
2658 }
2659
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002660 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll,
2661 false, dumpPackage, true, " Activities waiting to finish:", null);
2662 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll,
2663 false, dumpPackage, true, " Activities waiting to stop:", null);
2664 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll,
2665 false, dumpPackage, true, " Activities waiting for another to become visible:",
2666 null);
2667 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2668 false, dumpPackage, true, " Activities waiting to sleep:", null);
2669 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2670 false, dumpPackage, true, " Activities waiting to sleep:", null);
Craig Mautnerf3333272013-04-22 10:55:53 -07002671
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002672 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002673 }
2674
Dianne Hackborn390517b2013-05-30 15:03:32 -07002675 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
Craig Mautner8d341ef2013-03-26 09:03:27 -07002676 String prefix, String label, boolean complete, boolean brief, boolean client,
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002677 String dumpPackage, boolean needNL, String header1, String header2) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002678 TaskRecord lastTask = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002679 String innerPrefix = null;
2680 String[] args = null;
2681 boolean printed = false;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002682 for (int i=list.size()-1; i>=0; i--) {
2683 final ActivityRecord r = list.get(i);
2684 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2685 continue;
2686 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002687 if (innerPrefix == null) {
2688 innerPrefix = prefix + " ";
2689 args = new String[0];
2690 }
2691 printed = true;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002692 final boolean full = !brief && (complete || !r.isInHistory());
2693 if (needNL) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07002694 pw.println("");
Craig Mautner8d341ef2013-03-26 09:03:27 -07002695 needNL = false;
2696 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002697 if (header1 != null) {
2698 pw.println(header1);
2699 header1 = null;
2700 }
2701 if (header2 != null) {
2702 pw.println(header2);
2703 header2 = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002704 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002705 if (lastTask != r.task) {
2706 lastTask = r.task;
2707 pw.print(prefix);
2708 pw.print(full ? "* " : " ");
2709 pw.println(lastTask);
2710 if (full) {
2711 lastTask.dump(pw, prefix + " ");
2712 } else if (complete) {
2713 // Complete + brief == give a summary. Isn't that obvious?!?
2714 if (lastTask.intent != null) {
2715 pw.print(prefix); pw.print(" ");
2716 pw.println(lastTask.intent.toInsecureStringWithClip());
2717 }
2718 }
2719 }
2720 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
2721 pw.print(" #"); pw.print(i); pw.print(": ");
2722 pw.println(r);
2723 if (full) {
2724 r.dump(pw, innerPrefix);
2725 } else if (complete) {
2726 // Complete + brief == give a summary. Isn't that obvious?!?
2727 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2728 if (r.app != null) {
2729 pw.print(innerPrefix); pw.println(r.app);
2730 }
2731 }
2732 if (client && r.app != null && r.app.thread != null) {
2733 // flush anything that is already in the PrintWriter since the thread is going
2734 // to write to the file descriptor directly
2735 pw.flush();
2736 try {
2737 TransferPipe tp = new TransferPipe();
2738 try {
2739 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2740 r.appToken, innerPrefix, args);
2741 // Short timeout, since blocking here can
2742 // deadlock with the application.
2743 tp.go(fd, 2000);
2744 } finally {
2745 tp.kill();
2746 }
2747 } catch (IOException e) {
2748 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2749 } catch (RemoteException e) {
2750 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2751 }
2752 needNL = true;
2753 }
2754 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002755 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002756 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002757
Craig Mautnerf3333272013-04-22 10:55:53 -07002758 void scheduleIdleTimeoutLocked(ActivityRecord next) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002759 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
Craig Mautnerc64f73e2013-04-24 16:44:56 -07002760 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2761 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
Craig Mautnerf3333272013-04-22 10:55:53 -07002762 }
2763
2764 final void scheduleIdleLocked() {
Craig Mautner05d29032013-05-03 13:40:13 -07002765 mHandler.sendEmptyMessage(IDLE_NOW_MSG);
Craig Mautnerf3333272013-04-22 10:55:53 -07002766 }
2767
2768 void removeTimeoutsForActivityLocked(ActivityRecord r) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002769 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07002770 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2771 }
2772
Craig Mautner05d29032013-05-03 13:40:13 -07002773 final void scheduleResumeTopActivities() {
Craig Mautner34b73df2014-01-12 21:11:08 -08002774 if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
2775 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2776 }
Craig Mautner05d29032013-05-03 13:40:13 -07002777 }
2778
Craig Mautner0eea92c2013-05-16 13:35:39 -07002779 void removeSleepTimeouts() {
2780 mSleepTimeout = false;
2781 mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2782 }
2783
2784 final void scheduleSleepTimeout() {
2785 removeSleepTimeouts();
2786 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2787 }
2788
Craig Mautner4a1cb222013-12-04 16:14:06 -08002789 @Override
2790 public void onDisplayAdded(int displayId) {
2791 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
2792 }
2793
2794 @Override
2795 public void onDisplayRemoved(int displayId) {
2796 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
2797 }
2798
2799 @Override
2800 public void onDisplayChanged(int displayId) {
2801 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
2802 }
2803
2804 public void handleDisplayAddedLocked(int displayId) {
Craig Mautner4504de52013-12-20 09:06:56 -08002805 boolean newDisplay;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002806 synchronized (mService) {
Craig Mautner4504de52013-12-20 09:06:56 -08002807 newDisplay = mActivityDisplays.get(displayId) == null;
2808 if (newDisplay) {
2809 ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
2810 mActivityDisplays.put(displayId, activityDisplay);
2811 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002812 }
Craig Mautner4504de52013-12-20 09:06:56 -08002813 if (newDisplay) {
2814 mWindowManager.onDisplayAdded(displayId);
2815 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002816 }
2817
2818 public void handleDisplayRemovedLocked(int displayId) {
2819 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002820 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2821 if (activityDisplay != null) {
2822 ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002823 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner34b73df2014-01-12 21:11:08 -08002824 stacks.get(stackNdx).mActivityContainer.detachLocked();
Craig Mautner4a1cb222013-12-04 16:14:06 -08002825 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002826 mActivityDisplays.remove(displayId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002827 }
2828 }
2829 mWindowManager.onDisplayRemoved(displayId);
2830 }
2831
2832 public void handleDisplayChangedLocked(int displayId) {
2833 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002834 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2835 if (activityDisplay != null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002836 // TODO: Update the bounds.
2837 }
2838 }
2839 mWindowManager.onDisplayChanged(displayId);
2840 }
2841
2842 StackInfo getStackInfo(ActivityStack stack) {
2843 StackInfo info = new StackInfo();
2844 mWindowManager.getStackBounds(stack.mStackId, info.bounds);
2845 info.displayId = Display.DEFAULT_DISPLAY;
2846 info.stackId = stack.mStackId;
2847
2848 ArrayList<TaskRecord> tasks = stack.getAllTasks();
2849 final int numTasks = tasks.size();
2850 int[] taskIds = new int[numTasks];
2851 String[] taskNames = new String[numTasks];
2852 for (int i = 0; i < numTasks; ++i) {
2853 final TaskRecord task = tasks.get(i);
2854 taskIds[i] = task.taskId;
2855 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
2856 : task.realActivity != null ? task.realActivity.flattenToString()
2857 : task.getTopActivity() != null ? task.getTopActivity().packageName
2858 : "unknown";
2859 }
2860 info.taskIds = taskIds;
2861 info.taskNames = taskNames;
2862 return info;
2863 }
2864
2865 StackInfo getStackInfoLocked(int stackId) {
2866 ActivityStack stack = getStack(stackId);
2867 if (stack != null) {
2868 return getStackInfo(stack);
2869 }
2870 return null;
2871 }
2872
2873 ArrayList<StackInfo> getAllStackInfosLocked() {
2874 ArrayList<StackInfo> list = new ArrayList<StackInfo>();
Craig Mautnere0a38842013-12-16 16:14:02 -08002875 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2876 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002877 for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
2878 list.add(getStackInfo(stacks.get(ndx)));
2879 }
2880 }
2881 return list;
2882 }
2883
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002884 private final class ActivityStackSupervisorHandler extends Handler {
Craig Mautnerf3333272013-04-22 10:55:53 -07002885
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002886 public ActivityStackSupervisorHandler(Looper looper) {
2887 super(looper);
2888 }
2889
Craig Mautnerf3333272013-04-22 10:55:53 -07002890 void activityIdleInternal(ActivityRecord r) {
2891 synchronized (mService) {
2892 activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
2893 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002894 }
2895
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002896 @Override
2897 public void handleMessage(Message msg) {
2898 switch (msg.what) {
Craig Mautnerf3333272013-04-22 10:55:53 -07002899 case IDLE_TIMEOUT_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002900 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002901 if (mService.mDidDexOpt) {
2902 mService.mDidDexOpt = false;
2903 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2904 nmsg.obj = msg.obj;
2905 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
2906 return;
2907 }
2908 // We don't at this point know if the activity is fullscreen,
2909 // so we need to be conservative and assume it isn't.
2910 activityIdleInternal((ActivityRecord)msg.obj);
2911 } break;
2912 case IDLE_NOW_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002913 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002914 activityIdleInternal((ActivityRecord)msg.obj);
2915 } break;
Craig Mautner05d29032013-05-03 13:40:13 -07002916 case RESUME_TOP_ACTIVITY_MSG: {
2917 synchronized (mService) {
2918 resumeTopActivitiesLocked();
2919 }
2920 } break;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002921 case SLEEP_TIMEOUT_MSG: {
2922 synchronized (mService) {
2923 if (mService.isSleepingOrShuttingDown()) {
2924 Slog.w(TAG, "Sleep timeout! Sleeping now.");
2925 mSleepTimeout = true;
2926 checkReadyForSleepLocked();
2927 }
2928 }
2929 } break;
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002930 case LAUNCH_TIMEOUT_MSG: {
2931 if (mService.mDidDexOpt) {
2932 mService.mDidDexOpt = false;
2933 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
2934 return;
2935 }
2936 synchronized (mService) {
2937 if (mLaunchingActivity.isHeld()) {
2938 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
2939 if (VALIDATE_WAKE_LOCK_CALLER
2940 && Binder.getCallingUid() != Process.myUid()) {
2941 throw new IllegalStateException("Calling must be system uid");
2942 }
2943 mLaunchingActivity.release();
2944 }
2945 }
2946 } break;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002947 case HANDLE_DISPLAY_ADDED: {
2948 handleDisplayAddedLocked(msg.arg1);
2949 } break;
2950 case HANDLE_DISPLAY_CHANGED: {
2951 handleDisplayChangedLocked(msg.arg1);
2952 } break;
2953 case HANDLE_DISPLAY_REMOVED: {
2954 handleDisplayRemovedLocked(msg.arg1);
2955 } break;
Craig Mautnere3a00d72014-04-16 08:31:19 -07002956 case CONTAINER_CALLBACK_VISIBILITY: {
2957 final ActivityContainer container = (ActivityContainer) msg.obj;
2958 try {
2959 // We only send this message if mCallback is non-null.
2960 container.mCallback.setVisible(container.asBinder(), msg.arg1 == 1);
2961 } catch (RemoteException e) {
2962 }
2963 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002964 }
2965 }
2966 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08002967
Craig Mautner4a1cb222013-12-04 16:14:06 -08002968 class ActivityContainer extends IActivityContainer.Stub {
2969 final int mStackId;
2970 final IActivityContainerCallback mCallback;
2971 final ActivityStack mStack;
2972 final ActivityRecord mParentActivity;
Craig Mautner34b73df2014-01-12 21:11:08 -08002973 final String mIdString;
Craig Mautnerbdc748af2013-12-02 14:08:25 -08002974
Craig Mautnere3a00d72014-04-16 08:31:19 -07002975 boolean mVisible = true;
2976
Craig Mautner4a1cb222013-12-04 16:14:06 -08002977 /** Display this ActivityStack is currently on. Null if not attached to a Display. */
Craig Mautnere0a38842013-12-16 16:14:02 -08002978 ActivityDisplay mActivityDisplay;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002979
2980 ActivityContainer(ActivityRecord parentActivity, int stackId,
2981 IActivityContainerCallback callback) {
2982 synchronized (mService) {
2983 mStackId = stackId;
2984 mStack = new ActivityStack(this);
2985 mParentActivity = parentActivity;
2986 mCallback = callback;
Craig Mautner34b73df2014-01-12 21:11:08 -08002987 mIdString = "ActivtyContainer{" + mStackId + ", parent=" + mParentActivity + "}";
2988 if (DEBUG_STACK) Slog.d(TAG, "Creating " + this);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002989 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08002990 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002991
Craig Mautnere0a38842013-12-16 16:14:02 -08002992 void attachToDisplayLocked(ActivityDisplay activityDisplay) {
Craig Mautner34b73df2014-01-12 21:11:08 -08002993 if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this
2994 + " to display=" + activityDisplay);
Craig Mautnere0a38842013-12-16 16:14:02 -08002995 mActivityDisplay = activityDisplay;
2996 mStack.mDisplayId = activityDisplay.mDisplayId;
2997 mStack.mStacks = activityDisplay.mStacks;
2998
2999 activityDisplay.attachActivities(mStack);
Craig Mautnerdf88d732014-01-27 09:21:32 -08003000 mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003001 }
3002
3003 @Override
Jeff Brown38f96e52014-02-11 14:32:56 -08003004 public void attachToDisplay(int displayId) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003005 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08003006 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3007 if (activityDisplay == null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003008 return;
3009 }
Craig Mautnere0a38842013-12-16 16:14:02 -08003010 attachToDisplayLocked(activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003011 }
3012 }
3013
3014 @Override
Jeff Brown38f96e52014-02-11 14:32:56 -08003015 public int getDisplayId() {
Craig Mautnere0a38842013-12-16 16:14:02 -08003016 if (mActivityDisplay != null) {
3017 return mActivityDisplay.mDisplayId;
3018 }
3019 return -1;
Craig Mautner4a1cb222013-12-04 16:14:06 -08003020 }
3021
Jeff Brown38f96e52014-02-11 14:32:56 -08003022 @Override
3023 public boolean injectEvent(InputEvent event) {
3024 final long origId = Binder.clearCallingIdentity();
3025 try {
3026 if (mActivityDisplay != null) {
3027 return mInputManagerInternal.injectInputEvent(event,
3028 mActivityDisplay.mDisplayId,
3029 InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
3030 }
3031 return false;
3032 } finally {
3033 Binder.restoreCallingIdentity(origId);
3034 }
3035 }
3036
Craig Mautner34b73df2014-01-12 21:11:08 -08003037 private void detachLocked() {
3038 if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display="
3039 + mActivityDisplay + " Callers=" + Debug.getCallers(2));
Craig Mautnere0a38842013-12-16 16:14:02 -08003040 if (mActivityDisplay != null) {
3041 mActivityDisplay.detachActivitiesLocked(mStack);
3042 mActivityDisplay = null;
3043 mStack.mDisplayId = -1;
3044 mStack.mStacks = null;
Craig Mautnerdf88d732014-01-27 09:21:32 -08003045 mWindowManager.detachStack(mStackId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003046 }
3047 }
3048
3049 @Override
Jeff Brown38f96e52014-02-11 14:32:56 -08003050 public void detachFromDisplay() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003051 synchronized (mService) {
3052 detachLocked();
3053 }
3054 }
3055
3056 @Override
Craig Mautnere0a38842013-12-16 16:14:02 -08003057 public final int startActivity(Intent intent) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08003058 mService.enforceNotIsolatedCaller("ActivityContainer.startActivity");
Craig Mautnere0a38842013-12-16 16:14:02 -08003059 int userId = mService.handleIncomingUser(Binder.getCallingPid(),
3060 Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null);
3061 // TODO: Switch to user app stacks here.
3062 String mimeType = intent.getType();
3063 if (mimeType == null && intent.getData() != null
3064 && "content".equals(intent.getData().getScheme())) {
3065 mimeType = mService.getProviderMimeType(intent.getData(), userId);
3066 }
3067 return startActivityMayWait(null, -1, null, intent, mimeType, null, null, 0, 0, null,
3068 null, null, null, null, userId, this);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003069 }
3070
3071 @Override
Craig Mautnerdf88d732014-01-27 09:21:32 -08003072 public final int startActivityIntentSender(IIntentSender intentSender) {
3073 mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
3074
3075 if (!(intentSender instanceof PendingIntentRecord)) {
3076 throw new IllegalArgumentException("Bad PendingIntent object");
3077 }
3078
3079 return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null,
3080 null, 0, 0, 0, null, this);
3081 }
3082
3083 @Override
Craig Mautner4a1cb222013-12-04 16:14:06 -08003084 public IBinder asBinder() {
3085 return this;
3086 }
3087
Craig Mautner4504de52013-12-20 09:06:56 -08003088 @Override
Craig Mautner34b73df2014-01-12 21:11:08 -08003089 public void attachToSurface(Surface surface, int width, int height, int density) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08003090 mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
3091
3092 final long origId = Binder.clearCallingIdentity();
3093 try {
3094 synchronized (mService) {
3095 ActivityDisplay activityDisplay =
3096 new ActivityDisplay(surface, width, height, density);
3097 mActivityDisplays.put(activityDisplay.mDisplayId, activityDisplay);
3098 attachToDisplayLocked(activityDisplay);
3099 mStack.resumeTopActivityLocked(null);
3100 }
3101 if (DEBUG_STACK) Slog.d(TAG, "attachToSurface: " + this + " to display="
3102 + mActivityDisplay);
3103 } finally {
3104 Binder.restoreCallingIdentity(origId);
Craig Mautner4504de52013-12-20 09:06:56 -08003105 }
Craig Mautner4504de52013-12-20 09:06:56 -08003106 }
3107
Craig Mautner4a1cb222013-12-04 16:14:06 -08003108 ActivityStackSupervisor getOuter() {
3109 return ActivityStackSupervisor.this;
3110 }
3111
3112 boolean isAttached() {
Craig Mautnere0a38842013-12-16 16:14:02 -08003113 return mActivityDisplay != null;
Craig Mautner4a1cb222013-12-04 16:14:06 -08003114 }
3115
3116 void getBounds(Point outBounds) {
Craig Mautnere0a38842013-12-16 16:14:02 -08003117 if (mActivityDisplay != null) {
3118 mActivityDisplay.getBounds(outBounds);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003119 } else {
3120 outBounds.set(0, 0);
3121 }
3122 }
Craig Mautner34b73df2014-01-12 21:11:08 -08003123
Craig Mautnere3a00d72014-04-16 08:31:19 -07003124 void setVisible(boolean visible) {
3125 if (mVisible != visible) {
3126 mVisible = visible;
3127 if (mCallback != null) {
3128 mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0,
3129 0 /* unused */, this).sendToTarget();
3130 }
3131 }
3132 }
3133
Craig Mautner34b73df2014-01-12 21:11:08 -08003134 @Override
3135 public String toString() {
3136 return mIdString + (mActivityDisplay == null ? "N" : "A");
3137 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003138 }
3139
Craig Mautner4a1cb222013-12-04 16:14:06 -08003140 /** Exactly one of these classes per Display in the system. Capable of holding zero or more
3141 * attached {@link ActivityStack}s */
Craig Mautnere0a38842013-12-16 16:14:02 -08003142 final class ActivityDisplay {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003143 /** Actual Display this object tracks. */
Craig Mautner34b73df2014-01-12 21:11:08 -08003144 int mDisplayId;
3145 Display mDisplay;
3146 DisplayInfo mDisplayInfo = new DisplayInfo();
3147 Surface mSurface;
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003148
Craig Mautner4a1cb222013-12-04 16:14:06 -08003149 /** All of the stacks on this display. Order matters, topmost stack is in front of all other
3150 * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
Craig Mautnere0a38842013-12-16 16:14:02 -08003151 final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003152
Craig Mautner4504de52013-12-20 09:06:56 -08003153 /** If this display is for an ActivityView then the VirtualDisplay created for it is stored
3154 * here. */
3155 VirtualDisplay mVirtualDisplay;
3156
Craig Mautnere0a38842013-12-16 16:14:02 -08003157 ActivityDisplay(int displayId) {
Craig Mautner34b73df2014-01-12 21:11:08 -08003158 init(mDisplayManager.getDisplay(displayId));
Craig Mautner4504de52013-12-20 09:06:56 -08003159 }
3160
Craig Mautner34b73df2014-01-12 21:11:08 -08003161 ActivityDisplay(Surface surface, int width, int height, int density) {
3162 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
3163 long ident = Binder.clearCallingIdentity();
3164 try {
3165 mVirtualDisplay = dm.createVirtualDisplay(mService.mContext,
3166 VIRTUAL_DISPLAY_BASE_NAME, width, height, density, surface,
3167 DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
3168 DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY);
3169 } finally {
3170 Binder.restoreCallingIdentity(ident);
3171 }
3172
3173 init(mVirtualDisplay.getDisplay());
3174 mSurface = surface;
3175
3176 mWindowManager.handleDisplayAdded(mDisplayId);
3177 }
3178
3179 private void init(Display display) {
Craig Mautner4504de52013-12-20 09:06:56 -08003180 mDisplay = display;
3181 mDisplayId = display.getDisplayId();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003182 mDisplay.getDisplayInfo(mDisplayInfo);
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003183 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08003184
3185 void attachActivities(ActivityStack stack) {
Craig Mautnere0a38842013-12-16 16:14:02 -08003186 if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId="
3187 + mDisplayId);
3188 mStacks.add(stack);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003189 }
3190
Craig Mautnere0a38842013-12-16 16:14:02 -08003191 void detachActivitiesLocked(ActivityStack stack) {
Craig Mautner34b73df2014-01-12 21:11:08 -08003192 if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack
Craig Mautnere0a38842013-12-16 16:14:02 -08003193 + " from displayId=" + mDisplayId);
3194 mStacks.remove(stack);
Craig Mautner34b73df2014-01-12 21:11:08 -08003195 if (mStacks.isEmpty() && mVirtualDisplay != null) {
3196 mVirtualDisplay.release();
3197 mVirtualDisplay = null;
3198 }
3199 mSurface.release();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003200 }
3201
3202 void getBounds(Point bounds) {
3203 mDisplay.getDisplayInfo(mDisplayInfo);
3204 bounds.x = mDisplayInfo.appWidth;
3205 bounds.y = mDisplayInfo.appHeight;
3206 }
Craig Mautner34b73df2014-01-12 21:11:08 -08003207
3208 @Override
3209 public String toString() {
3210 return "ActivityDisplay={" + mDisplayId + (mVirtualDisplay == null ? "" : "V")
3211 + " numStacks=" + mStacks.size() + "}";
3212 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003213 }
Craig Mautner27084302013-03-25 08:05:25 -07003214}