blob: 90097fd976e20985952d6f60e2ea3b688070734b [file] [log] [blame]
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001/*
2 * Copyright (C) 2018 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
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070019import static android.Manifest.permission.BIND_VOICE_INTERACTION;
20import static android.Manifest.permission.CHANGE_CONFIGURATION;
21import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
22import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070023import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070024import static android.Manifest.permission.READ_FRAME_BUFFER;
25import static android.Manifest.permission.REMOVE_TASKS;
26import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
27import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
Wale Ogunwale6767eae2018-05-03 15:52:51 -070028import static android.app.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT;
29import static android.app.ActivityTaskManagerInternal.ASSIST_KEY_DATA;
30import static android.app.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
31import static android.app.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070032import static android.app.ActivityTaskManager.INVALID_STACK_ID;
33import static android.app.ActivityTaskManager.RESIZE_MODE_PRESERVE_WINDOW;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070034import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070035import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070036import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070037import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
38import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
39import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070040import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
41import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070042import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070043import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070044import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070045import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070046import static android.os.Process.SYSTEM_UID;
47import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
48import static android.view.Display.DEFAULT_DISPLAY;
49import static android.view.Display.INVALID_DISPLAY;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070050import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
Wale Ogunwale6767eae2018-05-03 15:52:51 -070051import static android.view.WindowManager.TRANSIT_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070052import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070053import static android.view.WindowManager.TRANSIT_TASK_OPEN;
54import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070055import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070056import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
57import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
58import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
59import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
Wale Ogunwale6767eae2018-05-03 15:52:51 -070060import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070061import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070062import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
63import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
64import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
65import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
66import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070067import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070068import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
69import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070070import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
71import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070072import static com.android.server.am.ActivityManagerService.ALLOW_FULL_ONLY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070073import static com.android.server.am.ActivityManagerService.ANIMATE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070074import static com.android.server.am.ActivityManagerService.DISPATCH_SCREEN_KEYGUARD_MSG;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070075import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS;
76import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070077import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070078import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
79import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
80import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
81import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
82import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
83import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
84import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070085import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070086import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
87import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
88import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070089
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070090import android.Manifest;
91import android.annotation.Nullable;
92import android.annotation.UserIdInt;
93import android.app.Activity;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070094import android.app.ActivityManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070095import android.app.ActivityOptions;
96import android.app.ActivityTaskManager;
Wale Ogunwale6767eae2018-05-03 15:52:51 -070097import android.app.ActivityTaskManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070098import android.app.AppGlobals;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070099import android.app.IActivityTaskManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700100import android.app.IApplicationThread;
101import android.app.IAssistDataReceiver;
102import android.app.ITaskStackListener;
103import android.app.PictureInPictureParams;
104import android.app.ProfilerInfo;
105import android.app.RemoteAction;
106import android.app.WaitResult;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700107import android.app.WindowConfiguration;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700108import android.app.admin.DevicePolicyCache;
109import android.app.assist.AssistContent;
110import android.app.assist.AssistStructure;
111import android.app.usage.UsageEvents;
112import android.content.ActivityNotFoundException;
113import android.content.ComponentName;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700114import android.content.Context;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700115import android.content.IIntentSender;
116import android.content.Intent;
117import android.content.pm.ActivityInfo;
118import android.content.pm.PackageManager;
119import android.content.pm.ParceledListSlice;
120import android.content.pm.ResolveInfo;
121import android.content.res.Configuration;
122import android.graphics.Bitmap;
123import android.graphics.Point;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700124import android.graphics.Rect;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700125import android.metrics.LogMaker;
126import android.net.Uri;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700127import android.os.Binder;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700128import android.os.Bundle;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700129import android.os.Handler;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700130import android.os.IBinder;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700131import android.os.LocaleList;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700132import android.os.Looper;
133import android.os.Message;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700134import android.os.PersistableBundle;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700135import android.os.Process;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700136import android.os.RemoteException;
137import android.os.TransactionTooLargeException;
138import android.os.UserHandle;
139import android.provider.Settings;
140import android.service.voice.IVoiceInteractionSession;
141import android.service.voice.VoiceInteractionManagerInternal;
142import android.telecom.TelecomManager;
143import android.text.TextUtils;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700144import android.util.Slog;
145
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700146import android.util.SparseIntArray;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700147import android.util.proto.ProtoOutputStream;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700148import android.view.IRecentsAnimationRunner;
149import android.view.RemoteAnimationAdapter;
150import android.view.RemoteAnimationDefinition;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700151
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700152import com.android.internal.app.AssistUtils;
153import com.android.internal.app.IVoiceInteractor;
154import com.android.internal.logging.MetricsLogger;
155import com.android.internal.os.logging.MetricsLoggerWrapper;
156import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
157import com.android.internal.policy.IKeyguardDismissCallback;
158import com.android.internal.policy.KeyguardDismissCallback;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700159import com.android.internal.util.Preconditions;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700160import com.android.server.LocalServices;
161import com.android.server.SystemService;
162import com.android.server.Watchdog;
163import com.android.server.vr.VrManagerInternal;
164import com.android.server.wm.PinnedStackWindowController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700165import com.android.server.wm.WindowManagerService;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700166
167import java.io.File;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700168import java.io.PrintWriter;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700169import java.util.ArrayList;
170import java.util.List;
171
172/**
173 * System service for managing activities and their containers (task, stacks, displays,... ).
174 *
175 * {@hide}
176 */
177public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
178 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityTaskManagerService" : TAG_AM;
179 private static final String TAG_STACK = TAG + POSTFIX_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700180 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
181 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
182 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
183 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
184 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700185
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700186 Context mContext;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700187 H mH;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700188 ActivityManagerService mAm;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700189 /* Global service lock used by the package the owns this service. */
190 Object mGlobalLock;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700191 ActivityStackSupervisor mStackSupervisor;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700192 WindowManagerService mWindowManager;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700193 /** List of intents that were used to start the most recent tasks. */
194 private RecentTasks mRecentTasks;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700195 /** State of external calls telling us if the device is awake or asleep. */
196 private boolean mKeyguardShown = false;
197
198 // Wrapper around VoiceInteractionServiceManager
199 private AssistUtils mAssistUtils;
200
201 // VoiceInteraction session ID that changes for each new request except when
202 // being called for multi-window assist in a single session.
203 private int mViSessionId = 1000;
204
205 // How long to wait in getAssistContextExtras for the activity and foreground services
206 // to respond with the result.
207 private static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
208
209 // How long top wait when going through the modern assist (which doesn't need to block
210 // on getting this result before starting to launch its UI).
211 private static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
212
213 // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
214 private static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
215
216 private final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
217
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700218 // Keeps track of the active voice interaction service component, notified from
219 // VoiceInteractionManagerService
220 ComponentName mActiveVoiceInteractionServiceComponent;
221
222 private VrController mVrController;
223 KeyguardController mKeyguardController;
224 private final ClientLifecycleManager mLifecycleManager;
225 private TaskChangeNotificationController mTaskChangeNotificationController;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700226 /** The controller for all operations related to locktask. */
227 private LockTaskController mLockTaskController;
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700228 private ActivityStartController mActivityStartController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700229
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700230 boolean mSuppressResizeConfigChanges;
231
232 private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
233 new UpdateConfigurationResult();
234
235 static final class UpdateConfigurationResult {
236 // Configuration changes that were updated.
237 int changes;
238 // If the activity was relaunched to match the new configuration.
239 boolean activityRelaunched;
240
241 void reset() {
242 changes = 0;
243 activityRelaunched = false;
244 }
245 }
246
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700247 /** Current sequencing integer of the configuration, for skipping old configurations. */
248 int mConfigurationSeq;
249
250 /**
251 * Temp object used when global and/or display override configuration is updated. It is also
252 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
253 * anyone...
254 */
255 Configuration mTempConfig = new Configuration();
256
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700257 ActivityTaskManagerService(Context context) {
258 mContext = context;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700259 mLifecycleManager = new ClientLifecycleManager();
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700260 }
261
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700262 void onSystemReady() {
263 mAssistUtils = new AssistUtils(mContext);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700264 mVrController.onSystemReady();
265 mRecentTasks.onSystemReadyLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700266 }
267
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700268 // TODO: Will be converted to WM lock once transition is complete.
269 void setActivityManagerService(ActivityManagerService am) {
270 mAm = am;
271 mGlobalLock = mAm;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700272 mH = new H(mAm.mHandlerThread.getLooper());
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700273
274 mTempConfig.setToDefaults();
275 mTempConfig.setLocales(LocaleList.getDefault());
276 mConfigurationSeq = mTempConfig.seq = 1;
277 mStackSupervisor = createStackSupervisor();
278 mStackSupervisor.onConfigurationChanged(mTempConfig);
279
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700280 mTaskChangeNotificationController =
281 new TaskChangeNotificationController(mAm, mStackSupervisor, mH);
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700282 mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mH);
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700283 mActivityStartController = new ActivityStartController(this);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700284 mRecentTasks = createRecentTasks();
285 mStackSupervisor.setRecentTasks(mRecentTasks);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700286 mVrController = new VrController(mAm);
287 mKeyguardController = mStackSupervisor.getKeyguardController();
288 }
289
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700290 protected ActivityStackSupervisor createStackSupervisor() {
291 final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mH.getLooper());
292 supervisor.initialize();
293 return supervisor;
294 }
295
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700296 void setWindowManager(WindowManagerService wm) {
297 mWindowManager = wm;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700298 mLockTaskController.setWindowManager(wm);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700299 }
300
301 protected RecentTasks createRecentTasks() {
302 return new RecentTasks(this, mStackSupervisor);
303 }
304
305 RecentTasks getRecentTasks() {
306 return mRecentTasks;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700307 }
308
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700309 ClientLifecycleManager getLifecycleManager() {
310 return mLifecycleManager;
311 }
312
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700313 ActivityStartController getActivityStartController() {
314 return mActivityStartController;
315 }
316
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700317 TaskChangeNotificationController getTaskChangeNotificationController() {
318 return mTaskChangeNotificationController;
319 }
320
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700321 LockTaskController getLockTaskController() {
322 return mLockTaskController;
323 }
324
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700325 private void start() {
326 LocalServices.addService(ActivityTaskManagerInternal.class, new LocalService());
327 }
328
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700329 public static final class Lifecycle extends SystemService {
330 private final ActivityTaskManagerService mService;
331
332 public Lifecycle(Context context) {
333 super(context);
334 mService = new ActivityTaskManagerService(context);
335 }
336
337 @Override
338 public void onStart() {
339 publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700340 mService.start();
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700341 }
342
343 public ActivityTaskManagerService getService() {
344 return mService;
345 }
346 }
347
348 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700349 public final int startActivity(IApplicationThread caller, String callingPackage,
350 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
351 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
352 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
353 resultWho, requestCode, startFlags, profilerInfo, bOptions,
354 UserHandle.getCallingUserId());
355 }
356
357 @Override
358 public final int startActivities(IApplicationThread caller, String callingPackage,
359 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
360 int userId) {
361 final String reason = "startActivities";
362 mAm.enforceNotIsolatedCaller(reason);
363 userId = mAm.mUserController.handleIncomingUser(Binder.getCallingPid(),
364 Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY, reason, null);
365 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700366 return getActivityStartController().startActivities(caller, -1, callingPackage, intents,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700367 resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId, reason);
368 }
369
370 @Override
371 public int startActivityAsUser(IApplicationThread caller, String callingPackage,
372 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
373 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
374 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
375 resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
376 true /*validateIncomingUser*/);
377 }
378
379 int startActivityAsUser(IApplicationThread caller, String callingPackage,
380 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
381 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
382 boolean validateIncomingUser) {
383 mAm.enforceNotIsolatedCaller("startActivityAsUser");
384
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700385 userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700386 Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
387
388 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700389 return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700390 .setCaller(caller)
391 .setCallingPackage(callingPackage)
392 .setResolvedType(resolvedType)
393 .setResultTo(resultTo)
394 .setResultWho(resultWho)
395 .setRequestCode(requestCode)
396 .setStartFlags(startFlags)
397 .setProfilerInfo(profilerInfo)
398 .setActivityOptions(bOptions)
399 .setMayWait(userId)
400 .execute();
401
402 }
403
404 @Override
405 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
406 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
407 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
408 throws TransactionTooLargeException {
409 mAm.enforceNotIsolatedCaller("startActivityIntentSender");
410 // Refuse possible leaked file descriptors
411 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
412 throw new IllegalArgumentException("File descriptors passed in Intent");
413 }
414
415 if (!(target instanceof PendingIntentRecord)) {
416 throw new IllegalArgumentException("Bad PendingIntent object");
417 }
418
419 PendingIntentRecord pir = (PendingIntentRecord)target;
420
421 synchronized (mGlobalLock) {
422 // If this is coming from the currently resumed activity, it is
423 // effectively saying that app switches are allowed at this point.
424 final ActivityStack stack = mAm.getFocusedStack();
425 if (stack.mResumedActivity != null &&
426 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
427 mAm.mAppSwitchesAllowedTime = 0;
428 }
429 }
430 int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
431 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
432 return ret;
433 }
434
435 @Override
436 public boolean startNextMatchingActivity(IBinder callingActivity, Intent intent,
437 Bundle bOptions) {
438 // Refuse possible leaked file descriptors
439 if (intent != null && intent.hasFileDescriptors()) {
440 throw new IllegalArgumentException("File descriptors passed in Intent");
441 }
442 SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
443
444 synchronized (mGlobalLock) {
445 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
446 if (r == null) {
447 SafeActivityOptions.abort(options);
448 return false;
449 }
450 if (r.app == null || r.app.thread == null) {
451 // The caller is not running... d'oh!
452 SafeActivityOptions.abort(options);
453 return false;
454 }
455 intent = new Intent(intent);
456 // The caller is not allowed to change the data.
457 intent.setDataAndType(r.intent.getData(), r.intent.getType());
458 // And we are resetting to find the next component...
459 intent.setComponent(null);
460
461 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
462
463 ActivityInfo aInfo = null;
464 try {
465 List<ResolveInfo> resolves =
466 AppGlobals.getPackageManager().queryIntentActivities(
467 intent, r.resolvedType,
468 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
469 UserHandle.getCallingUserId()).getList();
470
471 // Look for the original activity in the list...
472 final int N = resolves != null ? resolves.size() : 0;
473 for (int i=0; i<N; i++) {
474 ResolveInfo rInfo = resolves.get(i);
475 if (rInfo.activityInfo.packageName.equals(r.packageName)
476 && rInfo.activityInfo.name.equals(r.info.name)) {
477 // We found the current one... the next matching is
478 // after it.
479 i++;
480 if (i<N) {
481 aInfo = resolves.get(i).activityInfo;
482 }
483 if (debug) {
484 Slog.v(TAG, "Next matching activity: found current " + r.packageName
485 + "/" + r.info.name);
486 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
487 ? "null" : aInfo.packageName + "/" + aInfo.name));
488 }
489 break;
490 }
491 }
492 } catch (RemoteException e) {
493 }
494
495 if (aInfo == null) {
496 // Nobody who is next!
497 SafeActivityOptions.abort(options);
498 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
499 return false;
500 }
501
502 intent.setComponent(new ComponentName(
503 aInfo.applicationInfo.packageName, aInfo.name));
504 intent.setFlags(intent.getFlags()&~(
505 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
506 Intent.FLAG_ACTIVITY_CLEAR_TOP|
507 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
508 FLAG_ACTIVITY_NEW_TASK));
509
510 // Okay now we need to start the new activity, replacing the currently running activity.
511 // This is a little tricky because we want to start the new one as if the current one is
512 // finished, but not finish the current one first so that there is no flicker.
513 // And thus...
514 final boolean wasFinishing = r.finishing;
515 r.finishing = true;
516
517 // Propagate reply information over to the new activity.
518 final ActivityRecord resultTo = r.resultTo;
519 final String resultWho = r.resultWho;
520 final int requestCode = r.requestCode;
521 r.resultTo = null;
522 if (resultTo != null) {
523 resultTo.removeResultsLocked(r, resultWho, requestCode);
524 }
525
526 final long origId = Binder.clearCallingIdentity();
527 // TODO(b/64750076): Check if calling pid should really be -1.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700528 final int res = getActivityStartController()
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700529 .obtainStarter(intent, "startNextMatchingActivity")
530 .setCaller(r.app.thread)
531 .setResolvedType(r.resolvedType)
532 .setActivityInfo(aInfo)
533 .setResultTo(resultTo != null ? resultTo.appToken : null)
534 .setResultWho(resultWho)
535 .setRequestCode(requestCode)
536 .setCallingPid(-1)
537 .setCallingUid(r.launchedFromUid)
538 .setCallingPackage(r.launchedFromPackage)
539 .setRealCallingPid(-1)
540 .setRealCallingUid(r.launchedFromUid)
541 .setActivityOptions(options)
542 .execute();
543 Binder.restoreCallingIdentity(origId);
544
545 r.finishing = wasFinishing;
546 if (res != ActivityManager.START_SUCCESS) {
547 return false;
548 }
549 return true;
550 }
551 }
552
553 @Override
554 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
555 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
556 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
557 final WaitResult res = new WaitResult();
558 synchronized (mGlobalLock) {
559 mAm.enforceNotIsolatedCaller("startActivityAndWait");
560 userId = mAm.mUserController.handleIncomingUser(Binder.getCallingPid(),
561 Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY,
562 "startActivityAndWait", null);
563 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700564 getActivityStartController().obtainStarter(intent, "startActivityAndWait")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700565 .setCaller(caller)
566 .setCallingPackage(callingPackage)
567 .setResolvedType(resolvedType)
568 .setResultTo(resultTo)
569 .setResultWho(resultWho)
570 .setRequestCode(requestCode)
571 .setStartFlags(startFlags)
572 .setActivityOptions(bOptions)
573 .setMayWait(userId)
574 .setProfilerInfo(profilerInfo)
575 .setWaitResult(res)
576 .execute();
577 }
578 return res;
579 }
580
581 @Override
582 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
583 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
584 int startFlags, Configuration config, Bundle bOptions, int userId) {
585 synchronized (mGlobalLock) {
586 mAm.enforceNotIsolatedCaller("startActivityWithConfig");
587 userId = mAm.mUserController.handleIncomingUser(Binder.getCallingPid(),
588 Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY,
589 "startActivityWithConfig", null);
590 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700591 return getActivityStartController().obtainStarter(intent, "startActivityWithConfig")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700592 .setCaller(caller)
593 .setCallingPackage(callingPackage)
594 .setResolvedType(resolvedType)
595 .setResultTo(resultTo)
596 .setResultWho(resultWho)
597 .setRequestCode(requestCode)
598 .setStartFlags(startFlags)
599 .setGlobalConfiguration(config)
600 .setActivityOptions(bOptions)
601 .setMayWait(userId)
602 .execute();
603 }
604 }
605
606 @Override
607 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
608 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
609 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
610 int userId) {
611
612 // This is very dangerous -- it allows you to perform a start activity (including
613 // permission grants) as any app that may launch one of your own activities. So
614 // we will only allow this to be done from activities that are part of the core framework,
615 // and then only when they are running as the system.
616 final ActivityRecord sourceRecord;
617 final int targetUid;
618 final String targetPackage;
619 final boolean isResolver;
620 synchronized (mGlobalLock) {
621 if (resultTo == null) {
622 throw new SecurityException("Must be called from an activity");
623 }
624 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
625 if (sourceRecord == null) {
626 throw new SecurityException("Called with bad activity token: " + resultTo);
627 }
628 if (!sourceRecord.info.packageName.equals("android")) {
629 throw new SecurityException(
630 "Must be called from an activity that is declared in the android package");
631 }
632 if (sourceRecord.app == null) {
633 throw new SecurityException("Called without a process attached to activity");
634 }
635 if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
636 // This is still okay, as long as this activity is running under the
637 // uid of the original calling activity.
638 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
639 throw new SecurityException(
640 "Calling activity in uid " + sourceRecord.app.uid
641 + " must be system uid or original calling uid "
642 + sourceRecord.launchedFromUid);
643 }
644 }
645 if (ignoreTargetSecurity) {
646 if (intent.getComponent() == null) {
647 throw new SecurityException(
648 "Component must be specified with ignoreTargetSecurity");
649 }
650 if (intent.getSelector() != null) {
651 throw new SecurityException(
652 "Selector not allowed with ignoreTargetSecurity");
653 }
654 }
655 targetUid = sourceRecord.launchedFromUid;
656 targetPackage = sourceRecord.launchedFromPackage;
657 isResolver = sourceRecord.isResolverOrChildActivity();
658 }
659
660 if (userId == UserHandle.USER_NULL) {
661 userId = UserHandle.getUserId(sourceRecord.app.uid);
662 }
663
664 // TODO: Switch to user app stacks here.
665 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700666 return getActivityStartController().obtainStarter(intent, "startActivityAsCaller")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700667 .setCallingUid(targetUid)
668 .setCallingPackage(targetPackage)
669 .setResolvedType(resolvedType)
670 .setResultTo(resultTo)
671 .setResultWho(resultWho)
672 .setRequestCode(requestCode)
673 .setStartFlags(startFlags)
674 .setActivityOptions(bOptions)
675 .setMayWait(userId)
676 .setIgnoreTargetSecurity(ignoreTargetSecurity)
677 .setFilterCallingUid(isResolver ? 0 /* system */ : targetUid)
678 .execute();
679 } catch (SecurityException e) {
680 // XXX need to figure out how to propagate to original app.
681 // A SecurityException here is generally actually a fault of the original
682 // calling activity (such as a fairly granting permissions), so propagate it
683 // back to them.
684 /*
685 StringBuilder msg = new StringBuilder();
686 msg.append("While launching");
687 msg.append(intent.toString());
688 msg.append(": ");
689 msg.append(e.getMessage());
690 */
691 throw e;
692 }
693 }
694
695 @Override
696 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
697 Intent intent, String resolvedType, IVoiceInteractionSession session,
698 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
699 Bundle bOptions, int userId) {
700 mAm.enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
701 if (session == null || interactor == null) {
702 throw new NullPointerException("null session or interactor");
703 }
704 userId = mAm.mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
705 ALLOW_FULL_ONLY, "startVoiceActivity", null);
706 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700707 return getActivityStartController().obtainStarter(intent, "startVoiceActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700708 .setCallingUid(callingUid)
709 .setCallingPackage(callingPackage)
710 .setResolvedType(resolvedType)
711 .setVoiceSession(session)
712 .setVoiceInteractor(interactor)
713 .setStartFlags(startFlags)
714 .setProfilerInfo(profilerInfo)
715 .setActivityOptions(bOptions)
716 .setMayWait(userId)
717 .execute();
718 }
719
720 @Override
721 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
722 Intent intent, String resolvedType, Bundle bOptions, int userId) {
723 mAm.enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
724 userId = mAm.mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
725 ALLOW_FULL_ONLY, "startAssistantActivity", null);
726
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700727 return getActivityStartController().obtainStarter(intent, "startAssistantActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700728 .setCallingUid(callingUid)
729 .setCallingPackage(callingPackage)
730 .setResolvedType(resolvedType)
731 .setActivityOptions(bOptions)
732 .setMayWait(userId)
733 .execute();
734 }
735
736 @Override
737 public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
738 IRecentsAnimationRunner recentsAnimationRunner) {
739 mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
740 final int callingPid = Binder.getCallingPid();
741 final long origId = Binder.clearCallingIdentity();
742 try {
743 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700744 final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
745 final int recentsUid = mRecentTasks.getRecentsComponentUid();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700746
747 // Start a new recents animation
748 final RecentsAnimation anim = new RecentsAnimation(mAm, mStackSupervisor,
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700749 getActivityStartController(), mAm.mWindowManager, mAm.mUserController,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700750 callingPid);
751 anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
752 recentsUid, assistDataReceiver);
753 }
754 } finally {
755 Binder.restoreCallingIdentity(origId);
756 }
757 }
758
759 @Override
760 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
761 mAm.enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
762 "startActivityFromRecents()");
763
764 final int callingPid = Binder.getCallingPid();
765 final int callingUid = Binder.getCallingUid();
766 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(bOptions);
767 final long origId = Binder.clearCallingIdentity();
768 try {
769 synchronized (mGlobalLock) {
770 return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
771 safeOptions);
772 }
773 } finally {
774 Binder.restoreCallingIdentity(origId);
775 }
776 }
777
778 /**
779 * This is the internal entry point for handling Activity.finish().
780 *
781 * @param token The Binder token referencing the Activity we want to finish.
782 * @param resultCode Result code, if any, from this Activity.
783 * @param resultData Result data (Intent), if any, from this Activity.
784 * @param finishTask Whether to finish the task associated with this Activity.
785 *
786 * @return Returns true if the activity successfully finished, or false if it is still running.
787 */
788 @Override
789 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
790 int finishTask) {
791 // Refuse possible leaked file descriptors
792 if (resultData != null && resultData.hasFileDescriptors()) {
793 throw new IllegalArgumentException("File descriptors passed in Intent");
794 }
795
796 synchronized (mGlobalLock) {
797 ActivityRecord r = ActivityRecord.isInStackLocked(token);
798 if (r == null) {
799 return true;
800 }
801 // Keep track of the root activity of the task before we finish it
802 TaskRecord tr = r.getTask();
803 ActivityRecord rootR = tr.getRootActivity();
804 if (rootR == null) {
805 Slog.w(TAG, "Finishing task with all activities already finished");
806 }
807 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
808 // finish.
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700809 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700810 return false;
811 }
812
813 if (mAm.mController != null) {
814 // Find the first activity that is not finishing.
815 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
816 if (next != null) {
817 // ask watcher if this is allowed
818 boolean resumeOK = true;
819 try {
820 resumeOK = mAm.mController.activityResuming(next.packageName);
821 } catch (RemoteException e) {
822 mAm.mController = null;
823 Watchdog.getInstance().setActivityController(null);
824 }
825
826 if (!resumeOK) {
827 Slog.i(TAG, "Not finishing activity because controller resumed");
828 return false;
829 }
830 }
831 }
832 final long origId = Binder.clearCallingIdentity();
833 try {
834 boolean res;
835 final boolean finishWithRootActivity =
836 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
837 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
838 || (finishWithRootActivity && r == rootR)) {
839 // If requested, remove the task that is associated to this activity only if it
840 // was the root activity in the task. The result code and data is ignored
841 // because we don't support returning them across task boundaries. Also, to
842 // keep backwards compatibility we remove the task from recents when finishing
843 // task with root activity.
844 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
845 finishWithRootActivity, "finish-activity");
846 if (!res) {
847 Slog.i(TAG, "Removing task failed to finish activity");
848 }
849 } else {
850 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
851 resultData, "app-request", true);
852 if (!res) {
853 Slog.i(TAG, "Failed to finish by app-request");
854 }
855 }
856 return res;
857 } finally {
858 Binder.restoreCallingIdentity(origId);
859 }
860 }
861 }
862
863 @Override
864 public boolean finishActivityAffinity(IBinder token) {
865 synchronized (mGlobalLock) {
866 final long origId = Binder.clearCallingIdentity();
867 try {
868 ActivityRecord r = ActivityRecord.isInStackLocked(token);
869 if (r == null) {
870 return false;
871 }
872
873 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
874 // can finish.
875 final TaskRecord task = r.getTask();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700876 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700877 return false;
878 }
879 return task.getStack().finishActivityAffinityLocked(r);
880 } finally {
881 Binder.restoreCallingIdentity(origId);
882 }
883 }
884 }
885
886 @Override
887 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
888 final long origId = Binder.clearCallingIdentity();
889 synchronized (mGlobalLock) {
890 ActivityStack stack = ActivityRecord.getStackLocked(token);
891 if (stack != null) {
892 ActivityRecord r =
893 mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
894 false /* processPausingActivities */, config);
895 if (stopProfiling) {
896 if ((mAm.mProfileProc == r.app) && mAm.mProfilerInfo != null) {
897 mAm.clearProfilerLocked();
898 }
899 }
900 }
901 }
902 Binder.restoreCallingIdentity(origId);
903 }
904
905 @Override
906 public final void activityResumed(IBinder token) {
907 final long origId = Binder.clearCallingIdentity();
908 synchronized (mGlobalLock) {
909 ActivityRecord.activityResumedLocked(token);
910 mAm.mWindowManager.notifyAppResumedFinished(token);
911 }
912 Binder.restoreCallingIdentity(origId);
913 }
914
915 @Override
916 public final void activityPaused(IBinder token) {
917 final long origId = Binder.clearCallingIdentity();
918 synchronized (mGlobalLock) {
919 ActivityStack stack = ActivityRecord.getStackLocked(token);
920 if (stack != null) {
921 stack.activityPausedLocked(token, false);
922 }
923 }
924 Binder.restoreCallingIdentity(origId);
925 }
926
927 @Override
928 public final void activityStopped(IBinder token, Bundle icicle,
929 PersistableBundle persistentState, CharSequence description) {
930 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
931
932 // Refuse possible leaked file descriptors
933 if (icicle != null && icicle.hasFileDescriptors()) {
934 throw new IllegalArgumentException("File descriptors passed in Bundle");
935 }
936
937 final long origId = Binder.clearCallingIdentity();
938
939 synchronized (mGlobalLock) {
940 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
941 if (r != null) {
942 r.activityStoppedLocked(icicle, persistentState, description);
943 }
944 }
945
946 mAm.trimApplications();
947
948 Binder.restoreCallingIdentity(origId);
949 }
950
951 @Override
952 public final void activityDestroyed(IBinder token) {
953 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
954 synchronized (mGlobalLock) {
955 ActivityStack stack = ActivityRecord.getStackLocked(token);
956 if (stack != null) {
957 stack.activityDestroyedLocked(token, "activityDestroyed");
958 }
959 }
960 }
961
962 @Override
963 public final void activityRelaunched(IBinder token) {
964 final long origId = Binder.clearCallingIdentity();
965 synchronized (mGlobalLock) {
966 mStackSupervisor.activityRelaunchedLocked(token);
967 }
968 Binder.restoreCallingIdentity(origId);
969 }
970
971 public final void activitySlept(IBinder token) {
972 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
973
974 final long origId = Binder.clearCallingIdentity();
975
976 synchronized (mGlobalLock) {
977 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
978 if (r != null) {
979 mStackSupervisor.activitySleptLocked(r);
980 }
981 }
982
983 Binder.restoreCallingIdentity(origId);
984 }
985
986 @Override
987 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
988 synchronized (mGlobalLock) {
989 ActivityRecord r = ActivityRecord.isInStackLocked(token);
990 if (r == null) {
991 return;
992 }
993 final long origId = Binder.clearCallingIdentity();
994 try {
995 r.setRequestedOrientation(requestedOrientation);
996 } finally {
997 Binder.restoreCallingIdentity(origId);
998 }
999 }
1000 }
1001
1002 @Override
1003 public int getRequestedOrientation(IBinder token) {
1004 synchronized (mGlobalLock) {
1005 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1006 if (r == null) {
1007 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
1008 }
1009 return r.getRequestedOrientation();
1010 }
1011 }
1012
1013 @Override
1014 public void setImmersive(IBinder token, boolean immersive) {
1015 synchronized (mGlobalLock) {
1016 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1017 if (r == null) {
1018 throw new IllegalArgumentException();
1019 }
1020 r.immersive = immersive;
1021
1022 // update associated state if we're frontmost
1023 if (r == mStackSupervisor.getResumedActivityLocked()) {
1024 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
1025 mAm.applyUpdateLockStateLocked(r);
1026 }
1027 }
1028 }
1029
1030 @Override
1031 public boolean isImmersive(IBinder token) {
1032 synchronized (mGlobalLock) {
1033 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1034 if (r == null) {
1035 throw new IllegalArgumentException();
1036 }
1037 return r.immersive;
1038 }
1039 }
1040
1041 @Override
1042 public boolean isTopActivityImmersive() {
1043 mAm.enforceNotIsolatedCaller("isTopActivityImmersive");
1044 synchronized (mGlobalLock) {
1045 final ActivityRecord r = mAm.getFocusedStack().topRunningActivityLocked();
1046 return (r != null) ? r.immersive : false;
1047 }
1048 }
1049
1050 @Override
1051 public void overridePendingTransition(IBinder token, String packageName,
1052 int enterAnim, int exitAnim) {
1053 synchronized (mGlobalLock) {
1054 ActivityRecord self = ActivityRecord.isInStackLocked(token);
1055 if (self == null) {
1056 return;
1057 }
1058
1059 final long origId = Binder.clearCallingIdentity();
1060
1061 if (self.isState(
1062 ActivityStack.ActivityState.RESUMED, ActivityStack.ActivityState.PAUSING)) {
1063 mAm.mWindowManager.overridePendingAppTransition(packageName,
1064 enterAnim, exitAnim, null);
1065 }
1066
1067 Binder.restoreCallingIdentity(origId);
1068 }
1069 }
1070
1071 @Override
1072 public int getFrontActivityScreenCompatMode() {
1073 mAm.enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
1074 synchronized (mGlobalLock) {
1075 return mAm.mCompatModePackages.getFrontActivityScreenCompatModeLocked();
1076 }
1077 }
1078
1079 @Override
1080 public void setFrontActivityScreenCompatMode(int mode) {
1081 mAm.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
1082 "setFrontActivityScreenCompatMode");
1083 synchronized (mGlobalLock) {
1084 mAm.mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
1085 }
1086 }
1087
1088 @Override
1089 public int getLaunchedFromUid(IBinder activityToken) {
1090 ActivityRecord srec;
1091 synchronized (mGlobalLock) {
1092 srec = ActivityRecord.forTokenLocked(activityToken);
1093 }
1094 if (srec == null) {
1095 return -1;
1096 }
1097 return srec.launchedFromUid;
1098 }
1099
1100 @Override
1101 public String getLaunchedFromPackage(IBinder activityToken) {
1102 ActivityRecord srec;
1103 synchronized (mGlobalLock) {
1104 srec = ActivityRecord.forTokenLocked(activityToken);
1105 }
1106 if (srec == null) {
1107 return null;
1108 }
1109 return srec.launchedFromPackage;
1110 }
1111
1112 @Override
1113 public boolean convertFromTranslucent(IBinder token) {
1114 final long origId = Binder.clearCallingIdentity();
1115 try {
1116 synchronized (mGlobalLock) {
1117 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1118 if (r == null) {
1119 return false;
1120 }
1121 final boolean translucentChanged = r.changeWindowTranslucency(true);
1122 if (translucentChanged) {
1123 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
1124 }
1125 mAm.mWindowManager.setAppFullscreen(token, true);
1126 return translucentChanged;
1127 }
1128 } finally {
1129 Binder.restoreCallingIdentity(origId);
1130 }
1131 }
1132
1133 @Override
1134 public boolean convertToTranslucent(IBinder token, Bundle options) {
1135 SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
1136 final long origId = Binder.clearCallingIdentity();
1137 try {
1138 synchronized (mGlobalLock) {
1139 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1140 if (r == null) {
1141 return false;
1142 }
1143 final TaskRecord task = r.getTask();
1144 int index = task.mActivities.lastIndexOf(r);
1145 if (index > 0) {
1146 ActivityRecord under = task.mActivities.get(index - 1);
1147 under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
1148 }
1149 final boolean translucentChanged = r.changeWindowTranslucency(false);
1150 if (translucentChanged) {
1151 r.getStack().convertActivityToTranslucent(r);
1152 }
1153 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
1154 mAm.mWindowManager.setAppFullscreen(token, false);
1155 return translucentChanged;
1156 }
1157 } finally {
1158 Binder.restoreCallingIdentity(origId);
1159 }
1160 }
1161
1162 @Override
1163 public void notifyActivityDrawn(IBinder token) {
1164 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
1165 synchronized (mGlobalLock) {
1166 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
1167 if (r != null) {
1168 r.getStack().notifyActivityDrawnLocked(r);
1169 }
1170 }
1171 }
1172
1173 @Override
1174 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
1175 synchronized (mGlobalLock) {
1176 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1177 if (r == null) {
1178 return;
1179 }
1180 r.reportFullyDrawnLocked(restoredFromBundle);
1181 }
1182 }
1183
1184 @Override
1185 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
1186 synchronized (mGlobalLock) {
1187 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
1188 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
1189 return stack.mDisplayId;
1190 }
1191 return DEFAULT_DISPLAY;
1192 }
1193 }
1194
1195 @Override
1196 public ActivityManager.StackInfo getFocusedStackInfo() throws RemoteException {
1197 mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
1198 long ident = Binder.clearCallingIdentity();
1199 try {
1200 synchronized (mGlobalLock) {
1201 ActivityStack focusedStack = mAm.getFocusedStack();
1202 if (focusedStack != null) {
1203 return mStackSupervisor.getStackInfo(focusedStack.mStackId);
1204 }
1205 return null;
1206 }
1207 } finally {
1208 Binder.restoreCallingIdentity(ident);
1209 }
1210 }
1211
1212 @Override
1213 public void setFocusedStack(int stackId) {
1214 mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
1215 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
1216 final long callingId = Binder.clearCallingIdentity();
1217 try {
1218 synchronized (mGlobalLock) {
1219 final ActivityStack stack = mStackSupervisor.getStack(stackId);
1220 if (stack == null) {
1221 Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
1222 return;
1223 }
1224 final ActivityRecord r = stack.topRunningActivityLocked();
1225 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
1226 r, "setFocusedStack")) {
1227 mStackSupervisor.resumeFocusedStackTopActivityLocked();
1228 }
1229 }
1230 } finally {
1231 Binder.restoreCallingIdentity(callingId);
1232 }
1233 }
1234
1235 @Override
1236 public void setFocusedTask(int taskId) {
1237 mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
1238 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
1239 final long callingId = Binder.clearCallingIdentity();
1240 try {
1241 synchronized (mGlobalLock) {
1242 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1243 if (task == null) {
1244 return;
1245 }
1246 final ActivityRecord r = task.topRunningActivityLocked();
1247 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
1248 mStackSupervisor.resumeFocusedStackTopActivityLocked();
1249 }
1250 }
1251 } finally {
1252 Binder.restoreCallingIdentity(callingId);
1253 }
1254 }
1255
1256 @Override
1257 public boolean removeTask(int taskId) {
1258 mAm.enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
1259 synchronized (mGlobalLock) {
1260 final long ident = Binder.clearCallingIdentity();
1261 try {
1262 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
1263 "remove-task");
1264 } finally {
1265 Binder.restoreCallingIdentity(ident);
1266 }
1267 }
1268 }
1269
1270 @Override
1271 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
1272 synchronized (mGlobalLock) {
1273 final ActivityRecord srec = ActivityRecord.forTokenLocked(token);
1274 if (srec != null) {
1275 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
1276 }
1277 }
1278 return false;
1279 }
1280
1281 @Override
1282 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
1283 Intent resultData) {
1284
1285 synchronized (mGlobalLock) {
1286 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
1287 if (r != null) {
1288 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
1289 }
1290 return false;
1291 }
1292 }
1293
1294 /**
1295 * Attempts to move a task backwards in z-order (the order of activities within the task is
1296 * unchanged).
1297 *
1298 * There are several possible results of this call:
1299 * - if the task is locked, then we will show the lock toast
1300 * - if there is a task behind the provided task, then that task is made visible and resumed as
1301 * this task is moved to the back
1302 * - otherwise, if there are no other tasks in the stack:
1303 * - if this task is in the pinned stack, then we remove the stack completely, which will
1304 * have the effect of moving the task to the top or bottom of the fullscreen stack
1305 * (depending on whether it is visible)
1306 * - otherwise, we simply return home and hide this task
1307 *
1308 * @param token A reference to the activity we wish to move
1309 * @param nonRoot If false then this only works if the activity is the root
1310 * of a task; if true it will work for any activity in a task.
1311 * @return Returns true if the move completed, false if not.
1312 */
1313 @Override
1314 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
1315 mAm.enforceNotIsolatedCaller("moveActivityTaskToBack");
1316 synchronized (mGlobalLock) {
1317 final long origId = Binder.clearCallingIdentity();
1318 try {
1319 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
1320 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1321 if (task != null) {
1322 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
1323 }
1324 } finally {
1325 Binder.restoreCallingIdentity(origId);
1326 }
1327 }
1328 return false;
1329 }
1330
1331 @Override
1332 public Rect getTaskBounds(int taskId) {
1333 mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
1334 long ident = Binder.clearCallingIdentity();
1335 Rect rect = new Rect();
1336 try {
1337 synchronized (mGlobalLock) {
1338 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
1339 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1340 if (task == null) {
1341 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
1342 return rect;
1343 }
1344 if (task.getStack() != null) {
1345 // Return the bounds from window manager since it will be adjusted for various
1346 // things like the presense of a docked stack for tasks that aren't resizeable.
1347 task.getWindowContainerBounds(rect);
1348 } else {
1349 // Task isn't in window manager yet since it isn't associated with a stack.
1350 // Return the persist value from activity manager
1351 if (!task.matchParentBounds()) {
1352 rect.set(task.getBounds());
1353 } else if (task.mLastNonFullscreenBounds != null) {
1354 rect.set(task.mLastNonFullscreenBounds);
1355 }
1356 }
1357 }
1358 } finally {
1359 Binder.restoreCallingIdentity(ident);
1360 }
1361 return rect;
1362 }
1363
1364 @Override
1365 public ActivityManager.TaskDescription getTaskDescription(int id) {
1366 synchronized (mGlobalLock) {
1367 mAm.enforceCallerIsRecentsOrHasPermission(
1368 MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
1369 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
1370 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1371 if (tr != null) {
1372 return tr.lastTaskDescription;
1373 }
1374 }
1375 return null;
1376 }
1377
1378 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001379 public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
1380 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
1381 setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
1382 toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
1383 return;
1384 }
1385 mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
1386 synchronized (mGlobalLock) {
1387 final long ident = Binder.clearCallingIdentity();
1388 try {
1389 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1390 if (task == null) {
1391 Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
1392 return;
1393 }
1394
1395 if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
1396 + " to windowingMode=" + windowingMode + " toTop=" + toTop);
1397
1398 if (!task.isActivityTypeStandardOrUndefined()) {
1399 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
1400 + " non-standard task " + taskId + " to windowing mode="
1401 + windowingMode);
1402 }
1403
1404 final ActivityStack stack = task.getStack();
1405 if (toTop) {
1406 stack.moveToFront("setTaskWindowingMode", task);
1407 }
1408 stack.setWindowingMode(windowingMode);
1409 } finally {
1410 Binder.restoreCallingIdentity(ident);
1411 }
1412 }
1413 }
1414
1415 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001416 public String getCallingPackage(IBinder token) {
1417 synchronized (this) {
1418 ActivityRecord r = getCallingRecordLocked(token);
1419 return r != null ? r.info.packageName : null;
1420 }
1421 }
1422
1423 @Override
1424 public ComponentName getCallingActivity(IBinder token) {
1425 synchronized (this) {
1426 ActivityRecord r = getCallingRecordLocked(token);
1427 return r != null ? r.intent.getComponent() : null;
1428 }
1429 }
1430
1431 private ActivityRecord getCallingRecordLocked(IBinder token) {
1432 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1433 if (r == null) {
1434 return null;
1435 }
1436 return r.resultTo;
1437 }
1438
1439 @Override
1440 public void unhandledBack() {
1441 mAm.enforceCallingPermission(android.Manifest.permission.FORCE_BACK, "unhandledBack()");
1442
1443 synchronized (mGlobalLock) {
1444 final long origId = Binder.clearCallingIdentity();
1445 try {
1446 mAm.getFocusedStack().unhandledBackLocked();
1447 } finally {
1448 Binder.restoreCallingIdentity(origId);
1449 }
1450 }
1451 }
1452
1453 /**
1454 * TODO: Add mController hook
1455 */
1456 @Override
1457 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
1458 mAm.enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
1459
1460 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
1461 synchronized (mGlobalLock) {
1462 moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
1463 false /* fromRecents */);
1464 }
1465 }
1466
1467 void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
1468 boolean fromRecents) {
1469
1470 if (!mAm.checkAppSwitchAllowedLocked(Binder.getCallingPid(),
1471 Binder.getCallingUid(), -1, -1, "Task to front")) {
1472 SafeActivityOptions.abort(options);
1473 return;
1474 }
1475 final long origId = Binder.clearCallingIdentity();
1476 try {
1477 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1478 if (task == null) {
1479 Slog.d(TAG, "Could not find task for id: "+ taskId);
1480 return;
1481 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001482 if (getLockTaskController().isLockTaskModeViolation(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001483 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
1484 return;
1485 }
1486 ActivityOptions realOptions = options != null
1487 ? options.getOptions(mStackSupervisor)
1488 : null;
1489 mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
1490 false /* forceNonResizable */);
1491
1492 final ActivityRecord topActivity = task.getTopActivity();
1493 if (topActivity != null) {
1494
1495 // We are reshowing a task, use a starting window to hide the initial draw delay
1496 // so the transition can start earlier.
1497 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
1498 true /* taskSwitch */, fromRecents);
1499 }
1500 } finally {
1501 Binder.restoreCallingIdentity(origId);
1502 }
1503 SafeActivityOptions.abort(options);
1504 }
1505
1506 @Override
1507 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
1508 synchronized (mGlobalLock) {
1509 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
1510 }
1511 }
1512
1513 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001514 public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum) {
1515 return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
1516 }
1517
1518 @Override
1519 public List<ActivityManager.RunningTaskInfo> getFilteredTasks(int maxNum,
1520 @WindowConfiguration.ActivityType int ignoreActivityType,
1521 @WindowConfiguration.WindowingMode int ignoreWindowingMode) {
1522 final int callingUid = Binder.getCallingUid();
1523 ArrayList<ActivityManager.RunningTaskInfo> list = new ArrayList<>();
1524
1525 synchronized (mGlobalLock) {
1526 if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
1527
1528 final boolean allowed = mAm.isGetTasksAllowed("getTasks", Binder.getCallingPid(),
1529 callingUid);
1530 mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
1531 ignoreWindowingMode, callingUid, allowed);
1532 }
1533
1534 return list;
1535 }
1536
1537 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001538 public final void finishSubActivity(IBinder token, String resultWho, int requestCode) {
1539 synchronized (mGlobalLock) {
1540 final long origId = Binder.clearCallingIdentity();
1541 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1542 if (r != null) {
1543 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
1544 }
1545 Binder.restoreCallingIdentity(origId);
1546 }
1547 }
1548
1549 @Override
1550 public boolean willActivityBeVisible(IBinder token) {
1551 synchronized(this) {
1552 ActivityStack stack = ActivityRecord.getStackLocked(token);
1553 if (stack != null) {
1554 return stack.willActivityBeVisibleLocked(token);
1555 }
1556 return false;
1557 }
1558 }
1559
1560 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001561 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
1562 mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
1563 synchronized (mGlobalLock) {
1564 final long ident = Binder.clearCallingIdentity();
1565 try {
1566 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1567 if (task == null) {
1568 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
1569 return;
1570 }
1571
1572 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
1573 + " to stackId=" + stackId + " toTop=" + toTop);
1574
1575 final ActivityStack stack = mStackSupervisor.getStack(stackId);
1576 if (stack == null) {
1577 throw new IllegalStateException(
1578 "moveTaskToStack: No stack for stackId=" + stackId);
1579 }
1580 if (!stack.isActivityTypeStandardOrUndefined()) {
1581 throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
1582 + taskId + " to stack " + stackId);
1583 }
1584 if (stack.inSplitScreenPrimaryWindowingMode()) {
1585 mAm.mWindowManager.setDockedStackCreateState(
1586 SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
1587 }
1588 task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
1589 "moveTaskToStack");
1590 } finally {
1591 Binder.restoreCallingIdentity(ident);
1592 }
1593 }
1594 }
1595
1596 @Override
1597 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
1598 boolean preserveWindows, boolean animate, int animationDuration) {
1599 mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
1600
1601 final long ident = Binder.clearCallingIdentity();
1602 try {
1603 synchronized (mGlobalLock) {
1604 if (animate) {
1605 final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
1606 if (stack == null) {
1607 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
1608 return;
1609 }
1610 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
1611 throw new IllegalArgumentException("Stack: " + stackId
1612 + " doesn't support animated resize.");
1613 }
1614 stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
1615 animationDuration, false /* fromFullscreen */);
1616 } else {
1617 final ActivityStack stack = mStackSupervisor.getStack(stackId);
1618 if (stack == null) {
1619 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
1620 return;
1621 }
1622 mStackSupervisor.resizeStackLocked(stack, destBounds,
1623 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
1624 preserveWindows, allowResizeInDockedMode, !DEFER_RESUME);
1625 }
1626 }
1627 } finally {
1628 Binder.restoreCallingIdentity(ident);
1629 }
1630 }
1631
1632 /**
1633 * Moves the specified task to the primary-split-screen stack.
1634 *
1635 * @param taskId Id of task to move.
1636 * @param createMode The mode the primary split screen stack should be created in if it doesn't
1637 * exist already. See
1638 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
1639 * and
1640 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
1641 * @param toTop If the task and stack should be moved to the top.
1642 * @param animate Whether we should play an animation for the moving the task.
1643 * @param initialBounds If the primary stack gets created, it will use these bounds for the
1644 * stack. Pass {@code null} to use default bounds.
1645 * @param showRecents If the recents activity should be shown on the other side of the task
1646 * going into split-screen mode.
1647 */
1648 @Override
1649 public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode,
1650 boolean toTop, boolean animate, Rect initialBounds, boolean showRecents) {
1651 mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
1652 "setTaskWindowingModeSplitScreenPrimary()");
1653 synchronized (mGlobalLock) {
1654 final long ident = Binder.clearCallingIdentity();
1655 try {
1656 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1657 if (task == null) {
1658 Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
1659 return false;
1660 }
1661 if (DEBUG_STACK) Slog.d(TAG_STACK,
1662 "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
1663 + " to createMode=" + createMode + " toTop=" + toTop);
1664 if (!task.isActivityTypeStandardOrUndefined()) {
1665 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
1666 + " non-standard task " + taskId + " to split-screen windowing mode");
1667 }
1668
1669 mAm.mWindowManager.setDockedStackCreateState(createMode, initialBounds);
1670 final int windowingMode = task.getWindowingMode();
1671 final ActivityStack stack = task.getStack();
1672 if (toTop) {
1673 stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
1674 }
1675 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
1676 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */);
1677 return windowingMode != task.getWindowingMode();
1678 } finally {
1679 Binder.restoreCallingIdentity(ident);
1680 }
1681 }
1682 }
1683
1684 /**
1685 * Removes stacks in the input windowing modes from the system if they are of activity type
1686 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
1687 */
1688 @Override
1689 public void removeStacksInWindowingModes(int[] windowingModes) {
1690 mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
1691 "removeStacksInWindowingModes()");
1692
1693 synchronized (mGlobalLock) {
1694 final long ident = Binder.clearCallingIdentity();
1695 try {
1696 mStackSupervisor.removeStacksInWindowingModes(windowingModes);
1697 } finally {
1698 Binder.restoreCallingIdentity(ident);
1699 }
1700 }
1701 }
1702
1703 @Override
1704 public void removeStacksWithActivityTypes(int[] activityTypes) {
1705 mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
1706 "removeStacksWithActivityTypes()");
1707
1708 synchronized (mGlobalLock) {
1709 final long ident = Binder.clearCallingIdentity();
1710 try {
1711 mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
1712 } finally {
1713 Binder.restoreCallingIdentity(ident);
1714 }
1715 }
1716 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001717
1718 @Override
1719 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
1720 int userId) {
1721 final int callingUid = Binder.getCallingUid();
1722 userId = mAm.mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
1723 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
1724 final boolean allowed = mAm.isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
1725 callingUid);
1726 final boolean detailed = mAm.checkCallingPermission(
1727 android.Manifest.permission.GET_DETAILED_TASKS)
1728 == PackageManager.PERMISSION_GRANTED;
1729
1730 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07001731 return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001732 callingUid);
1733 }
1734 }
1735
1736 @Override
1737 public List<ActivityManager.StackInfo> getAllStackInfos() {
1738 mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
1739 long ident = Binder.clearCallingIdentity();
1740 try {
1741 synchronized (mGlobalLock) {
1742 return mStackSupervisor.getAllStackInfosLocked();
1743 }
1744 } finally {
1745 Binder.restoreCallingIdentity(ident);
1746 }
1747 }
1748
1749 @Override
1750 public ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
1751 mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
1752 long ident = Binder.clearCallingIdentity();
1753 try {
1754 synchronized (mGlobalLock) {
1755 return mStackSupervisor.getStackInfo(windowingMode, activityType);
1756 }
1757 } finally {
1758 Binder.restoreCallingIdentity(ident);
1759 }
1760 }
1761
1762 @Override
1763 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
1764 mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
1765 final long callingUid = Binder.getCallingUid();
1766 final long origId = Binder.clearCallingIdentity();
1767 try {
1768 synchronized (mGlobalLock) {
1769 // Cancel the recents animation synchronously (do not hold the WM lock)
1770 mAm.mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
1771 ? REORDER_MOVE_TO_ORIGINAL_POSITION
1772 : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
1773 }
1774 } finally {
1775 Binder.restoreCallingIdentity(origId);
1776 }
1777 }
1778
1779 @Override
1780 public void startLockTaskModeByToken(IBinder token) {
1781 synchronized (mGlobalLock) {
1782 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
1783 if (r == null) {
1784 return;
1785 }
1786 startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
1787 }
1788 }
1789
1790 @Override
1791 public void startSystemLockTaskMode(int taskId) throws RemoteException {
1792 mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
1793 // This makes inner call to look as if it was initiated by system.
1794 long ident = Binder.clearCallingIdentity();
1795 try {
1796 synchronized (mGlobalLock) {
1797 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1798
1799 // When starting lock task mode the stack must be in front and focused
1800 task.getStack().moveToFront("startSystemLockTaskMode");
1801 startLockTaskModeLocked(task, true /* isSystemCaller */);
1802 }
1803 } finally {
1804 Binder.restoreCallingIdentity(ident);
1805 }
1806 }
1807
1808 @Override
1809 public void stopLockTaskModeByToken(IBinder token) {
1810 synchronized (mGlobalLock) {
1811 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
1812 if (r == null) {
1813 return;
1814 }
1815 stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
1816 }
1817 }
1818
1819 /**
1820 * This API should be called by SystemUI only when user perform certain action to dismiss
1821 * lock task mode. We should only dismiss pinned lock task mode in this case.
1822 */
1823 @Override
1824 public void stopSystemLockTaskMode() throws RemoteException {
1825 mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
1826 stopLockTaskModeInternal(null, true /* isSystemCaller */);
1827 }
1828
1829 private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
1830 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
1831 if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
1832 return;
1833 }
1834
1835 final ActivityStack stack = mStackSupervisor.getFocusedStack();
1836 if (stack == null || task != stack.topTask()) {
1837 throw new IllegalArgumentException("Invalid task, not in foreground");
1838 }
1839
1840 // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
1841 // system or a specific app.
1842 // * System-initiated requests will only start the pinned mode (screen pinning)
1843 // * App-initiated requests
1844 // - will put the device in fully locked mode (LockTask), if the app is whitelisted
1845 // - will start the pinned mode, otherwise
1846 final int callingUid = Binder.getCallingUid();
1847 long ident = Binder.clearCallingIdentity();
1848 try {
1849 // When a task is locked, dismiss the pinned stack if it exists
1850 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
1851
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001852 getLockTaskController().startLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001853 } finally {
1854 Binder.restoreCallingIdentity(ident);
1855 }
1856 }
1857
1858 private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
1859 final int callingUid = Binder.getCallingUid();
1860 long ident = Binder.clearCallingIdentity();
1861 try {
1862 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001863 getLockTaskController().stopLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001864 }
1865 // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
1866 // task and jumping straight into a call in the case of emergency call back.
1867 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
1868 if (tm != null) {
1869 tm.showInCallScreen(false);
1870 }
1871 } finally {
1872 Binder.restoreCallingIdentity(ident);
1873 }
1874 }
1875
1876 @Override
1877 public boolean isInLockTaskMode() {
1878 return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
1879 }
1880
1881 @Override
1882 public int getLockTaskModeState() {
1883 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001884 return getLockTaskController().getLockTaskModeState();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001885 }
1886 }
1887
1888 @Override
1889 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
1890 synchronized (mGlobalLock) {
1891 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1892 if (r != null) {
1893 r.setTaskDescription(td);
1894 final TaskRecord task = r.getTask();
1895 task.updateTaskDescription();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07001896 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001897 }
1898 }
1899 }
1900
1901 @Override
1902 public Bundle getActivityOptions(IBinder token) {
1903 final long origId = Binder.clearCallingIdentity();
1904 try {
1905 synchronized (mGlobalLock) {
1906 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1907 if (r != null) {
1908 final ActivityOptions activityOptions = r.takeOptionsLocked();
1909 return activityOptions == null ? null : activityOptions.toBundle();
1910 }
1911 return null;
1912 }
1913 } finally {
1914 Binder.restoreCallingIdentity(origId);
1915 }
1916 }
1917
1918 @Override
1919 public List<IBinder> getAppTasks(String callingPackage) {
1920 int callingUid = Binder.getCallingUid();
1921 long ident = Binder.clearCallingIdentity();
1922 try {
1923 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07001924 return mRecentTasks.getAppTasksList(callingUid, callingPackage);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001925 }
1926 } finally {
1927 Binder.restoreCallingIdentity(ident);
1928 }
1929 }
1930
1931 @Override
1932 public void finishVoiceTask(IVoiceInteractionSession session) {
1933 synchronized (mGlobalLock) {
1934 final long origId = Binder.clearCallingIdentity();
1935 try {
1936 // TODO: VI Consider treating local voice interactions and voice tasks
1937 // differently here
1938 mStackSupervisor.finishVoiceTask(session);
1939 } finally {
1940 Binder.restoreCallingIdentity(origId);
1941 }
1942 }
1943
1944 }
1945
1946 @Override
1947 public boolean isTopOfTask(IBinder token) {
1948 synchronized (mGlobalLock) {
1949 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1950 if (r == null) {
1951 throw new IllegalArgumentException();
1952 }
1953 return r.getTask().getTopActivity() == r;
1954 }
1955 }
1956
1957 @Override
1958 public void notifyLaunchTaskBehindComplete(IBinder token) {
1959 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
1960 }
1961
1962 @Override
1963 public void notifyEnterAnimationComplete(IBinder token) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07001964 mH.post(() -> {
1965 synchronized (mGlobalLock) {
1966 ActivityRecord r = ActivityRecord.forTokenLocked(token);
1967 if (r != null && r.app != null && r.app.thread != null) {
1968 try {
1969 r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1970 } catch (RemoteException e) {
1971 }
1972 }
1973 }
1974
1975 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001976 }
1977
1978 /** Called from an app when assist data is ready. */
1979 @Override
1980 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
1981 AssistContent content, Uri referrer) {
1982 PendingAssistExtras pae = (PendingAssistExtras)token;
1983 synchronized (pae) {
1984 pae.result = extras;
1985 pae.structure = structure;
1986 pae.content = content;
1987 if (referrer != null) {
1988 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
1989 }
1990 if (structure != null) {
1991 structure.setHomeActivity(pae.isHome);
1992 }
1993 pae.haveResult = true;
1994 pae.notifyAll();
1995 if (pae.intent == null && pae.receiver == null) {
1996 // Caller is just waiting for the result.
1997 return;
1998 }
1999 }
2000 // We are now ready to launch the assist activity.
2001 IAssistDataReceiver sendReceiver = null;
2002 Bundle sendBundle = null;
2003 synchronized (mGlobalLock) {
2004 buildAssistBundleLocked(pae, extras);
2005 boolean exists = mPendingAssistExtras.remove(pae);
2006 mAm.mUiHandler.removeCallbacks(pae);
2007 if (!exists) {
2008 // Timed out.
2009 return;
2010 }
2011
2012 if ((sendReceiver=pae.receiver) != null) {
2013 // Caller wants result sent back to them.
2014 sendBundle = new Bundle();
2015 sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
2016 sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
2017 sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
2018 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
2019 }
2020 }
2021 if (sendReceiver != null) {
2022 try {
2023 sendReceiver.onHandleAssistData(sendBundle);
2024 } catch (RemoteException e) {
2025 }
2026 return;
2027 }
2028
2029 final long ident = Binder.clearCallingIdentity();
2030 try {
2031 if (TextUtils.equals(pae.intent.getAction(),
2032 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
2033 pae.intent.putExtras(pae.extras);
2034 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
2035 } else {
2036 pae.intent.replaceExtras(pae.extras);
2037 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
2038 | Intent.FLAG_ACTIVITY_SINGLE_TOP
2039 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
2040 mAm.closeSystemDialogs("assist");
2041
2042 try {
2043 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
2044 } catch (ActivityNotFoundException e) {
2045 Slog.w(TAG, "No activity to handle assist action.", e);
2046 }
2047 }
2048 } finally {
2049 Binder.restoreCallingIdentity(ident);
2050 }
2051 }
2052
2053 @Override
2054 public int addAppTask(IBinder activityToken, Intent intent,
2055 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
2056 final int callingUid = Binder.getCallingUid();
2057 final long callingIdent = Binder.clearCallingIdentity();
2058
2059 try {
2060 synchronized (mGlobalLock) {
2061 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
2062 if (r == null) {
2063 throw new IllegalArgumentException("Activity does not exist; token="
2064 + activityToken);
2065 }
2066 ComponentName comp = intent.getComponent();
2067 if (comp == null) {
2068 throw new IllegalArgumentException("Intent " + intent
2069 + " must specify explicit component");
2070 }
2071 if (thumbnail.getWidth() != mAm.mThumbnailWidth
2072 || thumbnail.getHeight() != mAm.mThumbnailHeight) {
2073 throw new IllegalArgumentException("Bad thumbnail size: got "
2074 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
2075 + mAm.mThumbnailWidth + "x" + mAm.mThumbnailHeight);
2076 }
2077 if (intent.getSelector() != null) {
2078 intent.setSelector(null);
2079 }
2080 if (intent.getSourceBounds() != null) {
2081 intent.setSourceBounds(null);
2082 }
2083 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
2084 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
2085 // The caller has added this as an auto-remove task... that makes no
2086 // sense, so turn off auto-remove.
2087 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
2088 }
2089 }
2090 final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
2091 STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
2092 if (ainfo.applicationInfo.uid != callingUid) {
2093 throw new SecurityException(
2094 "Can't add task for another application: target uid="
2095 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
2096 }
2097
2098 final ActivityStack stack = r.getStack();
2099 final TaskRecord task = stack.createTaskRecord(
2100 mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent,
2101 null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002102 if (!mRecentTasks.addToBottom(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002103 // The app has too many tasks already and we can't add any more
2104 stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
2105 return INVALID_TASK_ID;
2106 }
2107 task.lastTaskDescription.copyFrom(description);
2108
2109 // TODO: Send the thumbnail to WM to store it.
2110
2111 return task.taskId;
2112 }
2113 } finally {
2114 Binder.restoreCallingIdentity(callingIdent);
2115 }
2116 }
2117
2118 @Override
2119 public Point getAppTaskThumbnailSize() {
2120 synchronized (mGlobalLock) {
2121 return new Point(mAm.mThumbnailWidth, mAm.mThumbnailHeight);
2122 }
2123 }
2124
2125 @Override
2126 public void setTaskResizeable(int taskId, int resizeableMode) {
2127 synchronized (mGlobalLock) {
2128 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
2129 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
2130 if (task == null) {
2131 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
2132 return;
2133 }
2134 task.setResizeMode(resizeableMode);
2135 }
2136 }
2137
2138 @Override
2139 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
2140 mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
2141 long ident = Binder.clearCallingIdentity();
2142 try {
2143 synchronized (mGlobalLock) {
2144 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2145 if (task == null) {
2146 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
2147 return;
2148 }
2149 // Place the task in the right stack if it isn't there already based on
2150 // the requested bounds.
2151 // The stack transition logic is:
2152 // - a null bounds on a freeform task moves that task to fullscreen
2153 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
2154 // that task to freeform
2155 // - otherwise the task is not moved
2156 ActivityStack stack = task.getStack();
2157 if (!task.getWindowConfiguration().canResizeTask()) {
2158 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
2159 }
2160 if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
2161 stack = stack.getDisplay().getOrCreateStack(
2162 WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
2163 } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
2164 stack = stack.getDisplay().getOrCreateStack(
2165 WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
2166 }
2167
2168 // Reparent the task to the right stack if necessary
2169 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
2170 if (stack != task.getStack()) {
2171 // Defer resume until the task is resized below
2172 task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
2173 DEFER_RESUME, "resizeTask");
2174 preserveWindow = false;
2175 }
2176
2177 // After reparenting (which only resizes the task to the stack bounds), resize the
2178 // task to the actual bounds provided
2179 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
2180 }
2181 } finally {
2182 Binder.restoreCallingIdentity(ident);
2183 }
2184 }
2185
2186 @Override
2187 public boolean releaseActivityInstance(IBinder token) {
2188 synchronized (mGlobalLock) {
2189 final long origId = Binder.clearCallingIdentity();
2190 try {
2191 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2192 if (r == null) {
2193 return false;
2194 }
2195 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
2196 } finally {
2197 Binder.restoreCallingIdentity(origId);
2198 }
2199 }
2200 }
2201
2202 @Override
2203 public void releaseSomeActivities(IApplicationThread appInt) {
2204 synchronized (mGlobalLock) {
2205 final long origId = Binder.clearCallingIdentity();
2206 try {
2207 ProcessRecord app = mAm.getRecordForAppLocked(appInt);
2208 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
2209 } finally {
2210 Binder.restoreCallingIdentity(origId);
2211 }
2212 }
2213 }
2214
2215 @Override
2216 public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
2217 int secondaryDisplayShowing) {
2218 if (mAm.checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
2219 != PackageManager.PERMISSION_GRANTED) {
2220 throw new SecurityException("Requires permission "
2221 + android.Manifest.permission.DEVICE_POWER);
2222 }
2223
2224 synchronized (mGlobalLock) {
2225 long ident = Binder.clearCallingIdentity();
2226 if (mKeyguardShown != keyguardShowing) {
2227 mKeyguardShown = keyguardShowing;
2228 reportCurKeyguardUsageEventLocked(keyguardShowing);
2229 }
2230 try {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002231 mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002232 secondaryDisplayShowing);
2233 } finally {
2234 Binder.restoreCallingIdentity(ident);
2235 }
2236 }
2237
2238 mAm.mHandler.obtainMessage(DISPATCH_SCREEN_KEYGUARD_MSG, keyguardShowing ? 1 : 0, 0)
2239 .sendToTarget();
2240 }
2241
2242 @Override
2243 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
2244 userId = mAm.mUserController.handleIncomingUser(Binder.getCallingPid(),
2245 Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY, "getTaskDescriptionIcon", null);
2246
2247 final File passedIconFile = new File(filePath);
2248 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
2249 passedIconFile.getName());
2250 if (!legitIconFile.getPath().equals(filePath)
2251 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
2252 throw new IllegalArgumentException("Bad file path: " + filePath
2253 + " passed for userId " + userId);
2254 }
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002255 return mRecentTasks.getTaskDescriptionIcon(filePath);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002256 }
2257
2258 @Override
2259 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
2260 throws RemoteException {
2261 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
2262 final ActivityOptions activityOptions = safeOptions != null
2263 ? safeOptions.getOptions(mStackSupervisor)
2264 : null;
2265 if (activityOptions == null
2266 || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
2267 || activityOptions.getCustomInPlaceResId() == 0) {
2268 throw new IllegalArgumentException("Expected in-place ActivityOption " +
2269 "with valid animation");
2270 }
2271 mAm.mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
2272 mAm.mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
2273 activityOptions.getCustomInPlaceResId());
2274 mAm.mWindowManager.executeAppTransition();
2275 }
2276
2277 @Override
2278 public void removeStack(int stackId) {
2279 mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
2280 synchronized (mGlobalLock) {
2281 final long ident = Binder.clearCallingIdentity();
2282 try {
2283 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2284 if (stack == null) {
2285 Slog.w(TAG, "removeStack: No stack with id=" + stackId);
2286 return;
2287 }
2288 if (!stack.isActivityTypeStandardOrUndefined()) {
2289 throw new IllegalArgumentException(
2290 "Removing non-standard stack is not allowed.");
2291 }
2292 mStackSupervisor.removeStack(stack);
2293 } finally {
2294 Binder.restoreCallingIdentity(ident);
2295 }
2296 }
2297 }
2298
2299 @Override
2300 public void moveStackToDisplay(int stackId, int displayId) {
2301 mAm.enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
2302
2303 synchronized (mGlobalLock) {
2304 final long ident = Binder.clearCallingIdentity();
2305 try {
2306 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
2307 + " to displayId=" + displayId);
2308 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
2309 } finally {
2310 Binder.restoreCallingIdentity(ident);
2311 }
2312 }
2313 }
2314
2315 @Override
2316 public int createStackOnDisplay(int displayId) {
2317 mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
2318 synchronized (mGlobalLock) {
2319 final ActivityDisplay display =
2320 mStackSupervisor.getActivityDisplayOrCreateLocked(displayId);
2321 if (display == null) {
2322 return INVALID_STACK_ID;
2323 }
2324 // TODO(multi-display): Have the caller pass in the windowing mode and activity type.
2325 final ActivityStack stack = display.createStack(
2326 WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
2327 ON_TOP);
2328 return (stack != null) ? stack.mStackId : INVALID_STACK_ID;
2329 }
2330 }
2331
2332 @Override
2333 public void exitFreeformMode(IBinder token) {
2334 synchronized (mGlobalLock) {
2335 long ident = Binder.clearCallingIdentity();
2336 try {
2337 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2338 if (r == null) {
2339 throw new IllegalArgumentException(
2340 "exitFreeformMode: No activity record matching token=" + token);
2341 }
2342
2343 final ActivityStack stack = r.getStack();
2344 if (stack == null || !stack.inFreeformWindowingMode()) {
2345 throw new IllegalStateException(
2346 "exitFreeformMode: You can only go fullscreen from freeform.");
2347 }
2348
2349 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
2350 } finally {
2351 Binder.restoreCallingIdentity(ident);
2352 }
2353 }
2354 }
2355
2356 /** Sets the task stack listener that gets callbacks when a task stack changes. */
2357 @Override
2358 public void registerTaskStackListener(ITaskStackListener listener) {
2359 mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
2360 "registerTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002361 mTaskChangeNotificationController.registerTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002362 }
2363
2364 /** Unregister a task stack listener so that it stops receiving callbacks. */
2365 @Override
2366 public void unregisterTaskStackListener(ITaskStackListener listener) {
2367 mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
2368 "unregisterTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002369 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002370 }
2371
2372 private void reportCurKeyguardUsageEventLocked(boolean keyguardShowing) {
2373 mAm.reportGlobalUsageEventLocked(keyguardShowing
2374 ? UsageEvents.Event.KEYGUARD_SHOWN
2375 : UsageEvents.Event.KEYGUARD_HIDDEN);
2376 }
2377
2378 @Override
2379 public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
2380 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
2381 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
2382 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
2383 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
2384 }
2385
2386 @Override
2387 public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
2388 IBinder activityToken, int flags) {
2389 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
2390 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
2391 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
2392 }
2393
2394 @Override
2395 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
2396 Bundle args) {
2397 return enqueueAssistContext(requestType, intent, hint, null, null, null,
2398 true /* focused */, true /* newSessionId */, userHandle, args,
2399 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
2400 }
2401
2402 @Override
2403 public Bundle getAssistContextExtras(int requestType) {
2404 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
2405 null, null, true /* focused */, true /* newSessionId */,
2406 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
2407 if (pae == null) {
2408 return null;
2409 }
2410 synchronized (pae) {
2411 while (!pae.haveResult) {
2412 try {
2413 pae.wait();
2414 } catch (InterruptedException e) {
2415 }
2416 }
2417 }
2418 synchronized (mGlobalLock) {
2419 buildAssistBundleLocked(pae, pae.result);
2420 mPendingAssistExtras.remove(pae);
2421 mAm.mUiHandler.removeCallbacks(pae);
2422 }
2423 return pae.extras;
2424 }
2425
2426 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
2427 IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
2428 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
2429 int flags) {
2430 mAm.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
2431 "enqueueAssistContext()");
2432
2433 synchronized (mGlobalLock) {
2434 ActivityRecord activity = mAm.getFocusedStack().getTopActivity();
2435 if (activity == null) {
2436 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
2437 return null;
2438 }
2439 if (activity.app == null || activity.app.thread == null) {
2440 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
2441 return null;
2442 }
2443 if (focused) {
2444 if (activityToken != null) {
2445 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
2446 if (activity != caller) {
2447 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
2448 + " is not current top " + activity);
2449 return null;
2450 }
2451 }
2452 } else {
2453 activity = ActivityRecord.forTokenLocked(activityToken);
2454 if (activity == null) {
2455 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
2456 + " couldn't be found");
2457 return null;
2458 }
2459 if (activity.app == null || activity.app.thread == null) {
2460 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
2461 return null;
2462 }
2463 }
2464
2465 PendingAssistExtras pae;
2466 Bundle extras = new Bundle();
2467 if (args != null) {
2468 extras.putAll(args);
2469 }
2470 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
2471 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
2472
2473 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
2474 userHandle);
2475 pae.isHome = activity.isActivityTypeHome();
2476
2477 // Increment the sessionId if necessary
2478 if (newSessionId) {
2479 mViSessionId++;
2480 }
2481 try {
2482 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
2483 mViSessionId, flags);
2484 mPendingAssistExtras.add(pae);
2485 mAm.mUiHandler.postDelayed(pae, timeout);
2486 } catch (RemoteException e) {
2487 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
2488 return null;
2489 }
2490 return pae;
2491 }
2492 }
2493
2494 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
2495 if (result != null) {
2496 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
2497 }
2498 if (pae.hint != null) {
2499 pae.extras.putBoolean(pae.hint, true);
2500 }
2501 }
2502
2503 private void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
2504 IAssistDataReceiver receiver;
2505 synchronized (mGlobalLock) {
2506 mPendingAssistExtras.remove(pae);
2507 receiver = pae.receiver;
2508 }
2509 if (receiver != null) {
2510 // Caller wants result sent back to them.
2511 Bundle sendBundle = new Bundle();
2512 // At least return the receiver extras
2513 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
2514 try {
2515 pae.receiver.onHandleAssistData(sendBundle);
2516 } catch (RemoteException e) {
2517 }
2518 }
2519 }
2520
2521 public class PendingAssistExtras extends Binder implements Runnable {
2522 public final ActivityRecord activity;
2523 public boolean isHome;
2524 public final Bundle extras;
2525 public final Intent intent;
2526 public final String hint;
2527 public final IAssistDataReceiver receiver;
2528 public final int userHandle;
2529 public boolean haveResult = false;
2530 public Bundle result = null;
2531 public AssistStructure structure = null;
2532 public AssistContent content = null;
2533 public Bundle receiverExtras;
2534
2535 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
2536 String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
2537 int _userHandle) {
2538 activity = _activity;
2539 extras = _extras;
2540 intent = _intent;
2541 hint = _hint;
2542 receiver = _receiver;
2543 receiverExtras = _receiverExtras;
2544 userHandle = _userHandle;
2545 }
2546
2547 @Override
2548 public void run() {
2549 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
2550 synchronized (this) {
2551 haveResult = true;
2552 notifyAll();
2553 }
2554 pendingAssistExtrasTimedOut(this);
2555 }
2556 }
2557
2558 @Override
2559 public boolean isAssistDataAllowedOnCurrentActivity() {
2560 int userId;
2561 synchronized (mGlobalLock) {
2562 final ActivityStack focusedStack = mAm.getFocusedStack();
2563 if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
2564 return false;
2565 }
2566
2567 final ActivityRecord activity = focusedStack.getTopActivity();
2568 if (activity == null) {
2569 return false;
2570 }
2571 userId = activity.userId;
2572 }
2573 return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
2574 }
2575
2576 @Override
2577 public boolean showAssistFromActivity(IBinder token, Bundle args) {
2578 long ident = Binder.clearCallingIdentity();
2579 try {
2580 synchronized (mGlobalLock) {
2581 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
2582 ActivityRecord top = mAm.getFocusedStack().getTopActivity();
2583 if (top != caller) {
2584 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
2585 + " is not current top " + top);
2586 return false;
2587 }
2588 if (!top.nowVisible) {
2589 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
2590 + " is not visible");
2591 return false;
2592 }
2593 }
2594 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
2595 token);
2596 } finally {
2597 Binder.restoreCallingIdentity(ident);
2598 }
2599 }
2600
2601 @Override
2602 public boolean isRootVoiceInteraction(IBinder token) {
2603 synchronized (mGlobalLock) {
2604 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2605 if (r == null) {
2606 return false;
2607 }
2608 return r.rootVoiceInteraction;
2609 }
2610 }
2611
2612 @Override
2613 public ComponentName getActivityClassForToken(IBinder token) {
2614 synchronized (mGlobalLock) {
2615 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2616 if (r == null) {
2617 return null;
2618 }
2619 return r.intent.getComponent();
2620 }
2621 }
2622
2623 @Override
2624 public String getPackageForToken(IBinder token) {
2625 synchronized (mGlobalLock) {
2626 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2627 if (r == null) {
2628 return null;
2629 }
2630 return r.packageName;
2631 }
2632 }
2633
2634 @Override
2635 public void showLockTaskEscapeMessage(IBinder token) {
2636 synchronized (mGlobalLock) {
2637 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2638 if (r == null) {
2639 return;
2640 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002641 getLockTaskController().showLockTaskToast();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002642 }
2643 }
2644
2645 @Override
2646 public void keyguardGoingAway(int flags) {
2647 mAm.enforceNotIsolatedCaller("keyguardGoingAway");
2648 final long token = Binder.clearCallingIdentity();
2649 try {
2650 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002651 mKeyguardController.keyguardGoingAway(flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002652 }
2653 } finally {
2654 Binder.restoreCallingIdentity(token);
2655 }
2656 }
2657
2658 /**
2659 * Try to place task to provided position. The final position might be different depending on
2660 * current user and stacks state. The task will be moved to target stack if it's currently in
2661 * different stack.
2662 */
2663 @Override
2664 public void positionTaskInStack(int taskId, int stackId, int position) {
2665 mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
2666 synchronized (mGlobalLock) {
2667 long ident = Binder.clearCallingIdentity();
2668 try {
2669 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
2670 + taskId + " in stackId=" + stackId + " at position=" + position);
2671 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2672 if (task == null) {
2673 throw new IllegalArgumentException("positionTaskInStack: no task for id="
2674 + taskId);
2675 }
2676
2677 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2678
2679 if (stack == null) {
2680 throw new IllegalArgumentException("positionTaskInStack: no stack for id="
2681 + stackId);
2682 }
2683 if (!stack.isActivityTypeStandardOrUndefined()) {
2684 throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
2685 + " the position of task " + taskId + " in/to non-standard stack");
2686 }
2687
2688 // TODO: Have the callers of this API call a separate reparent method if that is
2689 // what they intended to do vs. having this method also do reparenting.
2690 if (task.getStack() == stack) {
2691 // Change position in current stack.
2692 stack.positionChildAt(task, position);
2693 } else {
2694 // Reparent to new stack.
2695 task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
2696 !DEFER_RESUME, "positionTaskInStack");
2697 }
2698 } finally {
2699 Binder.restoreCallingIdentity(ident);
2700 }
2701 }
2702 }
2703
2704 @Override
2705 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
2706 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
2707 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
2708 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
2709 synchronized (mGlobalLock) {
2710 ActivityRecord record = ActivityRecord.isInStackLocked(token);
2711 if (record == null) {
2712 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
2713 + "found for: " + token);
2714 }
2715 record.setSizeConfigurations(horizontalSizeConfiguration,
2716 verticalSizeConfigurations, smallestSizeConfigurations);
2717 }
2718 }
2719
2720 /**
2721 * Dismisses split-screen multi-window mode.
2722 * @param toTop If true the current primary split-screen stack will be placed or left on top.
2723 */
2724 @Override
2725 public void dismissSplitScreenMode(boolean toTop) {
2726 mAm.enforceCallerIsRecentsOrHasPermission(
2727 MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
2728 final long ident = Binder.clearCallingIdentity();
2729 try {
2730 synchronized (mGlobalLock) {
2731 final ActivityStack stack =
2732 mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
2733 if (stack == null) {
2734 Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
2735 return;
2736 }
2737
2738 if (toTop) {
2739 // Caller wants the current split-screen primary stack to be the top stack after
2740 // it goes fullscreen, so move it to the front.
2741 stack.moveToFront("dismissSplitScreenMode");
2742 } else if (mStackSupervisor.isFocusedStack(stack)) {
2743 // In this case the current split-screen primary stack shouldn't be the top
2744 // stack after it goes fullscreen, but it current has focus, so we move the
2745 // focus to the top-most split-screen secondary stack next to it.
2746 final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
2747 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
2748 if (otherStack != null) {
2749 otherStack.moveToFront("dismissSplitScreenMode_other");
2750 }
2751 }
2752
2753 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
2754 }
2755 } finally {
2756 Binder.restoreCallingIdentity(ident);
2757 }
2758 }
2759
2760 /**
2761 * Dismisses Pip
2762 * @param animate True if the dismissal should be animated.
2763 * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
2764 * default animation duration should be used.
2765 */
2766 @Override
2767 public void dismissPip(boolean animate, int animationDuration) {
2768 mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
2769 final long ident = Binder.clearCallingIdentity();
2770 try {
2771 synchronized (mGlobalLock) {
2772 final PinnedActivityStack stack =
2773 mStackSupervisor.getDefaultDisplay().getPinnedStack();
2774 if (stack == null) {
2775 Slog.w(TAG, "dismissPip: pinned stack not found.");
2776 return;
2777 }
2778 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
2779 throw new IllegalArgumentException("Stack: " + stack
2780 + " doesn't support animated resize.");
2781 }
2782 if (animate) {
2783 stack.animateResizePinnedStack(null /* sourceHintBounds */,
2784 null /* destBounds */, animationDuration, false /* fromFullscreen */);
2785 } else {
2786 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
2787 }
2788 }
2789 } finally {
2790 Binder.restoreCallingIdentity(ident);
2791 }
2792 }
2793
2794 @Override
2795 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
2796 mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
2797 synchronized (mGlobalLock) {
2798 mSuppressResizeConfigChanges = suppress;
2799 }
2800 }
2801
2802 /**
2803 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
2804 * animated the stack to the fullscreen, but can also be called if we are relaunching an
2805 * activity and clearing the task at the same time.
2806 */
2807 @Override
2808 // TODO: API should just be about changing windowing modes...
2809 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
2810 mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
2811 "moveTasksToFullscreenStack()");
2812 synchronized (mGlobalLock) {
2813 final long origId = Binder.clearCallingIdentity();
2814 try {
2815 final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
2816 if (stack != null){
2817 if (!stack.isActivityTypeStandardOrUndefined()) {
2818 throw new IllegalArgumentException(
2819 "You can't move tasks from non-standard stacks.");
2820 }
2821 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
2822 }
2823 } finally {
2824 Binder.restoreCallingIdentity(origId);
2825 }
2826 }
2827 }
2828
2829 /**
2830 * Moves the top activity in the input stackId to the pinned stack.
2831 *
2832 * @param stackId Id of stack to move the top activity to pinned stack.
2833 * @param bounds Bounds to use for pinned stack.
2834 *
2835 * @return True if the top activity of the input stack was successfully moved to the pinned
2836 * stack.
2837 */
2838 @Override
2839 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
2840 mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
2841 "moveTopActivityToPinnedStack()");
2842 synchronized (mGlobalLock) {
2843 if (!mAm.mSupportsPictureInPicture) {
2844 throw new IllegalStateException("moveTopActivityToPinnedStack:"
2845 + "Device doesn't support picture-in-picture mode");
2846 }
2847
2848 long ident = Binder.clearCallingIdentity();
2849 try {
2850 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
2851 } finally {
2852 Binder.restoreCallingIdentity(ident);
2853 }
2854 }
2855 }
2856
2857 @Override
2858 public boolean isInMultiWindowMode(IBinder token) {
2859 final long origId = Binder.clearCallingIdentity();
2860 try {
2861 synchronized (mGlobalLock) {
2862 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
2863 if (r == null) {
2864 return false;
2865 }
2866 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
2867 return r.inMultiWindowMode();
2868 }
2869 } finally {
2870 Binder.restoreCallingIdentity(origId);
2871 }
2872 }
2873
2874 @Override
2875 public boolean isInPictureInPictureMode(IBinder token) {
2876 final long origId = Binder.clearCallingIdentity();
2877 try {
2878 synchronized (mGlobalLock) {
2879 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
2880 }
2881 } finally {
2882 Binder.restoreCallingIdentity(origId);
2883 }
2884 }
2885
2886 private boolean isInPictureInPictureMode(ActivityRecord r) {
2887 if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
2888 || r.getStack().isInStackLocked(r) == null) {
2889 return false;
2890 }
2891
2892 // If we are animating to fullscreen then we have already dispatched the PIP mode
2893 // changed, so we should reflect that check here as well.
2894 final PinnedActivityStack stack = r.getStack();
2895 final PinnedStackWindowController windowController = stack.getWindowContainerController();
2896 return !windowController.isAnimatingBoundsToFullscreen();
2897 }
2898
2899 @Override
2900 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
2901 final long origId = Binder.clearCallingIdentity();
2902 try {
2903 synchronized (mGlobalLock) {
2904 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
2905 "enterPictureInPictureMode", token, params);
2906
2907 // If the activity is already in picture in picture mode, then just return early
2908 if (isInPictureInPictureMode(r)) {
2909 return true;
2910 }
2911
2912 // Activity supports picture-in-picture, now check that we can enter PiP at this
2913 // point, if it is
2914 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
2915 false /* beforeStopping */)) {
2916 return false;
2917 }
2918
2919 final Runnable enterPipRunnable = () -> {
Wale Ogunwalef276a6f2018-06-15 08:26:07 -07002920 synchronized (mGlobalLock) {
2921 // Only update the saved args from the args that are set
2922 r.pictureInPictureArgs.copyOnlySet(params);
2923 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
2924 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
2925 // Adjust the source bounds by the insets for the transition down
2926 final Rect sourceBounds = new Rect(
2927 r.pictureInPictureArgs.getSourceRectHint());
2928 mStackSupervisor.moveActivityToPinnedStackLocked(
2929 r, sourceBounds, aspectRatio, "enterPictureInPictureMode");
2930 final PinnedActivityStack stack = r.getStack();
2931 stack.setPictureInPictureAspectRatio(aspectRatio);
2932 stack.setPictureInPictureActions(actions);
2933 MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
2934 r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
2935 logPictureInPictureArgs(params);
2936 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002937 };
2938
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002939 if (isKeyguardLocked()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002940 // If the keyguard is showing or occluded, then try and dismiss it before
2941 // entering picture-in-picture (this will prompt the user to authenticate if the
2942 // device is currently locked).
2943 dismissKeyguard(token, new KeyguardDismissCallback() {
2944 @Override
2945 public void onDismissSucceeded() throws RemoteException {
2946 mAm.mHandler.post(enterPipRunnable);
2947 }
2948 }, null /* message */);
2949 } else {
2950 // Enter picture in picture immediately otherwise
2951 enterPipRunnable.run();
2952 }
2953 return true;
2954 }
2955 } finally {
2956 Binder.restoreCallingIdentity(origId);
2957 }
2958 }
2959
2960 @Override
2961 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
2962 final long origId = Binder.clearCallingIdentity();
2963 try {
2964 synchronized (mGlobalLock) {
2965 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
2966 "setPictureInPictureParams", token, params);
2967
2968 // Only update the saved args from the args that are set
2969 r.pictureInPictureArgs.copyOnlySet(params);
2970 if (r.inPinnedWindowingMode()) {
2971 // If the activity is already in picture-in-picture, update the pinned stack now
2972 // if it is not already expanding to fullscreen. Otherwise, the arguments will
2973 // be used the next time the activity enters PiP
2974 final PinnedActivityStack stack = r.getStack();
2975 if (!stack.isAnimatingBoundsToFullscreen()) {
2976 stack.setPictureInPictureAspectRatio(
2977 r.pictureInPictureArgs.getAspectRatio());
2978 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
2979 }
2980 }
2981 logPictureInPictureArgs(params);
2982 }
2983 } finally {
2984 Binder.restoreCallingIdentity(origId);
2985 }
2986 }
2987
2988 @Override
2989 public int getMaxNumPictureInPictureActions(IBinder token) {
2990 // Currently, this is a static constant, but later, we may change this to be dependent on
2991 // the context of the activity
2992 return 3;
2993 }
2994
2995 private void logPictureInPictureArgs(PictureInPictureParams params) {
2996 if (params.hasSetActions()) {
2997 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
2998 params.getActions().size());
2999 }
3000 if (params.hasSetAspectRatio()) {
3001 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
3002 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
3003 MetricsLogger.action(lm);
3004 }
3005 }
3006
3007 /**
3008 * Checks the state of the system and the activity associated with the given {@param token} to
3009 * verify that picture-in-picture is supported for that activity.
3010 *
3011 * @return the activity record for the given {@param token} if all the checks pass.
3012 */
3013 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
3014 IBinder token, PictureInPictureParams params) {
3015 if (!mAm.mSupportsPictureInPicture) {
3016 throw new IllegalStateException(caller
3017 + ": Device doesn't support picture-in-picture mode.");
3018 }
3019
3020 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3021 if (r == null) {
3022 throw new IllegalStateException(caller
3023 + ": Can't find activity for token=" + token);
3024 }
3025
3026 if (!r.supportsPictureInPicture()) {
3027 throw new IllegalStateException(caller
3028 + ": Current activity does not support picture-in-picture.");
3029 }
3030
3031 if (params.hasSetAspectRatio()
3032 && !mAm.mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
3033 params.getAspectRatio())) {
3034 final float minAspectRatio = mContext.getResources().getFloat(
3035 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
3036 final float maxAspectRatio = mContext.getResources().getFloat(
3037 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
3038 throw new IllegalArgumentException(String.format(caller
3039 + ": Aspect ratio is too extreme (must be between %f and %f).",
3040 minAspectRatio, maxAspectRatio));
3041 }
3042
3043 // Truncate the number of actions if necessary
3044 params.truncateActions(getMaxNumPictureInPictureActions(token));
3045
3046 return r;
3047 }
3048
3049 @Override
3050 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
3051 mAm.enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
3052 synchronized (mGlobalLock) {
3053 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
3054 if (r == null) {
3055 throw new IllegalArgumentException("Activity does not exist; token="
3056 + activityToken);
3057 }
3058 return r.getUriPermissionsLocked().getExternalTokenLocked();
3059 }
3060 }
3061
3062 @Override
3063 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
3064 Rect tempDockedTaskInsetBounds,
3065 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
3066 mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
3067 long ident = Binder.clearCallingIdentity();
3068 try {
3069 synchronized (mGlobalLock) {
3070 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
3071 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
3072 PRESERVE_WINDOWS);
3073 }
3074 } finally {
3075 Binder.restoreCallingIdentity(ident);
3076 }
3077 }
3078
3079 @Override
3080 public void setSplitScreenResizing(boolean resizing) {
3081 mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
3082 final long ident = Binder.clearCallingIdentity();
3083 try {
3084 synchronized (mGlobalLock) {
3085 mStackSupervisor.setSplitScreenResizing(resizing);
3086 }
3087 } finally {
3088 Binder.restoreCallingIdentity(ident);
3089 }
3090 }
3091
3092 @Override
3093 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
3094 mAm.enforceSystemHasVrFeature();
3095
3096 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3097
3098 ActivityRecord r;
3099 synchronized (mGlobalLock) {
3100 r = ActivityRecord.isInStackLocked(token);
3101 }
3102
3103 if (r == null) {
3104 throw new IllegalArgumentException();
3105 }
3106
3107 int err;
3108 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
3109 VrManagerInternal.NO_ERROR) {
3110 return err;
3111 }
3112
3113 // Clear the binder calling uid since this path may call moveToTask().
3114 final long callingId = Binder.clearCallingIdentity();
3115 try {
3116 synchronized (mGlobalLock) {
3117 r.requestedVrComponent = (enabled) ? packageName : null;
3118
3119 // Update associated state if this activity is currently focused
3120 if (r == mStackSupervisor.getResumedActivityLocked()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003121 applyUpdateVrModeLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003122 }
3123 return 0;
3124 }
3125 } finally {
3126 Binder.restoreCallingIdentity(callingId);
3127 }
3128 }
3129
3130 @Override
3131 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
3132 Slog.i(TAG, "Activity tried to startLocalVoiceInteraction");
3133 synchronized (mGlobalLock) {
3134 ActivityRecord activity = mAm.getFocusedStack().getTopActivity();
3135 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
3136 throw new SecurityException("Only focused activity can call startVoiceInteraction");
3137 }
3138 if (mAm.mRunningVoice != null || activity.getTask().voiceSession != null
3139 || activity.voiceSession != null) {
3140 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
3141 return;
3142 }
3143 if (activity.pendingVoiceInteractionStart) {
3144 Slog.w(TAG, "Pending start of voice interaction already.");
3145 return;
3146 }
3147 activity.pendingVoiceInteractionStart = true;
3148 }
3149 LocalServices.getService(VoiceInteractionManagerInternal.class)
3150 .startLocalVoiceInteraction(callingActivity, options);
3151 }
3152
3153 @Override
3154 public void stopLocalVoiceInteraction(IBinder callingActivity) {
3155 LocalServices.getService(VoiceInteractionManagerInternal.class)
3156 .stopLocalVoiceInteraction(callingActivity);
3157 }
3158
3159 @Override
3160 public boolean supportsLocalVoiceInteraction() {
3161 return LocalServices.getService(VoiceInteractionManagerInternal.class)
3162 .supportsLocalVoiceInteraction();
3163 }
3164
3165 /** Notifies all listeners when the pinned stack animation starts. */
3166 @Override
3167 public void notifyPinnedStackAnimationStarted() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003168 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003169 }
3170
3171 /** Notifies all listeners when the pinned stack animation ends. */
3172 @Override
3173 public void notifyPinnedStackAnimationEnded() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003174 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003175 }
3176
3177 @Override
3178 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
3179 mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
3180 final long ident = Binder.clearCallingIdentity();
3181 try {
3182 synchronized (mGlobalLock) {
3183 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
3184 }
3185 } finally {
3186 Binder.restoreCallingIdentity(ident);
3187 }
3188 }
3189
3190 @Override
3191 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
3192 mAm.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
3193
3194 synchronized (mGlobalLock) {
3195 // Check if display is initialized in AM.
3196 if (!mStackSupervisor.isDisplayAdded(displayId)) {
3197 // Call might come when display is not yet added or has already been removed.
3198 if (DEBUG_CONFIGURATION) {
3199 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
3200 + displayId);
3201 }
3202 return false;
3203 }
3204
3205 if (values == null && mAm.mWindowManager != null) {
3206 // sentinel: fetch the current configuration from the window manager
3207 values = mAm.mWindowManager.computeNewConfiguration(displayId);
3208 }
3209
3210 if (mAm.mWindowManager != null) {
3211 // Update OOM levels based on display size.
3212 mAm.mProcessList.applyDisplaySize(mAm.mWindowManager);
3213 }
3214
3215 final long origId = Binder.clearCallingIdentity();
3216 try {
3217 if (values != null) {
3218 Settings.System.clearConfiguration(values);
3219 }
3220 mAm.updateDisplayOverrideConfigurationLocked(values, null /* starting */,
3221 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
3222 return mTmpUpdateConfigurationResult.changes != 0;
3223 } finally {
3224 Binder.restoreCallingIdentity(origId);
3225 }
3226 }
3227 }
3228
3229 @Override
3230 public boolean updateConfiguration(Configuration values) {
3231 mAm.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
3232
3233 synchronized (mGlobalLock) {
3234 if (values == null && mAm.mWindowManager != null) {
3235 // sentinel: fetch the current configuration from the window manager
3236 values = mAm.mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
3237 }
3238
3239 if (mAm.mWindowManager != null) {
3240 // Update OOM levels based on display size.
3241 mAm.mProcessList.applyDisplaySize(mAm.mWindowManager);
3242 }
3243
3244 final long origId = Binder.clearCallingIdentity();
3245 try {
3246 if (values != null) {
3247 Settings.System.clearConfiguration(values);
3248 }
3249 mAm.updateConfigurationLocked(values, null, false, false /* persistent */,
3250 UserHandle.USER_NULL, false /* deferResume */,
3251 mTmpUpdateConfigurationResult);
3252 return mTmpUpdateConfigurationResult.changes != 0;
3253 } finally {
3254 Binder.restoreCallingIdentity(origId);
3255 }
3256 }
3257 }
3258
3259 @Override
3260 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
3261 CharSequence message) {
3262 if (message != null) {
3263 mAm.enforceCallingPermission(
3264 Manifest.permission.SHOW_KEYGUARD_MESSAGE, "dismissKeyguard()");
3265 }
3266 final long callingId = Binder.clearCallingIdentity();
3267 try {
3268 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003269 mKeyguardController.dismissKeyguard(token, callback, message);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003270 }
3271 } finally {
3272 Binder.restoreCallingIdentity(callingId);
3273 }
3274 }
3275
3276 @Override
3277 public void cancelTaskWindowTransition(int taskId) {
3278 mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
3279 "cancelTaskWindowTransition()");
3280 final long ident = Binder.clearCallingIdentity();
3281 try {
3282 synchronized (mGlobalLock) {
3283 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
3284 MATCH_TASK_IN_STACKS_ONLY);
3285 if (task == null) {
3286 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
3287 return;
3288 }
3289 task.cancelWindowTransition();
3290 }
3291 } finally {
3292 Binder.restoreCallingIdentity(ident);
3293 }
3294 }
3295
3296 @Override
3297 public ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
3298 mAm.enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
3299 final long ident = Binder.clearCallingIdentity();
3300 try {
3301 final TaskRecord task;
3302 synchronized (mGlobalLock) {
3303 task = mStackSupervisor.anyTaskForIdLocked(taskId,
3304 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
3305 if (task == null) {
3306 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
3307 return null;
3308 }
3309 }
3310 // Don't call this while holding the lock as this operation might hit the disk.
3311 return task.getSnapshot(reducedResolution);
3312 } finally {
3313 Binder.restoreCallingIdentity(ident);
3314 }
3315 }
3316
3317 @Override
3318 public void setDisablePreviewScreenshots(IBinder token, boolean disable) {
3319 synchronized (mGlobalLock) {
3320 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3321 if (r == null) {
3322 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
3323 + token);
3324 return;
3325 }
3326 final long origId = Binder.clearCallingIdentity();
3327 try {
3328 r.setDisablePreviewScreenshots(disable);
3329 } finally {
3330 Binder.restoreCallingIdentity(origId);
3331 }
3332 }
3333 }
3334
3335 /** Return the user id of the last resumed activity. */
3336 @Override
3337 public @UserIdInt
3338 int getLastResumedActivityUserId() {
3339 mAm.enforceCallingPermission(
3340 Manifest.permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
3341 synchronized (mGlobalLock) {
3342 if (mAm.mLastResumedActivity == null) {
3343 return mAm.mUserController.getCurrentUserId();
3344 }
3345 return mAm.mLastResumedActivity.userId;
3346 }
3347 }
3348
3349 @Override
3350 public void updateLockTaskFeatures(int userId, int flags) {
3351 final int callingUid = Binder.getCallingUid();
3352 if (callingUid != 0 && callingUid != SYSTEM_UID) {
3353 mAm.enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
3354 "updateLockTaskFeatures()");
3355 }
3356 synchronized (mGlobalLock) {
3357 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
3358 Integer.toHexString(flags));
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003359 getLockTaskController().updateLockTaskFeatures(userId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003360 }
3361 }
3362
3363 @Override
3364 public void setShowWhenLocked(IBinder token, boolean showWhenLocked) {
3365 synchronized (mGlobalLock) {
3366 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3367 if (r == null) {
3368 return;
3369 }
3370 final long origId = Binder.clearCallingIdentity();
3371 try {
3372 r.setShowWhenLocked(showWhenLocked);
3373 } finally {
3374 Binder.restoreCallingIdentity(origId);
3375 }
3376 }
3377 }
3378
3379 @Override
3380 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) {
3381 synchronized (mGlobalLock) {
3382 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3383 if (r == null) {
3384 return;
3385 }
3386 final long origId = Binder.clearCallingIdentity();
3387 try {
3388 r.setTurnScreenOn(turnScreenOn);
3389 } finally {
3390 Binder.restoreCallingIdentity(origId);
3391 }
3392 }
3393 }
3394
3395 @Override
3396 public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) {
3397 mAm.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
3398 "registerRemoteAnimations");
3399 definition.setCallingPid(Binder.getCallingPid());
3400 synchronized (mGlobalLock) {
3401 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3402 if (r == null) {
3403 return;
3404 }
3405 final long origId = Binder.clearCallingIdentity();
3406 try {
3407 r.registerRemoteAnimations(definition);
3408 } finally {
3409 Binder.restoreCallingIdentity(origId);
3410 }
3411 }
3412 }
3413
3414 @Override
3415 public void registerRemoteAnimationForNextActivityStart(String packageName,
3416 RemoteAnimationAdapter adapter) {
3417 mAm.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
3418 "registerRemoteAnimationForNextActivityStart");
3419 adapter.setCallingPid(Binder.getCallingPid());
3420 synchronized (mGlobalLock) {
3421 final long origId = Binder.clearCallingIdentity();
3422 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07003423 getActivityStartController().registerRemoteAnimationForNextActivityStart(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003424 packageName, adapter);
3425 } finally {
3426 Binder.restoreCallingIdentity(origId);
3427 }
3428 }
3429 }
3430
3431 /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
3432 @Override
3433 public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
3434 synchronized (mGlobalLock) {
3435 final long origId = Binder.clearCallingIdentity();
3436 try {
3437 mAm.mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
3438 } finally {
3439 Binder.restoreCallingIdentity(origId);
3440 }
3441 }
3442 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07003443
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003444 @Override
3445 public void setVrThread(int tid) {
3446 mAm.enforceSystemHasVrFeature();
3447 synchronized (mGlobalLock) {
3448 synchronized (mAm.mPidsSelfLocked) {
3449 final int pid = Binder.getCallingPid();
3450 final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
3451 mVrController.setVrThreadLocked(tid, pid, proc);
3452 }
3453 }
3454 }
3455
3456 @Override
3457 public void setPersistentVrThread(int tid) {
3458 if (mAm.checkCallingPermission(Manifest.permission.RESTRICTED_VR_ACCESS)
3459 != PERMISSION_GRANTED) {
3460 final String msg = "Permission Denial: setPersistentVrThread() from pid="
3461 + Binder.getCallingPid()
3462 + ", uid=" + Binder.getCallingUid()
3463 + " requires " + Manifest.permission.RESTRICTED_VR_ACCESS;
3464 Slog.w(TAG, msg);
3465 throw new SecurityException(msg);
3466 }
3467 mAm.enforceSystemHasVrFeature();
3468 synchronized (mGlobalLock) {
3469 synchronized (mAm.mPidsSelfLocked) {
3470 final int pid = Binder.getCallingPid();
3471 final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
3472 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
3473 }
3474 }
3475 }
3476
3477 /**
3478 * @return whether the system should disable UI modes incompatible with VR mode.
3479 */
3480 boolean shouldDisableNonVrUiLocked() {
3481 return mVrController.shouldDisableNonVrUiLocked();
3482 }
3483
3484 void applyUpdateVrModeLocked(ActivityRecord r) {
3485 // VR apps are expected to run in a main display. If an app is turning on VR for
3486 // itself, but lives in a dynamic stack, then make sure that it is moved to the main
3487 // fullscreen stack before enabling VR Mode.
3488 // TODO: The goal of this code is to keep the VR app on the main display. When the
3489 // stack implementation changes in the future, keep in mind that the use of the fullscreen
3490 // stack is a means to move the activity to the main display and a moveActivityToDisplay()
3491 // option would be a better choice here.
3492 if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
3493 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
3494 + " to main stack for VR");
3495 final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
3496 WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
3497 moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
3498 }
3499 mH.post(() -> {
3500 if (!mVrController.onVrModeChanged(r)) {
3501 return;
3502 }
3503 synchronized (mGlobalLock) {
3504 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
3505 mWindowManager.disableNonVrUi(disableNonVrUi);
3506 if (disableNonVrUi) {
3507 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
3508 // then remove the pinned stack.
3509 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
3510 }
3511 }
3512 });
3513 }
3514
3515 /** Pokes the task persister. */
3516 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
3517 mRecentTasks.notifyTaskPersisterLocked(task, flush);
3518 }
3519
3520 void onTopProcChangedLocked(ProcessRecord proc) {
3521 mVrController.onTopProcChangedLocked(proc);
3522 }
3523
3524 boolean isKeyguardLocked() {
3525 return mKeyguardController.isKeyguardLocked();
3526 }
3527
3528 boolean isNextTransitionForward() {
3529 int transit = mWindowManager.getPendingAppTransition();
3530 return transit == TRANSIT_ACTIVITY_OPEN
3531 || transit == TRANSIT_TASK_OPEN
3532 || transit == TRANSIT_TASK_TO_FRONT;
3533 }
3534
3535 void dumpVrControllerLocked(PrintWriter pw) {
3536 pw.println(" mVrController=" + mVrController);
3537 }
3538
3539 void writeVrControllerToProto(ProtoOutputStream proto, long fieldId) {
3540 mVrController.writeToProto(proto, fieldId);
3541 }
3542
3543 final class H extends Handler {
3544 public H(Looper looper) {
3545 super(looper, null, true);
3546 }
3547 }
3548
Wale Ogunwale6767eae2018-05-03 15:52:51 -07003549 final class LocalService extends ActivityTaskManagerInternal {
3550 @Override
3551 public SleepToken acquireSleepToken(String tag, int displayId) {
3552 Preconditions.checkNotNull(tag);
3553 return mAm.acquireSleepToken(tag, displayId);
3554 }
3555
3556 @Override
3557 public ComponentName getHomeActivityForUser(int userId) {
3558 synchronized (mGlobalLock) {
3559 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
3560 return homeActivity == null ? null : homeActivity.realActivity;
3561 }
3562 }
3563
3564 @Override
3565 public void onLocalVoiceInteractionStarted(IBinder activity,
3566 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
3567 synchronized (mGlobalLock) {
3568 mAm.onLocalVoiceInteractionStartedLocked(activity, voiceSession, voiceInteractor);
3569 }
3570 }
3571
3572 @Override
3573 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
3574 synchronized (mGlobalLock) {
3575 mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
3576 reasons, timestamp);
3577 }
3578 }
3579
3580 @Override
3581 public void notifyAppTransitionFinished() {
3582 synchronized (mGlobalLock) {
3583 mStackSupervisor.notifyAppTransitionDone();
3584 }
3585 }
3586
3587 @Override
3588 public void notifyAppTransitionCancelled() {
3589 synchronized (mGlobalLock) {
3590 mStackSupervisor.notifyAppTransitionDone();
3591 }
3592 }
3593
3594 @Override
3595 public List<IBinder> getTopVisibleActivities() {
3596 synchronized (mGlobalLock) {
3597 return mStackSupervisor.getTopVisibleActivities();
3598 }
3599 }
3600
3601 @Override
3602 public void notifyDockedStackMinimizedChanged(boolean minimized) {
3603 synchronized (mGlobalLock) {
3604 mStackSupervisor.setDockedStackMinimized(minimized);
3605 }
3606 }
3607
3608 @Override
3609 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
3610 Bundle bOptions) {
3611 Preconditions.checkNotNull(intents, "intents");
3612 final String[] resolvedTypes = new String[intents.length];
3613
3614 // UID of the package on user userId.
3615 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
3616 // packageUid may not be initialized.
3617 int packageUid = 0;
3618 final long ident = Binder.clearCallingIdentity();
3619
3620 try {
3621 for (int i = 0; i < intents.length; i++) {
3622 resolvedTypes[i] =
3623 intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
3624 }
3625
3626 packageUid = AppGlobals.getPackageManager().getPackageUid(
3627 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
3628 } catch (RemoteException e) {
3629 // Shouldn't happen.
3630 } finally {
3631 Binder.restoreCallingIdentity(ident);
3632 }
3633
3634 synchronized (mGlobalLock) {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07003635 return getActivityStartController().startActivitiesInPackage(
Wale Ogunwale6767eae2018-05-03 15:52:51 -07003636 packageUid, packageName,
3637 intents, resolvedTypes, null /* resultTo */,
3638 SafeActivityOptions.fromBundle(bOptions), userId,
3639 false /* validateIncomingUser */);
3640 }
3641 }
3642
3643 @Override
3644 public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
3645 Intent intent, Bundle options, int userId) {
3646 return ActivityTaskManagerService.this.startActivityAsUser(
3647 caller, callerPacakge, intent,
3648 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3649 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
3650 false /*validateIncomingUser*/);
3651 }
3652
3653 @Override
3654 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
3655 synchronized (mGlobalLock) {
3656
3657 // We might change the visibilities here, so prepare an empty app transition which
3658 // might be overridden later if we actually change visibilities.
3659 final boolean wasTransitionSet =
3660 mAm.mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
3661 if (!wasTransitionSet) {
3662 mAm.mWindowManager.prepareAppTransition(TRANSIT_NONE,
3663 false /* alwaysKeepCurrent */);
3664 }
3665 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
3666
3667 // If there was a transition set already we don't want to interfere with it as we
3668 // might be starting it too early.
3669 if (!wasTransitionSet) {
3670 mAm.mWindowManager.executeAppTransition();
3671 }
3672 }
3673 if (callback != null) {
3674 callback.run();
3675 }
3676 }
3677
3678 @Override
3679 public void notifyKeyguardTrustedChanged() {
3680 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003681 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
Wale Ogunwale6767eae2018-05-03 15:52:51 -07003682 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
3683 }
3684 }
3685 }
3686
3687 /**
3688 * Called after virtual display Id is updated by
3689 * {@link com.android.server.vr.Vr2dDisplay} with a specific
3690 * {@param vrVr2dDisplayId}.
3691 */
3692 @Override
3693 public void setVr2dDisplayId(int vr2dDisplayId) {
3694 if (DEBUG_STACK) Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
3695 synchronized (mGlobalLock) {
3696 mAm.mVr2dDisplayId = vr2dDisplayId;
3697 }
3698 }
3699
3700 @Override
3701 public void setFocusedActivity(IBinder token) {
3702 synchronized (mGlobalLock) {
3703 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3704 if (r == null) {
3705 throw new IllegalArgumentException(
3706 "setFocusedActivity: No activity record matching token=" + token);
3707 }
3708 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
3709 r, "setFocusedActivity")) {
3710 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3711 }
3712 }
3713 }
3714
3715 @Override
3716 public boolean hasRunningActivity(int uid, @Nullable String packageName) {
3717 if (packageName == null) return false;
3718
3719 synchronized (mGlobalLock) {
3720 for (int i = 0; i < mAm.mLruProcesses.size(); i++) {
3721 final ProcessRecord processRecord = mAm.mLruProcesses.get(i);
3722 if (processRecord.uid == uid) {
3723 for (int j = 0; j < processRecord.activities.size(); j++) {
3724 final ActivityRecord activityRecord = processRecord.activities.get(j);
3725 if (packageName.equals(activityRecord.packageName)) {
3726 return true;
3727 }
3728 }
3729 }
3730 }
3731 }
3732 return false;
3733 }
3734
3735 @Override
3736 public void registerScreenObserver(ScreenObserver observer) {
3737 mAm.mScreenObservers.add(observer);
3738 }
3739
3740 @Override
3741 public boolean isCallerRecents(int callingUid) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07003742 return getRecentTasks().isCallerRecents(callingUid);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07003743 }
3744
3745 @Override
3746 public boolean isRecentsComponentHomeActivity(int userId) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07003747 return getRecentTasks().isRecentsComponentHomeActivity(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07003748 }
3749
3750 @Override
3751 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
3752 ActivityTaskManagerService.this.cancelRecentsAnimation(restoreHomeStackPosition);
3753 }
3754
3755 @Override
3756 public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
3757 mAm.enforceCallerIsRecentsOrHasPermission(permission, func);
3758 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003759
3760 @Override
3761 public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
3762 synchronized (mGlobalLock) {
3763 mActiveVoiceInteractionServiceComponent = component;
3764 }
3765 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07003766 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07003767}