blob: 3555993fa91d8027cbc7a8dd4502d78c982b4599 [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 Mautnere0a38842013-12-16 16:14:02 -08001779 targetStack.moveToFront();
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 Mautneraea74a52014-03-08 14:23:10 -08001821 if (isLockTaskModeViolation(sourceTask)) {
1822 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
1823 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
1824 }
Craig Mautner525f3d92013-05-07 14:01:50 -07001825 r.setTask(sourceTask, sourceRecord.thumbHolder, false);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001826 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001827 + " in existing task " + r.task + " from source " + sourceRecord);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001828
1829 } else {
1830 // This not being started from an existing activity, and not part
1831 // of a new task... just put it in the top task, though these days
1832 // this case should never happen.
Craig Mautnerac6f8432013-07-17 13:24:59 -07001833 targetStack = adjustStackFocus(r);
Craig Mautnere0a38842013-12-16 16:14:02 -08001834 targetStack.moveToFront();
Craig Mautner1602ec22013-05-12 10:24:27 -07001835 ActivityRecord prev = targetStack.topActivity();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001836 r.setTask(prev != null ? prev.task
1837 : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1838 null, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001839 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1840 + " in new guessed " + r.task);
1841 }
1842
1843 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
1844 intent, r.getUriPermissionsLocked());
1845
1846 if (newTask) {
1847 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
1848 }
1849 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
Craig Mautner0f922742013-08-06 08:44:42 -07001850 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001851 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
Craig Mautner1d001b62013-06-18 16:52:43 -07001852 mService.setFocusedActivityLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001853 return ActivityManager.START_SUCCESS;
1854 }
1855
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001856 void acquireLaunchWakelock() {
1857 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
1858 throw new IllegalStateException("Calling must be system uid");
1859 }
1860 mLaunchingActivity.acquire();
1861 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
1862 // To be safe, don't allow the wake lock to be held for too long.
1863 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
1864 }
1865 }
1866
Craig Mautnerf3333272013-04-22 10:55:53 -07001867 // Checked.
1868 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
1869 Configuration config) {
1870 if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
1871
Craig Mautnerf3333272013-04-22 10:55:53 -07001872 ArrayList<ActivityRecord> stops = null;
1873 ArrayList<ActivityRecord> finishes = null;
1874 ArrayList<UserStartedState> startingUsers = null;
1875 int NS = 0;
1876 int NF = 0;
1877 IApplicationThread sendThumbnail = null;
1878 boolean booting = false;
1879 boolean enableScreen = false;
1880 boolean activityRemoved = false;
1881
1882 ActivityRecord r = ActivityRecord.forToken(token);
1883 if (r != null) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07001884 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
1885 Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07001886 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
1887 r.finishLaunchTickingLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001888 if (fromTimeout) {
1889 reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
Craig Mautnerf3333272013-04-22 10:55:53 -07001890 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001891
1892 // This is a hack to semi-deal with a race condition
1893 // in the client where it can be constructed with a
1894 // newer configuration from when we asked it to launch.
1895 // We'll update with whatever configuration it now says
1896 // it used to launch.
1897 if (config != null) {
1898 r.configuration = config;
1899 }
1900
1901 // We are now idle. If someone is waiting for a thumbnail from
1902 // us, we can now deliver.
1903 r.idle = true;
1904
1905 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
1906 sendThumbnail = r.app.thread;
1907 r.thumbnailNeeded = false;
1908 }
1909
1910 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
1911 if (!mService.mBooted && isFrontStack(r.task.stack)) {
1912 mService.mBooted = true;
1913 enableScreen = true;
1914 }
1915 }
1916
1917 if (allResumedActivitiesIdle()) {
1918 if (r != null) {
1919 mService.scheduleAppGcsLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001920 }
1921
1922 if (mLaunchingActivity.isHeld()) {
1923 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
1924 if (VALIDATE_WAKE_LOCK_CALLER &&
1925 Binder.getCallingUid() != Process.myUid()) {
1926 throw new IllegalStateException("Calling must be system uid");
1927 }
1928 mLaunchingActivity.release();
1929 }
1930 ensureActivitiesVisibleLocked(null, 0);
Craig Mautnerf3333272013-04-22 10:55:53 -07001931 }
1932
1933 // Atomically retrieve all of the other things to do.
1934 stops = processStoppingActivitiesLocked(true);
1935 NS = stops != null ? stops.size() : 0;
1936 if ((NF=mFinishingActivities.size()) > 0) {
1937 finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
1938 mFinishingActivities.clear();
1939 }
1940
1941 final ArrayList<ActivityRecord> thumbnails;
1942 final int NT = mCancelledThumbnails.size();
1943 if (NT > 0) {
1944 thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
1945 mCancelledThumbnails.clear();
1946 } else {
1947 thumbnails = null;
1948 }
1949
1950 if (isFrontStack(mHomeStack)) {
1951 booting = mService.mBooting;
1952 mService.mBooting = false;
1953 }
1954
1955 if (mStartingUsers.size() > 0) {
1956 startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
1957 mStartingUsers.clear();
1958 }
1959
1960 // Perform the following actions from unsynchronized state.
1961 final IApplicationThread thumbnailThread = sendThumbnail;
1962 mHandler.post(new Runnable() {
1963 @Override
1964 public void run() {
1965 if (thumbnailThread != null) {
1966 try {
1967 thumbnailThread.requestThumbnail(token);
1968 } catch (Exception e) {
1969 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
1970 mService.sendPendingThumbnail(null, token, null, null, true);
1971 }
1972 }
1973
1974 // Report back to any thumbnail receivers.
1975 for (int i = 0; i < NT; i++) {
1976 ActivityRecord r = thumbnails.get(i);
1977 mService.sendPendingThumbnail(r, null, null, null, true);
1978 }
1979 }
1980 });
1981
1982 // Stop any activities that are scheduled to do so but have been
1983 // waiting for the next one to start.
1984 for (int i = 0; i < NS; i++) {
1985 r = stops.get(i);
1986 final ActivityStack stack = r.task.stack;
1987 if (r.finishing) {
1988 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
1989 } else {
1990 stack.stopActivityLocked(r);
1991 }
1992 }
1993
1994 // Finish any activities that are scheduled to do so but have been
1995 // waiting for the next one to start.
1996 for (int i = 0; i < NF; i++) {
1997 r = finishes.get(i);
1998 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
1999 }
2000
2001 if (booting) {
2002 mService.finishBooting();
2003 } else if (startingUsers != null) {
2004 for (int i = 0; i < startingUsers.size(); i++) {
2005 mService.finishUserSwitch(startingUsers.get(i));
2006 }
2007 }
2008
2009 mService.trimApplications();
2010 //dump();
2011 //mWindowManager.dump();
2012
2013 if (enableScreen) {
2014 mService.enableScreenAfterBoot();
2015 }
2016
2017 if (activityRemoved) {
Craig Mautner05d29032013-05-03 13:40:13 -07002018 resumeTopActivitiesLocked();
Craig Mautnerf3333272013-04-22 10:55:53 -07002019 }
2020
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002021 return r;
Craig Mautnerf3333272013-04-22 10:55:53 -07002022 }
2023
Craig Mautner8e569572013-10-11 17:36:59 -07002024 boolean handleAppDiedLocked(ProcessRecord app) {
Craig Mautner19091252013-10-05 00:03:53 -07002025 boolean hasVisibleActivities = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002026 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2027 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002028 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2029 hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app);
2030 }
Craig Mautner6b74cb52013-09-27 17:02:21 -07002031 }
Craig Mautner19091252013-10-05 00:03:53 -07002032 return hasVisibleActivities;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002033 }
2034
2035 void closeSystemDialogsLocked() {
Craig Mautnere0a38842013-12-16 16:14:02 -08002036 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2037 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002038 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2039 stacks.get(stackNdx).closeSystemDialogsLocked();
2040 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002041 }
2042 }
2043
Craig Mautner93529a42013-10-04 15:03:13 -07002044 void removeUserLocked(int userId) {
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002045 mUserStackInFront.delete(userId);
Craig Mautner93529a42013-10-04 15:03:13 -07002046 }
2047
Craig Mautner8d341ef2013-03-26 09:03:27 -07002048 /**
2049 * @return true if some activity was finished (or would have finished if doit were true).
2050 */
2051 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
2052 boolean didSomething = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002053 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2054 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002055 final int numStacks = stacks.size();
2056 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2057 final ActivityStack stack = stacks.get(stackNdx);
2058 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
2059 didSomething = true;
2060 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002061 }
2062 }
2063 return didSomething;
2064 }
2065
Dianne Hackborna413dc02013-07-12 12:02:55 -07002066 void updatePreviousProcessLocked(ActivityRecord r) {
2067 // Now that this process has stopped, we may want to consider
2068 // it to be the previous app to try to keep around in case
2069 // the user wants to return to it.
2070
2071 // First, found out what is currently the foreground app, so that
2072 // we don't blow away the previous app if this activity is being
2073 // hosted by the process that is actually still the foreground.
2074 ProcessRecord fgApp = null;
Craig Mautnere0a38842013-12-16 16:14:02 -08002075 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2076 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002077 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2078 final ActivityStack stack = stacks.get(stackNdx);
2079 if (isFrontStack(stack)) {
2080 if (stack.mResumedActivity != null) {
2081 fgApp = stack.mResumedActivity.app;
2082 } else if (stack.mPausingActivity != null) {
2083 fgApp = stack.mPausingActivity.app;
2084 }
2085 break;
Dianne Hackborna413dc02013-07-12 12:02:55 -07002086 }
Dianne Hackborna413dc02013-07-12 12:02:55 -07002087 }
2088 }
2089
2090 // Now set this one as the previous process, only if that really
2091 // makes sense to.
2092 if (r.app != null && fgApp != null && r.app != fgApp
2093 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
Craig Mautner4ef26932013-09-18 15:15:52 -07002094 && r.app != mService.mHomeProcess) {
Dianne Hackborna413dc02013-07-12 12:02:55 -07002095 mService.mPreviousProcess = r.app;
2096 mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
2097 }
2098 }
2099
Craig Mautner05d29032013-05-03 13:40:13 -07002100 boolean resumeTopActivitiesLocked() {
2101 return resumeTopActivitiesLocked(null, null, null);
2102 }
2103
2104 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
2105 Bundle targetOptions) {
2106 if (targetStack == null) {
2107 targetStack = getFocusedStack();
2108 }
Craig Mautner12ff7392014-02-21 21:08:00 -08002109 // Do targetStack first.
Craig Mautner05d29032013-05-03 13:40:13 -07002110 boolean result = false;
Craig Mautner12ff7392014-02-21 21:08:00 -08002111 if (isFrontStack(targetStack)) {
2112 result = targetStack.resumeTopActivityLocked(target, targetOptions);
2113 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002114 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2115 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002116 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2117 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautner12ff7392014-02-21 21:08:00 -08002118 if (stack == targetStack) {
2119 // Already started above.
2120 continue;
2121 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002122 if (isFrontStack(stack)) {
Craig Mautner12ff7392014-02-21 21:08:00 -08002123 stack.resumeTopActivityLocked(null);
Craig Mautner05d29032013-05-03 13:40:13 -07002124 }
Craig Mautnerf88c50f2013-04-18 19:25:12 -07002125 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002126 }
Craig Mautner05d29032013-05-03 13:40:13 -07002127 return result;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002128 }
2129
2130 void finishTopRunningActivityLocked(ProcessRecord app) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002131 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2132 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002133 final int numStacks = stacks.size();
2134 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2135 final ActivityStack stack = stacks.get(stackNdx);
2136 stack.finishTopRunningActivityLocked(app);
2137 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002138 }
2139 }
2140
Craig Mautneraea74a52014-03-08 14:23:10 -08002141 void findTaskToMoveToFrontLocked(TaskRecord task, int flags, Bundle options) {
2142 if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
2143 mUserLeaving = true;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002144 }
Craig Mautneraea74a52014-03-08 14:23:10 -08002145 if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
2146 // Caller wants the home activity moved with it. To accomplish this,
2147 // we'll just indicate that this task returns to the home task.
2148 task.mOnTopOfHome = true;
2149 }
2150 task.stack.moveTaskToFrontLocked(task, null, options);
2151 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack="
2152 + task.stack);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002153 }
2154
Craig Mautner967212c2013-04-13 21:10:58 -07002155 ActivityStack getStack(int stackId) {
Craig Mautner4504de52013-12-20 09:06:56 -08002156 WeakReference<ActivityContainer> weakReference = mActivityContainers.get(stackId);
2157 if (weakReference != null) {
2158 ActivityContainer activityContainer = weakReference.get();
2159 if (activityContainer != null) {
2160 return activityContainer.mStack;
2161 } else {
2162 mActivityContainers.remove(stackId);
2163 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002164 }
2165 return null;
2166 }
2167
Craig Mautner967212c2013-04-13 21:10:58 -07002168 ArrayList<ActivityStack> getStacks() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002169 ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>();
Craig Mautnere0a38842013-12-16 16:14:02 -08002170 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2171 allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002172 }
2173 return allStacks;
Craig Mautner967212c2013-04-13 21:10:58 -07002174 }
2175
Craig Mautner4a1cb222013-12-04 16:14:06 -08002176 IBinder getHomeActivityToken() {
2177 final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
2178 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
2179 final TaskRecord task = tasks.get(taskNdx);
2180 if (task.isHomeTask()) {
2181 final ArrayList<ActivityRecord> activities = task.mActivities;
2182 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2183 final ActivityRecord r = activities.get(activityNdx);
2184 if (r.isHomeActivity()) {
2185 return r.appToken;
2186 }
2187 }
2188 }
2189 }
2190 return null;
2191 }
2192
2193 ActivityContainer createActivityContainer(ActivityRecord parentActivity, int stackId,
2194 IActivityContainerCallback callback) {
2195 ActivityContainer activityContainer = new ActivityContainer(parentActivity, stackId,
2196 callback);
Craig Mautner4504de52013-12-20 09:06:56 -08002197 mActivityContainers.put(stackId, new WeakReference<ActivityContainer>(activityContainer));
Craig Mautner4a1cb222013-12-04 16:14:06 -08002198 if (parentActivity != null) {
2199 parentActivity.mChildContainers.add(activityContainer.mStack);
2200 }
2201 return activityContainer;
2202 }
2203
2204 ActivityContainer createActivityContainer(ActivityRecord parentActivity,
2205 IActivityContainerCallback callback) {
2206 return createActivityContainer(parentActivity, getNextStackId(), callback);
2207 }
2208
Craig Mautner34b73df2014-01-12 21:11:08 -08002209 void removeChildActivityContainers(ActivityRecord parentActivity) {
2210 for (int ndx = mActivityContainers.size() - 1; ndx >= 0; --ndx) {
2211 final ActivityContainer container = mActivityContainers.valueAt(ndx).get();
2212 if (container == null) {
2213 mActivityContainers.removeAt(ndx);
2214 continue;
2215 }
2216 if (container.mParentActivity != parentActivity) {
2217 continue;
2218 }
2219
2220 ActivityStack stack = container.mStack;
2221 ActivityRecord top = stack.topRunningNonDelayedActivityLocked(null);
2222 if (top != null) {
2223 // TODO: Make sure the next activity doesn't start up when top is destroyed.
Craig Mautner95da1082014-02-24 17:54:35 -08002224 stack.destroyActivityLocked(top, true, true, "stack parent destroyed");
Craig Mautner34b73df2014-01-12 21:11:08 -08002225 }
2226 mActivityContainers.removeAt(ndx);
2227 container.detachLocked();
2228 }
2229 }
2230
Craig Mautner95da1082014-02-24 17:54:35 -08002231 void deleteActivityContainer(IActivityContainer container) {
2232 ActivityContainer activityContainer = (ActivityContainer)container;
2233 if (activityContainer != null) {
2234 activityContainer.mStack.destroyActivitiesLocked(null, true,
2235 "deleteActivityContainer");
2236 final ActivityRecord parent = activityContainer.mParentActivity;
2237 if (parent != null) {
2238 parent.mChildContainers.remove(activityContainer);
2239 }
2240 final int stackId = activityContainer.mStackId;
2241 mActivityContainers.remove(stackId);
2242 mWindowManager.removeStack(stackId);
2243 }
2244 }
2245
Craig Mautner4a1cb222013-12-04 16:14:06 -08002246 private int createStackOnDisplay(ActivityRecord parentActivity, int stackId, int displayId) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002247 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2248 if (activityDisplay == null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002249 return -1;
2250 }
2251
2252 ActivityContainer activityContainer =
2253 createActivityContainer(parentActivity, stackId, null);
Craig Mautnere0a38842013-12-16 16:14:02 -08002254 activityContainer.attachToDisplayLocked(activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002255 return stackId;
2256 }
2257
2258 int getNextStackId() {
Craig Mautner858d8a62013-04-23 17:08:34 -07002259 while (true) {
2260 if (++mLastStackId <= HOME_STACK_ID) {
2261 mLastStackId = HOME_STACK_ID + 1;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002262 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002263 if (getStack(mLastStackId) == null) {
2264 break;
2265 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002266 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002267 return mLastStackId;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002268 }
2269
2270 void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002271 final TaskRecord task = anyTaskForIdLocked(taskId);
2272 if (task == null) {
2273 return;
2274 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002275 final ActivityStack stack = getStack(stackId);
2276 if (stack == null) {
2277 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
2278 return;
2279 }
Craig Mautner04a0ea62014-01-13 12:51:26 -08002280 task.stack.removeTask(task);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002281 stack.addTask(task, toTop);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002282 mWindowManager.addTask(taskId, stackId, toTop);
Craig Mautner05d29032013-05-03 13:40:13 -07002283 resumeTopActivitiesLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002284 }
2285
Craig Mautnerac6f8432013-07-17 13:24:59 -07002286 ActivityRecord findTaskLocked(ActivityRecord r) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07002287 if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r);
Craig Mautnere0a38842013-12-16 16:14:02 -08002288 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2289 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002290 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2291 final ActivityStack stack = stacks.get(stackNdx);
2292 if (!r.isApplicationActivity() && !stack.isHomeStack()) {
2293 if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: " + stack);
2294 continue;
2295 }
2296 final ActivityRecord ar = stack.findTaskLocked(r);
2297 if (ar != null) {
2298 return ar;
2299 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07002300 }
2301 }
Dianne Hackborn2a272d42013-10-16 13:34:33 -07002302 if (DEBUG_TASKS) Slog.d(TAG, "No task found");
Craig Mautner8849a5e2013-04-02 16:41:03 -07002303 return null;
2304 }
2305
2306 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002307 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2308 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002309 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2310 final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info);
2311 if (ar != null) {
2312 return ar;
2313 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07002314 }
2315 }
2316 return null;
2317 }
2318
Craig Mautner8d341ef2013-03-26 09:03:27 -07002319 void goingToSleepLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002320 scheduleSleepTimeout();
2321 if (!mGoingToSleep.isHeld()) {
2322 mGoingToSleep.acquire();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002323 if (mLaunchingActivity.isHeld()) {
2324 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2325 throw new IllegalStateException("Calling must be system uid");
Craig Mautner0eea92c2013-05-16 13:35:39 -07002326 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002327 mLaunchingActivity.release();
2328 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
Craig Mautner0eea92c2013-05-16 13:35:39 -07002329 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002330 }
Amith Yamasanice15e152013-09-19 12:30:32 -07002331 checkReadyForSleepLocked();
Craig Mautneraea74a52014-03-08 14:23:10 -08002332 setLockTaskModeLocked(null);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002333 }
2334
2335 boolean shutdownLocked(int timeout) {
2336 boolean timedout = false;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002337 goingToSleepLocked();
Craig Mautner0eea92c2013-05-16 13:35:39 -07002338
2339 final long endTime = System.currentTimeMillis() + timeout;
2340 while (true) {
2341 boolean cantShutdown = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002342 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2343 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002344 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2345 cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
2346 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002347 }
2348 if (cantShutdown) {
2349 long timeRemaining = endTime - System.currentTimeMillis();
2350 if (timeRemaining > 0) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002351 try {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002352 mService.wait(timeRemaining);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002353 } catch (InterruptedException e) {
2354 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002355 } else {
2356 Slog.w(TAG, "Activity manager shutdown timed out");
2357 timedout = true;
2358 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002359 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002360 } else {
2361 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002362 }
2363 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002364
2365 // Force checkReadyForSleep to complete.
2366 mSleepTimeout = true;
2367 checkReadyForSleepLocked();
2368
Craig Mautner8d341ef2013-03-26 09:03:27 -07002369 return timedout;
2370 }
2371
2372 void comeOutOfSleepIfNeededLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002373 removeSleepTimeouts();
2374 if (mGoingToSleep.isHeld()) {
2375 mGoingToSleep.release();
2376 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002377 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2378 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002379 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2380 final ActivityStack stack = stacks.get(stackNdx);
2381 stack.awakeFromSleepingLocked();
2382 if (isFrontStack(stack)) {
2383 resumeTopActivitiesLocked();
2384 }
Craig Mautner5314a402013-09-26 12:40:16 -07002385 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002386 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002387 mGoingToSleepActivities.clear();
2388 }
2389
2390 void activitySleptLocked(ActivityRecord r) {
2391 mGoingToSleepActivities.remove(r);
2392 checkReadyForSleepLocked();
2393 }
2394
2395 void checkReadyForSleepLocked() {
2396 if (!mService.isSleepingOrShuttingDown()) {
2397 // Do not care.
2398 return;
2399 }
2400
2401 if (!mSleepTimeout) {
2402 boolean dontSleep = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002403 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2404 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002405 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2406 dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
2407 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002408 }
2409
2410 if (mStoppingActivities.size() > 0) {
2411 // Still need to tell some activities to stop; can't sleep yet.
2412 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2413 + mStoppingActivities.size() + " activities");
2414 scheduleIdleLocked();
2415 dontSleep = true;
2416 }
2417
2418 if (mGoingToSleepActivities.size() > 0) {
2419 // Still need to tell some activities to sleep; can't sleep yet.
2420 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2421 + mGoingToSleepActivities.size() + " activities");
2422 dontSleep = true;
2423 }
2424
2425 if (dontSleep) {
2426 return;
2427 }
2428 }
2429
Craig Mautnere0a38842013-12-16 16:14:02 -08002430 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2431 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002432 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2433 stacks.get(stackNdx).goToSleep();
2434 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002435 }
2436
2437 removeSleepTimeouts();
2438
2439 if (mGoingToSleep.isHeld()) {
2440 mGoingToSleep.release();
2441 }
2442 if (mService.mShuttingDown) {
2443 mService.notifyAll();
2444 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002445 }
2446
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002447 boolean reportResumedActivityLocked(ActivityRecord r) {
2448 final ActivityStack stack = r.task.stack;
2449 if (isFrontStack(stack)) {
Jeff Sharkey5782da72013-04-25 14:32:30 -07002450 mService.updateUsageStats(r, true);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002451 }
2452 if (allResumedActivitiesComplete()) {
2453 ensureActivitiesVisibleLocked(null, 0);
2454 mWindowManager.executeAppTransition();
2455 return true;
2456 }
2457 return false;
2458 }
2459
Craig Mautner8d341ef2013-03-26 09:03:27 -07002460 void handleAppCrashLocked(ProcessRecord app) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002461 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2462 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002463 final int numStacks = stacks.size();
2464 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2465 final ActivityStack stack = stacks.get(stackNdx);
2466 stack.handleAppCrashLocked(app);
2467 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002468 }
2469 }
2470
Craig Mautnerde4ef022013-04-07 19:01:33 -07002471 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
Craig Mautner580ea812013-04-25 12:58:38 -07002472 // First the front stacks. In case any are not fullscreen and are in front of home.
2473 boolean showHomeBehindStack = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002474 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2475 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002476 final int topStackNdx = stacks.size() - 1;
2477 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
2478 final ActivityStack stack = stacks.get(stackNdx);
2479 if (stackNdx == topStackNdx) {
2480 // Top stack.
2481 showHomeBehindStack =
2482 stack.ensureActivitiesVisibleLocked(starting, configChanges);
2483 } else {
2484 // Back stack.
2485 stack.ensureActivitiesVisibleLocked(starting, configChanges,
2486 showHomeBehindStack);
2487 }
Craig Mautner580ea812013-04-25 12:58:38 -07002488 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002489 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002490 }
2491
2492 void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002493 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2494 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002495 final int numStacks = stacks.size();
2496 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2497 final ActivityStack stack = stacks.get(stackNdx);
2498 stack.scheduleDestroyActivities(app, false, reason);
2499 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002500 }
2501 }
2502
2503 boolean switchUserLocked(int userId, UserStartedState uss) {
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002504 mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId());
2505 final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
Craig Mautner2420ead2013-04-01 17:13:20 -07002506 mCurrentUser = userId;
Craig Mautnerac6f8432013-07-17 13:24:59 -07002507
Craig Mautner858d8a62013-04-23 17:08:34 -07002508 mStartingUsers.add(uss);
Craig Mautnere0a38842013-12-16 16:14:02 -08002509 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2510 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002511 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002512 final ActivityStack stack = stacks.get(stackNdx);
2513 stack.switchUserLocked(userId);
Alexandra Gherghinadae57a12014-03-12 19:15:26 +00002514 TaskRecord task = stack.topTask();
2515 if (task != null) {
2516 mWindowManager.moveTaskToTop(task.taskId);
2517 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002518 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07002519 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002520
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002521 ActivityStack stack = getStack(restoreStackId);
2522 if (stack == null) {
2523 stack = mHomeStack;
2524 }
2525 final boolean homeInFront = stack.isHomeStack();
Craig Mautnere0a38842013-12-16 16:14:02 -08002526 if (stack.isOnHomeDisplay()) {
2527 moveHomeStack(homeInFront);
Alexandra Gherghinadae57a12014-03-12 19:15:26 +00002528 TaskRecord task = stack.topTask();
2529 if (task != null) {
2530 mWindowManager.moveTaskToTop(task.taskId);
2531 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002532 } else {
2533 // Stack was moved to another display while user was swapped out.
2534 resumeHomeActivity(null);
2535 }
Craig Mautner93529a42013-10-04 15:03:13 -07002536 return homeInFront;
Craig Mautner2219a1b2013-03-25 09:44:30 -07002537 }
2538
Craig Mautnerde4ef022013-04-07 19:01:33 -07002539 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2540 int N = mStoppingActivities.size();
2541 if (N <= 0) return null;
2542
2543 ArrayList<ActivityRecord> stops = null;
2544
2545 final boolean nowVisible = allResumedActivitiesVisible();
2546 for (int i=0; i<N; i++) {
2547 ActivityRecord s = mStoppingActivities.get(i);
Craig Mautnera7f2bd42013-10-15 16:13:50 -07002548 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
Craig Mautnerde4ef022013-04-07 19:01:33 -07002549 + nowVisible + " waitingVisible=" + s.waitingVisible
2550 + " finishing=" + s.finishing);
2551 if (s.waitingVisible && nowVisible) {
2552 mWaitingVisibleActivities.remove(s);
2553 s.waitingVisible = false;
2554 if (s.finishing) {
2555 // If this activity is finishing, it is sitting on top of
2556 // everyone else but we now know it is no longer needed...
2557 // so get rid of it. Otherwise, we need to go through the
2558 // normal flow and hide it once we determine that it is
2559 // hidden by the activities in front of it.
2560 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002561 mWindowManager.setAppVisibility(s.appToken, false);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002562 }
2563 }
2564 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2565 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2566 if (stops == null) {
2567 stops = new ArrayList<ActivityRecord>();
2568 }
2569 stops.add(s);
2570 mStoppingActivities.remove(i);
2571 N--;
2572 i--;
2573 }
2574 }
2575
2576 return stops;
2577 }
2578
Craig Mautnercf910b02013-04-23 11:23:27 -07002579 void validateTopActivitiesLocked() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002580 // FIXME
2581/* for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2582 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautnercf910b02013-04-23 11:23:27 -07002583 final ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002584 final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
Craig Mautnercf910b02013-04-23 11:23:27 -07002585 if (isFrontStack(stack)) {
2586 if (r == null) {
2587 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2588 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002589 final ActivityRecord pausing = stack.mPausingActivity;
2590 if (pausing != null && pausing == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002591 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002592 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002593 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002594 if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002595 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002596 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002597 }
2598 }
2599 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002600 final ActivityRecord resumed = stack.mResumedActivity;
2601 if (resumed != null && resumed == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002602 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002603 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002604 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002605 if (r != null && (state == ActivityState.INITIALIZING
2606 || state == ActivityState.RESUMED)) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002607 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002608 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002609 }
2610 }
2611 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002612*/
Craig Mautner76ea2242013-05-15 11:40:05 -07002613 }
2614
Craig Mautner27084302013-03-25 08:05:25 -07002615 public void dump(PrintWriter pw, String prefix) {
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002616 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity=");
Craig Mautner27084302013-03-25 08:05:25 -07002617 pw.println(mDismissKeyguardOnNextActivity);
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002618 pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002619 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002620 pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
2621 pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
2622 pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
Craig Mautner95da1082014-02-24 17:54:35 -08002623 pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
Craig Mautner27084302013-03-25 08:05:25 -07002624 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002625
Craig Mautner20e72272013-04-01 13:45:53 -07002626 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002627 return getFocusedStack().getDumpActivitiesLocked(name);
Craig Mautner20e72272013-04-01 13:45:53 -07002628 }
2629
Dianne Hackborn390517b2013-05-30 15:03:32 -07002630 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2631 boolean needSep, String prefix) {
2632 if (activity != null) {
2633 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2634 if (needSep) {
2635 pw.println();
Dianne Hackborn390517b2013-05-30 15:03:32 -07002636 }
2637 pw.print(prefix);
2638 pw.println(activity);
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002639 return true;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002640 }
2641 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002642 return false;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002643 }
2644
Craig Mautner8d341ef2013-03-26 09:03:27 -07002645 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2646 boolean dumpClient, String dumpPackage) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002647 boolean printed = false;
2648 boolean needSep = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002649 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2650 ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
2651 pw.print("Display #"); pw.println(activityDisplay.mDisplayId);
2652 ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002653 final int numStacks = stacks.size();
2654 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2655 final ActivityStack stack = stacks.get(stackNdx);
2656 StringBuilder stackHeader = new StringBuilder(128);
2657 stackHeader.append(" Stack #");
2658 stackHeader.append(stack.mStackId);
2659 stackHeader.append(":");
2660 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
2661 needSep, stackHeader.toString());
2662 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false,
2663 !dumpAll, false, dumpPackage, true,
2664 " Running activities (most recent first):", null);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002665
Craig Mautner4a1cb222013-12-04 16:14:06 -08002666 needSep = printed;
2667 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
2668 " mPausingActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002669 if (pr) {
2670 printed = true;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002671 needSep = false;
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002672 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002673 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
2674 " mResumedActivity: ");
2675 if (pr) {
2676 printed = true;
2677 needSep = false;
2678 }
2679 if (dumpAll) {
2680 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
2681 " mLastPausedActivity: ");
2682 if (pr) {
2683 printed = true;
2684 needSep = true;
2685 }
2686 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
2687 needSep, " mLastNoHistoryActivity: ");
2688 }
2689 needSep = printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002690 }
2691 }
2692
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002693 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll,
2694 false, dumpPackage, true, " Activities waiting to finish:", null);
2695 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll,
2696 false, dumpPackage, true, " Activities waiting to stop:", null);
2697 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll,
2698 false, dumpPackage, true, " Activities waiting for another to become visible:",
2699 null);
2700 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2701 false, dumpPackage, true, " Activities waiting to sleep:", null);
2702 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2703 false, dumpPackage, true, " Activities waiting to sleep:", null);
Craig Mautnerf3333272013-04-22 10:55:53 -07002704
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002705 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002706 }
2707
Dianne Hackborn390517b2013-05-30 15:03:32 -07002708 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
Craig Mautner8d341ef2013-03-26 09:03:27 -07002709 String prefix, String label, boolean complete, boolean brief, boolean client,
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002710 String dumpPackage, boolean needNL, String header1, String header2) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002711 TaskRecord lastTask = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002712 String innerPrefix = null;
2713 String[] args = null;
2714 boolean printed = false;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002715 for (int i=list.size()-1; i>=0; i--) {
2716 final ActivityRecord r = list.get(i);
2717 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2718 continue;
2719 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002720 if (innerPrefix == null) {
2721 innerPrefix = prefix + " ";
2722 args = new String[0];
2723 }
2724 printed = true;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002725 final boolean full = !brief && (complete || !r.isInHistory());
2726 if (needNL) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07002727 pw.println("");
Craig Mautner8d341ef2013-03-26 09:03:27 -07002728 needNL = false;
2729 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002730 if (header1 != null) {
2731 pw.println(header1);
2732 header1 = null;
2733 }
2734 if (header2 != null) {
2735 pw.println(header2);
2736 header2 = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002737 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002738 if (lastTask != r.task) {
2739 lastTask = r.task;
2740 pw.print(prefix);
2741 pw.print(full ? "* " : " ");
2742 pw.println(lastTask);
2743 if (full) {
2744 lastTask.dump(pw, prefix + " ");
2745 } else if (complete) {
2746 // Complete + brief == give a summary. Isn't that obvious?!?
2747 if (lastTask.intent != null) {
2748 pw.print(prefix); pw.print(" ");
2749 pw.println(lastTask.intent.toInsecureStringWithClip());
2750 }
2751 }
2752 }
2753 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
2754 pw.print(" #"); pw.print(i); pw.print(": ");
2755 pw.println(r);
2756 if (full) {
2757 r.dump(pw, innerPrefix);
2758 } else if (complete) {
2759 // Complete + brief == give a summary. Isn't that obvious?!?
2760 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2761 if (r.app != null) {
2762 pw.print(innerPrefix); pw.println(r.app);
2763 }
2764 }
2765 if (client && r.app != null && r.app.thread != null) {
2766 // flush anything that is already in the PrintWriter since the thread is going
2767 // to write to the file descriptor directly
2768 pw.flush();
2769 try {
2770 TransferPipe tp = new TransferPipe();
2771 try {
2772 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2773 r.appToken, innerPrefix, args);
2774 // Short timeout, since blocking here can
2775 // deadlock with the application.
2776 tp.go(fd, 2000);
2777 } finally {
2778 tp.kill();
2779 }
2780 } catch (IOException e) {
2781 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2782 } catch (RemoteException e) {
2783 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2784 }
2785 needNL = true;
2786 }
2787 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002788 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002789 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002790
Craig Mautnerf3333272013-04-22 10:55:53 -07002791 void scheduleIdleTimeoutLocked(ActivityRecord next) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002792 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
Craig Mautnerc64f73e2013-04-24 16:44:56 -07002793 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2794 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
Craig Mautnerf3333272013-04-22 10:55:53 -07002795 }
2796
2797 final void scheduleIdleLocked() {
Craig Mautner05d29032013-05-03 13:40:13 -07002798 mHandler.sendEmptyMessage(IDLE_NOW_MSG);
Craig Mautnerf3333272013-04-22 10:55:53 -07002799 }
2800
2801 void removeTimeoutsForActivityLocked(ActivityRecord r) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002802 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07002803 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2804 }
2805
Craig Mautner05d29032013-05-03 13:40:13 -07002806 final void scheduleResumeTopActivities() {
Craig Mautner34b73df2014-01-12 21:11:08 -08002807 if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
2808 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2809 }
Craig Mautner05d29032013-05-03 13:40:13 -07002810 }
2811
Craig Mautner0eea92c2013-05-16 13:35:39 -07002812 void removeSleepTimeouts() {
2813 mSleepTimeout = false;
2814 mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2815 }
2816
2817 final void scheduleSleepTimeout() {
2818 removeSleepTimeouts();
2819 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2820 }
2821
Craig Mautner4a1cb222013-12-04 16:14:06 -08002822 @Override
2823 public void onDisplayAdded(int displayId) {
2824 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
2825 }
2826
2827 @Override
2828 public void onDisplayRemoved(int displayId) {
2829 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
2830 }
2831
2832 @Override
2833 public void onDisplayChanged(int displayId) {
2834 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
2835 }
2836
2837 public void handleDisplayAddedLocked(int displayId) {
Craig Mautner4504de52013-12-20 09:06:56 -08002838 boolean newDisplay;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002839 synchronized (mService) {
Craig Mautner4504de52013-12-20 09:06:56 -08002840 newDisplay = mActivityDisplays.get(displayId) == null;
2841 if (newDisplay) {
2842 ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
2843 mActivityDisplays.put(displayId, activityDisplay);
2844 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002845 }
Craig Mautner4504de52013-12-20 09:06:56 -08002846 if (newDisplay) {
2847 mWindowManager.onDisplayAdded(displayId);
2848 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002849 }
2850
2851 public void handleDisplayRemovedLocked(int displayId) {
2852 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002853 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2854 if (activityDisplay != null) {
2855 ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002856 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner34b73df2014-01-12 21:11:08 -08002857 stacks.get(stackNdx).mActivityContainer.detachLocked();
Craig Mautner4a1cb222013-12-04 16:14:06 -08002858 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002859 mActivityDisplays.remove(displayId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002860 }
2861 }
2862 mWindowManager.onDisplayRemoved(displayId);
2863 }
2864
2865 public void handleDisplayChangedLocked(int displayId) {
2866 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002867 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2868 if (activityDisplay != null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002869 // TODO: Update the bounds.
2870 }
2871 }
2872 mWindowManager.onDisplayChanged(displayId);
2873 }
2874
2875 StackInfo getStackInfo(ActivityStack stack) {
2876 StackInfo info = new StackInfo();
2877 mWindowManager.getStackBounds(stack.mStackId, info.bounds);
2878 info.displayId = Display.DEFAULT_DISPLAY;
2879 info.stackId = stack.mStackId;
2880
2881 ArrayList<TaskRecord> tasks = stack.getAllTasks();
2882 final int numTasks = tasks.size();
2883 int[] taskIds = new int[numTasks];
2884 String[] taskNames = new String[numTasks];
2885 for (int i = 0; i < numTasks; ++i) {
2886 final TaskRecord task = tasks.get(i);
2887 taskIds[i] = task.taskId;
2888 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
2889 : task.realActivity != null ? task.realActivity.flattenToString()
2890 : task.getTopActivity() != null ? task.getTopActivity().packageName
2891 : "unknown";
2892 }
2893 info.taskIds = taskIds;
2894 info.taskNames = taskNames;
2895 return info;
2896 }
2897
2898 StackInfo getStackInfoLocked(int stackId) {
2899 ActivityStack stack = getStack(stackId);
2900 if (stack != null) {
2901 return getStackInfo(stack);
2902 }
2903 return null;
2904 }
2905
2906 ArrayList<StackInfo> getAllStackInfosLocked() {
2907 ArrayList<StackInfo> list = new ArrayList<StackInfo>();
Craig Mautnere0a38842013-12-16 16:14:02 -08002908 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2909 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002910 for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
2911 list.add(getStackInfo(stacks.get(ndx)));
2912 }
2913 }
2914 return list;
2915 }
2916
Craig Mautneraea74a52014-03-08 14:23:10 -08002917 void setLockTaskModeLocked(TaskRecord task) {
2918 if (task == null) {
2919 // Take out of lock task mode.
2920 mLockTaskModeTask = null;
2921 return;
2922 }
2923 if (isLockTaskModeViolation(task)) {
2924 Slog.e(TAG, "setLockTaskMode: Attempt to start a second Lock Task Mode task.");
2925 return;
2926 }
2927 mLockTaskModeTask = task;
2928 findTaskToMoveToFrontLocked(task, 0, null);
2929 resumeTopActivitiesLocked();
2930 }
2931
2932 boolean isLockTaskModeViolation(TaskRecord task) {
2933 return mLockTaskModeTask != null && mLockTaskModeTask != task;
2934 }
2935
2936 void endLockTaskModeIfTaskEnding(TaskRecord task) {
2937 if (mLockTaskModeTask != null && mLockTaskModeTask == task) {
2938 mLockTaskModeTask = null;
2939 }
2940 }
2941
2942 boolean isInLockTaskMode() {
2943 return mLockTaskModeTask != null;
2944 }
2945
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002946 private final class ActivityStackSupervisorHandler extends Handler {
Craig Mautnerf3333272013-04-22 10:55:53 -07002947
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002948 public ActivityStackSupervisorHandler(Looper looper) {
2949 super(looper);
2950 }
2951
Craig Mautnerf3333272013-04-22 10:55:53 -07002952 void activityIdleInternal(ActivityRecord r) {
2953 synchronized (mService) {
2954 activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
2955 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002956 }
2957
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002958 @Override
2959 public void handleMessage(Message msg) {
2960 switch (msg.what) {
Craig Mautnerf3333272013-04-22 10:55:53 -07002961 case IDLE_TIMEOUT_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002962 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002963 if (mService.mDidDexOpt) {
2964 mService.mDidDexOpt = false;
2965 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2966 nmsg.obj = msg.obj;
2967 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
2968 return;
2969 }
2970 // We don't at this point know if the activity is fullscreen,
2971 // so we need to be conservative and assume it isn't.
2972 activityIdleInternal((ActivityRecord)msg.obj);
2973 } break;
2974 case IDLE_NOW_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002975 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002976 activityIdleInternal((ActivityRecord)msg.obj);
2977 } break;
Craig Mautner05d29032013-05-03 13:40:13 -07002978 case RESUME_TOP_ACTIVITY_MSG: {
2979 synchronized (mService) {
2980 resumeTopActivitiesLocked();
2981 }
2982 } break;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002983 case SLEEP_TIMEOUT_MSG: {
2984 synchronized (mService) {
2985 if (mService.isSleepingOrShuttingDown()) {
2986 Slog.w(TAG, "Sleep timeout! Sleeping now.");
2987 mSleepTimeout = true;
2988 checkReadyForSleepLocked();
2989 }
2990 }
2991 } break;
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002992 case LAUNCH_TIMEOUT_MSG: {
2993 if (mService.mDidDexOpt) {
2994 mService.mDidDexOpt = false;
2995 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
2996 return;
2997 }
2998 synchronized (mService) {
2999 if (mLaunchingActivity.isHeld()) {
3000 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
3001 if (VALIDATE_WAKE_LOCK_CALLER
3002 && Binder.getCallingUid() != Process.myUid()) {
3003 throw new IllegalStateException("Calling must be system uid");
3004 }
3005 mLaunchingActivity.release();
3006 }
3007 }
3008 } break;
Craig Mautner4a1cb222013-12-04 16:14:06 -08003009 case HANDLE_DISPLAY_ADDED: {
3010 handleDisplayAddedLocked(msg.arg1);
3011 } break;
3012 case HANDLE_DISPLAY_CHANGED: {
3013 handleDisplayChangedLocked(msg.arg1);
3014 } break;
3015 case HANDLE_DISPLAY_REMOVED: {
3016 handleDisplayRemovedLocked(msg.arg1);
3017 } break;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07003018 }
3019 }
3020 }
Craig Mautnered6649f2013-12-02 14:08:25 -08003021
Craig Mautner4a1cb222013-12-04 16:14:06 -08003022 class ActivityContainer extends IActivityContainer.Stub {
3023 final int mStackId;
3024 final IActivityContainerCallback mCallback;
3025 final ActivityStack mStack;
3026 final ActivityRecord mParentActivity;
Craig Mautner34b73df2014-01-12 21:11:08 -08003027 final String mIdString;
Craig Mautnered6649f2013-12-02 14:08:25 -08003028
Craig Mautner4a1cb222013-12-04 16:14:06 -08003029 /** Display this ActivityStack is currently on. Null if not attached to a Display. */
Craig Mautnere0a38842013-12-16 16:14:02 -08003030 ActivityDisplay mActivityDisplay;
Craig Mautner4a1cb222013-12-04 16:14:06 -08003031
3032 ActivityContainer(ActivityRecord parentActivity, int stackId,
3033 IActivityContainerCallback callback) {
3034 synchronized (mService) {
3035 mStackId = stackId;
3036 mStack = new ActivityStack(this);
3037 mParentActivity = parentActivity;
3038 mCallback = callback;
Craig Mautner34b73df2014-01-12 21:11:08 -08003039 mIdString = "ActivtyContainer{" + mStackId + ", parent=" + mParentActivity + "}";
3040 if (DEBUG_STACK) Slog.d(TAG, "Creating " + this);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003041 }
Craig Mautnered6649f2013-12-02 14:08:25 -08003042 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08003043
Craig Mautnere0a38842013-12-16 16:14:02 -08003044 void attachToDisplayLocked(ActivityDisplay activityDisplay) {
Craig Mautner34b73df2014-01-12 21:11:08 -08003045 if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this
3046 + " to display=" + activityDisplay);
Craig Mautnere0a38842013-12-16 16:14:02 -08003047 mActivityDisplay = activityDisplay;
3048 mStack.mDisplayId = activityDisplay.mDisplayId;
3049 mStack.mStacks = activityDisplay.mStacks;
3050
3051 activityDisplay.attachActivities(mStack);
Craig Mautnerdf88d732014-01-27 09:21:32 -08003052 mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003053 }
3054
3055 @Override
Jeff Brownca9bc702014-02-11 14:32:56 -08003056 public void attachToDisplay(int displayId) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003057 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08003058 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3059 if (activityDisplay == null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003060 return;
3061 }
Craig Mautnere0a38842013-12-16 16:14:02 -08003062 attachToDisplayLocked(activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003063 }
3064 }
3065
3066 @Override
Jeff Brownca9bc702014-02-11 14:32:56 -08003067 public int getDisplayId() {
Craig Mautnere0a38842013-12-16 16:14:02 -08003068 if (mActivityDisplay != null) {
3069 return mActivityDisplay.mDisplayId;
3070 }
3071 return -1;
Craig Mautner4a1cb222013-12-04 16:14:06 -08003072 }
3073
Jeff Brownca9bc702014-02-11 14:32:56 -08003074 @Override
3075 public boolean injectEvent(InputEvent event) {
3076 final long origId = Binder.clearCallingIdentity();
3077 try {
3078 if (mActivityDisplay != null) {
3079 return mInputManagerInternal.injectInputEvent(event,
3080 mActivityDisplay.mDisplayId,
3081 InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
3082 }
3083 return false;
3084 } finally {
3085 Binder.restoreCallingIdentity(origId);
3086 }
3087 }
3088
Craig Mautner34b73df2014-01-12 21:11:08 -08003089 private void detachLocked() {
3090 if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display="
3091 + mActivityDisplay + " Callers=" + Debug.getCallers(2));
Craig Mautnere0a38842013-12-16 16:14:02 -08003092 if (mActivityDisplay != null) {
3093 mActivityDisplay.detachActivitiesLocked(mStack);
3094 mActivityDisplay = null;
3095 mStack.mDisplayId = -1;
3096 mStack.mStacks = null;
Craig Mautnerdf88d732014-01-27 09:21:32 -08003097 mWindowManager.detachStack(mStackId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003098 }
3099 }
3100
3101 @Override
Jeff Brownca9bc702014-02-11 14:32:56 -08003102 public void detachFromDisplay() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003103 synchronized (mService) {
3104 detachLocked();
3105 }
3106 }
3107
3108 @Override
Craig Mautnere0a38842013-12-16 16:14:02 -08003109 public final int startActivity(Intent intent) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08003110 mService.enforceNotIsolatedCaller("ActivityContainer.startActivity");
Craig Mautnere0a38842013-12-16 16:14:02 -08003111 int userId = mService.handleIncomingUser(Binder.getCallingPid(),
3112 Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null);
3113 // TODO: Switch to user app stacks here.
3114 String mimeType = intent.getType();
3115 if (mimeType == null && intent.getData() != null
3116 && "content".equals(intent.getData().getScheme())) {
3117 mimeType = mService.getProviderMimeType(intent.getData(), userId);
3118 }
3119 return startActivityMayWait(null, -1, null, intent, mimeType, null, null, 0, 0, null,
3120 null, null, null, null, userId, this);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003121 }
3122
3123 @Override
Craig Mautnerdf88d732014-01-27 09:21:32 -08003124 public final int startActivityIntentSender(IIntentSender intentSender) {
3125 mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
3126
3127 if (!(intentSender instanceof PendingIntentRecord)) {
3128 throw new IllegalArgumentException("Bad PendingIntent object");
3129 }
3130
3131 return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null,
3132 null, 0, 0, 0, null, this);
3133 }
3134
3135 @Override
Craig Mautner4a1cb222013-12-04 16:14:06 -08003136 public IBinder asBinder() {
3137 return this;
3138 }
3139
Craig Mautner4504de52013-12-20 09:06:56 -08003140 @Override
Craig Mautner34b73df2014-01-12 21:11:08 -08003141 public void attachToSurface(Surface surface, int width, int height, int density) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08003142 mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
3143
3144 final long origId = Binder.clearCallingIdentity();
3145 try {
3146 synchronized (mService) {
3147 ActivityDisplay activityDisplay =
3148 new ActivityDisplay(surface, width, height, density);
3149 mActivityDisplays.put(activityDisplay.mDisplayId, activityDisplay);
3150 attachToDisplayLocked(activityDisplay);
3151 mStack.resumeTopActivityLocked(null);
3152 }
3153 if (DEBUG_STACK) Slog.d(TAG, "attachToSurface: " + this + " to display="
3154 + mActivityDisplay);
3155 } finally {
3156 Binder.restoreCallingIdentity(origId);
Craig Mautner4504de52013-12-20 09:06:56 -08003157 }
Craig Mautner4504de52013-12-20 09:06:56 -08003158 }
3159
Craig Mautner4a1cb222013-12-04 16:14:06 -08003160 ActivityStackSupervisor getOuter() {
3161 return ActivityStackSupervisor.this;
3162 }
3163
3164 boolean isAttached() {
Craig Mautnere0a38842013-12-16 16:14:02 -08003165 return mActivityDisplay != null;
Craig Mautner4a1cb222013-12-04 16:14:06 -08003166 }
3167
3168 void getBounds(Point outBounds) {
Craig Mautnere0a38842013-12-16 16:14:02 -08003169 if (mActivityDisplay != null) {
3170 mActivityDisplay.getBounds(outBounds);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003171 } else {
3172 outBounds.set(0, 0);
3173 }
3174 }
Craig Mautner34b73df2014-01-12 21:11:08 -08003175
3176 @Override
3177 public String toString() {
3178 return mIdString + (mActivityDisplay == null ? "N" : "A");
3179 }
Craig Mautnered6649f2013-12-02 14:08:25 -08003180 }
3181
Craig Mautner4a1cb222013-12-04 16:14:06 -08003182 /** Exactly one of these classes per Display in the system. Capable of holding zero or more
3183 * attached {@link ActivityStack}s */
Craig Mautnere0a38842013-12-16 16:14:02 -08003184 final class ActivityDisplay {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003185 /** Actual Display this object tracks. */
Craig Mautner34b73df2014-01-12 21:11:08 -08003186 int mDisplayId;
3187 Display mDisplay;
3188 DisplayInfo mDisplayInfo = new DisplayInfo();
3189 Surface mSurface;
Craig Mautnered6649f2013-12-02 14:08:25 -08003190
Craig Mautner4a1cb222013-12-04 16:14:06 -08003191 /** All of the stacks on this display. Order matters, topmost stack is in front of all other
3192 * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
Craig Mautnere0a38842013-12-16 16:14:02 -08003193 final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003194
Craig Mautner4504de52013-12-20 09:06:56 -08003195 /** If this display is for an ActivityView then the VirtualDisplay created for it is stored
3196 * here. */
3197 VirtualDisplay mVirtualDisplay;
3198
Craig Mautnere0a38842013-12-16 16:14:02 -08003199 ActivityDisplay(int displayId) {
Craig Mautner34b73df2014-01-12 21:11:08 -08003200 init(mDisplayManager.getDisplay(displayId));
Craig Mautner4504de52013-12-20 09:06:56 -08003201 }
3202
Craig Mautner34b73df2014-01-12 21:11:08 -08003203 ActivityDisplay(Surface surface, int width, int height, int density) {
3204 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
3205 long ident = Binder.clearCallingIdentity();
3206 try {
3207 mVirtualDisplay = dm.createVirtualDisplay(mService.mContext,
3208 VIRTUAL_DISPLAY_BASE_NAME, width, height, density, surface,
3209 DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
3210 DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY);
3211 } finally {
3212 Binder.restoreCallingIdentity(ident);
3213 }
3214
3215 init(mVirtualDisplay.getDisplay());
3216 mSurface = surface;
3217
3218 mWindowManager.handleDisplayAdded(mDisplayId);
3219 }
3220
3221 private void init(Display display) {
Craig Mautner4504de52013-12-20 09:06:56 -08003222 mDisplay = display;
3223 mDisplayId = display.getDisplayId();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003224 mDisplay.getDisplayInfo(mDisplayInfo);
Craig Mautnered6649f2013-12-02 14:08:25 -08003225 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08003226
3227 void attachActivities(ActivityStack stack) {
Craig Mautnere0a38842013-12-16 16:14:02 -08003228 if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId="
3229 + mDisplayId);
3230 mStacks.add(stack);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003231 }
3232
Craig Mautnere0a38842013-12-16 16:14:02 -08003233 void detachActivitiesLocked(ActivityStack stack) {
Craig Mautner34b73df2014-01-12 21:11:08 -08003234 if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack
Craig Mautnere0a38842013-12-16 16:14:02 -08003235 + " from displayId=" + mDisplayId);
3236 mStacks.remove(stack);
Craig Mautner34b73df2014-01-12 21:11:08 -08003237 if (mStacks.isEmpty() && mVirtualDisplay != null) {
3238 mVirtualDisplay.release();
3239 mVirtualDisplay = null;
3240 }
3241 mSurface.release();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003242 }
3243
3244 void getBounds(Point bounds) {
3245 mDisplay.getDisplayInfo(mDisplayInfo);
3246 bounds.x = mDisplayInfo.appWidth;
3247 bounds.y = mDisplayInfo.appHeight;
3248 }
Craig Mautner34b73df2014-01-12 21:11:08 -08003249
3250 @Override
3251 public String toString() {
3252 return "ActivityDisplay={" + mDisplayId + (mVirtualDisplay == null ? "" : "V")
3253 + " numStacks=" + mStacks.size() + "}";
3254 }
Craig Mautnered6649f2013-12-02 14:08:25 -08003255 }
Craig Mautner27084302013-03-25 08:05:25 -07003256}