blob: 5a79e662f29c998662e3c2e0432c74f7339d4642 [file] [log] [blame]
Craig Mautner27084302013-03-25 08:05:25 -07001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
Craig Mautner6170f732013-04-02 13:05:23 -070019import static android.Manifest.permission.START_ANY_ACTIVITY;
Craig Mautner29219d92013-04-16 20:19:12 -070020import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
21import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
Craig Mautner6170f732013-04-02 13:05:23 -070022import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Craig Mautner2420ead2013-04-01 17:13:20 -070023import static com.android.server.am.ActivityManagerService.localLOGV;
Craig Mautner23ac33b2013-04-01 16:26:35 -070024import static com.android.server.am.ActivityManagerService.DEBUG_CONFIGURATION;
Craig Mautnere7c58b62013-06-12 20:19:00 -070025import static com.android.server.am.ActivityManagerService.DEBUG_FOCUS;
Craig Mautner0eea92c2013-05-16 13:35:39 -070026import static com.android.server.am.ActivityManagerService.DEBUG_PAUSE;
Craig Mautner6170f732013-04-02 13:05:23 -070027import static com.android.server.am.ActivityManagerService.DEBUG_RESULTS;
Craig Mautner0eea92c2013-05-16 13:35:39 -070028import static com.android.server.am.ActivityManagerService.DEBUG_STACK;
Craig Mautner2420ead2013-04-01 17:13:20 -070029import static com.android.server.am.ActivityManagerService.DEBUG_SWITCH;
Craig Mautner8849a5e2013-04-02 16:41:03 -070030import static com.android.server.am.ActivityManagerService.DEBUG_TASKS;
31import static com.android.server.am.ActivityManagerService.DEBUG_USER_LEAVING;
Craig Mautner05d29032013-05-03 13:40:13 -070032import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
Craig Mautner8d341ef2013-03-26 09:03:27 -070033import static com.android.server.am.ActivityManagerService.TAG;
34
Craig Mautner2420ead2013-04-01 17:13:20 -070035import android.app.Activity;
Craig Mautner23ac33b2013-04-01 16:26:35 -070036import android.app.ActivityManager;
Craig Mautnerbdc748af2013-12-02 14:08:25 -080037import android.app.ActivityManager.StackInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070038import android.app.ActivityOptions;
39import android.app.AppGlobals;
Craig Mautner4a1cb222013-12-04 16:14:06 -080040import android.app.IActivityContainer;
41import android.app.IActivityContainerCallback;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070042import android.app.IActivityManager;
Craig Mautner23ac33b2013-04-01 16:26:35 -070043import android.app.IApplicationThread;
Craig Mautner20e72272013-04-01 13:45:53 -070044import android.app.IThumbnailReceiver;
Craig Mautner23ac33b2013-04-01 16:26:35 -070045import android.app.PendingIntent;
Craig Mautner20e72272013-04-01 13:45:53 -070046import android.app.ActivityManager.RunningTaskInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070047import android.app.IActivityManager.WaitResult;
Craig Mautner2420ead2013-04-01 17:13:20 -070048import android.app.ResultInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070049import android.content.ComponentName;
Craig Mautner2219a1b2013-03-25 09:44:30 -070050import android.content.Context;
Craig Mautner23ac33b2013-04-01 16:26:35 -070051import android.content.IIntentSender;
Craig Mautner2219a1b2013-03-25 09:44:30 -070052import android.content.Intent;
Craig Mautner23ac33b2013-04-01 16:26:35 -070053import android.content.IntentSender;
Craig Mautner2219a1b2013-03-25 09:44:30 -070054import android.content.pm.ActivityInfo;
Craig Mautner23ac33b2013-04-01 16:26:35 -070055import android.content.pm.ApplicationInfo;
56import android.content.pm.PackageManager;
57import android.content.pm.ResolveInfo;
58import android.content.res.Configuration;
Craig Mautner4a1cb222013-12-04 16:14:06 -080059import android.graphics.Point;
60import android.hardware.display.DisplayManager;
61import android.hardware.display.DisplayManager.DisplayListener;
Craig Mautner4504de52013-12-20 09:06:56 -080062import android.hardware.display.DisplayManagerGlobal;
63import android.hardware.display.VirtualDisplay;
Jeff Brown38f96e52014-02-11 14:32:56 -080064import android.hardware.input.InputManager;
65import android.hardware.input.InputManagerInternal;
Craig Mautner23ac33b2013-04-01 16:26:35 -070066import android.os.Binder;
Craig Mautner8d341ef2013-03-26 09:03:27 -070067import android.os.Bundle;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -070068import android.os.Debug;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070069import android.os.Handler;
Craig Mautner23ac33b2013-04-01 16:26:35 -070070import android.os.IBinder;
Craig Mautner2219a1b2013-03-25 09:44:30 -070071import android.os.Looper;
Craig Mautner2420ead2013-04-01 17:13:20 -070072import android.os.Message;
Craig Mautner23ac33b2013-04-01 16:26:35 -070073import android.os.ParcelFileDescriptor;
Craig Mautner0eea92c2013-05-16 13:35:39 -070074import android.os.PowerManager;
Craig Mautner7ea5bd42013-07-05 15:27:08 -070075import android.os.Process;
Craig Mautner8d341ef2013-03-26 09:03:27 -070076import android.os.RemoteException;
Craig Mautner23ac33b2013-04-01 16:26:35 -070077import android.os.SystemClock;
Craig Mautner6170f732013-04-02 13:05:23 -070078import android.os.UserHandle;
Craig Mautner2420ead2013-04-01 17:13:20 -070079import android.util.EventLog;
Craig Mautner8d341ef2013-03-26 09:03:27 -070080import android.util.Slog;
Craig Mautner4a1cb222013-12-04 16:14:06 -080081import android.util.SparseArray;
Craig Mautner2219a1b2013-03-25 09:44:30 -070082
Craig Mautner4a1cb222013-12-04 16:14:06 -080083import android.util.SparseIntArray;
Craig Mautnerbdc748af2013-12-02 14:08:25 -080084import android.view.Display;
Craig Mautner4a1cb222013-12-04 16:14:06 -080085import android.view.DisplayInfo;
Jeff Brown38f96e52014-02-11 14:32:56 -080086import android.view.InputEvent;
Craig Mautner4504de52013-12-20 09:06:56 -080087import android.view.Surface;
Craig Mautner23ac33b2013-04-01 16:26:35 -070088import com.android.internal.app.HeavyWeightSwitcherActivity;
Dianne Hackborncbfd23e2013-06-11 14:26:53 -070089import com.android.internal.os.TransferPipe;
Jeff Brown38f96e52014-02-11 14:32:56 -080090import com.android.server.LocalServices;
Craig Mautner6170f732013-04-02 13:05:23 -070091import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
Craig Mautner2420ead2013-04-01 17:13:20 -070092import com.android.server.am.ActivityStack.ActivityState;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -070093import com.android.server.wm.WindowManagerService;
Craig Mautner23ac33b2013-04-01 16:26:35 -070094
Craig Mautner8d341ef2013-03-26 09:03:27 -070095import java.io.FileDescriptor;
96import java.io.IOException;
Craig Mautner27084302013-03-25 08:05:25 -070097import java.io.PrintWriter;
Craig Mautner2219a1b2013-03-25 09:44:30 -070098import java.util.ArrayList;
Craig Mautner8d341ef2013-03-26 09:03:27 -070099import java.util.List;
Craig Mautner27084302013-03-25 08:05:25 -0700100
Craig Mautner4a1cb222013-12-04 16:14:06 -0800101public final class ActivityStackSupervisor implements DisplayListener {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700102 static final boolean DEBUG = ActivityManagerService.DEBUG || false;
103 static final boolean DEBUG_ADD_REMOVE = DEBUG || false;
104 static final boolean DEBUG_APP = DEBUG || false;
105 static final boolean DEBUG_SAVED_STATE = DEBUG || false;
Craig Mautnera7f2bd42013-10-15 16:13:50 -0700106 static final boolean DEBUG_STATES = DEBUG || false;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -0700107 static final boolean DEBUG_IDLE = 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 Mautner4a1cb222013-12-04 16:14:06 -0800130
Craig Mautner4504de52013-12-20 09:06:56 -0800131 private final static String VIRTUAL_DISPLAY_BASE_NAME = "ActivityViewVirtualDisplay";
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700132
133 // For debugging to make sure the caller when acquiring/releasing our
134 // wake lock is the system process.
135 static final boolean VALIDATE_WAKE_LOCK_CALLER = false;
Craig Mautnerf3333272013-04-22 10:55:53 -0700136
Craig Mautner27084302013-03-25 08:05:25 -0700137 final ActivityManagerService mService;
138
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700139 final ActivityStackSupervisorHandler mHandler;
140
141 /** Short cut */
142 WindowManagerService mWindowManager;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800143 DisplayManager mDisplayManager;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700144
Craig Mautner27084302013-03-25 08:05:25 -0700145 /** Dismiss the keyguard after the next activity is displayed? */
Craig Mautner5314a402013-09-26 12:40:16 -0700146 boolean mDismissKeyguardOnNextActivity = false;
Craig Mautner27084302013-03-25 08:05:25 -0700147
Craig Mautner8d341ef2013-03-26 09:03:27 -0700148 /** Identifier counter for all ActivityStacks */
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -0700149 private int mLastStackId = HOME_STACK_ID;
Craig Mautner8d341ef2013-03-26 09:03:27 -0700150
151 /** Task identifier that activities are currently being started in. Incremented each time a
152 * new task is created. */
153 private int mCurTaskId = 0;
154
Craig Mautner2420ead2013-04-01 17:13:20 -0700155 /** The current user */
156 private int mCurrentUser;
157
Craig Mautnere0a38842013-12-16 16:14:02 -0800158 /** The stack containing the launcher app. Assumed to always be attached to
159 * Display.DEFAULT_DISPLAY. */
Craig Mautner2219a1b2013-03-25 09:44:30 -0700160 private ActivityStack mHomeStack;
Craig Mautner20e72272013-04-01 13:45:53 -0700161
Craig Mautnere0a38842013-12-16 16:14:02 -0800162 /** The stack currently receiving input or launching the next activity. */
Craig Mautner29219d92013-04-16 20:19:12 -0700163 private ActivityStack mFocusedStack;
Craig Mautner8d341ef2013-03-26 09:03:27 -0700164
Craig Mautner4a1cb222013-12-04 16:14:06 -0800165 /** If this is the same as mFocusedStack then the activity on the top of the focused stack has
166 * been resumed. If stacks are changing position this will hold the old stack until the new
Craig Mautnere0a38842013-12-16 16:14:02 -0800167 * stack becomes resumed after which it will be set to mFocusedStack. */
Craig Mautner4a1cb222013-12-04 16:14:06 -0800168 private ActivityStack mLastFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700169
170 /** List of activities that are waiting for a new activity to become visible before completing
171 * whatever operation they are supposed to do. */
172 final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<ActivityRecord>();
173
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700174 /** List of processes waiting to find out about the next visible activity. */
175 final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible =
176 new ArrayList<IActivityManager.WaitResult>();
177
178 /** List of processes waiting to find out about the next launched activity. */
179 final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched =
180 new ArrayList<IActivityManager.WaitResult>();
181
Craig Mautnerde4ef022013-04-07 19:01:33 -0700182 /** List of activities that are ready to be stopped, but waiting for the next activity to
183 * settle down before doing so. */
184 final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<ActivityRecord>();
185
Craig Mautnerf3333272013-04-22 10:55:53 -0700186 /** List of activities that are ready to be finished, but waiting for the previous activity to
187 * settle down before doing so. It contains ActivityRecord objects. */
188 final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<ActivityRecord>();
189
Craig Mautner0eea92c2013-05-16 13:35:39 -0700190 /** List of activities that are in the process of going to sleep. */
191 final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<ActivityRecord>();
192
Craig Mautnerf3333272013-04-22 10:55:53 -0700193 /** List of ActivityRecord objects that have been finished and must still report back to a
194 * pending thumbnail receiver. */
195 final ArrayList<ActivityRecord> mCancelledThumbnails = new ArrayList<ActivityRecord>();
196
197 /** Used on user changes */
198 final ArrayList<UserStartedState> mStartingUsers = new ArrayList<UserStartedState>();
199
Craig Mautnerde4ef022013-04-07 19:01:33 -0700200 /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity
201 * is being brought in front of us. */
202 boolean mUserLeaving = false;
203
Craig Mautner0eea92c2013-05-16 13:35:39 -0700204 /** Set when we have taken too long waiting to go to sleep. */
205 boolean mSleepTimeout = false;
206
207 /**
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700208 * We don't want to allow the device to go to sleep while in the process
209 * of launching an activity. This is primarily to allow alarm intent
210 * receivers to launch an activity and get that to run before the device
211 * goes back to sleep.
212 */
213 final PowerManager.WakeLock mLaunchingActivity;
214
215 /**
Craig Mautner0eea92c2013-05-16 13:35:39 -0700216 * Set when the system is going to sleep, until we have
217 * successfully paused the current activity and released our wake lock.
218 * At that point the system is allowed to actually sleep.
219 */
220 final PowerManager.WakeLock mGoingToSleep;
221
Craig Mautner4f1df4f2013-10-15 15:44:14 -0700222 /** Stack id of the front stack when user switched, indexed by userId. */
223 SparseIntArray mUserStackInFront = new SparseIntArray(2);
Craig Mautner93529a42013-10-04 15:03:13 -0700224
Craig Mautner4504de52013-12-20 09:06:56 -0800225 // TODO: Add listener for removal of references.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800226 /** Mapping from (ActivityStack/TaskStack).mStackId to their current state */
Craig Mautnerf4c909b2014-04-17 18:39:38 -0700227 SparseArray<ActivityContainer> mActivityContainers = new SparseArray<ActivityContainer>();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800228
229 /** Mapping from displayId to display current state */
Craig Mautnerf4c909b2014-04-17 18:39:38 -0700230 private final SparseArray<ActivityDisplay> mActivityDisplays =
231 new SparseArray<ActivityDisplay>();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800232
Jeff Brown38f96e52014-02-11 14:32:56 -0800233 InputManagerInternal mInputManagerInternal;
234
Craig Mautner4a1cb222013-12-04 16:14:06 -0800235 public ActivityStackSupervisor(ActivityManagerService service) {
Craig Mautner27084302013-03-25 08:05:25 -0700236 mService = service;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800237 PowerManager pm = (PowerManager)mService.mContext.getSystemService(Context.POWER_SERVICE);
Craig Mautner0eea92c2013-05-16 13:35:39 -0700238 mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
Craig Mautner4a1cb222013-12-04 16:14:06 -0800239 mHandler = new ActivityStackSupervisorHandler(mService.mHandler.getLooper());
Craig Mautner7ea5bd42013-07-05 15:27:08 -0700240 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
241 throw new IllegalStateException("Calling must be system uid");
242 }
243 mLaunchingActivity =
244 pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
245 mLaunchingActivity.setReferenceCounted(false);
Craig Mautner2219a1b2013-03-25 09:44:30 -0700246 }
247
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700248 void setWindowManager(WindowManagerService wm) {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800249 synchronized (mService) {
250 mWindowManager = wm;
251
252 mDisplayManager =
253 (DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE);
254 mDisplayManager.registerDisplayListener(this, null);
255
256 Display[] displays = mDisplayManager.getDisplays();
257 for (int displayNdx = displays.length - 1; displayNdx >= 0; --displayNdx) {
258 final int displayId = displays[displayNdx].getDisplayId();
Craig Mautnere0a38842013-12-16 16:14:02 -0800259 ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
260 mActivityDisplays.put(displayId, activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -0800261 }
262
Craig Mautnerf4c909b2014-04-17 18:39:38 -0700263 createStackOnDisplay(HOME_STACK_ID, Display.DEFAULT_DISPLAY);
Craig Mautner4a1cb222013-12-04 16:14:06 -0800264 mHomeStack = mFocusedStack = mLastFocusedStack = getStack(HOME_STACK_ID);
Jeff Brown38f96e52014-02-11 14:32:56 -0800265
266 mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
Craig Mautner4a1cb222013-12-04 16:14:06 -0800267 }
Craig Mautner27084302013-03-25 08:05:25 -0700268 }
269
270 void dismissKeyguard() {
Craig Mautner5314a402013-09-26 12:40:16 -0700271 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen("");
Craig Mautner27084302013-03-25 08:05:25 -0700272 if (mDismissKeyguardOnNextActivity) {
273 mDismissKeyguardOnNextActivity = false;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700274 mWindowManager.dismissKeyguard();
Craig Mautner27084302013-03-25 08:05:25 -0700275 }
276 }
277
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700278 ActivityStack getFocusedStack() {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800279 return mFocusedStack;
Craig Mautner20e72272013-04-01 13:45:53 -0700280 }
281
Craig Mautnerde4ef022013-04-07 19:01:33 -0700282 ActivityStack getLastStack() {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800283 return mLastFocusedStack;
Craig Mautner2219a1b2013-03-25 09:44:30 -0700284 }
285
Craig Mautner4a1cb222013-12-04 16:14:06 -0800286 // TODO: Split into two methods isFrontStack for any visible stack and isFrontmostStack for the
287 // top of all visible stacks.
Craig Mautnerde4ef022013-04-07 19:01:33 -0700288 boolean isFrontStack(ActivityStack stack) {
Craig Mautnerdf88d732014-01-27 09:21:32 -0800289 final ActivityRecord parent = stack.mActivityContainer.mParentActivity;
290 if (parent != null) {
291 stack = parent.task.stack;
292 }
Craig Mautnere0a38842013-12-16 16:14:02 -0800293 ArrayList<ActivityStack> stacks = stack.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800294 if (stacks != null && !stacks.isEmpty()) {
295 return stack == stacks.get(stacks.size() - 1);
296 }
297 return false;
Craig Mautner20e72272013-04-01 13:45:53 -0700298 }
299
Craig Mautnerde4ef022013-04-07 19:01:33 -0700300 void moveHomeStack(boolean toFront) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800301 ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800302 int topNdx = stacks.size() - 1;
303 if (topNdx <= 0) {
304 return;
305 }
306 ActivityStack topStack = stacks.get(topNdx);
307 final boolean homeInFront = topStack == mHomeStack;
308 if (homeInFront != toFront) {
309 mLastFocusedStack = topStack;
310 stacks.remove(mHomeStack);
311 stacks.add(toFront ? topNdx : 0, mHomeStack);
312 mFocusedStack = stacks.get(topNdx);
313 if (DEBUG_STACK) Slog.d(TAG, "moveHomeTask: topStack old=" + topStack + " new="
314 + mFocusedStack);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700315 }
316 }
317
Craig Mautner8e569572013-10-11 17:36:59 -0700318 void moveHomeToTop() {
Craig Mautner69ada552013-04-18 13:51:51 -0700319 moveHomeStack(true);
Craig Mautner8e569572013-10-11 17:36:59 -0700320 mHomeStack.moveHomeTaskToTop();
321 }
322
323 boolean resumeHomeActivity(ActivityRecord prev) {
324 moveHomeToTop();
Craig Mautner69ada552013-04-18 13:51:51 -0700325 if (prev != null) {
Craig Mautnerae7ecab2013-09-18 11:48:14 -0700326 prev.task.mOnTopOfHome = false;
Craig Mautner69ada552013-04-18 13:51:51 -0700327 }
Craig Mautnera8a90e02013-06-28 15:24:50 -0700328 ActivityRecord r = mHomeStack.topRunningActivityLocked(null);
Craig Mautner760b2312013-10-11 11:57:07 -0700329 if (r != null && r.isHomeActivity()) {
Craig Mautnera8a90e02013-06-28 15:24:50 -0700330 mService.setFocusedActivityLocked(r);
Craig Mautner05d29032013-05-03 13:40:13 -0700331 return resumeTopActivitiesLocked(mHomeStack, prev, null);
Craig Mautner69ada552013-04-18 13:51:51 -0700332 }
333 return mService.startHomeActivityLocked(mCurrentUser);
334 }
335
Craig Mautner27084302013-03-25 08:05:25 -0700336 void setDismissKeyguard(boolean dismiss) {
Craig Mautner5314a402013-09-26 12:40:16 -0700337 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen(" dismiss=" + dismiss);
Craig Mautner27084302013-03-25 08:05:25 -0700338 mDismissKeyguardOnNextActivity = dismiss;
339 }
340
Craig Mautner8d341ef2013-03-26 09:03:27 -0700341 TaskRecord anyTaskForIdLocked(int id) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800342 int numDisplays = mActivityDisplays.size();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800343 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800344 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800345 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
346 ActivityStack stack = stacks.get(stackNdx);
347 TaskRecord task = stack.taskForIdLocked(id);
348 if (task != null) {
349 return task;
350 }
Craig Mautner8d341ef2013-03-26 09:03:27 -0700351 }
352 }
353 return null;
354 }
355
Craig Mautner6170f732013-04-02 13:05:23 -0700356 ActivityRecord isInAnyStackLocked(IBinder token) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800357 int numDisplays = mActivityDisplays.size();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800358 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800359 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800360 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
361 final ActivityRecord r = stacks.get(stackNdx).isInStackLocked(token);
362 if (r != null) {
363 return r;
364 }
Craig Mautner6170f732013-04-02 13:05:23 -0700365 }
366 }
367 return null;
368 }
369
Craig Mautner8d341ef2013-03-26 09:03:27 -0700370 int getNextTaskId() {
371 do {
372 mCurTaskId++;
373 if (mCurTaskId <= 0) {
374 mCurTaskId = 1;
375 }
376 } while (anyTaskForIdLocked(mCurTaskId) != null);
377 return mCurTaskId;
378 }
379
Craig Mautnerde4ef022013-04-07 19:01:33 -0700380 ActivityRecord resumedAppLocked() {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700381 ActivityStack stack = getFocusedStack();
382 if (stack == null) {
383 return null;
384 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700385 ActivityRecord resumedActivity = stack.mResumedActivity;
386 if (resumedActivity == null || resumedActivity.app == null) {
387 resumedActivity = stack.mPausingActivity;
388 if (resumedActivity == null || resumedActivity.app == null) {
389 resumedActivity = stack.topRunningActivityLocked(null);
390 }
391 }
392 return resumedActivity;
393 }
394
Mike Lockwoode63f6f72013-11-15 11:01:47 -0800395 boolean attachApplicationLocked(ProcessRecord app) throws Exception {
Craig Mautner20e72272013-04-01 13:45:53 -0700396 final String processName = app.processName;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800397 boolean didSomething = false;
Craig Mautnere0a38842013-12-16 16:14:02 -0800398 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
399 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800400 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
401 final ActivityStack stack = stacks.get(stackNdx);
402 if (!isFrontStack(stack)) {
403 continue;
404 }
405 ActivityRecord hr = stack.topRunningActivityLocked(null);
406 if (hr != null) {
407 if (hr.app == null && app.uid == hr.info.applicationInfo.uid
408 && processName.equals(hr.processName)) {
409 try {
410 if (realStartActivityLocked(hr, app, true, true)) {
411 didSomething = true;
412 }
413 } catch (Exception e) {
414 Slog.w(TAG, "Exception in new application when starting activity "
415 + hr.intent.getComponent().flattenToShortString(), e);
416 throw e;
Craig Mautner20e72272013-04-01 13:45:53 -0700417 }
Craig Mautner20e72272013-04-01 13:45:53 -0700418 }
Craig Mautner20e72272013-04-01 13:45:53 -0700419 }
420 }
421 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -0700422 if (!didSomething) {
423 ensureActivitiesVisibleLocked(null, 0);
424 }
Craig Mautner20e72272013-04-01 13:45:53 -0700425 return didSomething;
426 }
427
428 boolean allResumedActivitiesIdle() {
Craig Mautnere0a38842013-12-16 16:14:02 -0800429 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
430 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800431 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
432 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautner34b73df2014-01-12 21:11:08 -0800433 if (!isFrontStack(stack) || stack.numActivities() == 0) {
Craig Mautner4a1cb222013-12-04 16:14:06 -0800434 continue;
435 }
436 final ActivityRecord resumedActivity = stack.mResumedActivity;
437 if (resumedActivity == null || !resumedActivity.idle) {
Craig Mautner34b73df2014-01-12 21:11:08 -0800438 if (DEBUG_STATES) Slog.d(TAG, "allResumedActivitiesIdle: stack="
439 + stack.mStackId + " " + resumedActivity + " not idle");
Craig Mautner4a1cb222013-12-04 16:14:06 -0800440 return false;
441 }
Craig Mautner20e72272013-04-01 13:45:53 -0700442 }
443 }
444 return true;
445 }
446
Craig Mautnerde4ef022013-04-07 19:01:33 -0700447 boolean allResumedActivitiesComplete() {
Craig Mautnere0a38842013-12-16 16:14:02 -0800448 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
449 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800450 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
451 final ActivityStack stack = stacks.get(stackNdx);
452 if (isFrontStack(stack)) {
453 final ActivityRecord r = stack.mResumedActivity;
454 if (r != null && r.state != ActivityState.RESUMED) {
455 return false;
456 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700457 }
458 }
459 }
460 // TODO: Not sure if this should check if all Paused are complete too.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800461 if (DEBUG_STACK) Slog.d(TAG,
462 "allResumedActivitiesComplete: mLastFocusedStack changing from=" +
463 mLastFocusedStack + " to=" + mFocusedStack);
464 mLastFocusedStack = mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700465 return true;
466 }
467
468 boolean allResumedActivitiesVisible() {
Craig Mautnere0a38842013-12-16 16:14:02 -0800469 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
470 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800471 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
472 final ActivityStack stack = stacks.get(stackNdx);
473 final ActivityRecord r = stack.mResumedActivity;
474 if (r != null && (!r.nowVisible || r.waitingVisible)) {
475 return false;
476 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700477 }
478 }
479 return true;
480 }
481
Craig Mautner2acc3892013-09-23 10:28:14 -0700482 /**
483 * Pause all activities in either all of the stacks or just the back stacks.
484 * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving().
Craig Mautner2acc3892013-09-23 10:28:14 -0700485 * @return true if any activity was paused as a result of this call.
486 */
Craig Mautner5314a402013-09-26 12:40:16 -0700487 boolean pauseBackStacks(boolean userLeaving) {
Craig Mautnercf910b02013-04-23 11:23:27 -0700488 boolean someActivityPaused = false;
Craig Mautnere0a38842013-12-16 16:14:02 -0800489 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
490 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800491 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
492 final ActivityStack stack = stacks.get(stackNdx);
493 if (!isFrontStack(stack) && stack.mResumedActivity != null) {
494 if (DEBUG_STATES) Slog.d(TAG, "pauseBackStacks: stack=" + stack +
495 " mResumedActivity=" + stack.mResumedActivity);
496 stack.startPausingLocked(userLeaving, false);
497 someActivityPaused = true;
498 }
Craig Mautnercf910b02013-04-23 11:23:27 -0700499 }
500 }
501 return someActivityPaused;
502 }
503
Craig Mautnerde4ef022013-04-07 19:01:33 -0700504 boolean allPausedActivitiesComplete() {
Craig Mautnerac6f8432013-07-17 13:24:59 -0700505 boolean pausing = true;
Craig Mautnere0a38842013-12-16 16:14:02 -0800506 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
507 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800508 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
509 final ActivityStack stack = stacks.get(stackNdx);
510 final ActivityRecord r = stack.mPausingActivity;
511 if (r != null && r.state != ActivityState.PAUSED
512 && r.state != ActivityState.STOPPED
513 && r.state != ActivityState.STOPPING) {
514 if (DEBUG_STATES) {
515 Slog.d(TAG, "allPausedActivitiesComplete: r=" + r + " state=" + r.state);
516 pausing = false;
517 } else {
518 return false;
519 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700520 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700521 }
522 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700523 return pausing;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700524 }
525
Craig Mautnerdf88d732014-01-27 09:21:32 -0800526 void pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping) {
Craig Mautnerd94b47f2014-06-02 15:06:40 -0700527 // TODO: Put all stacks in supervisor and iterate through them instead.
Craig Mautnerdf88d732014-01-27 09:21:32 -0800528 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
529 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
530 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
531 final ActivityStack stack = stacks.get(stackNdx);
532 if (stack.mResumedActivity != null &&
533 stack.mActivityContainer.mParentActivity == parent) {
534 stack.startPausingLocked(userLeaving, uiSleeping);
535 }
536 }
537 }
538 }
539
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700540 void reportActivityVisibleLocked(ActivityRecord r) {
Craig Mautner858d8a62013-04-23 17:08:34 -0700541 for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700542 WaitResult w = mWaitingActivityVisible.get(i);
543 w.timeout = false;
544 if (r != null) {
545 w.who = new ComponentName(r.info.packageName, r.info.name);
546 }
547 w.totalTime = SystemClock.uptimeMillis() - w.thisTime;
548 w.thisTime = w.totalTime;
549 }
550 mService.notifyAll();
551 dismissKeyguard();
552 }
553
554 void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r,
555 long thisTime, long totalTime) {
556 for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
Craig Mautnerc64f73e2013-04-24 16:44:56 -0700557 WaitResult w = mWaitingActivityLaunched.remove(i);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700558 w.timeout = timeout;
559 if (r != null) {
560 w.who = new ComponentName(r.info.packageName, r.info.name);
561 }
562 w.thisTime = thisTime;
563 w.totalTime = totalTime;
564 }
565 mService.notifyAll();
566 }
567
Craig Mautner29219d92013-04-16 20:19:12 -0700568 ActivityRecord topRunningActivityLocked() {
Craig Mautner1602ec22013-05-12 10:24:27 -0700569 final ActivityStack focusedStack = getFocusedStack();
570 ActivityRecord r = focusedStack.topRunningActivityLocked(null);
571 if (r != null) {
572 return r;
Craig Mautner29219d92013-04-16 20:19:12 -0700573 }
Craig Mautner1602ec22013-05-12 10:24:27 -0700574
Craig Mautner4a1cb222013-12-04 16:14:06 -0800575 // Return to the home stack.
Craig Mautnere0a38842013-12-16 16:14:02 -0800576 final ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800577 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
578 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautnerac6f8432013-07-17 13:24:59 -0700579 if (stack != focusedStack && isFrontStack(stack)) {
Craig Mautner29219d92013-04-16 20:19:12 -0700580 r = stack.topRunningActivityLocked(null);
581 if (r != null) {
582 return r;
583 }
584 }
585 }
586 return null;
587 }
588
Craig Mautner20e72272013-04-01 13:45:53 -0700589 ActivityRecord getTasksLocked(int maxNum, IThumbnailReceiver receiver,
590 PendingThumbnailsRecord pending, List<RunningTaskInfo> list) {
591 ActivityRecord r = null;
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700592
593 // Gather all of the running tasks for each stack into runningTaskLists.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800594 ArrayList<ArrayList<RunningTaskInfo>> runningTaskLists =
595 new ArrayList<ArrayList<RunningTaskInfo>>();
Craig Mautnere0a38842013-12-16 16:14:02 -0800596 final int numDisplays = mActivityDisplays.size();
Craig Mautner4a1cb222013-12-04 16:14:06 -0800597 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -0800598 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800599 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
600 final ActivityStack stack = stacks.get(stackNdx);
601 ArrayList<RunningTaskInfo> stackTaskList = new ArrayList<RunningTaskInfo>();
602 runningTaskLists.add(stackTaskList);
603 final ActivityRecord ar = stack.getTasksLocked(receiver, pending, stackTaskList);
604 if (r == null && isFrontStack(stack)) {
605 r = ar;
606 }
Craig Mautner20e72272013-04-01 13:45:53 -0700607 }
608 }
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700609
610 // The lists are already sorted from most recent to oldest. Just pull the most recent off
611 // each list and add it to list. Stop when all lists are empty or maxNum reached.
612 while (maxNum > 0) {
613 long mostRecentActiveTime = Long.MIN_VALUE;
614 ArrayList<RunningTaskInfo> selectedStackList = null;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800615 final int numTaskLists = runningTaskLists.size();
616 for (int stackNdx = 0; stackNdx < numTaskLists; ++stackNdx) {
617 ArrayList<RunningTaskInfo> stackTaskList = runningTaskLists.get(stackNdx);
Craig Mautnerc0fd8052013-09-19 11:20:17 -0700618 if (!stackTaskList.isEmpty()) {
619 final long lastActiveTime = stackTaskList.get(0).lastActiveTime;
620 if (lastActiveTime > mostRecentActiveTime) {
621 mostRecentActiveTime = lastActiveTime;
622 selectedStackList = stackTaskList;
623 }
624 }
625 }
626 if (selectedStackList != null) {
627 list.add(selectedStackList.remove(0));
628 --maxNum;
629 } else {
630 break;
631 }
632 }
633
Craig Mautner20e72272013-04-01 13:45:53 -0700634 return r;
635 }
636
Craig Mautner23ac33b2013-04-01 16:26:35 -0700637 ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
638 String profileFile, ParcelFileDescriptor profileFd, int userId) {
639 // Collect information about the target of the Intent.
640 ActivityInfo aInfo;
641 try {
642 ResolveInfo rInfo =
643 AppGlobals.getPackageManager().resolveIntent(
644 intent, resolvedType,
645 PackageManager.MATCH_DEFAULT_ONLY
646 | ActivityManagerService.STOCK_PM_FLAGS, userId);
647 aInfo = rInfo != null ? rInfo.activityInfo : null;
648 } catch (RemoteException e) {
649 aInfo = null;
650 }
651
652 if (aInfo != null) {
653 // Store the found target back into the intent, because now that
654 // we have it we never want to do this again. For example, if the
655 // user navigates back to this point in the history, we should
656 // always restart the exact same activity.
657 intent.setComponent(new ComponentName(
658 aInfo.applicationInfo.packageName, aInfo.name));
659
660 // Don't debug things in the system process
661 if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) {
662 if (!aInfo.processName.equals("system")) {
663 mService.setDebugApp(aInfo.processName, true, false);
664 }
665 }
666
667 if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) {
668 if (!aInfo.processName.equals("system")) {
669 mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName);
670 }
671 }
672
673 if (profileFile != null) {
674 if (!aInfo.processName.equals("system")) {
675 mService.setProfileApp(aInfo.applicationInfo, aInfo.processName,
676 profileFile, profileFd,
677 (startFlags&ActivityManager.START_FLAG_AUTO_STOP_PROFILER) != 0);
678 }
679 }
680 }
681 return aInfo;
682 }
683
Craig Mautner2219a1b2013-03-25 09:44:30 -0700684 void startHomeActivity(Intent intent, ActivityInfo aInfo) {
Craig Mautner8e569572013-10-11 17:36:59 -0700685 moveHomeToTop();
Craig Mautner6170f732013-04-02 13:05:23 -0700686 startActivityLocked(null, intent, null, aInfo, null, null, 0, 0, 0, null, 0,
Craig Mautnere0a38842013-12-16 16:14:02 -0800687 null, false, null, null);
Craig Mautner8d341ef2013-03-26 09:03:27 -0700688 }
689
Craig Mautner23ac33b2013-04-01 16:26:35 -0700690 final int startActivityMayWait(IApplicationThread caller, int callingUid,
691 String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
692 String resultWho, int requestCode, int startFlags, String profileFile,
693 ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config,
Craig Mautnere0a38842013-12-16 16:14:02 -0800694 Bundle options, int userId, IActivityContainer iContainer) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700695 // Refuse possible leaked file descriptors
696 if (intent != null && intent.hasFileDescriptors()) {
697 throw new IllegalArgumentException("File descriptors passed in Intent");
698 }
699 boolean componentSpecified = intent.getComponent() != null;
700
701 // Don't modify the client's object!
702 intent = new Intent(intent);
703
704 // Collect information about the target of the Intent.
705 ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
706 profileFile, profileFd, userId);
707
Craig Mautnere0a38842013-12-16 16:14:02 -0800708 ActivityContainer container = (ActivityContainer)iContainer;
Craig Mautner23ac33b2013-04-01 16:26:35 -0700709 synchronized (mService) {
710 int callingPid;
711 if (callingUid >= 0) {
712 callingPid = -1;
713 } else if (caller == null) {
714 callingPid = Binder.getCallingPid();
715 callingUid = Binder.getCallingUid();
716 } else {
717 callingPid = callingUid = -1;
718 }
719
Craig Mautnere0a38842013-12-16 16:14:02 -0800720 final ActivityStack stack;
721 if (container == null || container.mStack.isOnHomeDisplay()) {
722 stack = getFocusedStack();
723 } else {
724 stack = container.mStack;
725 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700726 stack.mConfigWillChange = config != null
Craig Mautner23ac33b2013-04-01 16:26:35 -0700727 && mService.mConfiguration.diff(config) != 0;
728 if (DEBUG_CONFIGURATION) Slog.v(TAG,
Craig Mautnerde4ef022013-04-07 19:01:33 -0700729 "Starting activity when config will change = " + stack.mConfigWillChange);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700730
731 final long origId = Binder.clearCallingIdentity();
732
733 if (aInfo != null &&
734 (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
735 // This may be a heavy-weight process! Check to see if we already
736 // have another, different heavy-weight process running.
737 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
738 if (mService.mHeavyWeightProcess != null &&
739 (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid ||
740 !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700741 int realCallingUid = callingUid;
742 if (caller != null) {
743 ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
744 if (callerApp != null) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700745 realCallingUid = callerApp.info.uid;
746 } else {
747 Slog.w(TAG, "Unable to find app for caller " + caller
Craig Mautner76ea2242013-05-15 11:40:05 -0700748 + " (pid=" + callingPid + ") when starting: "
Craig Mautner23ac33b2013-04-01 16:26:35 -0700749 + intent.toString());
750 ActivityOptions.abort(options);
751 return ActivityManager.START_PERMISSION_DENIED;
752 }
753 }
754
755 IIntentSender target = mService.getIntentSenderLocked(
756 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
757 realCallingUid, userId, null, null, 0, new Intent[] { intent },
758 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
759 | PendingIntent.FLAG_ONE_SHOT, null);
760
761 Intent newIntent = new Intent();
762 if (requestCode >= 0) {
763 // Caller is requesting a result.
764 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
765 }
766 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
767 new IntentSender(target));
768 if (mService.mHeavyWeightProcess.activities.size() > 0) {
769 ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0);
770 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
771 hist.packageName);
772 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
773 hist.task.taskId);
774 }
775 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
776 aInfo.packageName);
777 newIntent.setFlags(intent.getFlags());
778 newIntent.setClassName("android",
779 HeavyWeightSwitcherActivity.class.getName());
780 intent = newIntent;
781 resolvedType = null;
782 caller = null;
783 callingUid = Binder.getCallingUid();
784 callingPid = Binder.getCallingPid();
785 componentSpecified = true;
786 try {
787 ResolveInfo rInfo =
788 AppGlobals.getPackageManager().resolveIntent(
789 intent, null,
790 PackageManager.MATCH_DEFAULT_ONLY
791 | ActivityManagerService.STOCK_PM_FLAGS, userId);
792 aInfo = rInfo != null ? rInfo.activityInfo : null;
793 aInfo = mService.getActivityInfoForUser(aInfo, userId);
794 } catch (RemoteException e) {
795 aInfo = null;
796 }
797 }
798 }
799 }
800
Craig Mautnere0a38842013-12-16 16:14:02 -0800801 int res = startActivityLocked(caller, intent, resolvedType, aInfo, resultTo, resultWho,
802 requestCode, callingPid, callingUid, callingPackage, startFlags, options,
803 componentSpecified, null, container);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700804
Craig Mautnerde4ef022013-04-07 19:01:33 -0700805 if (stack.mConfigWillChange) {
Craig Mautner23ac33b2013-04-01 16:26:35 -0700806 // If the caller also wants to switch to a new configuration,
807 // do so now. This allows a clean switch, as we are waiting
808 // for the current activity to pause (so we will not destroy
809 // it), and have not yet started the next activity.
810 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
811 "updateConfiguration()");
Craig Mautnerde4ef022013-04-07 19:01:33 -0700812 stack.mConfigWillChange = false;
Craig Mautner23ac33b2013-04-01 16:26:35 -0700813 if (DEBUG_CONFIGURATION) Slog.v(TAG,
814 "Updating to new configuration after starting activity.");
815 mService.updateConfigurationLocked(config, null, false, false);
816 }
817
818 Binder.restoreCallingIdentity(origId);
819
820 if (outResult != null) {
821 outResult.result = res;
822 if (res == ActivityManager.START_SUCCESS) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700823 mWaitingActivityLaunched.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700824 do {
825 try {
826 mService.wait();
827 } catch (InterruptedException e) {
828 }
829 } while (!outResult.timeout && outResult.who == null);
830 } else if (res == ActivityManager.START_TASK_TO_FRONT) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700831 ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700832 if (r.nowVisible) {
833 outResult.timeout = false;
834 outResult.who = new ComponentName(r.info.packageName, r.info.name);
835 outResult.totalTime = 0;
836 outResult.thisTime = 0;
837 } else {
838 outResult.thisTime = SystemClock.uptimeMillis();
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700839 mWaitingActivityVisible.add(outResult);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700840 do {
841 try {
842 mService.wait();
843 } catch (InterruptedException e) {
844 }
845 } while (!outResult.timeout && outResult.who == null);
846 }
847 }
848 }
849
850 return res;
851 }
852 }
853
854 final int startActivities(IApplicationThread caller, int callingUid, String callingPackage,
855 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
856 Bundle options, int userId) {
857 if (intents == null) {
858 throw new NullPointerException("intents is null");
859 }
860 if (resolvedTypes == null) {
861 throw new NullPointerException("resolvedTypes is null");
862 }
863 if (intents.length != resolvedTypes.length) {
864 throw new IllegalArgumentException("intents are length different than resolvedTypes");
865 }
866
Craig Mautner23ac33b2013-04-01 16:26:35 -0700867
868 int callingPid;
869 if (callingUid >= 0) {
870 callingPid = -1;
871 } else if (caller == null) {
872 callingPid = Binder.getCallingPid();
873 callingUid = Binder.getCallingUid();
874 } else {
875 callingPid = callingUid = -1;
876 }
877 final long origId = Binder.clearCallingIdentity();
878 try {
879 synchronized (mService) {
Craig Mautner76ea2242013-05-15 11:40:05 -0700880 ActivityRecord[] outActivity = new ActivityRecord[1];
Craig Mautner23ac33b2013-04-01 16:26:35 -0700881 for (int i=0; i<intents.length; i++) {
882 Intent intent = intents[i];
883 if (intent == null) {
884 continue;
885 }
886
887 // Refuse possible leaked file descriptors
888 if (intent != null && intent.hasFileDescriptors()) {
889 throw new IllegalArgumentException("File descriptors passed in Intent");
890 }
891
892 boolean componentSpecified = intent.getComponent() != null;
893
894 // Don't modify the client's object!
895 intent = new Intent(intent);
896
897 // Collect information about the target of the Intent.
898 ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i],
899 0, null, null, userId);
900 // TODO: New, check if this is correct
901 aInfo = mService.getActivityInfoForUser(aInfo, userId);
902
903 if (aInfo != null &&
904 (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE)
905 != 0) {
906 throw new IllegalArgumentException(
907 "FLAG_CANT_SAVE_STATE not supported here");
908 }
909
910 Bundle theseOptions;
911 if (options != null && i == intents.length-1) {
912 theseOptions = options;
913 } else {
914 theseOptions = null;
915 }
Craig Mautner6170f732013-04-02 13:05:23 -0700916 int res = startActivityLocked(caller, intent, resolvedTypes[i],
Craig Mautner23ac33b2013-04-01 16:26:35 -0700917 aInfo, resultTo, null, -1, callingPid, callingUid, callingPackage,
Craig Mautnere0a38842013-12-16 16:14:02 -0800918 0, theseOptions, componentSpecified, outActivity, null);
Craig Mautner23ac33b2013-04-01 16:26:35 -0700919 if (res < 0) {
920 return res;
921 }
922
923 resultTo = outActivity[0] != null ? outActivity[0].appToken : null;
924 }
925 }
926 } finally {
927 Binder.restoreCallingIdentity(origId);
928 }
929
930 return ActivityManager.START_SUCCESS;
931 }
932
Craig Mautner2420ead2013-04-01 17:13:20 -0700933 final boolean realStartActivityLocked(ActivityRecord r,
934 ProcessRecord app, boolean andResume, boolean checkConfig)
935 throws RemoteException {
936
937 r.startFreezingScreenLocked(app, 0);
Craig Mautnera7f2bd42013-10-15 16:13:50 -0700938 if (false) Slog.d(TAG, "realStartActivity: setting app visibility true");
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700939 mWindowManager.setAppVisibility(r.appToken, true);
Craig Mautner2420ead2013-04-01 17:13:20 -0700940
941 // schedule launch ticks to collect information about slow apps.
942 r.startLaunchTickingLocked();
943
944 // Have the window manager re-evaluate the orientation of
945 // the screen based on the new activity order. Note that
946 // as a result of this, it can call back into the activity
947 // manager with a new orientation. We don't care about that,
948 // because the activity is not currently running so we are
949 // just restarting it anyway.
950 if (checkConfig) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700951 Configuration config = mWindowManager.updateOrientationFromAppTokens(
Craig Mautner2420ead2013-04-01 17:13:20 -0700952 mService.mConfiguration,
953 r.mayFreezeScreenLocked(app) ? r.appToken : null);
954 mService.updateConfigurationLocked(config, r, false, false);
955 }
956
957 r.app = app;
958 app.waitingToKill = null;
959 r.launchCount++;
960 r.lastLaunchTime = SystemClock.uptimeMillis();
961
962 if (localLOGV) Slog.v(TAG, "Launching: " + r);
963
964 int idx = app.activities.indexOf(r);
965 if (idx < 0) {
966 app.activities.add(r);
967 }
Dianne Hackborndb926082013-10-31 16:32:44 -0700968 mService.updateLruProcessLocked(app, true, null);
969 mService.updateOomAdjLocked();
Craig Mautner2420ead2013-04-01 17:13:20 -0700970
971 final ActivityStack stack = r.task.stack;
972 try {
973 if (app.thread == null) {
974 throw new RemoteException();
975 }
976 List<ResultInfo> results = null;
977 List<Intent> newIntents = null;
978 if (andResume) {
979 results = r.results;
980 newIntents = r.newIntents;
981 }
982 if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r
983 + " icicle=" + r.icicle
984 + " with results=" + results + " newIntents=" + newIntents
985 + " andResume=" + andResume);
986 if (andResume) {
987 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
988 r.userId, System.identityHashCode(r),
989 r.task.taskId, r.shortComponentName);
990 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700991 if (r.isHomeActivity() && r.isNotResolverActivity()) {
Craig Mautner4ef26932013-09-18 15:15:52 -0700992 // Home process is the root process of the task.
993 mService.mHomeProcess = r.task.mActivities.get(0).app;
Craig Mautner2420ead2013-04-01 17:13:20 -0700994 }
995 mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
996 r.sleeping = false;
997 r.forceNewConfig = false;
998 mService.showAskCompatModeDialogLocked(r);
999 r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
1000 String profileFile = null;
1001 ParcelFileDescriptor profileFd = null;
1002 boolean profileAutoStop = false;
1003 if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
1004 if (mService.mProfileProc == null || mService.mProfileProc == app) {
1005 mService.mProfileProc = app;
1006 profileFile = mService.mProfileFile;
1007 profileFd = mService.mProfileFd;
1008 profileAutoStop = mService.mAutoStopProfiler;
1009 }
1010 }
1011 app.hasShownUi = true;
1012 app.pendingUiClean = true;
1013 if (profileFd != null) {
1014 try {
1015 profileFd = profileFd.dup();
1016 } catch (IOException e) {
1017 if (profileFd != null) {
1018 try {
1019 profileFd.close();
1020 } catch (IOException o) {
1021 }
1022 profileFd = null;
1023 }
1024 }
1025 }
Dianne Hackborna413dc02013-07-12 12:02:55 -07001026 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
Craig Mautner2420ead2013-04-01 17:13:20 -07001027 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
1028 System.identityHashCode(r), r.info,
Dianne Hackborna413dc02013-07-12 12:02:55 -07001029 new Configuration(mService.mConfiguration), r.compat,
1030 app.repProcState, r.icicle, results, newIntents, !andResume,
Craig Mautner2420ead2013-04-01 17:13:20 -07001031 mService.isNextTransitionForward(), profileFile, profileFd,
1032 profileAutoStop);
1033
1034 if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
1035 // This may be a heavy-weight process! Note that the package
1036 // manager will ensure that only activity can run in the main
1037 // process of the .apk, which is the only thing that will be
1038 // considered heavy-weight.
1039 if (app.processName.equals(app.info.packageName)) {
1040 if (mService.mHeavyWeightProcess != null
1041 && mService.mHeavyWeightProcess != app) {
1042 Slog.w(TAG, "Starting new heavy weight process " + app
1043 + " when already running "
1044 + mService.mHeavyWeightProcess);
1045 }
1046 mService.mHeavyWeightProcess = app;
1047 Message msg = mService.mHandler.obtainMessage(
1048 ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
1049 msg.obj = r;
1050 mService.mHandler.sendMessage(msg);
1051 }
1052 }
1053
1054 } catch (RemoteException e) {
1055 if (r.launchFailed) {
1056 // This is the second time we failed -- finish activity
1057 // and give up.
1058 Slog.e(TAG, "Second failure launching "
1059 + r.intent.getComponent().flattenToShortString()
1060 + ", giving up", e);
1061 mService.appDiedLocked(app, app.pid, app.thread);
1062 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
1063 "2nd-crash", false);
1064 return false;
1065 }
1066
1067 // This is the first time we failed -- restart process and
1068 // retry.
1069 app.activities.remove(r);
1070 throw e;
1071 }
1072
1073 r.launchFailed = false;
1074 if (stack.updateLRUListLocked(r)) {
1075 Slog.w(TAG, "Activity " + r
1076 + " being launched, but already in LRU list");
1077 }
1078
1079 if (andResume) {
1080 // As part of the process of launching, ActivityThread also performs
1081 // a resume.
1082 stack.minimalResumeActivityLocked(r);
1083 } else {
1084 // This activity is not starting in the resumed state... which
1085 // should look like we asked it to pause+stop (but remain visible),
1086 // and it has done so and reported back the current icicle and
1087 // other state.
1088 if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r
1089 + " (starting in stopped state)");
1090 r.state = ActivityState.STOPPED;
1091 r.stopped = true;
1092 }
1093
1094 // Launch the new version setup screen if needed. We do this -after-
1095 // launching the initial activity (that is, home), so that it can have
1096 // a chance to initialize itself while in the background, making the
1097 // switch back to it faster and look better.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001098 if (isFrontStack(stack)) {
Craig Mautner2420ead2013-04-01 17:13:20 -07001099 mService.startSetupActivityLocked();
1100 }
1101
1102 return true;
1103 }
1104
Craig Mautnere79d42682013-04-01 19:01:53 -07001105 void startSpecificActivityLocked(ActivityRecord r,
1106 boolean andResume, boolean checkConfig) {
1107 // Is this activity's application already running?
1108 ProcessRecord app = mService.getProcessRecordLocked(r.processName,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001109 r.info.applicationInfo.uid, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001110
1111 r.task.stack.setLaunchTime(r);
1112
1113 if (app != null && app.thread != null) {
1114 try {
Dianne Hackborn237cefb2013-10-22 18:45:27 -07001115 if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
1116 || !"android".equals(r.info.packageName)) {
1117 // Don't add this if it is a platform component that is marked
1118 // to run in multiple processes, because this is actually
1119 // part of the framework so doesn't make sense to track as a
1120 // separate apk in the process.
1121 app.addPackage(r.info.packageName, mService.mProcessStats);
1122 }
Craig Mautnere79d42682013-04-01 19:01:53 -07001123 realStartActivityLocked(r, app, andResume, checkConfig);
1124 return;
1125 } catch (RemoteException e) {
1126 Slog.w(TAG, "Exception when starting activity "
1127 + r.intent.getComponent().flattenToShortString(), e);
1128 }
1129
1130 // If a dead object exception was thrown -- fall through to
1131 // restart the application.
1132 }
1133
1134 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001135 "activity", r.intent.getComponent(), false, false, true);
Craig Mautnere79d42682013-04-01 19:01:53 -07001136 }
1137
Craig Mautner6170f732013-04-02 13:05:23 -07001138 final int startActivityLocked(IApplicationThread caller,
1139 Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
1140 String resultWho, int requestCode,
1141 int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
Craig Mautnere0a38842013-12-16 16:14:02 -08001142 boolean componentSpecified, ActivityRecord[] outActivity, ActivityContainer container) {
Craig Mautner6170f732013-04-02 13:05:23 -07001143 int err = ActivityManager.START_SUCCESS;
1144
1145 ProcessRecord callerApp = null;
1146 if (caller != null) {
1147 callerApp = mService.getRecordForAppLocked(caller);
1148 if (callerApp != null) {
1149 callingPid = callerApp.pid;
1150 callingUid = callerApp.info.uid;
1151 } else {
1152 Slog.w(TAG, "Unable to find app for caller " + caller
1153 + " (pid=" + callingPid + ") when starting: "
1154 + intent.toString());
1155 err = ActivityManager.START_PERMISSION_DENIED;
1156 }
1157 }
1158
1159 if (err == ActivityManager.START_SUCCESS) {
1160 final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
1161 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
Craig Mautner9ef471f2014-02-07 13:11:47 -08001162 + "} from pid " + (callerApp != null ? callerApp.pid : callingPid)
1163 + " on display " + (container == null ? (mFocusedStack == null ?
1164 Display.DEFAULT_DISPLAY : mFocusedStack.mDisplayId) :
1165 (container.mActivityDisplay == null ? Display.DEFAULT_DISPLAY :
1166 container.mActivityDisplay.mDisplayId)));
Craig Mautner6170f732013-04-02 13:05:23 -07001167 }
1168
1169 ActivityRecord sourceRecord = null;
1170 ActivityRecord resultRecord = null;
1171 if (resultTo != null) {
1172 sourceRecord = isInAnyStackLocked(resultTo);
1173 if (DEBUG_RESULTS) Slog.v(
1174 TAG, "Will send result to " + resultTo + " " + sourceRecord);
1175 if (sourceRecord != null) {
1176 if (requestCode >= 0 && !sourceRecord.finishing) {
1177 resultRecord = sourceRecord;
1178 }
1179 }
1180 }
1181 ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
1182
1183 int launchFlags = intent.getFlags();
1184
1185 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
1186 && sourceRecord != null) {
1187 // Transfer the result target from the source activity to the new
1188 // one being started, including any failures.
1189 if (requestCode >= 0) {
1190 ActivityOptions.abort(options);
1191 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
1192 }
1193 resultRecord = sourceRecord.resultTo;
1194 resultWho = sourceRecord.resultWho;
1195 requestCode = sourceRecord.requestCode;
1196 sourceRecord.resultTo = null;
1197 if (resultRecord != null) {
Craig Mautner1b4bf852014-05-26 15:06:32 -07001198 resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
Craig Mautner6170f732013-04-02 13:05:23 -07001199 }
Dianne Hackbornd4981012014-03-14 16:27:40 +00001200 if (sourceRecord.launchedFromUid == callingUid) {
1201 // The new activity is being launched from the same uid as the previous
1202 // activity in the flow, and asking to forward its result back to the
1203 // previous. In this case the activity is serving as a trampoline between
1204 // the two, so we also want to update its launchedFromPackage to be the
1205 // same as the previous activity. Note that this is safe, since we know
1206 // these two packages come from the same uid; the caller could just as
1207 // well have supplied that same package name itself. This specifially
1208 // deals with the case of an intent picker/chooser being launched in the app
1209 // flow to redirect to an activity picked by the user, where we want the final
1210 // activity to consider it to have been launched by the previous app activity.
1211 callingPackage = sourceRecord.launchedFromPackage;
1212 }
Craig Mautner6170f732013-04-02 13:05:23 -07001213 }
1214
1215 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
1216 // We couldn't find a class that can handle the given Intent.
1217 // That's the end of that!
1218 err = ActivityManager.START_INTENT_NOT_RESOLVED;
1219 }
1220
1221 if (err == ActivityManager.START_SUCCESS && aInfo == null) {
1222 // We couldn't find the specific class specified in the Intent.
1223 // Also the end of the line.
1224 err = ActivityManager.START_CLASS_NOT_FOUND;
1225 }
1226
1227 if (err != ActivityManager.START_SUCCESS) {
1228 if (resultRecord != null) {
1229 resultStack.sendActivityResultLocked(-1,
1230 resultRecord, resultWho, requestCode,
1231 Activity.RESULT_CANCELED, null);
1232 }
1233 setDismissKeyguard(false);
1234 ActivityOptions.abort(options);
1235 return err;
1236 }
1237
1238 final int startAnyPerm = mService.checkPermission(
1239 START_ANY_ACTIVITY, callingPid, callingUid);
1240 final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
1241 callingUid, aInfo.applicationInfo.uid, aInfo.exported);
1242 if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
1243 if (resultRecord != null) {
1244 resultStack.sendActivityResultLocked(-1,
1245 resultRecord, resultWho, requestCode,
1246 Activity.RESULT_CANCELED, null);
1247 }
1248 setDismissKeyguard(false);
1249 String msg;
1250 if (!aInfo.exported) {
1251 msg = "Permission Denial: starting " + intent.toString()
1252 + " from " + callerApp + " (pid=" + callingPid
1253 + ", uid=" + callingUid + ")"
1254 + " not exported from uid " + aInfo.applicationInfo.uid;
1255 } else {
1256 msg = "Permission Denial: starting " + intent.toString()
1257 + " from " + callerApp + " (pid=" + callingPid
1258 + ", uid=" + callingUid + ")"
1259 + " requires " + aInfo.permission;
1260 }
1261 Slog.w(TAG, msg);
1262 throw new SecurityException(msg);
1263 }
1264
Ben Gruverdd72c9e2013-08-06 12:34:17 -07001265 boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
Ben Gruverb6223792013-07-29 16:35:40 -07001266 callingPid, resolvedType, aInfo.applicationInfo);
Ben Gruver5e207332013-04-03 17:41:37 -07001267
Craig Mautner6170f732013-04-02 13:05:23 -07001268 if (mService.mController != null) {
Craig Mautner6170f732013-04-02 13:05:23 -07001269 try {
1270 // The Intent we give to the watcher has the extra data
1271 // stripped off, since it can contain private information.
1272 Intent watchIntent = intent.cloneFilter();
Ben Gruver5e207332013-04-03 17:41:37 -07001273 abort |= !mService.mController.activityStarting(watchIntent,
Craig Mautner6170f732013-04-02 13:05:23 -07001274 aInfo.applicationInfo.packageName);
1275 } catch (RemoteException e) {
1276 mService.mController = null;
1277 }
Ben Gruver5e207332013-04-03 17:41:37 -07001278 }
Craig Mautner6170f732013-04-02 13:05:23 -07001279
Ben Gruver5e207332013-04-03 17:41:37 -07001280 if (abort) {
1281 if (resultRecord != null) {
1282 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
Craig Mautner6170f732013-04-02 13:05:23 -07001283 Activity.RESULT_CANCELED, null);
Craig Mautner6170f732013-04-02 13:05:23 -07001284 }
Ben Gruver5e207332013-04-03 17:41:37 -07001285 // We pretend to the caller that it was really started, but
1286 // they will just get a cancel result.
1287 setDismissKeyguard(false);
1288 ActivityOptions.abort(options);
1289 return ActivityManager.START_SUCCESS;
Craig Mautner6170f732013-04-02 13:05:23 -07001290 }
1291
1292 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
Craig Mautnere0a38842013-12-16 16:14:02 -08001293 intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
1294 requestCode, componentSpecified, this, container);
Craig Mautner6170f732013-04-02 13:05:23 -07001295 if (outActivity != null) {
1296 outActivity[0] = r;
1297 }
1298
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001299 final ActivityStack stack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001300 if (stack.mResumedActivity == null
1301 || stack.mResumedActivity.info.applicationInfo.uid != callingUid) {
Craig Mautner6170f732013-04-02 13:05:23 -07001302 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
1303 PendingActivityLaunch pal =
Craig Mautnerde4ef022013-04-07 19:01:33 -07001304 new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
Craig Mautner6170f732013-04-02 13:05:23 -07001305 mService.mPendingActivityLaunches.add(pal);
1306 setDismissKeyguard(false);
1307 ActivityOptions.abort(options);
1308 return ActivityManager.START_SWITCHES_CANCELED;
1309 }
1310 }
1311
1312 if (mService.mDidAppSwitch) {
1313 // This is the second allowed switch since we stopped switches,
1314 // so now just generally allow switches. Use case: user presses
1315 // home (switches disabled, switch to home, mDidAppSwitch now true);
1316 // user taps a home icon (coming from home so allowed, we hit here
1317 // and now allow anyone to switch again).
1318 mService.mAppSwitchesAllowedTime = 0;
1319 } else {
1320 mService.mDidAppSwitch = true;
1321 }
1322
1323 mService.doPendingActivityLaunchesLocked(false);
1324
Craig Mautner8849a5e2013-04-02 16:41:03 -07001325 err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
Craig Mautner10385a12013-09-22 21:08:32 -07001326
1327 if (allPausedActivitiesComplete()) {
1328 // If someone asked to have the keyguard dismissed on the next
Craig Mautner6170f732013-04-02 13:05:23 -07001329 // activity start, but we are not actually doing an activity
1330 // switch... just dismiss the keyguard now, because we
1331 // probably want to see whatever is behind it.
1332 dismissKeyguard();
1333 }
1334 return err;
1335 }
1336
Craig Mautner1b4bf852014-05-26 15:06:32 -07001337 ActivityStack adjustStackFocus(ActivityRecord r, boolean newTask) {
Craig Mautner1d001b62013-06-18 16:52:43 -07001338 final TaskRecord task = r.task;
1339 if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001340 if (task != null) {
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07001341 final ActivityStack taskStack = task.stack;
Craig Mautnere0a38842013-12-16 16:14:02 -08001342 if (taskStack.isOnHomeDisplay()) {
1343 if (mFocusedStack != taskStack) {
1344 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: Setting " +
1345 "focused stack to r=" + r + " task=" + task);
1346 mFocusedStack = taskStack;
1347 } else {
1348 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1349 "adjustStackFocus: Focused stack already=" + mFocusedStack);
1350 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001351 }
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07001352 return taskStack;
Craig Mautnerac6f8432013-07-17 13:24:59 -07001353 }
1354
Craig Mautnere0a38842013-12-16 16:14:02 -08001355 final ActivityContainer container = r.mInitialActivityContainer;
1356 if (container != null) {
1357 // The first time put it on the desired stack, after this put on task stack.
1358 r.mInitialActivityContainer = null;
1359 return container.mStack;
1360 }
1361
Craig Mautner1b4bf852014-05-26 15:06:32 -07001362 if (mFocusedStack != mHomeStack && (!newTask ||
1363 mFocusedStack.mActivityContainer.isEligibleForNewTasks())) {
Craig Mautnerac6f8432013-07-17 13:24:59 -07001364 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1365 "adjustStackFocus: Have a focused stack=" + mFocusedStack);
1366 return mFocusedStack;
1367 }
1368
Craig Mautnere0a38842013-12-16 16:14:02 -08001369 final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks;
1370 for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1371 final ActivityStack stack = homeDisplayStacks.get(stackNdx);
1372 if (!stack.isHomeStack()) {
1373 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1374 "adjustStackFocus: Setting focused stack=" + stack);
1375 mFocusedStack = stack;
1376 return mFocusedStack;
Craig Mautner858d8a62013-04-23 17:08:34 -07001377 }
1378 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07001379
Craig Mautner4a1cb222013-12-04 16:14:06 -08001380 // Need to create an app stack for this user.
Craig Mautnerf4c909b2014-04-17 18:39:38 -07001381 int stackId = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY);
Craig Mautnerac6f8432013-07-17 13:24:59 -07001382 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r +
1383 " stackId=" + stackId);
1384 mFocusedStack = getStack(stackId);
Craig Mautner29219d92013-04-16 20:19:12 -07001385 return mFocusedStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001386 }
1387 return mHomeStack;
1388 }
1389
Craig Mautner29219d92013-04-16 20:19:12 -07001390 void setFocusedStack(ActivityRecord r) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08001391 if (r != null) {
Craig Mautner12ff7392014-02-21 21:08:00 -08001392 final TaskRecord task = r.task;
1393 boolean isHomeActivity = !r.isApplicationActivity();
1394 if (!isHomeActivity && task != null) {
1395 isHomeActivity = !task.isApplicationTask();
1396 }
1397 if (!isHomeActivity && task != null) {
1398 final ActivityRecord parent = task.stack.mActivityContainer.mParentActivity;
1399 isHomeActivity = parent != null && parent.isHomeActivity();
1400 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08001401 moveHomeStack(isHomeActivity);
Craig Mautner29219d92013-04-16 20:19:12 -07001402 }
1403 }
1404
Craig Mautner8849a5e2013-04-02 16:41:03 -07001405 final int startActivityUncheckedLocked(ActivityRecord r,
1406 ActivityRecord sourceRecord, int startFlags, boolean doResume,
1407 Bundle options) {
1408 final Intent intent = r.intent;
1409 final int callingUid = r.launchedFromUid;
1410
1411 int launchFlags = intent.getFlags();
1412
Craig Mautner8849a5e2013-04-02 16:41:03 -07001413 // We'll invoke onUserLeaving before onPause only if the launching
1414 // activity did not explicitly state that this is an automated launch.
Craig Mautnerde4ef022013-04-07 19:01:33 -07001415 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1416 if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001417
1418 // If the caller has asked not to resume at this point, we make note
1419 // of this in the record so that we can skip it when trying to find
1420 // the top running activity.
1421 if (!doResume) {
1422 r.delayedResume = true;
1423 }
1424
1425 ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1426
1427 // If the onlyIfNeeded flag is set, then we can do this if the activity
1428 // being launched is the same as the one making the call... or, as
1429 // a special case, if we do not know the caller then we count the
1430 // current top activity as the caller.
1431 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1432 ActivityRecord checkedCaller = sourceRecord;
1433 if (checkedCaller == null) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001434 checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001435 }
1436 if (!checkedCaller.realActivity.equals(r.realActivity)) {
1437 // Caller is not the same as launcher, so always needed.
1438 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
1439 }
1440 }
1441
1442 if (sourceRecord == null) {
1443 // This activity is not being started from another... in this
1444 // case we -always- start a new task.
1445 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
Craig Mautner29219d92013-04-16 20:19:12 -07001446 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1447 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001448 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1449 }
1450 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1451 // The original activity who is starting us is running as a single
1452 // instance... this new activity it is starting must go on its
1453 // own task.
1454 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1455 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
1456 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1457 // The activity being started is a single instance... it always
1458 // gets launched into its own task.
1459 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1460 }
1461
Craig Mautner88629292013-11-10 20:39:05 -08001462 ActivityInfo newTaskInfo = null;
1463 Intent newTaskIntent = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001464 final ActivityStack sourceStack;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001465 if (sourceRecord != null) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001466 if (sourceRecord.finishing) {
1467 // If the source is finishing, we can't further count it as our source. This
1468 // is because the task it is associated with may now be empty and on its way out,
1469 // so we don't want to blindly throw it in to that task. Instead we will take
Craig Mautner88629292013-11-10 20:39:05 -08001470 // the NEW_TASK flow and try to find a task for it. But save the task information
1471 // so it can be used when creating the new task.
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001472 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
1473 Slog.w(TAG, "startActivity called from finishing " + sourceRecord
1474 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
1475 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
Craig Mautner88629292013-11-10 20:39:05 -08001476 newTaskInfo = sourceRecord.info;
1477 newTaskIntent = sourceRecord.task.intent;
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001478 }
1479 sourceRecord = null;
1480 sourceStack = null;
1481 } else {
1482 sourceStack = sourceRecord.task.stack;
1483 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07001484 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001485 sourceStack = null;
1486 }
1487
Craig Mautner1b4bf852014-05-26 15:06:32 -07001488 if (r.resultTo != null && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001489 // For whatever reason this activity is being launched into a new
1490 // task... yet the caller has requested a result back. Well, that
1491 // is pretty messed up, so instead immediately send back a cancel
1492 // and let the new task continue launched as normal without a
1493 // dependency on its originator.
1494 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1495 r.resultTo.task.stack.sendActivityResultLocked(-1,
1496 r.resultTo, r.resultWho, r.requestCode,
1497 Activity.RESULT_CANCELED, null);
1498 r.resultTo = null;
1499 }
1500
1501 boolean addingToTask = false;
1502 boolean movedHome = false;
1503 TaskRecord reuseTask = null;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001504 ActivityStack targetStack;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001505 if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
1506 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
1507 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1508 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1509 // If bring to front is requested, and no result is requested, and
1510 // we can find a task that was started with this same
1511 // component, then instead of launching bring that one to the front.
1512 if (r.resultTo == null) {
1513 // See if there is a task to bring to the front. If this is
1514 // a SINGLE_INSTANCE activity, there can be one and only one
1515 // instance of it in the history, and it is always in its own
1516 // unique task, so we do a special search.
1517 ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
Craig Mautnerac6f8432013-07-17 13:24:59 -07001518 ? findTaskLocked(r)
Craig Mautner8849a5e2013-04-02 16:41:03 -07001519 : findActivityLocked(intent, r.info);
1520 if (intentActivity != null) {
Craig Mautner29219d92013-04-16 20:19:12 -07001521 if (r.task == null) {
1522 r.task = intentActivity.task;
1523 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001524 targetStack = intentActivity.task.stack;
Craig Mautner0f922742013-08-06 08:44:42 -07001525 targetStack.mLastPausedActivity = null;
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001526 if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack
1527 + " from " + intentActivity);
Craig Mautnere0a38842013-12-16 16:14:02 -08001528 targetStack.moveToFront();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001529 if (intentActivity.task.intent == null) {
1530 // This task was started because of movement of
1531 // the activity based on affinity... now that we
1532 // are actually launching it, we can assign the
1533 // base intent.
1534 intentActivity.task.setIntent(intent, r.info);
1535 }
1536 // If the target task is not in the front, then we need
1537 // to bring it to the front... except... well, with
1538 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like
1539 // to have the same behavior as if a new instance was
1540 // being started, which means not bringing it to the front
1541 // if the caller is not itself in the front.
Craig Mautner165640b2013-04-20 10:34:33 -07001542 final ActivityStack lastStack = getLastStack();
1543 ActivityRecord curTop = lastStack == null?
1544 null : lastStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner7504d7b2013-09-17 10:50:53 -07001545 if (curTop != null && (curTop.task != intentActivity.task ||
1546 curTop.task != lastStack.topTask())) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001547 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Craig Mautnerd0f964f2013-08-07 11:16:33 -07001548 if (sourceRecord == null || (sourceStack.topActivity() != null &&
1549 sourceStack.topActivity().task == sourceRecord.task)) {
Craig Mautner8849a5e2013-04-02 16:41:03 -07001550 // We really do want to push this one into the
1551 // user's face, right now.
1552 movedHome = true;
Craig Mautnerb53d97c2013-10-25 11:54:37 -07001553 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001554 if ((launchFlags &
Craig Mautner29219d92013-04-16 20:19:12 -07001555 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1556 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
Craig Mautnere12a4a62013-08-29 12:24:56 -07001557 // Caller wants to appear on home activity.
Craig Mautnerae7ecab2013-09-18 11:48:14 -07001558 intentActivity.task.mOnTopOfHome = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001559 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001560 options = null;
1561 }
1562 }
1563 // If the caller has requested that the target task be
1564 // reset, then do so.
1565 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1566 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
1567 }
1568 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1569 // We don't need to start a new activity, and
1570 // the client said not to do anything if that
1571 // is the case, so this is it! And for paranoia, make
1572 // sure we have correctly resumed the top activity.
1573 if (doResume) {
Craig Mautner05d29032013-05-03 13:40:13 -07001574 resumeTopActivitiesLocked(targetStack, null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001575 } else {
1576 ActivityOptions.abort(options);
1577 }
1578 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1579 }
1580 if ((launchFlags &
1581 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
1582 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
1583 // The caller has requested to completely replace any
1584 // existing task with its new activity. Well that should
1585 // not be too hard...
1586 reuseTask = intentActivity.task;
1587 reuseTask.performClearTaskLocked();
1588 reuseTask.setIntent(r.intent, r.info);
1589 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
1590 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1591 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1592 // In this situation we want to remove all activities
1593 // from the task up to the one being started. In most
1594 // cases this means we are resetting the task to its
1595 // initial state.
1596 ActivityRecord top =
1597 intentActivity.task.performClearTaskLocked(r, launchFlags);
1598 if (top != null) {
1599 if (top.frontOfTask) {
1600 // Activity aliases may mean we use different
1601 // intents for the top activity, so make sure
1602 // the task now has the identity of the new
1603 // intent.
1604 top.task.setIntent(r.intent, r.info);
1605 }
1606 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
1607 r, top.task);
1608 top.deliverNewIntentLocked(callingUid, r.intent);
1609 } else {
1610 // A special case: we need to
1611 // start the activity because it is not currently
1612 // running, and the caller has asked to clear the
1613 // current task to have this activity at the top.
1614 addingToTask = true;
1615 // Now pretend like this activity is being started
1616 // by the top of its task, so it is put in the
1617 // right place.
1618 sourceRecord = intentActivity;
1619 }
1620 } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
1621 // In this case the top activity on the task is the
1622 // same as the one being launched, so we take that
1623 // as a request to bring the task to the foreground.
1624 // If the top activity in the task is the root
1625 // activity, deliver this new intent to it if it
1626 // desires.
1627 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1628 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
1629 && intentActivity.realActivity.equals(r.realActivity)) {
1630 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
1631 intentActivity.task);
1632 if (intentActivity.frontOfTask) {
1633 intentActivity.task.setIntent(r.intent, r.info);
1634 }
1635 intentActivity.deliverNewIntentLocked(callingUid, r.intent);
1636 } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
1637 // In this case we are launching the root activity
1638 // of the task, but with a different intent. We
1639 // should start a new instance on top.
1640 addingToTask = true;
1641 sourceRecord = intentActivity;
1642 }
1643 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1644 // In this case an activity is being launched in to an
1645 // existing task, without resetting that task. This
1646 // is typically the situation of launching an activity
1647 // from a notification or shortcut. We want to place
1648 // the new activity on top of the current task.
1649 addingToTask = true;
1650 sourceRecord = intentActivity;
1651 } else if (!intentActivity.task.rootWasReset) {
1652 // In this case we are launching in to an existing task
1653 // that has not yet been started from its front door.
1654 // The current task has been brought to the front.
1655 // Ideally, we'd probably like to place this new task
1656 // at the bottom of its stack, but that's a little hard
1657 // to do with the current organization of the code so
1658 // for now we'll just drop it.
1659 intentActivity.task.setIntent(r.intent, r.info);
1660 }
1661 if (!addingToTask && reuseTask == null) {
1662 // We didn't do anything... but it was needed (a.k.a., client
1663 // don't use that intent!) And for paranoia, make
1664 // sure we have correctly resumed the top activity.
1665 if (doResume) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001666 targetStack.resumeTopActivityLocked(null, options);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001667 } else {
1668 ActivityOptions.abort(options);
1669 }
1670 return ActivityManager.START_TASK_TO_FRONT;
1671 }
1672 }
1673 }
1674 }
1675
1676 //String uri = r.intent.toURI();
1677 //Intent intent2 = new Intent(uri);
1678 //Slog.i(TAG, "Given intent: " + r.intent);
1679 //Slog.i(TAG, "URI is: " + uri);
1680 //Slog.i(TAG, "To intent: " + intent2);
1681
1682 if (r.packageName != null) {
1683 // If the activity being launched is the same as the one currently
1684 // at the top, then we need to check if it should only be launched
1685 // once.
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07001686 ActivityStack topStack = getFocusedStack();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001687 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001688 if (top != null && r.resultTo == null) {
1689 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
1690 if (top.app != null && top.app.thread != null) {
1691 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1692 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
1693 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1694 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
1695 top.task);
1696 // For paranoia, make sure we have correctly
1697 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001698 topStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001699 if (doResume) {
Craig Mautner05d29032013-05-03 13:40:13 -07001700 resumeTopActivitiesLocked();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001701 }
1702 ActivityOptions.abort(options);
1703 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1704 // We don't need to start a new activity, and
1705 // the client said not to do anything if that
1706 // is the case, so this is it!
1707 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1708 }
1709 top.deliverNewIntentLocked(callingUid, r.intent);
1710 return ActivityManager.START_DELIVERED_TO_TOP;
1711 }
1712 }
1713 }
1714 }
1715
1716 } else {
1717 if (r.resultTo != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001718 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
1719 r.requestCode, Activity.RESULT_CANCELED, null);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001720 }
1721 ActivityOptions.abort(options);
1722 return ActivityManager.START_CLASS_NOT_FOUND;
1723 }
1724
1725 boolean newTask = false;
1726 boolean keepCurTransition = false;
1727
1728 // Should this be considered a new task?
1729 if (r.resultTo == null && !addingToTask
1730 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
Craig Mautner1b4bf852014-05-26 15:06:32 -07001731 newTask = true;
1732 targetStack = adjustStackFocus(r, newTask);
Craig Mautnere0a38842013-12-16 16:14:02 -08001733 targetStack.moveToFront();
Craig Mautner8849a5e2013-04-02 16:41:03 -07001734 if (reuseTask == null) {
Craig Mautner88629292013-11-10 20:39:05 -08001735 r.setTask(targetStack.createTaskRecord(getNextTaskId(),
1736 newTaskInfo != null ? newTaskInfo : r.info,
1737 newTaskIntent != null ? newTaskIntent : intent,
1738 true), null, true);
Craig Mautnerde4ef022013-04-07 19:01:33 -07001739 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
1740 r.task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001741 } else {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001742 r.setTask(reuseTask, reuseTask, true);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001743 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001744 if (!movedHome) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001745 if ((launchFlags &
1746 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
1747 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
1748 // Caller wants to appear on home activity, so before starting
1749 // their own activity we will bring home to the front.
Craig Mautnere0a38842013-12-16 16:14:02 -08001750 r.task.mOnTopOfHome = r.task.stack.isOnHomeDisplay();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001751 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001752 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07001753 } else if (sourceRecord != null) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001754 TaskRecord sourceTask = sourceRecord.task;
Craig Mautner525f3d92013-05-07 14:01:50 -07001755 targetStack = sourceTask.stack;
Craig Mautnere0a38842013-12-16 16:14:02 -08001756 targetStack.moveToFront();
Craig Mautnerf32b22e2014-03-25 11:04:16 -07001757 mWindowManager.moveTaskToTop(sourceTask.taskId);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001758 if (!addingToTask &&
1759 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
1760 // In this case, we are adding the activity to an existing
1761 // task, but the caller has asked to clear that task if the
1762 // activity is already running.
Craig Mautner525f3d92013-05-07 14:01:50 -07001763 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001764 keepCurTransition = true;
1765 if (top != null) {
1766 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
1767 top.deliverNewIntentLocked(callingUid, r.intent);
1768 // For paranoia, make sure we have correctly
1769 // resumed the top activity.
Craig Mautner0f922742013-08-06 08:44:42 -07001770 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001771 if (doResume) {
1772 targetStack.resumeTopActivityLocked(null);
1773 }
1774 ActivityOptions.abort(options);
1775 return ActivityManager.START_DELIVERED_TO_TOP;
1776 }
1777 } else if (!addingToTask &&
1778 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1779 // In this case, we are launching an activity in our own task
1780 // that may already be running somewhere in the history, and
1781 // we want to shuffle it to the front of the stack if so.
Craig Mautner525f3d92013-05-07 14:01:50 -07001782 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001783 if (top != null) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07001784 final TaskRecord task = top.task;
1785 task.moveActivityToFrontLocked(top);
1786 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001787 top.updateOptionsLocked(options);
1788 top.deliverNewIntentLocked(callingUid, r.intent);
Craig Mautner0f922742013-08-06 08:44:42 -07001789 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001790 if (doResume) {
1791 targetStack.resumeTopActivityLocked(null);
1792 }
1793 return ActivityManager.START_DELIVERED_TO_TOP;
1794 }
1795 }
1796 // An existing activity is starting this new activity, so we want
1797 // to keep the new one in the same task as the one that is starting
1798 // it.
Craig Mautner525f3d92013-05-07 14:01:50 -07001799 r.setTask(sourceTask, sourceRecord.thumbHolder, false);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001800 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
Dianne Hackborn2a272d42013-10-16 13:34:33 -07001801 + " in existing task " + r.task + " from source " + sourceRecord);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001802
1803 } else {
1804 // This not being started from an existing activity, and not part
1805 // of a new task... just put it in the top task, though these days
1806 // this case should never happen.
Craig Mautner1b4bf852014-05-26 15:06:32 -07001807 targetStack = adjustStackFocus(r, newTask);
Craig Mautnere0a38842013-12-16 16:14:02 -08001808 targetStack.moveToFront();
Craig Mautner1602ec22013-05-12 10:24:27 -07001809 ActivityRecord prev = targetStack.topActivity();
Craig Mautnerde4ef022013-04-07 19:01:33 -07001810 r.setTask(prev != null ? prev.task
1811 : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1812 null, true);
Craig Mautnerf32b22e2014-03-25 11:04:16 -07001813 mWindowManager.moveTaskToTop(r.task.taskId);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001814 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1815 + " in new guessed " + r.task);
1816 }
1817
1818 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
1819 intent, r.getUriPermissionsLocked());
1820
1821 if (newTask) {
1822 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
1823 }
1824 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
Craig Mautner0f922742013-08-06 08:44:42 -07001825 targetStack.mLastPausedActivity = null;
Craig Mautner8849a5e2013-04-02 16:41:03 -07001826 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
Craig Mautner1d001b62013-06-18 16:52:43 -07001827 mService.setFocusedActivityLocked(r);
Craig Mautner8849a5e2013-04-02 16:41:03 -07001828 return ActivityManager.START_SUCCESS;
1829 }
1830
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001831 void acquireLaunchWakelock() {
1832 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
1833 throw new IllegalStateException("Calling must be system uid");
1834 }
1835 mLaunchingActivity.acquire();
1836 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
1837 // To be safe, don't allow the wake lock to be held for too long.
1838 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
1839 }
1840 }
1841
Craig Mautnerf3333272013-04-22 10:55:53 -07001842 // Checked.
1843 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
1844 Configuration config) {
1845 if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
1846
Craig Mautnerf3333272013-04-22 10:55:53 -07001847 ArrayList<ActivityRecord> stops = null;
1848 ArrayList<ActivityRecord> finishes = null;
1849 ArrayList<UserStartedState> startingUsers = null;
1850 int NS = 0;
1851 int NF = 0;
1852 IApplicationThread sendThumbnail = null;
1853 boolean booting = false;
1854 boolean enableScreen = false;
1855 boolean activityRemoved = false;
1856
1857 ActivityRecord r = ActivityRecord.forToken(token);
1858 if (r != null) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07001859 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
1860 Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07001861 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
1862 r.finishLaunchTickingLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001863 if (fromTimeout) {
1864 reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
Craig Mautnerf3333272013-04-22 10:55:53 -07001865 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001866
1867 // This is a hack to semi-deal with a race condition
1868 // in the client where it can be constructed with a
1869 // newer configuration from when we asked it to launch.
1870 // We'll update with whatever configuration it now says
1871 // it used to launch.
1872 if (config != null) {
1873 r.configuration = config;
1874 }
1875
1876 // We are now idle. If someone is waiting for a thumbnail from
1877 // us, we can now deliver.
1878 r.idle = true;
1879
1880 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
1881 sendThumbnail = r.app.thread;
1882 r.thumbnailNeeded = false;
1883 }
1884
1885 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
1886 if (!mService.mBooted && isFrontStack(r.task.stack)) {
1887 mService.mBooted = true;
1888 enableScreen = true;
1889 }
1890 }
1891
1892 if (allResumedActivitiesIdle()) {
1893 if (r != null) {
1894 mService.scheduleAppGcsLocked();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001895 }
1896
1897 if (mLaunchingActivity.isHeld()) {
1898 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
1899 if (VALIDATE_WAKE_LOCK_CALLER &&
1900 Binder.getCallingUid() != Process.myUid()) {
1901 throw new IllegalStateException("Calling must be system uid");
1902 }
1903 mLaunchingActivity.release();
1904 }
1905 ensureActivitiesVisibleLocked(null, 0);
Craig Mautnerf3333272013-04-22 10:55:53 -07001906 }
1907
1908 // Atomically retrieve all of the other things to do.
1909 stops = processStoppingActivitiesLocked(true);
1910 NS = stops != null ? stops.size() : 0;
1911 if ((NF=mFinishingActivities.size()) > 0) {
1912 finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
1913 mFinishingActivities.clear();
1914 }
1915
1916 final ArrayList<ActivityRecord> thumbnails;
1917 final int NT = mCancelledThumbnails.size();
1918 if (NT > 0) {
1919 thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
1920 mCancelledThumbnails.clear();
1921 } else {
1922 thumbnails = null;
1923 }
1924
1925 if (isFrontStack(mHomeStack)) {
1926 booting = mService.mBooting;
1927 mService.mBooting = false;
1928 }
1929
1930 if (mStartingUsers.size() > 0) {
1931 startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
1932 mStartingUsers.clear();
1933 }
1934
1935 // Perform the following actions from unsynchronized state.
1936 final IApplicationThread thumbnailThread = sendThumbnail;
1937 mHandler.post(new Runnable() {
1938 @Override
1939 public void run() {
1940 if (thumbnailThread != null) {
1941 try {
1942 thumbnailThread.requestThumbnail(token);
1943 } catch (Exception e) {
1944 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
1945 mService.sendPendingThumbnail(null, token, null, null, true);
1946 }
1947 }
1948
1949 // Report back to any thumbnail receivers.
1950 for (int i = 0; i < NT; i++) {
1951 ActivityRecord r = thumbnails.get(i);
1952 mService.sendPendingThumbnail(r, null, null, null, true);
1953 }
1954 }
1955 });
1956
1957 // Stop any activities that are scheduled to do so but have been
1958 // waiting for the next one to start.
1959 for (int i = 0; i < NS; i++) {
1960 r = stops.get(i);
1961 final ActivityStack stack = r.task.stack;
1962 if (r.finishing) {
1963 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
1964 } else {
1965 stack.stopActivityLocked(r);
1966 }
1967 }
1968
1969 // Finish any activities that are scheduled to do so but have been
1970 // waiting for the next one to start.
1971 for (int i = 0; i < NF; i++) {
1972 r = finishes.get(i);
1973 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
1974 }
1975
1976 if (booting) {
1977 mService.finishBooting();
1978 } else if (startingUsers != null) {
1979 for (int i = 0; i < startingUsers.size(); i++) {
1980 mService.finishUserSwitch(startingUsers.get(i));
1981 }
1982 }
1983
1984 mService.trimApplications();
1985 //dump();
1986 //mWindowManager.dump();
1987
1988 if (enableScreen) {
1989 mService.enableScreenAfterBoot();
1990 }
1991
1992 if (activityRemoved) {
Craig Mautner05d29032013-05-03 13:40:13 -07001993 resumeTopActivitiesLocked();
Craig Mautnerf3333272013-04-22 10:55:53 -07001994 }
1995
Craig Mautner7ea5bd42013-07-05 15:27:08 -07001996 return r;
Craig Mautnerf3333272013-04-22 10:55:53 -07001997 }
1998
Craig Mautner8e569572013-10-11 17:36:59 -07001999 boolean handleAppDiedLocked(ProcessRecord app) {
Craig Mautner19091252013-10-05 00:03:53 -07002000 boolean hasVisibleActivities = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002001 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2002 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002003 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2004 hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app);
2005 }
Craig Mautner6b74cb52013-09-27 17:02:21 -07002006 }
Craig Mautner19091252013-10-05 00:03:53 -07002007 return hasVisibleActivities;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002008 }
2009
2010 void closeSystemDialogsLocked() {
Craig Mautnere0a38842013-12-16 16:14:02 -08002011 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2012 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002013 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2014 stacks.get(stackNdx).closeSystemDialogsLocked();
2015 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002016 }
2017 }
2018
Craig Mautner93529a42013-10-04 15:03:13 -07002019 void removeUserLocked(int userId) {
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002020 mUserStackInFront.delete(userId);
Craig Mautner93529a42013-10-04 15:03:13 -07002021 }
2022
Craig Mautner8d341ef2013-03-26 09:03:27 -07002023 /**
2024 * @return true if some activity was finished (or would have finished if doit were true).
2025 */
2026 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
2027 boolean didSomething = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002028 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2029 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002030 final int numStacks = stacks.size();
2031 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2032 final ActivityStack stack = stacks.get(stackNdx);
2033 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
2034 didSomething = true;
2035 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002036 }
2037 }
2038 return didSomething;
2039 }
2040
Dianne Hackborna413dc02013-07-12 12:02:55 -07002041 void updatePreviousProcessLocked(ActivityRecord r) {
2042 // Now that this process has stopped, we may want to consider
2043 // it to be the previous app to try to keep around in case
2044 // the user wants to return to it.
2045
2046 // First, found out what is currently the foreground app, so that
2047 // we don't blow away the previous app if this activity is being
2048 // hosted by the process that is actually still the foreground.
2049 ProcessRecord fgApp = null;
Craig Mautnere0a38842013-12-16 16:14:02 -08002050 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2051 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002052 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2053 final ActivityStack stack = stacks.get(stackNdx);
2054 if (isFrontStack(stack)) {
2055 if (stack.mResumedActivity != null) {
2056 fgApp = stack.mResumedActivity.app;
2057 } else if (stack.mPausingActivity != null) {
2058 fgApp = stack.mPausingActivity.app;
2059 }
2060 break;
Dianne Hackborna413dc02013-07-12 12:02:55 -07002061 }
Dianne Hackborna413dc02013-07-12 12:02:55 -07002062 }
2063 }
2064
2065 // Now set this one as the previous process, only if that really
2066 // makes sense to.
2067 if (r.app != null && fgApp != null && r.app != fgApp
2068 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
Craig Mautner4ef26932013-09-18 15:15:52 -07002069 && r.app != mService.mHomeProcess) {
Dianne Hackborna413dc02013-07-12 12:02:55 -07002070 mService.mPreviousProcess = r.app;
2071 mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
2072 }
2073 }
2074
Craig Mautner05d29032013-05-03 13:40:13 -07002075 boolean resumeTopActivitiesLocked() {
2076 return resumeTopActivitiesLocked(null, null, null);
2077 }
2078
2079 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
2080 Bundle targetOptions) {
2081 if (targetStack == null) {
2082 targetStack = getFocusedStack();
2083 }
Craig Mautner12ff7392014-02-21 21:08:00 -08002084 // Do targetStack first.
Craig Mautner05d29032013-05-03 13:40:13 -07002085 boolean result = false;
Craig Mautner12ff7392014-02-21 21:08:00 -08002086 if (isFrontStack(targetStack)) {
2087 result = targetStack.resumeTopActivityLocked(target, targetOptions);
2088 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002089 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2090 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002091 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2092 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautner12ff7392014-02-21 21:08:00 -08002093 if (stack == targetStack) {
2094 // Already started above.
2095 continue;
2096 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002097 if (isFrontStack(stack)) {
Craig Mautner12ff7392014-02-21 21:08:00 -08002098 stack.resumeTopActivityLocked(null);
Craig Mautner05d29032013-05-03 13:40:13 -07002099 }
Craig Mautnerf88c50f2013-04-18 19:25:12 -07002100 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002101 }
Craig Mautner05d29032013-05-03 13:40:13 -07002102 return result;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002103 }
2104
2105 void finishTopRunningActivityLocked(ProcessRecord app) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002106 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2107 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002108 final int numStacks = stacks.size();
2109 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2110 final ActivityStack stack = stacks.get(stackNdx);
2111 stack.finishTopRunningActivityLocked(app);
2112 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002113 }
2114 }
2115
Craig Mautner8d341ef2013-03-26 09:03:27 -07002116 void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002117 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2118 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002119 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2120 if (stacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) {
2121 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack="
2122 + stacks.get(stackNdx));
2123 return;
2124 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002125 }
2126 }
2127 }
2128
Craig Mautner967212c2013-04-13 21:10:58 -07002129 ActivityStack getStack(int stackId) {
Craig Mautnerf4c909b2014-04-17 18:39:38 -07002130 ActivityContainer activityContainer = mActivityContainers.get(stackId);
2131 if (activityContainer != null) {
2132 return activityContainer.mStack;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002133 }
2134 return null;
2135 }
2136
Craig Mautner967212c2013-04-13 21:10:58 -07002137 ArrayList<ActivityStack> getStacks() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002138 ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>();
Craig Mautnere0a38842013-12-16 16:14:02 -08002139 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2140 allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002141 }
2142 return allStacks;
Craig Mautner967212c2013-04-13 21:10:58 -07002143 }
2144
Craig Mautner4a1cb222013-12-04 16:14:06 -08002145 IBinder getHomeActivityToken() {
2146 final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
2147 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
2148 final TaskRecord task = tasks.get(taskNdx);
2149 if (task.isHomeTask()) {
2150 final ArrayList<ActivityRecord> activities = task.mActivities;
2151 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2152 final ActivityRecord r = activities.get(activityNdx);
2153 if (r.isHomeActivity()) {
2154 return r.appToken;
2155 }
2156 }
2157 }
2158 }
2159 return null;
2160 }
2161
Craig Mautnerf4c909b2014-04-17 18:39:38 -07002162 ActivityContainer createActivityContainer(ActivityRecord parentActivity,
Craig Mautner4a1cb222013-12-04 16:14:06 -08002163 IActivityContainerCallback callback) {
Craig Mautnerf4c909b2014-04-17 18:39:38 -07002164 ActivityContainer activityContainer = new VirtualActivityContainer(parentActivity, callback);
2165 mActivityContainers.put(activityContainer.mStackId, activityContainer);
2166 parentActivity.mChildContainers.add(activityContainer);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002167 return activityContainer;
2168 }
2169
Craig Mautner34b73df2014-01-12 21:11:08 -08002170 void removeChildActivityContainers(ActivityRecord parentActivity) {
Craig Mautnerf4c909b2014-04-17 18:39:38 -07002171 final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers;
2172 for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) {
2173 ActivityContainer container = childStacks.remove(containerNdx);
2174 container.release();
Craig Mautner34b73df2014-01-12 21:11:08 -08002175 }
2176 }
2177
Craig Mautner95da1082014-02-24 17:54:35 -08002178 void deleteActivityContainer(IActivityContainer container) {
2179 ActivityContainer activityContainer = (ActivityContainer)container;
2180 if (activityContainer != null) {
Craig Mautnerf4c909b2014-04-17 18:39:38 -07002181 activityContainer.mStack.finishAllActivitiesLocked();
Craig Mautner95da1082014-02-24 17:54:35 -08002182 final ActivityRecord parent = activityContainer.mParentActivity;
2183 if (parent != null) {
2184 parent.mChildContainers.remove(activityContainer);
2185 }
2186 final int stackId = activityContainer.mStackId;
2187 mActivityContainers.remove(stackId);
2188 mWindowManager.removeStack(stackId);
2189 }
2190 }
2191
Craig Mautnerf4c909b2014-04-17 18:39:38 -07002192 private int createStackOnDisplay(int stackId, int displayId) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002193 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2194 if (activityDisplay == null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002195 return -1;
2196 }
2197
Craig Mautnerf4c909b2014-04-17 18:39:38 -07002198 ActivityContainer activityContainer = new ActivityContainer(stackId);
2199 mActivityContainers.put(stackId, activityContainer);
Craig Mautnere0a38842013-12-16 16:14:02 -08002200 activityContainer.attachToDisplayLocked(activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002201 return stackId;
2202 }
2203
2204 int getNextStackId() {
Craig Mautner858d8a62013-04-23 17:08:34 -07002205 while (true) {
2206 if (++mLastStackId <= HOME_STACK_ID) {
2207 mLastStackId = HOME_STACK_ID + 1;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002208 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002209 if (getStack(mLastStackId) == null) {
2210 break;
2211 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002212 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002213 return mLastStackId;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002214 }
2215
2216 void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002217 final TaskRecord task = anyTaskForIdLocked(taskId);
2218 if (task == null) {
2219 return;
2220 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002221 final ActivityStack stack = getStack(stackId);
2222 if (stack == null) {
2223 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
2224 return;
2225 }
Craig Mautner04a0ea62014-01-13 12:51:26 -08002226 task.stack.removeTask(task);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002227 stack.addTask(task, toTop);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002228 mWindowManager.addTask(taskId, stackId, toTop);
Craig Mautner05d29032013-05-03 13:40:13 -07002229 resumeTopActivitiesLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002230 }
2231
Craig Mautnerac6f8432013-07-17 13:24:59 -07002232 ActivityRecord findTaskLocked(ActivityRecord r) {
Dianne Hackborn2a272d42013-10-16 13:34:33 -07002233 if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r);
Craig Mautnere0a38842013-12-16 16:14:02 -08002234 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2235 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002236 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2237 final ActivityStack stack = stacks.get(stackNdx);
2238 if (!r.isApplicationActivity() && !stack.isHomeStack()) {
Craig Mautner1b4bf852014-05-26 15:06:32 -07002239 if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (home activity) " + stack);
2240 continue;
2241 }
2242 if (!stack.mActivityContainer.isEligibleForNewTasks()) {
2243 if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (new task not allowed) " +
2244 stack);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002245 continue;
2246 }
2247 final ActivityRecord ar = stack.findTaskLocked(r);
2248 if (ar != null) {
2249 return ar;
2250 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07002251 }
2252 }
Dianne Hackborn2a272d42013-10-16 13:34:33 -07002253 if (DEBUG_TASKS) Slog.d(TAG, "No task found");
Craig Mautner8849a5e2013-04-02 16:41:03 -07002254 return null;
2255 }
2256
2257 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002258 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2259 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002260 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2261 final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info);
2262 if (ar != null) {
2263 return ar;
2264 }
Craig Mautner8849a5e2013-04-02 16:41:03 -07002265 }
2266 }
2267 return null;
2268 }
2269
Craig Mautner8d341ef2013-03-26 09:03:27 -07002270 void goingToSleepLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002271 scheduleSleepTimeout();
2272 if (!mGoingToSleep.isHeld()) {
2273 mGoingToSleep.acquire();
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002274 if (mLaunchingActivity.isHeld()) {
2275 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2276 throw new IllegalStateException("Calling must be system uid");
Craig Mautner0eea92c2013-05-16 13:35:39 -07002277 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002278 mLaunchingActivity.release();
2279 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
Craig Mautner0eea92c2013-05-16 13:35:39 -07002280 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002281 }
Amith Yamasanice15e152013-09-19 12:30:32 -07002282 checkReadyForSleepLocked();
Craig Mautner8d341ef2013-03-26 09:03:27 -07002283 }
2284
2285 boolean shutdownLocked(int timeout) {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002286 goingToSleepLocked();
Craig Mautner0eea92c2013-05-16 13:35:39 -07002287
Craig Mautnerf4c909b2014-04-17 18:39:38 -07002288 boolean timedout = false;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002289 final long endTime = System.currentTimeMillis() + timeout;
2290 while (true) {
2291 boolean cantShutdown = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002292 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2293 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002294 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2295 cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
2296 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002297 }
2298 if (cantShutdown) {
2299 long timeRemaining = endTime - System.currentTimeMillis();
2300 if (timeRemaining > 0) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002301 try {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002302 mService.wait(timeRemaining);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002303 } catch (InterruptedException e) {
2304 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002305 } else {
2306 Slog.w(TAG, "Activity manager shutdown timed out");
2307 timedout = true;
2308 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002309 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002310 } else {
2311 break;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002312 }
2313 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002314
2315 // Force checkReadyForSleep to complete.
2316 mSleepTimeout = true;
2317 checkReadyForSleepLocked();
2318
Craig Mautner8d341ef2013-03-26 09:03:27 -07002319 return timedout;
2320 }
2321
2322 void comeOutOfSleepIfNeededLocked() {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002323 removeSleepTimeouts();
2324 if (mGoingToSleep.isHeld()) {
2325 mGoingToSleep.release();
2326 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002327 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2328 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002329 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2330 final ActivityStack stack = stacks.get(stackNdx);
2331 stack.awakeFromSleepingLocked();
2332 if (isFrontStack(stack)) {
2333 resumeTopActivitiesLocked();
2334 }
Craig Mautner5314a402013-09-26 12:40:16 -07002335 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002336 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002337 mGoingToSleepActivities.clear();
2338 }
2339
2340 void activitySleptLocked(ActivityRecord r) {
2341 mGoingToSleepActivities.remove(r);
2342 checkReadyForSleepLocked();
2343 }
2344
2345 void checkReadyForSleepLocked() {
2346 if (!mService.isSleepingOrShuttingDown()) {
2347 // Do not care.
2348 return;
2349 }
2350
2351 if (!mSleepTimeout) {
2352 boolean dontSleep = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002353 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2354 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002355 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2356 dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
2357 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002358 }
2359
2360 if (mStoppingActivities.size() > 0) {
2361 // Still need to tell some activities to stop; can't sleep yet.
2362 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2363 + mStoppingActivities.size() + " activities");
2364 scheduleIdleLocked();
2365 dontSleep = true;
2366 }
2367
2368 if (mGoingToSleepActivities.size() > 0) {
2369 // Still need to tell some activities to sleep; can't sleep yet.
2370 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2371 + mGoingToSleepActivities.size() + " activities");
2372 dontSleep = true;
2373 }
2374
2375 if (dontSleep) {
2376 return;
2377 }
2378 }
2379
Craig Mautnere0a38842013-12-16 16:14:02 -08002380 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2381 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002382 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2383 stacks.get(stackNdx).goToSleep();
2384 }
Craig Mautner0eea92c2013-05-16 13:35:39 -07002385 }
2386
2387 removeSleepTimeouts();
2388
2389 if (mGoingToSleep.isHeld()) {
2390 mGoingToSleep.release();
2391 }
2392 if (mService.mShuttingDown) {
2393 mService.notifyAll();
2394 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002395 }
2396
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002397 boolean reportResumedActivityLocked(ActivityRecord r) {
2398 final ActivityStack stack = r.task.stack;
2399 if (isFrontStack(stack)) {
Jeff Sharkey5782da72013-04-25 14:32:30 -07002400 mService.updateUsageStats(r, true);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002401 }
2402 if (allResumedActivitiesComplete()) {
2403 ensureActivitiesVisibleLocked(null, 0);
2404 mWindowManager.executeAppTransition();
2405 return true;
2406 }
2407 return false;
2408 }
2409
Craig Mautner8d341ef2013-03-26 09:03:27 -07002410 void handleAppCrashLocked(ProcessRecord app) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002411 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2412 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002413 final int numStacks = stacks.size();
2414 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2415 final ActivityStack stack = stacks.get(stackNdx);
2416 stack.handleAppCrashLocked(app);
2417 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002418 }
2419 }
2420
Craig Mautnerde4ef022013-04-07 19:01:33 -07002421 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
Craig Mautner580ea812013-04-25 12:58:38 -07002422 // First the front stacks. In case any are not fullscreen and are in front of home.
2423 boolean showHomeBehindStack = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002424 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2425 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002426 final int topStackNdx = stacks.size() - 1;
2427 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
2428 final ActivityStack stack = stacks.get(stackNdx);
2429 if (stackNdx == topStackNdx) {
2430 // Top stack.
2431 showHomeBehindStack =
2432 stack.ensureActivitiesVisibleLocked(starting, configChanges);
2433 } else {
2434 // Back stack.
2435 stack.ensureActivitiesVisibleLocked(starting, configChanges,
2436 showHomeBehindStack);
2437 }
Craig Mautner580ea812013-04-25 12:58:38 -07002438 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002439 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002440 }
2441
2442 void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002443 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2444 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002445 final int numStacks = stacks.size();
2446 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2447 final ActivityStack stack = stacks.get(stackNdx);
2448 stack.scheduleDestroyActivities(app, false, reason);
2449 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002450 }
2451 }
2452
2453 boolean switchUserLocked(int userId, UserStartedState uss) {
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002454 mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId());
2455 final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
Craig Mautner2420ead2013-04-01 17:13:20 -07002456 mCurrentUser = userId;
Craig Mautnerac6f8432013-07-17 13:24:59 -07002457
Craig Mautner858d8a62013-04-23 17:08:34 -07002458 mStartingUsers.add(uss);
Craig Mautnere0a38842013-12-16 16:14:02 -08002459 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2460 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002461 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002462 final ActivityStack stack = stacks.get(stackNdx);
2463 stack.switchUserLocked(userId);
2464 mWindowManager.moveTaskToTop(stack.topTask().taskId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002465 }
Craig Mautnerac6f8432013-07-17 13:24:59 -07002466 }
Craig Mautner858d8a62013-04-23 17:08:34 -07002467
Craig Mautner4f1df4f2013-10-15 15:44:14 -07002468 ActivityStack stack = getStack(restoreStackId);
2469 if (stack == null) {
2470 stack = mHomeStack;
2471 }
2472 final boolean homeInFront = stack.isHomeStack();
Craig Mautnere0a38842013-12-16 16:14:02 -08002473 if (stack.isOnHomeDisplay()) {
2474 moveHomeStack(homeInFront);
2475 mWindowManager.moveTaskToTop(stack.topTask().taskId);
2476 } else {
2477 // Stack was moved to another display while user was swapped out.
2478 resumeHomeActivity(null);
2479 }
Craig Mautner93529a42013-10-04 15:03:13 -07002480 return homeInFront;
Craig Mautner2219a1b2013-03-25 09:44:30 -07002481 }
2482
Craig Mautnerde4ef022013-04-07 19:01:33 -07002483 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2484 int N = mStoppingActivities.size();
2485 if (N <= 0) return null;
2486
2487 ArrayList<ActivityRecord> stops = null;
2488
2489 final boolean nowVisible = allResumedActivitiesVisible();
2490 for (int i=0; i<N; i++) {
2491 ActivityRecord s = mStoppingActivities.get(i);
Craig Mautnera7f2bd42013-10-15 16:13:50 -07002492 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
Craig Mautnerde4ef022013-04-07 19:01:33 -07002493 + nowVisible + " waitingVisible=" + s.waitingVisible
2494 + " finishing=" + s.finishing);
2495 if (s.waitingVisible && nowVisible) {
2496 mWaitingVisibleActivities.remove(s);
2497 s.waitingVisible = false;
2498 if (s.finishing) {
2499 // If this activity is finishing, it is sitting on top of
2500 // everyone else but we now know it is no longer needed...
2501 // so get rid of it. Otherwise, we need to go through the
2502 // normal flow and hide it once we determine that it is
2503 // hidden by the activities in front of it.
2504 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002505 mWindowManager.setAppVisibility(s.appToken, false);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002506 }
2507 }
2508 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2509 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2510 if (stops == null) {
2511 stops = new ArrayList<ActivityRecord>();
2512 }
2513 stops.add(s);
2514 mStoppingActivities.remove(i);
2515 N--;
2516 i--;
2517 }
2518 }
2519
2520 return stops;
2521 }
2522
Craig Mautnercf910b02013-04-23 11:23:27 -07002523 void validateTopActivitiesLocked() {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002524 // FIXME
2525/* for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2526 final ActivityStack stack = stacks.get(stackNdx);
Craig Mautnercf910b02013-04-23 11:23:27 -07002527 final ActivityRecord r = stack.topRunningActivityLocked(null);
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002528 final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
Craig Mautnercf910b02013-04-23 11:23:27 -07002529 if (isFrontStack(stack)) {
2530 if (r == null) {
2531 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2532 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002533 final ActivityRecord pausing = stack.mPausingActivity;
2534 if (pausing != null && pausing == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002535 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002536 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002537 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002538 if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002539 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002540 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002541 }
2542 }
2543 } else {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002544 final ActivityRecord resumed = stack.mResumedActivity;
2545 if (resumed != null && resumed == r) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002546 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002547 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002548 }
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002549 if (r != null && (state == ActivityState.INITIALIZING
2550 || state == ActivityState.RESUMED)) {
Craig Mautnercf910b02013-04-23 11:23:27 -07002551 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
Craig Mautnerf0ac5c82013-06-24 11:21:57 -07002552 " state=" + state);
Craig Mautnercf910b02013-04-23 11:23:27 -07002553 }
2554 }
2555 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002556*/
Craig Mautner76ea2242013-05-15 11:40:05 -07002557 }
2558
Craig Mautner27084302013-03-25 08:05:25 -07002559 public void dump(PrintWriter pw, String prefix) {
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002560 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity=");
Craig Mautner27084302013-03-25 08:05:25 -07002561 pw.println(mDismissKeyguardOnNextActivity);
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002562 pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002563 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
Craig Mautnerd1bbdb4622013-10-22 09:53:20 -07002564 pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
2565 pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
2566 pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
Craig Mautner95da1082014-02-24 17:54:35 -08002567 pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
Craig Mautner27084302013-03-25 08:05:25 -07002568 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002569
Craig Mautner20e72272013-04-01 13:45:53 -07002570 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002571 return getFocusedStack().getDumpActivitiesLocked(name);
Craig Mautner20e72272013-04-01 13:45:53 -07002572 }
2573
Dianne Hackborn390517b2013-05-30 15:03:32 -07002574 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2575 boolean needSep, String prefix) {
2576 if (activity != null) {
2577 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2578 if (needSep) {
2579 pw.println();
Dianne Hackborn390517b2013-05-30 15:03:32 -07002580 }
2581 pw.print(prefix);
2582 pw.println(activity);
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002583 return true;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002584 }
2585 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002586 return false;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002587 }
2588
Craig Mautner8d341ef2013-03-26 09:03:27 -07002589 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2590 boolean dumpClient, String dumpPackage) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002591 boolean printed = false;
2592 boolean needSep = false;
Craig Mautnere0a38842013-12-16 16:14:02 -08002593 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2594 ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
2595 pw.print("Display #"); pw.println(activityDisplay.mDisplayId);
2596 ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002597 final int numStacks = stacks.size();
2598 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2599 final ActivityStack stack = stacks.get(stackNdx);
2600 StringBuilder stackHeader = new StringBuilder(128);
2601 stackHeader.append(" Stack #");
2602 stackHeader.append(stack.mStackId);
2603 stackHeader.append(":");
2604 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
2605 needSep, stackHeader.toString());
2606 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false,
2607 !dumpAll, false, dumpPackage, true,
2608 " Running activities (most recent first):", null);
Craig Mautner8d341ef2013-03-26 09:03:27 -07002609
Craig Mautner4a1cb222013-12-04 16:14:06 -08002610 needSep = printed;
2611 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
2612 " mPausingActivity: ");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002613 if (pr) {
2614 printed = true;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002615 needSep = false;
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002616 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002617 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
2618 " mResumedActivity: ");
2619 if (pr) {
2620 printed = true;
2621 needSep = false;
2622 }
2623 if (dumpAll) {
2624 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
2625 " mLastPausedActivity: ");
2626 if (pr) {
2627 printed = true;
2628 needSep = true;
2629 }
2630 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
2631 needSep, " mLastNoHistoryActivity: ");
2632 }
2633 needSep = printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002634 }
2635 }
2636
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002637 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll,
2638 false, dumpPackage, true, " Activities waiting to finish:", null);
2639 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll,
2640 false, dumpPackage, true, " Activities waiting to stop:", null);
2641 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll,
2642 false, dumpPackage, true, " Activities waiting for another to become visible:",
2643 null);
2644 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2645 false, dumpPackage, true, " Activities waiting to sleep:", null);
2646 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
2647 false, dumpPackage, true, " Activities waiting to sleep:", null);
Craig Mautnerf3333272013-04-22 10:55:53 -07002648
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002649 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002650 }
2651
Dianne Hackborn390517b2013-05-30 15:03:32 -07002652 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
Craig Mautner8d341ef2013-03-26 09:03:27 -07002653 String prefix, String label, boolean complete, boolean brief, boolean client,
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002654 String dumpPackage, boolean needNL, String header1, String header2) {
Craig Mautner8d341ef2013-03-26 09:03:27 -07002655 TaskRecord lastTask = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002656 String innerPrefix = null;
2657 String[] args = null;
2658 boolean printed = false;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002659 for (int i=list.size()-1; i>=0; i--) {
2660 final ActivityRecord r = list.get(i);
2661 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2662 continue;
2663 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002664 if (innerPrefix == null) {
2665 innerPrefix = prefix + " ";
2666 args = new String[0];
2667 }
2668 printed = true;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002669 final boolean full = !brief && (complete || !r.isInHistory());
2670 if (needNL) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07002671 pw.println("");
Craig Mautner8d341ef2013-03-26 09:03:27 -07002672 needNL = false;
2673 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002674 if (header1 != null) {
2675 pw.println(header1);
2676 header1 = null;
2677 }
2678 if (header2 != null) {
2679 pw.println(header2);
2680 header2 = null;
Dianne Hackborn390517b2013-05-30 15:03:32 -07002681 }
Craig Mautner8d341ef2013-03-26 09:03:27 -07002682 if (lastTask != r.task) {
2683 lastTask = r.task;
2684 pw.print(prefix);
2685 pw.print(full ? "* " : " ");
2686 pw.println(lastTask);
2687 if (full) {
2688 lastTask.dump(pw, prefix + " ");
2689 } else if (complete) {
2690 // Complete + brief == give a summary. Isn't that obvious?!?
2691 if (lastTask.intent != null) {
2692 pw.print(prefix); pw.print(" ");
2693 pw.println(lastTask.intent.toInsecureStringWithClip());
2694 }
2695 }
2696 }
2697 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
2698 pw.print(" #"); pw.print(i); pw.print(": ");
2699 pw.println(r);
2700 if (full) {
2701 r.dump(pw, innerPrefix);
2702 } else if (complete) {
2703 // Complete + brief == give a summary. Isn't that obvious?!?
2704 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2705 if (r.app != null) {
2706 pw.print(innerPrefix); pw.println(r.app);
2707 }
2708 }
2709 if (client && r.app != null && r.app.thread != null) {
2710 // flush anything that is already in the PrintWriter since the thread is going
2711 // to write to the file descriptor directly
2712 pw.flush();
2713 try {
2714 TransferPipe tp = new TransferPipe();
2715 try {
2716 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2717 r.appToken, innerPrefix, args);
2718 // Short timeout, since blocking here can
2719 // deadlock with the application.
2720 tp.go(fd, 2000);
2721 } finally {
2722 tp.kill();
2723 }
2724 } catch (IOException e) {
2725 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2726 } catch (RemoteException e) {
2727 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2728 }
2729 needNL = true;
2730 }
2731 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07002732 return printed;
Craig Mautner8d341ef2013-03-26 09:03:27 -07002733 }
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002734
Craig Mautnerf3333272013-04-22 10:55:53 -07002735 void scheduleIdleTimeoutLocked(ActivityRecord next) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002736 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
Craig Mautnerc64f73e2013-04-24 16:44:56 -07002737 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2738 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
Craig Mautnerf3333272013-04-22 10:55:53 -07002739 }
2740
2741 final void scheduleIdleLocked() {
Craig Mautner05d29032013-05-03 13:40:13 -07002742 mHandler.sendEmptyMessage(IDLE_NOW_MSG);
Craig Mautnerf3333272013-04-22 10:55:53 -07002743 }
2744
2745 void removeTimeoutsForActivityLocked(ActivityRecord r) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002746 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
Craig Mautnerf3333272013-04-22 10:55:53 -07002747 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2748 }
2749
Craig Mautner05d29032013-05-03 13:40:13 -07002750 final void scheduleResumeTopActivities() {
Craig Mautner34b73df2014-01-12 21:11:08 -08002751 if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
2752 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2753 }
Craig Mautner05d29032013-05-03 13:40:13 -07002754 }
2755
Craig Mautner0eea92c2013-05-16 13:35:39 -07002756 void removeSleepTimeouts() {
2757 mSleepTimeout = false;
2758 mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2759 }
2760
2761 final void scheduleSleepTimeout() {
2762 removeSleepTimeouts();
2763 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2764 }
2765
Craig Mautner4a1cb222013-12-04 16:14:06 -08002766 @Override
2767 public void onDisplayAdded(int displayId) {
2768 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
2769 }
2770
2771 @Override
2772 public void onDisplayRemoved(int displayId) {
2773 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
2774 }
2775
2776 @Override
2777 public void onDisplayChanged(int displayId) {
2778 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
2779 }
2780
2781 public void handleDisplayAddedLocked(int displayId) {
Craig Mautner4504de52013-12-20 09:06:56 -08002782 boolean newDisplay;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002783 synchronized (mService) {
Craig Mautner4504de52013-12-20 09:06:56 -08002784 newDisplay = mActivityDisplays.get(displayId) == null;
2785 if (newDisplay) {
2786 ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
2787 mActivityDisplays.put(displayId, activityDisplay);
2788 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002789 }
Craig Mautner4504de52013-12-20 09:06:56 -08002790 if (newDisplay) {
2791 mWindowManager.onDisplayAdded(displayId);
2792 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002793 }
2794
2795 public void handleDisplayRemovedLocked(int displayId) {
2796 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002797 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2798 if (activityDisplay != null) {
2799 ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002800 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautner34b73df2014-01-12 21:11:08 -08002801 stacks.get(stackNdx).mActivityContainer.detachLocked();
Craig Mautner4a1cb222013-12-04 16:14:06 -08002802 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002803 mActivityDisplays.remove(displayId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002804 }
2805 }
2806 mWindowManager.onDisplayRemoved(displayId);
2807 }
2808
2809 public void handleDisplayChangedLocked(int displayId) {
2810 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002811 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2812 if (activityDisplay != null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002813 // TODO: Update the bounds.
2814 }
2815 }
2816 mWindowManager.onDisplayChanged(displayId);
2817 }
2818
2819 StackInfo getStackInfo(ActivityStack stack) {
2820 StackInfo info = new StackInfo();
2821 mWindowManager.getStackBounds(stack.mStackId, info.bounds);
2822 info.displayId = Display.DEFAULT_DISPLAY;
2823 info.stackId = stack.mStackId;
2824
2825 ArrayList<TaskRecord> tasks = stack.getAllTasks();
2826 final int numTasks = tasks.size();
2827 int[] taskIds = new int[numTasks];
2828 String[] taskNames = new String[numTasks];
2829 for (int i = 0; i < numTasks; ++i) {
2830 final TaskRecord task = tasks.get(i);
2831 taskIds[i] = task.taskId;
2832 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
2833 : task.realActivity != null ? task.realActivity.flattenToString()
2834 : task.getTopActivity() != null ? task.getTopActivity().packageName
2835 : "unknown";
2836 }
2837 info.taskIds = taskIds;
2838 info.taskNames = taskNames;
2839 return info;
2840 }
2841
2842 StackInfo getStackInfoLocked(int stackId) {
2843 ActivityStack stack = getStack(stackId);
2844 if (stack != null) {
2845 return getStackInfo(stack);
2846 }
2847 return null;
2848 }
2849
2850 ArrayList<StackInfo> getAllStackInfosLocked() {
2851 ArrayList<StackInfo> list = new ArrayList<StackInfo>();
Craig Mautnere0a38842013-12-16 16:14:02 -08002852 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2853 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002854 for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
2855 list.add(getStackInfo(stacks.get(ndx)));
2856 }
2857 }
2858 return list;
2859 }
2860
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002861 private final class ActivityStackSupervisorHandler extends Handler {
Craig Mautnerf3333272013-04-22 10:55:53 -07002862
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002863 public ActivityStackSupervisorHandler(Looper looper) {
2864 super(looper);
2865 }
2866
Craig Mautnerf3333272013-04-22 10:55:53 -07002867 void activityIdleInternal(ActivityRecord r) {
2868 synchronized (mService) {
2869 activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
2870 }
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002871 }
2872
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002873 @Override
2874 public void handleMessage(Message msg) {
2875 switch (msg.what) {
Craig Mautnerf3333272013-04-22 10:55:53 -07002876 case IDLE_TIMEOUT_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002877 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002878 if (mService.mDidDexOpt) {
2879 mService.mDidDexOpt = false;
2880 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2881 nmsg.obj = msg.obj;
2882 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
2883 return;
2884 }
2885 // We don't at this point know if the activity is fullscreen,
2886 // so we need to be conservative and assume it isn't.
2887 activityIdleInternal((ActivityRecord)msg.obj);
2888 } break;
2889 case IDLE_NOW_MSG: {
Craig Mautner5eda9b32013-07-02 11:58:16 -07002890 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
Craig Mautnerf3333272013-04-22 10:55:53 -07002891 activityIdleInternal((ActivityRecord)msg.obj);
2892 } break;
Craig Mautner05d29032013-05-03 13:40:13 -07002893 case RESUME_TOP_ACTIVITY_MSG: {
2894 synchronized (mService) {
2895 resumeTopActivitiesLocked();
2896 }
2897 } break;
Craig Mautner0eea92c2013-05-16 13:35:39 -07002898 case SLEEP_TIMEOUT_MSG: {
2899 synchronized (mService) {
2900 if (mService.isSleepingOrShuttingDown()) {
2901 Slog.w(TAG, "Sleep timeout! Sleeping now.");
2902 mSleepTimeout = true;
2903 checkReadyForSleepLocked();
2904 }
2905 }
2906 } break;
Craig Mautner7ea5bd42013-07-05 15:27:08 -07002907 case LAUNCH_TIMEOUT_MSG: {
2908 if (mService.mDidDexOpt) {
2909 mService.mDidDexOpt = false;
2910 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
2911 return;
2912 }
2913 synchronized (mService) {
2914 if (mLaunchingActivity.isHeld()) {
2915 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
2916 if (VALIDATE_WAKE_LOCK_CALLER
2917 && Binder.getCallingUid() != Process.myUid()) {
2918 throw new IllegalStateException("Calling must be system uid");
2919 }
2920 mLaunchingActivity.release();
2921 }
2922 }
2923 } break;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002924 case HANDLE_DISPLAY_ADDED: {
2925 handleDisplayAddedLocked(msg.arg1);
2926 } break;
2927 case HANDLE_DISPLAY_CHANGED: {
2928 handleDisplayChangedLocked(msg.arg1);
2929 } break;
2930 case HANDLE_DISPLAY_REMOVED: {
2931 handleDisplayRemovedLocked(msg.arg1);
2932 } break;
Craig Mautnere3a00d72014-04-16 08:31:19 -07002933 case CONTAINER_CALLBACK_VISIBILITY: {
2934 final ActivityContainer container = (ActivityContainer) msg.obj;
Craig Mautnerd94b47f2014-06-02 15:06:40 -07002935 final IActivityContainerCallback callback = container.mCallback;
2936 if (callback != null) {
2937 try {
2938 callback.setVisible(container.asBinder(), msg.arg1 == 1);
2939 } catch (RemoteException e) {
2940 }
Craig Mautnere3a00d72014-04-16 08:31:19 -07002941 }
Craig Mautnerd94b47f2014-06-02 15:06:40 -07002942 } break;
2943 case CONTAINER_CALLBACK_TASK_LIST_EMPTY: {
2944 final ActivityContainer container = (ActivityContainer) msg.obj;
2945 final IActivityContainerCallback callback = container.mCallback;
2946 if (callback != null) {
2947 try {
2948 callback.onAllActivitiesComplete(container.asBinder());
2949 } catch (RemoteException e) {
2950 }
2951 }
2952 } break;
Craig Mautnerce5f3cb2013-04-22 08:58:54 -07002953 }
2954 }
2955 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08002956
Ying Wangb081a592014-04-22 15:20:16 -07002957 class ActivityContainer extends android.app.IActivityContainer.Stub {
Craig Mautner7f7bdb22014-04-22 19:57:19 -07002958 final static int FORCE_NEW_TASK_FLAGS = Intent.FLAG_ACTIVITY_NEW_TASK |
2959 Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002960 final int mStackId;
Craig Mautnerf4c909b2014-04-17 18:39:38 -07002961 IActivityContainerCallback mCallback = null;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002962 final ActivityStack mStack;
Craig Mautnerf4c909b2014-04-17 18:39:38 -07002963 ActivityRecord mParentActivity = null;
2964 String mIdString;
Craig Mautnerbdc748af2013-12-02 14:08:25 -08002965
Craig Mautnere3a00d72014-04-16 08:31:19 -07002966 boolean mVisible = true;
2967
Craig Mautner4a1cb222013-12-04 16:14:06 -08002968 /** Display this ActivityStack is currently on. Null if not attached to a Display. */
Craig Mautnere0a38842013-12-16 16:14:02 -08002969 ActivityDisplay mActivityDisplay;
Craig Mautner4a1cb222013-12-04 16:14:06 -08002970
Craig Mautnerf4c909b2014-04-17 18:39:38 -07002971 final static int CONTAINER_STATE_HAS_SURFACE = 0;
2972 final static int CONTAINER_STATE_NO_SURFACE = 1;
2973 final static int CONTAINER_STATE_FINISHING = 2;
2974 int mContainerState = CONTAINER_STATE_HAS_SURFACE;
2975
2976 ActivityContainer(int stackId) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002977 synchronized (mService) {
2978 mStackId = stackId;
2979 mStack = new ActivityStack(this);
Craig Mautnerf4c909b2014-04-17 18:39:38 -07002980 mIdString = "ActivtyContainer{" + mStackId + "}";
Craig Mautner34b73df2014-01-12 21:11:08 -08002981 if (DEBUG_STACK) Slog.d(TAG, "Creating " + this);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002982 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08002983 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08002984
Craig Mautnere0a38842013-12-16 16:14:02 -08002985 void attachToDisplayLocked(ActivityDisplay activityDisplay) {
Craig Mautner34b73df2014-01-12 21:11:08 -08002986 if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this
2987 + " to display=" + activityDisplay);
Craig Mautnere0a38842013-12-16 16:14:02 -08002988 mActivityDisplay = activityDisplay;
2989 mStack.mDisplayId = activityDisplay.mDisplayId;
2990 mStack.mStacks = activityDisplay.mStacks;
2991
2992 activityDisplay.attachActivities(mStack);
Craig Mautnerdf88d732014-01-27 09:21:32 -08002993 mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08002994 }
2995
2996 @Override
Jeff Brown38f96e52014-02-11 14:32:56 -08002997 public void attachToDisplay(int displayId) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08002998 synchronized (mService) {
Craig Mautnere0a38842013-12-16 16:14:02 -08002999 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3000 if (activityDisplay == null) {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003001 return;
3002 }
Craig Mautnere0a38842013-12-16 16:14:02 -08003003 attachToDisplayLocked(activityDisplay);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003004 }
3005 }
3006
3007 @Override
Jeff Brown38f96e52014-02-11 14:32:56 -08003008 public int getDisplayId() {
Craig Mautnere0a38842013-12-16 16:14:02 -08003009 if (mActivityDisplay != null) {
3010 return mActivityDisplay.mDisplayId;
3011 }
3012 return -1;
Craig Mautner4a1cb222013-12-04 16:14:06 -08003013 }
3014
Jeff Brown38f96e52014-02-11 14:32:56 -08003015 @Override
3016 public boolean injectEvent(InputEvent event) {
3017 final long origId = Binder.clearCallingIdentity();
3018 try {
3019 if (mActivityDisplay != null) {
3020 return mInputManagerInternal.injectInputEvent(event,
3021 mActivityDisplay.mDisplayId,
3022 InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
3023 }
3024 return false;
3025 } finally {
3026 Binder.restoreCallingIdentity(origId);
3027 }
3028 }
3029
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003030 @Override
3031 public void release() {
3032 mContainerState = CONTAINER_STATE_FINISHING;
3033 mStack.finishAllActivitiesLocked();
3034 detachLocked();
3035 mWindowManager.removeStack(mStackId);
3036 }
3037
Craig Mautner34b73df2014-01-12 21:11:08 -08003038 private void detachLocked() {
3039 if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display="
3040 + mActivityDisplay + " Callers=" + Debug.getCallers(2));
Craig Mautnere0a38842013-12-16 16:14:02 -08003041 if (mActivityDisplay != null) {
3042 mActivityDisplay.detachActivitiesLocked(mStack);
3043 mActivityDisplay = null;
3044 mStack.mDisplayId = -1;
3045 mStack.mStacks = null;
Craig Mautnerdf88d732014-01-27 09:21:32 -08003046 mWindowManager.detachStack(mStackId);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003047 }
3048 }
3049
3050 @Override
Craig Mautnere0a38842013-12-16 16:14:02 -08003051 public final int startActivity(Intent intent) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08003052 mService.enforceNotIsolatedCaller("ActivityContainer.startActivity");
Craig Mautnere0a38842013-12-16 16:14:02 -08003053 int userId = mService.handleIncomingUser(Binder.getCallingPid(),
3054 Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null);
3055 // TODO: Switch to user app stacks here.
Craig Mautner7f7bdb22014-04-22 19:57:19 -07003056 intent.addFlags(FORCE_NEW_TASK_FLAGS);
Craig Mautnere0a38842013-12-16 16:14:02 -08003057 String mimeType = intent.getType();
3058 if (mimeType == null && intent.getData() != null
3059 && "content".equals(intent.getData().getScheme())) {
3060 mimeType = mService.getProviderMimeType(intent.getData(), userId);
3061 }
3062 return startActivityMayWait(null, -1, null, intent, mimeType, null, null, 0, 0, null,
3063 null, null, null, null, userId, this);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003064 }
3065
3066 @Override
Craig Mautnerdf88d732014-01-27 09:21:32 -08003067 public final int startActivityIntentSender(IIntentSender intentSender) {
3068 mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
3069
3070 if (!(intentSender instanceof PendingIntentRecord)) {
3071 throw new IllegalArgumentException("Bad PendingIntent object");
3072 }
3073
3074 return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null,
Craig Mautner7f7bdb22014-04-22 19:57:19 -07003075 null, 0, FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this);
Craig Mautnerdf88d732014-01-27 09:21:32 -08003076 }
3077
Craig Mautner247ab652014-04-25 10:09:00 -07003078 private void checkEmbeddedAllowedInner(Intent intent, String resolvedType) {
3079 int userId = mService.handleIncomingUser(Binder.getCallingPid(),
3080 Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null);
3081 if (resolvedType == null) {
3082 resolvedType = intent.getType();
3083 if (resolvedType == null && intent.getData() != null
3084 && "content".equals(intent.getData().getScheme())) {
3085 resolvedType = mService.getProviderMimeType(intent.getData(), userId);
3086 }
3087 }
3088 ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, null, userId);
Craig Mautner05678d52014-05-05 12:32:40 -07003089 if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) {
Craig Mautner247ab652014-04-25 10:09:00 -07003090 throw new SecurityException(
3091 "Attempt to embed activity that has not set allowEmbedded=\"true\"");
3092 }
3093 }
3094
3095 /** Throw a SecurityException if allowEmbedded is not true */
3096 @Override
3097 public final void checkEmbeddedAllowed(Intent intent) {
3098 checkEmbeddedAllowedInner(intent, null);
3099 }
3100
3101 /** Throw a SecurityException if allowEmbedded is not true */
3102 @Override
3103 public final void checkEmbeddedAllowedIntentSender(IIntentSender intentSender) {
3104 if (!(intentSender instanceof PendingIntentRecord)) {
3105 throw new IllegalArgumentException("Bad PendingIntent object");
3106 }
3107 PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender;
3108 checkEmbeddedAllowedInner(pendingIntent.key.requestIntent,
3109 pendingIntent.key.requestResolvedType);
3110 }
3111
Craig Mautnerdf88d732014-01-27 09:21:32 -08003112 @Override
Craig Mautner4a1cb222013-12-04 16:14:06 -08003113 public IBinder asBinder() {
3114 return this;
3115 }
3116
Craig Mautner4504de52013-12-20 09:06:56 -08003117 @Override
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003118 public void setSurface(Surface surface, int width, int height, int density) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08003119 mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
Craig Mautner4504de52013-12-20 09:06:56 -08003120 }
3121
Craig Mautner4a1cb222013-12-04 16:14:06 -08003122 ActivityStackSupervisor getOuter() {
3123 return ActivityStackSupervisor.this;
3124 }
3125
3126 boolean isAttached() {
Craig Mautnere0a38842013-12-16 16:14:02 -08003127 return mActivityDisplay != null;
Craig Mautner4a1cb222013-12-04 16:14:06 -08003128 }
3129
3130 void getBounds(Point outBounds) {
Craig Mautnere0a38842013-12-16 16:14:02 -08003131 if (mActivityDisplay != null) {
3132 mActivityDisplay.getBounds(outBounds);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003133 } else {
3134 outBounds.set(0, 0);
3135 }
3136 }
Craig Mautner34b73df2014-01-12 21:11:08 -08003137
Craig Mautner6985bad2014-04-21 15:22:06 -07003138 // TODO: Make sure every change to ActivityRecord.visible results in a call to this.
Craig Mautnere3a00d72014-04-16 08:31:19 -07003139 void setVisible(boolean visible) {
3140 if (mVisible != visible) {
3141 mVisible = visible;
3142 if (mCallback != null) {
3143 mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0,
3144 0 /* unused */, this).sendToTarget();
3145 }
3146 }
3147 }
3148
Craig Mautner6985bad2014-04-21 15:22:06 -07003149 void setDrawn() {
3150 }
3151
Craig Mautner1b4bf852014-05-26 15:06:32 -07003152 // You can always start a new task on a regular ActivityStack.
3153 boolean isEligibleForNewTasks() {
3154 return true;
3155 }
3156
Craig Mautnerd94b47f2014-06-02 15:06:40 -07003157 void onTaskListEmpty() {
3158 mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget();
3159 }
3160
Craig Mautner34b73df2014-01-12 21:11:08 -08003161 @Override
3162 public String toString() {
3163 return mIdString + (mActivityDisplay == null ? "N" : "A");
3164 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003165 }
3166
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003167 private class VirtualActivityContainer extends ActivityContainer {
3168 Surface mSurface;
Craig Mautner6985bad2014-04-21 15:22:06 -07003169 boolean mDrawn = false;
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003170
3171 VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) {
3172 super(getNextStackId());
3173 mParentActivity = parent;
3174 mCallback = callback;
3175 mContainerState = CONTAINER_STATE_NO_SURFACE;
3176 mIdString = "VirtualActivtyContainer{" + mStackId + ", parent=" + mParentActivity + "}";
3177 }
3178
3179 @Override
3180 public void setSurface(Surface surface, int width, int height, int density) {
3181 super.setSurface(surface, width, height, density);
3182
3183 synchronized (mService) {
3184 final long origId = Binder.clearCallingIdentity();
3185 try {
3186 setSurfaceLocked(surface, width, height, density);
3187 } finally {
3188 Binder.restoreCallingIdentity(origId);
3189 }
3190 }
3191 }
3192
3193 private void setSurfaceLocked(Surface surface, int width, int height, int density) {
3194 if (mContainerState == CONTAINER_STATE_FINISHING) {
3195 return;
3196 }
3197 VirtualActivityDisplay virtualActivityDisplay =
3198 (VirtualActivityDisplay) mActivityDisplay;
3199 if (virtualActivityDisplay == null) {
3200 virtualActivityDisplay =
Craig Mautner6985bad2014-04-21 15:22:06 -07003201 new VirtualActivityDisplay(width, height, density);
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003202 mActivityDisplay = virtualActivityDisplay;
3203 mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay);
3204 attachToDisplayLocked(virtualActivityDisplay);
3205 }
3206
3207 if (mSurface != null) {
3208 mSurface.release();
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003209 }
3210
Craig Mautner6985bad2014-04-21 15:22:06 -07003211 mSurface = surface;
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003212 if (surface != null) {
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003213 mStack.resumeTopActivityLocked(null);
3214 } else {
3215 mContainerState = CONTAINER_STATE_NO_SURFACE;
Craig Mautner6985bad2014-04-21 15:22:06 -07003216 ((VirtualActivityDisplay) mActivityDisplay).setSurface(null);
Craig Mautnerd13a5582014-05-05 12:07:40 -07003217 if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) {
3218 mStack.startPausingLocked(false, true);
3219 }
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003220 }
Craig Mautner6985bad2014-04-21 15:22:06 -07003221
3222 setSurfaceIfReady();
3223
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003224 if (DEBUG_STACK) Slog.d(TAG, "setSurface: " + this + " to display="
3225 + virtualActivityDisplay);
Craig Mautner6985bad2014-04-21 15:22:06 -07003226 }
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003227
Craig Mautner6985bad2014-04-21 15:22:06 -07003228 @Override
Craig Mautnerd13a5582014-05-05 12:07:40 -07003229 boolean isAttached() {
3230 return mSurface != null && super.isAttached();
3231 }
3232
3233 @Override
Craig Mautner6985bad2014-04-21 15:22:06 -07003234 void setDrawn() {
3235 synchronized (mService) {
3236 mDrawn = true;
3237 setSurfaceIfReady();
3238 }
3239 }
3240
Craig Mautner1b4bf852014-05-26 15:06:32 -07003241 // Never start a new task on an ActivityView if it isn't explicitly specified.
3242 @Override
3243 boolean isEligibleForNewTasks() {
3244 return false;
3245 }
3246
Craig Mautner6985bad2014-04-21 15:22:06 -07003247 private void setSurfaceIfReady() {
3248 if (DEBUG_STACK) Slog.v(TAG, "setSurfaceIfReady: mDrawn=" + mDrawn +
3249 " mContainerState=" + mContainerState + " mSurface=" + mSurface);
3250 if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) {
3251 ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface);
3252 mContainerState = CONTAINER_STATE_HAS_SURFACE;
3253 }
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003254 }
3255 }
3256
Craig Mautner4a1cb222013-12-04 16:14:06 -08003257 /** Exactly one of these classes per Display in the system. Capable of holding zero or more
3258 * attached {@link ActivityStack}s */
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003259 class ActivityDisplay {
Craig Mautner4a1cb222013-12-04 16:14:06 -08003260 /** Actual Display this object tracks. */
Craig Mautner34b73df2014-01-12 21:11:08 -08003261 int mDisplayId;
3262 Display mDisplay;
3263 DisplayInfo mDisplayInfo = new DisplayInfo();
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003264
Craig Mautner4a1cb222013-12-04 16:14:06 -08003265 /** All of the stacks on this display. Order matters, topmost stack is in front of all other
3266 * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
Craig Mautnere0a38842013-12-16 16:14:02 -08003267 final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003268
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003269 ActivityDisplay() {
3270 }
Craig Mautner4504de52013-12-20 09:06:56 -08003271
Craig Mautnere0a38842013-12-16 16:14:02 -08003272 ActivityDisplay(int displayId) {
Craig Mautner34b73df2014-01-12 21:11:08 -08003273 init(mDisplayManager.getDisplay(displayId));
Craig Mautner4504de52013-12-20 09:06:56 -08003274 }
3275
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003276 void init(Display display) {
Craig Mautner4504de52013-12-20 09:06:56 -08003277 mDisplay = display;
3278 mDisplayId = display.getDisplayId();
Craig Mautner4a1cb222013-12-04 16:14:06 -08003279 mDisplay.getDisplayInfo(mDisplayInfo);
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003280 }
Craig Mautner4a1cb222013-12-04 16:14:06 -08003281
3282 void attachActivities(ActivityStack stack) {
Craig Mautnere0a38842013-12-16 16:14:02 -08003283 if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId="
3284 + mDisplayId);
3285 mStacks.add(stack);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003286 }
3287
Craig Mautnere0a38842013-12-16 16:14:02 -08003288 void detachActivitiesLocked(ActivityStack stack) {
Craig Mautner34b73df2014-01-12 21:11:08 -08003289 if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack
Craig Mautnere0a38842013-12-16 16:14:02 -08003290 + " from displayId=" + mDisplayId);
3291 mStacks.remove(stack);
Craig Mautner4a1cb222013-12-04 16:14:06 -08003292 }
3293
3294 void getBounds(Point bounds) {
3295 mDisplay.getDisplayInfo(mDisplayInfo);
3296 bounds.x = mDisplayInfo.appWidth;
3297 bounds.y = mDisplayInfo.appHeight;
3298 }
Craig Mautner34b73df2014-01-12 21:11:08 -08003299
3300 @Override
3301 public String toString() {
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003302 return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}";
3303 }
3304 }
3305
3306 class VirtualActivityDisplay extends ActivityDisplay {
3307 VirtualDisplay mVirtualDisplay;
3308
Craig Mautner6985bad2014-04-21 15:22:06 -07003309 VirtualActivityDisplay(int width, int height, int density) {
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003310 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
3311 mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, VIRTUAL_DISPLAY_BASE_NAME,
Craig Mautner6985bad2014-04-21 15:22:06 -07003312 width, height, density, null, DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
Craig Mautnerf4c909b2014-04-17 18:39:38 -07003313 DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY);
3314
3315 init(mVirtualDisplay.getDisplay());
3316
3317 mWindowManager.handleDisplayAdded(mDisplayId);
3318 }
3319
3320 void setSurface(Surface surface) {
3321 if (mVirtualDisplay != null) {
3322 mVirtualDisplay.setSurface(surface);
3323 }
3324 }
3325
3326 @Override
3327 void detachActivitiesLocked(ActivityStack stack) {
3328 super.detachActivitiesLocked(stack);
3329 if (mVirtualDisplay != null) {
3330 mVirtualDisplay.release();
3331 mVirtualDisplay = null;
3332 }
3333 }
3334
3335 @Override
3336 public String toString() {
3337 return "VirtualActivityDisplay={" + mDisplayId + "}";
Craig Mautner34b73df2014-01-12 21:11:08 -08003338 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003339 }
Craig Mautner27084302013-03-25 08:05:25 -07003340}