blob: 07f76bd07f51d73717b11676cb01aafa310dbb54 [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 Mautnerd00f4742014-03-12 14:17:26 -070020import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
Craig Mautner29219d92013-04-16 20:19:12 -070021import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
22import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
Craig Mautner6170f732013-04-02 13:05:23 -070023import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Craig Mautner2420ead2013-04-01 17:13:20 -070024import static com.android.server.am.ActivityManagerService.localLOGV;
Craig Mautner23ac33b2013-04-01 16:26:35 -070025import static com.android.server.am.ActivityManagerService.DEBUG_CONFIGURATION;
Craig Mautnere7c58b62013-06-12 20:19:00 -070026import static com.android.server.am.ActivityManagerService.DEBUG_FOCUS;
Craig Mautner0eea92c2013-05-16 13:35:39 -070027import static com.android.server.am.ActivityManagerService.DEBUG_PAUSE;
Craig Mautner6170f732013-04-02 13:05:23 -070028import static com.android.server.am.ActivityManagerService.DEBUG_RESULTS;
Craig Mautner0eea92c2013-05-16 13:35:39 -070029import static com.android.server.am.ActivityManagerService.DEBUG_STACK;
Craig Mautner2420ead2013-04-01 17:13:20 -070030import static com.android.server.am.ActivityManagerService.DEBUG_SWITCH;
Craig Mautner8849a5e2013-04-02 16:41:03 -070031import static com.android.server.am.ActivityManagerService.DEBUG_TASKS;
32import static com.android.server.am.ActivityManagerService.DEBUG_USER_LEAVING;
Craig Mautner05d29032013-05-03 13:40:13 -070033import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
Craig Mautner8d341ef2013-03-26 09:03:27 -070034import static com.android.server.am.ActivityManagerService.TAG;
35
Craig Mautner2420ead2013-04-01 17:13:20 -070036import android.app.Activity;
Craig Mautner23ac33b2013-04-01 16:26:35 -070037import android.app.ActivityManager;
Craig Mautnered6649f2013-12-02 14:08:25 -080038import android.app.ActivityManager.StackInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070039import android.app.ActivityOptions;
40import android.app.AppGlobals;
Craig Mautner4a1cb222013-12-04 16:14:06 -080041import android.app.IActivityContainer;
42import android.app.IActivityContainerCallback;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070043import android.app.IActivityManager;
Craig Mautner23ac33b2013-04-01 16:26:35 -070044import android.app.IApplicationThread;
Craig Mautner20e72272013-04-01 13:45:53 -070045import android.app.IThumbnailReceiver;
Craig Mautner23ac33b2013-04-01 16:26:35 -070046import android.app.PendingIntent;
Craig Mautner20e72272013-04-01 13:45:53 -070047import android.app.ActivityManager.RunningTaskInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070048import android.app.IActivityManager.WaitResult;
Craig Mautner2420ead2013-04-01 17:13:20 -070049import android.app.ResultInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070050import android.content.ComponentName;
Craig Mautner2219a1b2013-03-25 09:44:30 -070051import android.content.Context;
Craig Mautner23ac33b2013-04-01 16:26:35 -070052import android.content.IIntentSender;
Craig Mautner2219a1b2013-03-25 09:44:30 -070053import android.content.Intent;
Craig Mautner23ac33b2013-04-01 16:26:35 -070054import android.content.IntentSender;
Craig Mautner2219a1b2013-03-25 09:44:30 -070055import android.content.pm.ActivityInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070056import android.content.pm.ApplicationInfo;
57import android.content.pm.PackageManager;
58import android.content.pm.ResolveInfo;
59import android.content.res.Configuration;
Craig Mautner4a1cb222013-12-04 16:14:06 -080060import android.graphics.Point;
61import android.hardware.display.DisplayManager;
62import android.hardware.display.DisplayManager.DisplayListener;
Craig Mautner4504de52013-12-20 09:06:56 -080063import android.hardware.display.DisplayManagerGlobal;
64import android.hardware.display.VirtualDisplay;
Jeff Brownca9bc702014-02-11 14:32:56 -080065import android.hardware.input.InputManager;
66import android.hardware.input.InputManagerInternal;
Craig Mautner23ac33b2013-04-01 16:26:35 -070067import android.os.Binder;
Craig Mautner8d341ef2013-03-26 09:03:27 -070068import android.os.Bundle;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -070069import android.os.Debug;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070070import android.os.Handler;
Craig Mautner23ac33b2013-04-01 16:26:35 -070071import android.os.IBinder;
Craig Mautner2219a1b2013-03-25 09:44:30 -070072import android.os.Looper;
Craig Mautner2420ead2013-04-01 17:13:20 -070073import android.os.Message;
Craig Mautner23ac33b2013-04-01 16:26:35 -070074import android.os.ParcelFileDescriptor;
Craig Mautner0eea92c2013-05-16 13:35:39 -070075import android.os.PowerManager;
Craig Mautner7ea5bd42013-07-05 15:27:08 -070076import android.os.Process;
Craig Mautner8d341ef2013-03-26 09:03:27 -070077import android.os.RemoteException;
Craig Mautner23ac33b2013-04-01 16:26:35 -070078import android.os.SystemClock;
Craig Mautner6170f732013-04-02 13:05:23 -070079import android.os.UserHandle;
Craig Mautner2420ead2013-04-01 17:13:20 -070080import android.util.EventLog;
Craig Mautner8d341ef2013-03-26 09:03:27 -070081import android.util.Slog;
Craig Mautner4a1cb222013-12-04 16:14:06 -080082import android.util.SparseArray;
Craig Mautner2219a1b2013-03-25 09:44:30 -070083
Craig Mautner4a1cb222013-12-04 16:14:06 -080084import android.util.SparseIntArray;
Craig Mautnered6649f2013-12-02 14:08:25 -080085import android.view.Display;
Craig Mautner4a1cb222013-12-04 16:14:06 -080086import android.view.DisplayInfo;
Jeff Brownca9bc702014-02-11 14:32:56 -080087import android.view.InputEvent;
Craig Mautner4504de52013-12-20 09:06:56 -080088import android.view.Surface;
Craig Mautner23ac33b2013-04-01 16:26:35 -070089import com.android.internal.app.HeavyWeightSwitcherActivity;
Dianne Hackborncbfd23e2013-06-11 14:26:53 -070090import com.android.internal.os.TransferPipe;
Jeff Brownca9bc702014-02-11 14:32:56 -080091import com.android.server.LocalServices;
Craig Mautner6170f732013-04-02 13:05:23 -070092import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
Craig Mautner2420ead2013-04-01 17:13:20 -070093import com.android.server.am.ActivityStack.ActivityState;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070094import com.android.server.wm.WindowManagerService;
Craig Mautner23ac33b2013-04-01 16:26:35 -070095
Craig Mautner8d341ef2013-03-26 09:03:27 -070096import java.io.FileDescriptor;
97import java.io.IOException;
Craig Mautner27084302013-03-25 08:05:25 -070098import java.io.PrintWriter;
Craig Mautner4504de52013-12-20 09:06:56 -080099import java.lang.ref.WeakReference;
Craig Mautner2219a1b2013-03-25 09:44:30 -0700100import java.util.ArrayList;
Craig Mautner8d341ef2013-03-26 09:03:27 -0700101import java.util.List;
Craig Mautner27084302013-03-25 08:05:25 -0700102
Craig Mautner4a1cb222013-12-04 16:14:06 -0800103public final class ActivityStackSupervisor implements DisplayListener {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700104 static final boolean DEBUG = ActivityManagerService.DEBUG || false;
105 static final boolean DEBUG_ADD_REMOVE = DEBUG || false;
106 static final boolean DEBUG_APP = DEBUG || false;
107 static final boolean DEBUG_SAVED_STATE = DEBUG || false;
Craig Mautnera7f2bd42013-10-15 16:13:50 -0700108 static final boolean DEBUG_STATES = DEBUG || false;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -0700109 static final boolean DEBUG_IDLE = DEBUG || false;
Craig Mautner2420ead2013-04-01 17:13:20 -0700110
Craig Mautner2219a1b2013-03-25 09:44:30 -0700111 public static final int HOME_STACK_ID = 0;
Craig Mautner27084302013-03-25 08:05:25 -0700112
Craig Mautnerf3333272013-04-22 10:55:53 -0700113 /** How long we wait until giving up on the last activity telling us it is idle. */
114 static final int IDLE_TIMEOUT = 10*1000;
115
Craig Mautner0eea92c2013-05-16 13:35:39 -0700116 /** How long we can hold the sleep wake lock before giving up. */
117 static final int SLEEP_TIMEOUT = 5*1000;
118
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700119 // How long we can hold the launch wake lock before giving up.
120 static final int LAUNCH_TIMEOUT = 10*1000;
121
Craig Mautner05d29032013-05-03 13:40:13 -0700122 static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG;
123 static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1;
124 static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2;
Craig Mautner0eea92c2013-05-16 13:35:39 -0700125 static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3;
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700126 static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800127 static final int HANDLE_DISPLAY_ADDED = FIRST_SUPERVISOR_STACK_MSG + 5;
128 static final int HANDLE_DISPLAY_CHANGED = FIRST_SUPERVISOR_STACK_MSG + 6;
129 static final int HANDLE_DISPLAY_REMOVED = FIRST_SUPERVISOR_STACK_MSG + 7;
130
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 Brownca9bc702014-02-11 14:32:56 -0800233 InputManagerInternal mInputManagerInternal;
234
Craig Mautneraea74a52014-03-08 14:23:10 -0800235 /** If non-null then the task specified remains in front and no other tasks may be started
236 * until the task exits or #stopLockTaskMode() is called. */
237 private TaskRecord mLockTaskModeTask;
238
Craig Mautner4a1cb222013-12-04 16:14:06 -0800239 public ActivityStackSupervisor(ActivityManagerService service) {
Craig Mautner27084302013-03-25 08:05:25 -0700240 mService = service;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800241 PowerManager pm = (PowerManager)mService.mContext.getSystemService(Context.POWER_SERVICE);
Craig Mautner0eea92c2013-05-16 13:35:39 -0700242 mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
Craig Mautner4a1cb222013-12-04 16:14:06 -0800243 mHandler = new ActivityStackSupervisorHandler(mService.mHandler.getLooper());
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700244 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
245 throw new IllegalStateException("Calling must be system uid");
246 }
247 mLaunchingActivity =
248 pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
249 mLaunchingActivity.setReferenceCounted(false);
Craig Mautner2219a1b2013-03-25 09:44:30 -0700250 }
251
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700252 void setWindowManager(WindowManagerService wm) {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800253 synchronized (mService) {
254 mWindowManager = wm;
255
256 mDisplayManager =
257 (DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE);
258 mDisplayManager.registerDisplayListener(this, null);
259
260 Display[] displays = mDisplayManager.getDisplays();
261 for (int displayNdx = displays.length - 1; displayNdx >= 0; --displayNdx) {
262 final int displayId = displays[displayNdx].getDisplayId();
Craig Mautnere0a38842013-12-16 16:14:02 -0800263 ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
264 mActivityDisplays.put(displayId, activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -0800265 }
266
267 createStackOnDisplay(null, HOME_STACK_ID, Display.DEFAULT_DISPLAY);
268 mHomeStack = mFocusedStack = mLastFocusedStack = getStack(HOME_STACK_ID);
Jeff Brownca9bc702014-02-11 14:32:56 -0800269
270 mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
Craig Mautner4a1cb222013-12-04 16:14:06 -0800271 }
Craig Mautner27084302013-03-25 08:05:25 -0700272 }
273
274 void dismissKeyguard() {
Craig Mautner5314a402013-09-26 12:40:16 -0700275 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen("");
Craig Mautner27084302013-03-25 08:05:25 -0700276 if (mDismissKeyguardOnNextActivity) {
277 mDismissKeyguardOnNextActivity = false;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700278 mWindowManager.dismissKeyguard();
Craig Mautner27084302013-03-25 08:05:25 -0700279 }
280 }
281
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700282 ActivityStack getFocusedStack() {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800283 return mFocusedStack;
Craig Mautner20e72272013-04-01 13:45:53 -0700284 }
285
Craig Mautnerde4ef022013-04-07 19:01:33 -0700286 ActivityStack getLastStack() {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800287 return mLastFocusedStack;
Craig Mautner2219a1b2013-03-25 09:44:30 -0700288 }
289
Craig Mautner4a1cb222013-12-04 16:14:06 -0800290 // TODO: Split into two methods isFrontStack for any visible stack and isFrontmostStack for the
291 // top of all visible stacks.
Craig Mautnerde4ef022013-04-07 19:01:33 -0700292 boolean isFrontStack(ActivityStack stack) {
Craig Mautnerdf88d732014-01-27 09:21:32 -0800293 final ActivityRecord parent = stack.mActivityContainer.mParentActivity;
294 if (parent != null) {
295 stack = parent.task.stack;
296 }
Craig Mautnere0a38842013-12-16 16:14:02 -0800297 ArrayList<ActivityStack> stacks = stack.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800298 if (stacks != null && !stacks.isEmpty()) {
299 return stack == stacks.get(stacks.size() - 1);
300 }
301 return false;
Craig Mautner20e72272013-04-01 13:45:53 -0700302 }
303
Craig Mautnerde4ef022013-04-07 19:01:33 -0700304 void moveHomeStack(boolean toFront) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800305 ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800306 int topNdx = stacks.size() - 1;
307 if (topNdx <= 0) {
308 return;
309 }
310 ActivityStack topStack = stacks.get(topNdx);
311 final boolean homeInFront = topStack == mHomeStack;
312 if (homeInFront != toFront) {
313 mLastFocusedStack = topStack;
314 stacks.remove(mHomeStack);
315 stacks.add(toFront ? topNdx : 0, mHomeStack);
316 mFocusedStack = stacks.get(topNdx);
317 if (DEBUG_STACK) Slog.d(TAG, "moveHomeTask: topStack old=" + topStack + " new="
318 + mFocusedStack);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700319 }
320 }
321
Craig Mautner8e569572013-10-11 17:36:59 -0700322 void moveHomeToTop() {
Craig Mautner69ada552013-04-18 13:51:51 -0700323 moveHomeStack(true);
Craig Mautner8e569572013-10-11 17:36:59 -0700324 mHomeStack.moveHomeTaskToTop();
325 }
326
327 boolean resumeHomeActivity(ActivityRecord prev) {
328 moveHomeToTop();
Craig Mautner69ada552013-04-18 13:51:51 -0700329 if (prev != null) {
Craig Mautnerae7ecab2013-09-18 11:48:14 -0700330 prev.task.mOnTopOfHome = false;
Craig Mautner69ada552013-04-18 13:51:51 -0700331 }
Craig Mautnera8a90e02013-06-28 15:24:50 -0700332 ActivityRecord r = mHomeStack.topRunningActivityLocked(null);
Craig Mautner760b2312013-10-11 11:57:07 -0700333 if (r != null && r.isHomeActivity()) {
Craig Mautnera8a90e02013-06-28 15:24:50 -0700334 mService.setFocusedActivityLocked(r);
Craig Mautner05d29032013-05-03 13:40:13 -0700335 return resumeTopActivitiesLocked(mHomeStack, prev, null);
Craig Mautner69ada552013-04-18 13:51:51 -0700336 }
337 return mService.startHomeActivityLocked(mCurrentUser);
338 }
339
Craig Mautner27084302013-03-25 08:05:25 -0700340 void setDismissKeyguard(boolean dismiss) {
Craig Mautner5314a402013-09-26 12:40:16 -0700341 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen(" dismiss=" + dismiss);
Craig Mautner27084302013-03-25 08:05:25 -0700342 mDismissKeyguardOnNextActivity = dismiss;
343 }
344
Craig Mautner8d341ef2013-03-26 09:03:27 -0700345 TaskRecord anyTaskForIdLocked(int id) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800346 int numDisplays = mActivityDisplays.size();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800347 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800348 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800349 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
350 ActivityStack stack = stacks.get(stackNdx);
351 TaskRecord task = stack.taskForIdLocked(id);
352 if (task != null) {
353 return task;
354 }
Craig Mautner8d341ef2013-03-26 09:03:27 -0700355 }
356 }
357 return null;
358 }
359
Craig Mautner6170f732013-04-02 13:05:23 -0700360 ActivityRecord isInAnyStackLocked(IBinder token) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800361 int numDisplays = mActivityDisplays.size();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800362 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800363 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800364 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
365 final ActivityRecord r = stacks.get(stackNdx).isInStackLocked(token);
366 if (r != null) {
367 return r;
368 }
Craig Mautner6170f732013-04-02 13:05:23 -0700369 }
370 }
371 return null;
372 }
373
Craig Mautner8d341ef2013-03-26 09:03:27 -0700374 int getNextTaskId() {
375 do {
376 mCurTaskId++;
377 if (mCurTaskId <= 0) {
378 mCurTaskId = 1;
379 }
380 } while (anyTaskForIdLocked(mCurTaskId) != null);
381 return mCurTaskId;
382 }
383
Craig Mautnerde4ef022013-04-07 19:01:33 -0700384 ActivityRecord resumedAppLocked() {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700385 ActivityStack stack = getFocusedStack();
386 if (stack == null) {
387 return null;
388 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700389 ActivityRecord resumedActivity = stack.mResumedActivity;
390 if (resumedActivity == null || resumedActivity.app == null) {
391 resumedActivity = stack.mPausingActivity;
392 if (resumedActivity == null || resumedActivity.app == null) {
393 resumedActivity = stack.topRunningActivityLocked(null);
394 }
395 }
396 return resumedActivity;
397 }
398
Mike Lockwooded8902d2013-11-15 11:01:47 -0800399 boolean attachApplicationLocked(ProcessRecord app) throws Exception {
Craig Mautner20e72272013-04-01 13:45:53 -0700400 final String processName = app.processName;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800401 boolean didSomething = false;
Craig Mautnere0a38842013-12-16 16:14:02 -0800402 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
403 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800404 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
405 final ActivityStack stack = stacks.get(stackNdx);
406 if (!isFrontStack(stack)) {
407 continue;
408 }
409 ActivityRecord hr = stack.topRunningActivityLocked(null);
410 if (hr != null) {
411 if (hr.app == null && app.uid == hr.info.applicationInfo.uid
412 && processName.equals(hr.processName)) {
413 try {
George Mount2c92c972014-03-20 09:38:23 -0700414 if (realStartActivityLocked(hr, app, true, true)) {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800415 didSomething = true;
416 }
417 } catch (Exception e) {
418 Slog.w(TAG, "Exception in new application when starting activity "
419 + hr.intent.getComponent().flattenToShortString(), e);
420 throw e;
Craig Mautner20e72272013-04-01 13:45:53 -0700421 }
Craig Mautner20e72272013-04-01 13:45:53 -0700422 }
Craig Mautner20e72272013-04-01 13:45:53 -0700423 }
424 }
425 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -0700426 if (!didSomething) {
427 ensureActivitiesVisibleLocked(null, 0);
428 }
Craig Mautner20e72272013-04-01 13:45:53 -0700429 return didSomething;
430 }
431
432 boolean allResumedActivitiesIdle() {
Craig Mautnere0a38842013-12-16 16:14:02 -0800433 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
434 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800435 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
436 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautner34b73df2014-01-12 21:11:08 -0800437 if (!isFrontStack(stack) || stack.numActivities() == 0) {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800438 continue;
439 }
440 final ActivityRecord resumedActivity = stack.mResumedActivity;
441 if (resumedActivity == null || !resumedActivity.idle) {
Craig Mautner34b73df2014-01-12 21:11:08 -0800442 if (DEBUG_STATES) Slog.d(TAG, "allResumedActivitiesIdle: stack="
443 + stack.mStackId + " " + resumedActivity + " not idle");
Craig Mautner4a1cb222013-12-04 16:14:06 -0800444 return false;
445 }
Craig Mautner20e72272013-04-01 13:45:53 -0700446 }
447 }
448 return true;
449 }
450
Craig Mautnerde4ef022013-04-07 19:01:33 -0700451 boolean allResumedActivitiesComplete() {
Craig Mautnere0a38842013-12-16 16:14:02 -0800452 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
453 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800454 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
455 final ActivityStack stack = stacks.get(stackNdx);
456 if (isFrontStack(stack)) {
457 final ActivityRecord r = stack.mResumedActivity;
458 if (r != null && r.state != ActivityState.RESUMED) {
459 return false;
460 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700461 }
462 }
463 }
464 // TODO: Not sure if this should check if all Paused are complete too.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800465 if (DEBUG_STACK) Slog.d(TAG,
466 "allResumedActivitiesComplete: mLastFocusedStack changing from=" +
467 mLastFocusedStack + " to=" + mFocusedStack);
468 mLastFocusedStack = mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700469 return true;
470 }
471
472 boolean allResumedActivitiesVisible() {
Craig Mautnere0a38842013-12-16 16:14:02 -0800473 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
474 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800475 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
476 final ActivityStack stack = stacks.get(stackNdx);
477 final ActivityRecord r = stack.mResumedActivity;
478 if (r != null && (!r.nowVisible || r.waitingVisible)) {
479 return false;
480 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700481 }
482 }
483 return true;
484 }
485
Craig Mautner2acc3892013-09-23 10:28:14 -0700486 /**
487 * Pause all activities in either all of the stacks or just the back stacks.
488 * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving().
Craig Mautner2acc3892013-09-23 10:28:14 -0700489 * @return true if any activity was paused as a result of this call.
490 */
Craig Mautner5314a402013-09-26 12:40:16 -0700491 boolean pauseBackStacks(boolean userLeaving) {
Craig Mautnercf910b02013-04-23 11:23:27 -0700492 boolean someActivityPaused = false;
Craig Mautnere0a38842013-12-16 16:14:02 -0800493 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
494 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800495 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
496 final ActivityStack stack = stacks.get(stackNdx);
497 if (!isFrontStack(stack) && stack.mResumedActivity != null) {
498 if (DEBUG_STATES) Slog.d(TAG, "pauseBackStacks: stack=" + stack +
499 " mResumedActivity=" + stack.mResumedActivity);
500 stack.startPausingLocked(userLeaving, false);
501 someActivityPaused = true;
502 }
Craig Mautnercf910b02013-04-23 11:23:27 -0700503 }
504 }
505 return someActivityPaused;
506 }
507
Craig Mautnerde4ef022013-04-07 19:01:33 -0700508 boolean allPausedActivitiesComplete() {
Craig Mautnerac6f8432013-07-17 13:24:59 -0700509 boolean pausing = true;
Craig Mautnere0a38842013-12-16 16:14:02 -0800510 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
511 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800512 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
513 final ActivityStack stack = stacks.get(stackNdx);
514 final ActivityRecord r = stack.mPausingActivity;
515 if (r != null && r.state != ActivityState.PAUSED
516 && r.state != ActivityState.STOPPED
517 && r.state != ActivityState.STOPPING) {
518 if (DEBUG_STATES) {
519 Slog.d(TAG, "allPausedActivitiesComplete: r=" + r + " state=" + r.state);
520 pausing = false;
521 } else {
522 return false;
523 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700524 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700525 }
526 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700527 return pausing;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700528 }
529
Craig Mautnerdf88d732014-01-27 09:21:32 -0800530 void pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping) {
John Spurlock8a985d22014-02-25 09:40:05 -0500531 // TODO: Put all stacks in supervisor and iterate through them instead.
Craig Mautnerdf88d732014-01-27 09:21:32 -0800532 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
533 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
534 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
535 final ActivityStack stack = stacks.get(stackNdx);
536 if (stack.mResumedActivity != null &&
537 stack.mActivityContainer.mParentActivity == parent) {
538 stack.startPausingLocked(userLeaving, uiSleeping);
539 }
540 }
541 }
542 }
543
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700544 void reportActivityVisibleLocked(ActivityRecord r) {
Craig Mautner858d8a62013-04-23 17:08:34 -0700545 for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700546 WaitResult w = mWaitingActivityVisible.get(i);
547 w.timeout = false;
548 if (r != null) {
549 w.who = new ComponentName(r.info.packageName, r.info.name);
550 }
551 w.totalTime = SystemClock.uptimeMillis() - w.thisTime;
552 w.thisTime = w.totalTime;
553 }
554 mService.notifyAll();
555 dismissKeyguard();
556 }
557
558 void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r,
559 long thisTime, long totalTime) {
560 for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
Craig Mautnerc64f73e2013-04-24 16:44:56 -0700561 WaitResult w = mWaitingActivityLaunched.remove(i);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700562 w.timeout = timeout;
563 if (r != null) {
564 w.who = new ComponentName(r.info.packageName, r.info.name);
565 }
566 w.thisTime = thisTime;
567 w.totalTime = totalTime;
568 }
569 mService.notifyAll();
570 }
571
Craig Mautner29219d92013-04-16 20:19:12 -0700572 ActivityRecord topRunningActivityLocked() {
Craig Mautner1602ec22013-05-12 10:24:27 -0700573 final ActivityStack focusedStack = getFocusedStack();
574 ActivityRecord r = focusedStack.topRunningActivityLocked(null);
575 if (r != null) {
576 return r;
Craig Mautner29219d92013-04-16 20:19:12 -0700577 }
Craig Mautner1602ec22013-05-12 10:24:27 -0700578
Craig Mautner4a1cb222013-12-04 16:14:06 -0800579 // Return to the home stack.
Craig Mautnere0a38842013-12-16 16:14:02 -0800580 final ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800581 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
582 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautnerac6f8432013-07-17 13:24:59 -0700583 if (stack != focusedStack && isFrontStack(stack)) {
Craig Mautner29219d92013-04-16 20:19:12 -0700584 r = stack.topRunningActivityLocked(null);
585 if (r != null) {
586 return r;
587 }
588 }
589 }
590 return null;
591 }
592
Craig Mautner20e72272013-04-01 13:45:53 -0700593 ActivityRecord getTasksLocked(int maxNum, IThumbnailReceiver receiver,
594 PendingThumbnailsRecord pending, List<RunningTaskInfo> list) {
595 ActivityRecord r = null;
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700596
597 // Gather all of the running tasks for each stack into runningTaskLists.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800598 ArrayList<ArrayList<RunningTaskInfo>> runningTaskLists =
599 new ArrayList<ArrayList<RunningTaskInfo>>();
Craig Mautnere0a38842013-12-16 16:14:02 -0800600 final int numDisplays = mActivityDisplays.size();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800601 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800602 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800603 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
604 final ActivityStack stack = stacks.get(stackNdx);
605 ArrayList<RunningTaskInfo> stackTaskList = new ArrayList<RunningTaskInfo>();
606 runningTaskLists.add(stackTaskList);
607 final ActivityRecord ar = stack.getTasksLocked(receiver, pending, stackTaskList);
608 if (r == null && isFrontStack(stack)) {
609 r = ar;
610 }
Craig Mautner20e72272013-04-01 13:45:53 -0700611 }
612 }
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700613
614 // The lists are already sorted from most recent to oldest. Just pull the most recent off
615 // each list and add it to list. Stop when all lists are empty or maxNum reached.
616 while (maxNum > 0) {
617 long mostRecentActiveTime = Long.MIN_VALUE;
618 ArrayList<RunningTaskInfo> selectedStackList = null;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800619 final int numTaskLists = runningTaskLists.size();
620 for (int stackNdx = 0; stackNdx < numTaskLists; ++stackNdx) {
621 ArrayList<RunningTaskInfo> stackTaskList = runningTaskLists.get(stackNdx);
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700622 if (!stackTaskList.isEmpty()) {
623 final long lastActiveTime = stackTaskList.get(0).lastActiveTime;
624 if (lastActiveTime > mostRecentActiveTime) {
625 mostRecentActiveTime = lastActiveTime;
626 selectedStackList = stackTaskList;
627 }
628 }
629 }
630 if (selectedStackList != null) {
631 list.add(selectedStackList.remove(0));
632 --maxNum;
633 } else {
634 break;
635 }
636 }
637
Craig Mautner20e72272013-04-01 13:45:53 -0700638 return r;
639 }
640
Craig Mautner23ac33b2013-04-01 16:26:35 -0700641 ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
642 String profileFile, ParcelFileDescriptor profileFd, int userId) {
643 // Collect information about the target of the Intent.
644 ActivityInfo aInfo;
645 try {
646 ResolveInfo rInfo =
647 AppGlobals.getPackageManager().resolveIntent(
648 intent, resolvedType,
649 PackageManager.MATCH_DEFAULT_ONLY
650 | ActivityManagerService.STOCK_PM_FLAGS, userId);
651 aInfo = rInfo != null ? rInfo.activityInfo : null;
652 } catch (RemoteException e) {
653 aInfo = null;
654 }
655
656 if (aInfo != null) {
657 // Store the found target back into the intent, because now that
658 // we have it we never want to do this again. For example, if the
659 // user navigates back to this point in the history, we should
660 // always restart the exact same activity.
661 intent.setComponent(new ComponentName(
662 aInfo.applicationInfo.packageName, aInfo.name));
663
664 // Don't debug things in the system process
665 if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) {
666 if (!aInfo.processName.equals("system")) {
667 mService.setDebugApp(aInfo.processName, true, false);
668 }
669 }
670
671 if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) {
672 if (!aInfo.processName.equals("system")) {
673 mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName);
674 }
675 }
676
677 if (profileFile != null) {
678 if (!aInfo.processName.equals("system")) {
679 mService.setProfileApp(aInfo.applicationInfo, aInfo.processName,
680 profileFile, profileFd,
681 (startFlags&ActivityManager.START_FLAG_AUTO_STOP_PROFILER) != 0);
682 }
683 }
684 }
685 return aInfo;
686 }
687
Craig Mautner2219a1b2013-03-25 09:44:30 -0700688 void startHomeActivity(Intent intent, ActivityInfo aInfo) {
Craig Mautner8e569572013-10-11 17:36:59 -0700689 moveHomeToTop();
Craig Mautner6170f732013-04-02 13:05:23 -0700690 startActivityLocked(null, intent, null, aInfo, null, null, 0, 0, 0, null, 0,
Craig Mautnere0a38842013-12-16 16:14:02 -0800691 null, false, null, null);
Craig Mautner8d341ef2013-03-26 09:03:27 -0700692 }
693
Craig Mautner23ac33b2013-04-01 16:26:35 -0700694 final int startActivityMayWait(IApplicationThread caller, int callingUid,
695 String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
696 String resultWho, int requestCode, int startFlags, String profileFile,
697 ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config,
Craig Mautnere0a38842013-12-16 16:14:02 -0800698 Bundle options, int userId, IActivityContainer iContainer) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700699 // Refuse possible leaked file descriptors
700 if (intent != null && intent.hasFileDescriptors()) {
701 throw new IllegalArgumentException("File descriptors passed in Intent");
702 }
703 boolean componentSpecified = intent.getComponent() != null;
704
705 // Don't modify the client's object!
706 intent = new Intent(intent);
707
708 // Collect information about the target of the Intent.
709 ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
710 profileFile, profileFd, userId);
711
Craig Mautnere0a38842013-12-16 16:14:02 -0800712 ActivityContainer container = (ActivityContainer)iContainer;
Craig Mautner23ac33b2013-04-01 16:26:35 -0700713 synchronized (mService) {
714 int callingPid;
715 if (callingUid >= 0) {
716 callingPid = -1;
717 } else if (caller == null) {
718 callingPid = Binder.getCallingPid();
719 callingUid = Binder.getCallingUid();
720 } else {
721 callingPid = callingUid = -1;
722 }
723
Craig Mautnere0a38842013-12-16 16:14:02 -0800724 final ActivityStack stack;
725 if (container == null || container.mStack.isOnHomeDisplay()) {
726 stack = getFocusedStack();
727 } else {
728 stack = container.mStack;
729 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700730 stack.mConfigWillChange = config != null
Craig Mautner23ac33b2013-04-01 16:26:35 -0700731 && mService.mConfiguration.diff(config) != 0;
732 if (DEBUG_CONFIGURATION) Slog.v(TAG,
Craig Mautnerde4ef022013-04-07 19:01:33 -0700733 "Starting activity when config will change = " + stack.mConfigWillChange);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700734
735 final long origId = Binder.clearCallingIdentity();
736
737 if (aInfo != null &&
738 (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
739 // This may be a heavy-weight process! Check to see if we already
740 // have another, different heavy-weight process running.
741 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
742 if (mService.mHeavyWeightProcess != null &&
743 (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid ||
744 !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700745 int realCallingUid = callingUid;
746 if (caller != null) {
747 ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
748 if (callerApp != null) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700749 realCallingUid = callerApp.info.uid;
750 } else {
751 Slog.w(TAG, "Unable to find app for caller " + caller
Craig Mautner76ea2242013-05-15 11:40:05 -0700752 + " (pid=" + callingPid + ") when starting: "
Craig Mautner23ac33b2013-04-01 16:26:35 -0700753 + intent.toString());
754 ActivityOptions.abort(options);
755 return ActivityManager.START_PERMISSION_DENIED;
756 }
757 }
758
759 IIntentSender target = mService.getIntentSenderLocked(
760 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
761 realCallingUid, userId, null, null, 0, new Intent[] { intent },
762 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
763 | PendingIntent.FLAG_ONE_SHOT, null);
764
765 Intent newIntent = new Intent();
766 if (requestCode >= 0) {
767 // Caller is requesting a result.
768 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
769 }
770 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
771 new IntentSender(target));
772 if (mService.mHeavyWeightProcess.activities.size() > 0) {
773 ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0);
774 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
775 hist.packageName);
776 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
777 hist.task.taskId);
778 }
779 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
780 aInfo.packageName);
781 newIntent.setFlags(intent.getFlags());
782 newIntent.setClassName("android",
783 HeavyWeightSwitcherActivity.class.getName());
784 intent = newIntent;
785 resolvedType = null;
786 caller = null;
787 callingUid = Binder.getCallingUid();
788 callingPid = Binder.getCallingPid();
789 componentSpecified = true;
790 try {
791 ResolveInfo rInfo =
792 AppGlobals.getPackageManager().resolveIntent(
793 intent, null,
794 PackageManager.MATCH_DEFAULT_ONLY
795 | ActivityManagerService.STOCK_PM_FLAGS, userId);
796 aInfo = rInfo != null ? rInfo.activityInfo : null;
797 aInfo = mService.getActivityInfoForUser(aInfo, userId);
798 } catch (RemoteException e) {
799 aInfo = null;
800 }
801 }
802 }
803 }
804
Craig Mautnere0a38842013-12-16 16:14:02 -0800805 int res = startActivityLocked(caller, intent, resolvedType, aInfo, resultTo, resultWho,
806 requestCode, callingPid, callingUid, callingPackage, startFlags, options,
807 componentSpecified, null, container);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700808
Craig Mautnerde4ef022013-04-07 19:01:33 -0700809 if (stack.mConfigWillChange) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700810 // If the caller also wants to switch to a new configuration,
811 // do so now. This allows a clean switch, as we are waiting
812 // for the current activity to pause (so we will not destroy
813 // it), and have not yet started the next activity.
814 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
815 "updateConfiguration()");
Craig Mautnerde4ef022013-04-07 19:01:33 -0700816 stack.mConfigWillChange = false;
Craig Mautner23ac33b2013-04-01 16:26:35 -0700817 if (DEBUG_CONFIGURATION) Slog.v(TAG,
818 "Updating to new configuration after starting activity.");
819 mService.updateConfigurationLocked(config, null, false, false);
820 }
821
822 Binder.restoreCallingIdentity(origId);
823
824 if (outResult != null) {
825 outResult.result = res;
826 if (res == ActivityManager.START_SUCCESS) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700827 mWaitingActivityLaunched.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700828 do {
829 try {
830 mService.wait();
831 } catch (InterruptedException e) {
832 }
833 } while (!outResult.timeout && outResult.who == null);
834 } else if (res == ActivityManager.START_TASK_TO_FRONT) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700835 ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700836 if (r.nowVisible) {
837 outResult.timeout = false;
838 outResult.who = new ComponentName(r.info.packageName, r.info.name);
839 outResult.totalTime = 0;
840 outResult.thisTime = 0;
841 } else {
842 outResult.thisTime = SystemClock.uptimeMillis();
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700843 mWaitingActivityVisible.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700844 do {
845 try {
846 mService.wait();
847 } catch (InterruptedException e) {
848 }
849 } while (!outResult.timeout && outResult.who == null);
850 }
851 }
852 }
853
854 return res;
855 }
856 }
857
858 final int startActivities(IApplicationThread caller, int callingUid, String callingPackage,
859 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
860 Bundle options, int userId) {
861 if (intents == null) {
862 throw new NullPointerException("intents is null");
863 }
864 if (resolvedTypes == null) {
865 throw new NullPointerException("resolvedTypes is null");
866 }
867 if (intents.length != resolvedTypes.length) {
868 throw new IllegalArgumentException("intents are length different than resolvedTypes");
869 }
870
Craig Mautner23ac33b2013-04-01 16:26:35 -0700871
872 int callingPid;
873 if (callingUid >= 0) {
874 callingPid = -1;
875 } else if (caller == null) {
876 callingPid = Binder.getCallingPid();
877 callingUid = Binder.getCallingUid();
878 } else {
879 callingPid = callingUid = -1;
880 }
881 final long origId = Binder.clearCallingIdentity();
882 try {
883 synchronized (mService) {
Craig Mautner76ea2242013-05-15 11:40:05 -0700884 ActivityRecord[] outActivity = new ActivityRecord[1];
Craig Mautner23ac33b2013-04-01 16:26:35 -0700885 for (int i=0; i<intents.length; i++) {
886 Intent intent = intents[i];
887 if (intent == null) {
888 continue;
889 }
890
891 // Refuse possible leaked file descriptors
892 if (intent != null && intent.hasFileDescriptors()) {
893 throw new IllegalArgumentException("File descriptors passed in Intent");
894 }
895
896 boolean componentSpecified = intent.getComponent() != null;
897
898 // Don't modify the client's object!
899 intent = new Intent(intent);
900
901 // Collect information about the target of the Intent.
902 ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i],
903 0, null, null, userId);
904 // TODO: New, check if this is correct
905 aInfo = mService.getActivityInfoForUser(aInfo, userId);
906
907 if (aInfo != null &&
908 (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE)
909 != 0) {
910 throw new IllegalArgumentException(
911 "FLAG_CANT_SAVE_STATE not supported here");
912 }
913
914 Bundle theseOptions;
915 if (options != null && i == intents.length-1) {
916 theseOptions = options;
917 } else {
918 theseOptions = null;
919 }
Craig Mautner6170f732013-04-02 13:05:23 -0700920 int res = startActivityLocked(caller, intent, resolvedTypes[i],
Craig Mautner23ac33b2013-04-01 16:26:35 -0700921 aInfo, resultTo, null, -1, callingPid, callingUid, callingPackage,
Craig Mautnere0a38842013-12-16 16:14:02 -0800922 0, theseOptions, componentSpecified, outActivity, null);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700923 if (res < 0) {
924 return res;
925 }
926
927 resultTo = outActivity[0] != null ? outActivity[0].appToken : null;
928 }
929 }
930 } finally {
931 Binder.restoreCallingIdentity(origId);
932 }
933
934 return ActivityManager.START_SUCCESS;
935 }
936
Craig Mautner2420ead2013-04-01 17:13:20 -0700937 final boolean realStartActivityLocked(ActivityRecord r,
George Mount2c92c972014-03-20 09:38:23 -0700938 ProcessRecord app, boolean andResume, boolean checkConfig)
Craig Mautner2420ead2013-04-01 17:13:20 -0700939 throws RemoteException {
940
941 r.startFreezingScreenLocked(app, 0);
Craig Mautnera7f2bd42013-10-15 16:13:50 -0700942 if (false) Slog.d(TAG, "realStartActivity: setting app visibility true");
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700943 mWindowManager.setAppVisibility(r.appToken, true);
Craig Mautner2420ead2013-04-01 17:13:20 -0700944
945 // schedule launch ticks to collect information about slow apps.
946 r.startLaunchTickingLocked();
947
948 // Have the window manager re-evaluate the orientation of
949 // the screen based on the new activity order. Note that
950 // as a result of this, it can call back into the activity
951 // manager with a new orientation. We don't care about that,
952 // because the activity is not currently running so we are
953 // just restarting it anyway.
954 if (checkConfig) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700955 Configuration config = mWindowManager.updateOrientationFromAppTokens(
Craig Mautner2420ead2013-04-01 17:13:20 -0700956 mService.mConfiguration,
957 r.mayFreezeScreenLocked(app) ? r.appToken : null);
958 mService.updateConfigurationLocked(config, r, false, false);
959 }
960
961 r.app = app;
962 app.waitingToKill = null;
963 r.launchCount++;
964 r.lastLaunchTime = SystemClock.uptimeMillis();
965
966 if (localLOGV) Slog.v(TAG, "Launching: " + r);
967
968 int idx = app.activities.indexOf(r);
969 if (idx < 0) {
970 app.activities.add(r);
971 }
Dianne Hackborndb926082013-10-31 16:32:44 -0700972 mService.updateLruProcessLocked(app, true, null);
973 mService.updateOomAdjLocked();
Craig Mautner2420ead2013-04-01 17:13:20 -0700974
975 final ActivityStack stack = r.task.stack;
976 try {
977 if (app.thread == null) {
978 throw new RemoteException();
979 }
980 List<ResultInfo> results = null;
981 List<Intent> newIntents = null;
982 if (andResume) {
983 results = r.results;
984 newIntents = r.newIntents;
985 }
986 if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r
987 + " icicle=" + r.icicle
988 + " with results=" + results + " newIntents=" + newIntents
989 + " andResume=" + andResume);
990 if (andResume) {
991 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
992 r.userId, System.identityHashCode(r),
993 r.task.taskId, r.shortComponentName);
994 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700995 if (r.isHomeActivity() && r.isNotResolverActivity()) {
Craig Mautner4ef26932013-09-18 15:15:52 -0700996 // Home process is the root process of the task.
997 mService.mHomeProcess = r.task.mActivities.get(0).app;
Craig Mautner2420ead2013-04-01 17:13:20 -0700998 }
999 mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
1000 r.sleeping = false;
1001 r.forceNewConfig = false;
1002 mService.showAskCompatModeDialogLocked(r);
1003 r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
1004 String profileFile = null;
1005 ParcelFileDescriptor profileFd = null;
1006 boolean profileAutoStop = false;
1007 if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
1008 if (mService.mProfileProc == null || mService.mProfileProc == app) {
1009 mService.mProfileProc = app;
1010 profileFile = mService.mProfileFile;
1011 profileFd = mService.mProfileFd;
1012 profileAutoStop = mService.mAutoStopProfiler;
1013 }
1014 }
1015 app.hasShownUi = true;
1016 app.pendingUiClean = true;
1017 if (profileFd != null) {
1018 try {
1019 profileFd = profileFd.dup();
1020 } catch (IOException e) {
1021 if (profileFd != null) {
1022 try {
1023 profileFd.close();
1024 } catch (IOException o) {
1025 }
1026 profileFd = null;
1027 }
1028 }
1029 }
Adam Powellcfbe9be2013-11-06 14:58:58 -08001030
Dianne Hackborna413dc02013-07-12 12:02:55 -07001031 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
George Mount2c92c972014-03-20 09:38:23 -07001032 Bundle options = (r.pendingOptions == null) ? null : r.pendingOptions.toBundle();
1033 r.clearOptionsLocked();
Craig Mautner2420ead2013-04-01 17:13:20 -07001034 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
1035 System.identityHashCode(r), r.info,
Dianne Hackborna413dc02013-07-12 12:02:55 -07001036 new Configuration(mService.mConfiguration), r.compat,
1037 app.repProcState, r.icicle, results, newIntents, !andResume,
Craig Mautner2420ead2013-04-01 17:13:20 -07001038 mService.isNextTransitionForward(), profileFile, profileFd,
George Mount2c92c972014-03-20 09:38:23 -07001039 profileAutoStop, options);
Craig Mautner2420ead2013-04-01 17:13:20 -07001040
1041 if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
1042 // This may be a heavy-weight process! Note that the package
1043 // manager will ensure that only activity can run in the main
1044 // process of the .apk, which is the only thing that will be
1045 // considered heavy-weight.
1046 if (app.processName.equals(app.info.packageName)) {
1047 if (mService.mHeavyWeightProcess != null
1048 && mService.mHeavyWeightProcess != app) {
1049 Slog.w(TAG, "Starting new heavy weight process " + app
1050 + " when already running "
1051 + mService.mHeavyWeightProcess);
1052 }
1053 mService.mHeavyWeightProcess = app;
1054 Message msg = mService.mHandler.obtainMessage(
1055 ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
1056 msg.obj = r;
1057 mService.mHandler.sendMessage(msg);
1058 }
1059 }
1060
1061 } catch (RemoteException e) {
1062 if (r.launchFailed) {
1063 // This is the second time we failed -- finish activity
1064 // and give up.
1065 Slog.e(TAG, "Second failure launching "
1066 + r.intent.getComponent().flattenToShortString()
1067 + ", giving up", e);
1068 mService.appDiedLocked(app, app.pid, app.thread);
1069 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
1070 "2nd-crash", false);
1071 return false;
1072 }
1073
1074 // This is the first time we failed -- restart process and
1075 // retry.
1076 app.activities.remove(r);
1077 throw e;
1078 }
1079
1080 r.launchFailed = false;
1081 if (stack.updateLRUListLocked(r)) {
1082 Slog.w(TAG, "Activity " + r
1083 + " being launched, but already in LRU list");
1084 }
1085
1086 if (andResume) {
1087 // As part of the process of launching, ActivityThread also performs
1088 // a resume.
1089 stack.minimalResumeActivityLocked(r);
1090 } else {
1091 // This activity is not starting in the resumed state... which
1092 // should look like we asked it to pause+stop (but remain visible),
1093 // and it has done so and reported back the current icicle and
1094 // other state.
1095 if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r
1096 + " (starting in stopped state)");
1097 r.state = ActivityState.STOPPED;
1098 r.stopped = true;
1099 }
1100
1101 // Launch the new version setup screen if needed. We do this -after-
1102 // launching the initial activity (that is, home), so that it can have
1103 // a chance to initialize itself while in the background, making the
1104 // switch back to it faster and look better.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001105 if (isFrontStack(stack)) {
Craig Mautner2420ead2013-04-01 17:13:20 -07001106 mService.startSetupActivityLocked();
1107 }
1108
1109 return true;
1110 }
1111
Craig Mautnere79d42682013-04-01 19:01:53 -07001112 void startSpecificActivityLocked(ActivityRecord r,
George Mount2c92c972014-03-20 09:38:23 -07001113 boolean andResume, boolean checkConfig) {
Craig Mautnere79d42682013-04-01 19:01:53 -07001114 // Is this activity's application already running?
1115 ProcessRecord app = mService.getProcessRecordLocked(r.processName,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001116 r.info.applicationInfo.uid, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001117
1118 r.task.stack.setLaunchTime(r);
1119
1120 if (app != null && app.thread != null) {
1121 try {
Dianne Hackborn237cefb2013-10-22 18:45:27 -07001122 if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
1123 || !"android".equals(r.info.packageName)) {
1124 // Don't add this if it is a platform component that is marked
1125 // to run in multiple processes, because this is actually
1126 // part of the framework so doesn't make sense to track as a
1127 // separate apk in the process.
1128 app.addPackage(r.info.packageName, mService.mProcessStats);
1129 }
George Mount2c92c972014-03-20 09:38:23 -07001130 realStartActivityLocked(r, app, andResume, checkConfig);
Craig Mautnere79d42682013-04-01 19:01:53 -07001131 return;
1132 } catch (RemoteException e) {
1133 Slog.w(TAG, "Exception when starting activity "
1134 + r.intent.getComponent().flattenToShortString(), e);
1135 }
1136
1137 // If a dead object exception was thrown -- fall through to
1138 // restart the application.
1139 }
1140
1141 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001142 "activity", r.intent.getComponent(), false, false, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001143 }
1144
Craig Mautner6170f732013-04-02 13:05:23 -07001145 final int startActivityLocked(IApplicationThread caller,
1146 Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
1147 String resultWho, int requestCode,
1148 int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
Craig Mautnere0a38842013-12-16 16:14:02 -08001149 boolean componentSpecified, ActivityRecord[] outActivity, ActivityContainer container) {
Craig Mautner6170f732013-04-02 13:05:23 -07001150 int err = ActivityManager.START_SUCCESS;
1151
1152 ProcessRecord callerApp = null;
1153 if (caller != null) {
1154 callerApp = mService.getRecordForAppLocked(caller);
1155 if (callerApp != null) {
1156 callingPid = callerApp.pid;
1157 callingUid = callerApp.info.uid;
1158 } else {
1159 Slog.w(TAG, "Unable to find app for caller " + caller
1160 + " (pid=" + callingPid + ") when starting: "
1161 + intent.toString());
1162 err = ActivityManager.START_PERMISSION_DENIED;
1163 }
1164 }
1165
1166 if (err == ActivityManager.START_SUCCESS) {
1167 final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
1168 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
Craig Mautner9ef471f2014-02-07 13:11:47 -08001169 + "} from pid " + (callerApp != null ? callerApp.pid : callingPid)
1170 + " on display " + (container == null ? (mFocusedStack == null ?
1171 Display.DEFAULT_DISPLAY : mFocusedStack.mDisplayId) :
1172 (container.mActivityDisplay == null ? Display.DEFAULT_DISPLAY :
1173 container.mActivityDisplay.mDisplayId)));
Craig Mautner6170f732013-04-02 13:05:23 -07001174 }
1175
1176 ActivityRecord sourceRecord = null;
1177 ActivityRecord resultRecord = null;
1178 if (resultTo != null) {
1179 sourceRecord = isInAnyStackLocked(resultTo);
1180 if (DEBUG_RESULTS) Slog.v(
1181 TAG, "Will send result to " + resultTo + " " + sourceRecord);
1182 if (sourceRecord != null) {
1183 if (requestCode >= 0 && !sourceRecord.finishing) {
1184 resultRecord = sourceRecord;
1185 }
1186 }
1187 }
1188 ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
1189
1190 int launchFlags = intent.getFlags();
1191
1192 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
1193 && sourceRecord != null) {
1194 // Transfer the result target from the source activity to the new
1195 // one being started, including any failures.
1196 if (requestCode >= 0) {
1197 ActivityOptions.abort(options);
1198 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
1199 }
1200 resultRecord = sourceRecord.resultTo;
1201 resultWho = sourceRecord.resultWho;
1202 requestCode = sourceRecord.requestCode;
1203 sourceRecord.resultTo = null;
1204 if (resultRecord != null) {
1205 resultRecord.removeResultsLocked(
1206 sourceRecord, resultWho, requestCode);
1207 }
Dianne Hackbornd4981012014-03-14 16:27:40 +00001208 if (sourceRecord.launchedFromUid == callingUid) {
1209 // The new activity is being launched from the same uid as the previous
1210 // activity in the flow, and asking to forward its result back to the
1211 // previous. In this case the activity is serving as a trampoline between
1212 // the two, so we also want to update its launchedFromPackage to be the
1213 // same as the previous activity. Note that this is safe, since we know
1214 // these two packages come from the same uid; the caller could just as
1215 // well have supplied that same package name itself. This specifially
1216 // deals with the case of an intent picker/chooser being launched in the app
1217 // flow to redirect to an activity picked by the user, where we want the final
1218 // activity to consider it to have been launched by the previous app activity.
1219 callingPackage = sourceRecord.launchedFromPackage;
1220 }
Craig Mautner6170f732013-04-02 13:05:23 -07001221 }
1222
1223 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
1224 // We couldn't find a class that can handle the given Intent.
1225 // That's the end of that!
1226 err = ActivityManager.START_INTENT_NOT_RESOLVED;
1227 }
1228
1229 if (err == ActivityManager.START_SUCCESS && aInfo == null) {
1230 // We couldn't find the specific class specified in the Intent.
1231 // Also the end of the line.
1232 err = ActivityManager.START_CLASS_NOT_FOUND;
1233 }
1234
1235 if (err != ActivityManager.START_SUCCESS) {
1236 if (resultRecord != null) {
1237 resultStack.sendActivityResultLocked(-1,
1238 resultRecord, resultWho, requestCode,
1239 Activity.RESULT_CANCELED, null);
1240 }
1241 setDismissKeyguard(false);
1242 ActivityOptions.abort(options);
1243 return err;
1244 }
1245
1246 final int startAnyPerm = mService.checkPermission(
1247 START_ANY_ACTIVITY, callingPid, callingUid);
1248 final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
1249 callingUid, aInfo.applicationInfo.uid, aInfo.exported);
1250 if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
1251 if (resultRecord != null) {
1252 resultStack.sendActivityResultLocked(-1,
1253 resultRecord, resultWho, requestCode,
1254 Activity.RESULT_CANCELED, null);
1255 }
1256 setDismissKeyguard(false);
1257 String msg;
1258 if (!aInfo.exported) {
1259 msg = "Permission Denial: starting " + intent.toString()
1260 + " from " + callerApp + " (pid=" + callingPid
1261 + ", uid=" + callingUid + ")"
1262 + " not exported from uid " + aInfo.applicationInfo.uid;
1263 } else {
1264 msg = "Permission Denial: starting " + intent.toString()
1265 + " from " + callerApp + " (pid=" + callingPid
1266 + ", uid=" + callingUid + ")"
1267 + " requires " + aInfo.permission;
1268 }
1269 Slog.w(TAG, msg);
1270 throw new SecurityException(msg);
1271 }
1272
Ben Gruverdd72c9e2013-08-06 12:34:17 -07001273 boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
Ben Gruverb6223792013-07-29 16:35:40 -07001274 callingPid, resolvedType, aInfo.applicationInfo);
Ben Gruver5e207332013-04-03 17:41:37 -07001275
Craig Mautner6170f732013-04-02 13:05:23 -07001276 if (mService.mController != null) {
Craig Mautner6170f732013-04-02 13:05:23 -07001277 try {
1278 // The Intent we give to the watcher has the extra data
1279 // stripped off, since it can contain private information.
1280 Intent watchIntent = intent.cloneFilter();
Ben Gruver5e207332013-04-03 17:41:37 -07001281 abort |= !mService.mController.activityStarting(watchIntent,
Craig Mautner6170f732013-04-02 13:05:23 -07001282 aInfo.applicationInfo.packageName);
1283 } catch (RemoteException e) {
1284 mService.mController = null;
1285 }
Ben Gruver5e207332013-04-03 17:41:37 -07001286 }
Craig Mautner6170f732013-04-02 13:05:23 -07001287
Ben Gruver5e207332013-04-03 17:41:37 -07001288 if (abort) {
1289 if (resultRecord != null) {
1290 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
Craig Mautner6170f732013-04-02 13:05:23 -07001291 Activity.RESULT_CANCELED, null);
Craig Mautner6170f732013-04-02 13:05:23 -07001292 }
Ben Gruver5e207332013-04-03 17:41:37 -07001293 // We pretend to the caller that it was really started, but
1294 // they will just get a cancel result.
1295 setDismissKeyguard(false);
1296 ActivityOptions.abort(options);
1297 return ActivityManager.START_SUCCESS;
Craig Mautner6170f732013-04-02 13:05:23 -07001298 }
1299
1300 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
Craig Mautnere0a38842013-12-16 16:14:02 -08001301 intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
1302 requestCode, componentSpecified, this, container);
Craig Mautner6170f732013-04-02 13:05:23 -07001303 if (outActivity != null) {
1304 outActivity[0] = r;
1305 }
1306
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001307 final ActivityStack stack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001308 if (stack.mResumedActivity == null
1309 || stack.mResumedActivity.info.applicationInfo.uid != callingUid) {
Craig Mautner6170f732013-04-02 13:05:23 -07001310 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
1311 PendingActivityLaunch pal =
Craig Mautnerde4ef022013-04-07 19:01:33 -07001312 new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
Craig Mautner6170f732013-04-02 13:05:23 -07001313 mService.mPendingActivityLaunches.add(pal);
1314 setDismissKeyguard(false);
1315 ActivityOptions.abort(options);
1316 return ActivityManager.START_SWITCHES_CANCELED;
1317 }
1318 }
1319
1320 if (mService.mDidAppSwitch) {
1321 // This is the second allowed switch since we stopped switches,
1322 // so now just generally allow switches. Use case: user presses
1323 // home (switches disabled, switch to home, mDidAppSwitch now true);
1324 // user taps a home icon (coming from home so allowed, we hit here
1325 // and now allow anyone to switch again).
1326 mService.mAppSwitchesAllowedTime = 0;
1327 } else {
1328 mService.mDidAppSwitch = true;
1329 }
1330
1331 mService.doPendingActivityLaunchesLocked(false);
1332
Craig Mautner8849a5e2013-04-02 16:41:03 -07001333 err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
Craig Mautner10385a12013-09-22 21:08:32 -07001334
1335 if (allPausedActivitiesComplete()) {
1336 // If someone asked to have the keyguard dismissed on the next
Craig Mautner6170f732013-04-02 13:05:23 -07001337 // activity start, but we are not actually doing an activity
1338 // switch... just dismiss the keyguard now, because we
1339 // probably want to see whatever is behind it.
1340 dismissKeyguard();
1341 }
1342 return err;
1343 }
1344
Craig Mautnerac6f8432013-07-17 13:24:59 -07001345 ActivityStack adjustStackFocus(ActivityRecord r) {
Craig Mautner1d001b62013-06-18 16:52:43 -07001346 final TaskRecord task = r.task;
1347 if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001348 if (task != null) {
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07001349 final ActivityStack taskStack = task.stack;
Craig Mautnere0a38842013-12-16 16:14:02 -08001350 if (taskStack.isOnHomeDisplay()) {
1351 if (mFocusedStack != taskStack) {
1352 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: Setting " +
1353 "focused stack to r=" + r + " task=" + task);
1354 mFocusedStack = taskStack;
1355 } else {
1356 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1357 "adjustStackFocus: Focused stack already=" + mFocusedStack);
1358 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001359 }
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07001360 return taskStack;
Craig Mautnerac6f8432013-07-17 13:24:59 -07001361 }
1362
Craig Mautnere0a38842013-12-16 16:14:02 -08001363 final ActivityContainer container = r.mInitialActivityContainer;
1364 if (container != null) {
1365 // The first time put it on the desired stack, after this put on task stack.
1366 r.mInitialActivityContainer = null;
1367 return container.mStack;
1368 }
1369
Craig Mautner4a1cb222013-12-04 16:14:06 -08001370 if (mFocusedStack != mHomeStack) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001371 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1372 "adjustStackFocus: Have a focused stack=" + mFocusedStack);
1373 return mFocusedStack;
1374 }
1375
Craig Mautnere0a38842013-12-16 16:14:02 -08001376 final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks;
1377 for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1378 final ActivityStack stack = homeDisplayStacks.get(stackNdx);
1379 if (!stack.isHomeStack()) {
1380 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1381 "adjustStackFocus: Setting focused stack=" + stack);
1382 mFocusedStack = stack;
1383 return mFocusedStack;
Craig Mautner858d8a62013-04-23 17:08:34 -07001384 }
1385 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001386
Craig Mautner4a1cb222013-12-04 16:14:06 -08001387 // Need to create an app stack for this user.
1388 int stackId = createStackOnDisplay(null, getNextStackId(), Display.DEFAULT_DISPLAY);
Craig Mautnerac6f8432013-07-17 13:24:59 -07001389 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r +
1390 " stackId=" + stackId);
1391 mFocusedStack = getStack(stackId);
Craig Mautner29219d92013-04-16 20:19:12 -07001392 return mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001393 }
1394 return mHomeStack;
1395 }
1396
Craig Mautner29219d92013-04-16 20:19:12 -07001397 void setFocusedStack(ActivityRecord r) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08001398 if (r != null) {
Craig Mautner12ff7392014-02-21 21:08:00 -08001399 final TaskRecord task = r.task;
1400 boolean isHomeActivity = !r.isApplicationActivity();
1401 if (!isHomeActivity && task != null) {
1402 isHomeActivity = !task.isApplicationTask();
1403 }
1404 if (!isHomeActivity && task != null) {
1405 final ActivityRecord parent = task.stack.mActivityContainer.mParentActivity;
1406 isHomeActivity = parent != null && parent.isHomeActivity();
1407 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08001408 moveHomeStack(isHomeActivity);
Craig Mautner29219d92013-04-16 20:19:12 -07001409 }
1410 }
1411
Craig Mautner8849a5e2013-04-02 16:41:03 -07001412 final int startActivityUncheckedLocked(ActivityRecord r,
1413 ActivityRecord sourceRecord, int startFlags, boolean doResume,
1414 Bundle options) {
1415 final Intent intent = r.intent;
1416 final int callingUid = r.launchedFromUid;
1417
1418 int launchFlags = intent.getFlags();
1419
Craig Mautner8849a5e2013-04-02 16:41:03 -07001420 // We'll invoke onUserLeaving before onPause only if the launching
1421 // activity did not explicitly state that this is an automated launch.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001422 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1423 if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001424
1425 // If the caller has asked not to resume at this point, we make note
1426 // of this in the record so that we can skip it when trying to find
1427 // the top running activity.
1428 if (!doResume) {
1429 r.delayedResume = true;
1430 }
1431
1432 ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1433
1434 // If the onlyIfNeeded flag is set, then we can do this if the activity
1435 // being launched is the same as the one making the call... or, as
1436 // a special case, if we do not know the caller then we count the
1437 // current top activity as the caller.
1438 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1439 ActivityRecord checkedCaller = sourceRecord;
1440 if (checkedCaller == null) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001441 checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001442 }
1443 if (!checkedCaller.realActivity.equals(r.realActivity)) {
1444 // Caller is not the same as launcher, so always needed.
1445 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
1446 }
1447 }
1448
Craig Mautnerd00f4742014-03-12 14:17:26 -07001449 final boolean newDocument = intent.isDocument();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001450 if (sourceRecord == null) {
1451 // This activity is not being started from another... in this
1452 // case we -always- start a new task.
Craig Mautnerd00f4742014-03-12 14:17:26 -07001453 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
Craig Mautner29219d92013-04-16 20:19:12 -07001454 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1455 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001456 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1457 }
Craig Mautnerd00f4742014-03-12 14:17:26 -07001458 } else if (newDocument) {
1459 if (r.launchMode != ActivityInfo.LAUNCH_MULTIPLE) {
1460 Slog.w(TAG, "FLAG_ACTIVITY_NEW_DOCUMENT and launchMode != \"standard\"");
1461 r.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
1462 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001463 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1464 // The original activity who is starting us is running as a single
1465 // instance... this new activity it is starting must go on its
1466 // own task.
1467 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1468 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
1469 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1470 // The activity being started is a single instance... it always
1471 // gets launched into its own task.
1472 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1473 }
1474
Craig Mautner88629292013-11-10 20:39:05 -08001475 ActivityInfo newTaskInfo = null;
1476 Intent newTaskIntent = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001477 final ActivityStack sourceStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001478 if (sourceRecord != null) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001479 if (sourceRecord.finishing) {
1480 // If the source is finishing, we can't further count it as our source. This
1481 // is because the task it is associated with may now be empty and on its way out,
1482 // so we don't want to blindly throw it in to that task. Instead we will take
Craig Mautner88629292013-11-10 20:39:05 -08001483 // the NEW_TASK flow and try to find a task for it. But save the task information
1484 // so it can be used when creating the new task.
Craig Mautnerd00f4742014-03-12 14:17:26 -07001485 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001486 Slog.w(TAG, "startActivity called from finishing " + sourceRecord
1487 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
1488 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
Craig Mautner88629292013-11-10 20:39:05 -08001489 newTaskInfo = sourceRecord.info;
1490 newTaskIntent = sourceRecord.task.intent;
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001491 }
1492 sourceRecord = null;
1493 sourceStack = null;
1494 } else {
1495 sourceStack = sourceRecord.task.stack;
1496 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07001497 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001498 sourceStack = null;
1499 }
1500
Craig Mautnerd00f4742014-03-12 14:17:26 -07001501 if (r.resultTo != null && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001502 // For whatever reason this activity is being launched into a new
1503 // task... yet the caller has requested a result back. Well, that
1504 // is pretty messed up, so instead immediately send back a cancel
1505 // and let the new task continue launched as normal without a
1506 // dependency on its originator.
1507 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1508 r.resultTo.task.stack.sendActivityResultLocked(-1,
1509 r.resultTo, r.resultWho, r.requestCode,
1510 Activity.RESULT_CANCELED, null);
1511 r.resultTo = null;
1512 }
1513
1514 boolean addingToTask = false;
1515 boolean movedHome = false;
1516 TaskRecord reuseTask = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001517 ActivityStack targetStack;
Craig Mautnerd00f4742014-03-12 14:17:26 -07001518 if (((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
1519 (launchFlags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
Craig Mautner8849a5e2013-04-02 16:41:03 -07001520 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1521 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1522 // If bring to front is requested, and no result is requested, and
1523 // we can find a task that was started with this same
1524 // component, then instead of launching bring that one to the front.
1525 if (r.resultTo == null) {
1526 // See if there is a task to bring to the front. If this is
1527 // a SINGLE_INSTANCE activity, there can be one and only one
1528 // instance of it in the history, and it is always in its own
1529 // unique task, so we do a special search.
1530 ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
Craig Mautnerac6f8432013-07-17 13:24:59 -07001531 ? findTaskLocked(r)
Craig Mautner8849a5e2013-04-02 16:41:03 -07001532 : findActivityLocked(intent, r.info);
1533 if (intentActivity != null) {
Craig Mautneraea74a52014-03-08 14:23:10 -08001534 if (isLockTaskModeViolation(intentActivity.task)) {
1535 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
1536 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
1537 }
Craig Mautner29219d92013-04-16 20:19:12 -07001538 if (r.task == null) {
1539 r.task = intentActivity.task;
1540 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001541 targetStack = intentActivity.task.stack;
Craig Mautner0f922742013-08-06 08:44:42 -07001542 targetStack.mLastPausedActivity = null;
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001543 if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack
1544 + " from " + intentActivity);
Craig Mautnere0a38842013-12-16 16:14:02 -08001545 targetStack.moveToFront();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001546 if (intentActivity.task.intent == null) {
1547 // This task was started because of movement of
1548 // the activity based on affinity... now that we
1549 // are actually launching it, we can assign the
1550 // base intent.
1551 intentActivity.task.setIntent(intent, r.info);
1552 }
1553 // If the target task is not in the front, then we need
1554 // to bring it to the front... except... well, with
1555 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like
1556 // to have the same behavior as if a new instance was
1557 // being started, which means not bringing it to the front
1558 // if the caller is not itself in the front.
Craig Mautner165640b2013-04-20 10:34:33 -07001559 final ActivityStack lastStack = getLastStack();
1560 ActivityRecord curTop = lastStack == null?
1561 null : lastStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner7504d7b2013-09-17 10:50:53 -07001562 if (curTop != null && (curTop.task != intentActivity.task ||
1563 curTop.task != lastStack.topTask())) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001564 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Craig Mautnerd0f964f2013-08-07 11:16:33 -07001565 if (sourceRecord == null || (sourceStack.topActivity() != null &&
1566 sourceStack.topActivity().task == sourceRecord.task)) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001567 // We really do want to push this one into the
1568 // user's face, right now.
1569 movedHome = true;
Craig Mautnerb53d97c2013-10-25 11:54:37 -07001570 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001571 if ((launchFlags &
Craig Mautner29219d92013-04-16 20:19:12 -07001572 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1573 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
Craig Mautnere12a4a62013-08-29 12:24:56 -07001574 // Caller wants to appear on home activity.
Craig Mautnerae7ecab2013-09-18 11:48:14 -07001575 intentActivity.task.mOnTopOfHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001576 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001577 options = null;
1578 }
1579 }
1580 // If the caller has requested that the target task be
1581 // reset, then do so.
1582 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1583 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
1584 }
1585 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1586 // We don't need to start a new activity, and
1587 // the client said not to do anything if that
1588 // is the case, so this is it! And for paranoia, make
1589 // sure we have correctly resumed the top activity.
1590 if (doResume) {
Craig Mautner05d29032013-05-03 13:40:13 -07001591 resumeTopActivitiesLocked(targetStack, null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001592 } else {
1593 ActivityOptions.abort(options);
1594 }
1595 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1596 }
1597 if ((launchFlags &
1598 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
1599 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
1600 // The caller has requested to completely replace any
1601 // existing task with its new activity. Well that should
1602 // not be too hard...
1603 reuseTask = intentActivity.task;
1604 reuseTask.performClearTaskLocked();
1605 reuseTask.setIntent(r.intent, r.info);
1606 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
1607 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1608 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1609 // In this situation we want to remove all activities
1610 // from the task up to the one being started. In most
1611 // cases this means we are resetting the task to its
1612 // initial state.
1613 ActivityRecord top =
1614 intentActivity.task.performClearTaskLocked(r, launchFlags);
1615 if (top != null) {
1616 if (top.frontOfTask) {
1617 // Activity aliases may mean we use different
1618 // intents for the top activity, so make sure
1619 // the task now has the identity of the new
1620 // intent.
1621 top.task.setIntent(r.intent, r.info);
1622 }
1623 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
1624 r, top.task);
1625 top.deliverNewIntentLocked(callingUid, r.intent);
1626 } else {
1627 // A special case: we need to
1628 // start the activity because it is not currently
1629 // running, and the caller has asked to clear the
1630 // current task to have this activity at the top.
1631 addingToTask = true;
1632 // Now pretend like this activity is being started
1633 // by the top of its task, so it is put in the
1634 // right place.
1635 sourceRecord = intentActivity;
1636 }
1637 } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
1638 // In this case the top activity on the task is the
1639 // same as the one being launched, so we take that
1640 // as a request to bring the task to the foreground.
1641 // If the top activity in the task is the root
1642 // activity, deliver this new intent to it if it
1643 // desires.
1644 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1645 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
1646 && intentActivity.realActivity.equals(r.realActivity)) {
1647 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
1648 intentActivity.task);
1649 if (intentActivity.frontOfTask) {
1650 intentActivity.task.setIntent(r.intent, r.info);
1651 }
1652 intentActivity.deliverNewIntentLocked(callingUid, r.intent);
1653 } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
1654 // In this case we are launching the root activity
1655 // of the task, but with a different intent. We
1656 // should start a new instance on top.
1657 addingToTask = true;
1658 sourceRecord = intentActivity;
1659 }
1660 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1661 // In this case an activity is being launched in to an
1662 // existing task, without resetting that task. This
1663 // is typically the situation of launching an activity
1664 // from a notification or shortcut. We want to place
1665 // the new activity on top of the current task.
1666 addingToTask = true;
1667 sourceRecord = intentActivity;
1668 } else if (!intentActivity.task.rootWasReset) {
1669 // In this case we are launching in to an existing task
1670 // that has not yet been started from its front door.
1671 // The current task has been brought to the front.
1672 // Ideally, we'd probably like to place this new task
1673 // at the bottom of its stack, but that's a little hard
1674 // to do with the current organization of the code so
1675 // for now we'll just drop it.
1676 intentActivity.task.setIntent(r.intent, r.info);
1677 }
1678 if (!addingToTask && reuseTask == null) {
1679 // We didn't do anything... but it was needed (a.k.a., client
1680 // don't use that intent!) And for paranoia, make
1681 // sure we have correctly resumed the top activity.
1682 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001683 targetStack.resumeTopActivityLocked(null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001684 } else {
1685 ActivityOptions.abort(options);
1686 }
1687 return ActivityManager.START_TASK_TO_FRONT;
1688 }
1689 }
1690 }
1691 }
1692
1693 //String uri = r.intent.toURI();
1694 //Intent intent2 = new Intent(uri);
1695 //Slog.i(TAG, "Given intent: " + r.intent);
1696 //Slog.i(TAG, "URI is: " + uri);
1697 //Slog.i(TAG, "To intent: " + intent2);
1698
1699 if (r.packageName != null) {
1700 // If the activity being launched is the same as the one currently
1701 // at the top, then we need to check if it should only be launched
1702 // once.
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001703 ActivityStack topStack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001704 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001705 if (top != null && r.resultTo == null) {
1706 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
1707 if (top.app != null && top.app.thread != null) {
Craig Mautnerd00f4742014-03-12 14:17:26 -07001708 if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
Craig Mautner8849a5e2013-04-02 16:41:03 -07001709 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
1710 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1711 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
1712 top.task);
1713 // For paranoia, make sure we have correctly
1714 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001715 topStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001716 if (doResume) {
Craig Mautner05d29032013-05-03 13:40:13 -07001717 resumeTopActivitiesLocked();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001718 }
1719 ActivityOptions.abort(options);
1720 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1721 // We don't need to start a new activity, and
1722 // the client said not to do anything if that
1723 // is the case, so this is it!
1724 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1725 }
1726 top.deliverNewIntentLocked(callingUid, r.intent);
1727 return ActivityManager.START_DELIVERED_TO_TOP;
1728 }
1729 }
1730 }
1731 }
1732
1733 } else {
1734 if (r.resultTo != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001735 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
1736 r.requestCode, Activity.RESULT_CANCELED, null);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001737 }
1738 ActivityOptions.abort(options);
1739 return ActivityManager.START_CLASS_NOT_FOUND;
1740 }
1741
1742 boolean newTask = false;
1743 boolean keepCurTransition = false;
1744
1745 // Should this be considered a new task?
1746 if (r.resultTo == null && !addingToTask
1747 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
Craig Mautneraea74a52014-03-08 14:23:10 -08001748 if (isLockTaskModeViolation(reuseTask)) {
1749 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
1750 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
1751 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001752 targetStack = adjustStackFocus(r);
Craig Mautnere0a38842013-12-16 16:14:02 -08001753 targetStack.moveToFront();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001754 if (reuseTask == null) {
Craig Mautner88629292013-11-10 20:39:05 -08001755 r.setTask(targetStack.createTaskRecord(getNextTaskId(),
1756 newTaskInfo != null ? newTaskInfo : r.info,
1757 newTaskIntent != null ? newTaskIntent : intent,
1758 true), null, true);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001759 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
1760 r.task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001761 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001762 r.setTask(reuseTask, reuseTask, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001763 }
1764 newTask = true;
1765 if (!movedHome) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001766 if ((launchFlags &
1767 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
1768 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
1769 // Caller wants to appear on home activity, so before starting
1770 // their own activity we will bring home to the front.
Craig Mautnere0a38842013-12-16 16:14:02 -08001771 r.task.mOnTopOfHome = r.task.stack.isOnHomeDisplay();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001772 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001773 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001774 } else if (sourceRecord != null) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001775 TaskRecord sourceTask = sourceRecord.task;
Craig Mautneraea74a52014-03-08 14:23:10 -08001776 if (isLockTaskModeViolation(sourceTask)) {
1777 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
1778 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
1779 }
Craig Mautner525f3d92013-05-07 14:01:50 -07001780 targetStack = sourceTask.stack;
Craig Mautner95e9daa2014-03-17 15:57:20 -07001781 mWindowManager.moveTaskToTop(sourceTask.taskId);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001782 if (!addingToTask &&
1783 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
1784 // In this case, we are adding the activity to an existing
1785 // task, but the caller has asked to clear that task if the
1786 // activity is already running.
Craig Mautner525f3d92013-05-07 14:01:50 -07001787 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001788 keepCurTransition = true;
1789 if (top != null) {
1790 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
1791 top.deliverNewIntentLocked(callingUid, r.intent);
1792 // For paranoia, make sure we have correctly
1793 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001794 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001795 if (doResume) {
1796 targetStack.resumeTopActivityLocked(null);
1797 }
1798 ActivityOptions.abort(options);
1799 return ActivityManager.START_DELIVERED_TO_TOP;
1800 }
1801 } else if (!addingToTask &&
1802 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1803 // In this case, we are launching an activity in our own task
1804 // that may already be running somewhere in the history, and
1805 // we want to shuffle it to the front of the stack if so.
Craig Mautner525f3d92013-05-07 14:01:50 -07001806 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001807 if (top != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001808 final TaskRecord task = top.task;
1809 task.moveActivityToFrontLocked(top);
1810 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001811 top.updateOptionsLocked(options);
1812 top.deliverNewIntentLocked(callingUid, r.intent);
Craig Mautner0f922742013-08-06 08:44:42 -07001813 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001814 if (doResume) {
1815 targetStack.resumeTopActivityLocked(null);
1816 }
1817 return ActivityManager.START_DELIVERED_TO_TOP;
1818 }
1819 }
1820 // An existing activity is starting this new activity, so we want
1821 // to keep the new one in the same task as the one that is starting
1822 // it.
Craig Mautner525f3d92013-05-07 14:01:50 -07001823 r.setTask(sourceTask, sourceRecord.thumbHolder, false);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001824 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001825 + " in existing task " + r.task + " from source " + sourceRecord);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001826
1827 } else {
1828 // This not being started from an existing activity, and not part
1829 // of a new task... just put it in the top task, though these days
1830 // this case should never happen.
Craig Mautnerac6f8432013-07-17 13:24:59 -07001831 targetStack = adjustStackFocus(r);
Craig Mautner1602ec22013-05-12 10:24:27 -07001832 ActivityRecord prev = targetStack.topActivity();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001833 r.setTask(prev != null ? prev.task
1834 : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1835 null, true);
Craig Mautner95e9daa2014-03-17 15:57:20 -07001836 mWindowManager.moveTaskToTop(r.task.taskId);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001837 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1838 + " in new guessed " + r.task);
1839 }
1840
1841 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
1842 intent, r.getUriPermissionsLocked());
1843
1844 if (newTask) {
1845 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
1846 }
1847 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
Craig Mautner0f922742013-08-06 08:44:42 -07001848 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001849 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
Craig Mautner1d001b62013-06-18 16:52:43 -07001850 mService.setFocusedActivityLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001851 return ActivityManager.START_SUCCESS;
1852 }
1853
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001854 void acquireLaunchWakelock() {
1855 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
1856 throw new IllegalStateException("Calling must be system uid");
1857 }
1858 mLaunchingActivity.acquire();
1859 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
1860 // To be safe, don't allow the wake lock to be held for too long.
1861 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
1862 }
1863 }
1864
Craig Mautnerf3333272013-04-22 10:55:53 -07001865 // Checked.
1866 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
1867 Configuration config) {
1868 if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
1869
Craig Mautnerf3333272013-04-22 10:55:53 -07001870 ArrayList<ActivityRecord> stops = null;
1871 ArrayList<ActivityRecord> finishes = null;
1872 ArrayList<UserStartedState> startingUsers = null;
1873 int NS = 0;
1874 int NF = 0;
1875 IApplicationThread sendThumbnail = null;
1876 boolean booting = false;
1877 boolean enableScreen = false;
1878 boolean activityRemoved = false;
1879
1880 ActivityRecord r = ActivityRecord.forToken(token);
1881 if (r != null) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07001882 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
1883 Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07001884 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
1885 r.finishLaunchTickingLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001886 if (fromTimeout) {
1887 reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
Craig Mautnerf3333272013-04-22 10:55:53 -07001888 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001889
1890 // This is a hack to semi-deal with a race condition
1891 // in the client where it can be constructed with a
1892 // newer configuration from when we asked it to launch.
1893 // We'll update with whatever configuration it now says
1894 // it used to launch.
1895 if (config != null) {
1896 r.configuration = config;
1897 }
1898
1899 // We are now idle. If someone is waiting for a thumbnail from
1900 // us, we can now deliver.
1901 r.idle = true;
1902
1903 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
1904 sendThumbnail = r.app.thread;
1905 r.thumbnailNeeded = false;
1906 }
1907
1908 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
1909 if (!mService.mBooted && isFrontStack(r.task.stack)) {
1910 mService.mBooted = true;
1911 enableScreen = true;
1912 }
1913 }
1914
1915 if (allResumedActivitiesIdle()) {
1916 if (r != null) {
1917 mService.scheduleAppGcsLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001918 }
1919
1920 if (mLaunchingActivity.isHeld()) {
1921 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
1922 if (VALIDATE_WAKE_LOCK_CALLER &&
1923 Binder.getCallingUid() != Process.myUid()) {
1924 throw new IllegalStateException("Calling must be system uid");
1925 }
1926 mLaunchingActivity.release();
1927 }
1928 ensureActivitiesVisibleLocked(null, 0);
Craig Mautnerf3333272013-04-22 10:55:53 -07001929 }
1930
1931 // Atomically retrieve all of the other things to do.
1932 stops = processStoppingActivitiesLocked(true);
1933 NS = stops != null ? stops.size() : 0;
1934 if ((NF=mFinishingActivities.size()) > 0) {
1935 finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
1936 mFinishingActivities.clear();
1937 }
1938
1939 final ArrayList<ActivityRecord> thumbnails;
1940 final int NT = mCancelledThumbnails.size();
1941 if (NT > 0) {
1942 thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
1943 mCancelledThumbnails.clear();
1944 } else {
1945 thumbnails = null;
1946 }
1947
1948 if (isFrontStack(mHomeStack)) {
1949 booting = mService.mBooting;
1950 mService.mBooting = false;
1951 }
1952
1953 if (mStartingUsers.size() > 0) {
1954 startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
1955 mStartingUsers.clear();
1956 }
1957
1958 // Perform the following actions from unsynchronized state.
1959 final IApplicationThread thumbnailThread = sendThumbnail;
1960 mHandler.post(new Runnable() {
1961 @Override
1962 public void run() {
1963 if (thumbnailThread != null) {
1964 try {
1965 thumbnailThread.requestThumbnail(token);
1966 } catch (Exception e) {
1967 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
1968 mService.sendPendingThumbnail(null, token, null, null, true);
1969 }
1970 }
1971
1972 // Report back to any thumbnail receivers.
1973 for (int i = 0; i < NT; i++) {
1974 ActivityRecord r = thumbnails.get(i);
1975 mService.sendPendingThumbnail(r, null, null, null, true);
1976 }
1977 }
1978 });
1979
1980 // Stop any activities that are scheduled to do so but have been
1981 // waiting for the next one to start.
1982 for (int i = 0; i < NS; i++) {
1983 r = stops.get(i);
1984 final ActivityStack stack = r.task.stack;
1985 if (r.finishing) {
1986 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
1987 } else {
1988 stack.stopActivityLocked(r);
1989 }
1990 }
1991
1992 // Finish any activities that are scheduled to do so but have been
1993 // waiting for the next one to start.
1994 for (int i = 0; i < NF; i++) {
1995 r = finishes.get(i);
1996 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
1997 }
1998
1999 if (booting) {
2000 mService.finishBooting();
2001 } else if (startingUsers != null) {
2002 for (int i = 0; i < startingUsers.size(); i++) {
2003 mService.finishUserSwitch(startingUsers.get(i));
2004 }
2005 }
2006
2007 mService.trimApplications();
2008 //dump();
2009 //mWindowManager.dump();
2010
2011 if (enableScreen) {
2012 mService.enableScreenAfterBoot();
2013 }
2014
2015 if (activityRemoved) {
Craig Mautner05d29032013-05-03 13:40:13 -07002016 resumeTopActivitiesLocked();
Craig Mautnerf3333272013-04-22 10:55:53 -07002017 }
2018
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002019 return r;
Craig Mautnerf3333272013-04-22 10:55:53 -07002020 }
2021
Craig Mautner8e569572013-10-11 17:36:59 -07002022 boolean handleAppDiedLocked(ProcessRecord app) {
Craig Mautner19091252013-10-05 00:03:53 -07002023 boolean hasVisibleActivities = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002024 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2025 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002026 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2027 hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app);
2028 }
Craig Mautner6b74cb52013-09-27 17:02:21 -07002029 }
Craig Mautner19091252013-10-05 00:03:53 -07002030 return hasVisibleActivities;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002031 }
2032
2033 void closeSystemDialogsLocked() {
Craig Mautnere0a38842013-12-16 16:14:02 -08002034 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2035 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002036 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2037 stacks.get(stackNdx).closeSystemDialogsLocked();
2038 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002039 }
2040 }
2041
Craig Mautner93529a42013-10-04 15:03:13 -07002042 void removeUserLocked(int userId) {
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002043 mUserStackInFront.delete(userId);
Craig Mautner93529a42013-10-04 15:03:13 -07002044 }
2045
Craig Mautner8d341ef2013-03-26 09:03:27 -07002046 /**
2047 * @return true if some activity was finished (or would have finished if doit were true).
2048 */
2049 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
2050 boolean didSomething = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002051 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2052 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002053 final int numStacks = stacks.size();
2054 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2055 final ActivityStack stack = stacks.get(stackNdx);
2056 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
2057 didSomething = true;
2058 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002059 }
2060 }
2061 return didSomething;
2062 }
2063
Dianne Hackborna413dc02013-07-12 12:02:55 -07002064 void updatePreviousProcessLocked(ActivityRecord r) {
2065 // Now that this process has stopped, we may want to consider
2066 // it to be the previous app to try to keep around in case
2067 // the user wants to return to it.
2068
2069 // First, found out what is currently the foreground app, so that
2070 // we don't blow away the previous app if this activity is being
2071 // hosted by the process that is actually still the foreground.
2072 ProcessRecord fgApp = null;
Craig Mautnere0a38842013-12-16 16:14:02 -08002073 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2074 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002075 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2076 final ActivityStack stack = stacks.get(stackNdx);
2077 if (isFrontStack(stack)) {
2078 if (stack.mResumedActivity != null) {
2079 fgApp = stack.mResumedActivity.app;
2080 } else if (stack.mPausingActivity != null) {
2081 fgApp = stack.mPausingActivity.app;
2082 }
2083 break;
Dianne Hackborna413dc02013-07-12 12:02:55 -07002084 }
Dianne Hackborna413dc02013-07-12 12:02:55 -07002085 }
2086 }
2087
2088 // Now set this one as the previous process, only if that really
2089 // makes sense to.
2090 if (r.app != null && fgApp != null && r.app != fgApp
2091 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
Craig Mautner4ef26932013-09-18 15:15:52 -07002092 && r.app != mService.mHomeProcess) {
Dianne Hackborna413dc02013-07-12 12:02:55 -07002093 mService.mPreviousProcess = r.app;
2094 mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
2095 }
2096 }
2097
Craig Mautner05d29032013-05-03 13:40:13 -07002098 boolean resumeTopActivitiesLocked() {
2099 return resumeTopActivitiesLocked(null, null, null);
2100 }
2101
2102 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
2103 Bundle targetOptions) {
2104 if (targetStack == null) {
2105 targetStack = getFocusedStack();
2106 }
Craig Mautner12ff7392014-02-21 21:08:00 -08002107 // Do targetStack first.
Craig Mautner05d29032013-05-03 13:40:13 -07002108 boolean result = false;
Craig Mautner12ff7392014-02-21 21:08:00 -08002109 if (isFrontStack(targetStack)) {
2110 result = targetStack.resumeTopActivityLocked(target, targetOptions);
2111 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002112 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2113 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002114 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2115 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautner12ff7392014-02-21 21:08:00 -08002116 if (stack == targetStack) {
2117 // Already started above.
2118 continue;
2119 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002120 if (isFrontStack(stack)) {
Craig Mautner12ff7392014-02-21 21:08:00 -08002121 stack.resumeTopActivityLocked(null);
Craig Mautner05d29032013-05-03 13:40:13 -07002122 }
Craig Mautnerf88c50f2013-04-18 19:25:12 -07002123 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002124 }
Craig Mautner05d29032013-05-03 13:40:13 -07002125 return result;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002126 }
2127
2128 void finishTopRunningActivityLocked(ProcessRecord app) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002129 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2130 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002131 final int numStacks = stacks.size();
2132 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2133 final ActivityStack stack = stacks.get(stackNdx);
2134 stack.finishTopRunningActivityLocked(app);
2135 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002136 }
2137 }
2138
Craig Mautneraea74a52014-03-08 14:23:10 -08002139 void findTaskToMoveToFrontLocked(TaskRecord task, int flags, Bundle options) {
2140 if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
2141 mUserLeaving = true;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002142 }
Craig Mautneraea74a52014-03-08 14:23:10 -08002143 if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
2144 // Caller wants the home activity moved with it. To accomplish this,
2145 // we'll just indicate that this task returns to the home task.
2146 task.mOnTopOfHome = true;
2147 }
2148 task.stack.moveTaskToFrontLocked(task, null, options);
2149 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack="
2150 + task.stack);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002151 }
2152
Craig Mautner967212c2013-04-13 21:10:58 -07002153 ActivityStack getStack(int stackId) {
Craig Mautner4504de52013-12-20 09:06:56 -08002154 WeakReference<ActivityContainer> weakReference = mActivityContainers.get(stackId);
2155 if (weakReference != null) {
2156 ActivityContainer activityContainer = weakReference.get();
2157 if (activityContainer != null) {
2158 return activityContainer.mStack;
2159 } else {
2160 mActivityContainers.remove(stackId);
2161 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002162 }
2163 return null;
2164 }
2165
Craig Mautner967212c2013-04-13 21:10:58 -07002166 ArrayList<ActivityStack> getStacks() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002167 ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>();
Craig Mautnere0a38842013-12-16 16:14:02 -08002168 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2169 allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002170 }
2171 return allStacks;
Craig Mautner967212c2013-04-13 21:10:58 -07002172 }
2173
Craig Mautner4a1cb222013-12-04 16:14:06 -08002174 IBinder getHomeActivityToken() {
2175 final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
2176 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
2177 final TaskRecord task = tasks.get(taskNdx);
2178 if (task.isHomeTask()) {
2179 final ArrayList<ActivityRecord> activities = task.mActivities;
2180 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2181 final ActivityRecord r = activities.get(activityNdx);
2182 if (r.isHomeActivity()) {
2183 return r.appToken;
2184 }
2185 }
2186 }
2187 }
2188 return null;
2189 }
2190
2191 ActivityContainer createActivityContainer(ActivityRecord parentActivity, int stackId,
2192 IActivityContainerCallback callback) {
2193 ActivityContainer activityContainer = new ActivityContainer(parentActivity, stackId,
2194 callback);
Craig Mautner4504de52013-12-20 09:06:56 -08002195 mActivityContainers.put(stackId, new WeakReference<ActivityContainer>(activityContainer));
Craig Mautner4a1cb222013-12-04 16:14:06 -08002196 if (parentActivity != null) {
2197 parentActivity.mChildContainers.add(activityContainer.mStack);
2198 }
2199 return activityContainer;
2200 }
2201
2202 ActivityContainer createActivityContainer(ActivityRecord parentActivity,
2203 IActivityContainerCallback callback) {
2204 return createActivityContainer(parentActivity, getNextStackId(), callback);
2205 }
2206
Craig Mautner34b73df2014-01-12 21:11:08 -08002207 void removeChildActivityContainers(ActivityRecord parentActivity) {
2208 for (int ndx = mActivityContainers.size() - 1; ndx >= 0; --ndx) {
2209 final ActivityContainer container = mActivityContainers.valueAt(ndx).get();
2210 if (container == null) {
2211 mActivityContainers.removeAt(ndx);
2212 continue;
2213 }
2214 if (container.mParentActivity != parentActivity) {
2215 continue;
2216 }
2217
2218 ActivityStack stack = container.mStack;
2219 ActivityRecord top = stack.topRunningNonDelayedActivityLocked(null);
2220 if (top != null) {
2221 // TODO: Make sure the next activity doesn't start up when top is destroyed.
Craig Mautner95da1082014-02-24 17:54:35 -08002222 stack.destroyActivityLocked(top, true, true, "stack parent destroyed");
Craig Mautner34b73df2014-01-12 21:11:08 -08002223 }
2224 mActivityContainers.removeAt(ndx);
2225 container.detachLocked();
2226 }
2227 }
2228
Craig Mautner95da1082014-02-24 17:54:35 -08002229 void deleteActivityContainer(IActivityContainer container) {
2230 ActivityContainer activityContainer = (ActivityContainer)container;
2231 if (activityContainer != null) {
2232 activityContainer.mStack.destroyActivitiesLocked(null, true,
2233 "deleteActivityContainer");
2234 final ActivityRecord parent = activityContainer.mParentActivity;
2235 if (parent != null) {
2236 parent.mChildContainers.remove(activityContainer);
2237 }
2238 final int stackId = activityContainer.mStackId;
2239 mActivityContainers.remove(stackId);
2240 mWindowManager.removeStack(stackId);
2241 }
2242 }
2243
Craig Mautner4a1cb222013-12-04 16:14:06 -08002244 private int createStackOnDisplay(ActivityRecord parentActivity, int stackId, int displayId) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002245 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2246 if (activityDisplay == null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002247 return -1;
2248 }
2249
2250 ActivityContainer activityContainer =
2251 createActivityContainer(parentActivity, stackId, null);
Craig Mautnere0a38842013-12-16 16:14:02 -08002252 activityContainer.attachToDisplayLocked(activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002253 return stackId;
2254 }
2255
2256 int getNextStackId() {
Craig Mautner858d8a62013-04-23 17:08:34 -07002257 while (true) {
2258 if (++mLastStackId <= HOME_STACK_ID) {
2259 mLastStackId = HOME_STACK_ID + 1;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002260 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002261 if (getStack(mLastStackId) == null) {
2262 break;
2263 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002264 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002265 return mLastStackId;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002266 }
2267
2268 void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002269 final TaskRecord task = anyTaskForIdLocked(taskId);
2270 if (task == null) {
2271 return;
2272 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002273 final ActivityStack stack = getStack(stackId);
2274 if (stack == null) {
2275 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
2276 return;
2277 }
Craig Mautner04a0ea62014-01-13 12:51:26 -08002278 task.stack.removeTask(task);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002279 stack.addTask(task, toTop);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002280 mWindowManager.addTask(taskId, stackId, toTop);
Craig Mautner05d29032013-05-03 13:40:13 -07002281 resumeTopActivitiesLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002282 }
2283
Craig Mautnerac6f8432013-07-17 13:24:59 -07002284 ActivityRecord findTaskLocked(ActivityRecord r) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07002285 if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r);
Craig Mautnere0a38842013-12-16 16:14:02 -08002286 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2287 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002288 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2289 final ActivityStack stack = stacks.get(stackNdx);
2290 if (!r.isApplicationActivity() && !stack.isHomeStack()) {
2291 if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: " + stack);
2292 continue;
2293 }
2294 final ActivityRecord ar = stack.findTaskLocked(r);
2295 if (ar != null) {
2296 return ar;
2297 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07002298 }
2299 }
Dianne Hackborn2a272d42013-10-16 13:34:33 -07002300 if (DEBUG_TASKS) Slog.d(TAG, "No task found");
Craig Mautner8849a5e2013-04-02 16:41:03 -07002301 return null;
2302 }
2303
2304 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002305 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2306 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002307 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2308 final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info);
2309 if (ar != null) {
2310 return ar;
2311 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07002312 }
2313 }
2314 return null;
2315 }
2316
Craig Mautner8d341ef2013-03-26 09:03:27 -07002317 void goingToSleepLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002318 scheduleSleepTimeout();
2319 if (!mGoingToSleep.isHeld()) {
2320 mGoingToSleep.acquire();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002321 if (mLaunchingActivity.isHeld()) {
2322 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2323 throw new IllegalStateException("Calling must be system uid");
Craig Mautner0eea92c2013-05-16 13:35:39 -07002324 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002325 mLaunchingActivity.release();
2326 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
Craig Mautner0eea92c2013-05-16 13:35:39 -07002327 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002328 }
Amith Yamasanice15e152013-09-19 12:30:32 -07002329 checkReadyForSleepLocked();
Craig Mautneraea74a52014-03-08 14:23:10 -08002330 setLockTaskModeLocked(null);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002331 }
2332
2333 boolean shutdownLocked(int timeout) {
2334 boolean timedout = false;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002335 goingToSleepLocked();
Craig Mautner0eea92c2013-05-16 13:35:39 -07002336
2337 final long endTime = System.currentTimeMillis() + timeout;
2338 while (true) {
2339 boolean cantShutdown = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002340 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2341 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002342 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2343 cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
2344 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002345 }
2346 if (cantShutdown) {
2347 long timeRemaining = endTime - System.currentTimeMillis();
2348 if (timeRemaining > 0) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002349 try {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002350 mService.wait(timeRemaining);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002351 } catch (InterruptedException e) {
2352 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002353 } else {
2354 Slog.w(TAG, "Activity manager shutdown timed out");
2355 timedout = true;
2356 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002357 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002358 } else {
2359 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002360 }
2361 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002362
2363 // Force checkReadyForSleep to complete.
2364 mSleepTimeout = true;
2365 checkReadyForSleepLocked();
2366
Craig Mautner8d341ef2013-03-26 09:03:27 -07002367 return timedout;
2368 }
2369
2370 void comeOutOfSleepIfNeededLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002371 removeSleepTimeouts();
2372 if (mGoingToSleep.isHeld()) {
2373 mGoingToSleep.release();
2374 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002375 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2376 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002377 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2378 final ActivityStack stack = stacks.get(stackNdx);
2379 stack.awakeFromSleepingLocked();
2380 if (isFrontStack(stack)) {
2381 resumeTopActivitiesLocked();
2382 }
Craig Mautner5314a402013-09-26 12:40:16 -07002383 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002384 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002385 mGoingToSleepActivities.clear();
2386 }
2387
2388 void activitySleptLocked(ActivityRecord r) {
2389 mGoingToSleepActivities.remove(r);
2390 checkReadyForSleepLocked();
2391 }
2392
2393 void checkReadyForSleepLocked() {
2394 if (!mService.isSleepingOrShuttingDown()) {
2395 // Do not care.
2396 return;
2397 }
2398
2399 if (!mSleepTimeout) {
2400 boolean dontSleep = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002401 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2402 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002403 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2404 dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
2405 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002406 }
2407
2408 if (mStoppingActivities.size() > 0) {
2409 // Still need to tell some activities to stop; can't sleep yet.
2410 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2411 + mStoppingActivities.size() + " activities");
2412 scheduleIdleLocked();
2413 dontSleep = true;
2414 }
2415
2416 if (mGoingToSleepActivities.size() > 0) {
2417 // Still need to tell some activities to sleep; can't sleep yet.
2418 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2419 + mGoingToSleepActivities.size() + " activities");
2420 dontSleep = true;
2421 }
2422
2423 if (dontSleep) {
2424 return;
2425 }
2426 }
2427
Craig Mautnere0a38842013-12-16 16:14:02 -08002428 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2429 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002430 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2431 stacks.get(stackNdx).goToSleep();
2432 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002433 }
2434
2435 removeSleepTimeouts();
2436
2437 if (mGoingToSleep.isHeld()) {
2438 mGoingToSleep.release();
2439 }
2440 if (mService.mShuttingDown) {
2441 mService.notifyAll();
2442 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002443 }
2444
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002445 boolean reportResumedActivityLocked(ActivityRecord r) {
2446 final ActivityStack stack = r.task.stack;
2447 if (isFrontStack(stack)) {
Jeff Sharkey5782da72013-04-25 14:32:30 -07002448 mService.updateUsageStats(r, true);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002449 }
2450 if (allResumedActivitiesComplete()) {
2451 ensureActivitiesVisibleLocked(null, 0);
2452 mWindowManager.executeAppTransition();
2453 return true;
2454 }
2455 return false;
2456 }
2457
Craig Mautner8d341ef2013-03-26 09:03:27 -07002458 void handleAppCrashLocked(ProcessRecord app) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002459 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2460 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002461 final int numStacks = stacks.size();
2462 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2463 final ActivityStack stack = stacks.get(stackNdx);
2464 stack.handleAppCrashLocked(app);
2465 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002466 }
2467 }
2468
Craig Mautnerde4ef022013-04-07 19:01:33 -07002469 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
Craig Mautner580ea812013-04-25 12:58:38 -07002470 // First the front stacks. In case any are not fullscreen and are in front of home.
2471 boolean showHomeBehindStack = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002472 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2473 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002474 final int topStackNdx = stacks.size() - 1;
2475 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
2476 final ActivityStack stack = stacks.get(stackNdx);
2477 if (stackNdx == topStackNdx) {
2478 // Top stack.
2479 showHomeBehindStack =
2480 stack.ensureActivitiesVisibleLocked(starting, configChanges);
2481 } else {
2482 // Back stack.
2483 stack.ensureActivitiesVisibleLocked(starting, configChanges,
2484 showHomeBehindStack);
2485 }
Craig Mautner580ea812013-04-25 12:58:38 -07002486 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002487 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002488 }
2489
2490 void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002491 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2492 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002493 final int numStacks = stacks.size();
2494 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2495 final ActivityStack stack = stacks.get(stackNdx);
2496 stack.scheduleDestroyActivities(app, false, reason);
2497 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002498 }
2499 }
2500
2501 boolean switchUserLocked(int userId, UserStartedState uss) {
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002502 mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId());
2503 final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
Craig Mautner2420ead2013-04-01 17:13:20 -07002504 mCurrentUser = userId;
Craig Mautnerac6f8432013-07-17 13:24:59 -07002505
Craig Mautner858d8a62013-04-23 17:08:34 -07002506 mStartingUsers.add(uss);
Craig Mautnere0a38842013-12-16 16:14:02 -08002507 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2508 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002509 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002510 final ActivityStack stack = stacks.get(stackNdx);
2511 stack.switchUserLocked(userId);
Alexandra Gherghinadae57a12014-03-12 19:15:26 +00002512 TaskRecord task = stack.topTask();
2513 if (task != null) {
2514 mWindowManager.moveTaskToTop(task.taskId);
2515 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002516 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07002517 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002518
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002519 ActivityStack stack = getStack(restoreStackId);
2520 if (stack == null) {
2521 stack = mHomeStack;
2522 }
2523 final boolean homeInFront = stack.isHomeStack();
Craig Mautnere0a38842013-12-16 16:14:02 -08002524 if (stack.isOnHomeDisplay()) {
2525 moveHomeStack(homeInFront);
Alexandra Gherghinadae57a12014-03-12 19:15:26 +00002526 TaskRecord task = stack.topTask();
2527 if (task != null) {
2528 mWindowManager.moveTaskToTop(task.taskId);
2529 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002530 } else {
2531 // Stack was moved to another display while user was swapped out.
2532 resumeHomeActivity(null);
2533 }
Craig Mautner93529a42013-10-04 15:03:13 -07002534 return homeInFront;
Craig Mautner2219a1b2013-03-25 09:44:30 -07002535 }
2536
Craig Mautnerde4ef022013-04-07 19:01:33 -07002537 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2538 int N = mStoppingActivities.size();
2539 if (N <= 0) return null;
2540
2541 ArrayList<ActivityRecord> stops = null;
2542
2543 final boolean nowVisible = allResumedActivitiesVisible();
2544 for (int i=0; i<N; i++) {
2545 ActivityRecord s = mStoppingActivities.get(i);
Craig Mautnera7f2bd42013-10-15 16:13:50 -07002546 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
Craig Mautnerde4ef022013-04-07 19:01:33 -07002547 + nowVisible + " waitingVisible=" + s.waitingVisible
2548 + " finishing=" + s.finishing);
2549 if (s.waitingVisible && nowVisible) {
2550 mWaitingVisibleActivities.remove(s);
2551 s.waitingVisible = false;
2552 if (s.finishing) {
2553 // If this activity is finishing, it is sitting on top of
2554 // everyone else but we now know it is no longer needed...
2555 // so get rid of it. Otherwise, we need to go through the
2556 // normal flow and hide it once we determine that it is
2557 // hidden by the activities in front of it.
2558 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002559 mWindowManager.setAppVisibility(s.appToken, false);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002560 }
2561 }
2562 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2563 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2564 if (stops == null) {
2565 stops = new ArrayList<ActivityRecord>();
2566 }
2567 stops.add(s);
2568 mStoppingActivities.remove(i);
2569 N--;
2570 i--;
2571 }
2572 }
2573
2574 return stops;
2575 }
2576
Craig Mautnercf910b02013-04-23 11:23:27 -07002577 void validateTopActivitiesLocked() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002578 // FIXME
2579/* for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2580 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautnercf910b02013-04-23 11:23:27 -07002581 final ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002582 final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
Craig Mautnercf910b02013-04-23 11:23:27 -07002583 if (isFrontStack(stack)) {
2584 if (r == null) {
2585 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2586 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002587 final ActivityRecord pausing = stack.mPausingActivity;
2588 if (pausing != null && pausing == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002589 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002590 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002591 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002592 if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002593 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002594 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002595 }
2596 }
2597 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002598 final ActivityRecord resumed = stack.mResumedActivity;
2599 if (resumed != null && resumed == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002600 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002601 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002602 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002603 if (r != null && (state == ActivityState.INITIALIZING
2604 || state == ActivityState.RESUMED)) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002605 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002606 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002607 }
2608 }
2609 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002610*/
Craig Mautner76ea2242013-05-15 11:40:05 -07002611 }
2612
Craig Mautner27084302013-03-25 08:05:25 -07002613 public void dump(PrintWriter pw, String prefix) {
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002614 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity=");
Craig Mautner27084302013-03-25 08:05:25 -07002615 pw.println(mDismissKeyguardOnNextActivity);
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002616 pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002617 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002618 pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
2619 pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
2620 pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
Craig Mautner95da1082014-02-24 17:54:35 -08002621 pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
Craig Mautner27084302013-03-25 08:05:25 -07002622 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002623
Craig Mautner20e72272013-04-01 13:45:53 -07002624 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002625 return getFocusedStack().getDumpActivitiesLocked(name);
Craig Mautner20e72272013-04-01 13:45:53 -07002626 }
2627
Dianne Hackborn390517b2013-05-30 15:03:32 -07002628 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2629 boolean needSep, String prefix) {
2630 if (activity != null) {
2631 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2632 if (needSep) {
2633 pw.println();
Dianne Hackborn390517b2013-05-30 15:03:32 -07002634 }
2635 pw.print(prefix);
2636 pw.println(activity);
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002637 return true;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002638 }
2639 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002640 return false;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002641 }
2642
Craig Mautner8d341ef2013-03-26 09:03:27 -07002643 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2644 boolean dumpClient, String dumpPackage) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002645 boolean printed = false;
2646 boolean needSep = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002647 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2648 ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
2649 pw.print("Display #"); pw.println(activityDisplay.mDisplayId);
2650 ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002651 final int numStacks = stacks.size();
2652 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2653 final ActivityStack stack = stacks.get(stackNdx);
2654 StringBuilder stackHeader = new StringBuilder(128);
2655 stackHeader.append(" Stack #");
2656 stackHeader.append(stack.mStackId);
2657 stackHeader.append(":");
2658 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
2659 needSep, stackHeader.toString());
2660 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false,
2661 !dumpAll, false, dumpPackage, true,
2662 " Running activities (most recent first):", null);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002663
Craig Mautner4a1cb222013-12-04 16:14:06 -08002664 needSep = printed;
2665 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
2666 " mPausingActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002667 if (pr) {
2668 printed = true;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002669 needSep = false;
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002670 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002671 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
2672 " mResumedActivity: ");
2673 if (pr) {
2674 printed = true;
2675 needSep = false;
2676 }
2677 if (dumpAll) {
2678 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
2679 " mLastPausedActivity: ");
2680 if (pr) {
2681 printed = true;
2682 needSep = true;
2683 }
2684 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
2685 needSep, " mLastNoHistoryActivity: ");
2686 }
2687 needSep = printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002688 }
2689 }
2690
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002691 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll,
2692 false, dumpPackage, true, " Activities waiting to finish:", null);
2693 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll,
2694 false, dumpPackage, true, " Activities waiting to stop:", null);
2695 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll,
2696 false, dumpPackage, true, " Activities waiting for another to become visible:",
2697 null);
2698 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2699 false, dumpPackage, true, " Activities waiting to sleep:", null);
2700 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2701 false, dumpPackage, true, " Activities waiting to sleep:", null);
Craig Mautnerf3333272013-04-22 10:55:53 -07002702
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002703 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002704 }
2705
Dianne Hackborn390517b2013-05-30 15:03:32 -07002706 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
Craig Mautner8d341ef2013-03-26 09:03:27 -07002707 String prefix, String label, boolean complete, boolean brief, boolean client,
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002708 String dumpPackage, boolean needNL, String header1, String header2) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002709 TaskRecord lastTask = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002710 String innerPrefix = null;
2711 String[] args = null;
2712 boolean printed = false;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002713 for (int i=list.size()-1; i>=0; i--) {
2714 final ActivityRecord r = list.get(i);
2715 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2716 continue;
2717 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002718 if (innerPrefix == null) {
2719 innerPrefix = prefix + " ";
2720 args = new String[0];
2721 }
2722 printed = true;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002723 final boolean full = !brief && (complete || !r.isInHistory());
2724 if (needNL) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07002725 pw.println("");
Craig Mautner8d341ef2013-03-26 09:03:27 -07002726 needNL = false;
2727 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002728 if (header1 != null) {
2729 pw.println(header1);
2730 header1 = null;
2731 }
2732 if (header2 != null) {
2733 pw.println(header2);
2734 header2 = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002735 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002736 if (lastTask != r.task) {
2737 lastTask = r.task;
2738 pw.print(prefix);
2739 pw.print(full ? "* " : " ");
2740 pw.println(lastTask);
2741 if (full) {
2742 lastTask.dump(pw, prefix + " ");
2743 } else if (complete) {
2744 // Complete + brief == give a summary. Isn't that obvious?!?
2745 if (lastTask.intent != null) {
2746 pw.print(prefix); pw.print(" ");
2747 pw.println(lastTask.intent.toInsecureStringWithClip());
2748 }
2749 }
2750 }
2751 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
2752 pw.print(" #"); pw.print(i); pw.print(": ");
2753 pw.println(r);
2754 if (full) {
2755 r.dump(pw, innerPrefix);
2756 } else if (complete) {
2757 // Complete + brief == give a summary. Isn't that obvious?!?
2758 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2759 if (r.app != null) {
2760 pw.print(innerPrefix); pw.println(r.app);
2761 }
2762 }
2763 if (client && r.app != null && r.app.thread != null) {
2764 // flush anything that is already in the PrintWriter since the thread is going
2765 // to write to the file descriptor directly
2766 pw.flush();
2767 try {
2768 TransferPipe tp = new TransferPipe();
2769 try {
2770 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2771 r.appToken, innerPrefix, args);
2772 // Short timeout, since blocking here can
2773 // deadlock with the application.
2774 tp.go(fd, 2000);
2775 } finally {
2776 tp.kill();
2777 }
2778 } catch (IOException e) {
2779 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2780 } catch (RemoteException e) {
2781 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2782 }
2783 needNL = true;
2784 }
2785 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002786 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002787 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002788
Craig Mautnerf3333272013-04-22 10:55:53 -07002789 void scheduleIdleTimeoutLocked(ActivityRecord next) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002790 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
Craig Mautnerc64f73e2013-04-24 16:44:56 -07002791 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2792 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
Craig Mautnerf3333272013-04-22 10:55:53 -07002793 }
2794
2795 final void scheduleIdleLocked() {
Craig Mautner05d29032013-05-03 13:40:13 -07002796 mHandler.sendEmptyMessage(IDLE_NOW_MSG);
Craig Mautnerf3333272013-04-22 10:55:53 -07002797 }
2798
2799 void removeTimeoutsForActivityLocked(ActivityRecord r) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002800 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07002801 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2802 }
2803
Craig Mautner05d29032013-05-03 13:40:13 -07002804 final void scheduleResumeTopActivities() {
Craig Mautner34b73df2014-01-12 21:11:08 -08002805 if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
2806 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2807 }
Craig Mautner05d29032013-05-03 13:40:13 -07002808 }
2809
Craig Mautner0eea92c2013-05-16 13:35:39 -07002810 void removeSleepTimeouts() {
2811 mSleepTimeout = false;
2812 mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2813 }
2814
2815 final void scheduleSleepTimeout() {
2816 removeSleepTimeouts();
2817 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2818 }
2819
Craig Mautner4a1cb222013-12-04 16:14:06 -08002820 @Override
2821 public void onDisplayAdded(int displayId) {
2822 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
2823 }
2824
2825 @Override
2826 public void onDisplayRemoved(int displayId) {
2827 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
2828 }
2829
2830 @Override
2831 public void onDisplayChanged(int displayId) {
2832 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
2833 }
2834
2835 public void handleDisplayAddedLocked(int displayId) {
Craig Mautner4504de52013-12-20 09:06:56 -08002836 boolean newDisplay;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002837 synchronized (mService) {
Craig Mautner4504de52013-12-20 09:06:56 -08002838 newDisplay = mActivityDisplays.get(displayId) == null;
2839 if (newDisplay) {
2840 ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
2841 mActivityDisplays.put(displayId, activityDisplay);
2842 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002843 }
Craig Mautner4504de52013-12-20 09:06:56 -08002844 if (newDisplay) {
2845 mWindowManager.onDisplayAdded(displayId);
2846 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002847 }
2848
2849 public void handleDisplayRemovedLocked(int displayId) {
2850 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002851 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2852 if (activityDisplay != null) {
2853 ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002854 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner34b73df2014-01-12 21:11:08 -08002855 stacks.get(stackNdx).mActivityContainer.detachLocked();
Craig Mautner4a1cb222013-12-04 16:14:06 -08002856 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002857 mActivityDisplays.remove(displayId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002858 }
2859 }
2860 mWindowManager.onDisplayRemoved(displayId);
2861 }
2862
2863 public void handleDisplayChangedLocked(int displayId) {
2864 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002865 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2866 if (activityDisplay != null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002867 // TODO: Update the bounds.
2868 }
2869 }
2870 mWindowManager.onDisplayChanged(displayId);
2871 }
2872
2873 StackInfo getStackInfo(ActivityStack stack) {
2874 StackInfo info = new StackInfo();
2875 mWindowManager.getStackBounds(stack.mStackId, info.bounds);
2876 info.displayId = Display.DEFAULT_DISPLAY;
2877 info.stackId = stack.mStackId;
2878
2879 ArrayList<TaskRecord> tasks = stack.getAllTasks();
2880 final int numTasks = tasks.size();
2881 int[] taskIds = new int[numTasks];
2882 String[] taskNames = new String[numTasks];
2883 for (int i = 0; i < numTasks; ++i) {
2884 final TaskRecord task = tasks.get(i);
2885 taskIds[i] = task.taskId;
2886 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
2887 : task.realActivity != null ? task.realActivity.flattenToString()
2888 : task.getTopActivity() != null ? task.getTopActivity().packageName
2889 : "unknown";
2890 }
2891 info.taskIds = taskIds;
2892 info.taskNames = taskNames;
2893 return info;
2894 }
2895
2896 StackInfo getStackInfoLocked(int stackId) {
2897 ActivityStack stack = getStack(stackId);
2898 if (stack != null) {
2899 return getStackInfo(stack);
2900 }
2901 return null;
2902 }
2903
2904 ArrayList<StackInfo> getAllStackInfosLocked() {
2905 ArrayList<StackInfo> list = new ArrayList<StackInfo>();
Craig Mautnere0a38842013-12-16 16:14:02 -08002906 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2907 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002908 for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
2909 list.add(getStackInfo(stacks.get(ndx)));
2910 }
2911 }
2912 return list;
2913 }
2914
Craig Mautneraea74a52014-03-08 14:23:10 -08002915 void setLockTaskModeLocked(TaskRecord task) {
2916 if (task == null) {
2917 // Take out of lock task mode.
2918 mLockTaskModeTask = null;
2919 return;
2920 }
2921 if (isLockTaskModeViolation(task)) {
2922 Slog.e(TAG, "setLockTaskMode: Attempt to start a second Lock Task Mode task.");
2923 return;
2924 }
2925 mLockTaskModeTask = task;
2926 findTaskToMoveToFrontLocked(task, 0, null);
2927 resumeTopActivitiesLocked();
2928 }
2929
2930 boolean isLockTaskModeViolation(TaskRecord task) {
2931 return mLockTaskModeTask != null && mLockTaskModeTask != task;
2932 }
2933
2934 void endLockTaskModeIfTaskEnding(TaskRecord task) {
2935 if (mLockTaskModeTask != null && mLockTaskModeTask == task) {
2936 mLockTaskModeTask = null;
2937 }
2938 }
2939
2940 boolean isInLockTaskMode() {
2941 return mLockTaskModeTask != null;
2942 }
2943
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002944 private final class ActivityStackSupervisorHandler extends Handler {
Craig Mautnerf3333272013-04-22 10:55:53 -07002945
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002946 public ActivityStackSupervisorHandler(Looper looper) {
2947 super(looper);
2948 }
2949
Craig Mautnerf3333272013-04-22 10:55:53 -07002950 void activityIdleInternal(ActivityRecord r) {
2951 synchronized (mService) {
2952 activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
2953 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002954 }
2955
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002956 @Override
2957 public void handleMessage(Message msg) {
2958 switch (msg.what) {
Craig Mautnerf3333272013-04-22 10:55:53 -07002959 case IDLE_TIMEOUT_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002960 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002961 if (mService.mDidDexOpt) {
2962 mService.mDidDexOpt = false;
2963 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2964 nmsg.obj = msg.obj;
2965 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
2966 return;
2967 }
2968 // We don't at this point know if the activity is fullscreen,
2969 // so we need to be conservative and assume it isn't.
2970 activityIdleInternal((ActivityRecord)msg.obj);
2971 } break;
2972 case IDLE_NOW_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002973 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002974 activityIdleInternal((ActivityRecord)msg.obj);
2975 } break;
Craig Mautner05d29032013-05-03 13:40:13 -07002976 case RESUME_TOP_ACTIVITY_MSG: {
2977 synchronized (mService) {
2978 resumeTopActivitiesLocked();
2979 }
2980 } break;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002981 case SLEEP_TIMEOUT_MSG: {
2982 synchronized (mService) {
2983 if (mService.isSleepingOrShuttingDown()) {
2984 Slog.w(TAG, "Sleep timeout! Sleeping now.");
2985 mSleepTimeout = true;
2986 checkReadyForSleepLocked();
2987 }
2988 }
2989 } break;
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002990 case LAUNCH_TIMEOUT_MSG: {
2991 if (mService.mDidDexOpt) {
2992 mService.mDidDexOpt = false;
2993 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
2994 return;
2995 }
2996 synchronized (mService) {
2997 if (mLaunchingActivity.isHeld()) {
2998 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
2999 if (VALIDATE_WAKE_LOCK_CALLER
3000 && Binder.getCallingUid() != Process.myUid()) {
3001 throw new IllegalStateException("Calling must be system uid");
3002 }
3003 mLaunchingActivity.release();
3004 }
3005 }
3006 } break;
Craig Mautner4a1cb222013-12-04 16:14:06 -08003007 case HANDLE_DISPLAY_ADDED: {
3008 handleDisplayAddedLocked(msg.arg1);
3009 } break;
3010 case HANDLE_DISPLAY_CHANGED: {
3011 handleDisplayChangedLocked(msg.arg1);
3012 } break;
3013 case HANDLE_DISPLAY_REMOVED: {
3014 handleDisplayRemovedLocked(msg.arg1);
3015 } break;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07003016 }
3017 }
3018 }
Craig Mautnered6649f2013-12-02 14:08:25 -08003019
Craig Mautner4a1cb222013-12-04 16:14:06 -08003020 class ActivityContainer extends IActivityContainer.Stub {
3021 final int mStackId;
3022 final IActivityContainerCallback mCallback;
3023 final ActivityStack mStack;
3024 final ActivityRecord mParentActivity;
Craig Mautner34b73df2014-01-12 21:11:08 -08003025 final String mIdString;
Craig Mautnered6649f2013-12-02 14:08:25 -08003026
Craig Mautner4a1cb222013-12-04 16:14:06 -08003027 /** Display this ActivityStack is currently on. Null if not attached to a Display. */
Craig Mautnere0a38842013-12-16 16:14:02 -08003028 ActivityDisplay mActivityDisplay;
Craig Mautner4a1cb222013-12-04 16:14:06 -08003029
3030 ActivityContainer(ActivityRecord parentActivity, int stackId,
3031 IActivityContainerCallback callback) {
3032 synchronized (mService) {
3033 mStackId = stackId;
3034 mStack = new ActivityStack(this);
3035 mParentActivity = parentActivity;
3036 mCallback = callback;
Craig Mautner34b73df2014-01-12 21:11:08 -08003037 mIdString = "ActivtyContainer{" + mStackId + ", parent=" + mParentActivity + "}";
3038 if (DEBUG_STACK) Slog.d(TAG, "Creating " + this);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003039 }
Craig Mautnered6649f2013-12-02 14:08:25 -08003040 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08003041
Craig Mautnere0a38842013-12-16 16:14:02 -08003042 void attachToDisplayLocked(ActivityDisplay activityDisplay) {
Craig Mautner34b73df2014-01-12 21:11:08 -08003043 if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this
3044 + " to display=" + activityDisplay);
Craig Mautnere0a38842013-12-16 16:14:02 -08003045 mActivityDisplay = activityDisplay;
3046 mStack.mDisplayId = activityDisplay.mDisplayId;
3047 mStack.mStacks = activityDisplay.mStacks;
3048
3049 activityDisplay.attachActivities(mStack);
Craig Mautnerdf88d732014-01-27 09:21:32 -08003050 mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003051 }
3052
3053 @Override
Jeff Brownca9bc702014-02-11 14:32:56 -08003054 public void attachToDisplay(int displayId) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003055 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08003056 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3057 if (activityDisplay == null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003058 return;
3059 }
Craig Mautnere0a38842013-12-16 16:14:02 -08003060 attachToDisplayLocked(activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003061 }
3062 }
3063
3064 @Override
Jeff Brownca9bc702014-02-11 14:32:56 -08003065 public int getDisplayId() {
Craig Mautnere0a38842013-12-16 16:14:02 -08003066 if (mActivityDisplay != null) {
3067 return mActivityDisplay.mDisplayId;
3068 }
3069 return -1;
Craig Mautner4a1cb222013-12-04 16:14:06 -08003070 }
3071
Jeff Brownca9bc702014-02-11 14:32:56 -08003072 @Override
3073 public boolean injectEvent(InputEvent event) {
3074 final long origId = Binder.clearCallingIdentity();
3075 try {
3076 if (mActivityDisplay != null) {
3077 return mInputManagerInternal.injectInputEvent(event,
3078 mActivityDisplay.mDisplayId,
3079 InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
3080 }
3081 return false;
3082 } finally {
3083 Binder.restoreCallingIdentity(origId);
3084 }
3085 }
3086
Craig Mautner34b73df2014-01-12 21:11:08 -08003087 private void detachLocked() {
3088 if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display="
3089 + mActivityDisplay + " Callers=" + Debug.getCallers(2));
Craig Mautnere0a38842013-12-16 16:14:02 -08003090 if (mActivityDisplay != null) {
3091 mActivityDisplay.detachActivitiesLocked(mStack);
3092 mActivityDisplay = null;
3093 mStack.mDisplayId = -1;
3094 mStack.mStacks = null;
Craig Mautnerdf88d732014-01-27 09:21:32 -08003095 mWindowManager.detachStack(mStackId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003096 }
3097 }
3098
3099 @Override
Jeff Brownca9bc702014-02-11 14:32:56 -08003100 public void detachFromDisplay() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003101 synchronized (mService) {
3102 detachLocked();
3103 }
3104 }
3105
3106 @Override
Craig Mautnere0a38842013-12-16 16:14:02 -08003107 public final int startActivity(Intent intent) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08003108 mService.enforceNotIsolatedCaller("ActivityContainer.startActivity");
Craig Mautnere0a38842013-12-16 16:14:02 -08003109 int userId = mService.handleIncomingUser(Binder.getCallingPid(),
3110 Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null);
3111 // TODO: Switch to user app stacks here.
3112 String mimeType = intent.getType();
3113 if (mimeType == null && intent.getData() != null
3114 && "content".equals(intent.getData().getScheme())) {
3115 mimeType = mService.getProviderMimeType(intent.getData(), userId);
3116 }
3117 return startActivityMayWait(null, -1, null, intent, mimeType, null, null, 0, 0, null,
3118 null, null, null, null, userId, this);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003119 }
3120
3121 @Override
Craig Mautnerdf88d732014-01-27 09:21:32 -08003122 public final int startActivityIntentSender(IIntentSender intentSender) {
3123 mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
3124
3125 if (!(intentSender instanceof PendingIntentRecord)) {
3126 throw new IllegalArgumentException("Bad PendingIntent object");
3127 }
3128
3129 return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null,
3130 null, 0, 0, 0, null, this);
3131 }
3132
3133 @Override
Craig Mautner4a1cb222013-12-04 16:14:06 -08003134 public IBinder asBinder() {
3135 return this;
3136 }
3137
Craig Mautner4504de52013-12-20 09:06:56 -08003138 @Override
Craig Mautner34b73df2014-01-12 21:11:08 -08003139 public void attachToSurface(Surface surface, int width, int height, int density) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08003140 mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
3141
3142 final long origId = Binder.clearCallingIdentity();
3143 try {
3144 synchronized (mService) {
3145 ActivityDisplay activityDisplay =
3146 new ActivityDisplay(surface, width, height, density);
3147 mActivityDisplays.put(activityDisplay.mDisplayId, activityDisplay);
3148 attachToDisplayLocked(activityDisplay);
3149 mStack.resumeTopActivityLocked(null);
3150 }
3151 if (DEBUG_STACK) Slog.d(TAG, "attachToSurface: " + this + " to display="
3152 + mActivityDisplay);
3153 } finally {
3154 Binder.restoreCallingIdentity(origId);
Craig Mautner4504de52013-12-20 09:06:56 -08003155 }
Craig Mautner4504de52013-12-20 09:06:56 -08003156 }
3157
Craig Mautner4a1cb222013-12-04 16:14:06 -08003158 ActivityStackSupervisor getOuter() {
3159 return ActivityStackSupervisor.this;
3160 }
3161
3162 boolean isAttached() {
Craig Mautnere0a38842013-12-16 16:14:02 -08003163 return mActivityDisplay != null;
Craig Mautner4a1cb222013-12-04 16:14:06 -08003164 }
3165
3166 void getBounds(Point outBounds) {
Craig Mautnere0a38842013-12-16 16:14:02 -08003167 if (mActivityDisplay != null) {
3168 mActivityDisplay.getBounds(outBounds);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003169 } else {
3170 outBounds.set(0, 0);
3171 }
3172 }
Craig Mautner34b73df2014-01-12 21:11:08 -08003173
3174 @Override
3175 public String toString() {
3176 return mIdString + (mActivityDisplay == null ? "N" : "A");
3177 }
Craig Mautnered6649f2013-12-02 14:08:25 -08003178 }
3179
Craig Mautner4a1cb222013-12-04 16:14:06 -08003180 /** Exactly one of these classes per Display in the system. Capable of holding zero or more
3181 * attached {@link ActivityStack}s */
Craig Mautnere0a38842013-12-16 16:14:02 -08003182 final class ActivityDisplay {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003183 /** Actual Display this object tracks. */
Craig Mautner34b73df2014-01-12 21:11:08 -08003184 int mDisplayId;
3185 Display mDisplay;
3186 DisplayInfo mDisplayInfo = new DisplayInfo();
3187 Surface mSurface;
Craig Mautnered6649f2013-12-02 14:08:25 -08003188
Craig Mautner4a1cb222013-12-04 16:14:06 -08003189 /** All of the stacks on this display. Order matters, topmost stack is in front of all other
3190 * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
Craig Mautnere0a38842013-12-16 16:14:02 -08003191 final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003192
Craig Mautner4504de52013-12-20 09:06:56 -08003193 /** If this display is for an ActivityView then the VirtualDisplay created for it is stored
3194 * here. */
3195 VirtualDisplay mVirtualDisplay;
3196
Craig Mautnere0a38842013-12-16 16:14:02 -08003197 ActivityDisplay(int displayId) {
Craig Mautner34b73df2014-01-12 21:11:08 -08003198 init(mDisplayManager.getDisplay(displayId));
Craig Mautner4504de52013-12-20 09:06:56 -08003199 }
3200
Craig Mautner34b73df2014-01-12 21:11:08 -08003201 ActivityDisplay(Surface surface, int width, int height, int density) {
3202 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
3203 long ident = Binder.clearCallingIdentity();
3204 try {
3205 mVirtualDisplay = dm.createVirtualDisplay(mService.mContext,
3206 VIRTUAL_DISPLAY_BASE_NAME, width, height, density, surface,
3207 DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
3208 DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY);
3209 } finally {
3210 Binder.restoreCallingIdentity(ident);
3211 }
3212
3213 init(mVirtualDisplay.getDisplay());
3214 mSurface = surface;
3215
3216 mWindowManager.handleDisplayAdded(mDisplayId);
3217 }
3218
3219 private void init(Display display) {
Craig Mautner4504de52013-12-20 09:06:56 -08003220 mDisplay = display;
3221 mDisplayId = display.getDisplayId();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003222 mDisplay.getDisplayInfo(mDisplayInfo);
Craig Mautnered6649f2013-12-02 14:08:25 -08003223 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08003224
3225 void attachActivities(ActivityStack stack) {
Craig Mautnere0a38842013-12-16 16:14:02 -08003226 if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId="
3227 + mDisplayId);
3228 mStacks.add(stack);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003229 }
3230
Craig Mautnere0a38842013-12-16 16:14:02 -08003231 void detachActivitiesLocked(ActivityStack stack) {
Craig Mautner34b73df2014-01-12 21:11:08 -08003232 if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack
Craig Mautnere0a38842013-12-16 16:14:02 -08003233 + " from displayId=" + mDisplayId);
3234 mStacks.remove(stack);
Craig Mautner34b73df2014-01-12 21:11:08 -08003235 if (mStacks.isEmpty() && mVirtualDisplay != null) {
3236 mVirtualDisplay.release();
3237 mVirtualDisplay = null;
3238 }
3239 mSurface.release();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003240 }
3241
3242 void getBounds(Point bounds) {
3243 mDisplay.getDisplayInfo(mDisplayInfo);
3244 bounds.x = mDisplayInfo.appWidth;
3245 bounds.y = mDisplayInfo.appHeight;
3246 }
Craig Mautner34b73df2014-01-12 21:11:08 -08003247
3248 @Override
3249 public String toString() {
3250 return "ActivityDisplay={" + mDisplayId + (mVirtualDisplay == null ? "" : "V")
3251 + " numStacks=" + mStacks.size() + "}";
3252 }
Craig Mautnered6649f2013-12-02 14:08:25 -08003253 }
Craig Mautner27084302013-03-25 08:05:25 -07003254}