blob: 09ec4f6c2b43ff5243ebc8ba97404f6f864510da [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 {
Craig Mautner74266842013-12-19 13:02:30 -0800414 if (realStartActivityLocked(hr, app, true, true, null)) {
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,
Adam Powellcfbe9be2013-11-06 14:58:58 -0800938 ProcessRecord app, boolean andResume, boolean checkConfig, Bundle resumeArgs)
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);
Craig Mautner2420ead2013-04-01 17:13:20 -07001032 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
1033 System.identityHashCode(r), r.info,
Dianne Hackborna413dc02013-07-12 12:02:55 -07001034 new Configuration(mService.mConfiguration), r.compat,
1035 app.repProcState, r.icicle, results, newIntents, !andResume,
Craig Mautner2420ead2013-04-01 17:13:20 -07001036 mService.isNextTransitionForward(), profileFile, profileFd,
Adam Powellcfbe9be2013-11-06 14:58:58 -08001037 profileAutoStop, resumeArgs);
Craig Mautner2420ead2013-04-01 17:13:20 -07001038
1039 if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
1040 // This may be a heavy-weight process! Note that the package
1041 // manager will ensure that only activity can run in the main
1042 // process of the .apk, which is the only thing that will be
1043 // considered heavy-weight.
1044 if (app.processName.equals(app.info.packageName)) {
1045 if (mService.mHeavyWeightProcess != null
1046 && mService.mHeavyWeightProcess != app) {
1047 Slog.w(TAG, "Starting new heavy weight process " + app
1048 + " when already running "
1049 + mService.mHeavyWeightProcess);
1050 }
1051 mService.mHeavyWeightProcess = app;
1052 Message msg = mService.mHandler.obtainMessage(
1053 ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
1054 msg.obj = r;
1055 mService.mHandler.sendMessage(msg);
1056 }
1057 }
1058
1059 } catch (RemoteException e) {
1060 if (r.launchFailed) {
1061 // This is the second time we failed -- finish activity
1062 // and give up.
1063 Slog.e(TAG, "Second failure launching "
1064 + r.intent.getComponent().flattenToShortString()
1065 + ", giving up", e);
1066 mService.appDiedLocked(app, app.pid, app.thread);
1067 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
1068 "2nd-crash", false);
1069 return false;
1070 }
1071
1072 // This is the first time we failed -- restart process and
1073 // retry.
1074 app.activities.remove(r);
1075 throw e;
1076 }
1077
1078 r.launchFailed = false;
1079 if (stack.updateLRUListLocked(r)) {
1080 Slog.w(TAG, "Activity " + r
1081 + " being launched, but already in LRU list");
1082 }
1083
1084 if (andResume) {
1085 // As part of the process of launching, ActivityThread also performs
1086 // a resume.
1087 stack.minimalResumeActivityLocked(r);
1088 } else {
1089 // This activity is not starting in the resumed state... which
1090 // should look like we asked it to pause+stop (but remain visible),
1091 // and it has done so and reported back the current icicle and
1092 // other state.
1093 if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r
1094 + " (starting in stopped state)");
1095 r.state = ActivityState.STOPPED;
1096 r.stopped = true;
1097 }
1098
1099 // Launch the new version setup screen if needed. We do this -after-
1100 // launching the initial activity (that is, home), so that it can have
1101 // a chance to initialize itself while in the background, making the
1102 // switch back to it faster and look better.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001103 if (isFrontStack(stack)) {
Craig Mautner2420ead2013-04-01 17:13:20 -07001104 mService.startSetupActivityLocked();
1105 }
1106
1107 return true;
1108 }
1109
Craig Mautnere79d42682013-04-01 19:01:53 -07001110 void startSpecificActivityLocked(ActivityRecord r,
Adam Powellcfbe9be2013-11-06 14:58:58 -08001111 boolean andResume, boolean checkConfig, Bundle resumeArgs) {
Craig Mautnere79d42682013-04-01 19:01:53 -07001112 // Is this activity's application already running?
1113 ProcessRecord app = mService.getProcessRecordLocked(r.processName,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001114 r.info.applicationInfo.uid, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001115
1116 r.task.stack.setLaunchTime(r);
1117
1118 if (app != null && app.thread != null) {
1119 try {
Dianne Hackborn237cefb2013-10-22 18:45:27 -07001120 if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
1121 || !"android".equals(r.info.packageName)) {
1122 // Don't add this if it is a platform component that is marked
1123 // to run in multiple processes, because this is actually
1124 // part of the framework so doesn't make sense to track as a
1125 // separate apk in the process.
1126 app.addPackage(r.info.packageName, mService.mProcessStats);
1127 }
Adam Powellcfbe9be2013-11-06 14:58:58 -08001128 realStartActivityLocked(r, app, andResume, checkConfig, resumeArgs);
Craig Mautnere79d42682013-04-01 19:01:53 -07001129 return;
1130 } catch (RemoteException e) {
1131 Slog.w(TAG, "Exception when starting activity "
1132 + r.intent.getComponent().flattenToShortString(), e);
1133 }
1134
1135 // If a dead object exception was thrown -- fall through to
1136 // restart the application.
1137 }
1138
1139 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001140 "activity", r.intent.getComponent(), false, false, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001141 }
1142
Craig Mautner6170f732013-04-02 13:05:23 -07001143 final int startActivityLocked(IApplicationThread caller,
1144 Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
1145 String resultWho, int requestCode,
1146 int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
Craig Mautnere0a38842013-12-16 16:14:02 -08001147 boolean componentSpecified, ActivityRecord[] outActivity, ActivityContainer container) {
Craig Mautner6170f732013-04-02 13:05:23 -07001148 int err = ActivityManager.START_SUCCESS;
1149
1150 ProcessRecord callerApp = null;
1151 if (caller != null) {
1152 callerApp = mService.getRecordForAppLocked(caller);
1153 if (callerApp != null) {
1154 callingPid = callerApp.pid;
1155 callingUid = callerApp.info.uid;
1156 } else {
1157 Slog.w(TAG, "Unable to find app for caller " + caller
1158 + " (pid=" + callingPid + ") when starting: "
1159 + intent.toString());
1160 err = ActivityManager.START_PERMISSION_DENIED;
1161 }
1162 }
1163
1164 if (err == ActivityManager.START_SUCCESS) {
1165 final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
1166 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
Craig Mautner9ef471f2014-02-07 13:11:47 -08001167 + "} from pid " + (callerApp != null ? callerApp.pid : callingPid)
1168 + " on display " + (container == null ? (mFocusedStack == null ?
1169 Display.DEFAULT_DISPLAY : mFocusedStack.mDisplayId) :
1170 (container.mActivityDisplay == null ? Display.DEFAULT_DISPLAY :
1171 container.mActivityDisplay.mDisplayId)));
Craig Mautner6170f732013-04-02 13:05:23 -07001172 }
1173
1174 ActivityRecord sourceRecord = null;
1175 ActivityRecord resultRecord = null;
1176 if (resultTo != null) {
1177 sourceRecord = isInAnyStackLocked(resultTo);
1178 if (DEBUG_RESULTS) Slog.v(
1179 TAG, "Will send result to " + resultTo + " " + sourceRecord);
1180 if (sourceRecord != null) {
1181 if (requestCode >= 0 && !sourceRecord.finishing) {
1182 resultRecord = sourceRecord;
1183 }
1184 }
1185 }
1186 ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
1187
1188 int launchFlags = intent.getFlags();
1189
1190 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
1191 && sourceRecord != null) {
1192 // Transfer the result target from the source activity to the new
1193 // one being started, including any failures.
1194 if (requestCode >= 0) {
1195 ActivityOptions.abort(options);
1196 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
1197 }
1198 resultRecord = sourceRecord.resultTo;
1199 resultWho = sourceRecord.resultWho;
1200 requestCode = sourceRecord.requestCode;
1201 sourceRecord.resultTo = null;
1202 if (resultRecord != null) {
1203 resultRecord.removeResultsLocked(
1204 sourceRecord, resultWho, requestCode);
1205 }
Dianne Hackbornd4981012014-03-14 16:27:40 +00001206 if (sourceRecord.launchedFromUid == callingUid) {
1207 // The new activity is being launched from the same uid as the previous
1208 // activity in the flow, and asking to forward its result back to the
1209 // previous. In this case the activity is serving as a trampoline between
1210 // the two, so we also want to update its launchedFromPackage to be the
1211 // same as the previous activity. Note that this is safe, since we know
1212 // these two packages come from the same uid; the caller could just as
1213 // well have supplied that same package name itself. This specifially
1214 // deals with the case of an intent picker/chooser being launched in the app
1215 // flow to redirect to an activity picked by the user, where we want the final
1216 // activity to consider it to have been launched by the previous app activity.
1217 callingPackage = sourceRecord.launchedFromPackage;
1218 }
Craig Mautner6170f732013-04-02 13:05:23 -07001219 }
1220
1221 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
1222 // We couldn't find a class that can handle the given Intent.
1223 // That's the end of that!
1224 err = ActivityManager.START_INTENT_NOT_RESOLVED;
1225 }
1226
1227 if (err == ActivityManager.START_SUCCESS && aInfo == null) {
1228 // We couldn't find the specific class specified in the Intent.
1229 // Also the end of the line.
1230 err = ActivityManager.START_CLASS_NOT_FOUND;
1231 }
1232
1233 if (err != ActivityManager.START_SUCCESS) {
1234 if (resultRecord != null) {
1235 resultStack.sendActivityResultLocked(-1,
1236 resultRecord, resultWho, requestCode,
1237 Activity.RESULT_CANCELED, null);
1238 }
1239 setDismissKeyguard(false);
1240 ActivityOptions.abort(options);
1241 return err;
1242 }
1243
1244 final int startAnyPerm = mService.checkPermission(
1245 START_ANY_ACTIVITY, callingPid, callingUid);
1246 final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
1247 callingUid, aInfo.applicationInfo.uid, aInfo.exported);
1248 if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
1249 if (resultRecord != null) {
1250 resultStack.sendActivityResultLocked(-1,
1251 resultRecord, resultWho, requestCode,
1252 Activity.RESULT_CANCELED, null);
1253 }
1254 setDismissKeyguard(false);
1255 String msg;
1256 if (!aInfo.exported) {
1257 msg = "Permission Denial: starting " + intent.toString()
1258 + " from " + callerApp + " (pid=" + callingPid
1259 + ", uid=" + callingUid + ")"
1260 + " not exported from uid " + aInfo.applicationInfo.uid;
1261 } else {
1262 msg = "Permission Denial: starting " + intent.toString()
1263 + " from " + callerApp + " (pid=" + callingPid
1264 + ", uid=" + callingUid + ")"
1265 + " requires " + aInfo.permission;
1266 }
1267 Slog.w(TAG, msg);
1268 throw new SecurityException(msg);
1269 }
1270
Ben Gruverdd72c9e2013-08-06 12:34:17 -07001271 boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
Ben Gruverb6223792013-07-29 16:35:40 -07001272 callingPid, resolvedType, aInfo.applicationInfo);
Ben Gruver5e207332013-04-03 17:41:37 -07001273
Craig Mautner6170f732013-04-02 13:05:23 -07001274 if (mService.mController != null) {
Craig Mautner6170f732013-04-02 13:05:23 -07001275 try {
1276 // The Intent we give to the watcher has the extra data
1277 // stripped off, since it can contain private information.
1278 Intent watchIntent = intent.cloneFilter();
Ben Gruver5e207332013-04-03 17:41:37 -07001279 abort |= !mService.mController.activityStarting(watchIntent,
Craig Mautner6170f732013-04-02 13:05:23 -07001280 aInfo.applicationInfo.packageName);
1281 } catch (RemoteException e) {
1282 mService.mController = null;
1283 }
Ben Gruver5e207332013-04-03 17:41:37 -07001284 }
Craig Mautner6170f732013-04-02 13:05:23 -07001285
Ben Gruver5e207332013-04-03 17:41:37 -07001286 if (abort) {
1287 if (resultRecord != null) {
1288 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
Craig Mautner6170f732013-04-02 13:05:23 -07001289 Activity.RESULT_CANCELED, null);
Craig Mautner6170f732013-04-02 13:05:23 -07001290 }
Ben Gruver5e207332013-04-03 17:41:37 -07001291 // We pretend to the caller that it was really started, but
1292 // they will just get a cancel result.
1293 setDismissKeyguard(false);
1294 ActivityOptions.abort(options);
1295 return ActivityManager.START_SUCCESS;
Craig Mautner6170f732013-04-02 13:05:23 -07001296 }
1297
1298 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
Craig Mautnere0a38842013-12-16 16:14:02 -08001299 intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
1300 requestCode, componentSpecified, this, container);
Craig Mautner6170f732013-04-02 13:05:23 -07001301 if (outActivity != null) {
1302 outActivity[0] = r;
1303 }
1304
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001305 final ActivityStack stack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001306 if (stack.mResumedActivity == null
1307 || stack.mResumedActivity.info.applicationInfo.uid != callingUid) {
Craig Mautner6170f732013-04-02 13:05:23 -07001308 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
1309 PendingActivityLaunch pal =
Craig Mautnerde4ef022013-04-07 19:01:33 -07001310 new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
Craig Mautner6170f732013-04-02 13:05:23 -07001311 mService.mPendingActivityLaunches.add(pal);
1312 setDismissKeyguard(false);
1313 ActivityOptions.abort(options);
1314 return ActivityManager.START_SWITCHES_CANCELED;
1315 }
1316 }
1317
1318 if (mService.mDidAppSwitch) {
1319 // This is the second allowed switch since we stopped switches,
1320 // so now just generally allow switches. Use case: user presses
1321 // home (switches disabled, switch to home, mDidAppSwitch now true);
1322 // user taps a home icon (coming from home so allowed, we hit here
1323 // and now allow anyone to switch again).
1324 mService.mAppSwitchesAllowedTime = 0;
1325 } else {
1326 mService.mDidAppSwitch = true;
1327 }
1328
1329 mService.doPendingActivityLaunchesLocked(false);
1330
Craig Mautner8849a5e2013-04-02 16:41:03 -07001331 err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
Craig Mautner10385a12013-09-22 21:08:32 -07001332
1333 if (allPausedActivitiesComplete()) {
1334 // If someone asked to have the keyguard dismissed on the next
Craig Mautner6170f732013-04-02 13:05:23 -07001335 // activity start, but we are not actually doing an activity
1336 // switch... just dismiss the keyguard now, because we
1337 // probably want to see whatever is behind it.
1338 dismissKeyguard();
1339 }
1340 return err;
1341 }
1342
Craig Mautnerac6f8432013-07-17 13:24:59 -07001343 ActivityStack adjustStackFocus(ActivityRecord r) {
Craig Mautner1d001b62013-06-18 16:52:43 -07001344 final TaskRecord task = r.task;
1345 if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001346 if (task != null) {
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07001347 final ActivityStack taskStack = task.stack;
Craig Mautnere0a38842013-12-16 16:14:02 -08001348 if (taskStack.isOnHomeDisplay()) {
1349 if (mFocusedStack != taskStack) {
1350 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: Setting " +
1351 "focused stack to r=" + r + " task=" + task);
1352 mFocusedStack = taskStack;
1353 } else {
1354 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1355 "adjustStackFocus: Focused stack already=" + mFocusedStack);
1356 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001357 }
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07001358 return taskStack;
Craig Mautnerac6f8432013-07-17 13:24:59 -07001359 }
1360
Craig Mautnere0a38842013-12-16 16:14:02 -08001361 final ActivityContainer container = r.mInitialActivityContainer;
1362 if (container != null) {
1363 // The first time put it on the desired stack, after this put on task stack.
1364 r.mInitialActivityContainer = null;
1365 return container.mStack;
1366 }
1367
Craig Mautner4a1cb222013-12-04 16:14:06 -08001368 if (mFocusedStack != mHomeStack) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001369 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1370 "adjustStackFocus: Have a focused stack=" + mFocusedStack);
1371 return mFocusedStack;
1372 }
1373
Craig Mautnere0a38842013-12-16 16:14:02 -08001374 final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks;
1375 for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1376 final ActivityStack stack = homeDisplayStacks.get(stackNdx);
1377 if (!stack.isHomeStack()) {
1378 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1379 "adjustStackFocus: Setting focused stack=" + stack);
1380 mFocusedStack = stack;
1381 return mFocusedStack;
Craig Mautner858d8a62013-04-23 17:08:34 -07001382 }
1383 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001384
Craig Mautner4a1cb222013-12-04 16:14:06 -08001385 // Need to create an app stack for this user.
1386 int stackId = createStackOnDisplay(null, getNextStackId(), Display.DEFAULT_DISPLAY);
Craig Mautnerac6f8432013-07-17 13:24:59 -07001387 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r +
1388 " stackId=" + stackId);
1389 mFocusedStack = getStack(stackId);
Craig Mautner29219d92013-04-16 20:19:12 -07001390 return mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001391 }
1392 return mHomeStack;
1393 }
1394
Craig Mautner29219d92013-04-16 20:19:12 -07001395 void setFocusedStack(ActivityRecord r) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08001396 if (r != null) {
Craig Mautner12ff7392014-02-21 21:08:00 -08001397 final TaskRecord task = r.task;
1398 boolean isHomeActivity = !r.isApplicationActivity();
1399 if (!isHomeActivity && task != null) {
1400 isHomeActivity = !task.isApplicationTask();
1401 }
1402 if (!isHomeActivity && task != null) {
1403 final ActivityRecord parent = task.stack.mActivityContainer.mParentActivity;
1404 isHomeActivity = parent != null && parent.isHomeActivity();
1405 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08001406 moveHomeStack(isHomeActivity);
Craig Mautner29219d92013-04-16 20:19:12 -07001407 }
1408 }
1409
Craig Mautner8849a5e2013-04-02 16:41:03 -07001410 final int startActivityUncheckedLocked(ActivityRecord r,
1411 ActivityRecord sourceRecord, int startFlags, boolean doResume,
1412 Bundle options) {
1413 final Intent intent = r.intent;
1414 final int callingUid = r.launchedFromUid;
1415
1416 int launchFlags = intent.getFlags();
1417
Craig Mautner8849a5e2013-04-02 16:41:03 -07001418 // We'll invoke onUserLeaving before onPause only if the launching
1419 // activity did not explicitly state that this is an automated launch.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001420 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1421 if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001422
1423 // If the caller has asked not to resume at this point, we make note
1424 // of this in the record so that we can skip it when trying to find
1425 // the top running activity.
1426 if (!doResume) {
1427 r.delayedResume = true;
1428 }
1429
1430 ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1431
1432 // If the onlyIfNeeded flag is set, then we can do this if the activity
1433 // being launched is the same as the one making the call... or, as
1434 // a special case, if we do not know the caller then we count the
1435 // current top activity as the caller.
1436 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1437 ActivityRecord checkedCaller = sourceRecord;
1438 if (checkedCaller == null) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001439 checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001440 }
1441 if (!checkedCaller.realActivity.equals(r.realActivity)) {
1442 // Caller is not the same as launcher, so always needed.
1443 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
1444 }
1445 }
1446
Craig Mautnerd00f4742014-03-12 14:17:26 -07001447 final boolean newDocument = intent.isDocument();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001448 if (sourceRecord == null) {
1449 // This activity is not being started from another... in this
1450 // case we -always- start a new task.
Craig Mautnerd00f4742014-03-12 14:17:26 -07001451 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
Craig Mautner29219d92013-04-16 20:19:12 -07001452 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1453 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001454 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1455 }
Craig Mautnerd00f4742014-03-12 14:17:26 -07001456 } else if (newDocument) {
1457 if (r.launchMode != ActivityInfo.LAUNCH_MULTIPLE) {
1458 Slog.w(TAG, "FLAG_ACTIVITY_NEW_DOCUMENT and launchMode != \"standard\"");
1459 r.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
1460 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001461 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1462 // The original activity who is starting us is running as a single
1463 // instance... this new activity it is starting must go on its
1464 // own task.
1465 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1466 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
1467 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1468 // The activity being started is a single instance... it always
1469 // gets launched into its own task.
1470 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1471 }
1472
Craig Mautner88629292013-11-10 20:39:05 -08001473 ActivityInfo newTaskInfo = null;
1474 Intent newTaskIntent = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001475 final ActivityStack sourceStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001476 if (sourceRecord != null) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001477 if (sourceRecord.finishing) {
1478 // If the source is finishing, we can't further count it as our source. This
1479 // is because the task it is associated with may now be empty and on its way out,
1480 // so we don't want to blindly throw it in to that task. Instead we will take
Craig Mautner88629292013-11-10 20:39:05 -08001481 // the NEW_TASK flow and try to find a task for it. But save the task information
1482 // so it can be used when creating the new task.
Craig Mautnerd00f4742014-03-12 14:17:26 -07001483 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001484 Slog.w(TAG, "startActivity called from finishing " + sourceRecord
1485 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
1486 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
Craig Mautner88629292013-11-10 20:39:05 -08001487 newTaskInfo = sourceRecord.info;
1488 newTaskIntent = sourceRecord.task.intent;
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001489 }
1490 sourceRecord = null;
1491 sourceStack = null;
1492 } else {
1493 sourceStack = sourceRecord.task.stack;
1494 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07001495 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001496 sourceStack = null;
1497 }
1498
Craig Mautnerd00f4742014-03-12 14:17:26 -07001499 if (r.resultTo != null && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001500 // For whatever reason this activity is being launched into a new
1501 // task... yet the caller has requested a result back. Well, that
1502 // is pretty messed up, so instead immediately send back a cancel
1503 // and let the new task continue launched as normal without a
1504 // dependency on its originator.
1505 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1506 r.resultTo.task.stack.sendActivityResultLocked(-1,
1507 r.resultTo, r.resultWho, r.requestCode,
1508 Activity.RESULT_CANCELED, null);
1509 r.resultTo = null;
1510 }
1511
1512 boolean addingToTask = false;
1513 boolean movedHome = false;
1514 TaskRecord reuseTask = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001515 ActivityStack targetStack;
Craig Mautnerd00f4742014-03-12 14:17:26 -07001516 if (((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
1517 (launchFlags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
Craig Mautner8849a5e2013-04-02 16:41:03 -07001518 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1519 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1520 // If bring to front is requested, and no result is requested, and
1521 // we can find a task that was started with this same
1522 // component, then instead of launching bring that one to the front.
1523 if (r.resultTo == null) {
1524 // See if there is a task to bring to the front. If this is
1525 // a SINGLE_INSTANCE activity, there can be one and only one
1526 // instance of it in the history, and it is always in its own
1527 // unique task, so we do a special search.
1528 ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
Craig Mautnerac6f8432013-07-17 13:24:59 -07001529 ? findTaskLocked(r)
Craig Mautner8849a5e2013-04-02 16:41:03 -07001530 : findActivityLocked(intent, r.info);
1531 if (intentActivity != null) {
Craig Mautneraea74a52014-03-08 14:23:10 -08001532 if (isLockTaskModeViolation(intentActivity.task)) {
1533 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
1534 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
1535 }
Craig Mautner29219d92013-04-16 20:19:12 -07001536 if (r.task == null) {
1537 r.task = intentActivity.task;
1538 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001539 targetStack = intentActivity.task.stack;
Craig Mautner0f922742013-08-06 08:44:42 -07001540 targetStack.mLastPausedActivity = null;
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001541 if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack
1542 + " from " + intentActivity);
Craig Mautnere0a38842013-12-16 16:14:02 -08001543 targetStack.moveToFront();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001544 if (intentActivity.task.intent == null) {
1545 // This task was started because of movement of
1546 // the activity based on affinity... now that we
1547 // are actually launching it, we can assign the
1548 // base intent.
1549 intentActivity.task.setIntent(intent, r.info);
1550 }
1551 // If the target task is not in the front, then we need
1552 // to bring it to the front... except... well, with
1553 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like
1554 // to have the same behavior as if a new instance was
1555 // being started, which means not bringing it to the front
1556 // if the caller is not itself in the front.
Craig Mautner165640b2013-04-20 10:34:33 -07001557 final ActivityStack lastStack = getLastStack();
1558 ActivityRecord curTop = lastStack == null?
1559 null : lastStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner7504d7b2013-09-17 10:50:53 -07001560 if (curTop != null && (curTop.task != intentActivity.task ||
1561 curTop.task != lastStack.topTask())) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001562 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Craig Mautnerd0f964f2013-08-07 11:16:33 -07001563 if (sourceRecord == null || (sourceStack.topActivity() != null &&
1564 sourceStack.topActivity().task == sourceRecord.task)) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001565 // We really do want to push this one into the
1566 // user's face, right now.
1567 movedHome = true;
Craig Mautnerb53d97c2013-10-25 11:54:37 -07001568 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001569 if ((launchFlags &
Craig Mautner29219d92013-04-16 20:19:12 -07001570 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1571 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
Craig Mautnere12a4a62013-08-29 12:24:56 -07001572 // Caller wants to appear on home activity.
Craig Mautnerae7ecab2013-09-18 11:48:14 -07001573 intentActivity.task.mOnTopOfHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001574 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001575 options = null;
1576 }
1577 }
1578 // If the caller has requested that the target task be
1579 // reset, then do so.
1580 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1581 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
1582 }
1583 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1584 // We don't need to start a new activity, and
1585 // the client said not to do anything if that
1586 // is the case, so this is it! And for paranoia, make
1587 // sure we have correctly resumed the top activity.
1588 if (doResume) {
Craig Mautner05d29032013-05-03 13:40:13 -07001589 resumeTopActivitiesLocked(targetStack, null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001590 } else {
1591 ActivityOptions.abort(options);
1592 }
1593 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1594 }
1595 if ((launchFlags &
1596 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
1597 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
1598 // The caller has requested to completely replace any
1599 // existing task with its new activity. Well that should
1600 // not be too hard...
1601 reuseTask = intentActivity.task;
1602 reuseTask.performClearTaskLocked();
1603 reuseTask.setIntent(r.intent, r.info);
1604 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
1605 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1606 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1607 // In this situation we want to remove all activities
1608 // from the task up to the one being started. In most
1609 // cases this means we are resetting the task to its
1610 // initial state.
1611 ActivityRecord top =
1612 intentActivity.task.performClearTaskLocked(r, launchFlags);
1613 if (top != null) {
1614 if (top.frontOfTask) {
1615 // Activity aliases may mean we use different
1616 // intents for the top activity, so make sure
1617 // the task now has the identity of the new
1618 // intent.
1619 top.task.setIntent(r.intent, r.info);
1620 }
1621 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
1622 r, top.task);
1623 top.deliverNewIntentLocked(callingUid, r.intent);
1624 } else {
1625 // A special case: we need to
1626 // start the activity because it is not currently
1627 // running, and the caller has asked to clear the
1628 // current task to have this activity at the top.
1629 addingToTask = true;
1630 // Now pretend like this activity is being started
1631 // by the top of its task, so it is put in the
1632 // right place.
1633 sourceRecord = intentActivity;
1634 }
1635 } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
1636 // In this case the top activity on the task is the
1637 // same as the one being launched, so we take that
1638 // as a request to bring the task to the foreground.
1639 // If the top activity in the task is the root
1640 // activity, deliver this new intent to it if it
1641 // desires.
1642 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1643 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
1644 && intentActivity.realActivity.equals(r.realActivity)) {
1645 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
1646 intentActivity.task);
1647 if (intentActivity.frontOfTask) {
1648 intentActivity.task.setIntent(r.intent, r.info);
1649 }
1650 intentActivity.deliverNewIntentLocked(callingUid, r.intent);
1651 } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
1652 // In this case we are launching the root activity
1653 // of the task, but with a different intent. We
1654 // should start a new instance on top.
1655 addingToTask = true;
1656 sourceRecord = intentActivity;
1657 }
1658 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1659 // In this case an activity is being launched in to an
1660 // existing task, without resetting that task. This
1661 // is typically the situation of launching an activity
1662 // from a notification or shortcut. We want to place
1663 // the new activity on top of the current task.
1664 addingToTask = true;
1665 sourceRecord = intentActivity;
1666 } else if (!intentActivity.task.rootWasReset) {
1667 // In this case we are launching in to an existing task
1668 // that has not yet been started from its front door.
1669 // The current task has been brought to the front.
1670 // Ideally, we'd probably like to place this new task
1671 // at the bottom of its stack, but that's a little hard
1672 // to do with the current organization of the code so
1673 // for now we'll just drop it.
1674 intentActivity.task.setIntent(r.intent, r.info);
1675 }
1676 if (!addingToTask && reuseTask == null) {
1677 // We didn't do anything... but it was needed (a.k.a., client
1678 // don't use that intent!) And for paranoia, make
1679 // sure we have correctly resumed the top activity.
1680 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001681 targetStack.resumeTopActivityLocked(null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001682 } else {
1683 ActivityOptions.abort(options);
1684 }
1685 return ActivityManager.START_TASK_TO_FRONT;
1686 }
1687 }
1688 }
1689 }
1690
1691 //String uri = r.intent.toURI();
1692 //Intent intent2 = new Intent(uri);
1693 //Slog.i(TAG, "Given intent: " + r.intent);
1694 //Slog.i(TAG, "URI is: " + uri);
1695 //Slog.i(TAG, "To intent: " + intent2);
1696
1697 if (r.packageName != null) {
1698 // If the activity being launched is the same as the one currently
1699 // at the top, then we need to check if it should only be launched
1700 // once.
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001701 ActivityStack topStack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001702 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001703 if (top != null && r.resultTo == null) {
1704 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
1705 if (top.app != null && top.app.thread != null) {
Craig Mautnerd00f4742014-03-12 14:17:26 -07001706 if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
Craig Mautner8849a5e2013-04-02 16:41:03 -07001707 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
1708 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1709 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
1710 top.task);
1711 // For paranoia, make sure we have correctly
1712 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001713 topStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001714 if (doResume) {
Craig Mautner05d29032013-05-03 13:40:13 -07001715 resumeTopActivitiesLocked();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001716 }
1717 ActivityOptions.abort(options);
1718 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1719 // We don't need to start a new activity, and
1720 // the client said not to do anything if that
1721 // is the case, so this is it!
1722 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1723 }
1724 top.deliverNewIntentLocked(callingUid, r.intent);
1725 return ActivityManager.START_DELIVERED_TO_TOP;
1726 }
1727 }
1728 }
1729 }
1730
1731 } else {
1732 if (r.resultTo != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001733 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
1734 r.requestCode, Activity.RESULT_CANCELED, null);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001735 }
1736 ActivityOptions.abort(options);
1737 return ActivityManager.START_CLASS_NOT_FOUND;
1738 }
1739
1740 boolean newTask = false;
1741 boolean keepCurTransition = false;
1742
1743 // Should this be considered a new task?
1744 if (r.resultTo == null && !addingToTask
1745 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
Craig Mautneraea74a52014-03-08 14:23:10 -08001746 if (isLockTaskModeViolation(reuseTask)) {
1747 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
1748 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
1749 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001750 targetStack = adjustStackFocus(r);
Craig Mautnere0a38842013-12-16 16:14:02 -08001751 targetStack.moveToFront();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001752 if (reuseTask == null) {
Craig Mautner88629292013-11-10 20:39:05 -08001753 r.setTask(targetStack.createTaskRecord(getNextTaskId(),
1754 newTaskInfo != null ? newTaskInfo : r.info,
1755 newTaskIntent != null ? newTaskIntent : intent,
1756 true), null, true);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001757 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
1758 r.task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001759 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001760 r.setTask(reuseTask, reuseTask, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001761 }
1762 newTask = true;
1763 if (!movedHome) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001764 if ((launchFlags &
1765 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
1766 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
1767 // Caller wants to appear on home activity, so before starting
1768 // their own activity we will bring home to the front.
Craig Mautnere0a38842013-12-16 16:14:02 -08001769 r.task.mOnTopOfHome = r.task.stack.isOnHomeDisplay();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001770 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001771 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001772 } else if (sourceRecord != null) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001773 TaskRecord sourceTask = sourceRecord.task;
Craig Mautneraea74a52014-03-08 14:23:10 -08001774 if (isLockTaskModeViolation(sourceTask)) {
1775 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
1776 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
1777 }
Craig Mautner525f3d92013-05-07 14:01:50 -07001778 targetStack = sourceTask.stack;
Craig Mautner95e9daa2014-03-17 15:57:20 -07001779 mWindowManager.moveTaskToTop(sourceTask.taskId);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001780 if (!addingToTask &&
1781 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
1782 // In this case, we are adding the activity to an existing
1783 // task, but the caller has asked to clear that task if the
1784 // activity is already running.
Craig Mautner525f3d92013-05-07 14:01:50 -07001785 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001786 keepCurTransition = true;
1787 if (top != null) {
1788 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
1789 top.deliverNewIntentLocked(callingUid, r.intent);
1790 // For paranoia, make sure we have correctly
1791 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001792 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001793 if (doResume) {
1794 targetStack.resumeTopActivityLocked(null);
1795 }
1796 ActivityOptions.abort(options);
1797 return ActivityManager.START_DELIVERED_TO_TOP;
1798 }
1799 } else if (!addingToTask &&
1800 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1801 // In this case, we are launching an activity in our own task
1802 // that may already be running somewhere in the history, and
1803 // we want to shuffle it to the front of the stack if so.
Craig Mautner525f3d92013-05-07 14:01:50 -07001804 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001805 if (top != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001806 final TaskRecord task = top.task;
1807 task.moveActivityToFrontLocked(top);
1808 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001809 top.updateOptionsLocked(options);
1810 top.deliverNewIntentLocked(callingUid, r.intent);
Craig Mautner0f922742013-08-06 08:44:42 -07001811 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001812 if (doResume) {
1813 targetStack.resumeTopActivityLocked(null);
1814 }
1815 return ActivityManager.START_DELIVERED_TO_TOP;
1816 }
1817 }
1818 // An existing activity is starting this new activity, so we want
1819 // to keep the new one in the same task as the one that is starting
1820 // it.
Craig Mautner525f3d92013-05-07 14:01:50 -07001821 r.setTask(sourceTask, sourceRecord.thumbHolder, false);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001822 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001823 + " in existing task " + r.task + " from source " + sourceRecord);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001824
1825 } else {
1826 // This not being started from an existing activity, and not part
1827 // of a new task... just put it in the top task, though these days
1828 // this case should never happen.
Craig Mautnerac6f8432013-07-17 13:24:59 -07001829 targetStack = adjustStackFocus(r);
Craig Mautner1602ec22013-05-12 10:24:27 -07001830 ActivityRecord prev = targetStack.topActivity();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001831 r.setTask(prev != null ? prev.task
1832 : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1833 null, true);
Craig Mautner95e9daa2014-03-17 15:57:20 -07001834 mWindowManager.moveTaskToTop(r.task.taskId);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001835 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1836 + " in new guessed " + r.task);
1837 }
1838
1839 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
1840 intent, r.getUriPermissionsLocked());
1841
1842 if (newTask) {
1843 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
1844 }
1845 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
Craig Mautner0f922742013-08-06 08:44:42 -07001846 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001847 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
Craig Mautner1d001b62013-06-18 16:52:43 -07001848 mService.setFocusedActivityLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001849 return ActivityManager.START_SUCCESS;
1850 }
1851
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001852 void acquireLaunchWakelock() {
1853 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
1854 throw new IllegalStateException("Calling must be system uid");
1855 }
1856 mLaunchingActivity.acquire();
1857 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
1858 // To be safe, don't allow the wake lock to be held for too long.
1859 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
1860 }
1861 }
1862
Craig Mautnerf3333272013-04-22 10:55:53 -07001863 // Checked.
1864 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
1865 Configuration config) {
1866 if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
1867
Craig Mautnerf3333272013-04-22 10:55:53 -07001868 ArrayList<ActivityRecord> stops = null;
1869 ArrayList<ActivityRecord> finishes = null;
1870 ArrayList<UserStartedState> startingUsers = null;
1871 int NS = 0;
1872 int NF = 0;
1873 IApplicationThread sendThumbnail = null;
1874 boolean booting = false;
1875 boolean enableScreen = false;
1876 boolean activityRemoved = false;
1877
1878 ActivityRecord r = ActivityRecord.forToken(token);
1879 if (r != null) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07001880 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
1881 Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07001882 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
1883 r.finishLaunchTickingLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001884 if (fromTimeout) {
1885 reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
Craig Mautnerf3333272013-04-22 10:55:53 -07001886 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001887
1888 // This is a hack to semi-deal with a race condition
1889 // in the client where it can be constructed with a
1890 // newer configuration from when we asked it to launch.
1891 // We'll update with whatever configuration it now says
1892 // it used to launch.
1893 if (config != null) {
1894 r.configuration = config;
1895 }
1896
1897 // We are now idle. If someone is waiting for a thumbnail from
1898 // us, we can now deliver.
1899 r.idle = true;
1900
1901 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
1902 sendThumbnail = r.app.thread;
1903 r.thumbnailNeeded = false;
1904 }
1905
1906 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
1907 if (!mService.mBooted && isFrontStack(r.task.stack)) {
1908 mService.mBooted = true;
1909 enableScreen = true;
1910 }
1911 }
1912
1913 if (allResumedActivitiesIdle()) {
1914 if (r != null) {
1915 mService.scheduleAppGcsLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001916 }
1917
1918 if (mLaunchingActivity.isHeld()) {
1919 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
1920 if (VALIDATE_WAKE_LOCK_CALLER &&
1921 Binder.getCallingUid() != Process.myUid()) {
1922 throw new IllegalStateException("Calling must be system uid");
1923 }
1924 mLaunchingActivity.release();
1925 }
1926 ensureActivitiesVisibleLocked(null, 0);
Craig Mautnerf3333272013-04-22 10:55:53 -07001927 }
1928
1929 // Atomically retrieve all of the other things to do.
1930 stops = processStoppingActivitiesLocked(true);
1931 NS = stops != null ? stops.size() : 0;
1932 if ((NF=mFinishingActivities.size()) > 0) {
1933 finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
1934 mFinishingActivities.clear();
1935 }
1936
1937 final ArrayList<ActivityRecord> thumbnails;
1938 final int NT = mCancelledThumbnails.size();
1939 if (NT > 0) {
1940 thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
1941 mCancelledThumbnails.clear();
1942 } else {
1943 thumbnails = null;
1944 }
1945
1946 if (isFrontStack(mHomeStack)) {
1947 booting = mService.mBooting;
1948 mService.mBooting = false;
1949 }
1950
1951 if (mStartingUsers.size() > 0) {
1952 startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
1953 mStartingUsers.clear();
1954 }
1955
1956 // Perform the following actions from unsynchronized state.
1957 final IApplicationThread thumbnailThread = sendThumbnail;
1958 mHandler.post(new Runnable() {
1959 @Override
1960 public void run() {
1961 if (thumbnailThread != null) {
1962 try {
1963 thumbnailThread.requestThumbnail(token);
1964 } catch (Exception e) {
1965 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
1966 mService.sendPendingThumbnail(null, token, null, null, true);
1967 }
1968 }
1969
1970 // Report back to any thumbnail receivers.
1971 for (int i = 0; i < NT; i++) {
1972 ActivityRecord r = thumbnails.get(i);
1973 mService.sendPendingThumbnail(r, null, null, null, true);
1974 }
1975 }
1976 });
1977
1978 // Stop any activities that are scheduled to do so but have been
1979 // waiting for the next one to start.
1980 for (int i = 0; i < NS; i++) {
1981 r = stops.get(i);
1982 final ActivityStack stack = r.task.stack;
1983 if (r.finishing) {
1984 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
1985 } else {
1986 stack.stopActivityLocked(r);
1987 }
1988 }
1989
1990 // Finish any activities that are scheduled to do so but have been
1991 // waiting for the next one to start.
1992 for (int i = 0; i < NF; i++) {
1993 r = finishes.get(i);
1994 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
1995 }
1996
1997 if (booting) {
1998 mService.finishBooting();
1999 } else if (startingUsers != null) {
2000 for (int i = 0; i < startingUsers.size(); i++) {
2001 mService.finishUserSwitch(startingUsers.get(i));
2002 }
2003 }
2004
2005 mService.trimApplications();
2006 //dump();
2007 //mWindowManager.dump();
2008
2009 if (enableScreen) {
2010 mService.enableScreenAfterBoot();
2011 }
2012
2013 if (activityRemoved) {
Craig Mautner05d29032013-05-03 13:40:13 -07002014 resumeTopActivitiesLocked();
Craig Mautnerf3333272013-04-22 10:55:53 -07002015 }
2016
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002017 return r;
Craig Mautnerf3333272013-04-22 10:55:53 -07002018 }
2019
Craig Mautner8e569572013-10-11 17:36:59 -07002020 boolean handleAppDiedLocked(ProcessRecord app) {
Craig Mautner19091252013-10-05 00:03:53 -07002021 boolean hasVisibleActivities = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002022 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2023 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002024 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2025 hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app);
2026 }
Craig Mautner6b74cb52013-09-27 17:02:21 -07002027 }
Craig Mautner19091252013-10-05 00:03:53 -07002028 return hasVisibleActivities;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002029 }
2030
2031 void closeSystemDialogsLocked() {
Craig Mautnere0a38842013-12-16 16:14:02 -08002032 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2033 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002034 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2035 stacks.get(stackNdx).closeSystemDialogsLocked();
2036 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002037 }
2038 }
2039
Craig Mautner93529a42013-10-04 15:03:13 -07002040 void removeUserLocked(int userId) {
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002041 mUserStackInFront.delete(userId);
Craig Mautner93529a42013-10-04 15:03:13 -07002042 }
2043
Craig Mautner8d341ef2013-03-26 09:03:27 -07002044 /**
2045 * @return true if some activity was finished (or would have finished if doit were true).
2046 */
2047 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
2048 boolean didSomething = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002049 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2050 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002051 final int numStacks = stacks.size();
2052 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2053 final ActivityStack stack = stacks.get(stackNdx);
2054 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
2055 didSomething = true;
2056 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002057 }
2058 }
2059 return didSomething;
2060 }
2061
Dianne Hackborna413dc02013-07-12 12:02:55 -07002062 void updatePreviousProcessLocked(ActivityRecord r) {
2063 // Now that this process has stopped, we may want to consider
2064 // it to be the previous app to try to keep around in case
2065 // the user wants to return to it.
2066
2067 // First, found out what is currently the foreground app, so that
2068 // we don't blow away the previous app if this activity is being
2069 // hosted by the process that is actually still the foreground.
2070 ProcessRecord fgApp = null;
Craig Mautnere0a38842013-12-16 16:14:02 -08002071 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2072 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002073 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2074 final ActivityStack stack = stacks.get(stackNdx);
2075 if (isFrontStack(stack)) {
2076 if (stack.mResumedActivity != null) {
2077 fgApp = stack.mResumedActivity.app;
2078 } else if (stack.mPausingActivity != null) {
2079 fgApp = stack.mPausingActivity.app;
2080 }
2081 break;
Dianne Hackborna413dc02013-07-12 12:02:55 -07002082 }
Dianne Hackborna413dc02013-07-12 12:02:55 -07002083 }
2084 }
2085
2086 // Now set this one as the previous process, only if that really
2087 // makes sense to.
2088 if (r.app != null && fgApp != null && r.app != fgApp
2089 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
Craig Mautner4ef26932013-09-18 15:15:52 -07002090 && r.app != mService.mHomeProcess) {
Dianne Hackborna413dc02013-07-12 12:02:55 -07002091 mService.mPreviousProcess = r.app;
2092 mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
2093 }
2094 }
2095
Craig Mautner05d29032013-05-03 13:40:13 -07002096 boolean resumeTopActivitiesLocked() {
2097 return resumeTopActivitiesLocked(null, null, null);
2098 }
2099
2100 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
2101 Bundle targetOptions) {
2102 if (targetStack == null) {
2103 targetStack = getFocusedStack();
2104 }
Craig Mautner12ff7392014-02-21 21:08:00 -08002105 // Do targetStack first.
Craig Mautner05d29032013-05-03 13:40:13 -07002106 boolean result = false;
Craig Mautner12ff7392014-02-21 21:08:00 -08002107 if (isFrontStack(targetStack)) {
2108 result = targetStack.resumeTopActivityLocked(target, targetOptions);
2109 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002110 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2111 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002112 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2113 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautner12ff7392014-02-21 21:08:00 -08002114 if (stack == targetStack) {
2115 // Already started above.
2116 continue;
2117 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002118 if (isFrontStack(stack)) {
Craig Mautner12ff7392014-02-21 21:08:00 -08002119 stack.resumeTopActivityLocked(null);
Craig Mautner05d29032013-05-03 13:40:13 -07002120 }
Craig Mautnerf88c50f2013-04-18 19:25:12 -07002121 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002122 }
Craig Mautner05d29032013-05-03 13:40:13 -07002123 return result;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002124 }
2125
2126 void finishTopRunningActivityLocked(ProcessRecord app) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002127 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2128 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002129 final int numStacks = stacks.size();
2130 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2131 final ActivityStack stack = stacks.get(stackNdx);
2132 stack.finishTopRunningActivityLocked(app);
2133 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002134 }
2135 }
2136
Craig Mautneraea74a52014-03-08 14:23:10 -08002137 void findTaskToMoveToFrontLocked(TaskRecord task, int flags, Bundle options) {
2138 if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
2139 mUserLeaving = true;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002140 }
Craig Mautneraea74a52014-03-08 14:23:10 -08002141 if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
2142 // Caller wants the home activity moved with it. To accomplish this,
2143 // we'll just indicate that this task returns to the home task.
2144 task.mOnTopOfHome = true;
2145 }
2146 task.stack.moveTaskToFrontLocked(task, null, options);
2147 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack="
2148 + task.stack);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002149 }
2150
Craig Mautner967212c2013-04-13 21:10:58 -07002151 ActivityStack getStack(int stackId) {
Craig Mautner4504de52013-12-20 09:06:56 -08002152 WeakReference<ActivityContainer> weakReference = mActivityContainers.get(stackId);
2153 if (weakReference != null) {
2154 ActivityContainer activityContainer = weakReference.get();
2155 if (activityContainer != null) {
2156 return activityContainer.mStack;
2157 } else {
2158 mActivityContainers.remove(stackId);
2159 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002160 }
2161 return null;
2162 }
2163
Craig Mautner967212c2013-04-13 21:10:58 -07002164 ArrayList<ActivityStack> getStacks() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002165 ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>();
Craig Mautnere0a38842013-12-16 16:14:02 -08002166 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2167 allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002168 }
2169 return allStacks;
Craig Mautner967212c2013-04-13 21:10:58 -07002170 }
2171
Craig Mautner4a1cb222013-12-04 16:14:06 -08002172 IBinder getHomeActivityToken() {
2173 final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
2174 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
2175 final TaskRecord task = tasks.get(taskNdx);
2176 if (task.isHomeTask()) {
2177 final ArrayList<ActivityRecord> activities = task.mActivities;
2178 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2179 final ActivityRecord r = activities.get(activityNdx);
2180 if (r.isHomeActivity()) {
2181 return r.appToken;
2182 }
2183 }
2184 }
2185 }
2186 return null;
2187 }
2188
2189 ActivityContainer createActivityContainer(ActivityRecord parentActivity, int stackId,
2190 IActivityContainerCallback callback) {
2191 ActivityContainer activityContainer = new ActivityContainer(parentActivity, stackId,
2192 callback);
Craig Mautner4504de52013-12-20 09:06:56 -08002193 mActivityContainers.put(stackId, new WeakReference<ActivityContainer>(activityContainer));
Craig Mautner4a1cb222013-12-04 16:14:06 -08002194 if (parentActivity != null) {
2195 parentActivity.mChildContainers.add(activityContainer.mStack);
2196 }
2197 return activityContainer;
2198 }
2199
2200 ActivityContainer createActivityContainer(ActivityRecord parentActivity,
2201 IActivityContainerCallback callback) {
2202 return createActivityContainer(parentActivity, getNextStackId(), callback);
2203 }
2204
Craig Mautner34b73df2014-01-12 21:11:08 -08002205 void removeChildActivityContainers(ActivityRecord parentActivity) {
2206 for (int ndx = mActivityContainers.size() - 1; ndx >= 0; --ndx) {
2207 final ActivityContainer container = mActivityContainers.valueAt(ndx).get();
2208 if (container == null) {
2209 mActivityContainers.removeAt(ndx);
2210 continue;
2211 }
2212 if (container.mParentActivity != parentActivity) {
2213 continue;
2214 }
2215
2216 ActivityStack stack = container.mStack;
2217 ActivityRecord top = stack.topRunningNonDelayedActivityLocked(null);
2218 if (top != null) {
2219 // TODO: Make sure the next activity doesn't start up when top is destroyed.
Craig Mautner95da1082014-02-24 17:54:35 -08002220 stack.destroyActivityLocked(top, true, true, "stack parent destroyed");
Craig Mautner34b73df2014-01-12 21:11:08 -08002221 }
2222 mActivityContainers.removeAt(ndx);
2223 container.detachLocked();
2224 }
2225 }
2226
Craig Mautner95da1082014-02-24 17:54:35 -08002227 void deleteActivityContainer(IActivityContainer container) {
2228 ActivityContainer activityContainer = (ActivityContainer)container;
2229 if (activityContainer != null) {
2230 activityContainer.mStack.destroyActivitiesLocked(null, true,
2231 "deleteActivityContainer");
2232 final ActivityRecord parent = activityContainer.mParentActivity;
2233 if (parent != null) {
2234 parent.mChildContainers.remove(activityContainer);
2235 }
2236 final int stackId = activityContainer.mStackId;
2237 mActivityContainers.remove(stackId);
2238 mWindowManager.removeStack(stackId);
2239 }
2240 }
2241
Craig Mautner4a1cb222013-12-04 16:14:06 -08002242 private int createStackOnDisplay(ActivityRecord parentActivity, int stackId, int displayId) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002243 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2244 if (activityDisplay == null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002245 return -1;
2246 }
2247
2248 ActivityContainer activityContainer =
2249 createActivityContainer(parentActivity, stackId, null);
Craig Mautnere0a38842013-12-16 16:14:02 -08002250 activityContainer.attachToDisplayLocked(activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002251 return stackId;
2252 }
2253
2254 int getNextStackId() {
Craig Mautner858d8a62013-04-23 17:08:34 -07002255 while (true) {
2256 if (++mLastStackId <= HOME_STACK_ID) {
2257 mLastStackId = HOME_STACK_ID + 1;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002258 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002259 if (getStack(mLastStackId) == null) {
2260 break;
2261 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002262 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002263 return mLastStackId;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002264 }
2265
2266 void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002267 final TaskRecord task = anyTaskForIdLocked(taskId);
2268 if (task == null) {
2269 return;
2270 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002271 final ActivityStack stack = getStack(stackId);
2272 if (stack == null) {
2273 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
2274 return;
2275 }
Craig Mautner04a0ea62014-01-13 12:51:26 -08002276 task.stack.removeTask(task);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002277 stack.addTask(task, toTop);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002278 mWindowManager.addTask(taskId, stackId, toTop);
Craig Mautner05d29032013-05-03 13:40:13 -07002279 resumeTopActivitiesLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002280 }
2281
Craig Mautnerac6f8432013-07-17 13:24:59 -07002282 ActivityRecord findTaskLocked(ActivityRecord r) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07002283 if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r);
Craig Mautnere0a38842013-12-16 16:14:02 -08002284 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2285 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002286 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2287 final ActivityStack stack = stacks.get(stackNdx);
2288 if (!r.isApplicationActivity() && !stack.isHomeStack()) {
2289 if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: " + stack);
2290 continue;
2291 }
2292 final ActivityRecord ar = stack.findTaskLocked(r);
2293 if (ar != null) {
2294 return ar;
2295 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07002296 }
2297 }
Dianne Hackborn2a272d42013-10-16 13:34:33 -07002298 if (DEBUG_TASKS) Slog.d(TAG, "No task found");
Craig Mautner8849a5e2013-04-02 16:41:03 -07002299 return null;
2300 }
2301
2302 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002303 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2304 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002305 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2306 final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info);
2307 if (ar != null) {
2308 return ar;
2309 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07002310 }
2311 }
2312 return null;
2313 }
2314
Craig Mautner8d341ef2013-03-26 09:03:27 -07002315 void goingToSleepLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002316 scheduleSleepTimeout();
2317 if (!mGoingToSleep.isHeld()) {
2318 mGoingToSleep.acquire();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002319 if (mLaunchingActivity.isHeld()) {
2320 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2321 throw new IllegalStateException("Calling must be system uid");
Craig Mautner0eea92c2013-05-16 13:35:39 -07002322 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002323 mLaunchingActivity.release();
2324 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
Craig Mautner0eea92c2013-05-16 13:35:39 -07002325 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002326 }
Amith Yamasanice15e152013-09-19 12:30:32 -07002327 checkReadyForSleepLocked();
Craig Mautneraea74a52014-03-08 14:23:10 -08002328 setLockTaskModeLocked(null);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002329 }
2330
2331 boolean shutdownLocked(int timeout) {
2332 boolean timedout = false;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002333 goingToSleepLocked();
Craig Mautner0eea92c2013-05-16 13:35:39 -07002334
2335 final long endTime = System.currentTimeMillis() + timeout;
2336 while (true) {
2337 boolean cantShutdown = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002338 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2339 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002340 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2341 cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
2342 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002343 }
2344 if (cantShutdown) {
2345 long timeRemaining = endTime - System.currentTimeMillis();
2346 if (timeRemaining > 0) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002347 try {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002348 mService.wait(timeRemaining);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002349 } catch (InterruptedException e) {
2350 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002351 } else {
2352 Slog.w(TAG, "Activity manager shutdown timed out");
2353 timedout = true;
2354 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002355 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002356 } else {
2357 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002358 }
2359 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002360
2361 // Force checkReadyForSleep to complete.
2362 mSleepTimeout = true;
2363 checkReadyForSleepLocked();
2364
Craig Mautner8d341ef2013-03-26 09:03:27 -07002365 return timedout;
2366 }
2367
2368 void comeOutOfSleepIfNeededLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002369 removeSleepTimeouts();
2370 if (mGoingToSleep.isHeld()) {
2371 mGoingToSleep.release();
2372 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002373 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2374 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002375 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2376 final ActivityStack stack = stacks.get(stackNdx);
2377 stack.awakeFromSleepingLocked();
2378 if (isFrontStack(stack)) {
2379 resumeTopActivitiesLocked();
2380 }
Craig Mautner5314a402013-09-26 12:40:16 -07002381 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002382 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002383 mGoingToSleepActivities.clear();
2384 }
2385
2386 void activitySleptLocked(ActivityRecord r) {
2387 mGoingToSleepActivities.remove(r);
2388 checkReadyForSleepLocked();
2389 }
2390
2391 void checkReadyForSleepLocked() {
2392 if (!mService.isSleepingOrShuttingDown()) {
2393 // Do not care.
2394 return;
2395 }
2396
2397 if (!mSleepTimeout) {
2398 boolean dontSleep = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002399 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2400 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002401 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2402 dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
2403 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002404 }
2405
2406 if (mStoppingActivities.size() > 0) {
2407 // Still need to tell some activities to stop; can't sleep yet.
2408 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2409 + mStoppingActivities.size() + " activities");
2410 scheduleIdleLocked();
2411 dontSleep = true;
2412 }
2413
2414 if (mGoingToSleepActivities.size() > 0) {
2415 // Still need to tell some activities to sleep; can't sleep yet.
2416 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2417 + mGoingToSleepActivities.size() + " activities");
2418 dontSleep = true;
2419 }
2420
2421 if (dontSleep) {
2422 return;
2423 }
2424 }
2425
Craig Mautnere0a38842013-12-16 16:14:02 -08002426 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2427 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002428 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2429 stacks.get(stackNdx).goToSleep();
2430 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002431 }
2432
2433 removeSleepTimeouts();
2434
2435 if (mGoingToSleep.isHeld()) {
2436 mGoingToSleep.release();
2437 }
2438 if (mService.mShuttingDown) {
2439 mService.notifyAll();
2440 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002441 }
2442
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002443 boolean reportResumedActivityLocked(ActivityRecord r) {
2444 final ActivityStack stack = r.task.stack;
2445 if (isFrontStack(stack)) {
Jeff Sharkey5782da72013-04-25 14:32:30 -07002446 mService.updateUsageStats(r, true);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002447 }
2448 if (allResumedActivitiesComplete()) {
2449 ensureActivitiesVisibleLocked(null, 0);
2450 mWindowManager.executeAppTransition();
2451 return true;
2452 }
2453 return false;
2454 }
2455
Craig Mautner8d341ef2013-03-26 09:03:27 -07002456 void handleAppCrashLocked(ProcessRecord app) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002457 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2458 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002459 final int numStacks = stacks.size();
2460 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2461 final ActivityStack stack = stacks.get(stackNdx);
2462 stack.handleAppCrashLocked(app);
2463 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002464 }
2465 }
2466
Craig Mautnerde4ef022013-04-07 19:01:33 -07002467 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
Craig Mautner580ea812013-04-25 12:58:38 -07002468 // First the front stacks. In case any are not fullscreen and are in front of home.
2469 boolean showHomeBehindStack = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002470 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2471 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002472 final int topStackNdx = stacks.size() - 1;
2473 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
2474 final ActivityStack stack = stacks.get(stackNdx);
2475 if (stackNdx == topStackNdx) {
2476 // Top stack.
2477 showHomeBehindStack =
2478 stack.ensureActivitiesVisibleLocked(starting, configChanges);
2479 } else {
2480 // Back stack.
2481 stack.ensureActivitiesVisibleLocked(starting, configChanges,
2482 showHomeBehindStack);
2483 }
Craig Mautner580ea812013-04-25 12:58:38 -07002484 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002485 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002486 }
2487
2488 void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002489 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2490 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002491 final int numStacks = stacks.size();
2492 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2493 final ActivityStack stack = stacks.get(stackNdx);
2494 stack.scheduleDestroyActivities(app, false, reason);
2495 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002496 }
2497 }
2498
2499 boolean switchUserLocked(int userId, UserStartedState uss) {
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002500 mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId());
2501 final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
Craig Mautner2420ead2013-04-01 17:13:20 -07002502 mCurrentUser = userId;
Craig Mautnerac6f8432013-07-17 13:24:59 -07002503
Craig Mautner858d8a62013-04-23 17:08:34 -07002504 mStartingUsers.add(uss);
Craig Mautnere0a38842013-12-16 16:14:02 -08002505 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2506 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002507 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002508 final ActivityStack stack = stacks.get(stackNdx);
2509 stack.switchUserLocked(userId);
Alexandra Gherghinadae57a12014-03-12 19:15:26 +00002510 TaskRecord task = stack.topTask();
2511 if (task != null) {
2512 mWindowManager.moveTaskToTop(task.taskId);
2513 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002514 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07002515 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002516
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002517 ActivityStack stack = getStack(restoreStackId);
2518 if (stack == null) {
2519 stack = mHomeStack;
2520 }
2521 final boolean homeInFront = stack.isHomeStack();
Craig Mautnere0a38842013-12-16 16:14:02 -08002522 if (stack.isOnHomeDisplay()) {
2523 moveHomeStack(homeInFront);
Alexandra Gherghinadae57a12014-03-12 19:15:26 +00002524 TaskRecord task = stack.topTask();
2525 if (task != null) {
2526 mWindowManager.moveTaskToTop(task.taskId);
2527 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002528 } else {
2529 // Stack was moved to another display while user was swapped out.
2530 resumeHomeActivity(null);
2531 }
Craig Mautner93529a42013-10-04 15:03:13 -07002532 return homeInFront;
Craig Mautner2219a1b2013-03-25 09:44:30 -07002533 }
2534
Craig Mautnerde4ef022013-04-07 19:01:33 -07002535 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2536 int N = mStoppingActivities.size();
2537 if (N <= 0) return null;
2538
2539 ArrayList<ActivityRecord> stops = null;
2540
2541 final boolean nowVisible = allResumedActivitiesVisible();
2542 for (int i=0; i<N; i++) {
2543 ActivityRecord s = mStoppingActivities.get(i);
Craig Mautnera7f2bd42013-10-15 16:13:50 -07002544 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
Craig Mautnerde4ef022013-04-07 19:01:33 -07002545 + nowVisible + " waitingVisible=" + s.waitingVisible
2546 + " finishing=" + s.finishing);
2547 if (s.waitingVisible && nowVisible) {
2548 mWaitingVisibleActivities.remove(s);
2549 s.waitingVisible = false;
2550 if (s.finishing) {
2551 // If this activity is finishing, it is sitting on top of
2552 // everyone else but we now know it is no longer needed...
2553 // so get rid of it. Otherwise, we need to go through the
2554 // normal flow and hide it once we determine that it is
2555 // hidden by the activities in front of it.
2556 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002557 mWindowManager.setAppVisibility(s.appToken, false);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002558 }
2559 }
2560 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2561 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2562 if (stops == null) {
2563 stops = new ArrayList<ActivityRecord>();
2564 }
2565 stops.add(s);
2566 mStoppingActivities.remove(i);
2567 N--;
2568 i--;
2569 }
2570 }
2571
2572 return stops;
2573 }
2574
Craig Mautnercf910b02013-04-23 11:23:27 -07002575 void validateTopActivitiesLocked() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002576 // FIXME
2577/* for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2578 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautnercf910b02013-04-23 11:23:27 -07002579 final ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002580 final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
Craig Mautnercf910b02013-04-23 11:23:27 -07002581 if (isFrontStack(stack)) {
2582 if (r == null) {
2583 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2584 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002585 final ActivityRecord pausing = stack.mPausingActivity;
2586 if (pausing != null && pausing == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002587 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002588 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002589 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002590 if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002591 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002592 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002593 }
2594 }
2595 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002596 final ActivityRecord resumed = stack.mResumedActivity;
2597 if (resumed != null && resumed == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002598 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002599 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002600 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002601 if (r != null && (state == ActivityState.INITIALIZING
2602 || state == ActivityState.RESUMED)) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002603 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002604 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002605 }
2606 }
2607 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002608*/
Craig Mautner76ea2242013-05-15 11:40:05 -07002609 }
2610
Craig Mautner27084302013-03-25 08:05:25 -07002611 public void dump(PrintWriter pw, String prefix) {
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002612 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity=");
Craig Mautner27084302013-03-25 08:05:25 -07002613 pw.println(mDismissKeyguardOnNextActivity);
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002614 pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002615 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002616 pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
2617 pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
2618 pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
Craig Mautner95da1082014-02-24 17:54:35 -08002619 pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
Craig Mautner27084302013-03-25 08:05:25 -07002620 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002621
Craig Mautner20e72272013-04-01 13:45:53 -07002622 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002623 return getFocusedStack().getDumpActivitiesLocked(name);
Craig Mautner20e72272013-04-01 13:45:53 -07002624 }
2625
Dianne Hackborn390517b2013-05-30 15:03:32 -07002626 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2627 boolean needSep, String prefix) {
2628 if (activity != null) {
2629 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2630 if (needSep) {
2631 pw.println();
Dianne Hackborn390517b2013-05-30 15:03:32 -07002632 }
2633 pw.print(prefix);
2634 pw.println(activity);
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002635 return true;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002636 }
2637 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002638 return false;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002639 }
2640
Craig Mautner8d341ef2013-03-26 09:03:27 -07002641 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2642 boolean dumpClient, String dumpPackage) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002643 boolean printed = false;
2644 boolean needSep = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002645 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2646 ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
2647 pw.print("Display #"); pw.println(activityDisplay.mDisplayId);
2648 ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002649 final int numStacks = stacks.size();
2650 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2651 final ActivityStack stack = stacks.get(stackNdx);
2652 StringBuilder stackHeader = new StringBuilder(128);
2653 stackHeader.append(" Stack #");
2654 stackHeader.append(stack.mStackId);
2655 stackHeader.append(":");
2656 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
2657 needSep, stackHeader.toString());
2658 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false,
2659 !dumpAll, false, dumpPackage, true,
2660 " Running activities (most recent first):", null);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002661
Craig Mautner4a1cb222013-12-04 16:14:06 -08002662 needSep = printed;
2663 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
2664 " mPausingActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002665 if (pr) {
2666 printed = true;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002667 needSep = false;
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002668 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002669 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
2670 " mResumedActivity: ");
2671 if (pr) {
2672 printed = true;
2673 needSep = false;
2674 }
2675 if (dumpAll) {
2676 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
2677 " mLastPausedActivity: ");
2678 if (pr) {
2679 printed = true;
2680 needSep = true;
2681 }
2682 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
2683 needSep, " mLastNoHistoryActivity: ");
2684 }
2685 needSep = printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002686 }
2687 }
2688
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002689 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll,
2690 false, dumpPackage, true, " Activities waiting to finish:", null);
2691 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll,
2692 false, dumpPackage, true, " Activities waiting to stop:", null);
2693 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll,
2694 false, dumpPackage, true, " Activities waiting for another to become visible:",
2695 null);
2696 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2697 false, dumpPackage, true, " Activities waiting to sleep:", null);
2698 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2699 false, dumpPackage, true, " Activities waiting to sleep:", null);
Craig Mautnerf3333272013-04-22 10:55:53 -07002700
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002701 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002702 }
2703
Dianne Hackborn390517b2013-05-30 15:03:32 -07002704 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
Craig Mautner8d341ef2013-03-26 09:03:27 -07002705 String prefix, String label, boolean complete, boolean brief, boolean client,
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002706 String dumpPackage, boolean needNL, String header1, String header2) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002707 TaskRecord lastTask = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002708 String innerPrefix = null;
2709 String[] args = null;
2710 boolean printed = false;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002711 for (int i=list.size()-1; i>=0; i--) {
2712 final ActivityRecord r = list.get(i);
2713 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2714 continue;
2715 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002716 if (innerPrefix == null) {
2717 innerPrefix = prefix + " ";
2718 args = new String[0];
2719 }
2720 printed = true;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002721 final boolean full = !brief && (complete || !r.isInHistory());
2722 if (needNL) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07002723 pw.println("");
Craig Mautner8d341ef2013-03-26 09:03:27 -07002724 needNL = false;
2725 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002726 if (header1 != null) {
2727 pw.println(header1);
2728 header1 = null;
2729 }
2730 if (header2 != null) {
2731 pw.println(header2);
2732 header2 = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002733 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002734 if (lastTask != r.task) {
2735 lastTask = r.task;
2736 pw.print(prefix);
2737 pw.print(full ? "* " : " ");
2738 pw.println(lastTask);
2739 if (full) {
2740 lastTask.dump(pw, prefix + " ");
2741 } else if (complete) {
2742 // Complete + brief == give a summary. Isn't that obvious?!?
2743 if (lastTask.intent != null) {
2744 pw.print(prefix); pw.print(" ");
2745 pw.println(lastTask.intent.toInsecureStringWithClip());
2746 }
2747 }
2748 }
2749 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
2750 pw.print(" #"); pw.print(i); pw.print(": ");
2751 pw.println(r);
2752 if (full) {
2753 r.dump(pw, innerPrefix);
2754 } else if (complete) {
2755 // Complete + brief == give a summary. Isn't that obvious?!?
2756 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2757 if (r.app != null) {
2758 pw.print(innerPrefix); pw.println(r.app);
2759 }
2760 }
2761 if (client && r.app != null && r.app.thread != null) {
2762 // flush anything that is already in the PrintWriter since the thread is going
2763 // to write to the file descriptor directly
2764 pw.flush();
2765 try {
2766 TransferPipe tp = new TransferPipe();
2767 try {
2768 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2769 r.appToken, innerPrefix, args);
2770 // Short timeout, since blocking here can
2771 // deadlock with the application.
2772 tp.go(fd, 2000);
2773 } finally {
2774 tp.kill();
2775 }
2776 } catch (IOException e) {
2777 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2778 } catch (RemoteException e) {
2779 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2780 }
2781 needNL = true;
2782 }
2783 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002784 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002785 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002786
Craig Mautnerf3333272013-04-22 10:55:53 -07002787 void scheduleIdleTimeoutLocked(ActivityRecord next) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002788 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
Craig Mautnerc64f73e2013-04-24 16:44:56 -07002789 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2790 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
Craig Mautnerf3333272013-04-22 10:55:53 -07002791 }
2792
2793 final void scheduleIdleLocked() {
Craig Mautner05d29032013-05-03 13:40:13 -07002794 mHandler.sendEmptyMessage(IDLE_NOW_MSG);
Craig Mautnerf3333272013-04-22 10:55:53 -07002795 }
2796
2797 void removeTimeoutsForActivityLocked(ActivityRecord r) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002798 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07002799 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2800 }
2801
Craig Mautner05d29032013-05-03 13:40:13 -07002802 final void scheduleResumeTopActivities() {
Craig Mautner34b73df2014-01-12 21:11:08 -08002803 if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
2804 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2805 }
Craig Mautner05d29032013-05-03 13:40:13 -07002806 }
2807
Craig Mautner0eea92c2013-05-16 13:35:39 -07002808 void removeSleepTimeouts() {
2809 mSleepTimeout = false;
2810 mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2811 }
2812
2813 final void scheduleSleepTimeout() {
2814 removeSleepTimeouts();
2815 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2816 }
2817
Craig Mautner4a1cb222013-12-04 16:14:06 -08002818 @Override
2819 public void onDisplayAdded(int displayId) {
2820 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
2821 }
2822
2823 @Override
2824 public void onDisplayRemoved(int displayId) {
2825 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
2826 }
2827
2828 @Override
2829 public void onDisplayChanged(int displayId) {
2830 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
2831 }
2832
2833 public void handleDisplayAddedLocked(int displayId) {
Craig Mautner4504de52013-12-20 09:06:56 -08002834 boolean newDisplay;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002835 synchronized (mService) {
Craig Mautner4504de52013-12-20 09:06:56 -08002836 newDisplay = mActivityDisplays.get(displayId) == null;
2837 if (newDisplay) {
2838 ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
2839 mActivityDisplays.put(displayId, activityDisplay);
2840 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002841 }
Craig Mautner4504de52013-12-20 09:06:56 -08002842 if (newDisplay) {
2843 mWindowManager.onDisplayAdded(displayId);
2844 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002845 }
2846
2847 public void handleDisplayRemovedLocked(int displayId) {
2848 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002849 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2850 if (activityDisplay != null) {
2851 ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002852 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner34b73df2014-01-12 21:11:08 -08002853 stacks.get(stackNdx).mActivityContainer.detachLocked();
Craig Mautner4a1cb222013-12-04 16:14:06 -08002854 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002855 mActivityDisplays.remove(displayId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002856 }
2857 }
2858 mWindowManager.onDisplayRemoved(displayId);
2859 }
2860
2861 public void handleDisplayChangedLocked(int displayId) {
2862 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002863 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2864 if (activityDisplay != null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002865 // TODO: Update the bounds.
2866 }
2867 }
2868 mWindowManager.onDisplayChanged(displayId);
2869 }
2870
2871 StackInfo getStackInfo(ActivityStack stack) {
2872 StackInfo info = new StackInfo();
2873 mWindowManager.getStackBounds(stack.mStackId, info.bounds);
2874 info.displayId = Display.DEFAULT_DISPLAY;
2875 info.stackId = stack.mStackId;
2876
2877 ArrayList<TaskRecord> tasks = stack.getAllTasks();
2878 final int numTasks = tasks.size();
2879 int[] taskIds = new int[numTasks];
2880 String[] taskNames = new String[numTasks];
2881 for (int i = 0; i < numTasks; ++i) {
2882 final TaskRecord task = tasks.get(i);
2883 taskIds[i] = task.taskId;
2884 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
2885 : task.realActivity != null ? task.realActivity.flattenToString()
2886 : task.getTopActivity() != null ? task.getTopActivity().packageName
2887 : "unknown";
2888 }
2889 info.taskIds = taskIds;
2890 info.taskNames = taskNames;
2891 return info;
2892 }
2893
2894 StackInfo getStackInfoLocked(int stackId) {
2895 ActivityStack stack = getStack(stackId);
2896 if (stack != null) {
2897 return getStackInfo(stack);
2898 }
2899 return null;
2900 }
2901
2902 ArrayList<StackInfo> getAllStackInfosLocked() {
2903 ArrayList<StackInfo> list = new ArrayList<StackInfo>();
Craig Mautnere0a38842013-12-16 16:14:02 -08002904 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2905 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002906 for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
2907 list.add(getStackInfo(stacks.get(ndx)));
2908 }
2909 }
2910 return list;
2911 }
2912
Craig Mautneraea74a52014-03-08 14:23:10 -08002913 void setLockTaskModeLocked(TaskRecord task) {
2914 if (task == null) {
2915 // Take out of lock task mode.
2916 mLockTaskModeTask = null;
2917 return;
2918 }
2919 if (isLockTaskModeViolation(task)) {
2920 Slog.e(TAG, "setLockTaskMode: Attempt to start a second Lock Task Mode task.");
2921 return;
2922 }
2923 mLockTaskModeTask = task;
2924 findTaskToMoveToFrontLocked(task, 0, null);
2925 resumeTopActivitiesLocked();
2926 }
2927
2928 boolean isLockTaskModeViolation(TaskRecord task) {
2929 return mLockTaskModeTask != null && mLockTaskModeTask != task;
2930 }
2931
2932 void endLockTaskModeIfTaskEnding(TaskRecord task) {
2933 if (mLockTaskModeTask != null && mLockTaskModeTask == task) {
2934 mLockTaskModeTask = null;
2935 }
2936 }
2937
2938 boolean isInLockTaskMode() {
2939 return mLockTaskModeTask != null;
2940 }
2941
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002942 private final class ActivityStackSupervisorHandler extends Handler {
Craig Mautnerf3333272013-04-22 10:55:53 -07002943
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002944 public ActivityStackSupervisorHandler(Looper looper) {
2945 super(looper);
2946 }
2947
Craig Mautnerf3333272013-04-22 10:55:53 -07002948 void activityIdleInternal(ActivityRecord r) {
2949 synchronized (mService) {
2950 activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
2951 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002952 }
2953
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002954 @Override
2955 public void handleMessage(Message msg) {
2956 switch (msg.what) {
Craig Mautnerf3333272013-04-22 10:55:53 -07002957 case IDLE_TIMEOUT_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002958 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002959 if (mService.mDidDexOpt) {
2960 mService.mDidDexOpt = false;
2961 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2962 nmsg.obj = msg.obj;
2963 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
2964 return;
2965 }
2966 // We don't at this point know if the activity is fullscreen,
2967 // so we need to be conservative and assume it isn't.
2968 activityIdleInternal((ActivityRecord)msg.obj);
2969 } break;
2970 case IDLE_NOW_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002971 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002972 activityIdleInternal((ActivityRecord)msg.obj);
2973 } break;
Craig Mautner05d29032013-05-03 13:40:13 -07002974 case RESUME_TOP_ACTIVITY_MSG: {
2975 synchronized (mService) {
2976 resumeTopActivitiesLocked();
2977 }
2978 } break;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002979 case SLEEP_TIMEOUT_MSG: {
2980 synchronized (mService) {
2981 if (mService.isSleepingOrShuttingDown()) {
2982 Slog.w(TAG, "Sleep timeout! Sleeping now.");
2983 mSleepTimeout = true;
2984 checkReadyForSleepLocked();
2985 }
2986 }
2987 } break;
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002988 case LAUNCH_TIMEOUT_MSG: {
2989 if (mService.mDidDexOpt) {
2990 mService.mDidDexOpt = false;
2991 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
2992 return;
2993 }
2994 synchronized (mService) {
2995 if (mLaunchingActivity.isHeld()) {
2996 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
2997 if (VALIDATE_WAKE_LOCK_CALLER
2998 && Binder.getCallingUid() != Process.myUid()) {
2999 throw new IllegalStateException("Calling must be system uid");
3000 }
3001 mLaunchingActivity.release();
3002 }
3003 }
3004 } break;
Craig Mautner4a1cb222013-12-04 16:14:06 -08003005 case HANDLE_DISPLAY_ADDED: {
3006 handleDisplayAddedLocked(msg.arg1);
3007 } break;
3008 case HANDLE_DISPLAY_CHANGED: {
3009 handleDisplayChangedLocked(msg.arg1);
3010 } break;
3011 case HANDLE_DISPLAY_REMOVED: {
3012 handleDisplayRemovedLocked(msg.arg1);
3013 } break;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07003014 }
3015 }
3016 }
Craig Mautnered6649f2013-12-02 14:08:25 -08003017
Craig Mautner4a1cb222013-12-04 16:14:06 -08003018 class ActivityContainer extends IActivityContainer.Stub {
3019 final int mStackId;
3020 final IActivityContainerCallback mCallback;
3021 final ActivityStack mStack;
3022 final ActivityRecord mParentActivity;
Craig Mautner34b73df2014-01-12 21:11:08 -08003023 final String mIdString;
Craig Mautnered6649f2013-12-02 14:08:25 -08003024
Craig Mautner4a1cb222013-12-04 16:14:06 -08003025 /** Display this ActivityStack is currently on. Null if not attached to a Display. */
Craig Mautnere0a38842013-12-16 16:14:02 -08003026 ActivityDisplay mActivityDisplay;
Craig Mautner4a1cb222013-12-04 16:14:06 -08003027
3028 ActivityContainer(ActivityRecord parentActivity, int stackId,
3029 IActivityContainerCallback callback) {
3030 synchronized (mService) {
3031 mStackId = stackId;
3032 mStack = new ActivityStack(this);
3033 mParentActivity = parentActivity;
3034 mCallback = callback;
Craig Mautner34b73df2014-01-12 21:11:08 -08003035 mIdString = "ActivtyContainer{" + mStackId + ", parent=" + mParentActivity + "}";
3036 if (DEBUG_STACK) Slog.d(TAG, "Creating " + this);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003037 }
Craig Mautnered6649f2013-12-02 14:08:25 -08003038 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08003039
Craig Mautnere0a38842013-12-16 16:14:02 -08003040 void attachToDisplayLocked(ActivityDisplay activityDisplay) {
Craig Mautner34b73df2014-01-12 21:11:08 -08003041 if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this
3042 + " to display=" + activityDisplay);
Craig Mautnere0a38842013-12-16 16:14:02 -08003043 mActivityDisplay = activityDisplay;
3044 mStack.mDisplayId = activityDisplay.mDisplayId;
3045 mStack.mStacks = activityDisplay.mStacks;
3046
3047 activityDisplay.attachActivities(mStack);
Craig Mautnerdf88d732014-01-27 09:21:32 -08003048 mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003049 }
3050
3051 @Override
Jeff Brownca9bc702014-02-11 14:32:56 -08003052 public void attachToDisplay(int displayId) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003053 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08003054 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3055 if (activityDisplay == null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003056 return;
3057 }
Craig Mautnere0a38842013-12-16 16:14:02 -08003058 attachToDisplayLocked(activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003059 }
3060 }
3061
3062 @Override
Jeff Brownca9bc702014-02-11 14:32:56 -08003063 public int getDisplayId() {
Craig Mautnere0a38842013-12-16 16:14:02 -08003064 if (mActivityDisplay != null) {
3065 return mActivityDisplay.mDisplayId;
3066 }
3067 return -1;
Craig Mautner4a1cb222013-12-04 16:14:06 -08003068 }
3069
Jeff Brownca9bc702014-02-11 14:32:56 -08003070 @Override
3071 public boolean injectEvent(InputEvent event) {
3072 final long origId = Binder.clearCallingIdentity();
3073 try {
3074 if (mActivityDisplay != null) {
3075 return mInputManagerInternal.injectInputEvent(event,
3076 mActivityDisplay.mDisplayId,
3077 InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
3078 }
3079 return false;
3080 } finally {
3081 Binder.restoreCallingIdentity(origId);
3082 }
3083 }
3084
Craig Mautner34b73df2014-01-12 21:11:08 -08003085 private void detachLocked() {
3086 if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display="
3087 + mActivityDisplay + " Callers=" + Debug.getCallers(2));
Craig Mautnere0a38842013-12-16 16:14:02 -08003088 if (mActivityDisplay != null) {
3089 mActivityDisplay.detachActivitiesLocked(mStack);
3090 mActivityDisplay = null;
3091 mStack.mDisplayId = -1;
3092 mStack.mStacks = null;
Craig Mautnerdf88d732014-01-27 09:21:32 -08003093 mWindowManager.detachStack(mStackId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003094 }
3095 }
3096
3097 @Override
Jeff Brownca9bc702014-02-11 14:32:56 -08003098 public void detachFromDisplay() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003099 synchronized (mService) {
3100 detachLocked();
3101 }
3102 }
3103
3104 @Override
Craig Mautnere0a38842013-12-16 16:14:02 -08003105 public final int startActivity(Intent intent) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08003106 mService.enforceNotIsolatedCaller("ActivityContainer.startActivity");
Craig Mautnere0a38842013-12-16 16:14:02 -08003107 int userId = mService.handleIncomingUser(Binder.getCallingPid(),
3108 Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null);
3109 // TODO: Switch to user app stacks here.
3110 String mimeType = intent.getType();
3111 if (mimeType == null && intent.getData() != null
3112 && "content".equals(intent.getData().getScheme())) {
3113 mimeType = mService.getProviderMimeType(intent.getData(), userId);
3114 }
3115 return startActivityMayWait(null, -1, null, intent, mimeType, null, null, 0, 0, null,
3116 null, null, null, null, userId, this);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003117 }
3118
3119 @Override
Craig Mautnerdf88d732014-01-27 09:21:32 -08003120 public final int startActivityIntentSender(IIntentSender intentSender) {
3121 mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
3122
3123 if (!(intentSender instanceof PendingIntentRecord)) {
3124 throw new IllegalArgumentException("Bad PendingIntent object");
3125 }
3126
3127 return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null,
3128 null, 0, 0, 0, null, this);
3129 }
3130
3131 @Override
Craig Mautner4a1cb222013-12-04 16:14:06 -08003132 public IBinder asBinder() {
3133 return this;
3134 }
3135
Craig Mautner4504de52013-12-20 09:06:56 -08003136 @Override
Craig Mautner34b73df2014-01-12 21:11:08 -08003137 public void attachToSurface(Surface surface, int width, int height, int density) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08003138 mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
3139
3140 final long origId = Binder.clearCallingIdentity();
3141 try {
3142 synchronized (mService) {
3143 ActivityDisplay activityDisplay =
3144 new ActivityDisplay(surface, width, height, density);
3145 mActivityDisplays.put(activityDisplay.mDisplayId, activityDisplay);
3146 attachToDisplayLocked(activityDisplay);
3147 mStack.resumeTopActivityLocked(null);
3148 }
3149 if (DEBUG_STACK) Slog.d(TAG, "attachToSurface: " + this + " to display="
3150 + mActivityDisplay);
3151 } finally {
3152 Binder.restoreCallingIdentity(origId);
Craig Mautner4504de52013-12-20 09:06:56 -08003153 }
Craig Mautner4504de52013-12-20 09:06:56 -08003154 }
3155
Craig Mautner4a1cb222013-12-04 16:14:06 -08003156 ActivityStackSupervisor getOuter() {
3157 return ActivityStackSupervisor.this;
3158 }
3159
3160 boolean isAttached() {
Craig Mautnere0a38842013-12-16 16:14:02 -08003161 return mActivityDisplay != null;
Craig Mautner4a1cb222013-12-04 16:14:06 -08003162 }
3163
3164 void getBounds(Point outBounds) {
Craig Mautnere0a38842013-12-16 16:14:02 -08003165 if (mActivityDisplay != null) {
3166 mActivityDisplay.getBounds(outBounds);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003167 } else {
3168 outBounds.set(0, 0);
3169 }
3170 }
Craig Mautner34b73df2014-01-12 21:11:08 -08003171
3172 @Override
3173 public String toString() {
3174 return mIdString + (mActivityDisplay == null ? "N" : "A");
3175 }
Craig Mautnered6649f2013-12-02 14:08:25 -08003176 }
3177
Craig Mautner4a1cb222013-12-04 16:14:06 -08003178 /** Exactly one of these classes per Display in the system. Capable of holding zero or more
3179 * attached {@link ActivityStack}s */
Craig Mautnere0a38842013-12-16 16:14:02 -08003180 final class ActivityDisplay {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003181 /** Actual Display this object tracks. */
Craig Mautner34b73df2014-01-12 21:11:08 -08003182 int mDisplayId;
3183 Display mDisplay;
3184 DisplayInfo mDisplayInfo = new DisplayInfo();
3185 Surface mSurface;
Craig Mautnered6649f2013-12-02 14:08:25 -08003186
Craig Mautner4a1cb222013-12-04 16:14:06 -08003187 /** All of the stacks on this display. Order matters, topmost stack is in front of all other
3188 * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
Craig Mautnere0a38842013-12-16 16:14:02 -08003189 final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003190
Craig Mautner4504de52013-12-20 09:06:56 -08003191 /** If this display is for an ActivityView then the VirtualDisplay created for it is stored
3192 * here. */
3193 VirtualDisplay mVirtualDisplay;
3194
Craig Mautnere0a38842013-12-16 16:14:02 -08003195 ActivityDisplay(int displayId) {
Craig Mautner34b73df2014-01-12 21:11:08 -08003196 init(mDisplayManager.getDisplay(displayId));
Craig Mautner4504de52013-12-20 09:06:56 -08003197 }
3198
Craig Mautner34b73df2014-01-12 21:11:08 -08003199 ActivityDisplay(Surface surface, int width, int height, int density) {
3200 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
3201 long ident = Binder.clearCallingIdentity();
3202 try {
3203 mVirtualDisplay = dm.createVirtualDisplay(mService.mContext,
3204 VIRTUAL_DISPLAY_BASE_NAME, width, height, density, surface,
3205 DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
3206 DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY);
3207 } finally {
3208 Binder.restoreCallingIdentity(ident);
3209 }
3210
3211 init(mVirtualDisplay.getDisplay());
3212 mSurface = surface;
3213
3214 mWindowManager.handleDisplayAdded(mDisplayId);
3215 }
3216
3217 private void init(Display display) {
Craig Mautner4504de52013-12-20 09:06:56 -08003218 mDisplay = display;
3219 mDisplayId = display.getDisplayId();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003220 mDisplay.getDisplayInfo(mDisplayInfo);
Craig Mautnered6649f2013-12-02 14:08:25 -08003221 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08003222
3223 void attachActivities(ActivityStack stack) {
Craig Mautnere0a38842013-12-16 16:14:02 -08003224 if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId="
3225 + mDisplayId);
3226 mStacks.add(stack);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003227 }
3228
Craig Mautnere0a38842013-12-16 16:14:02 -08003229 void detachActivitiesLocked(ActivityStack stack) {
Craig Mautner34b73df2014-01-12 21:11:08 -08003230 if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack
Craig Mautnere0a38842013-12-16 16:14:02 -08003231 + " from displayId=" + mDisplayId);
3232 mStacks.remove(stack);
Craig Mautner34b73df2014-01-12 21:11:08 -08003233 if (mStacks.isEmpty() && mVirtualDisplay != null) {
3234 mVirtualDisplay.release();
3235 mVirtualDisplay = null;
3236 }
3237 mSurface.release();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003238 }
3239
3240 void getBounds(Point bounds) {
3241 mDisplay.getDisplayInfo(mDisplayInfo);
3242 bounds.x = mDisplayInfo.appWidth;
3243 bounds.y = mDisplayInfo.appHeight;
3244 }
Craig Mautner34b73df2014-01-12 21:11:08 -08003245
3246 @Override
3247 public String toString() {
3248 return "ActivityDisplay={" + mDisplayId + (mVirtualDisplay == null ? "" : "V")
3249 + " numStacks=" + mStacks.size() + "}";
3250 }
Craig Mautnered6649f2013-12-02 14:08:25 -08003251 }
Craig Mautner27084302013-03-25 08:05:25 -07003252}