blob: 91915c1751139d01dc94029f723c90c4291626de [file] [log] [blame]
Craig Mautner27084302013-03-25 08:05:25 -07001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
Craig Mautner6170f732013-04-02 13:05:23 -070019import static android.Manifest.permission.START_ANY_ACTIVITY;
Craig Mautner29219d92013-04-16 20:19:12 -070020import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
21import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
Craig Mautner6170f732013-04-02 13:05:23 -070022import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Craig Mautner2420ead2013-04-01 17:13:20 -070023import static com.android.server.am.ActivityManagerService.localLOGV;
Craig Mautner23ac33b2013-04-01 16:26:35 -070024import static com.android.server.am.ActivityManagerService.DEBUG_CONFIGURATION;
Craig Mautnere7c58b62013-06-12 20:19:00 -070025import static com.android.server.am.ActivityManagerService.DEBUG_FOCUS;
Craig Mautner0eea92c2013-05-16 13:35:39 -070026import static com.android.server.am.ActivityManagerService.DEBUG_PAUSE;
Craig Mautner6170f732013-04-02 13:05:23 -070027import static com.android.server.am.ActivityManagerService.DEBUG_RESULTS;
Craig Mautner0eea92c2013-05-16 13:35:39 -070028import static com.android.server.am.ActivityManagerService.DEBUG_STACK;
Craig Mautner2420ead2013-04-01 17:13:20 -070029import static com.android.server.am.ActivityManagerService.DEBUG_SWITCH;
Craig Mautner8849a5e2013-04-02 16:41:03 -070030import static com.android.server.am.ActivityManagerService.DEBUG_TASKS;
31import static com.android.server.am.ActivityManagerService.DEBUG_USER_LEAVING;
Craig Mautner05d29032013-05-03 13:40:13 -070032import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
Craig Mautner8d341ef2013-03-26 09:03:27 -070033import static com.android.server.am.ActivityManagerService.TAG;
34
Craig Mautner2420ead2013-04-01 17:13:20 -070035import android.app.Activity;
Craig Mautner23ac33b2013-04-01 16:26:35 -070036import android.app.ActivityManager;
Craig Mautnerbdc748af2013-12-02 14:08:25 -080037import android.app.ActivityManager.StackInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070038import android.app.ActivityOptions;
39import android.app.AppGlobals;
Craig Mautner4a1cb222013-12-04 16:14:06 -080040import android.app.IActivityContainer;
41import android.app.IActivityContainerCallback;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070042import android.app.IActivityManager;
Craig Mautner23ac33b2013-04-01 16:26:35 -070043import android.app.IApplicationThread;
Craig Mautner20e72272013-04-01 13:45:53 -070044import android.app.IThumbnailReceiver;
Craig Mautner23ac33b2013-04-01 16:26:35 -070045import android.app.PendingIntent;
Craig Mautner20e72272013-04-01 13:45:53 -070046import android.app.ActivityManager.RunningTaskInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070047import android.app.IActivityManager.WaitResult;
Craig Mautner2420ead2013-04-01 17:13:20 -070048import android.app.ResultInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070049import android.content.ComponentName;
Craig Mautner2219a1b2013-03-25 09:44:30 -070050import android.content.Context;
Craig Mautner23ac33b2013-04-01 16:26:35 -070051import android.content.IIntentSender;
Craig Mautner2219a1b2013-03-25 09:44:30 -070052import android.content.Intent;
Craig Mautner23ac33b2013-04-01 16:26:35 -070053import android.content.IntentSender;
Craig Mautner2219a1b2013-03-25 09:44:30 -070054import android.content.pm.ActivityInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070055import android.content.pm.ApplicationInfo;
56import android.content.pm.PackageManager;
57import android.content.pm.ResolveInfo;
58import android.content.res.Configuration;
Craig Mautner4a1cb222013-12-04 16:14:06 -080059import android.graphics.Point;
60import android.hardware.display.DisplayManager;
61import android.hardware.display.DisplayManager.DisplayListener;
Craig Mautner4504de52013-12-20 09:06:56 -080062import android.hardware.display.DisplayManagerGlobal;
63import android.hardware.display.VirtualDisplay;
Jeff Brown38f96e52014-02-11 14:32:56 -080064import android.hardware.input.InputManager;
65import android.hardware.input.InputManagerInternal;
Craig Mautner23ac33b2013-04-01 16:26:35 -070066import android.os.Binder;
Craig Mautner8d341ef2013-03-26 09:03:27 -070067import android.os.Bundle;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -070068import android.os.Debug;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070069import android.os.Handler;
Craig Mautner23ac33b2013-04-01 16:26:35 -070070import android.os.IBinder;
Craig Mautner2219a1b2013-03-25 09:44:30 -070071import android.os.Looper;
Craig Mautner2420ead2013-04-01 17:13:20 -070072import android.os.Message;
Craig Mautner23ac33b2013-04-01 16:26:35 -070073import android.os.ParcelFileDescriptor;
Craig Mautner0eea92c2013-05-16 13:35:39 -070074import android.os.PowerManager;
Craig Mautner7ea5bd42013-07-05 15:27:08 -070075import android.os.Process;
Craig Mautner8d341ef2013-03-26 09:03:27 -070076import android.os.RemoteException;
Craig Mautner23ac33b2013-04-01 16:26:35 -070077import android.os.SystemClock;
Craig Mautner6170f732013-04-02 13:05:23 -070078import android.os.UserHandle;
Craig Mautner2420ead2013-04-01 17:13:20 -070079import android.util.EventLog;
Craig Mautner8d341ef2013-03-26 09:03:27 -070080import android.util.Slog;
Craig Mautner4a1cb222013-12-04 16:14:06 -080081import android.util.SparseArray;
Craig Mautner2219a1b2013-03-25 09:44:30 -070082
Craig Mautner4a1cb222013-12-04 16:14:06 -080083import android.util.SparseIntArray;
Craig Mautnerbdc748af2013-12-02 14:08:25 -080084import android.view.Display;
Craig Mautner4a1cb222013-12-04 16:14:06 -080085import android.view.DisplayInfo;
Jeff Brown38f96e52014-02-11 14:32:56 -080086import android.view.InputEvent;
Craig Mautner4504de52013-12-20 09:06:56 -080087import android.view.Surface;
Craig Mautner23ac33b2013-04-01 16:26:35 -070088import com.android.internal.app.HeavyWeightSwitcherActivity;
Dianne Hackborncbfd23e2013-06-11 14:26:53 -070089import com.android.internal.os.TransferPipe;
Jeff Brown38f96e52014-02-11 14:32:56 -080090import com.android.server.LocalServices;
Craig Mautner2420ead2013-04-01 17:13:20 -070091import com.android.server.am.ActivityStack.ActivityState;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070092import com.android.server.wm.WindowManagerService;
Craig Mautner23ac33b2013-04-01 16:26:35 -070093
Craig Mautner8d341ef2013-03-26 09:03:27 -070094import java.io.FileDescriptor;
95import java.io.IOException;
Craig Mautner27084302013-03-25 08:05:25 -070096import java.io.PrintWriter;
Craig Mautner2219a1b2013-03-25 09:44:30 -070097import java.util.ArrayList;
Craig Mautner8d341ef2013-03-26 09:03:27 -070098import java.util.List;
Craig Mautner27084302013-03-25 08:05:25 -070099
Craig Mautner4a1cb222013-12-04 16:14:06 -0800100public final class ActivityStackSupervisor implements DisplayListener {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700101 static final boolean DEBUG = ActivityManagerService.DEBUG || false;
102 static final boolean DEBUG_ADD_REMOVE = DEBUG || false;
103 static final boolean DEBUG_APP = DEBUG || false;
104 static final boolean DEBUG_SAVED_STATE = DEBUG || false;
Craig Mautnera7f2bd42013-10-15 16:13:50 -0700105 static final boolean DEBUG_STATES = DEBUG || false;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -0700106 static final boolean DEBUG_IDLE = DEBUG || false;
Craig Mautner6335fbc2014-06-13 17:18:47 -0700107 static final boolean DEBUG_CONTAINERS = DEBUG || false;
Craig Mautner2420ead2013-04-01 17:13:20 -0700108
Craig Mautner2219a1b2013-03-25 09:44:30 -0700109 public static final int HOME_STACK_ID = 0;
Craig Mautner27084302013-03-25 08:05:25 -0700110
Craig Mautnerf3333272013-04-22 10:55:53 -0700111 /** How long we wait until giving up on the last activity telling us it is idle. */
112 static final int IDLE_TIMEOUT = 10*1000;
113
Craig Mautner0eea92c2013-05-16 13:35:39 -0700114 /** How long we can hold the sleep wake lock before giving up. */
115 static final int SLEEP_TIMEOUT = 5*1000;
116
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700117 // How long we can hold the launch wake lock before giving up.
118 static final int LAUNCH_TIMEOUT = 10*1000;
119
Craig Mautner05d29032013-05-03 13:40:13 -0700120 static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG;
121 static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1;
122 static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2;
Craig Mautner0eea92c2013-05-16 13:35:39 -0700123 static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3;
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700124 static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800125 static final int HANDLE_DISPLAY_ADDED = FIRST_SUPERVISOR_STACK_MSG + 5;
126 static final int HANDLE_DISPLAY_CHANGED = FIRST_SUPERVISOR_STACK_MSG + 6;
127 static final int HANDLE_DISPLAY_REMOVED = FIRST_SUPERVISOR_STACK_MSG + 7;
Craig Mautnere3a00d72014-04-16 08:31:19 -0700128 static final int CONTAINER_CALLBACK_VISIBILITY = FIRST_SUPERVISOR_STACK_MSG + 8;
Craig Mautnerd94b47f2014-06-02 15:06:40 -0700129 static final int CONTAINER_CALLBACK_TASK_LIST_EMPTY = FIRST_SUPERVISOR_STACK_MSG + 9;
Craig Mautner6335fbc2014-06-13 17:18:47 -0700130 static final int CONTAINER_TASK_LIST_EMPTY_TIMEOUT = FIRST_SUPERVISOR_STACK_MSG + 10;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800131
Craig Mautner4504de52013-12-20 09:06:56 -0800132 private final static String VIRTUAL_DISPLAY_BASE_NAME = "ActivityViewVirtualDisplay";
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700133
134 // For debugging to make sure the caller when acquiring/releasing our
135 // wake lock is the system process.
136 static final boolean VALIDATE_WAKE_LOCK_CALLER = false;
Craig Mautnerf3333272013-04-22 10:55:53 -0700137
Craig Mautner27084302013-03-25 08:05:25 -0700138 final ActivityManagerService mService;
139
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700140 final ActivityStackSupervisorHandler mHandler;
141
142 /** Short cut */
143 WindowManagerService mWindowManager;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800144 DisplayManager mDisplayManager;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700145
Craig Mautner27084302013-03-25 08:05:25 -0700146 /** Dismiss the keyguard after the next activity is displayed? */
Craig Mautner5314a402013-09-26 12:40:16 -0700147 boolean mDismissKeyguardOnNextActivity = false;
Craig Mautner27084302013-03-25 08:05:25 -0700148
Craig Mautner8d341ef2013-03-26 09:03:27 -0700149 /** Identifier counter for all ActivityStacks */
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -0700150 private int mLastStackId = HOME_STACK_ID;
Craig Mautner8d341ef2013-03-26 09:03:27 -0700151
152 /** Task identifier that activities are currently being started in. Incremented each time a
153 * new task is created. */
154 private int mCurTaskId = 0;
155
Craig Mautner2420ead2013-04-01 17:13:20 -0700156 /** The current user */
157 private int mCurrentUser;
158
Craig Mautnere0a38842013-12-16 16:14:02 -0800159 /** The stack containing the launcher app. Assumed to always be attached to
160 * Display.DEFAULT_DISPLAY. */
Craig Mautner2219a1b2013-03-25 09:44:30 -0700161 private ActivityStack mHomeStack;
Craig Mautner20e72272013-04-01 13:45:53 -0700162
Craig Mautnere0a38842013-12-16 16:14:02 -0800163 /** The stack currently receiving input or launching the next activity. */
Craig Mautner29219d92013-04-16 20:19:12 -0700164 private ActivityStack mFocusedStack;
Craig Mautner8d341ef2013-03-26 09:03:27 -0700165
Craig Mautner4a1cb222013-12-04 16:14:06 -0800166 /** If this is the same as mFocusedStack then the activity on the top of the focused stack has
167 * been resumed. If stacks are changing position this will hold the old stack until the new
Craig Mautnere0a38842013-12-16 16:14:02 -0800168 * stack becomes resumed after which it will be set to mFocusedStack. */
Craig Mautner4a1cb222013-12-04 16:14:06 -0800169 private ActivityStack mLastFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700170
171 /** List of activities that are waiting for a new activity to become visible before completing
172 * whatever operation they are supposed to do. */
173 final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<ActivityRecord>();
174
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700175 /** List of processes waiting to find out about the next visible activity. */
176 final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible =
177 new ArrayList<IActivityManager.WaitResult>();
178
179 /** List of processes waiting to find out about the next launched activity. */
180 final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched =
181 new ArrayList<IActivityManager.WaitResult>();
182
Craig Mautnerde4ef022013-04-07 19:01:33 -0700183 /** List of activities that are ready to be stopped, but waiting for the next activity to
184 * settle down before doing so. */
185 final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<ActivityRecord>();
186
Craig Mautnerf3333272013-04-22 10:55:53 -0700187 /** List of activities that are ready to be finished, but waiting for the previous activity to
188 * settle down before doing so. It contains ActivityRecord objects. */
189 final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<ActivityRecord>();
190
Craig Mautner0eea92c2013-05-16 13:35:39 -0700191 /** List of activities that are in the process of going to sleep. */
192 final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<ActivityRecord>();
193
Craig Mautnerf3333272013-04-22 10:55:53 -0700194 /** List of ActivityRecord objects that have been finished and must still report back to a
195 * pending thumbnail receiver. */
196 final ArrayList<ActivityRecord> mCancelledThumbnails = new ArrayList<ActivityRecord>();
197
198 /** Used on user changes */
199 final ArrayList<UserStartedState> mStartingUsers = new ArrayList<UserStartedState>();
200
Craig Mautnerde4ef022013-04-07 19:01:33 -0700201 /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity
202 * is being brought in front of us. */
203 boolean mUserLeaving = false;
204
Craig Mautner0eea92c2013-05-16 13:35:39 -0700205 /** Set when we have taken too long waiting to go to sleep. */
206 boolean mSleepTimeout = false;
207
208 /**
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700209 * We don't want to allow the device to go to sleep while in the process
210 * of launching an activity. This is primarily to allow alarm intent
211 * receivers to launch an activity and get that to run before the device
212 * goes back to sleep.
213 */
214 final PowerManager.WakeLock mLaunchingActivity;
215
216 /**
Craig Mautner0eea92c2013-05-16 13:35:39 -0700217 * Set when the system is going to sleep, until we have
218 * successfully paused the current activity and released our wake lock.
219 * At that point the system is allowed to actually sleep.
220 */
221 final PowerManager.WakeLock mGoingToSleep;
222
Craig Mautner4f1df4f2013-10-15 15:44:14 -0700223 /** Stack id of the front stack when user switched, indexed by userId. */
224 SparseIntArray mUserStackInFront = new SparseIntArray(2);
Craig Mautner93529a42013-10-04 15:03:13 -0700225
Craig Mautner4504de52013-12-20 09:06:56 -0800226 // TODO: Add listener for removal of references.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800227 /** Mapping from (ActivityStack/TaskStack).mStackId to their current state */
Craig Mautner6335fbc2014-06-13 17:18:47 -0700228 private SparseArray<ActivityContainer> mActivityContainers = new SparseArray<ActivityContainer>();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800229
230 /** Mapping from displayId to display current state */
Craig Mautnerf4c909b2014-04-17 18:39:38 -0700231 private final SparseArray<ActivityDisplay> mActivityDisplays =
232 new SparseArray<ActivityDisplay>();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800233
Jeff Brown38f96e52014-02-11 14:32:56 -0800234 InputManagerInternal mInputManagerInternal;
235
Craig Mautneree36c772014-07-16 14:56:05 -0700236 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
237 = new ArrayList<PendingActivityLaunch>();
238
239 /**
240 * Description of a request to start a new activity, which has been held
241 * due to app switches being disabled.
242 */
243 static class PendingActivityLaunch {
244 final ActivityRecord r;
245 final ActivityRecord sourceRecord;
246 final int startFlags;
247 final ActivityStack stack;
248
249 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
250 int _startFlags, ActivityStack _stack) {
251 r = _r;
252 sourceRecord = _sourceRecord;
253 startFlags = _startFlags;
254 stack = _stack;
255 }
256 }
257
Craig Mautner4a1cb222013-12-04 16:14:06 -0800258 public ActivityStackSupervisor(ActivityManagerService service) {
Craig Mautner27084302013-03-25 08:05:25 -0700259 mService = service;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800260 PowerManager pm = (PowerManager)mService.mContext.getSystemService(Context.POWER_SERVICE);
Craig Mautner0eea92c2013-05-16 13:35:39 -0700261 mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
Craig Mautner4a1cb222013-12-04 16:14:06 -0800262 mHandler = new ActivityStackSupervisorHandler(mService.mHandler.getLooper());
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700263 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
264 throw new IllegalStateException("Calling must be system uid");
265 }
266 mLaunchingActivity =
267 pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
268 mLaunchingActivity.setReferenceCounted(false);
Craig Mautner2219a1b2013-03-25 09:44:30 -0700269 }
270
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700271 void setWindowManager(WindowManagerService wm) {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800272 synchronized (mService) {
273 mWindowManager = wm;
274
275 mDisplayManager =
276 (DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE);
277 mDisplayManager.registerDisplayListener(this, null);
278
279 Display[] displays = mDisplayManager.getDisplays();
280 for (int displayNdx = displays.length - 1; displayNdx >= 0; --displayNdx) {
281 final int displayId = displays[displayNdx].getDisplayId();
Craig Mautnere0a38842013-12-16 16:14:02 -0800282 ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
283 mActivityDisplays.put(displayId, activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -0800284 }
285
Craig Mautnerf4c909b2014-04-17 18:39:38 -0700286 createStackOnDisplay(HOME_STACK_ID, Display.DEFAULT_DISPLAY);
Craig Mautner4a1cb222013-12-04 16:14:06 -0800287 mHomeStack = mFocusedStack = mLastFocusedStack = getStack(HOME_STACK_ID);
Jeff Brown38f96e52014-02-11 14:32:56 -0800288
289 mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
Craig Mautner4a1cb222013-12-04 16:14:06 -0800290 }
Craig Mautner27084302013-03-25 08:05:25 -0700291 }
292
293 void dismissKeyguard() {
Craig Mautner5314a402013-09-26 12:40:16 -0700294 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen("");
Craig Mautner27084302013-03-25 08:05:25 -0700295 if (mDismissKeyguardOnNextActivity) {
296 mDismissKeyguardOnNextActivity = false;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700297 mWindowManager.dismissKeyguard();
Craig Mautner27084302013-03-25 08:05:25 -0700298 }
299 }
300
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700301 ActivityStack getFocusedStack() {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800302 return mFocusedStack;
Craig Mautner20e72272013-04-01 13:45:53 -0700303 }
304
Craig Mautnerde4ef022013-04-07 19:01:33 -0700305 ActivityStack getLastStack() {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800306 return mLastFocusedStack;
Craig Mautner2219a1b2013-03-25 09:44:30 -0700307 }
308
Craig Mautner4a1cb222013-12-04 16:14:06 -0800309 // TODO: Split into two methods isFrontStack for any visible stack and isFrontmostStack for the
310 // top of all visible stacks.
Craig Mautnerde4ef022013-04-07 19:01:33 -0700311 boolean isFrontStack(ActivityStack stack) {
Craig Mautnerdf88d732014-01-27 09:21:32 -0800312 final ActivityRecord parent = stack.mActivityContainer.mParentActivity;
313 if (parent != null) {
314 stack = parent.task.stack;
315 }
Craig Mautnere0a38842013-12-16 16:14:02 -0800316 ArrayList<ActivityStack> stacks = stack.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800317 if (stacks != null && !stacks.isEmpty()) {
318 return stack == stacks.get(stacks.size() - 1);
319 }
320 return false;
Craig Mautner20e72272013-04-01 13:45:53 -0700321 }
322
Craig Mautnerde4ef022013-04-07 19:01:33 -0700323 void moveHomeStack(boolean toFront) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800324 ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800325 int topNdx = stacks.size() - 1;
326 if (topNdx <= 0) {
327 return;
328 }
329 ActivityStack topStack = stacks.get(topNdx);
330 final boolean homeInFront = topStack == mHomeStack;
331 if (homeInFront != toFront) {
332 mLastFocusedStack = topStack;
333 stacks.remove(mHomeStack);
334 stacks.add(toFront ? topNdx : 0, mHomeStack);
335 mFocusedStack = stacks.get(topNdx);
336 if (DEBUG_STACK) Slog.d(TAG, "moveHomeTask: topStack old=" + topStack + " new="
337 + mFocusedStack);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700338 }
339 }
340
Craig Mautner8e569572013-10-11 17:36:59 -0700341 void moveHomeToTop() {
Craig Mautner69ada552013-04-18 13:51:51 -0700342 moveHomeStack(true);
Craig Mautner8e569572013-10-11 17:36:59 -0700343 mHomeStack.moveHomeTaskToTop();
344 }
345
346 boolean resumeHomeActivity(ActivityRecord prev) {
347 moveHomeToTop();
Craig Mautner69ada552013-04-18 13:51:51 -0700348 if (prev != null) {
Craig Mautnerae7ecab2013-09-18 11:48:14 -0700349 prev.task.mOnTopOfHome = false;
Craig Mautner69ada552013-04-18 13:51:51 -0700350 }
Craig Mautnera8a90e02013-06-28 15:24:50 -0700351 ActivityRecord r = mHomeStack.topRunningActivityLocked(null);
Craig Mautner760b2312013-10-11 11:57:07 -0700352 if (r != null && r.isHomeActivity()) {
Craig Mautnera8a90e02013-06-28 15:24:50 -0700353 mService.setFocusedActivityLocked(r);
Craig Mautner05d29032013-05-03 13:40:13 -0700354 return resumeTopActivitiesLocked(mHomeStack, prev, null);
Craig Mautner69ada552013-04-18 13:51:51 -0700355 }
356 return mService.startHomeActivityLocked(mCurrentUser);
357 }
358
Craig Mautner27084302013-03-25 08:05:25 -0700359 void setDismissKeyguard(boolean dismiss) {
Craig Mautner5314a402013-09-26 12:40:16 -0700360 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen(" dismiss=" + dismiss);
Craig Mautner27084302013-03-25 08:05:25 -0700361 mDismissKeyguardOnNextActivity = dismiss;
362 }
363
Craig Mautner8d341ef2013-03-26 09:03:27 -0700364 TaskRecord anyTaskForIdLocked(int id) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800365 int numDisplays = mActivityDisplays.size();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800366 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800367 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800368 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
369 ActivityStack stack = stacks.get(stackNdx);
370 TaskRecord task = stack.taskForIdLocked(id);
371 if (task != null) {
372 return task;
373 }
Craig Mautner8d341ef2013-03-26 09:03:27 -0700374 }
375 }
376 return null;
377 }
378
Craig Mautner6170f732013-04-02 13:05:23 -0700379 ActivityRecord isInAnyStackLocked(IBinder token) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800380 int numDisplays = mActivityDisplays.size();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800381 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800382 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800383 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
384 final ActivityRecord r = stacks.get(stackNdx).isInStackLocked(token);
385 if (r != null) {
386 return r;
387 }
Craig Mautner6170f732013-04-02 13:05:23 -0700388 }
389 }
390 return null;
391 }
392
Craig Mautner8d341ef2013-03-26 09:03:27 -0700393 int getNextTaskId() {
394 do {
395 mCurTaskId++;
396 if (mCurTaskId <= 0) {
397 mCurTaskId = 1;
398 }
399 } while (anyTaskForIdLocked(mCurTaskId) != null);
400 return mCurTaskId;
401 }
402
Craig Mautnerde4ef022013-04-07 19:01:33 -0700403 ActivityRecord resumedAppLocked() {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700404 ActivityStack stack = getFocusedStack();
405 if (stack == null) {
406 return null;
407 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700408 ActivityRecord resumedActivity = stack.mResumedActivity;
409 if (resumedActivity == null || resumedActivity.app == null) {
410 resumedActivity = stack.mPausingActivity;
411 if (resumedActivity == null || resumedActivity.app == null) {
412 resumedActivity = stack.topRunningActivityLocked(null);
413 }
414 }
415 return resumedActivity;
416 }
417
Mike Lockwoode63f6f72013-11-15 11:01:47 -0800418 boolean attachApplicationLocked(ProcessRecord app) throws Exception {
Craig Mautner20e72272013-04-01 13:45:53 -0700419 final String processName = app.processName;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800420 boolean didSomething = false;
Craig Mautnere0a38842013-12-16 16:14:02 -0800421 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
422 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800423 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
424 final ActivityStack stack = stacks.get(stackNdx);
425 if (!isFrontStack(stack)) {
426 continue;
427 }
428 ActivityRecord hr = stack.topRunningActivityLocked(null);
429 if (hr != null) {
430 if (hr.app == null && app.uid == hr.info.applicationInfo.uid
431 && processName.equals(hr.processName)) {
432 try {
433 if (realStartActivityLocked(hr, app, true, true)) {
434 didSomething = true;
435 }
436 } catch (Exception e) {
437 Slog.w(TAG, "Exception in new application when starting activity "
438 + hr.intent.getComponent().flattenToShortString(), e);
439 throw e;
Craig Mautner20e72272013-04-01 13:45:53 -0700440 }
Craig Mautner20e72272013-04-01 13:45:53 -0700441 }
Craig Mautner20e72272013-04-01 13:45:53 -0700442 }
443 }
444 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -0700445 if (!didSomething) {
446 ensureActivitiesVisibleLocked(null, 0);
447 }
Craig Mautner20e72272013-04-01 13:45:53 -0700448 return didSomething;
449 }
450
451 boolean allResumedActivitiesIdle() {
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);
Craig Mautner34b73df2014-01-12 21:11:08 -0800456 if (!isFrontStack(stack) || stack.numActivities() == 0) {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800457 continue;
458 }
459 final ActivityRecord resumedActivity = stack.mResumedActivity;
460 if (resumedActivity == null || !resumedActivity.idle) {
Craig Mautner34b73df2014-01-12 21:11:08 -0800461 if (DEBUG_STATES) Slog.d(TAG, "allResumedActivitiesIdle: stack="
462 + stack.mStackId + " " + resumedActivity + " not idle");
Craig Mautner4a1cb222013-12-04 16:14:06 -0800463 return false;
464 }
Craig Mautner20e72272013-04-01 13:45:53 -0700465 }
466 }
467 return true;
468 }
469
Craig Mautnerde4ef022013-04-07 19:01:33 -0700470 boolean allResumedActivitiesComplete() {
Craig Mautnere0a38842013-12-16 16:14:02 -0800471 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
472 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800473 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
474 final ActivityStack stack = stacks.get(stackNdx);
475 if (isFrontStack(stack)) {
476 final ActivityRecord r = stack.mResumedActivity;
477 if (r != null && r.state != ActivityState.RESUMED) {
478 return false;
479 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700480 }
481 }
482 }
483 // TODO: Not sure if this should check if all Paused are complete too.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800484 if (DEBUG_STACK) Slog.d(TAG,
485 "allResumedActivitiesComplete: mLastFocusedStack changing from=" +
486 mLastFocusedStack + " to=" + mFocusedStack);
487 mLastFocusedStack = mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700488 return true;
489 }
490
491 boolean allResumedActivitiesVisible() {
Craig Mautnere0a38842013-12-16 16:14:02 -0800492 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
493 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800494 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
495 final ActivityStack stack = stacks.get(stackNdx);
496 final ActivityRecord r = stack.mResumedActivity;
497 if (r != null && (!r.nowVisible || r.waitingVisible)) {
498 return false;
499 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700500 }
501 }
502 return true;
503 }
504
Craig Mautner2acc3892013-09-23 10:28:14 -0700505 /**
506 * Pause all activities in either all of the stacks or just the back stacks.
507 * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving().
Craig Mautner2acc3892013-09-23 10:28:14 -0700508 * @return true if any activity was paused as a result of this call.
509 */
Craig Mautner5314a402013-09-26 12:40:16 -0700510 boolean pauseBackStacks(boolean userLeaving) {
Craig Mautnercf910b02013-04-23 11:23:27 -0700511 boolean someActivityPaused = false;
Craig Mautnere0a38842013-12-16 16:14:02 -0800512 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
513 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800514 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
515 final ActivityStack stack = stacks.get(stackNdx);
516 if (!isFrontStack(stack) && stack.mResumedActivity != null) {
517 if (DEBUG_STATES) Slog.d(TAG, "pauseBackStacks: stack=" + stack +
518 " mResumedActivity=" + stack.mResumedActivity);
519 stack.startPausingLocked(userLeaving, false);
520 someActivityPaused = true;
521 }
Craig Mautnercf910b02013-04-23 11:23:27 -0700522 }
523 }
524 return someActivityPaused;
525 }
526
Craig Mautnerde4ef022013-04-07 19:01:33 -0700527 boolean allPausedActivitiesComplete() {
Craig Mautnerac6f8432013-07-17 13:24:59 -0700528 boolean pausing = true;
Craig Mautnere0a38842013-12-16 16:14:02 -0800529 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
530 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800531 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
532 final ActivityStack stack = stacks.get(stackNdx);
533 final ActivityRecord r = stack.mPausingActivity;
534 if (r != null && r.state != ActivityState.PAUSED
535 && r.state != ActivityState.STOPPED
536 && r.state != ActivityState.STOPPING) {
537 if (DEBUG_STATES) {
538 Slog.d(TAG, "allPausedActivitiesComplete: r=" + r + " state=" + r.state);
539 pausing = false;
540 } else {
541 return false;
542 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700543 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700544 }
545 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700546 return pausing;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700547 }
548
Craig Mautnerdf88d732014-01-27 09:21:32 -0800549 void pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping) {
Craig Mautnerd94b47f2014-06-02 15:06:40 -0700550 // TODO: Put all stacks in supervisor and iterate through them instead.
Craig Mautnerdf88d732014-01-27 09:21:32 -0800551 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
552 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
553 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
554 final ActivityStack stack = stacks.get(stackNdx);
555 if (stack.mResumedActivity != null &&
556 stack.mActivityContainer.mParentActivity == parent) {
557 stack.startPausingLocked(userLeaving, uiSleeping);
558 }
559 }
560 }
561 }
562
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700563 void reportActivityVisibleLocked(ActivityRecord r) {
Craig Mautner858d8a62013-04-23 17:08:34 -0700564 for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700565 WaitResult w = mWaitingActivityVisible.get(i);
566 w.timeout = false;
567 if (r != null) {
568 w.who = new ComponentName(r.info.packageName, r.info.name);
569 }
570 w.totalTime = SystemClock.uptimeMillis() - w.thisTime;
571 w.thisTime = w.totalTime;
572 }
573 mService.notifyAll();
574 dismissKeyguard();
575 }
576
577 void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r,
578 long thisTime, long totalTime) {
579 for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
Craig Mautnerc64f73e2013-04-24 16:44:56 -0700580 WaitResult w = mWaitingActivityLaunched.remove(i);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700581 w.timeout = timeout;
582 if (r != null) {
583 w.who = new ComponentName(r.info.packageName, r.info.name);
584 }
585 w.thisTime = thisTime;
586 w.totalTime = totalTime;
587 }
588 mService.notifyAll();
589 }
590
Craig Mautner29219d92013-04-16 20:19:12 -0700591 ActivityRecord topRunningActivityLocked() {
Craig Mautner1602ec22013-05-12 10:24:27 -0700592 final ActivityStack focusedStack = getFocusedStack();
593 ActivityRecord r = focusedStack.topRunningActivityLocked(null);
594 if (r != null) {
595 return r;
Craig Mautner29219d92013-04-16 20:19:12 -0700596 }
Craig Mautner1602ec22013-05-12 10:24:27 -0700597
Craig Mautner4a1cb222013-12-04 16:14:06 -0800598 // Return to the home stack.
Craig Mautnere0a38842013-12-16 16:14:02 -0800599 final ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800600 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
601 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautnerac6f8432013-07-17 13:24:59 -0700602 if (stack != focusedStack && isFrontStack(stack)) {
Craig Mautner29219d92013-04-16 20:19:12 -0700603 r = stack.topRunningActivityLocked(null);
604 if (r != null) {
605 return r;
606 }
607 }
608 }
609 return null;
610 }
611
Craig Mautner20e72272013-04-01 13:45:53 -0700612 ActivityRecord getTasksLocked(int maxNum, IThumbnailReceiver receiver,
613 PendingThumbnailsRecord pending, List<RunningTaskInfo> list) {
614 ActivityRecord r = null;
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700615
616 // Gather all of the running tasks for each stack into runningTaskLists.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800617 ArrayList<ArrayList<RunningTaskInfo>> runningTaskLists =
618 new ArrayList<ArrayList<RunningTaskInfo>>();
Craig Mautnere0a38842013-12-16 16:14:02 -0800619 final int numDisplays = mActivityDisplays.size();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800620 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800621 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800622 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
623 final ActivityStack stack = stacks.get(stackNdx);
624 ArrayList<RunningTaskInfo> stackTaskList = new ArrayList<RunningTaskInfo>();
625 runningTaskLists.add(stackTaskList);
626 final ActivityRecord ar = stack.getTasksLocked(receiver, pending, stackTaskList);
627 if (r == null && isFrontStack(stack)) {
628 r = ar;
629 }
Craig Mautner20e72272013-04-01 13:45:53 -0700630 }
631 }
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700632
633 // The lists are already sorted from most recent to oldest. Just pull the most recent off
634 // each list and add it to list. Stop when all lists are empty or maxNum reached.
635 while (maxNum > 0) {
636 long mostRecentActiveTime = Long.MIN_VALUE;
637 ArrayList<RunningTaskInfo> selectedStackList = null;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800638 final int numTaskLists = runningTaskLists.size();
639 for (int stackNdx = 0; stackNdx < numTaskLists; ++stackNdx) {
640 ArrayList<RunningTaskInfo> stackTaskList = runningTaskLists.get(stackNdx);
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700641 if (!stackTaskList.isEmpty()) {
642 final long lastActiveTime = stackTaskList.get(0).lastActiveTime;
643 if (lastActiveTime > mostRecentActiveTime) {
644 mostRecentActiveTime = lastActiveTime;
645 selectedStackList = stackTaskList;
646 }
647 }
648 }
649 if (selectedStackList != null) {
650 list.add(selectedStackList.remove(0));
651 --maxNum;
652 } else {
653 break;
654 }
655 }
656
Craig Mautner20e72272013-04-01 13:45:53 -0700657 return r;
658 }
659
Craig Mautner23ac33b2013-04-01 16:26:35 -0700660 ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
661 String profileFile, ParcelFileDescriptor profileFd, int userId) {
662 // Collect information about the target of the Intent.
663 ActivityInfo aInfo;
664 try {
665 ResolveInfo rInfo =
666 AppGlobals.getPackageManager().resolveIntent(
667 intent, resolvedType,
668 PackageManager.MATCH_DEFAULT_ONLY
669 | ActivityManagerService.STOCK_PM_FLAGS, userId);
670 aInfo = rInfo != null ? rInfo.activityInfo : null;
671 } catch (RemoteException e) {
672 aInfo = null;
673 }
674
675 if (aInfo != null) {
676 // Store the found target back into the intent, because now that
677 // we have it we never want to do this again. For example, if the
678 // user navigates back to this point in the history, we should
679 // always restart the exact same activity.
680 intent.setComponent(new ComponentName(
681 aInfo.applicationInfo.packageName, aInfo.name));
682
683 // Don't debug things in the system process
684 if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) {
685 if (!aInfo.processName.equals("system")) {
686 mService.setDebugApp(aInfo.processName, true, false);
687 }
688 }
689
690 if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) {
691 if (!aInfo.processName.equals("system")) {
692 mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName);
693 }
694 }
695
696 if (profileFile != null) {
697 if (!aInfo.processName.equals("system")) {
698 mService.setProfileApp(aInfo.applicationInfo, aInfo.processName,
699 profileFile, profileFd,
700 (startFlags&ActivityManager.START_FLAG_AUTO_STOP_PROFILER) != 0);
701 }
702 }
703 }
704 return aInfo;
705 }
706
Craig Mautner2219a1b2013-03-25 09:44:30 -0700707 void startHomeActivity(Intent intent, ActivityInfo aInfo) {
Craig Mautner8e569572013-10-11 17:36:59 -0700708 moveHomeToTop();
Craig Mautner6170f732013-04-02 13:05:23 -0700709 startActivityLocked(null, intent, null, aInfo, null, null, 0, 0, 0, null, 0,
Craig Mautnere0a38842013-12-16 16:14:02 -0800710 null, false, null, null);
Craig Mautner8d341ef2013-03-26 09:03:27 -0700711 }
712
Craig Mautner23ac33b2013-04-01 16:26:35 -0700713 final int startActivityMayWait(IApplicationThread caller, int callingUid,
714 String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
715 String resultWho, int requestCode, int startFlags, String profileFile,
716 ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config,
Craig Mautnere0a38842013-12-16 16:14:02 -0800717 Bundle options, int userId, IActivityContainer iContainer) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700718 // Refuse possible leaked file descriptors
719 if (intent != null && intent.hasFileDescriptors()) {
720 throw new IllegalArgumentException("File descriptors passed in Intent");
721 }
722 boolean componentSpecified = intent.getComponent() != null;
723
724 // Don't modify the client's object!
725 intent = new Intent(intent);
726
727 // Collect information about the target of the Intent.
728 ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
729 profileFile, profileFd, userId);
730
Craig Mautnere0a38842013-12-16 16:14:02 -0800731 ActivityContainer container = (ActivityContainer)iContainer;
Craig Mautner23ac33b2013-04-01 16:26:35 -0700732 synchronized (mService) {
733 int callingPid;
734 if (callingUid >= 0) {
735 callingPid = -1;
736 } else if (caller == null) {
737 callingPid = Binder.getCallingPid();
738 callingUid = Binder.getCallingUid();
739 } else {
740 callingPid = callingUid = -1;
741 }
742
Craig Mautnere0a38842013-12-16 16:14:02 -0800743 final ActivityStack stack;
744 if (container == null || container.mStack.isOnHomeDisplay()) {
745 stack = getFocusedStack();
746 } else {
747 stack = container.mStack;
748 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700749 stack.mConfigWillChange = config != null
Craig Mautner23ac33b2013-04-01 16:26:35 -0700750 && mService.mConfiguration.diff(config) != 0;
751 if (DEBUG_CONFIGURATION) Slog.v(TAG,
Craig Mautnerde4ef022013-04-07 19:01:33 -0700752 "Starting activity when config will change = " + stack.mConfigWillChange);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700753
754 final long origId = Binder.clearCallingIdentity();
755
756 if (aInfo != null &&
757 (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
758 // This may be a heavy-weight process! Check to see if we already
759 // have another, different heavy-weight process running.
760 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
761 if (mService.mHeavyWeightProcess != null &&
762 (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid ||
763 !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700764 int realCallingUid = callingUid;
765 if (caller != null) {
766 ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
767 if (callerApp != null) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700768 realCallingUid = callerApp.info.uid;
769 } else {
770 Slog.w(TAG, "Unable to find app for caller " + caller
Craig Mautner76ea2242013-05-15 11:40:05 -0700771 + " (pid=" + callingPid + ") when starting: "
Craig Mautner23ac33b2013-04-01 16:26:35 -0700772 + intent.toString());
773 ActivityOptions.abort(options);
774 return ActivityManager.START_PERMISSION_DENIED;
775 }
776 }
777
778 IIntentSender target = mService.getIntentSenderLocked(
779 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
780 realCallingUid, userId, null, null, 0, new Intent[] { intent },
781 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
782 | PendingIntent.FLAG_ONE_SHOT, null);
783
784 Intent newIntent = new Intent();
785 if (requestCode >= 0) {
786 // Caller is requesting a result.
787 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
788 }
789 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
790 new IntentSender(target));
791 if (mService.mHeavyWeightProcess.activities.size() > 0) {
792 ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0);
793 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
794 hist.packageName);
795 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
796 hist.task.taskId);
797 }
798 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
799 aInfo.packageName);
800 newIntent.setFlags(intent.getFlags());
801 newIntent.setClassName("android",
802 HeavyWeightSwitcherActivity.class.getName());
803 intent = newIntent;
804 resolvedType = null;
805 caller = null;
806 callingUid = Binder.getCallingUid();
807 callingPid = Binder.getCallingPid();
808 componentSpecified = true;
809 try {
810 ResolveInfo rInfo =
811 AppGlobals.getPackageManager().resolveIntent(
812 intent, null,
813 PackageManager.MATCH_DEFAULT_ONLY
814 | ActivityManagerService.STOCK_PM_FLAGS, userId);
815 aInfo = rInfo != null ? rInfo.activityInfo : null;
816 aInfo = mService.getActivityInfoForUser(aInfo, userId);
817 } catch (RemoteException e) {
818 aInfo = null;
819 }
820 }
821 }
822 }
823
Craig Mautnere0a38842013-12-16 16:14:02 -0800824 int res = startActivityLocked(caller, intent, resolvedType, aInfo, resultTo, resultWho,
825 requestCode, callingPid, callingUid, callingPackage, startFlags, options,
826 componentSpecified, null, container);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700827
Craig Mautnerde4ef022013-04-07 19:01:33 -0700828 if (stack.mConfigWillChange) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700829 // If the caller also wants to switch to a new configuration,
830 // do so now. This allows a clean switch, as we are waiting
831 // for the current activity to pause (so we will not destroy
832 // it), and have not yet started the next activity.
833 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
834 "updateConfiguration()");
Craig Mautnerde4ef022013-04-07 19:01:33 -0700835 stack.mConfigWillChange = false;
Craig Mautner23ac33b2013-04-01 16:26:35 -0700836 if (DEBUG_CONFIGURATION) Slog.v(TAG,
837 "Updating to new configuration after starting activity.");
838 mService.updateConfigurationLocked(config, null, false, false);
839 }
840
841 Binder.restoreCallingIdentity(origId);
842
843 if (outResult != null) {
844 outResult.result = res;
845 if (res == ActivityManager.START_SUCCESS) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700846 mWaitingActivityLaunched.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700847 do {
848 try {
849 mService.wait();
850 } catch (InterruptedException e) {
851 }
852 } while (!outResult.timeout && outResult.who == null);
853 } else if (res == ActivityManager.START_TASK_TO_FRONT) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700854 ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700855 if (r.nowVisible) {
856 outResult.timeout = false;
857 outResult.who = new ComponentName(r.info.packageName, r.info.name);
858 outResult.totalTime = 0;
859 outResult.thisTime = 0;
860 } else {
861 outResult.thisTime = SystemClock.uptimeMillis();
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700862 mWaitingActivityVisible.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700863 do {
864 try {
865 mService.wait();
866 } catch (InterruptedException e) {
867 }
868 } while (!outResult.timeout && outResult.who == null);
869 }
870 }
871 }
872
873 return res;
874 }
875 }
876
877 final int startActivities(IApplicationThread caller, int callingUid, String callingPackage,
878 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
879 Bundle options, int userId) {
880 if (intents == null) {
881 throw new NullPointerException("intents is null");
882 }
883 if (resolvedTypes == null) {
884 throw new NullPointerException("resolvedTypes is null");
885 }
886 if (intents.length != resolvedTypes.length) {
887 throw new IllegalArgumentException("intents are length different than resolvedTypes");
888 }
889
Craig Mautner23ac33b2013-04-01 16:26:35 -0700890
891 int callingPid;
892 if (callingUid >= 0) {
893 callingPid = -1;
894 } else if (caller == null) {
895 callingPid = Binder.getCallingPid();
896 callingUid = Binder.getCallingUid();
897 } else {
898 callingPid = callingUid = -1;
899 }
900 final long origId = Binder.clearCallingIdentity();
901 try {
902 synchronized (mService) {
Craig Mautner76ea2242013-05-15 11:40:05 -0700903 ActivityRecord[] outActivity = new ActivityRecord[1];
Craig Mautner23ac33b2013-04-01 16:26:35 -0700904 for (int i=0; i<intents.length; i++) {
905 Intent intent = intents[i];
906 if (intent == null) {
907 continue;
908 }
909
910 // Refuse possible leaked file descriptors
911 if (intent != null && intent.hasFileDescriptors()) {
912 throw new IllegalArgumentException("File descriptors passed in Intent");
913 }
914
915 boolean componentSpecified = intent.getComponent() != null;
916
917 // Don't modify the client's object!
918 intent = new Intent(intent);
919
920 // Collect information about the target of the Intent.
921 ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i],
922 0, null, null, userId);
923 // TODO: New, check if this is correct
924 aInfo = mService.getActivityInfoForUser(aInfo, userId);
925
926 if (aInfo != null &&
927 (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE)
928 != 0) {
929 throw new IllegalArgumentException(
930 "FLAG_CANT_SAVE_STATE not supported here");
931 }
932
933 Bundle theseOptions;
934 if (options != null && i == intents.length-1) {
935 theseOptions = options;
936 } else {
937 theseOptions = null;
938 }
Craig Mautner6170f732013-04-02 13:05:23 -0700939 int res = startActivityLocked(caller, intent, resolvedTypes[i],
Craig Mautner23ac33b2013-04-01 16:26:35 -0700940 aInfo, resultTo, null, -1, callingPid, callingUid, callingPackage,
Craig Mautnere0a38842013-12-16 16:14:02 -0800941 0, theseOptions, componentSpecified, outActivity, null);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700942 if (res < 0) {
943 return res;
944 }
945
946 resultTo = outActivity[0] != null ? outActivity[0].appToken : null;
947 }
948 }
949 } finally {
950 Binder.restoreCallingIdentity(origId);
951 }
952
953 return ActivityManager.START_SUCCESS;
954 }
955
Craig Mautner2420ead2013-04-01 17:13:20 -0700956 final boolean realStartActivityLocked(ActivityRecord r,
957 ProcessRecord app, boolean andResume, boolean checkConfig)
958 throws RemoteException {
959
960 r.startFreezingScreenLocked(app, 0);
Craig Mautnera7f2bd42013-10-15 16:13:50 -0700961 if (false) Slog.d(TAG, "realStartActivity: setting app visibility true");
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700962 mWindowManager.setAppVisibility(r.appToken, true);
Craig Mautner2420ead2013-04-01 17:13:20 -0700963
964 // schedule launch ticks to collect information about slow apps.
965 r.startLaunchTickingLocked();
966
967 // Have the window manager re-evaluate the orientation of
968 // the screen based on the new activity order. Note that
969 // as a result of this, it can call back into the activity
970 // manager with a new orientation. We don't care about that,
971 // because the activity is not currently running so we are
972 // just restarting it anyway.
973 if (checkConfig) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700974 Configuration config = mWindowManager.updateOrientationFromAppTokens(
Craig Mautner2420ead2013-04-01 17:13:20 -0700975 mService.mConfiguration,
976 r.mayFreezeScreenLocked(app) ? r.appToken : null);
977 mService.updateConfigurationLocked(config, r, false, false);
978 }
979
980 r.app = app;
981 app.waitingToKill = null;
982 r.launchCount++;
983 r.lastLaunchTime = SystemClock.uptimeMillis();
984
985 if (localLOGV) Slog.v(TAG, "Launching: " + r);
986
987 int idx = app.activities.indexOf(r);
988 if (idx < 0) {
989 app.activities.add(r);
990 }
Dianne Hackborndb926082013-10-31 16:32:44 -0700991 mService.updateLruProcessLocked(app, true, null);
992 mService.updateOomAdjLocked();
Craig Mautner2420ead2013-04-01 17:13:20 -0700993
994 final ActivityStack stack = r.task.stack;
995 try {
996 if (app.thread == null) {
997 throw new RemoteException();
998 }
999 List<ResultInfo> results = null;
1000 List<Intent> newIntents = null;
1001 if (andResume) {
1002 results = r.results;
1003 newIntents = r.newIntents;
1004 }
1005 if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r
1006 + " icicle=" + r.icicle
1007 + " with results=" + results + " newIntents=" + newIntents
1008 + " andResume=" + andResume);
1009 if (andResume) {
1010 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
1011 r.userId, System.identityHashCode(r),
1012 r.task.taskId, r.shortComponentName);
1013 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001014 if (r.isHomeActivity() && r.isNotResolverActivity()) {
Craig Mautner4ef26932013-09-18 15:15:52 -07001015 // Home process is the root process of the task.
1016 mService.mHomeProcess = r.task.mActivities.get(0).app;
Craig Mautner2420ead2013-04-01 17:13:20 -07001017 }
1018 mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
1019 r.sleeping = false;
1020 r.forceNewConfig = false;
1021 mService.showAskCompatModeDialogLocked(r);
1022 r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
1023 String profileFile = null;
1024 ParcelFileDescriptor profileFd = null;
1025 boolean profileAutoStop = false;
1026 if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
1027 if (mService.mProfileProc == null || mService.mProfileProc == app) {
1028 mService.mProfileProc = app;
1029 profileFile = mService.mProfileFile;
1030 profileFd = mService.mProfileFd;
1031 profileAutoStop = mService.mAutoStopProfiler;
1032 }
1033 }
1034 app.hasShownUi = true;
1035 app.pendingUiClean = true;
1036 if (profileFd != null) {
1037 try {
1038 profileFd = profileFd.dup();
1039 } catch (IOException e) {
1040 if (profileFd != null) {
1041 try {
1042 profileFd.close();
1043 } catch (IOException o) {
1044 }
1045 profileFd = null;
1046 }
1047 }
1048 }
Dianne Hackborna413dc02013-07-12 12:02:55 -07001049 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
Craig Mautner2420ead2013-04-01 17:13:20 -07001050 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
1051 System.identityHashCode(r), r.info,
Dianne Hackborna413dc02013-07-12 12:02:55 -07001052 new Configuration(mService.mConfiguration), r.compat,
1053 app.repProcState, r.icicle, results, newIntents, !andResume,
Craig Mautner2420ead2013-04-01 17:13:20 -07001054 mService.isNextTransitionForward(), profileFile, profileFd,
1055 profileAutoStop);
1056
1057 if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
1058 // This may be a heavy-weight process! Note that the package
1059 // manager will ensure that only activity can run in the main
1060 // process of the .apk, which is the only thing that will be
1061 // considered heavy-weight.
1062 if (app.processName.equals(app.info.packageName)) {
1063 if (mService.mHeavyWeightProcess != null
1064 && mService.mHeavyWeightProcess != app) {
1065 Slog.w(TAG, "Starting new heavy weight process " + app
1066 + " when already running "
1067 + mService.mHeavyWeightProcess);
1068 }
1069 mService.mHeavyWeightProcess = app;
1070 Message msg = mService.mHandler.obtainMessage(
1071 ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
1072 msg.obj = r;
1073 mService.mHandler.sendMessage(msg);
1074 }
1075 }
1076
1077 } catch (RemoteException e) {
1078 if (r.launchFailed) {
1079 // This is the second time we failed -- finish activity
1080 // and give up.
1081 Slog.e(TAG, "Second failure launching "
1082 + r.intent.getComponent().flattenToShortString()
1083 + ", giving up", e);
1084 mService.appDiedLocked(app, app.pid, app.thread);
1085 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
1086 "2nd-crash", false);
1087 return false;
1088 }
1089
1090 // This is the first time we failed -- restart process and
1091 // retry.
1092 app.activities.remove(r);
1093 throw e;
1094 }
1095
1096 r.launchFailed = false;
1097 if (stack.updateLRUListLocked(r)) {
1098 Slog.w(TAG, "Activity " + r
1099 + " being launched, but already in LRU list");
1100 }
1101
1102 if (andResume) {
1103 // As part of the process of launching, ActivityThread also performs
1104 // a resume.
1105 stack.minimalResumeActivityLocked(r);
1106 } else {
1107 // This activity is not starting in the resumed state... which
1108 // should look like we asked it to pause+stop (but remain visible),
1109 // and it has done so and reported back the current icicle and
1110 // other state.
1111 if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r
1112 + " (starting in stopped state)");
1113 r.state = ActivityState.STOPPED;
1114 r.stopped = true;
1115 }
1116
1117 // Launch the new version setup screen if needed. We do this -after-
1118 // launching the initial activity (that is, home), so that it can have
1119 // a chance to initialize itself while in the background, making the
1120 // switch back to it faster and look better.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001121 if (isFrontStack(stack)) {
Craig Mautner2420ead2013-04-01 17:13:20 -07001122 mService.startSetupActivityLocked();
1123 }
1124
1125 return true;
1126 }
1127
Craig Mautnere79d42682013-04-01 19:01:53 -07001128 void startSpecificActivityLocked(ActivityRecord r,
1129 boolean andResume, boolean checkConfig) {
1130 // Is this activity's application already running?
1131 ProcessRecord app = mService.getProcessRecordLocked(r.processName,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001132 r.info.applicationInfo.uid, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001133
1134 r.task.stack.setLaunchTime(r);
1135
1136 if (app != null && app.thread != null) {
1137 try {
Dianne Hackborn237cefb2013-10-22 18:45:27 -07001138 if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
1139 || !"android".equals(r.info.packageName)) {
1140 // Don't add this if it is a platform component that is marked
1141 // to run in multiple processes, because this is actually
1142 // part of the framework so doesn't make sense to track as a
1143 // separate apk in the process.
1144 app.addPackage(r.info.packageName, mService.mProcessStats);
1145 }
Craig Mautnere79d42682013-04-01 19:01:53 -07001146 realStartActivityLocked(r, app, andResume, checkConfig);
1147 return;
1148 } catch (RemoteException e) {
1149 Slog.w(TAG, "Exception when starting activity "
1150 + r.intent.getComponent().flattenToShortString(), e);
1151 }
1152
1153 // If a dead object exception was thrown -- fall through to
1154 // restart the application.
1155 }
1156
1157 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001158 "activity", r.intent.getComponent(), false, false, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001159 }
1160
Craig Mautner6170f732013-04-02 13:05:23 -07001161 final int startActivityLocked(IApplicationThread caller,
1162 Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
1163 String resultWho, int requestCode,
1164 int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
Craig Mautnere0a38842013-12-16 16:14:02 -08001165 boolean componentSpecified, ActivityRecord[] outActivity, ActivityContainer container) {
Craig Mautner6170f732013-04-02 13:05:23 -07001166 int err = ActivityManager.START_SUCCESS;
1167
1168 ProcessRecord callerApp = null;
1169 if (caller != null) {
1170 callerApp = mService.getRecordForAppLocked(caller);
1171 if (callerApp != null) {
1172 callingPid = callerApp.pid;
1173 callingUid = callerApp.info.uid;
1174 } else {
1175 Slog.w(TAG, "Unable to find app for caller " + caller
1176 + " (pid=" + callingPid + ") when starting: "
1177 + intent.toString());
1178 err = ActivityManager.START_PERMISSION_DENIED;
1179 }
1180 }
1181
1182 if (err == ActivityManager.START_SUCCESS) {
1183 final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
1184 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
Craig Mautner9ef471f2014-02-07 13:11:47 -08001185 + "} from pid " + (callerApp != null ? callerApp.pid : callingPid)
1186 + " on display " + (container == null ? (mFocusedStack == null ?
1187 Display.DEFAULT_DISPLAY : mFocusedStack.mDisplayId) :
1188 (container.mActivityDisplay == null ? Display.DEFAULT_DISPLAY :
1189 container.mActivityDisplay.mDisplayId)));
Craig Mautner6170f732013-04-02 13:05:23 -07001190 }
1191
1192 ActivityRecord sourceRecord = null;
1193 ActivityRecord resultRecord = null;
1194 if (resultTo != null) {
1195 sourceRecord = isInAnyStackLocked(resultTo);
1196 if (DEBUG_RESULTS) Slog.v(
1197 TAG, "Will send result to " + resultTo + " " + sourceRecord);
1198 if (sourceRecord != null) {
1199 if (requestCode >= 0 && !sourceRecord.finishing) {
1200 resultRecord = sourceRecord;
1201 }
1202 }
1203 }
1204 ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
1205
1206 int launchFlags = intent.getFlags();
1207
1208 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
1209 && sourceRecord != null) {
1210 // Transfer the result target from the source activity to the new
1211 // one being started, including any failures.
1212 if (requestCode >= 0) {
1213 ActivityOptions.abort(options);
1214 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
1215 }
1216 resultRecord = sourceRecord.resultTo;
1217 resultWho = sourceRecord.resultWho;
1218 requestCode = sourceRecord.requestCode;
1219 sourceRecord.resultTo = null;
1220 if (resultRecord != null) {
Craig Mautner1b4bf852014-05-26 15:06:32 -07001221 resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
Craig Mautner6170f732013-04-02 13:05:23 -07001222 }
Dianne Hackbornd4981012014-03-14 16:27:40 +00001223 if (sourceRecord.launchedFromUid == callingUid) {
1224 // The new activity is being launched from the same uid as the previous
1225 // activity in the flow, and asking to forward its result back to the
1226 // previous. In this case the activity is serving as a trampoline between
1227 // the two, so we also want to update its launchedFromPackage to be the
1228 // same as the previous activity. Note that this is safe, since we know
1229 // these two packages come from the same uid; the caller could just as
1230 // well have supplied that same package name itself. This specifially
1231 // deals with the case of an intent picker/chooser being launched in the app
1232 // flow to redirect to an activity picked by the user, where we want the final
1233 // activity to consider it to have been launched by the previous app activity.
1234 callingPackage = sourceRecord.launchedFromPackage;
1235 }
Craig Mautner6170f732013-04-02 13:05:23 -07001236 }
1237
1238 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
1239 // We couldn't find a class that can handle the given Intent.
1240 // That's the end of that!
1241 err = ActivityManager.START_INTENT_NOT_RESOLVED;
1242 }
1243
1244 if (err == ActivityManager.START_SUCCESS && aInfo == null) {
1245 // We couldn't find the specific class specified in the Intent.
1246 // Also the end of the line.
1247 err = ActivityManager.START_CLASS_NOT_FOUND;
1248 }
1249
1250 if (err != ActivityManager.START_SUCCESS) {
1251 if (resultRecord != null) {
1252 resultStack.sendActivityResultLocked(-1,
1253 resultRecord, resultWho, requestCode,
1254 Activity.RESULT_CANCELED, null);
1255 }
1256 setDismissKeyguard(false);
1257 ActivityOptions.abort(options);
1258 return err;
1259 }
1260
1261 final int startAnyPerm = mService.checkPermission(
1262 START_ANY_ACTIVITY, callingPid, callingUid);
1263 final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
1264 callingUid, aInfo.applicationInfo.uid, aInfo.exported);
1265 if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
1266 if (resultRecord != null) {
1267 resultStack.sendActivityResultLocked(-1,
1268 resultRecord, resultWho, requestCode,
1269 Activity.RESULT_CANCELED, null);
1270 }
1271 setDismissKeyguard(false);
1272 String msg;
1273 if (!aInfo.exported) {
1274 msg = "Permission Denial: starting " + intent.toString()
1275 + " from " + callerApp + " (pid=" + callingPid
1276 + ", uid=" + callingUid + ")"
1277 + " not exported from uid " + aInfo.applicationInfo.uid;
1278 } else {
1279 msg = "Permission Denial: starting " + intent.toString()
1280 + " from " + callerApp + " (pid=" + callingPid
1281 + ", uid=" + callingUid + ")"
1282 + " requires " + aInfo.permission;
1283 }
1284 Slog.w(TAG, msg);
1285 throw new SecurityException(msg);
1286 }
1287
Ben Gruverdd72c9e2013-08-06 12:34:17 -07001288 boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
Ben Gruverb6223792013-07-29 16:35:40 -07001289 callingPid, resolvedType, aInfo.applicationInfo);
Ben Gruver5e207332013-04-03 17:41:37 -07001290
Craig Mautner6170f732013-04-02 13:05:23 -07001291 if (mService.mController != null) {
Craig Mautner6170f732013-04-02 13:05:23 -07001292 try {
1293 // The Intent we give to the watcher has the extra data
1294 // stripped off, since it can contain private information.
1295 Intent watchIntent = intent.cloneFilter();
Ben Gruver5e207332013-04-03 17:41:37 -07001296 abort |= !mService.mController.activityStarting(watchIntent,
Craig Mautner6170f732013-04-02 13:05:23 -07001297 aInfo.applicationInfo.packageName);
1298 } catch (RemoteException e) {
1299 mService.mController = null;
1300 }
Ben Gruver5e207332013-04-03 17:41:37 -07001301 }
Craig Mautner6170f732013-04-02 13:05:23 -07001302
Ben Gruver5e207332013-04-03 17:41:37 -07001303 if (abort) {
1304 if (resultRecord != null) {
1305 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
Craig Mautner6170f732013-04-02 13:05:23 -07001306 Activity.RESULT_CANCELED, null);
Craig Mautner6170f732013-04-02 13:05:23 -07001307 }
Ben Gruver5e207332013-04-03 17:41:37 -07001308 // We pretend to the caller that it was really started, but
1309 // they will just get a cancel result.
1310 setDismissKeyguard(false);
1311 ActivityOptions.abort(options);
1312 return ActivityManager.START_SUCCESS;
Craig Mautner6170f732013-04-02 13:05:23 -07001313 }
1314
1315 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
Craig Mautnere0a38842013-12-16 16:14:02 -08001316 intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
1317 requestCode, componentSpecified, this, container);
Craig Mautner6170f732013-04-02 13:05:23 -07001318 if (outActivity != null) {
1319 outActivity[0] = r;
1320 }
1321
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001322 final ActivityStack stack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001323 if (stack.mResumedActivity == null
1324 || stack.mResumedActivity.info.applicationInfo.uid != callingUid) {
Craig Mautner6170f732013-04-02 13:05:23 -07001325 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
1326 PendingActivityLaunch pal =
Craig Mautnerde4ef022013-04-07 19:01:33 -07001327 new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
Craig Mautneree36c772014-07-16 14:56:05 -07001328 mPendingActivityLaunches.add(pal);
Craig Mautner6170f732013-04-02 13:05:23 -07001329 setDismissKeyguard(false);
1330 ActivityOptions.abort(options);
1331 return ActivityManager.START_SWITCHES_CANCELED;
1332 }
1333 }
1334
1335 if (mService.mDidAppSwitch) {
1336 // This is the second allowed switch since we stopped switches,
1337 // so now just generally allow switches. Use case: user presses
1338 // home (switches disabled, switch to home, mDidAppSwitch now true);
1339 // user taps a home icon (coming from home so allowed, we hit here
1340 // and now allow anyone to switch again).
1341 mService.mAppSwitchesAllowedTime = 0;
1342 } else {
1343 mService.mDidAppSwitch = true;
1344 }
1345
Craig Mautneree36c772014-07-16 14:56:05 -07001346 doPendingActivityLaunchesLocked(false);
Craig Mautner6170f732013-04-02 13:05:23 -07001347
Craig Mautner8849a5e2013-04-02 16:41:03 -07001348 err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
Craig Mautner10385a12013-09-22 21:08:32 -07001349
1350 if (allPausedActivitiesComplete()) {
1351 // If someone asked to have the keyguard dismissed on the next
Craig Mautner6170f732013-04-02 13:05:23 -07001352 // activity start, but we are not actually doing an activity
1353 // switch... just dismiss the keyguard now, because we
1354 // probably want to see whatever is behind it.
1355 dismissKeyguard();
1356 }
1357 return err;
1358 }
1359
Craig Mautner1b4bf852014-05-26 15:06:32 -07001360 ActivityStack adjustStackFocus(ActivityRecord r, boolean newTask) {
Craig Mautner1d001b62013-06-18 16:52:43 -07001361 final TaskRecord task = r.task;
1362 if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001363 if (task != null) {
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07001364 final ActivityStack taskStack = task.stack;
Craig Mautnere0a38842013-12-16 16:14:02 -08001365 if (taskStack.isOnHomeDisplay()) {
1366 if (mFocusedStack != taskStack) {
1367 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: Setting " +
1368 "focused stack to r=" + r + " task=" + task);
1369 mFocusedStack = taskStack;
1370 } else {
1371 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1372 "adjustStackFocus: Focused stack already=" + mFocusedStack);
1373 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001374 }
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07001375 return taskStack;
Craig Mautnerac6f8432013-07-17 13:24:59 -07001376 }
1377
Craig Mautnere0a38842013-12-16 16:14:02 -08001378 final ActivityContainer container = r.mInitialActivityContainer;
1379 if (container != null) {
1380 // The first time put it on the desired stack, after this put on task stack.
1381 r.mInitialActivityContainer = null;
1382 return container.mStack;
1383 }
1384
Craig Mautner1b4bf852014-05-26 15:06:32 -07001385 if (mFocusedStack != mHomeStack && (!newTask ||
1386 mFocusedStack.mActivityContainer.isEligibleForNewTasks())) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001387 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1388 "adjustStackFocus: Have a focused stack=" + mFocusedStack);
1389 return mFocusedStack;
1390 }
1391
Craig Mautnere0a38842013-12-16 16:14:02 -08001392 final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks;
1393 for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1394 final ActivityStack stack = homeDisplayStacks.get(stackNdx);
1395 if (!stack.isHomeStack()) {
1396 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1397 "adjustStackFocus: Setting focused stack=" + stack);
1398 mFocusedStack = stack;
1399 return mFocusedStack;
Craig Mautner858d8a62013-04-23 17:08:34 -07001400 }
1401 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001402
Craig Mautner4a1cb222013-12-04 16:14:06 -08001403 // Need to create an app stack for this user.
Craig Mautnerf4c909b2014-04-17 18:39:38 -07001404 int stackId = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY);
Craig Mautnerac6f8432013-07-17 13:24:59 -07001405 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r +
1406 " stackId=" + stackId);
1407 mFocusedStack = getStack(stackId);
Craig Mautner29219d92013-04-16 20:19:12 -07001408 return mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001409 }
1410 return mHomeStack;
1411 }
1412
Craig Mautner29219d92013-04-16 20:19:12 -07001413 void setFocusedStack(ActivityRecord r) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08001414 if (r != null) {
Craig Mautner12ff7392014-02-21 21:08:00 -08001415 final TaskRecord task = r.task;
1416 boolean isHomeActivity = !r.isApplicationActivity();
1417 if (!isHomeActivity && task != null) {
1418 isHomeActivity = !task.isApplicationTask();
1419 }
1420 if (!isHomeActivity && task != null) {
1421 final ActivityRecord parent = task.stack.mActivityContainer.mParentActivity;
1422 isHomeActivity = parent != null && parent.isHomeActivity();
1423 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08001424 moveHomeStack(isHomeActivity);
Craig Mautner29219d92013-04-16 20:19:12 -07001425 }
1426 }
1427
Craig Mautner8849a5e2013-04-02 16:41:03 -07001428 final int startActivityUncheckedLocked(ActivityRecord r,
1429 ActivityRecord sourceRecord, int startFlags, boolean doResume,
1430 Bundle options) {
1431 final Intent intent = r.intent;
1432 final int callingUid = r.launchedFromUid;
1433
1434 int launchFlags = intent.getFlags();
1435
Craig Mautner8849a5e2013-04-02 16:41:03 -07001436 // We'll invoke onUserLeaving before onPause only if the launching
1437 // activity did not explicitly state that this is an automated launch.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001438 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1439 if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001440
1441 // If the caller has asked not to resume at this point, we make note
1442 // of this in the record so that we can skip it when trying to find
1443 // the top running activity.
1444 if (!doResume) {
1445 r.delayedResume = true;
1446 }
1447
1448 ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1449
1450 // If the onlyIfNeeded flag is set, then we can do this if the activity
1451 // being launched is the same as the one making the call... or, as
1452 // a special case, if we do not know the caller then we count the
1453 // current top activity as the caller.
1454 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1455 ActivityRecord checkedCaller = sourceRecord;
1456 if (checkedCaller == null) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001457 checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001458 }
1459 if (!checkedCaller.realActivity.equals(r.realActivity)) {
1460 // Caller is not the same as launcher, so always needed.
1461 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
1462 }
1463 }
1464
1465 if (sourceRecord == null) {
1466 // This activity is not being started from another... in this
1467 // case we -always- start a new task.
1468 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
Craig Mautner29219d92013-04-16 20:19:12 -07001469 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1470 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001471 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1472 }
1473 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1474 // The original activity who is starting us is running as a single
1475 // instance... this new activity it is starting must go on its
1476 // own task.
1477 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1478 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
1479 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1480 // The activity being started is a single instance... it always
1481 // gets launched into its own task.
1482 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1483 }
1484
Craig Mautner88629292013-11-10 20:39:05 -08001485 ActivityInfo newTaskInfo = null;
1486 Intent newTaskIntent = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001487 final ActivityStack sourceStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001488 if (sourceRecord != null) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001489 if (sourceRecord.finishing) {
1490 // If the source is finishing, we can't further count it as our source. This
1491 // is because the task it is associated with may now be empty and on its way out,
1492 // so we don't want to blindly throw it in to that task. Instead we will take
Craig Mautner88629292013-11-10 20:39:05 -08001493 // the NEW_TASK flow and try to find a task for it. But save the task information
1494 // so it can be used when creating the new task.
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001495 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
1496 Slog.w(TAG, "startActivity called from finishing " + sourceRecord
1497 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
1498 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
Craig Mautner88629292013-11-10 20:39:05 -08001499 newTaskInfo = sourceRecord.info;
1500 newTaskIntent = sourceRecord.task.intent;
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001501 }
1502 sourceRecord = null;
1503 sourceStack = null;
1504 } else {
1505 sourceStack = sourceRecord.task.stack;
1506 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07001507 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001508 sourceStack = null;
1509 }
1510
Craig Mautner1b4bf852014-05-26 15:06:32 -07001511 if (r.resultTo != null && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001512 // For whatever reason this activity is being launched into a new
1513 // task... yet the caller has requested a result back. Well, that
1514 // is pretty messed up, so instead immediately send back a cancel
1515 // and let the new task continue launched as normal without a
1516 // dependency on its originator.
1517 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1518 r.resultTo.task.stack.sendActivityResultLocked(-1,
1519 r.resultTo, r.resultWho, r.requestCode,
1520 Activity.RESULT_CANCELED, null);
1521 r.resultTo = null;
1522 }
1523
1524 boolean addingToTask = false;
1525 boolean movedHome = false;
1526 TaskRecord reuseTask = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001527 ActivityStack targetStack;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001528 if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
1529 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
1530 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1531 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1532 // If bring to front is requested, and no result is requested, and
1533 // we can find a task that was started with this same
1534 // component, then instead of launching bring that one to the front.
1535 if (r.resultTo == null) {
1536 // See if there is a task to bring to the front. If this is
1537 // a SINGLE_INSTANCE activity, there can be one and only one
1538 // instance of it in the history, and it is always in its own
1539 // unique task, so we do a special search.
1540 ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
Craig Mautnerac6f8432013-07-17 13:24:59 -07001541 ? findTaskLocked(r)
Craig Mautner8849a5e2013-04-02 16:41:03 -07001542 : findActivityLocked(intent, r.info);
1543 if (intentActivity != null) {
Craig Mautner29219d92013-04-16 20:19:12 -07001544 if (r.task == null) {
1545 r.task = intentActivity.task;
1546 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001547 targetStack = intentActivity.task.stack;
Craig Mautner0f922742013-08-06 08:44:42 -07001548 targetStack.mLastPausedActivity = null;
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001549 if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack
1550 + " from " + intentActivity);
Craig Mautnere0a38842013-12-16 16:14:02 -08001551 targetStack.moveToFront();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001552 if (intentActivity.task.intent == null) {
1553 // This task was started because of movement of
1554 // the activity based on affinity... now that we
1555 // are actually launching it, we can assign the
1556 // base intent.
1557 intentActivity.task.setIntent(intent, r.info);
1558 }
1559 // If the target task is not in the front, then we need
1560 // to bring it to the front... except... well, with
1561 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like
1562 // to have the same behavior as if a new instance was
1563 // being started, which means not bringing it to the front
1564 // if the caller is not itself in the front.
Craig Mautner165640b2013-04-20 10:34:33 -07001565 final ActivityStack lastStack = getLastStack();
1566 ActivityRecord curTop = lastStack == null?
1567 null : lastStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner7504d7b2013-09-17 10:50:53 -07001568 if (curTop != null && (curTop.task != intentActivity.task ||
1569 curTop.task != lastStack.topTask())) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001570 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Craig Mautnerd0f964f2013-08-07 11:16:33 -07001571 if (sourceRecord == null || (sourceStack.topActivity() != null &&
1572 sourceStack.topActivity().task == sourceRecord.task)) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001573 // We really do want to push this one into the
1574 // user's face, right now.
1575 movedHome = true;
Craig Mautnerb53d97c2013-10-25 11:54:37 -07001576 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001577 if ((launchFlags &
Craig Mautner29219d92013-04-16 20:19:12 -07001578 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1579 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
Craig Mautnere12a4a62013-08-29 12:24:56 -07001580 // Caller wants to appear on home activity.
Craig Mautnerae7ecab2013-09-18 11:48:14 -07001581 intentActivity.task.mOnTopOfHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001582 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001583 options = null;
1584 }
1585 }
1586 // If the caller has requested that the target task be
1587 // reset, then do so.
1588 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1589 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
1590 }
1591 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1592 // We don't need to start a new activity, and
1593 // the client said not to do anything if that
1594 // is the case, so this is it! And for paranoia, make
1595 // sure we have correctly resumed the top activity.
1596 if (doResume) {
Craig Mautner05d29032013-05-03 13:40:13 -07001597 resumeTopActivitiesLocked(targetStack, null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001598 } else {
1599 ActivityOptions.abort(options);
1600 }
1601 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1602 }
1603 if ((launchFlags &
1604 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
1605 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
1606 // The caller has requested to completely replace any
1607 // existing task with its new activity. Well that should
1608 // not be too hard...
1609 reuseTask = intentActivity.task;
1610 reuseTask.performClearTaskLocked();
1611 reuseTask.setIntent(r.intent, r.info);
1612 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
1613 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1614 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1615 // In this situation we want to remove all activities
1616 // from the task up to the one being started. In most
1617 // cases this means we are resetting the task to its
1618 // initial state.
1619 ActivityRecord top =
1620 intentActivity.task.performClearTaskLocked(r, launchFlags);
1621 if (top != null) {
1622 if (top.frontOfTask) {
1623 // Activity aliases may mean we use different
1624 // intents for the top activity, so make sure
1625 // the task now has the identity of the new
1626 // intent.
1627 top.task.setIntent(r.intent, r.info);
1628 }
1629 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
1630 r, top.task);
1631 top.deliverNewIntentLocked(callingUid, r.intent);
1632 } else {
1633 // A special case: we need to
1634 // start the activity because it is not currently
1635 // running, and the caller has asked to clear the
1636 // current task to have this activity at the top.
1637 addingToTask = true;
1638 // Now pretend like this activity is being started
1639 // by the top of its task, so it is put in the
1640 // right place.
1641 sourceRecord = intentActivity;
1642 }
1643 } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
1644 // In this case the top activity on the task is the
1645 // same as the one being launched, so we take that
1646 // as a request to bring the task to the foreground.
1647 // If the top activity in the task is the root
1648 // activity, deliver this new intent to it if it
1649 // desires.
1650 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1651 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
1652 && intentActivity.realActivity.equals(r.realActivity)) {
1653 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
1654 intentActivity.task);
1655 if (intentActivity.frontOfTask) {
1656 intentActivity.task.setIntent(r.intent, r.info);
1657 }
1658 intentActivity.deliverNewIntentLocked(callingUid, r.intent);
1659 } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
1660 // In this case we are launching the root activity
1661 // of the task, but with a different intent. We
1662 // should start a new instance on top.
1663 addingToTask = true;
1664 sourceRecord = intentActivity;
1665 }
1666 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1667 // In this case an activity is being launched in to an
1668 // existing task, without resetting that task. This
1669 // is typically the situation of launching an activity
1670 // from a notification or shortcut. We want to place
1671 // the new activity on top of the current task.
1672 addingToTask = true;
1673 sourceRecord = intentActivity;
1674 } else if (!intentActivity.task.rootWasReset) {
1675 // In this case we are launching in to an existing task
1676 // that has not yet been started from its front door.
1677 // The current task has been brought to the front.
1678 // Ideally, we'd probably like to place this new task
1679 // at the bottom of its stack, but that's a little hard
1680 // to do with the current organization of the code so
1681 // for now we'll just drop it.
1682 intentActivity.task.setIntent(r.intent, r.info);
1683 }
1684 if (!addingToTask && reuseTask == null) {
1685 // We didn't do anything... but it was needed (a.k.a., client
1686 // don't use that intent!) And for paranoia, make
1687 // sure we have correctly resumed the top activity.
1688 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001689 targetStack.resumeTopActivityLocked(null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001690 } else {
1691 ActivityOptions.abort(options);
1692 }
1693 return ActivityManager.START_TASK_TO_FRONT;
1694 }
1695 }
1696 }
1697 }
1698
1699 //String uri = r.intent.toURI();
1700 //Intent intent2 = new Intent(uri);
1701 //Slog.i(TAG, "Given intent: " + r.intent);
1702 //Slog.i(TAG, "URI is: " + uri);
1703 //Slog.i(TAG, "To intent: " + intent2);
1704
1705 if (r.packageName != null) {
1706 // If the activity being launched is the same as the one currently
1707 // at the top, then we need to check if it should only be launched
1708 // once.
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001709 ActivityStack topStack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001710 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001711 if (top != null && r.resultTo == null) {
1712 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
1713 if (top.app != null && top.app.thread != null) {
1714 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1715 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
1716 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1717 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
1718 top.task);
1719 // For paranoia, make sure we have correctly
1720 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001721 topStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001722 if (doResume) {
Craig Mautner05d29032013-05-03 13:40:13 -07001723 resumeTopActivitiesLocked();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001724 }
1725 ActivityOptions.abort(options);
1726 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1727 // We don't need to start a new activity, and
1728 // the client said not to do anything if that
1729 // is the case, so this is it!
1730 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1731 }
1732 top.deliverNewIntentLocked(callingUid, r.intent);
1733 return ActivityManager.START_DELIVERED_TO_TOP;
1734 }
1735 }
1736 }
1737 }
1738
1739 } else {
1740 if (r.resultTo != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001741 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
1742 r.requestCode, Activity.RESULT_CANCELED, null);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001743 }
1744 ActivityOptions.abort(options);
1745 return ActivityManager.START_CLASS_NOT_FOUND;
1746 }
1747
1748 boolean newTask = false;
1749 boolean keepCurTransition = false;
1750
1751 // Should this be considered a new task?
1752 if (r.resultTo == null && !addingToTask
1753 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
Craig Mautner1b4bf852014-05-26 15:06:32 -07001754 newTask = true;
1755 targetStack = adjustStackFocus(r, newTask);
Craig Mautnere0a38842013-12-16 16:14:02 -08001756 targetStack.moveToFront();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001757 if (reuseTask == null) {
Craig Mautner88629292013-11-10 20:39:05 -08001758 r.setTask(targetStack.createTaskRecord(getNextTaskId(),
1759 newTaskInfo != null ? newTaskInfo : r.info,
1760 newTaskIntent != null ? newTaskIntent : intent,
1761 true), null, true);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001762 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
1763 r.task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001764 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001765 r.setTask(reuseTask, reuseTask, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001766 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001767 if (!movedHome) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001768 if ((launchFlags &
1769 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
1770 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
1771 // Caller wants to appear on home activity, so before starting
1772 // their own activity we will bring home to the front.
Craig Mautnere0a38842013-12-16 16:14:02 -08001773 r.task.mOnTopOfHome = r.task.stack.isOnHomeDisplay();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001774 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001775 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001776 } else if (sourceRecord != null) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001777 TaskRecord sourceTask = sourceRecord.task;
Craig Mautner525f3d92013-05-07 14:01:50 -07001778 targetStack = sourceTask.stack;
Craig Mautnere0a38842013-12-16 16:14:02 -08001779 targetStack.moveToFront();
Craig Mautnerf32b22e2014-03-25 11:04:16 -07001780 mWindowManager.moveTaskToTop(sourceTask.taskId);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001781 if (!addingToTask &&
1782 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
1783 // In this case, we are adding the activity to an existing
1784 // task, but the caller has asked to clear that task if the
1785 // activity is already running.
Craig Mautner525f3d92013-05-07 14:01:50 -07001786 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001787 keepCurTransition = true;
1788 if (top != null) {
1789 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
1790 top.deliverNewIntentLocked(callingUid, r.intent);
1791 // For paranoia, make sure we have correctly
1792 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001793 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001794 if (doResume) {
1795 targetStack.resumeTopActivityLocked(null);
1796 }
1797 ActivityOptions.abort(options);
1798 return ActivityManager.START_DELIVERED_TO_TOP;
1799 }
1800 } else if (!addingToTask &&
1801 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1802 // In this case, we are launching an activity in our own task
1803 // that may already be running somewhere in the history, and
1804 // we want to shuffle it to the front of the stack if so.
Craig Mautner525f3d92013-05-07 14:01:50 -07001805 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001806 if (top != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001807 final TaskRecord task = top.task;
1808 task.moveActivityToFrontLocked(top);
1809 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001810 top.updateOptionsLocked(options);
1811 top.deliverNewIntentLocked(callingUid, r.intent);
Craig Mautner0f922742013-08-06 08:44:42 -07001812 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001813 if (doResume) {
1814 targetStack.resumeTopActivityLocked(null);
1815 }
1816 return ActivityManager.START_DELIVERED_TO_TOP;
1817 }
1818 }
1819 // An existing activity is starting this new activity, so we want
1820 // to keep the new one in the same task as the one that is starting
1821 // it.
Craig Mautner525f3d92013-05-07 14:01:50 -07001822 r.setTask(sourceTask, sourceRecord.thumbHolder, false);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001823 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001824 + " in existing task " + r.task + " from source " + sourceRecord);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001825
1826 } else {
1827 // This not being started from an existing activity, and not part
1828 // of a new task... just put it in the top task, though these days
1829 // this case should never happen.
Craig Mautner1b4bf852014-05-26 15:06:32 -07001830 targetStack = adjustStackFocus(r, newTask);
Craig Mautnere0a38842013-12-16 16:14:02 -08001831 targetStack.moveToFront();
Craig Mautner1602ec22013-05-12 10:24:27 -07001832 ActivityRecord prev = targetStack.topActivity();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001833 r.setTask(prev != null ? prev.task
1834 : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1835 null, true);
Craig Mautnerf32b22e2014-03-25 11:04:16 -07001836 mWindowManager.moveTaskToTop(r.task.taskId);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001837 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1838 + " in new guessed " + r.task);
1839 }
1840
1841 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
1842 intent, r.getUriPermissionsLocked());
1843
1844 if (newTask) {
1845 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
1846 }
1847 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
Craig Mautner0f922742013-08-06 08:44:42 -07001848 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001849 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
Craig Mautner1d001b62013-06-18 16:52:43 -07001850 mService.setFocusedActivityLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001851 return ActivityManager.START_SUCCESS;
1852 }
1853
Craig Mautneree36c772014-07-16 14:56:05 -07001854 final void doPendingActivityLaunchesLocked(boolean doResume) {
1855 while (!mPendingActivityLaunches.isEmpty()) {
1856 PendingActivityLaunch pal = mPendingActivityLaunches.remove(0);
1857 startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
1858 doResume && mPendingActivityLaunches.isEmpty(), null);
1859 }
1860 }
1861
Craig Mautner7f13ed32014-07-28 14:00:35 -07001862 void removePendingActivityLaunchesLocked(ActivityStack stack) {
Craig Mautneree36c772014-07-16 14:56:05 -07001863 for (int palNdx = mPendingActivityLaunches.size() - 1; palNdx >= 0; --palNdx) {
1864 PendingActivityLaunch pal = mPendingActivityLaunches.get(palNdx);
Craig Mautner7f13ed32014-07-28 14:00:35 -07001865 if (pal.stack == stack) {
Craig Mautneree36c772014-07-16 14:56:05 -07001866 mPendingActivityLaunches.remove(palNdx);
1867 }
1868 }
1869 }
1870
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001871 void acquireLaunchWakelock() {
1872 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
1873 throw new IllegalStateException("Calling must be system uid");
1874 }
1875 mLaunchingActivity.acquire();
1876 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
1877 // To be safe, don't allow the wake lock to be held for too long.
1878 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
1879 }
1880 }
1881
Craig Mautnerf3333272013-04-22 10:55:53 -07001882 // Checked.
1883 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
1884 Configuration config) {
1885 if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
1886
Craig Mautnerf3333272013-04-22 10:55:53 -07001887 ArrayList<ActivityRecord> stops = null;
1888 ArrayList<ActivityRecord> finishes = null;
1889 ArrayList<UserStartedState> startingUsers = null;
1890 int NS = 0;
1891 int NF = 0;
1892 IApplicationThread sendThumbnail = null;
1893 boolean booting = false;
1894 boolean enableScreen = false;
1895 boolean activityRemoved = false;
1896
1897 ActivityRecord r = ActivityRecord.forToken(token);
1898 if (r != null) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07001899 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
1900 Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07001901 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
1902 r.finishLaunchTickingLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001903 if (fromTimeout) {
1904 reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
Craig Mautnerf3333272013-04-22 10:55:53 -07001905 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001906
1907 // This is a hack to semi-deal with a race condition
1908 // in the client where it can be constructed with a
1909 // newer configuration from when we asked it to launch.
1910 // We'll update with whatever configuration it now says
1911 // it used to launch.
1912 if (config != null) {
1913 r.configuration = config;
1914 }
1915
1916 // We are now idle. If someone is waiting for a thumbnail from
1917 // us, we can now deliver.
1918 r.idle = true;
1919
1920 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
1921 sendThumbnail = r.app.thread;
1922 r.thumbnailNeeded = false;
1923 }
1924
1925 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
1926 if (!mService.mBooted && isFrontStack(r.task.stack)) {
1927 mService.mBooted = true;
1928 enableScreen = true;
1929 }
1930 }
1931
1932 if (allResumedActivitiesIdle()) {
1933 if (r != null) {
1934 mService.scheduleAppGcsLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001935 }
1936
1937 if (mLaunchingActivity.isHeld()) {
1938 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
1939 if (VALIDATE_WAKE_LOCK_CALLER &&
1940 Binder.getCallingUid() != Process.myUid()) {
1941 throw new IllegalStateException("Calling must be system uid");
1942 }
1943 mLaunchingActivity.release();
1944 }
1945 ensureActivitiesVisibleLocked(null, 0);
Craig Mautnerf3333272013-04-22 10:55:53 -07001946 }
1947
1948 // Atomically retrieve all of the other things to do.
1949 stops = processStoppingActivitiesLocked(true);
1950 NS = stops != null ? stops.size() : 0;
1951 if ((NF=mFinishingActivities.size()) > 0) {
1952 finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
1953 mFinishingActivities.clear();
1954 }
1955
1956 final ArrayList<ActivityRecord> thumbnails;
1957 final int NT = mCancelledThumbnails.size();
1958 if (NT > 0) {
1959 thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
1960 mCancelledThumbnails.clear();
1961 } else {
1962 thumbnails = null;
1963 }
1964
1965 if (isFrontStack(mHomeStack)) {
1966 booting = mService.mBooting;
1967 mService.mBooting = false;
1968 }
1969
1970 if (mStartingUsers.size() > 0) {
1971 startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
1972 mStartingUsers.clear();
1973 }
1974
1975 // Perform the following actions from unsynchronized state.
1976 final IApplicationThread thumbnailThread = sendThumbnail;
1977 mHandler.post(new Runnable() {
1978 @Override
1979 public void run() {
1980 if (thumbnailThread != null) {
1981 try {
1982 thumbnailThread.requestThumbnail(token);
1983 } catch (Exception e) {
1984 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
1985 mService.sendPendingThumbnail(null, token, null, null, true);
1986 }
1987 }
1988
1989 // Report back to any thumbnail receivers.
1990 for (int i = 0; i < NT; i++) {
1991 ActivityRecord r = thumbnails.get(i);
1992 mService.sendPendingThumbnail(r, null, null, null, true);
1993 }
1994 }
1995 });
1996
1997 // Stop any activities that are scheduled to do so but have been
1998 // waiting for the next one to start.
1999 for (int i = 0; i < NS; i++) {
2000 r = stops.get(i);
2001 final ActivityStack stack = r.task.stack;
2002 if (r.finishing) {
2003 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
2004 } else {
2005 stack.stopActivityLocked(r);
2006 }
2007 }
2008
2009 // Finish any activities that are scheduled to do so but have been
2010 // waiting for the next one to start.
2011 for (int i = 0; i < NF; i++) {
2012 r = finishes.get(i);
2013 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
2014 }
2015
2016 if (booting) {
2017 mService.finishBooting();
2018 } else if (startingUsers != null) {
2019 for (int i = 0; i < startingUsers.size(); i++) {
2020 mService.finishUserSwitch(startingUsers.get(i));
2021 }
2022 }
2023
2024 mService.trimApplications();
2025 //dump();
2026 //mWindowManager.dump();
2027
2028 if (enableScreen) {
2029 mService.enableScreenAfterBoot();
2030 }
2031
2032 if (activityRemoved) {
Craig Mautner05d29032013-05-03 13:40:13 -07002033 resumeTopActivitiesLocked();
Craig Mautnerf3333272013-04-22 10:55:53 -07002034 }
2035
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002036 return r;
Craig Mautnerf3333272013-04-22 10:55:53 -07002037 }
2038
Craig Mautner8e569572013-10-11 17:36:59 -07002039 boolean handleAppDiedLocked(ProcessRecord app) {
Craig Mautner19091252013-10-05 00:03:53 -07002040 boolean hasVisibleActivities = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002041 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2042 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002043 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2044 hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app);
2045 }
Craig Mautner6b74cb52013-09-27 17:02:21 -07002046 }
Craig Mautner19091252013-10-05 00:03:53 -07002047 return hasVisibleActivities;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002048 }
2049
2050 void closeSystemDialogsLocked() {
Craig Mautnere0a38842013-12-16 16:14:02 -08002051 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2052 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002053 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2054 stacks.get(stackNdx).closeSystemDialogsLocked();
2055 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002056 }
2057 }
2058
Craig Mautner93529a42013-10-04 15:03:13 -07002059 void removeUserLocked(int userId) {
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002060 mUserStackInFront.delete(userId);
Craig Mautner93529a42013-10-04 15:03:13 -07002061 }
2062
Craig Mautner8d341ef2013-03-26 09:03:27 -07002063 /**
2064 * @return true if some activity was finished (or would have finished if doit were true).
2065 */
2066 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
2067 boolean didSomething = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002068 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2069 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002070 final int numStacks = stacks.size();
2071 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2072 final ActivityStack stack = stacks.get(stackNdx);
2073 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
2074 didSomething = true;
2075 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002076 }
2077 }
2078 return didSomething;
2079 }
2080
Dianne Hackborna413dc02013-07-12 12:02:55 -07002081 void updatePreviousProcessLocked(ActivityRecord r) {
2082 // Now that this process has stopped, we may want to consider
2083 // it to be the previous app to try to keep around in case
2084 // the user wants to return to it.
2085
2086 // First, found out what is currently the foreground app, so that
2087 // we don't blow away the previous app if this activity is being
2088 // hosted by the process that is actually still the foreground.
2089 ProcessRecord fgApp = null;
Craig Mautnere0a38842013-12-16 16:14:02 -08002090 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2091 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002092 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2093 final ActivityStack stack = stacks.get(stackNdx);
2094 if (isFrontStack(stack)) {
2095 if (stack.mResumedActivity != null) {
2096 fgApp = stack.mResumedActivity.app;
2097 } else if (stack.mPausingActivity != null) {
2098 fgApp = stack.mPausingActivity.app;
2099 }
2100 break;
Dianne Hackborna413dc02013-07-12 12:02:55 -07002101 }
Dianne Hackborna413dc02013-07-12 12:02:55 -07002102 }
2103 }
2104
2105 // Now set this one as the previous process, only if that really
2106 // makes sense to.
2107 if (r.app != null && fgApp != null && r.app != fgApp
2108 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
Craig Mautner4ef26932013-09-18 15:15:52 -07002109 && r.app != mService.mHomeProcess) {
Dianne Hackborna413dc02013-07-12 12:02:55 -07002110 mService.mPreviousProcess = r.app;
2111 mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
2112 }
2113 }
2114
Craig Mautner05d29032013-05-03 13:40:13 -07002115 boolean resumeTopActivitiesLocked() {
2116 return resumeTopActivitiesLocked(null, null, null);
2117 }
2118
2119 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
2120 Bundle targetOptions) {
2121 if (targetStack == null) {
2122 targetStack = getFocusedStack();
2123 }
Craig Mautner12ff7392014-02-21 21:08:00 -08002124 // Do targetStack first.
Craig Mautner05d29032013-05-03 13:40:13 -07002125 boolean result = false;
Craig Mautner12ff7392014-02-21 21:08:00 -08002126 if (isFrontStack(targetStack)) {
2127 result = targetStack.resumeTopActivityLocked(target, targetOptions);
2128 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002129 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2130 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002131 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2132 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautner12ff7392014-02-21 21:08:00 -08002133 if (stack == targetStack) {
2134 // Already started above.
2135 continue;
2136 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002137 if (isFrontStack(stack)) {
Craig Mautner12ff7392014-02-21 21:08:00 -08002138 stack.resumeTopActivityLocked(null);
Craig Mautner05d29032013-05-03 13:40:13 -07002139 }
Craig Mautnerf88c50f2013-04-18 19:25:12 -07002140 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002141 }
Craig Mautner05d29032013-05-03 13:40:13 -07002142 return result;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002143 }
2144
2145 void finishTopRunningActivityLocked(ProcessRecord app) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002146 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2147 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002148 final int numStacks = stacks.size();
2149 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2150 final ActivityStack stack = stacks.get(stackNdx);
2151 stack.finishTopRunningActivityLocked(app);
2152 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002153 }
2154 }
2155
Craig Mautner8d341ef2013-03-26 09:03:27 -07002156 void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002157 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2158 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002159 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2160 if (stacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) {
2161 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack="
2162 + stacks.get(stackNdx));
2163 return;
2164 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002165 }
2166 }
2167 }
2168
Craig Mautner967212c2013-04-13 21:10:58 -07002169 ActivityStack getStack(int stackId) {
Craig Mautnerf4c909b2014-04-17 18:39:38 -07002170 ActivityContainer activityContainer = mActivityContainers.get(stackId);
2171 if (activityContainer != null) {
2172 return activityContainer.mStack;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002173 }
2174 return null;
2175 }
2176
Craig Mautner967212c2013-04-13 21:10:58 -07002177 ArrayList<ActivityStack> getStacks() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002178 ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>();
Craig Mautnere0a38842013-12-16 16:14:02 -08002179 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2180 allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002181 }
2182 return allStacks;
Craig Mautner967212c2013-04-13 21:10:58 -07002183 }
2184
Craig Mautner4a1cb222013-12-04 16:14:06 -08002185 IBinder getHomeActivityToken() {
2186 final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
2187 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
2188 final TaskRecord task = tasks.get(taskNdx);
2189 if (task.isHomeTask()) {
2190 final ArrayList<ActivityRecord> activities = task.mActivities;
2191 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2192 final ActivityRecord r = activities.get(activityNdx);
2193 if (r.isHomeActivity()) {
2194 return r.appToken;
2195 }
2196 }
2197 }
2198 }
2199 return null;
2200 }
2201
Craig Mautnerf4c909b2014-04-17 18:39:38 -07002202 ActivityContainer createActivityContainer(ActivityRecord parentActivity,
Craig Mautner4a1cb222013-12-04 16:14:06 -08002203 IActivityContainerCallback callback) {
Craig Mautner6335fbc2014-06-13 17:18:47 -07002204 ActivityContainer activityContainer =
2205 new VirtualActivityContainer(parentActivity, callback);
Craig Mautnerf4c909b2014-04-17 18:39:38 -07002206 mActivityContainers.put(activityContainer.mStackId, activityContainer);
Craig Mautner6335fbc2014-06-13 17:18:47 -07002207 if (DEBUG_CONTAINERS) Slog.d(TAG, "createActivityContainer: " + activityContainer);
Craig Mautnerf4c909b2014-04-17 18:39:38 -07002208 parentActivity.mChildContainers.add(activityContainer);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002209 return activityContainer;
2210 }
2211
Craig Mautner34b73df2014-01-12 21:11:08 -08002212 void removeChildActivityContainers(ActivityRecord parentActivity) {
Craig Mautnerf4c909b2014-04-17 18:39:38 -07002213 final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers;
2214 for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) {
2215 ActivityContainer container = childStacks.remove(containerNdx);
Craig Mautner6335fbc2014-06-13 17:18:47 -07002216 if (DEBUG_CONTAINERS) Slog.d(TAG, "removeChildActivityContainers: removing " +
2217 container);
Craig Mautnerf4c909b2014-04-17 18:39:38 -07002218 container.release();
Craig Mautner34b73df2014-01-12 21:11:08 -08002219 }
2220 }
2221
Craig Mautner95da1082014-02-24 17:54:35 -08002222 void deleteActivityContainer(IActivityContainer container) {
2223 ActivityContainer activityContainer = (ActivityContainer)container;
2224 if (activityContainer != null) {
Craig Mautner6335fbc2014-06-13 17:18:47 -07002225 if (DEBUG_CONTAINERS) Slog.d(TAG, "deleteActivityContainer: ",
2226 new RuntimeException("here").fillInStackTrace());
Craig Mautner95da1082014-02-24 17:54:35 -08002227 final int stackId = activityContainer.mStackId;
2228 mActivityContainers.remove(stackId);
2229 mWindowManager.removeStack(stackId);
2230 }
2231 }
2232
Craig Mautnerf4c909b2014-04-17 18:39:38 -07002233 private int createStackOnDisplay(int stackId, int displayId) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002234 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2235 if (activityDisplay == null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002236 return -1;
2237 }
2238
Craig Mautnerf4c909b2014-04-17 18:39:38 -07002239 ActivityContainer activityContainer = new ActivityContainer(stackId);
2240 mActivityContainers.put(stackId, activityContainer);
Craig Mautnere0a38842013-12-16 16:14:02 -08002241 activityContainer.attachToDisplayLocked(activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002242 return stackId;
2243 }
2244
2245 int getNextStackId() {
Craig Mautner858d8a62013-04-23 17:08:34 -07002246 while (true) {
2247 if (++mLastStackId <= HOME_STACK_ID) {
2248 mLastStackId = HOME_STACK_ID + 1;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002249 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002250 if (getStack(mLastStackId) == null) {
2251 break;
2252 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002253 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002254 return mLastStackId;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002255 }
2256
2257 void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002258 final TaskRecord task = anyTaskForIdLocked(taskId);
2259 if (task == null) {
2260 return;
2261 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002262 final ActivityStack stack = getStack(stackId);
2263 if (stack == null) {
2264 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
2265 return;
2266 }
Craig Mautner04a0ea62014-01-13 12:51:26 -08002267 task.stack.removeTask(task);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002268 stack.addTask(task, toTop);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002269 mWindowManager.addTask(taskId, stackId, toTop);
Craig Mautner05d29032013-05-03 13:40:13 -07002270 resumeTopActivitiesLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002271 }
2272
Craig Mautnerac6f8432013-07-17 13:24:59 -07002273 ActivityRecord findTaskLocked(ActivityRecord r) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07002274 if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r);
Craig Mautnere0a38842013-12-16 16:14:02 -08002275 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2276 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002277 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2278 final ActivityStack stack = stacks.get(stackNdx);
2279 if (!r.isApplicationActivity() && !stack.isHomeStack()) {
Craig Mautner1b4bf852014-05-26 15:06:32 -07002280 if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (home activity) " + stack);
2281 continue;
2282 }
2283 if (!stack.mActivityContainer.isEligibleForNewTasks()) {
2284 if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (new task not allowed) " +
2285 stack);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002286 continue;
2287 }
2288 final ActivityRecord ar = stack.findTaskLocked(r);
2289 if (ar != null) {
2290 return ar;
2291 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07002292 }
2293 }
Dianne Hackborn2a272d42013-10-16 13:34:33 -07002294 if (DEBUG_TASKS) Slog.d(TAG, "No task found");
Craig Mautner8849a5e2013-04-02 16:41:03 -07002295 return null;
2296 }
2297
2298 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002299 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2300 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002301 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2302 final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info);
2303 if (ar != null) {
2304 return ar;
2305 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07002306 }
2307 }
2308 return null;
2309 }
2310
Craig Mautner8d341ef2013-03-26 09:03:27 -07002311 void goingToSleepLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002312 scheduleSleepTimeout();
2313 if (!mGoingToSleep.isHeld()) {
2314 mGoingToSleep.acquire();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002315 if (mLaunchingActivity.isHeld()) {
2316 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2317 throw new IllegalStateException("Calling must be system uid");
Craig Mautner0eea92c2013-05-16 13:35:39 -07002318 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002319 mLaunchingActivity.release();
2320 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
Craig Mautner0eea92c2013-05-16 13:35:39 -07002321 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002322 }
Amith Yamasanice15e152013-09-19 12:30:32 -07002323 checkReadyForSleepLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002324 }
2325
2326 boolean shutdownLocked(int timeout) {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002327 goingToSleepLocked();
Craig Mautner0eea92c2013-05-16 13:35:39 -07002328
Craig Mautnerf4c909b2014-04-17 18:39:38 -07002329 boolean timedout = false;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002330 final long endTime = System.currentTimeMillis() + timeout;
2331 while (true) {
2332 boolean cantShutdown = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002333 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2334 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002335 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2336 cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
2337 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002338 }
2339 if (cantShutdown) {
2340 long timeRemaining = endTime - System.currentTimeMillis();
2341 if (timeRemaining > 0) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002342 try {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002343 mService.wait(timeRemaining);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002344 } catch (InterruptedException e) {
2345 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002346 } else {
2347 Slog.w(TAG, "Activity manager shutdown timed out");
2348 timedout = true;
2349 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002350 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002351 } else {
2352 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002353 }
2354 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002355
2356 // Force checkReadyForSleep to complete.
2357 mSleepTimeout = true;
2358 checkReadyForSleepLocked();
2359
Craig Mautner8d341ef2013-03-26 09:03:27 -07002360 return timedout;
2361 }
2362
2363 void comeOutOfSleepIfNeededLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002364 removeSleepTimeouts();
2365 if (mGoingToSleep.isHeld()) {
2366 mGoingToSleep.release();
2367 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002368 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2369 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002370 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2371 final ActivityStack stack = stacks.get(stackNdx);
2372 stack.awakeFromSleepingLocked();
2373 if (isFrontStack(stack)) {
2374 resumeTopActivitiesLocked();
2375 }
Craig Mautner5314a402013-09-26 12:40:16 -07002376 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002377 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002378 mGoingToSleepActivities.clear();
2379 }
2380
2381 void activitySleptLocked(ActivityRecord r) {
2382 mGoingToSleepActivities.remove(r);
2383 checkReadyForSleepLocked();
2384 }
2385
2386 void checkReadyForSleepLocked() {
2387 if (!mService.isSleepingOrShuttingDown()) {
2388 // Do not care.
2389 return;
2390 }
2391
2392 if (!mSleepTimeout) {
2393 boolean dontSleep = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002394 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2395 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002396 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2397 dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
2398 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002399 }
2400
2401 if (mStoppingActivities.size() > 0) {
2402 // Still need to tell some activities to stop; can't sleep yet.
2403 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2404 + mStoppingActivities.size() + " activities");
2405 scheduleIdleLocked();
2406 dontSleep = true;
2407 }
2408
2409 if (mGoingToSleepActivities.size() > 0) {
2410 // Still need to tell some activities to sleep; can't sleep yet.
2411 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2412 + mGoingToSleepActivities.size() + " activities");
2413 dontSleep = true;
2414 }
2415
2416 if (dontSleep) {
2417 return;
2418 }
2419 }
2420
Craig Mautnere0a38842013-12-16 16:14:02 -08002421 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2422 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002423 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2424 stacks.get(stackNdx).goToSleep();
2425 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002426 }
2427
2428 removeSleepTimeouts();
2429
2430 if (mGoingToSleep.isHeld()) {
2431 mGoingToSleep.release();
2432 }
2433 if (mService.mShuttingDown) {
2434 mService.notifyAll();
2435 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002436 }
2437
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002438 boolean reportResumedActivityLocked(ActivityRecord r) {
2439 final ActivityStack stack = r.task.stack;
2440 if (isFrontStack(stack)) {
Jeff Sharkey5782da72013-04-25 14:32:30 -07002441 mService.updateUsageStats(r, true);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002442 }
2443 if (allResumedActivitiesComplete()) {
2444 ensureActivitiesVisibleLocked(null, 0);
2445 mWindowManager.executeAppTransition();
2446 return true;
2447 }
2448 return false;
2449 }
2450
Craig Mautner8d341ef2013-03-26 09:03:27 -07002451 void handleAppCrashLocked(ProcessRecord app) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002452 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2453 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002454 final int numStacks = stacks.size();
2455 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2456 final ActivityStack stack = stacks.get(stackNdx);
2457 stack.handleAppCrashLocked(app);
2458 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002459 }
2460 }
2461
Craig Mautnerde4ef022013-04-07 19:01:33 -07002462 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
Craig Mautner580ea812013-04-25 12:58:38 -07002463 // First the front stacks. In case any are not fullscreen and are in front of home.
2464 boolean showHomeBehindStack = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002465 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2466 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002467 final int topStackNdx = stacks.size() - 1;
2468 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
2469 final ActivityStack stack = stacks.get(stackNdx);
2470 if (stackNdx == topStackNdx) {
2471 // Top stack.
2472 showHomeBehindStack =
2473 stack.ensureActivitiesVisibleLocked(starting, configChanges);
2474 } else {
2475 // Back stack.
2476 stack.ensureActivitiesVisibleLocked(starting, configChanges,
2477 showHomeBehindStack);
2478 }
Craig Mautner580ea812013-04-25 12:58:38 -07002479 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002480 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002481 }
2482
2483 void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002484 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2485 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002486 final int numStacks = stacks.size();
2487 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2488 final ActivityStack stack = stacks.get(stackNdx);
2489 stack.scheduleDestroyActivities(app, false, reason);
2490 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002491 }
2492 }
2493
2494 boolean switchUserLocked(int userId, UserStartedState uss) {
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002495 mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId());
2496 final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
Craig Mautner2420ead2013-04-01 17:13:20 -07002497 mCurrentUser = userId;
Craig Mautnerac6f8432013-07-17 13:24:59 -07002498
Craig Mautner858d8a62013-04-23 17:08:34 -07002499 mStartingUsers.add(uss);
Craig Mautnere0a38842013-12-16 16:14:02 -08002500 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2501 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002502 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002503 final ActivityStack stack = stacks.get(stackNdx);
2504 stack.switchUserLocked(userId);
2505 mWindowManager.moveTaskToTop(stack.topTask().taskId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002506 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07002507 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002508
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002509 ActivityStack stack = getStack(restoreStackId);
2510 if (stack == null) {
2511 stack = mHomeStack;
2512 }
2513 final boolean homeInFront = stack.isHomeStack();
Craig Mautnere0a38842013-12-16 16:14:02 -08002514 if (stack.isOnHomeDisplay()) {
2515 moveHomeStack(homeInFront);
2516 mWindowManager.moveTaskToTop(stack.topTask().taskId);
2517 } else {
2518 // Stack was moved to another display while user was swapped out.
2519 resumeHomeActivity(null);
2520 }
Craig Mautner93529a42013-10-04 15:03:13 -07002521 return homeInFront;
Craig Mautner2219a1b2013-03-25 09:44:30 -07002522 }
2523
Craig Mautnerde4ef022013-04-07 19:01:33 -07002524 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2525 int N = mStoppingActivities.size();
2526 if (N <= 0) return null;
2527
2528 ArrayList<ActivityRecord> stops = null;
2529
2530 final boolean nowVisible = allResumedActivitiesVisible();
2531 for (int i=0; i<N; i++) {
2532 ActivityRecord s = mStoppingActivities.get(i);
Craig Mautnera7f2bd42013-10-15 16:13:50 -07002533 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
Craig Mautnerde4ef022013-04-07 19:01:33 -07002534 + nowVisible + " waitingVisible=" + s.waitingVisible
2535 + " finishing=" + s.finishing);
2536 if (s.waitingVisible && nowVisible) {
2537 mWaitingVisibleActivities.remove(s);
2538 s.waitingVisible = false;
2539 if (s.finishing) {
2540 // If this activity is finishing, it is sitting on top of
2541 // everyone else but we now know it is no longer needed...
2542 // so get rid of it. Otherwise, we need to go through the
2543 // normal flow and hide it once we determine that it is
2544 // hidden by the activities in front of it.
2545 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002546 mWindowManager.setAppVisibility(s.appToken, false);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002547 }
2548 }
2549 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2550 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2551 if (stops == null) {
2552 stops = new ArrayList<ActivityRecord>();
2553 }
2554 stops.add(s);
2555 mStoppingActivities.remove(i);
2556 N--;
2557 i--;
2558 }
2559 }
2560
2561 return stops;
2562 }
2563
Craig Mautnercf910b02013-04-23 11:23:27 -07002564 void validateTopActivitiesLocked() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002565 // FIXME
2566/* for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2567 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautnercf910b02013-04-23 11:23:27 -07002568 final ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002569 final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
Craig Mautnercf910b02013-04-23 11:23:27 -07002570 if (isFrontStack(stack)) {
2571 if (r == null) {
2572 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2573 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002574 final ActivityRecord pausing = stack.mPausingActivity;
2575 if (pausing != null && pausing == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002576 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002577 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002578 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002579 if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002580 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002581 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002582 }
2583 }
2584 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002585 final ActivityRecord resumed = stack.mResumedActivity;
2586 if (resumed != null && resumed == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002587 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002588 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002589 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002590 if (r != null && (state == ActivityState.INITIALIZING
2591 || state == ActivityState.RESUMED)) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002592 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002593 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002594 }
2595 }
2596 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002597*/
Craig Mautner76ea2242013-05-15 11:40:05 -07002598 }
2599
Craig Mautner27084302013-03-25 08:05:25 -07002600 public void dump(PrintWriter pw, String prefix) {
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002601 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity=");
Craig Mautner27084302013-03-25 08:05:25 -07002602 pw.println(mDismissKeyguardOnNextActivity);
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002603 pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002604 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002605 pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
2606 pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
2607 pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
Craig Mautner95da1082014-02-24 17:54:35 -08002608 pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
Craig Mautner27084302013-03-25 08:05:25 -07002609 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002610
Craig Mautner20e72272013-04-01 13:45:53 -07002611 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002612 return getFocusedStack().getDumpActivitiesLocked(name);
Craig Mautner20e72272013-04-01 13:45:53 -07002613 }
2614
Dianne Hackborn390517b2013-05-30 15:03:32 -07002615 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2616 boolean needSep, String prefix) {
2617 if (activity != null) {
2618 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2619 if (needSep) {
2620 pw.println();
Dianne Hackborn390517b2013-05-30 15:03:32 -07002621 }
2622 pw.print(prefix);
2623 pw.println(activity);
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002624 return true;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002625 }
2626 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002627 return false;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002628 }
2629
Craig Mautner8d341ef2013-03-26 09:03:27 -07002630 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2631 boolean dumpClient, String dumpPackage) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002632 boolean printed = false;
2633 boolean needSep = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002634 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2635 ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
2636 pw.print("Display #"); pw.println(activityDisplay.mDisplayId);
2637 ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002638 final int numStacks = stacks.size();
2639 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2640 final ActivityStack stack = stacks.get(stackNdx);
2641 StringBuilder stackHeader = new StringBuilder(128);
2642 stackHeader.append(" Stack #");
2643 stackHeader.append(stack.mStackId);
2644 stackHeader.append(":");
2645 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
2646 needSep, stackHeader.toString());
2647 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false,
2648 !dumpAll, false, dumpPackage, true,
2649 " Running activities (most recent first):", null);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002650
Craig Mautner4a1cb222013-12-04 16:14:06 -08002651 needSep = printed;
2652 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
2653 " mPausingActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002654 if (pr) {
2655 printed = true;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002656 needSep = false;
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002657 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002658 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
2659 " mResumedActivity: ");
2660 if (pr) {
2661 printed = true;
2662 needSep = false;
2663 }
2664 if (dumpAll) {
2665 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
2666 " mLastPausedActivity: ");
2667 if (pr) {
2668 printed = true;
2669 needSep = true;
2670 }
2671 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
2672 needSep, " mLastNoHistoryActivity: ");
2673 }
2674 needSep = printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002675 }
2676 }
2677
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002678 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll,
2679 false, dumpPackage, true, " Activities waiting to finish:", null);
2680 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll,
2681 false, dumpPackage, true, " Activities waiting to stop:", null);
2682 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll,
2683 false, dumpPackage, true, " Activities waiting for another to become visible:",
2684 null);
2685 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2686 false, dumpPackage, true, " Activities waiting to sleep:", null);
2687 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2688 false, dumpPackage, true, " Activities waiting to sleep:", null);
Craig Mautnerf3333272013-04-22 10:55:53 -07002689
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002690 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002691 }
2692
Dianne Hackborn390517b2013-05-30 15:03:32 -07002693 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
Craig Mautner8d341ef2013-03-26 09:03:27 -07002694 String prefix, String label, boolean complete, boolean brief, boolean client,
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002695 String dumpPackage, boolean needNL, String header1, String header2) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002696 TaskRecord lastTask = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002697 String innerPrefix = null;
2698 String[] args = null;
2699 boolean printed = false;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002700 for (int i=list.size()-1; i>=0; i--) {
2701 final ActivityRecord r = list.get(i);
2702 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2703 continue;
2704 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002705 if (innerPrefix == null) {
2706 innerPrefix = prefix + " ";
2707 args = new String[0];
2708 }
2709 printed = true;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002710 final boolean full = !brief && (complete || !r.isInHistory());
2711 if (needNL) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07002712 pw.println("");
Craig Mautner8d341ef2013-03-26 09:03:27 -07002713 needNL = false;
2714 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002715 if (header1 != null) {
2716 pw.println(header1);
2717 header1 = null;
2718 }
2719 if (header2 != null) {
2720 pw.println(header2);
2721 header2 = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002722 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002723 if (lastTask != r.task) {
2724 lastTask = r.task;
2725 pw.print(prefix);
2726 pw.print(full ? "* " : " ");
2727 pw.println(lastTask);
2728 if (full) {
2729 lastTask.dump(pw, prefix + " ");
2730 } else if (complete) {
2731 // Complete + brief == give a summary. Isn't that obvious?!?
2732 if (lastTask.intent != null) {
2733 pw.print(prefix); pw.print(" ");
2734 pw.println(lastTask.intent.toInsecureStringWithClip());
2735 }
2736 }
2737 }
2738 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
2739 pw.print(" #"); pw.print(i); pw.print(": ");
2740 pw.println(r);
2741 if (full) {
2742 r.dump(pw, innerPrefix);
2743 } else if (complete) {
2744 // Complete + brief == give a summary. Isn't that obvious?!?
2745 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2746 if (r.app != null) {
2747 pw.print(innerPrefix); pw.println(r.app);
2748 }
2749 }
2750 if (client && r.app != null && r.app.thread != null) {
2751 // flush anything that is already in the PrintWriter since the thread is going
2752 // to write to the file descriptor directly
2753 pw.flush();
2754 try {
2755 TransferPipe tp = new TransferPipe();
2756 try {
2757 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2758 r.appToken, innerPrefix, args);
2759 // Short timeout, since blocking here can
2760 // deadlock with the application.
2761 tp.go(fd, 2000);
2762 } finally {
2763 tp.kill();
2764 }
2765 } catch (IOException e) {
2766 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2767 } catch (RemoteException e) {
2768 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2769 }
2770 needNL = true;
2771 }
2772 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002773 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002774 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002775
Craig Mautnerf3333272013-04-22 10:55:53 -07002776 void scheduleIdleTimeoutLocked(ActivityRecord next) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002777 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
Craig Mautnerc64f73e2013-04-24 16:44:56 -07002778 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2779 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
Craig Mautnerf3333272013-04-22 10:55:53 -07002780 }
2781
2782 final void scheduleIdleLocked() {
Craig Mautner05d29032013-05-03 13:40:13 -07002783 mHandler.sendEmptyMessage(IDLE_NOW_MSG);
Craig Mautnerf3333272013-04-22 10:55:53 -07002784 }
2785
2786 void removeTimeoutsForActivityLocked(ActivityRecord r) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002787 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07002788 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2789 }
2790
Craig Mautner05d29032013-05-03 13:40:13 -07002791 final void scheduleResumeTopActivities() {
Craig Mautner34b73df2014-01-12 21:11:08 -08002792 if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
2793 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2794 }
Craig Mautner05d29032013-05-03 13:40:13 -07002795 }
2796
Craig Mautner0eea92c2013-05-16 13:35:39 -07002797 void removeSleepTimeouts() {
2798 mSleepTimeout = false;
2799 mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2800 }
2801
2802 final void scheduleSleepTimeout() {
2803 removeSleepTimeouts();
2804 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2805 }
2806
Craig Mautner4a1cb222013-12-04 16:14:06 -08002807 @Override
2808 public void onDisplayAdded(int displayId) {
Craig Mautner6335fbc2014-06-13 17:18:47 -07002809 Slog.v(TAG, "Display added displayId=" + displayId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002810 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
2811 }
2812
2813 @Override
2814 public void onDisplayRemoved(int displayId) {
Craig Mautner6335fbc2014-06-13 17:18:47 -07002815 Slog.v(TAG, "Display removed displayId=" + displayId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002816 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
2817 }
2818
2819 @Override
2820 public void onDisplayChanged(int displayId) {
Craig Mautner6335fbc2014-06-13 17:18:47 -07002821 Slog.v(TAG, "Display changed displayId=" + displayId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002822 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
2823 }
2824
2825 public void handleDisplayAddedLocked(int displayId) {
Craig Mautner4504de52013-12-20 09:06:56 -08002826 boolean newDisplay;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002827 synchronized (mService) {
Craig Mautner4504de52013-12-20 09:06:56 -08002828 newDisplay = mActivityDisplays.get(displayId) == null;
2829 if (newDisplay) {
2830 ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
2831 mActivityDisplays.put(displayId, activityDisplay);
2832 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002833 }
Craig Mautner4504de52013-12-20 09:06:56 -08002834 if (newDisplay) {
2835 mWindowManager.onDisplayAdded(displayId);
2836 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002837 }
2838
2839 public void handleDisplayRemovedLocked(int displayId) {
2840 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002841 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2842 if (activityDisplay != null) {
2843 ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002844 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner34b73df2014-01-12 21:11:08 -08002845 stacks.get(stackNdx).mActivityContainer.detachLocked();
Craig Mautner4a1cb222013-12-04 16:14:06 -08002846 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002847 mActivityDisplays.remove(displayId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002848 }
2849 }
2850 mWindowManager.onDisplayRemoved(displayId);
2851 }
2852
2853 public void handleDisplayChangedLocked(int displayId) {
2854 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002855 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2856 if (activityDisplay != null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002857 // TODO: Update the bounds.
2858 }
2859 }
2860 mWindowManager.onDisplayChanged(displayId);
2861 }
2862
2863 StackInfo getStackInfo(ActivityStack stack) {
2864 StackInfo info = new StackInfo();
2865 mWindowManager.getStackBounds(stack.mStackId, info.bounds);
2866 info.displayId = Display.DEFAULT_DISPLAY;
2867 info.stackId = stack.mStackId;
2868
2869 ArrayList<TaskRecord> tasks = stack.getAllTasks();
2870 final int numTasks = tasks.size();
2871 int[] taskIds = new int[numTasks];
2872 String[] taskNames = new String[numTasks];
2873 for (int i = 0; i < numTasks; ++i) {
2874 final TaskRecord task = tasks.get(i);
2875 taskIds[i] = task.taskId;
2876 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
2877 : task.realActivity != null ? task.realActivity.flattenToString()
2878 : task.getTopActivity() != null ? task.getTopActivity().packageName
2879 : "unknown";
2880 }
2881 info.taskIds = taskIds;
2882 info.taskNames = taskNames;
2883 return info;
2884 }
2885
2886 StackInfo getStackInfoLocked(int stackId) {
2887 ActivityStack stack = getStack(stackId);
2888 if (stack != null) {
2889 return getStackInfo(stack);
2890 }
2891 return null;
2892 }
2893
2894 ArrayList<StackInfo> getAllStackInfosLocked() {
2895 ArrayList<StackInfo> list = new ArrayList<StackInfo>();
Craig Mautnere0a38842013-12-16 16:14:02 -08002896 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2897 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002898 for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
2899 list.add(getStackInfo(stacks.get(ndx)));
2900 }
2901 }
2902 return list;
2903 }
2904
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002905 private final class ActivityStackSupervisorHandler extends Handler {
Craig Mautnerf3333272013-04-22 10:55:53 -07002906
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002907 public ActivityStackSupervisorHandler(Looper looper) {
2908 super(looper);
2909 }
2910
Craig Mautnerf3333272013-04-22 10:55:53 -07002911 void activityIdleInternal(ActivityRecord r) {
2912 synchronized (mService) {
2913 activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
2914 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002915 }
2916
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002917 @Override
2918 public void handleMessage(Message msg) {
2919 switch (msg.what) {
Craig Mautnerf3333272013-04-22 10:55:53 -07002920 case IDLE_TIMEOUT_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002921 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002922 if (mService.mDidDexOpt) {
2923 mService.mDidDexOpt = false;
2924 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2925 nmsg.obj = msg.obj;
2926 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
2927 return;
2928 }
2929 // We don't at this point know if the activity is fullscreen,
2930 // so we need to be conservative and assume it isn't.
2931 activityIdleInternal((ActivityRecord)msg.obj);
2932 } break;
2933 case IDLE_NOW_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002934 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002935 activityIdleInternal((ActivityRecord)msg.obj);
2936 } break;
Craig Mautner05d29032013-05-03 13:40:13 -07002937 case RESUME_TOP_ACTIVITY_MSG: {
2938 synchronized (mService) {
2939 resumeTopActivitiesLocked();
2940 }
2941 } break;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002942 case SLEEP_TIMEOUT_MSG: {
2943 synchronized (mService) {
2944 if (mService.isSleepingOrShuttingDown()) {
2945 Slog.w(TAG, "Sleep timeout! Sleeping now.");
2946 mSleepTimeout = true;
2947 checkReadyForSleepLocked();
2948 }
2949 }
2950 } break;
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002951 case LAUNCH_TIMEOUT_MSG: {
2952 if (mService.mDidDexOpt) {
2953 mService.mDidDexOpt = false;
2954 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
2955 return;
2956 }
2957 synchronized (mService) {
2958 if (mLaunchingActivity.isHeld()) {
2959 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
2960 if (VALIDATE_WAKE_LOCK_CALLER
2961 && Binder.getCallingUid() != Process.myUid()) {
2962 throw new IllegalStateException("Calling must be system uid");
2963 }
2964 mLaunchingActivity.release();
2965 }
2966 }
2967 } break;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002968 case HANDLE_DISPLAY_ADDED: {
2969 handleDisplayAddedLocked(msg.arg1);
2970 } break;
2971 case HANDLE_DISPLAY_CHANGED: {
2972 handleDisplayChangedLocked(msg.arg1);
2973 } break;
2974 case HANDLE_DISPLAY_REMOVED: {
2975 handleDisplayRemovedLocked(msg.arg1);
2976 } break;
Craig Mautnere3a00d72014-04-16 08:31:19 -07002977 case CONTAINER_CALLBACK_VISIBILITY: {
2978 final ActivityContainer container = (ActivityContainer) msg.obj;
Craig Mautnerd94b47f2014-06-02 15:06:40 -07002979 final IActivityContainerCallback callback = container.mCallback;
2980 if (callback != null) {
2981 try {
2982 callback.setVisible(container.asBinder(), msg.arg1 == 1);
2983 } catch (RemoteException e) {
2984 }
Craig Mautnere3a00d72014-04-16 08:31:19 -07002985 }
Craig Mautnerd94b47f2014-06-02 15:06:40 -07002986 } break;
2987 case CONTAINER_CALLBACK_TASK_LIST_EMPTY: {
2988 final ActivityContainer container = (ActivityContainer) msg.obj;
2989 final IActivityContainerCallback callback = container.mCallback;
2990 if (callback != null) {
2991 try {
2992 callback.onAllActivitiesComplete(container.asBinder());
2993 } catch (RemoteException e) {
2994 }
2995 }
2996 } break;
Craig Mautner6335fbc2014-06-13 17:18:47 -07002997 case CONTAINER_TASK_LIST_EMPTY_TIMEOUT: {
2998 synchronized (mService) {
2999 Slog.w(TAG, "Timeout waiting for all activities in task to finish. " +
3000 msg.obj);
Craig Mautneree36c772014-07-16 14:56:05 -07003001 final ActivityContainer container = (ActivityContainer) msg.obj;
3002 container.mStack.finishAllActivitiesLocked(true);
3003 container.onTaskListEmptyLocked();
Craig Mautner6335fbc2014-06-13 17:18:47 -07003004 }
3005 } break;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07003006 }
3007 }
3008 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003009
Ying Wangb081a592014-04-22 15:20:16 -07003010 class ActivityContainer extends android.app.IActivityContainer.Stub {
Craig Mautner7f7bdb22014-04-22 19:57:19 -07003011 final static int FORCE_NEW_TASK_FLAGS = Intent.FLAG_ACTIVITY_NEW_TASK |
Craig Mautnere6d80f42014-06-10 13:31:02 -07003012 Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION;
Craig Mautner4a1cb222013-12-04 16:14:06 -08003013 final int mStackId;
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003014 IActivityContainerCallback mCallback = null;
Craig Mautner4a1cb222013-12-04 16:14:06 -08003015 final ActivityStack mStack;
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003016 ActivityRecord mParentActivity = null;
3017 String mIdString;
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003018
Craig Mautnere3a00d72014-04-16 08:31:19 -07003019 boolean mVisible = true;
3020
Craig Mautner4a1cb222013-12-04 16:14:06 -08003021 /** Display this ActivityStack is currently on. Null if not attached to a Display. */
Craig Mautnere0a38842013-12-16 16:14:02 -08003022 ActivityDisplay mActivityDisplay;
Craig Mautner4a1cb222013-12-04 16:14:06 -08003023
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003024 final static int CONTAINER_STATE_HAS_SURFACE = 0;
3025 final static int CONTAINER_STATE_NO_SURFACE = 1;
3026 final static int CONTAINER_STATE_FINISHING = 2;
3027 int mContainerState = CONTAINER_STATE_HAS_SURFACE;
3028
3029 ActivityContainer(int stackId) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003030 synchronized (mService) {
3031 mStackId = stackId;
3032 mStack = new ActivityStack(this);
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003033 mIdString = "ActivtyContainer{" + mStackId + "}";
Craig Mautner34b73df2014-01-12 21:11:08 -08003034 if (DEBUG_STACK) Slog.d(TAG, "Creating " + this);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003035 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003036 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08003037
Craig Mautnere0a38842013-12-16 16:14:02 -08003038 void attachToDisplayLocked(ActivityDisplay activityDisplay) {
Craig Mautner34b73df2014-01-12 21:11:08 -08003039 if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this
3040 + " to display=" + activityDisplay);
Craig Mautnere0a38842013-12-16 16:14:02 -08003041 mActivityDisplay = activityDisplay;
3042 mStack.mDisplayId = activityDisplay.mDisplayId;
3043 mStack.mStacks = activityDisplay.mStacks;
3044
3045 activityDisplay.attachActivities(mStack);
Craig Mautnerdf88d732014-01-27 09:21:32 -08003046 mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003047 }
3048
3049 @Override
Jeff Brown38f96e52014-02-11 14:32:56 -08003050 public void attachToDisplay(int displayId) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003051 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08003052 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3053 if (activityDisplay == null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003054 return;
3055 }
Craig Mautnere0a38842013-12-16 16:14:02 -08003056 attachToDisplayLocked(activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003057 }
3058 }
3059
3060 @Override
Jeff Brown38f96e52014-02-11 14:32:56 -08003061 public int getDisplayId() {
Craig Mautner6335fbc2014-06-13 17:18:47 -07003062 synchronized (mService) {
3063 if (mActivityDisplay != null) {
3064 return mActivityDisplay.mDisplayId;
3065 }
Craig Mautnere0a38842013-12-16 16:14:02 -08003066 }
3067 return -1;
Craig Mautner4a1cb222013-12-04 16:14:06 -08003068 }
3069
Jeff Brown38f96e52014-02-11 14:32:56 -08003070 @Override
3071 public boolean injectEvent(InputEvent event) {
3072 final long origId = Binder.clearCallingIdentity();
3073 try {
Craig Mautner6335fbc2014-06-13 17:18:47 -07003074 synchronized (mService) {
3075 if (mActivityDisplay != null) {
3076 return mInputManagerInternal.injectInputEvent(event,
3077 mActivityDisplay.mDisplayId,
3078 InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
3079 }
Jeff Brown38f96e52014-02-11 14:32:56 -08003080 }
3081 return false;
3082 } finally {
3083 Binder.restoreCallingIdentity(origId);
3084 }
3085 }
3086
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003087 @Override
3088 public void release() {
Craig Mautner6335fbc2014-06-13 17:18:47 -07003089 synchronized (mService) {
3090 if (mContainerState == CONTAINER_STATE_FINISHING) {
3091 return;
3092 }
3093 mContainerState = CONTAINER_STATE_FINISHING;
3094
3095 final Message msg =
3096 mHandler.obtainMessage(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this);
Craig Mautneree36c772014-07-16 14:56:05 -07003097 mHandler.sendMessageDelayed(msg, 2000);
Craig Mautner6335fbc2014-06-13 17:18:47 -07003098
3099 long origId = Binder.clearCallingIdentity();
3100 try {
Craig Mautneree36c772014-07-16 14:56:05 -07003101 mStack.finishAllActivitiesLocked(false);
Craig Mautner7f13ed32014-07-28 14:00:35 -07003102 removePendingActivityLaunchesLocked(mStack);
Craig Mautner6335fbc2014-06-13 17:18:47 -07003103 } finally {
3104 Binder.restoreCallingIdentity(origId);
3105 }
3106 }
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003107 }
3108
Craig Mautner34b73df2014-01-12 21:11:08 -08003109 private void detachLocked() {
3110 if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display="
3111 + mActivityDisplay + " Callers=" + Debug.getCallers(2));
Craig Mautnere0a38842013-12-16 16:14:02 -08003112 if (mActivityDisplay != null) {
3113 mActivityDisplay.detachActivitiesLocked(mStack);
3114 mActivityDisplay = null;
3115 mStack.mDisplayId = -1;
3116 mStack.mStacks = null;
Craig Mautnerdf88d732014-01-27 09:21:32 -08003117 mWindowManager.detachStack(mStackId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003118 }
3119 }
3120
3121 @Override
Craig Mautnere0a38842013-12-16 16:14:02 -08003122 public final int startActivity(Intent intent) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08003123 mService.enforceNotIsolatedCaller("ActivityContainer.startActivity");
Craig Mautnere0a38842013-12-16 16:14:02 -08003124 int userId = mService.handleIncomingUser(Binder.getCallingPid(),
3125 Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null);
3126 // TODO: Switch to user app stacks here.
Craig Mautner7f7bdb22014-04-22 19:57:19 -07003127 intent.addFlags(FORCE_NEW_TASK_FLAGS);
Craig Mautnere0a38842013-12-16 16:14:02 -08003128 String mimeType = intent.getType();
3129 if (mimeType == null && intent.getData() != null
3130 && "content".equals(intent.getData().getScheme())) {
3131 mimeType = mService.getProviderMimeType(intent.getData(), userId);
3132 }
3133 return startActivityMayWait(null, -1, null, intent, mimeType, null, null, 0, 0, null,
3134 null, null, null, null, userId, this);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003135 }
3136
3137 @Override
Craig Mautnerdf88d732014-01-27 09:21:32 -08003138 public final int startActivityIntentSender(IIntentSender intentSender) {
3139 mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
3140
3141 if (!(intentSender instanceof PendingIntentRecord)) {
3142 throw new IllegalArgumentException("Bad PendingIntent object");
3143 }
3144
3145 return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null,
Craig Mautner7f7bdb22014-04-22 19:57:19 -07003146 null, 0, FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this);
Craig Mautnerdf88d732014-01-27 09:21:32 -08003147 }
3148
Craig Mautner247ab652014-04-25 10:09:00 -07003149 private void checkEmbeddedAllowedInner(Intent intent, String resolvedType) {
3150 int userId = mService.handleIncomingUser(Binder.getCallingPid(),
3151 Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null);
3152 if (resolvedType == null) {
3153 resolvedType = intent.getType();
3154 if (resolvedType == null && intent.getData() != null
3155 && "content".equals(intent.getData().getScheme())) {
3156 resolvedType = mService.getProviderMimeType(intent.getData(), userId);
3157 }
3158 }
3159 ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, null, userId);
Craig Mautner05678d52014-05-05 12:32:40 -07003160 if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) {
Craig Mautner247ab652014-04-25 10:09:00 -07003161 throw new SecurityException(
3162 "Attempt to embed activity that has not set allowEmbedded=\"true\"");
3163 }
3164 }
3165
3166 /** Throw a SecurityException if allowEmbedded is not true */
3167 @Override
3168 public final void checkEmbeddedAllowed(Intent intent) {
3169 checkEmbeddedAllowedInner(intent, null);
3170 }
3171
3172 /** Throw a SecurityException if allowEmbedded is not true */
3173 @Override
3174 public final void checkEmbeddedAllowedIntentSender(IIntentSender intentSender) {
3175 if (!(intentSender instanceof PendingIntentRecord)) {
3176 throw new IllegalArgumentException("Bad PendingIntent object");
3177 }
3178 PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender;
3179 checkEmbeddedAllowedInner(pendingIntent.key.requestIntent,
3180 pendingIntent.key.requestResolvedType);
3181 }
3182
Craig Mautnerdf88d732014-01-27 09:21:32 -08003183 @Override
Craig Mautner4a1cb222013-12-04 16:14:06 -08003184 public IBinder asBinder() {
3185 return this;
3186 }
3187
Craig Mautner4504de52013-12-20 09:06:56 -08003188 @Override
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003189 public void setSurface(Surface surface, int width, int height, int density) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08003190 mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
Craig Mautner4504de52013-12-20 09:06:56 -08003191 }
3192
Craig Mautner4a1cb222013-12-04 16:14:06 -08003193 ActivityStackSupervisor getOuter() {
3194 return ActivityStackSupervisor.this;
3195 }
3196
Craig Mautner6335fbc2014-06-13 17:18:47 -07003197 boolean isAttachedLocked() {
Craig Mautnere0a38842013-12-16 16:14:02 -08003198 return mActivityDisplay != null;
Craig Mautner4a1cb222013-12-04 16:14:06 -08003199 }
3200
3201 void getBounds(Point outBounds) {
Craig Mautner6335fbc2014-06-13 17:18:47 -07003202 synchronized (mService) {
3203 if (mActivityDisplay != null) {
3204 mActivityDisplay.getBounds(outBounds);
3205 } else {
3206 outBounds.set(0, 0);
3207 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08003208 }
3209 }
Craig Mautner34b73df2014-01-12 21:11:08 -08003210
Craig Mautner6985bad2014-04-21 15:22:06 -07003211 // TODO: Make sure every change to ActivityRecord.visible results in a call to this.
Craig Mautnere3a00d72014-04-16 08:31:19 -07003212 void setVisible(boolean visible) {
3213 if (mVisible != visible) {
3214 mVisible = visible;
3215 if (mCallback != null) {
3216 mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0,
3217 0 /* unused */, this).sendToTarget();
3218 }
3219 }
3220 }
3221
Craig Mautner6985bad2014-04-21 15:22:06 -07003222 void setDrawn() {
3223 }
3224
Craig Mautner1b4bf852014-05-26 15:06:32 -07003225 // You can always start a new task on a regular ActivityStack.
3226 boolean isEligibleForNewTasks() {
3227 return true;
3228 }
3229
Craig Mautner6335fbc2014-06-13 17:18:47 -07003230 void onTaskListEmptyLocked() {
3231 mHandler.removeMessages(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this);
3232 if (!mStack.isHomeStack()) {
3233 detachLocked();
3234 deleteActivityContainer(this);
3235 }
Craig Mautnerd94b47f2014-06-02 15:06:40 -07003236 mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget();
3237 }
3238
Craig Mautner34b73df2014-01-12 21:11:08 -08003239 @Override
3240 public String toString() {
3241 return mIdString + (mActivityDisplay == null ? "N" : "A");
3242 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003243 }
3244
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003245 private class VirtualActivityContainer extends ActivityContainer {
3246 Surface mSurface;
Craig Mautner6985bad2014-04-21 15:22:06 -07003247 boolean mDrawn = false;
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003248
3249 VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) {
3250 super(getNextStackId());
3251 mParentActivity = parent;
3252 mCallback = callback;
3253 mContainerState = CONTAINER_STATE_NO_SURFACE;
Craig Mautner6335fbc2014-06-13 17:18:47 -07003254 mIdString = "VirtualActivityContainer{" + mStackId + ", parent=" + mParentActivity + "}";
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003255 }
3256
3257 @Override
3258 public void setSurface(Surface surface, int width, int height, int density) {
3259 super.setSurface(surface, width, height, density);
3260
3261 synchronized (mService) {
3262 final long origId = Binder.clearCallingIdentity();
3263 try {
3264 setSurfaceLocked(surface, width, height, density);
3265 } finally {
3266 Binder.restoreCallingIdentity(origId);
3267 }
3268 }
3269 }
3270
3271 private void setSurfaceLocked(Surface surface, int width, int height, int density) {
3272 if (mContainerState == CONTAINER_STATE_FINISHING) {
3273 return;
3274 }
3275 VirtualActivityDisplay virtualActivityDisplay =
3276 (VirtualActivityDisplay) mActivityDisplay;
3277 if (virtualActivityDisplay == null) {
3278 virtualActivityDisplay =
Craig Mautner6985bad2014-04-21 15:22:06 -07003279 new VirtualActivityDisplay(width, height, density);
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003280 mActivityDisplay = virtualActivityDisplay;
3281 mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay);
3282 attachToDisplayLocked(virtualActivityDisplay);
3283 }
3284
3285 if (mSurface != null) {
3286 mSurface.release();
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003287 }
3288
Craig Mautner6985bad2014-04-21 15:22:06 -07003289 mSurface = surface;
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003290 if (surface != null) {
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003291 mStack.resumeTopActivityLocked(null);
3292 } else {
3293 mContainerState = CONTAINER_STATE_NO_SURFACE;
Craig Mautner6985bad2014-04-21 15:22:06 -07003294 ((VirtualActivityDisplay) mActivityDisplay).setSurface(null);
Craig Mautnerd13a5582014-05-05 12:07:40 -07003295 if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) {
3296 mStack.startPausingLocked(false, true);
3297 }
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003298 }
Craig Mautner6985bad2014-04-21 15:22:06 -07003299
Craig Mautner6335fbc2014-06-13 17:18:47 -07003300 setSurfaceIfReadyLocked();
Craig Mautner6985bad2014-04-21 15:22:06 -07003301
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003302 if (DEBUG_STACK) Slog.d(TAG, "setSurface: " + this + " to display="
3303 + virtualActivityDisplay);
Craig Mautner6985bad2014-04-21 15:22:06 -07003304 }
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003305
Craig Mautner6985bad2014-04-21 15:22:06 -07003306 @Override
Craig Mautner6335fbc2014-06-13 17:18:47 -07003307 boolean isAttachedLocked() {
3308 return mSurface != null && super.isAttachedLocked();
Craig Mautnerd13a5582014-05-05 12:07:40 -07003309 }
3310
3311 @Override
Craig Mautner6985bad2014-04-21 15:22:06 -07003312 void setDrawn() {
3313 synchronized (mService) {
3314 mDrawn = true;
Craig Mautner6335fbc2014-06-13 17:18:47 -07003315 setSurfaceIfReadyLocked();
Craig Mautner6985bad2014-04-21 15:22:06 -07003316 }
3317 }
3318
Craig Mautner1b4bf852014-05-26 15:06:32 -07003319 // Never start a new task on an ActivityView if it isn't explicitly specified.
3320 @Override
3321 boolean isEligibleForNewTasks() {
3322 return false;
3323 }
3324
Craig Mautner6335fbc2014-06-13 17:18:47 -07003325 private void setSurfaceIfReadyLocked() {
3326 if (DEBUG_STACK) Slog.v(TAG, "setSurfaceIfReadyLocked: mDrawn=" + mDrawn +
Craig Mautner6985bad2014-04-21 15:22:06 -07003327 " mContainerState=" + mContainerState + " mSurface=" + mSurface);
3328 if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) {
3329 ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface);
3330 mContainerState = CONTAINER_STATE_HAS_SURFACE;
3331 }
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003332 }
3333 }
3334
Craig Mautner4a1cb222013-12-04 16:14:06 -08003335 /** Exactly one of these classes per Display in the system. Capable of holding zero or more
3336 * attached {@link ActivityStack}s */
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003337 class ActivityDisplay {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003338 /** Actual Display this object tracks. */
Craig Mautner34b73df2014-01-12 21:11:08 -08003339 int mDisplayId;
3340 Display mDisplay;
3341 DisplayInfo mDisplayInfo = new DisplayInfo();
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003342
Craig Mautner4a1cb222013-12-04 16:14:06 -08003343 /** All of the stacks on this display. Order matters, topmost stack is in front of all other
3344 * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
Craig Mautnere0a38842013-12-16 16:14:02 -08003345 final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003346
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003347 ActivityDisplay() {
3348 }
Craig Mautner4504de52013-12-20 09:06:56 -08003349
Craig Mautnere0a38842013-12-16 16:14:02 -08003350 ActivityDisplay(int displayId) {
Craig Mautner34b73df2014-01-12 21:11:08 -08003351 init(mDisplayManager.getDisplay(displayId));
Craig Mautner4504de52013-12-20 09:06:56 -08003352 }
3353
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003354 void init(Display display) {
Craig Mautner4504de52013-12-20 09:06:56 -08003355 mDisplay = display;
3356 mDisplayId = display.getDisplayId();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003357 mDisplay.getDisplayInfo(mDisplayInfo);
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003358 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08003359
3360 void attachActivities(ActivityStack stack) {
Craig Mautnere0a38842013-12-16 16:14:02 -08003361 if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId="
3362 + mDisplayId);
3363 mStacks.add(stack);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003364 }
3365
Craig Mautnere0a38842013-12-16 16:14:02 -08003366 void detachActivitiesLocked(ActivityStack stack) {
Craig Mautner34b73df2014-01-12 21:11:08 -08003367 if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack
Craig Mautnere0a38842013-12-16 16:14:02 -08003368 + " from displayId=" + mDisplayId);
3369 mStacks.remove(stack);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003370 }
3371
3372 void getBounds(Point bounds) {
3373 mDisplay.getDisplayInfo(mDisplayInfo);
3374 bounds.x = mDisplayInfo.appWidth;
3375 bounds.y = mDisplayInfo.appHeight;
3376 }
Craig Mautner34b73df2014-01-12 21:11:08 -08003377
3378 @Override
3379 public String toString() {
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003380 return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}";
3381 }
3382 }
3383
3384 class VirtualActivityDisplay extends ActivityDisplay {
3385 VirtualDisplay mVirtualDisplay;
3386
Craig Mautner6985bad2014-04-21 15:22:06 -07003387 VirtualActivityDisplay(int width, int height, int density) {
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003388 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
3389 mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, VIRTUAL_DISPLAY_BASE_NAME,
Craig Mautner6985bad2014-04-21 15:22:06 -07003390 width, height, density, null, DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003391 DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY);
3392
3393 init(mVirtualDisplay.getDisplay());
3394
3395 mWindowManager.handleDisplayAdded(mDisplayId);
3396 }
3397
3398 void setSurface(Surface surface) {
3399 if (mVirtualDisplay != null) {
3400 mVirtualDisplay.setSurface(surface);
3401 }
3402 }
3403
3404 @Override
3405 void detachActivitiesLocked(ActivityStack stack) {
3406 super.detachActivitiesLocked(stack);
3407 if (mVirtualDisplay != null) {
3408 mVirtualDisplay.release();
3409 mVirtualDisplay = null;
3410 }
3411 }
3412
3413 @Override
3414 public String toString() {
3415 return "VirtualActivityDisplay={" + mDisplayId + "}";
Craig Mautner34b73df2014-01-12 21:11:08 -08003416 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003417 }
Craig Mautner27084302013-03-25 08:05:25 -07003418}