blob: d554e0f3c71375a687df692a04aef70d5a8ed10d [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;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070027import static android.Manifest.permission.STOP_APP_SWITCHES;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070028import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
Wale Ogunwale6767eae2018-05-03 15:52:51 -070029import static android.app.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT;
30import static android.app.ActivityTaskManagerInternal.ASSIST_KEY_DATA;
31import static android.app.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
32import static android.app.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070033import static android.app.ActivityTaskManager.INVALID_STACK_ID;
34import static android.app.ActivityTaskManager.RESIZE_MODE_PRESERVE_WINDOW;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070035import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070036import static android.app.AppOpsManager.OP_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070037import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070038import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070039import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
40import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
41import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070042import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
43import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070044import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070045import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070046import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070047import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
48import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
49import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
50import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070051import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070052import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
53import static android.os.Build.VERSION_CODES.N;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070054import static android.os.Process.SYSTEM_UID;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070055import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
56import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
57import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
58import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
59import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070060import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
61import static android.view.Display.DEFAULT_DISPLAY;
62import static android.view.Display.INVALID_DISPLAY;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070063import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
Wale Ogunwale6767eae2018-05-03 15:52:51 -070064import static android.view.WindowManager.TRANSIT_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070065import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070066import static android.view.WindowManager.TRANSIT_TASK_OPEN;
67import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070068import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070069import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
70import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
71import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
72import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
Wale Ogunwale6767eae2018-05-03 15:52:51 -070073import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070074import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070075import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070076import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070077import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070078import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070079import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
80import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
81import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070082import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070083import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
84import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070085import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
86import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070087import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070088import static com.android.server.am.ActivityManagerService.ANIMATE;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070089import static com.android.server.am.ActivityManagerService.MY_PID;
90import static com.android.server.am.ActivityManagerService.SEND_LOCALE_TO_MOUNT_DAEMON_MSG;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070091import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070092import static com.android.server.am.ActivityManagerService.UPDATE_CONFIGURATION_MSG;
93import static com.android.server.am.ActivityManagerService.checkComponentPermission;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070094import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070095import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070096import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
97import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
98import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
99import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
100import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
101import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
102import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700103import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700104import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
105import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
106import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700107
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700108import android.Manifest;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700109import android.annotation.NonNull;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700110import android.annotation.Nullable;
111import android.annotation.UserIdInt;
112import android.app.Activity;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700113import android.app.ActivityManager;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700114import android.app.ActivityManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700115import android.app.ActivityOptions;
116import android.app.ActivityTaskManager;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700117import android.app.ActivityTaskManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700118import android.app.AppGlobals;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700119import android.app.IActivityController;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700120import android.app.IActivityTaskManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700121import android.app.IApplicationThread;
122import android.app.IAssistDataReceiver;
123import android.app.ITaskStackListener;
124import android.app.PictureInPictureParams;
125import android.app.ProfilerInfo;
126import android.app.RemoteAction;
127import android.app.WaitResult;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700128import android.app.WindowConfiguration;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700129import android.app.admin.DevicePolicyCache;
130import android.app.assist.AssistContent;
131import android.app.assist.AssistStructure;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700132import android.app.servertransaction.ConfigurationChangeItem;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700133import android.app.usage.UsageEvents;
134import android.content.ActivityNotFoundException;
135import android.content.ComponentName;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700136import android.content.ContentResolver;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700137import android.content.Context;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700138import android.content.IIntentSender;
139import android.content.Intent;
140import android.content.pm.ActivityInfo;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700141import android.content.pm.ApplicationInfo;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700142import android.content.pm.PackageManager;
143import android.content.pm.ParceledListSlice;
144import android.content.pm.ResolveInfo;
145import android.content.res.Configuration;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700146import android.content.res.Resources;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700147import android.graphics.Bitmap;
148import android.graphics.Point;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700149import android.graphics.Rect;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700150import android.metrics.LogMaker;
151import android.net.Uri;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700152import android.os.Binder;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700153import android.os.Bundle;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700154import android.os.Handler;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700155import android.os.IBinder;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700156import android.os.LocaleList;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700157import android.os.Looper;
158import android.os.Message;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700159import android.os.PersistableBundle;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700160import android.os.Process;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700161import android.os.RemoteException;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700162import android.os.SystemClock;
163import android.os.SystemProperties;
164import android.os.UpdateLock;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700165import android.os.UserHandle;
166import android.provider.Settings;
167import android.service.voice.IVoiceInteractionSession;
168import android.service.voice.VoiceInteractionManagerInternal;
169import android.telecom.TelecomManager;
170import android.text.TextUtils;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700171import android.util.ArrayMap;
172import android.util.EventLog;
173import android.util.Log;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700174import android.util.Slog;
175
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700176import android.util.SparseArray;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700177import android.util.SparseIntArray;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700178import android.util.StatsLog;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700179import android.util.proto.ProtoOutputStream;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700180import android.view.IRecentsAnimationRunner;
181import android.view.RemoteAnimationAdapter;
182import android.view.RemoteAnimationDefinition;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700183
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700184import com.android.internal.annotations.VisibleForTesting;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700185import com.android.internal.app.AssistUtils;
186import com.android.internal.app.IVoiceInteractor;
187import com.android.internal.logging.MetricsLogger;
188import com.android.internal.os.logging.MetricsLoggerWrapper;
189import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
190import com.android.internal.policy.IKeyguardDismissCallback;
191import com.android.internal.policy.KeyguardDismissCallback;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700192import com.android.internal.util.Preconditions;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700193import com.android.server.AttributeCache;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700194import com.android.server.LocalServices;
195import com.android.server.SystemService;
196import com.android.server.Watchdog;
197import com.android.server.vr.VrManagerInternal;
198import com.android.server.wm.PinnedStackWindowController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700199import com.android.server.wm.WindowManagerService;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700200
201import java.io.File;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700202import java.io.PrintWriter;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700203import java.io.StringWriter;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700204import java.util.ArrayList;
205import java.util.List;
206
207/**
208 * System service for managing activities and their containers (task, stacks, displays,... ).
209 *
210 * {@hide}
211 */
212public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
213 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityTaskManagerService" : TAG_AM;
214 private static final String TAG_STACK = TAG + POSTFIX_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700215 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
216 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
217 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
218 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
219 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700220 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700221
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700222 Context mContext;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700223 H mH;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700224 UiHandler mUiHandler;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700225 ActivityManagerService mAm;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700226 ActivityManagerInternal mAmInternal;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700227 /* Global service lock used by the package the owns this service. */
228 Object mGlobalLock;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700229 ActivityStackSupervisor mStackSupervisor;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700230 WindowManagerService mWindowManager;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700231 /** List of intents that were used to start the most recent tasks. */
232 private RecentTasks mRecentTasks;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700233 /** State of external calls telling us if the device is awake or asleep. */
234 private boolean mKeyguardShown = false;
235
236 // Wrapper around VoiceInteractionServiceManager
237 private AssistUtils mAssistUtils;
238
239 // VoiceInteraction session ID that changes for each new request except when
240 // being called for multi-window assist in a single session.
241 private int mViSessionId = 1000;
242
243 // How long to wait in getAssistContextExtras for the activity and foreground services
244 // to respond with the result.
245 private static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
246
247 // How long top wait when going through the modern assist (which doesn't need to block
248 // on getting this result before starting to launch its UI).
249 private static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
250
251 // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
252 private static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
253
254 private final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
255
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700256 // Keeps track of the active voice interaction service component, notified from
257 // VoiceInteractionManagerService
258 ComponentName mActiveVoiceInteractionServiceComponent;
259
260 private VrController mVrController;
261 KeyguardController mKeyguardController;
262 private final ClientLifecycleManager mLifecycleManager;
263 private TaskChangeNotificationController mTaskChangeNotificationController;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700264 /** The controller for all operations related to locktask. */
265 private LockTaskController mLockTaskController;
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700266 private ActivityStartController mActivityStartController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700267
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700268 boolean mSuppressResizeConfigChanges;
269
270 private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
271 new UpdateConfigurationResult();
272
273 static final class UpdateConfigurationResult {
274 // Configuration changes that were updated.
275 int changes;
276 // If the activity was relaunched to match the new configuration.
277 boolean activityRelaunched;
278
279 void reset() {
280 changes = 0;
281 activityRelaunched = false;
282 }
283 }
284
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700285 /** Current sequencing integer of the configuration, for skipping old configurations. */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700286 private int mConfigurationSeq;
287 // To cache the list of supported system locales
288 private String[] mSupportedSystemLocales = null;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700289
290 /**
291 * Temp object used when global and/or display override configuration is updated. It is also
292 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
293 * anyone...
294 */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700295 private Configuration mTempConfig = new Configuration();
296
297 // Amount of time after a call to stopAppSwitches() during which we will
298 // prevent further untrusted switches from happening.
299 private static final long APP_SWITCH_DELAY_TIME = 5 * 1000;
300
301 /**
302 * The time at which we will allow normal application switches again,
303 * after a call to {@link #stopAppSwitches()}.
304 */
305 long mAppSwitchesAllowedTime;
306 /**
307 * This is set to true after the first switch after mAppSwitchesAllowedTime
308 * is set; any switches after that will clear the time.
309 */
310 boolean mDidAppSwitch;
311
312 IActivityController mController = null;
313 boolean mControllerIsAMonkey = false;
314
315 /**
316 * Used to retain an update lock when the foreground activity is in
317 * immersive mode.
318 */
319 final UpdateLock mUpdateLock = new UpdateLock("immersive");
320
321 /**
322 * Packages that are being allowed to perform unrestricted app switches. Mapping is
323 * User -> Type -> uid.
324 */
325 final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
326
327 /** The dimensions of the thumbnails in the Recents UI. */
328 int mThumbnailWidth;
329 int mThumbnailHeight;
330 float mFullscreenThumbnailScale;
331
332 /**
333 * Flag that indicates if multi-window is enabled.
334 *
335 * For any particular form of multi-window to be enabled, generic multi-window must be enabled
336 * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
337 * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
338 * At least one of the forms of multi-window must be enabled in order for this flag to be
339 * initialized to 'true'.
340 *
341 * @see #mSupportsSplitScreenMultiWindow
342 * @see #mSupportsFreeformWindowManagement
343 * @see #mSupportsPictureInPicture
344 * @see #mSupportsMultiDisplay
345 */
346 boolean mSupportsMultiWindow;
347 boolean mSupportsSplitScreenMultiWindow;
348 boolean mSupportsFreeformWindowManagement;
349 boolean mSupportsPictureInPicture;
350 boolean mSupportsMultiDisplay;
351 boolean mForceResizableActivities;
352
353 final List<ActivityTaskManagerInternal.ScreenObserver> mScreenObservers = new ArrayList<>();
354
355 // VR Vr2d Display Id.
356 int mVr2dDisplayId = INVALID_DISPLAY;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700357
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700358 ActivityTaskManagerService(Context context) {
359 mContext = context;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700360 mLifecycleManager = new ClientLifecycleManager();
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700361 }
362
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700363 void onSystemReady() {
364 mAssistUtils = new AssistUtils(mContext);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700365 mVrController.onSystemReady();
366 mRecentTasks.onSystemReadyLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700367 }
368
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700369 void retrieveSettings(ContentResolver resolver) {
370 final boolean freeformWindowManagement =
371 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
372 || Settings.Global.getInt(
373 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
374
375 final boolean supportsMultiWindow = ActivityTaskManager.supportsMultiWindow(mContext);
376 final boolean supportsPictureInPicture = supportsMultiWindow &&
377 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
378 final boolean supportsSplitScreenMultiWindow =
379 ActivityTaskManager.supportsSplitScreenMultiWindow(mContext);
380 final boolean supportsMultiDisplay = mContext.getPackageManager()
381 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
382 final boolean alwaysFinishActivities =
383 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
384 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
385 final boolean forceResizable = Settings.Global.getInt(
386 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
387
388 // Transfer any global setting for forcing RTL layout, into a System Property
389 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
390
391 final Configuration configuration = new Configuration();
392 Settings.System.getConfiguration(resolver, configuration);
393 if (forceRtl) {
394 // This will take care of setting the correct layout direction flags
395 configuration.setLayoutDirection(configuration.locale);
396 }
397
398 synchronized (mGlobalLock) {
399 mForceResizableActivities = forceResizable;
400 final boolean multiWindowFormEnabled = freeformWindowManagement
401 || supportsSplitScreenMultiWindow
402 || supportsPictureInPicture
403 || supportsMultiDisplay;
404 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
405 mSupportsMultiWindow = true;
406 mSupportsFreeformWindowManagement = freeformWindowManagement;
407 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
408 mSupportsPictureInPicture = supportsPictureInPicture;
409 mSupportsMultiDisplay = supportsMultiDisplay;
410 } else {
411 mSupportsMultiWindow = false;
412 mSupportsFreeformWindowManagement = false;
413 mSupportsSplitScreenMultiWindow = false;
414 mSupportsPictureInPicture = false;
415 mSupportsMultiDisplay = false;
416 }
417 mWindowManager.setForceResizableTasks(mForceResizableActivities);
418 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
419 // This happens before any activities are started, so we can change global configuration
420 // in-place.
421 updateConfigurationLocked(configuration, null, true);
422 final Configuration globalConfig = getGlobalConfiguration();
423 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
424
425 // Load resources only after the current configuration has been set.
426 final Resources res = mContext.getResources();
427 mThumbnailWidth = res.getDimensionPixelSize(
428 com.android.internal.R.dimen.thumbnail_width);
429 mThumbnailHeight = res.getDimensionPixelSize(
430 com.android.internal.R.dimen.thumbnail_height);
431
432 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
433 mFullscreenThumbnailScale = (float) res
434 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
435 (float) globalConfig.screenWidthDp;
436 } else {
437 mFullscreenThumbnailScale = res.getFraction(
438 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
439 }
440 }
441 }
442
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700443 // TODO: Will be converted to WM lock once transition is complete.
444 void setActivityManagerService(ActivityManagerService am) {
445 mAm = am;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700446 mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700447 mGlobalLock = mAm;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700448 mH = new H(mAm.mHandlerThread.getLooper());
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700449 mUiHandler = new UiHandler();
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700450
451 mTempConfig.setToDefaults();
452 mTempConfig.setLocales(LocaleList.getDefault());
453 mConfigurationSeq = mTempConfig.seq = 1;
454 mStackSupervisor = createStackSupervisor();
455 mStackSupervisor.onConfigurationChanged(mTempConfig);
456
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700457 mTaskChangeNotificationController =
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700458 new TaskChangeNotificationController(mGlobalLock, mStackSupervisor, mH);
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700459 mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mH);
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700460 mActivityStartController = new ActivityStartController(this);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700461 mRecentTasks = createRecentTasks();
462 mStackSupervisor.setRecentTasks(mRecentTasks);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700463 mVrController = new VrController(mGlobalLock);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700464 mKeyguardController = mStackSupervisor.getKeyguardController();
465 }
466
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700467 protected ActivityStackSupervisor createStackSupervisor() {
468 final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mH.getLooper());
469 supervisor.initialize();
470 return supervisor;
471 }
472
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700473 void setWindowManager(WindowManagerService wm) {
474 mWindowManager = wm;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700475 mLockTaskController.setWindowManager(wm);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700476 }
477
478 protected RecentTasks createRecentTasks() {
479 return new RecentTasks(this, mStackSupervisor);
480 }
481
482 RecentTasks getRecentTasks() {
483 return mRecentTasks;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700484 }
485
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700486 ClientLifecycleManager getLifecycleManager() {
487 return mLifecycleManager;
488 }
489
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700490 ActivityStartController getActivityStartController() {
491 return mActivityStartController;
492 }
493
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700494 TaskChangeNotificationController getTaskChangeNotificationController() {
495 return mTaskChangeNotificationController;
496 }
497
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700498 LockTaskController getLockTaskController() {
499 return mLockTaskController;
500 }
501
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700502 private void start() {
503 LocalServices.addService(ActivityTaskManagerInternal.class, new LocalService());
504 }
505
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700506 public static final class Lifecycle extends SystemService {
507 private final ActivityTaskManagerService mService;
508
509 public Lifecycle(Context context) {
510 super(context);
511 mService = new ActivityTaskManagerService(context);
512 }
513
514 @Override
515 public void onStart() {
516 publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700517 mService.start();
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700518 }
519
520 public ActivityTaskManagerService getService() {
521 return mService;
522 }
523 }
524
525 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700526 public final int startActivity(IApplicationThread caller, String callingPackage,
527 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
528 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
529 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
530 resultWho, requestCode, startFlags, profilerInfo, bOptions,
531 UserHandle.getCallingUserId());
532 }
533
534 @Override
535 public final int startActivities(IApplicationThread caller, String callingPackage,
536 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
537 int userId) {
538 final String reason = "startActivities";
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700539 enforceNotIsolatedCaller(reason);
540 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, reason);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700541 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700542 return getActivityStartController().startActivities(caller, -1, callingPackage, intents,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700543 resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId, reason);
544 }
545
546 @Override
547 public int startActivityAsUser(IApplicationThread caller, String callingPackage,
548 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
549 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
550 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
551 resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
552 true /*validateIncomingUser*/);
553 }
554
555 int startActivityAsUser(IApplicationThread caller, String callingPackage,
556 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
557 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
558 boolean validateIncomingUser) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700559 enforceNotIsolatedCaller("startActivityAsUser");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700560
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700561 userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700562 Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
563
564 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700565 return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700566 .setCaller(caller)
567 .setCallingPackage(callingPackage)
568 .setResolvedType(resolvedType)
569 .setResultTo(resultTo)
570 .setResultWho(resultWho)
571 .setRequestCode(requestCode)
572 .setStartFlags(startFlags)
573 .setProfilerInfo(profilerInfo)
574 .setActivityOptions(bOptions)
575 .setMayWait(userId)
576 .execute();
577
578 }
579
580 @Override
581 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
582 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700583 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions) {
584 enforceNotIsolatedCaller("startActivityIntentSender");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700585 // Refuse possible leaked file descriptors
586 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
587 throw new IllegalArgumentException("File descriptors passed in Intent");
588 }
589
590 if (!(target instanceof PendingIntentRecord)) {
591 throw new IllegalArgumentException("Bad PendingIntent object");
592 }
593
594 PendingIntentRecord pir = (PendingIntentRecord)target;
595
596 synchronized (mGlobalLock) {
597 // If this is coming from the currently resumed activity, it is
598 // effectively saying that app switches are allowed at this point.
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700599 final ActivityStack stack = getFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700600 if (stack.mResumedActivity != null &&
601 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700602 mAppSwitchesAllowedTime = 0;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700603 }
604 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700605 return pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700606 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700607 }
608
609 @Override
610 public boolean startNextMatchingActivity(IBinder callingActivity, Intent intent,
611 Bundle bOptions) {
612 // Refuse possible leaked file descriptors
613 if (intent != null && intent.hasFileDescriptors()) {
614 throw new IllegalArgumentException("File descriptors passed in Intent");
615 }
616 SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
617
618 synchronized (mGlobalLock) {
619 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
620 if (r == null) {
621 SafeActivityOptions.abort(options);
622 return false;
623 }
624 if (r.app == null || r.app.thread == null) {
625 // The caller is not running... d'oh!
626 SafeActivityOptions.abort(options);
627 return false;
628 }
629 intent = new Intent(intent);
630 // The caller is not allowed to change the data.
631 intent.setDataAndType(r.intent.getData(), r.intent.getType());
632 // And we are resetting to find the next component...
633 intent.setComponent(null);
634
635 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
636
637 ActivityInfo aInfo = null;
638 try {
639 List<ResolveInfo> resolves =
640 AppGlobals.getPackageManager().queryIntentActivities(
641 intent, r.resolvedType,
642 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
643 UserHandle.getCallingUserId()).getList();
644
645 // Look for the original activity in the list...
646 final int N = resolves != null ? resolves.size() : 0;
647 for (int i=0; i<N; i++) {
648 ResolveInfo rInfo = resolves.get(i);
649 if (rInfo.activityInfo.packageName.equals(r.packageName)
650 && rInfo.activityInfo.name.equals(r.info.name)) {
651 // We found the current one... the next matching is
652 // after it.
653 i++;
654 if (i<N) {
655 aInfo = resolves.get(i).activityInfo;
656 }
657 if (debug) {
658 Slog.v(TAG, "Next matching activity: found current " + r.packageName
659 + "/" + r.info.name);
660 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
661 ? "null" : aInfo.packageName + "/" + aInfo.name));
662 }
663 break;
664 }
665 }
666 } catch (RemoteException e) {
667 }
668
669 if (aInfo == null) {
670 // Nobody who is next!
671 SafeActivityOptions.abort(options);
672 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
673 return false;
674 }
675
676 intent.setComponent(new ComponentName(
677 aInfo.applicationInfo.packageName, aInfo.name));
678 intent.setFlags(intent.getFlags()&~(
679 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
680 Intent.FLAG_ACTIVITY_CLEAR_TOP|
681 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
682 FLAG_ACTIVITY_NEW_TASK));
683
684 // Okay now we need to start the new activity, replacing the currently running activity.
685 // This is a little tricky because we want to start the new one as if the current one is
686 // finished, but not finish the current one first so that there is no flicker.
687 // And thus...
688 final boolean wasFinishing = r.finishing;
689 r.finishing = true;
690
691 // Propagate reply information over to the new activity.
692 final ActivityRecord resultTo = r.resultTo;
693 final String resultWho = r.resultWho;
694 final int requestCode = r.requestCode;
695 r.resultTo = null;
696 if (resultTo != null) {
697 resultTo.removeResultsLocked(r, resultWho, requestCode);
698 }
699
700 final long origId = Binder.clearCallingIdentity();
701 // TODO(b/64750076): Check if calling pid should really be -1.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700702 final int res = getActivityStartController()
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700703 .obtainStarter(intent, "startNextMatchingActivity")
704 .setCaller(r.app.thread)
705 .setResolvedType(r.resolvedType)
706 .setActivityInfo(aInfo)
707 .setResultTo(resultTo != null ? resultTo.appToken : null)
708 .setResultWho(resultWho)
709 .setRequestCode(requestCode)
710 .setCallingPid(-1)
711 .setCallingUid(r.launchedFromUid)
712 .setCallingPackage(r.launchedFromPackage)
713 .setRealCallingPid(-1)
714 .setRealCallingUid(r.launchedFromUid)
715 .setActivityOptions(options)
716 .execute();
717 Binder.restoreCallingIdentity(origId);
718
719 r.finishing = wasFinishing;
720 if (res != ActivityManager.START_SUCCESS) {
721 return false;
722 }
723 return true;
724 }
725 }
726
727 @Override
728 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
729 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
730 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
731 final WaitResult res = new WaitResult();
732 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700733 enforceNotIsolatedCaller("startActivityAndWait");
734 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
735 userId, "startActivityAndWait");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700736 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700737 getActivityStartController().obtainStarter(intent, "startActivityAndWait")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700738 .setCaller(caller)
739 .setCallingPackage(callingPackage)
740 .setResolvedType(resolvedType)
741 .setResultTo(resultTo)
742 .setResultWho(resultWho)
743 .setRequestCode(requestCode)
744 .setStartFlags(startFlags)
745 .setActivityOptions(bOptions)
746 .setMayWait(userId)
747 .setProfilerInfo(profilerInfo)
748 .setWaitResult(res)
749 .execute();
750 }
751 return res;
752 }
753
754 @Override
755 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
756 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
757 int startFlags, Configuration config, Bundle bOptions, int userId) {
758 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700759 enforceNotIsolatedCaller("startActivityWithConfig");
760 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
761 "startActivityWithConfig");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700762 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700763 return getActivityStartController().obtainStarter(intent, "startActivityWithConfig")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700764 .setCaller(caller)
765 .setCallingPackage(callingPackage)
766 .setResolvedType(resolvedType)
767 .setResultTo(resultTo)
768 .setResultWho(resultWho)
769 .setRequestCode(requestCode)
770 .setStartFlags(startFlags)
771 .setGlobalConfiguration(config)
772 .setActivityOptions(bOptions)
773 .setMayWait(userId)
774 .execute();
775 }
776 }
777
778 @Override
779 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
780 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
781 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
782 int userId) {
783
784 // This is very dangerous -- it allows you to perform a start activity (including
785 // permission grants) as any app that may launch one of your own activities. So
786 // we will only allow this to be done from activities that are part of the core framework,
787 // and then only when they are running as the system.
788 final ActivityRecord sourceRecord;
789 final int targetUid;
790 final String targetPackage;
791 final boolean isResolver;
792 synchronized (mGlobalLock) {
793 if (resultTo == null) {
794 throw new SecurityException("Must be called from an activity");
795 }
796 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
797 if (sourceRecord == null) {
798 throw new SecurityException("Called with bad activity token: " + resultTo);
799 }
800 if (!sourceRecord.info.packageName.equals("android")) {
801 throw new SecurityException(
802 "Must be called from an activity that is declared in the android package");
803 }
804 if (sourceRecord.app == null) {
805 throw new SecurityException("Called without a process attached to activity");
806 }
807 if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
808 // This is still okay, as long as this activity is running under the
809 // uid of the original calling activity.
810 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
811 throw new SecurityException(
812 "Calling activity in uid " + sourceRecord.app.uid
813 + " must be system uid or original calling uid "
814 + sourceRecord.launchedFromUid);
815 }
816 }
817 if (ignoreTargetSecurity) {
818 if (intent.getComponent() == null) {
819 throw new SecurityException(
820 "Component must be specified with ignoreTargetSecurity");
821 }
822 if (intent.getSelector() != null) {
823 throw new SecurityException(
824 "Selector not allowed with ignoreTargetSecurity");
825 }
826 }
827 targetUid = sourceRecord.launchedFromUid;
828 targetPackage = sourceRecord.launchedFromPackage;
829 isResolver = sourceRecord.isResolverOrChildActivity();
830 }
831
832 if (userId == UserHandle.USER_NULL) {
833 userId = UserHandle.getUserId(sourceRecord.app.uid);
834 }
835
836 // TODO: Switch to user app stacks here.
837 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700838 return getActivityStartController().obtainStarter(intent, "startActivityAsCaller")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700839 .setCallingUid(targetUid)
840 .setCallingPackage(targetPackage)
841 .setResolvedType(resolvedType)
842 .setResultTo(resultTo)
843 .setResultWho(resultWho)
844 .setRequestCode(requestCode)
845 .setStartFlags(startFlags)
846 .setActivityOptions(bOptions)
847 .setMayWait(userId)
848 .setIgnoreTargetSecurity(ignoreTargetSecurity)
849 .setFilterCallingUid(isResolver ? 0 /* system */ : targetUid)
850 .execute();
851 } catch (SecurityException e) {
852 // XXX need to figure out how to propagate to original app.
853 // A SecurityException here is generally actually a fault of the original
854 // calling activity (such as a fairly granting permissions), so propagate it
855 // back to them.
856 /*
857 StringBuilder msg = new StringBuilder();
858 msg.append("While launching");
859 msg.append(intent.toString());
860 msg.append(": ");
861 msg.append(e.getMessage());
862 */
863 throw e;
864 }
865 }
866
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700867 int handleIncomingUser(int callingPid, int callingUid, int userId, String name) {
868 return mAmInternal.handleIncomingUser(callingPid, callingUid, userId, false /* allowAll */,
869 ALLOW_FULL_ONLY, name, null /* callerPackage */);
870 }
871
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700872 @Override
873 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
874 Intent intent, String resolvedType, IVoiceInteractionSession session,
875 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
876 Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700877 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700878 if (session == null || interactor == null) {
879 throw new NullPointerException("null session or interactor");
880 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700881 userId = handleIncomingUser(callingPid, callingUid, userId, "startVoiceActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700882 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700883 return getActivityStartController().obtainStarter(intent, "startVoiceActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700884 .setCallingUid(callingUid)
885 .setCallingPackage(callingPackage)
886 .setResolvedType(resolvedType)
887 .setVoiceSession(session)
888 .setVoiceInteractor(interactor)
889 .setStartFlags(startFlags)
890 .setProfilerInfo(profilerInfo)
891 .setActivityOptions(bOptions)
892 .setMayWait(userId)
893 .execute();
894 }
895
896 @Override
897 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
898 Intent intent, String resolvedType, Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700899 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
900 userId = handleIncomingUser(callingPid, callingUid, userId, "startAssistantActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700901
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700902 return getActivityStartController().obtainStarter(intent, "startAssistantActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700903 .setCallingUid(callingUid)
904 .setCallingPackage(callingPackage)
905 .setResolvedType(resolvedType)
906 .setActivityOptions(bOptions)
907 .setMayWait(userId)
908 .execute();
909 }
910
911 @Override
912 public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
913 IRecentsAnimationRunner recentsAnimationRunner) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700914 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700915 final int callingPid = Binder.getCallingPid();
916 final long origId = Binder.clearCallingIdentity();
917 try {
918 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700919 final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
920 final int recentsUid = mRecentTasks.getRecentsComponentUid();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700921
922 // Start a new recents animation
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700923 final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
924 getActivityStartController(), mWindowManager, callingPid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700925 anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
926 recentsUid, assistDataReceiver);
927 }
928 } finally {
929 Binder.restoreCallingIdentity(origId);
930 }
931 }
932
933 @Override
934 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700935 enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700936 "startActivityFromRecents()");
937
938 final int callingPid = Binder.getCallingPid();
939 final int callingUid = Binder.getCallingUid();
940 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(bOptions);
941 final long origId = Binder.clearCallingIdentity();
942 try {
943 synchronized (mGlobalLock) {
944 return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
945 safeOptions);
946 }
947 } finally {
948 Binder.restoreCallingIdentity(origId);
949 }
950 }
951
952 /**
953 * This is the internal entry point for handling Activity.finish().
954 *
955 * @param token The Binder token referencing the Activity we want to finish.
956 * @param resultCode Result code, if any, from this Activity.
957 * @param resultData Result data (Intent), if any, from this Activity.
958 * @param finishTask Whether to finish the task associated with this Activity.
959 *
960 * @return Returns true if the activity successfully finished, or false if it is still running.
961 */
962 @Override
963 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
964 int finishTask) {
965 // Refuse possible leaked file descriptors
966 if (resultData != null && resultData.hasFileDescriptors()) {
967 throw new IllegalArgumentException("File descriptors passed in Intent");
968 }
969
970 synchronized (mGlobalLock) {
971 ActivityRecord r = ActivityRecord.isInStackLocked(token);
972 if (r == null) {
973 return true;
974 }
975 // Keep track of the root activity of the task before we finish it
976 TaskRecord tr = r.getTask();
977 ActivityRecord rootR = tr.getRootActivity();
978 if (rootR == null) {
979 Slog.w(TAG, "Finishing task with all activities already finished");
980 }
981 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
982 // finish.
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700983 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700984 return false;
985 }
986
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700987 // TODO: There is a dup. of this block of code in ActivityStack.navigateUpToLocked
988 // We should consolidate.
989 if (mController != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700990 // Find the first activity that is not finishing.
991 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
992 if (next != null) {
993 // ask watcher if this is allowed
994 boolean resumeOK = true;
995 try {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700996 resumeOK = mController.activityResuming(next.packageName);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700997 } catch (RemoteException e) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700998 mController = null;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700999 Watchdog.getInstance().setActivityController(null);
1000 }
1001
1002 if (!resumeOK) {
1003 Slog.i(TAG, "Not finishing activity because controller resumed");
1004 return false;
1005 }
1006 }
1007 }
1008 final long origId = Binder.clearCallingIdentity();
1009 try {
1010 boolean res;
1011 final boolean finishWithRootActivity =
1012 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
1013 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
1014 || (finishWithRootActivity && r == rootR)) {
1015 // If requested, remove the task that is associated to this activity only if it
1016 // was the root activity in the task. The result code and data is ignored
1017 // because we don't support returning them across task boundaries. Also, to
1018 // keep backwards compatibility we remove the task from recents when finishing
1019 // task with root activity.
1020 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
1021 finishWithRootActivity, "finish-activity");
1022 if (!res) {
1023 Slog.i(TAG, "Removing task failed to finish activity");
1024 }
1025 } else {
1026 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
1027 resultData, "app-request", true);
1028 if (!res) {
1029 Slog.i(TAG, "Failed to finish by app-request");
1030 }
1031 }
1032 return res;
1033 } finally {
1034 Binder.restoreCallingIdentity(origId);
1035 }
1036 }
1037 }
1038
1039 @Override
1040 public boolean finishActivityAffinity(IBinder token) {
1041 synchronized (mGlobalLock) {
1042 final long origId = Binder.clearCallingIdentity();
1043 try {
1044 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1045 if (r == null) {
1046 return false;
1047 }
1048
1049 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
1050 // can finish.
1051 final TaskRecord task = r.getTask();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001052 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001053 return false;
1054 }
1055 return task.getStack().finishActivityAffinityLocked(r);
1056 } finally {
1057 Binder.restoreCallingIdentity(origId);
1058 }
1059 }
1060 }
1061
1062 @Override
1063 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
1064 final long origId = Binder.clearCallingIdentity();
1065 synchronized (mGlobalLock) {
1066 ActivityStack stack = ActivityRecord.getStackLocked(token);
1067 if (stack != null) {
1068 ActivityRecord r =
1069 mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
1070 false /* processPausingActivities */, config);
1071 if (stopProfiling) {
1072 if ((mAm.mProfileProc == r.app) && mAm.mProfilerInfo != null) {
1073 mAm.clearProfilerLocked();
1074 }
1075 }
1076 }
1077 }
1078 Binder.restoreCallingIdentity(origId);
1079 }
1080
1081 @Override
1082 public final void activityResumed(IBinder token) {
1083 final long origId = Binder.clearCallingIdentity();
1084 synchronized (mGlobalLock) {
1085 ActivityRecord.activityResumedLocked(token);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001086 mWindowManager.notifyAppResumedFinished(token);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001087 }
1088 Binder.restoreCallingIdentity(origId);
1089 }
1090
1091 @Override
1092 public final void activityPaused(IBinder token) {
1093 final long origId = Binder.clearCallingIdentity();
1094 synchronized (mGlobalLock) {
1095 ActivityStack stack = ActivityRecord.getStackLocked(token);
1096 if (stack != null) {
1097 stack.activityPausedLocked(token, false);
1098 }
1099 }
1100 Binder.restoreCallingIdentity(origId);
1101 }
1102
1103 @Override
1104 public final void activityStopped(IBinder token, Bundle icicle,
1105 PersistableBundle persistentState, CharSequence description) {
1106 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
1107
1108 // Refuse possible leaked file descriptors
1109 if (icicle != null && icicle.hasFileDescriptors()) {
1110 throw new IllegalArgumentException("File descriptors passed in Bundle");
1111 }
1112
1113 final long origId = Binder.clearCallingIdentity();
1114
1115 synchronized (mGlobalLock) {
1116 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1117 if (r != null) {
1118 r.activityStoppedLocked(icicle, persistentState, description);
1119 }
1120 }
1121
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001122 mAmInternal.trimApplications();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001123
1124 Binder.restoreCallingIdentity(origId);
1125 }
1126
1127 @Override
1128 public final void activityDestroyed(IBinder token) {
1129 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
1130 synchronized (mGlobalLock) {
1131 ActivityStack stack = ActivityRecord.getStackLocked(token);
1132 if (stack != null) {
1133 stack.activityDestroyedLocked(token, "activityDestroyed");
1134 }
1135 }
1136 }
1137
1138 @Override
1139 public final void activityRelaunched(IBinder token) {
1140 final long origId = Binder.clearCallingIdentity();
1141 synchronized (mGlobalLock) {
1142 mStackSupervisor.activityRelaunchedLocked(token);
1143 }
1144 Binder.restoreCallingIdentity(origId);
1145 }
1146
1147 public final void activitySlept(IBinder token) {
1148 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
1149
1150 final long origId = Binder.clearCallingIdentity();
1151
1152 synchronized (mGlobalLock) {
1153 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1154 if (r != null) {
1155 mStackSupervisor.activitySleptLocked(r);
1156 }
1157 }
1158
1159 Binder.restoreCallingIdentity(origId);
1160 }
1161
1162 @Override
1163 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
1164 synchronized (mGlobalLock) {
1165 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1166 if (r == null) {
1167 return;
1168 }
1169 final long origId = Binder.clearCallingIdentity();
1170 try {
1171 r.setRequestedOrientation(requestedOrientation);
1172 } finally {
1173 Binder.restoreCallingIdentity(origId);
1174 }
1175 }
1176 }
1177
1178 @Override
1179 public int getRequestedOrientation(IBinder token) {
1180 synchronized (mGlobalLock) {
1181 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1182 if (r == null) {
1183 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
1184 }
1185 return r.getRequestedOrientation();
1186 }
1187 }
1188
1189 @Override
1190 public void setImmersive(IBinder token, boolean immersive) {
1191 synchronized (mGlobalLock) {
1192 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1193 if (r == null) {
1194 throw new IllegalArgumentException();
1195 }
1196 r.immersive = immersive;
1197
1198 // update associated state if we're frontmost
1199 if (r == mStackSupervisor.getResumedActivityLocked()) {
1200 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001201 applyUpdateLockStateLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001202 }
1203 }
1204 }
1205
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001206 void applyUpdateLockStateLocked(ActivityRecord r) {
1207 // Modifications to the UpdateLock state are done on our handler, outside
1208 // the activity manager's locks. The new state is determined based on the
1209 // state *now* of the relevant activity record. The object is passed to
1210 // the handler solely for logging detail, not to be consulted/modified.
1211 final boolean nextState = r != null && r.immersive;
1212 mH.post(() -> {
1213 if (mUpdateLock.isHeld() != nextState) {
1214 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1215 "Applying new update lock state '" + nextState + "' for " + r);
1216 if (nextState) {
1217 mUpdateLock.acquire();
1218 } else {
1219 mUpdateLock.release();
1220 }
1221 }
1222 });
1223 }
1224
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001225 @Override
1226 public boolean isImmersive(IBinder token) {
1227 synchronized (mGlobalLock) {
1228 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1229 if (r == null) {
1230 throw new IllegalArgumentException();
1231 }
1232 return r.immersive;
1233 }
1234 }
1235
1236 @Override
1237 public boolean isTopActivityImmersive() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001238 enforceNotIsolatedCaller("isTopActivityImmersive");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001239 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001240 final ActivityRecord r = getFocusedStack().topRunningActivityLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001241 return (r != null) ? r.immersive : false;
1242 }
1243 }
1244
1245 @Override
1246 public void overridePendingTransition(IBinder token, String packageName,
1247 int enterAnim, int exitAnim) {
1248 synchronized (mGlobalLock) {
1249 ActivityRecord self = ActivityRecord.isInStackLocked(token);
1250 if (self == null) {
1251 return;
1252 }
1253
1254 final long origId = Binder.clearCallingIdentity();
1255
1256 if (self.isState(
1257 ActivityStack.ActivityState.RESUMED, ActivityStack.ActivityState.PAUSING)) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001258 mWindowManager.overridePendingAppTransition(packageName,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001259 enterAnim, exitAnim, null);
1260 }
1261
1262 Binder.restoreCallingIdentity(origId);
1263 }
1264 }
1265
1266 @Override
1267 public int getFrontActivityScreenCompatMode() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001268 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
1269 ApplicationInfo ai;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001270 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001271 final ActivityRecord r = getFocusedStack().topRunningActivityLocked();
1272 if (r == null) {
1273 return ActivityManager.COMPAT_MODE_UNKNOWN;
1274 }
1275 ai = r.info.applicationInfo;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001276 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001277
1278 return mAmInternal.getPackageScreenCompatMode(ai);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001279 }
1280
1281 @Override
1282 public void setFrontActivityScreenCompatMode(int mode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001283 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001284 "setFrontActivityScreenCompatMode");
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001285 ApplicationInfo ai;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001286 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001287 final ActivityRecord r = getFocusedStack().topRunningActivityLocked();
1288 if (r == null) {
1289 Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity");
1290 return;
1291 }
1292 ai = r.info.applicationInfo;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001293 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001294
1295 mAmInternal.setPackageScreenCompatMode(ai, mode);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001296 }
1297
1298 @Override
1299 public int getLaunchedFromUid(IBinder activityToken) {
1300 ActivityRecord srec;
1301 synchronized (mGlobalLock) {
1302 srec = ActivityRecord.forTokenLocked(activityToken);
1303 }
1304 if (srec == null) {
1305 return -1;
1306 }
1307 return srec.launchedFromUid;
1308 }
1309
1310 @Override
1311 public String getLaunchedFromPackage(IBinder activityToken) {
1312 ActivityRecord srec;
1313 synchronized (mGlobalLock) {
1314 srec = ActivityRecord.forTokenLocked(activityToken);
1315 }
1316 if (srec == null) {
1317 return null;
1318 }
1319 return srec.launchedFromPackage;
1320 }
1321
1322 @Override
1323 public boolean convertFromTranslucent(IBinder token) {
1324 final long origId = Binder.clearCallingIdentity();
1325 try {
1326 synchronized (mGlobalLock) {
1327 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1328 if (r == null) {
1329 return false;
1330 }
1331 final boolean translucentChanged = r.changeWindowTranslucency(true);
1332 if (translucentChanged) {
1333 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
1334 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001335 mWindowManager.setAppFullscreen(token, true);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001336 return translucentChanged;
1337 }
1338 } finally {
1339 Binder.restoreCallingIdentity(origId);
1340 }
1341 }
1342
1343 @Override
1344 public boolean convertToTranslucent(IBinder token, Bundle options) {
1345 SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
1346 final long origId = Binder.clearCallingIdentity();
1347 try {
1348 synchronized (mGlobalLock) {
1349 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1350 if (r == null) {
1351 return false;
1352 }
1353 final TaskRecord task = r.getTask();
1354 int index = task.mActivities.lastIndexOf(r);
1355 if (index > 0) {
1356 ActivityRecord under = task.mActivities.get(index - 1);
1357 under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
1358 }
1359 final boolean translucentChanged = r.changeWindowTranslucency(false);
1360 if (translucentChanged) {
1361 r.getStack().convertActivityToTranslucent(r);
1362 }
1363 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001364 mWindowManager.setAppFullscreen(token, false);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001365 return translucentChanged;
1366 }
1367 } finally {
1368 Binder.restoreCallingIdentity(origId);
1369 }
1370 }
1371
1372 @Override
1373 public void notifyActivityDrawn(IBinder token) {
1374 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
1375 synchronized (mGlobalLock) {
1376 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
1377 if (r != null) {
1378 r.getStack().notifyActivityDrawnLocked(r);
1379 }
1380 }
1381 }
1382
1383 @Override
1384 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
1385 synchronized (mGlobalLock) {
1386 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1387 if (r == null) {
1388 return;
1389 }
1390 r.reportFullyDrawnLocked(restoredFromBundle);
1391 }
1392 }
1393
1394 @Override
1395 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
1396 synchronized (mGlobalLock) {
1397 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
1398 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
1399 return stack.mDisplayId;
1400 }
1401 return DEFAULT_DISPLAY;
1402 }
1403 }
1404
1405 @Override
1406 public ActivityManager.StackInfo getFocusedStackInfo() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001407 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001408 long ident = Binder.clearCallingIdentity();
1409 try {
1410 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001411 ActivityStack focusedStack = getFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001412 if (focusedStack != null) {
1413 return mStackSupervisor.getStackInfo(focusedStack.mStackId);
1414 }
1415 return null;
1416 }
1417 } finally {
1418 Binder.restoreCallingIdentity(ident);
1419 }
1420 }
1421
1422 @Override
1423 public void setFocusedStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001424 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001425 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
1426 final long callingId = Binder.clearCallingIdentity();
1427 try {
1428 synchronized (mGlobalLock) {
1429 final ActivityStack stack = mStackSupervisor.getStack(stackId);
1430 if (stack == null) {
1431 Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
1432 return;
1433 }
1434 final ActivityRecord r = stack.topRunningActivityLocked();
1435 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
1436 r, "setFocusedStack")) {
1437 mStackSupervisor.resumeFocusedStackTopActivityLocked();
1438 }
1439 }
1440 } finally {
1441 Binder.restoreCallingIdentity(callingId);
1442 }
1443 }
1444
1445 @Override
1446 public void setFocusedTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001447 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001448 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
1449 final long callingId = Binder.clearCallingIdentity();
1450 try {
1451 synchronized (mGlobalLock) {
1452 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1453 if (task == null) {
1454 return;
1455 }
1456 final ActivityRecord r = task.topRunningActivityLocked();
1457 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
1458 mStackSupervisor.resumeFocusedStackTopActivityLocked();
1459 }
1460 }
1461 } finally {
1462 Binder.restoreCallingIdentity(callingId);
1463 }
1464 }
1465
1466 @Override
1467 public boolean removeTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001468 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001469 synchronized (mGlobalLock) {
1470 final long ident = Binder.clearCallingIdentity();
1471 try {
1472 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
1473 "remove-task");
1474 } finally {
1475 Binder.restoreCallingIdentity(ident);
1476 }
1477 }
1478 }
1479
1480 @Override
1481 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
1482 synchronized (mGlobalLock) {
1483 final ActivityRecord srec = ActivityRecord.forTokenLocked(token);
1484 if (srec != null) {
1485 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
1486 }
1487 }
1488 return false;
1489 }
1490
1491 @Override
1492 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
1493 Intent resultData) {
1494
1495 synchronized (mGlobalLock) {
1496 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
1497 if (r != null) {
1498 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
1499 }
1500 return false;
1501 }
1502 }
1503
1504 /**
1505 * Attempts to move a task backwards in z-order (the order of activities within the task is
1506 * unchanged).
1507 *
1508 * There are several possible results of this call:
1509 * - if the task is locked, then we will show the lock toast
1510 * - if there is a task behind the provided task, then that task is made visible and resumed as
1511 * this task is moved to the back
1512 * - otherwise, if there are no other tasks in the stack:
1513 * - if this task is in the pinned stack, then we remove the stack completely, which will
1514 * have the effect of moving the task to the top or bottom of the fullscreen stack
1515 * (depending on whether it is visible)
1516 * - otherwise, we simply return home and hide this task
1517 *
1518 * @param token A reference to the activity we wish to move
1519 * @param nonRoot If false then this only works if the activity is the root
1520 * of a task; if true it will work for any activity in a task.
1521 * @return Returns true if the move completed, false if not.
1522 */
1523 @Override
1524 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001525 enforceNotIsolatedCaller("moveActivityTaskToBack");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001526 synchronized (mGlobalLock) {
1527 final long origId = Binder.clearCallingIdentity();
1528 try {
1529 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
1530 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1531 if (task != null) {
1532 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
1533 }
1534 } finally {
1535 Binder.restoreCallingIdentity(origId);
1536 }
1537 }
1538 return false;
1539 }
1540
1541 @Override
1542 public Rect getTaskBounds(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001543 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001544 long ident = Binder.clearCallingIdentity();
1545 Rect rect = new Rect();
1546 try {
1547 synchronized (mGlobalLock) {
1548 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
1549 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1550 if (task == null) {
1551 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
1552 return rect;
1553 }
1554 if (task.getStack() != null) {
1555 // Return the bounds from window manager since it will be adjusted for various
1556 // things like the presense of a docked stack for tasks that aren't resizeable.
1557 task.getWindowContainerBounds(rect);
1558 } else {
1559 // Task isn't in window manager yet since it isn't associated with a stack.
1560 // Return the persist value from activity manager
1561 if (!task.matchParentBounds()) {
1562 rect.set(task.getBounds());
1563 } else if (task.mLastNonFullscreenBounds != null) {
1564 rect.set(task.mLastNonFullscreenBounds);
1565 }
1566 }
1567 }
1568 } finally {
1569 Binder.restoreCallingIdentity(ident);
1570 }
1571 return rect;
1572 }
1573
1574 @Override
1575 public ActivityManager.TaskDescription getTaskDescription(int id) {
1576 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001577 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001578 MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
1579 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
1580 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1581 if (tr != null) {
1582 return tr.lastTaskDescription;
1583 }
1584 }
1585 return null;
1586 }
1587
1588 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001589 public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
1590 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
1591 setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
1592 toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
1593 return;
1594 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001595 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001596 synchronized (mGlobalLock) {
1597 final long ident = Binder.clearCallingIdentity();
1598 try {
1599 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1600 if (task == null) {
1601 Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
1602 return;
1603 }
1604
1605 if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
1606 + " to windowingMode=" + windowingMode + " toTop=" + toTop);
1607
1608 if (!task.isActivityTypeStandardOrUndefined()) {
1609 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
1610 + " non-standard task " + taskId + " to windowing mode="
1611 + windowingMode);
1612 }
1613
1614 final ActivityStack stack = task.getStack();
1615 if (toTop) {
1616 stack.moveToFront("setTaskWindowingMode", task);
1617 }
1618 stack.setWindowingMode(windowingMode);
1619 } finally {
1620 Binder.restoreCallingIdentity(ident);
1621 }
1622 }
1623 }
1624
1625 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001626 public String getCallingPackage(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001627 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001628 ActivityRecord r = getCallingRecordLocked(token);
1629 return r != null ? r.info.packageName : null;
1630 }
1631 }
1632
1633 @Override
1634 public ComponentName getCallingActivity(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001635 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001636 ActivityRecord r = getCallingRecordLocked(token);
1637 return r != null ? r.intent.getComponent() : null;
1638 }
1639 }
1640
1641 private ActivityRecord getCallingRecordLocked(IBinder token) {
1642 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1643 if (r == null) {
1644 return null;
1645 }
1646 return r.resultTo;
1647 }
1648
1649 @Override
1650 public void unhandledBack() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001651 mAmInternal.enforceCallingPermission(android.Manifest.permission.FORCE_BACK, "unhandledBack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001652
1653 synchronized (mGlobalLock) {
1654 final long origId = Binder.clearCallingIdentity();
1655 try {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001656 getFocusedStack().unhandledBackLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001657 } finally {
1658 Binder.restoreCallingIdentity(origId);
1659 }
1660 }
1661 }
1662
1663 /**
1664 * TODO: Add mController hook
1665 */
1666 @Override
1667 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001668 mAmInternal.enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001669
1670 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
1671 synchronized (mGlobalLock) {
1672 moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
1673 false /* fromRecents */);
1674 }
1675 }
1676
1677 void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
1678 boolean fromRecents) {
1679
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001680 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001681 Binder.getCallingUid(), -1, -1, "Task to front")) {
1682 SafeActivityOptions.abort(options);
1683 return;
1684 }
1685 final long origId = Binder.clearCallingIdentity();
1686 try {
1687 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1688 if (task == null) {
1689 Slog.d(TAG, "Could not find task for id: "+ taskId);
1690 return;
1691 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001692 if (getLockTaskController().isLockTaskModeViolation(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001693 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
1694 return;
1695 }
1696 ActivityOptions realOptions = options != null
1697 ? options.getOptions(mStackSupervisor)
1698 : null;
1699 mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
1700 false /* forceNonResizable */);
1701
1702 final ActivityRecord topActivity = task.getTopActivity();
1703 if (topActivity != null) {
1704
1705 // We are reshowing a task, use a starting window to hide the initial draw delay
1706 // so the transition can start earlier.
1707 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
1708 true /* taskSwitch */, fromRecents);
1709 }
1710 } finally {
1711 Binder.restoreCallingIdentity(origId);
1712 }
1713 SafeActivityOptions.abort(options);
1714 }
1715
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001716 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
1717 int callingPid, int callingUid, String name) {
1718 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
1719 return true;
1720 }
1721
1722 if (getRecentTasks().isCallerRecents(sourceUid)) {
1723 return true;
1724 }
1725
1726 int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
1727 if (perm == PackageManager.PERMISSION_GRANTED) {
1728 return true;
1729 }
1730 if (checkAllowAppSwitchUid(sourceUid)) {
1731 return true;
1732 }
1733
1734 // If the actual IPC caller is different from the logical source, then
1735 // also see if they are allowed to control app switches.
1736 if (callingUid != -1 && callingUid != sourceUid) {
1737 perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
1738 if (perm == PackageManager.PERMISSION_GRANTED) {
1739 return true;
1740 }
1741 if (checkAllowAppSwitchUid(callingUid)) {
1742 return true;
1743 }
1744 }
1745
1746 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
1747 return false;
1748 }
1749
1750 private boolean checkAllowAppSwitchUid(int uid) {
1751 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
1752 if (types != null) {
1753 for (int i = types.size() - 1; i >= 0; i--) {
1754 if (types.valueAt(i).intValue() == uid) {
1755 return true;
1756 }
1757 }
1758 }
1759 return false;
1760 }
1761
1762 @Override
1763 public void setActivityController(IActivityController controller, boolean imAMonkey) {
1764 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
1765 "setActivityController()");
1766 synchronized (mGlobalLock) {
1767 mController = controller;
1768 mControllerIsAMonkey = imAMonkey;
1769 Watchdog.getInstance().setActivityController(controller);
1770 }
1771 }
1772
1773 boolean isControllerAMonkey() {
1774 synchronized (mGlobalLock) {
1775 return mController != null && mControllerIsAMonkey;
1776 }
1777 }
1778
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001779 @Override
1780 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
1781 synchronized (mGlobalLock) {
1782 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
1783 }
1784 }
1785
1786 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001787 public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum) {
1788 return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
1789 }
1790
1791 @Override
1792 public List<ActivityManager.RunningTaskInfo> getFilteredTasks(int maxNum,
1793 @WindowConfiguration.ActivityType int ignoreActivityType,
1794 @WindowConfiguration.WindowingMode int ignoreWindowingMode) {
1795 final int callingUid = Binder.getCallingUid();
1796 ArrayList<ActivityManager.RunningTaskInfo> list = new ArrayList<>();
1797
1798 synchronized (mGlobalLock) {
1799 if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
1800
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001801 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001802 callingUid);
1803 mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
1804 ignoreWindowingMode, callingUid, allowed);
1805 }
1806
1807 return list;
1808 }
1809
1810 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001811 public final void finishSubActivity(IBinder token, String resultWho, int requestCode) {
1812 synchronized (mGlobalLock) {
1813 final long origId = Binder.clearCallingIdentity();
1814 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1815 if (r != null) {
1816 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
1817 }
1818 Binder.restoreCallingIdentity(origId);
1819 }
1820 }
1821
1822 @Override
1823 public boolean willActivityBeVisible(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001824 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001825 ActivityStack stack = ActivityRecord.getStackLocked(token);
1826 if (stack != null) {
1827 return stack.willActivityBeVisibleLocked(token);
1828 }
1829 return false;
1830 }
1831 }
1832
1833 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001834 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001835 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001836 synchronized (mGlobalLock) {
1837 final long ident = Binder.clearCallingIdentity();
1838 try {
1839 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1840 if (task == null) {
1841 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
1842 return;
1843 }
1844
1845 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
1846 + " to stackId=" + stackId + " toTop=" + toTop);
1847
1848 final ActivityStack stack = mStackSupervisor.getStack(stackId);
1849 if (stack == null) {
1850 throw new IllegalStateException(
1851 "moveTaskToStack: No stack for stackId=" + stackId);
1852 }
1853 if (!stack.isActivityTypeStandardOrUndefined()) {
1854 throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
1855 + taskId + " to stack " + stackId);
1856 }
1857 if (stack.inSplitScreenPrimaryWindowingMode()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001858 mWindowManager.setDockedStackCreateState(
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001859 SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
1860 }
1861 task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
1862 "moveTaskToStack");
1863 } finally {
1864 Binder.restoreCallingIdentity(ident);
1865 }
1866 }
1867 }
1868
1869 @Override
1870 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
1871 boolean preserveWindows, boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001872 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001873
1874 final long ident = Binder.clearCallingIdentity();
1875 try {
1876 synchronized (mGlobalLock) {
1877 if (animate) {
1878 final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
1879 if (stack == null) {
1880 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
1881 return;
1882 }
1883 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
1884 throw new IllegalArgumentException("Stack: " + stackId
1885 + " doesn't support animated resize.");
1886 }
1887 stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
1888 animationDuration, false /* fromFullscreen */);
1889 } else {
1890 final ActivityStack stack = mStackSupervisor.getStack(stackId);
1891 if (stack == null) {
1892 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
1893 return;
1894 }
1895 mStackSupervisor.resizeStackLocked(stack, destBounds,
1896 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
1897 preserveWindows, allowResizeInDockedMode, !DEFER_RESUME);
1898 }
1899 }
1900 } finally {
1901 Binder.restoreCallingIdentity(ident);
1902 }
1903 }
1904
1905 /**
1906 * Moves the specified task to the primary-split-screen stack.
1907 *
1908 * @param taskId Id of task to move.
1909 * @param createMode The mode the primary split screen stack should be created in if it doesn't
1910 * exist already. See
1911 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
1912 * and
1913 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
1914 * @param toTop If the task and stack should be moved to the top.
1915 * @param animate Whether we should play an animation for the moving the task.
1916 * @param initialBounds If the primary stack gets created, it will use these bounds for the
1917 * stack. Pass {@code null} to use default bounds.
1918 * @param showRecents If the recents activity should be shown on the other side of the task
1919 * going into split-screen mode.
1920 */
1921 @Override
1922 public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode,
1923 boolean toTop, boolean animate, Rect initialBounds, boolean showRecents) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001924 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001925 "setTaskWindowingModeSplitScreenPrimary()");
1926 synchronized (mGlobalLock) {
1927 final long ident = Binder.clearCallingIdentity();
1928 try {
1929 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1930 if (task == null) {
1931 Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
1932 return false;
1933 }
1934 if (DEBUG_STACK) Slog.d(TAG_STACK,
1935 "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
1936 + " to createMode=" + createMode + " toTop=" + toTop);
1937 if (!task.isActivityTypeStandardOrUndefined()) {
1938 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
1939 + " non-standard task " + taskId + " to split-screen windowing mode");
1940 }
1941
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001942 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001943 final int windowingMode = task.getWindowingMode();
1944 final ActivityStack stack = task.getStack();
1945 if (toTop) {
1946 stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
1947 }
1948 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
1949 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */);
1950 return windowingMode != task.getWindowingMode();
1951 } finally {
1952 Binder.restoreCallingIdentity(ident);
1953 }
1954 }
1955 }
1956
1957 /**
1958 * Removes stacks in the input windowing modes from the system if they are of activity type
1959 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
1960 */
1961 @Override
1962 public void removeStacksInWindowingModes(int[] windowingModes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001963 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001964 "removeStacksInWindowingModes()");
1965
1966 synchronized (mGlobalLock) {
1967 final long ident = Binder.clearCallingIdentity();
1968 try {
1969 mStackSupervisor.removeStacksInWindowingModes(windowingModes);
1970 } finally {
1971 Binder.restoreCallingIdentity(ident);
1972 }
1973 }
1974 }
1975
1976 @Override
1977 public void removeStacksWithActivityTypes(int[] activityTypes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001978 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001979 "removeStacksWithActivityTypes()");
1980
1981 synchronized (mGlobalLock) {
1982 final long ident = Binder.clearCallingIdentity();
1983 try {
1984 mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
1985 } finally {
1986 Binder.restoreCallingIdentity(ident);
1987 }
1988 }
1989 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001990
1991 @Override
1992 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
1993 int userId) {
1994 final int callingUid = Binder.getCallingUid();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001995 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, "getRecentTasks");
1996 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001997 callingUid);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001998 final boolean detailed = checkGetTasksPermission(
1999 android.Manifest.permission.GET_DETAILED_TASKS, Binder.getCallingPid(),
2000 UserHandle.getAppId(callingUid))
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002001 == PackageManager.PERMISSION_GRANTED;
2002
2003 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002004 return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002005 callingUid);
2006 }
2007 }
2008
2009 @Override
2010 public List<ActivityManager.StackInfo> getAllStackInfos() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002011 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002012 long ident = Binder.clearCallingIdentity();
2013 try {
2014 synchronized (mGlobalLock) {
2015 return mStackSupervisor.getAllStackInfosLocked();
2016 }
2017 } finally {
2018 Binder.restoreCallingIdentity(ident);
2019 }
2020 }
2021
2022 @Override
2023 public ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002024 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002025 long ident = Binder.clearCallingIdentity();
2026 try {
2027 synchronized (mGlobalLock) {
2028 return mStackSupervisor.getStackInfo(windowingMode, activityType);
2029 }
2030 } finally {
2031 Binder.restoreCallingIdentity(ident);
2032 }
2033 }
2034
2035 @Override
2036 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002037 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002038 final long callingUid = Binder.getCallingUid();
2039 final long origId = Binder.clearCallingIdentity();
2040 try {
2041 synchronized (mGlobalLock) {
2042 // Cancel the recents animation synchronously (do not hold the WM lock)
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002043 mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002044 ? REORDER_MOVE_TO_ORIGINAL_POSITION
2045 : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
2046 }
2047 } finally {
2048 Binder.restoreCallingIdentity(origId);
2049 }
2050 }
2051
2052 @Override
2053 public void startLockTaskModeByToken(IBinder token) {
2054 synchronized (mGlobalLock) {
2055 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2056 if (r == null) {
2057 return;
2058 }
2059 startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
2060 }
2061 }
2062
2063 @Override
2064 public void startSystemLockTaskMode(int taskId) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002065 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002066 // This makes inner call to look as if it was initiated by system.
2067 long ident = Binder.clearCallingIdentity();
2068 try {
2069 synchronized (mGlobalLock) {
2070 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2071
2072 // When starting lock task mode the stack must be in front and focused
2073 task.getStack().moveToFront("startSystemLockTaskMode");
2074 startLockTaskModeLocked(task, true /* isSystemCaller */);
2075 }
2076 } finally {
2077 Binder.restoreCallingIdentity(ident);
2078 }
2079 }
2080
2081 @Override
2082 public void stopLockTaskModeByToken(IBinder token) {
2083 synchronized (mGlobalLock) {
2084 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2085 if (r == null) {
2086 return;
2087 }
2088 stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
2089 }
2090 }
2091
2092 /**
2093 * This API should be called by SystemUI only when user perform certain action to dismiss
2094 * lock task mode. We should only dismiss pinned lock task mode in this case.
2095 */
2096 @Override
2097 public void stopSystemLockTaskMode() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002098 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002099 stopLockTaskModeInternal(null, true /* isSystemCaller */);
2100 }
2101
2102 private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
2103 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
2104 if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
2105 return;
2106 }
2107
2108 final ActivityStack stack = mStackSupervisor.getFocusedStack();
2109 if (stack == null || task != stack.topTask()) {
2110 throw new IllegalArgumentException("Invalid task, not in foreground");
2111 }
2112
2113 // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
2114 // system or a specific app.
2115 // * System-initiated requests will only start the pinned mode (screen pinning)
2116 // * App-initiated requests
2117 // - will put the device in fully locked mode (LockTask), if the app is whitelisted
2118 // - will start the pinned mode, otherwise
2119 final int callingUid = Binder.getCallingUid();
2120 long ident = Binder.clearCallingIdentity();
2121 try {
2122 // When a task is locked, dismiss the pinned stack if it exists
2123 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2124
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002125 getLockTaskController().startLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002126 } finally {
2127 Binder.restoreCallingIdentity(ident);
2128 }
2129 }
2130
2131 private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
2132 final int callingUid = Binder.getCallingUid();
2133 long ident = Binder.clearCallingIdentity();
2134 try {
2135 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002136 getLockTaskController().stopLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002137 }
2138 // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
2139 // task and jumping straight into a call in the case of emergency call back.
2140 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
2141 if (tm != null) {
2142 tm.showInCallScreen(false);
2143 }
2144 } finally {
2145 Binder.restoreCallingIdentity(ident);
2146 }
2147 }
2148
2149 @Override
2150 public boolean isInLockTaskMode() {
2151 return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
2152 }
2153
2154 @Override
2155 public int getLockTaskModeState() {
2156 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002157 return getLockTaskController().getLockTaskModeState();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002158 }
2159 }
2160
2161 @Override
2162 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
2163 synchronized (mGlobalLock) {
2164 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2165 if (r != null) {
2166 r.setTaskDescription(td);
2167 final TaskRecord task = r.getTask();
2168 task.updateTaskDescription();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002169 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002170 }
2171 }
2172 }
2173
2174 @Override
2175 public Bundle getActivityOptions(IBinder token) {
2176 final long origId = Binder.clearCallingIdentity();
2177 try {
2178 synchronized (mGlobalLock) {
2179 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
2180 if (r != null) {
2181 final ActivityOptions activityOptions = r.takeOptionsLocked();
2182 return activityOptions == null ? null : activityOptions.toBundle();
2183 }
2184 return null;
2185 }
2186 } finally {
2187 Binder.restoreCallingIdentity(origId);
2188 }
2189 }
2190
2191 @Override
2192 public List<IBinder> getAppTasks(String callingPackage) {
2193 int callingUid = Binder.getCallingUid();
2194 long ident = Binder.clearCallingIdentity();
2195 try {
2196 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002197 return mRecentTasks.getAppTasksList(callingUid, callingPackage);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002198 }
2199 } finally {
2200 Binder.restoreCallingIdentity(ident);
2201 }
2202 }
2203
2204 @Override
2205 public void finishVoiceTask(IVoiceInteractionSession session) {
2206 synchronized (mGlobalLock) {
2207 final long origId = Binder.clearCallingIdentity();
2208 try {
2209 // TODO: VI Consider treating local voice interactions and voice tasks
2210 // differently here
2211 mStackSupervisor.finishVoiceTask(session);
2212 } finally {
2213 Binder.restoreCallingIdentity(origId);
2214 }
2215 }
2216
2217 }
2218
2219 @Override
2220 public boolean isTopOfTask(IBinder token) {
2221 synchronized (mGlobalLock) {
2222 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2223 if (r == null) {
2224 throw new IllegalArgumentException();
2225 }
2226 return r.getTask().getTopActivity() == r;
2227 }
2228 }
2229
2230 @Override
2231 public void notifyLaunchTaskBehindComplete(IBinder token) {
2232 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
2233 }
2234
2235 @Override
2236 public void notifyEnterAnimationComplete(IBinder token) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002237 mH.post(() -> {
2238 synchronized (mGlobalLock) {
2239 ActivityRecord r = ActivityRecord.forTokenLocked(token);
2240 if (r != null && r.app != null && r.app.thread != null) {
2241 try {
2242 r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2243 } catch (RemoteException e) {
2244 }
2245 }
2246 }
2247
2248 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002249 }
2250
2251 /** Called from an app when assist data is ready. */
2252 @Override
2253 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
2254 AssistContent content, Uri referrer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002255 PendingAssistExtras pae = (PendingAssistExtras) token;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002256 synchronized (pae) {
2257 pae.result = extras;
2258 pae.structure = structure;
2259 pae.content = content;
2260 if (referrer != null) {
2261 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
2262 }
2263 if (structure != null) {
2264 structure.setHomeActivity(pae.isHome);
2265 }
2266 pae.haveResult = true;
2267 pae.notifyAll();
2268 if (pae.intent == null && pae.receiver == null) {
2269 // Caller is just waiting for the result.
2270 return;
2271 }
2272 }
2273 // We are now ready to launch the assist activity.
2274 IAssistDataReceiver sendReceiver = null;
2275 Bundle sendBundle = null;
2276 synchronized (mGlobalLock) {
2277 buildAssistBundleLocked(pae, extras);
2278 boolean exists = mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002279 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002280 if (!exists) {
2281 // Timed out.
2282 return;
2283 }
2284
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002285 if ((sendReceiver = pae.receiver) != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002286 // Caller wants result sent back to them.
2287 sendBundle = new Bundle();
2288 sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
2289 sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
2290 sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
2291 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
2292 }
2293 }
2294 if (sendReceiver != null) {
2295 try {
2296 sendReceiver.onHandleAssistData(sendBundle);
2297 } catch (RemoteException e) {
2298 }
2299 return;
2300 }
2301
2302 final long ident = Binder.clearCallingIdentity();
2303 try {
2304 if (TextUtils.equals(pae.intent.getAction(),
2305 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
2306 pae.intent.putExtras(pae.extras);
2307 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
2308 } else {
2309 pae.intent.replaceExtras(pae.extras);
2310 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
2311 | Intent.FLAG_ACTIVITY_SINGLE_TOP
2312 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002313 mAmInternal.closeSystemDialogs("assist");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002314
2315 try {
2316 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
2317 } catch (ActivityNotFoundException e) {
2318 Slog.w(TAG, "No activity to handle assist action.", e);
2319 }
2320 }
2321 } finally {
2322 Binder.restoreCallingIdentity(ident);
2323 }
2324 }
2325
2326 @Override
2327 public int addAppTask(IBinder activityToken, Intent intent,
2328 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
2329 final int callingUid = Binder.getCallingUid();
2330 final long callingIdent = Binder.clearCallingIdentity();
2331
2332 try {
2333 synchronized (mGlobalLock) {
2334 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
2335 if (r == null) {
2336 throw new IllegalArgumentException("Activity does not exist; token="
2337 + activityToken);
2338 }
2339 ComponentName comp = intent.getComponent();
2340 if (comp == null) {
2341 throw new IllegalArgumentException("Intent " + intent
2342 + " must specify explicit component");
2343 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002344 if (thumbnail.getWidth() != mThumbnailWidth
2345 || thumbnail.getHeight() != mThumbnailHeight) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002346 throw new IllegalArgumentException("Bad thumbnail size: got "
2347 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002348 + mThumbnailWidth + "x" + mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002349 }
2350 if (intent.getSelector() != null) {
2351 intent.setSelector(null);
2352 }
2353 if (intent.getSourceBounds() != null) {
2354 intent.setSourceBounds(null);
2355 }
2356 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
2357 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
2358 // The caller has added this as an auto-remove task... that makes no
2359 // sense, so turn off auto-remove.
2360 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
2361 }
2362 }
2363 final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
2364 STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
2365 if (ainfo.applicationInfo.uid != callingUid) {
2366 throw new SecurityException(
2367 "Can't add task for another application: target uid="
2368 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
2369 }
2370
2371 final ActivityStack stack = r.getStack();
2372 final TaskRecord task = stack.createTaskRecord(
2373 mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent,
2374 null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002375 if (!mRecentTasks.addToBottom(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002376 // The app has too many tasks already and we can't add any more
2377 stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
2378 return INVALID_TASK_ID;
2379 }
2380 task.lastTaskDescription.copyFrom(description);
2381
2382 // TODO: Send the thumbnail to WM to store it.
2383
2384 return task.taskId;
2385 }
2386 } finally {
2387 Binder.restoreCallingIdentity(callingIdent);
2388 }
2389 }
2390
2391 @Override
2392 public Point getAppTaskThumbnailSize() {
2393 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002394 return new Point(mThumbnailWidth, mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002395 }
2396 }
2397
2398 @Override
2399 public void setTaskResizeable(int taskId, int resizeableMode) {
2400 synchronized (mGlobalLock) {
2401 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
2402 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
2403 if (task == null) {
2404 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
2405 return;
2406 }
2407 task.setResizeMode(resizeableMode);
2408 }
2409 }
2410
2411 @Override
2412 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002413 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002414 long ident = Binder.clearCallingIdentity();
2415 try {
2416 synchronized (mGlobalLock) {
2417 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2418 if (task == null) {
2419 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
2420 return;
2421 }
2422 // Place the task in the right stack if it isn't there already based on
2423 // the requested bounds.
2424 // The stack transition logic is:
2425 // - a null bounds on a freeform task moves that task to fullscreen
2426 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
2427 // that task to freeform
2428 // - otherwise the task is not moved
2429 ActivityStack stack = task.getStack();
2430 if (!task.getWindowConfiguration().canResizeTask()) {
2431 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
2432 }
2433 if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
2434 stack = stack.getDisplay().getOrCreateStack(
2435 WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
2436 } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
2437 stack = stack.getDisplay().getOrCreateStack(
2438 WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
2439 }
2440
2441 // Reparent the task to the right stack if necessary
2442 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
2443 if (stack != task.getStack()) {
2444 // Defer resume until the task is resized below
2445 task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
2446 DEFER_RESUME, "resizeTask");
2447 preserveWindow = false;
2448 }
2449
2450 // After reparenting (which only resizes the task to the stack bounds), resize the
2451 // task to the actual bounds provided
2452 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
2453 }
2454 } finally {
2455 Binder.restoreCallingIdentity(ident);
2456 }
2457 }
2458
2459 @Override
2460 public boolean releaseActivityInstance(IBinder token) {
2461 synchronized (mGlobalLock) {
2462 final long origId = Binder.clearCallingIdentity();
2463 try {
2464 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2465 if (r == null) {
2466 return false;
2467 }
2468 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
2469 } finally {
2470 Binder.restoreCallingIdentity(origId);
2471 }
2472 }
2473 }
2474
2475 @Override
2476 public void releaseSomeActivities(IApplicationThread appInt) {
2477 synchronized (mGlobalLock) {
2478 final long origId = Binder.clearCallingIdentity();
2479 try {
2480 ProcessRecord app = mAm.getRecordForAppLocked(appInt);
2481 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
2482 } finally {
2483 Binder.restoreCallingIdentity(origId);
2484 }
2485 }
2486 }
2487
2488 @Override
2489 public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
2490 int secondaryDisplayShowing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002491 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002492 != PackageManager.PERMISSION_GRANTED) {
2493 throw new SecurityException("Requires permission "
2494 + android.Manifest.permission.DEVICE_POWER);
2495 }
2496
2497 synchronized (mGlobalLock) {
2498 long ident = Binder.clearCallingIdentity();
2499 if (mKeyguardShown != keyguardShowing) {
2500 mKeyguardShown = keyguardShowing;
2501 reportCurKeyguardUsageEventLocked(keyguardShowing);
2502 }
2503 try {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002504 mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002505 secondaryDisplayShowing);
2506 } finally {
2507 Binder.restoreCallingIdentity(ident);
2508 }
2509 }
2510
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002511 mH.post(() -> {
2512 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2513 mScreenObservers.get(i).onKeyguardStateChanged(keyguardShowing);
2514 }
2515 });
2516 }
2517
2518 void onScreenAwakeChanged(boolean isAwake) {
2519 mH.post(() -> {
2520 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2521 mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2522 }
2523 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002524 }
2525
2526 @Override
2527 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002528 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
2529 userId, "getTaskDescriptionIcon");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002530
2531 final File passedIconFile = new File(filePath);
2532 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
2533 passedIconFile.getName());
2534 if (!legitIconFile.getPath().equals(filePath)
2535 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
2536 throw new IllegalArgumentException("Bad file path: " + filePath
2537 + " passed for userId " + userId);
2538 }
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002539 return mRecentTasks.getTaskDescriptionIcon(filePath);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002540 }
2541
2542 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002543 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002544 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
2545 final ActivityOptions activityOptions = safeOptions != null
2546 ? safeOptions.getOptions(mStackSupervisor)
2547 : null;
2548 if (activityOptions == null
2549 || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
2550 || activityOptions.getCustomInPlaceResId() == 0) {
2551 throw new IllegalArgumentException("Expected in-place ActivityOption " +
2552 "with valid animation");
2553 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002554 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
2555 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002556 activityOptions.getCustomInPlaceResId());
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002557 mWindowManager.executeAppTransition();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002558 }
2559
2560 @Override
2561 public void removeStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002562 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002563 synchronized (mGlobalLock) {
2564 final long ident = Binder.clearCallingIdentity();
2565 try {
2566 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2567 if (stack == null) {
2568 Slog.w(TAG, "removeStack: No stack with id=" + stackId);
2569 return;
2570 }
2571 if (!stack.isActivityTypeStandardOrUndefined()) {
2572 throw new IllegalArgumentException(
2573 "Removing non-standard stack is not allowed.");
2574 }
2575 mStackSupervisor.removeStack(stack);
2576 } finally {
2577 Binder.restoreCallingIdentity(ident);
2578 }
2579 }
2580 }
2581
2582 @Override
2583 public void moveStackToDisplay(int stackId, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002584 mAmInternal.enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002585
2586 synchronized (mGlobalLock) {
2587 final long ident = Binder.clearCallingIdentity();
2588 try {
2589 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
2590 + " to displayId=" + displayId);
2591 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
2592 } finally {
2593 Binder.restoreCallingIdentity(ident);
2594 }
2595 }
2596 }
2597
2598 @Override
2599 public int createStackOnDisplay(int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002600 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002601 synchronized (mGlobalLock) {
2602 final ActivityDisplay display =
2603 mStackSupervisor.getActivityDisplayOrCreateLocked(displayId);
2604 if (display == null) {
2605 return INVALID_STACK_ID;
2606 }
2607 // TODO(multi-display): Have the caller pass in the windowing mode and activity type.
2608 final ActivityStack stack = display.createStack(
2609 WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
2610 ON_TOP);
2611 return (stack != null) ? stack.mStackId : INVALID_STACK_ID;
2612 }
2613 }
2614
2615 @Override
2616 public void exitFreeformMode(IBinder token) {
2617 synchronized (mGlobalLock) {
2618 long ident = Binder.clearCallingIdentity();
2619 try {
2620 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2621 if (r == null) {
2622 throw new IllegalArgumentException(
2623 "exitFreeformMode: No activity record matching token=" + token);
2624 }
2625
2626 final ActivityStack stack = r.getStack();
2627 if (stack == null || !stack.inFreeformWindowingMode()) {
2628 throw new IllegalStateException(
2629 "exitFreeformMode: You can only go fullscreen from freeform.");
2630 }
2631
2632 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
2633 } finally {
2634 Binder.restoreCallingIdentity(ident);
2635 }
2636 }
2637 }
2638
2639 /** Sets the task stack listener that gets callbacks when a task stack changes. */
2640 @Override
2641 public void registerTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002642 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002643 "registerTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002644 mTaskChangeNotificationController.registerTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002645 }
2646
2647 /** Unregister a task stack listener so that it stops receiving callbacks. */
2648 @Override
2649 public void unregisterTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002650 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002651 "unregisterTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002652 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002653 }
2654
2655 private void reportCurKeyguardUsageEventLocked(boolean keyguardShowing) {
2656 mAm.reportGlobalUsageEventLocked(keyguardShowing
2657 ? UsageEvents.Event.KEYGUARD_SHOWN
2658 : UsageEvents.Event.KEYGUARD_HIDDEN);
2659 }
2660
2661 @Override
2662 public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
2663 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
2664 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
2665 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
2666 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
2667 }
2668
2669 @Override
2670 public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
2671 IBinder activityToken, int flags) {
2672 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
2673 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
2674 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
2675 }
2676
2677 @Override
2678 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
2679 Bundle args) {
2680 return enqueueAssistContext(requestType, intent, hint, null, null, null,
2681 true /* focused */, true /* newSessionId */, userHandle, args,
2682 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
2683 }
2684
2685 @Override
2686 public Bundle getAssistContextExtras(int requestType) {
2687 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
2688 null, null, true /* focused */, true /* newSessionId */,
2689 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
2690 if (pae == null) {
2691 return null;
2692 }
2693 synchronized (pae) {
2694 while (!pae.haveResult) {
2695 try {
2696 pae.wait();
2697 } catch (InterruptedException e) {
2698 }
2699 }
2700 }
2701 synchronized (mGlobalLock) {
2702 buildAssistBundleLocked(pae, pae.result);
2703 mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002704 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002705 }
2706 return pae.extras;
2707 }
2708
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002709 /**
2710 * Binder IPC calls go through the public entry point.
2711 * This can be called with or without the global lock held.
2712 */
2713 private static int checkCallingPermission(String permission) {
2714 return checkPermission(
2715 permission, Binder.getCallingPid(), UserHandle.getAppId(Binder.getCallingUid()));
2716 }
2717
2718 /** This can be called with or without the global lock held. */
2719 void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
2720 if (!getRecentTasks().isCallerRecents(Binder.getCallingUid())) {
2721 mAmInternal.enforceCallingPermission(permission, func);
2722 }
2723 }
2724
2725 @VisibleForTesting
2726 int checkGetTasksPermission(String permission, int pid, int uid) {
2727 return checkPermission(permission, pid, uid);
2728 }
2729
2730 static int checkPermission(String permission, int pid, int uid) {
2731 if (permission == null) {
2732 return PackageManager.PERMISSION_DENIED;
2733 }
2734 return checkComponentPermission(permission, pid, uid, -1, true);
2735 }
2736
2737 boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
2738 if (getRecentTasks().isCallerRecents(callingUid)) {
2739 // Always allow the recents component to get tasks
2740 return true;
2741 }
2742
2743 boolean allowed = checkGetTasksPermission(android.Manifest.permission.REAL_GET_TASKS,
2744 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
2745 if (!allowed) {
2746 if (checkGetTasksPermission(android.Manifest.permission.GET_TASKS,
2747 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
2748 // Temporary compatibility: some existing apps on the system image may
2749 // still be requesting the old permission and not switched to the new
2750 // one; if so, we'll still allow them full access. This means we need
2751 // to see if they are holding the old permission and are a system app.
2752 try {
2753 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
2754 allowed = true;
2755 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
2756 + " is using old GET_TASKS but privileged; allowing");
2757 }
2758 } catch (RemoteException e) {
2759 }
2760 }
2761 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
2762 + " does not hold REAL_GET_TASKS; limiting output");
2763 }
2764 return allowed;
2765 }
2766
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002767 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
2768 IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
2769 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
2770 int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002771 mAmInternal.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002772 "enqueueAssistContext()");
2773
2774 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002775 ActivityRecord activity = getFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002776 if (activity == null) {
2777 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
2778 return null;
2779 }
2780 if (activity.app == null || activity.app.thread == null) {
2781 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
2782 return null;
2783 }
2784 if (focused) {
2785 if (activityToken != null) {
2786 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
2787 if (activity != caller) {
2788 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
2789 + " is not current top " + activity);
2790 return null;
2791 }
2792 }
2793 } else {
2794 activity = ActivityRecord.forTokenLocked(activityToken);
2795 if (activity == null) {
2796 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
2797 + " couldn't be found");
2798 return null;
2799 }
2800 if (activity.app == null || activity.app.thread == null) {
2801 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
2802 return null;
2803 }
2804 }
2805
2806 PendingAssistExtras pae;
2807 Bundle extras = new Bundle();
2808 if (args != null) {
2809 extras.putAll(args);
2810 }
2811 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
2812 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
2813
2814 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
2815 userHandle);
2816 pae.isHome = activity.isActivityTypeHome();
2817
2818 // Increment the sessionId if necessary
2819 if (newSessionId) {
2820 mViSessionId++;
2821 }
2822 try {
2823 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
2824 mViSessionId, flags);
2825 mPendingAssistExtras.add(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002826 mUiHandler.postDelayed(pae, timeout);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002827 } catch (RemoteException e) {
2828 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
2829 return null;
2830 }
2831 return pae;
2832 }
2833 }
2834
2835 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
2836 if (result != null) {
2837 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
2838 }
2839 if (pae.hint != null) {
2840 pae.extras.putBoolean(pae.hint, true);
2841 }
2842 }
2843
2844 private void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
2845 IAssistDataReceiver receiver;
2846 synchronized (mGlobalLock) {
2847 mPendingAssistExtras.remove(pae);
2848 receiver = pae.receiver;
2849 }
2850 if (receiver != null) {
2851 // Caller wants result sent back to them.
2852 Bundle sendBundle = new Bundle();
2853 // At least return the receiver extras
2854 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
2855 try {
2856 pae.receiver.onHandleAssistData(sendBundle);
2857 } catch (RemoteException e) {
2858 }
2859 }
2860 }
2861
2862 public class PendingAssistExtras extends Binder implements Runnable {
2863 public final ActivityRecord activity;
2864 public boolean isHome;
2865 public final Bundle extras;
2866 public final Intent intent;
2867 public final String hint;
2868 public final IAssistDataReceiver receiver;
2869 public final int userHandle;
2870 public boolean haveResult = false;
2871 public Bundle result = null;
2872 public AssistStructure structure = null;
2873 public AssistContent content = null;
2874 public Bundle receiverExtras;
2875
2876 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
2877 String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
2878 int _userHandle) {
2879 activity = _activity;
2880 extras = _extras;
2881 intent = _intent;
2882 hint = _hint;
2883 receiver = _receiver;
2884 receiverExtras = _receiverExtras;
2885 userHandle = _userHandle;
2886 }
2887
2888 @Override
2889 public void run() {
2890 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
2891 synchronized (this) {
2892 haveResult = true;
2893 notifyAll();
2894 }
2895 pendingAssistExtrasTimedOut(this);
2896 }
2897 }
2898
2899 @Override
2900 public boolean isAssistDataAllowedOnCurrentActivity() {
2901 int userId;
2902 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002903 final ActivityStack focusedStack = getFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002904 if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
2905 return false;
2906 }
2907
2908 final ActivityRecord activity = focusedStack.getTopActivity();
2909 if (activity == null) {
2910 return false;
2911 }
2912 userId = activity.userId;
2913 }
2914 return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
2915 }
2916
2917 @Override
2918 public boolean showAssistFromActivity(IBinder token, Bundle args) {
2919 long ident = Binder.clearCallingIdentity();
2920 try {
2921 synchronized (mGlobalLock) {
2922 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002923 ActivityRecord top = getFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002924 if (top != caller) {
2925 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
2926 + " is not current top " + top);
2927 return false;
2928 }
2929 if (!top.nowVisible) {
2930 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
2931 + " is not visible");
2932 return false;
2933 }
2934 }
2935 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
2936 token);
2937 } finally {
2938 Binder.restoreCallingIdentity(ident);
2939 }
2940 }
2941
2942 @Override
2943 public boolean isRootVoiceInteraction(IBinder token) {
2944 synchronized (mGlobalLock) {
2945 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2946 if (r == null) {
2947 return false;
2948 }
2949 return r.rootVoiceInteraction;
2950 }
2951 }
2952
2953 @Override
2954 public ComponentName getActivityClassForToken(IBinder token) {
2955 synchronized (mGlobalLock) {
2956 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2957 if (r == null) {
2958 return null;
2959 }
2960 return r.intent.getComponent();
2961 }
2962 }
2963
2964 @Override
2965 public String getPackageForToken(IBinder token) {
2966 synchronized (mGlobalLock) {
2967 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2968 if (r == null) {
2969 return null;
2970 }
2971 return r.packageName;
2972 }
2973 }
2974
2975 @Override
2976 public void showLockTaskEscapeMessage(IBinder token) {
2977 synchronized (mGlobalLock) {
2978 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2979 if (r == null) {
2980 return;
2981 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002982 getLockTaskController().showLockTaskToast();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002983 }
2984 }
2985
2986 @Override
2987 public void keyguardGoingAway(int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002988 enforceNotIsolatedCaller("keyguardGoingAway");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002989 final long token = Binder.clearCallingIdentity();
2990 try {
2991 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002992 mKeyguardController.keyguardGoingAway(flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002993 }
2994 } finally {
2995 Binder.restoreCallingIdentity(token);
2996 }
2997 }
2998
2999 /**
3000 * Try to place task to provided position. The final position might be different depending on
3001 * current user and stacks state. The task will be moved to target stack if it's currently in
3002 * different stack.
3003 */
3004 @Override
3005 public void positionTaskInStack(int taskId, int stackId, int position) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003006 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003007 synchronized (mGlobalLock) {
3008 long ident = Binder.clearCallingIdentity();
3009 try {
3010 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
3011 + taskId + " in stackId=" + stackId + " at position=" + position);
3012 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3013 if (task == null) {
3014 throw new IllegalArgumentException("positionTaskInStack: no task for id="
3015 + taskId);
3016 }
3017
3018 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3019
3020 if (stack == null) {
3021 throw new IllegalArgumentException("positionTaskInStack: no stack for id="
3022 + stackId);
3023 }
3024 if (!stack.isActivityTypeStandardOrUndefined()) {
3025 throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
3026 + " the position of task " + taskId + " in/to non-standard stack");
3027 }
3028
3029 // TODO: Have the callers of this API call a separate reparent method if that is
3030 // what they intended to do vs. having this method also do reparenting.
3031 if (task.getStack() == stack) {
3032 // Change position in current stack.
3033 stack.positionChildAt(task, position);
3034 } else {
3035 // Reparent to new stack.
3036 task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
3037 !DEFER_RESUME, "positionTaskInStack");
3038 }
3039 } finally {
3040 Binder.restoreCallingIdentity(ident);
3041 }
3042 }
3043 }
3044
3045 @Override
3046 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
3047 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
3048 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
3049 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
3050 synchronized (mGlobalLock) {
3051 ActivityRecord record = ActivityRecord.isInStackLocked(token);
3052 if (record == null) {
3053 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
3054 + "found for: " + token);
3055 }
3056 record.setSizeConfigurations(horizontalSizeConfiguration,
3057 verticalSizeConfigurations, smallestSizeConfigurations);
3058 }
3059 }
3060
3061 /**
3062 * Dismisses split-screen multi-window mode.
3063 * @param toTop If true the current primary split-screen stack will be placed or left on top.
3064 */
3065 @Override
3066 public void dismissSplitScreenMode(boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003067 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003068 MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
3069 final long ident = Binder.clearCallingIdentity();
3070 try {
3071 synchronized (mGlobalLock) {
3072 final ActivityStack stack =
3073 mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
3074 if (stack == null) {
3075 Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
3076 return;
3077 }
3078
3079 if (toTop) {
3080 // Caller wants the current split-screen primary stack to be the top stack after
3081 // it goes fullscreen, so move it to the front.
3082 stack.moveToFront("dismissSplitScreenMode");
3083 } else if (mStackSupervisor.isFocusedStack(stack)) {
3084 // In this case the current split-screen primary stack shouldn't be the top
3085 // stack after it goes fullscreen, but it current has focus, so we move the
3086 // focus to the top-most split-screen secondary stack next to it.
3087 final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
3088 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
3089 if (otherStack != null) {
3090 otherStack.moveToFront("dismissSplitScreenMode_other");
3091 }
3092 }
3093
3094 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
3095 }
3096 } finally {
3097 Binder.restoreCallingIdentity(ident);
3098 }
3099 }
3100
3101 /**
3102 * Dismisses Pip
3103 * @param animate True if the dismissal should be animated.
3104 * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
3105 * default animation duration should be used.
3106 */
3107 @Override
3108 public void dismissPip(boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003109 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003110 final long ident = Binder.clearCallingIdentity();
3111 try {
3112 synchronized (mGlobalLock) {
3113 final PinnedActivityStack stack =
3114 mStackSupervisor.getDefaultDisplay().getPinnedStack();
3115 if (stack == null) {
3116 Slog.w(TAG, "dismissPip: pinned stack not found.");
3117 return;
3118 }
3119 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
3120 throw new IllegalArgumentException("Stack: " + stack
3121 + " doesn't support animated resize.");
3122 }
3123 if (animate) {
3124 stack.animateResizePinnedStack(null /* sourceHintBounds */,
3125 null /* destBounds */, animationDuration, false /* fromFullscreen */);
3126 } else {
3127 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
3128 }
3129 }
3130 } finally {
3131 Binder.restoreCallingIdentity(ident);
3132 }
3133 }
3134
3135 @Override
3136 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003137 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003138 synchronized (mGlobalLock) {
3139 mSuppressResizeConfigChanges = suppress;
3140 }
3141 }
3142
3143 /**
3144 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
3145 * animated the stack to the fullscreen, but can also be called if we are relaunching an
3146 * activity and clearing the task at the same time.
3147 */
3148 @Override
3149 // TODO: API should just be about changing windowing modes...
3150 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003151 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003152 "moveTasksToFullscreenStack()");
3153 synchronized (mGlobalLock) {
3154 final long origId = Binder.clearCallingIdentity();
3155 try {
3156 final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
3157 if (stack != null){
3158 if (!stack.isActivityTypeStandardOrUndefined()) {
3159 throw new IllegalArgumentException(
3160 "You can't move tasks from non-standard stacks.");
3161 }
3162 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
3163 }
3164 } finally {
3165 Binder.restoreCallingIdentity(origId);
3166 }
3167 }
3168 }
3169
3170 /**
3171 * Moves the top activity in the input stackId to the pinned stack.
3172 *
3173 * @param stackId Id of stack to move the top activity to pinned stack.
3174 * @param bounds Bounds to use for pinned stack.
3175 *
3176 * @return True if the top activity of the input stack was successfully moved to the pinned
3177 * stack.
3178 */
3179 @Override
3180 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003181 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003182 "moveTopActivityToPinnedStack()");
3183 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003184 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003185 throw new IllegalStateException("moveTopActivityToPinnedStack:"
3186 + "Device doesn't support picture-in-picture mode");
3187 }
3188
3189 long ident = Binder.clearCallingIdentity();
3190 try {
3191 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
3192 } finally {
3193 Binder.restoreCallingIdentity(ident);
3194 }
3195 }
3196 }
3197
3198 @Override
3199 public boolean isInMultiWindowMode(IBinder token) {
3200 final long origId = Binder.clearCallingIdentity();
3201 try {
3202 synchronized (mGlobalLock) {
3203 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3204 if (r == null) {
3205 return false;
3206 }
3207 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
3208 return r.inMultiWindowMode();
3209 }
3210 } finally {
3211 Binder.restoreCallingIdentity(origId);
3212 }
3213 }
3214
3215 @Override
3216 public boolean isInPictureInPictureMode(IBinder token) {
3217 final long origId = Binder.clearCallingIdentity();
3218 try {
3219 synchronized (mGlobalLock) {
3220 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
3221 }
3222 } finally {
3223 Binder.restoreCallingIdentity(origId);
3224 }
3225 }
3226
3227 private boolean isInPictureInPictureMode(ActivityRecord r) {
3228 if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
3229 || r.getStack().isInStackLocked(r) == null) {
3230 return false;
3231 }
3232
3233 // If we are animating to fullscreen then we have already dispatched the PIP mode
3234 // changed, so we should reflect that check here as well.
3235 final PinnedActivityStack stack = r.getStack();
3236 final PinnedStackWindowController windowController = stack.getWindowContainerController();
3237 return !windowController.isAnimatingBoundsToFullscreen();
3238 }
3239
3240 @Override
3241 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
3242 final long origId = Binder.clearCallingIdentity();
3243 try {
3244 synchronized (mGlobalLock) {
3245 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3246 "enterPictureInPictureMode", token, params);
3247
3248 // If the activity is already in picture in picture mode, then just return early
3249 if (isInPictureInPictureMode(r)) {
3250 return true;
3251 }
3252
3253 // Activity supports picture-in-picture, now check that we can enter PiP at this
3254 // point, if it is
3255 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
3256 false /* beforeStopping */)) {
3257 return false;
3258 }
3259
3260 final Runnable enterPipRunnable = () -> {
Wale Ogunwalef276a6f2018-06-15 08:26:07 -07003261 synchronized (mGlobalLock) {
3262 // Only update the saved args from the args that are set
3263 r.pictureInPictureArgs.copyOnlySet(params);
3264 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
3265 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
3266 // Adjust the source bounds by the insets for the transition down
3267 final Rect sourceBounds = new Rect(
3268 r.pictureInPictureArgs.getSourceRectHint());
3269 mStackSupervisor.moveActivityToPinnedStackLocked(
3270 r, sourceBounds, aspectRatio, "enterPictureInPictureMode");
3271 final PinnedActivityStack stack = r.getStack();
3272 stack.setPictureInPictureAspectRatio(aspectRatio);
3273 stack.setPictureInPictureActions(actions);
3274 MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
3275 r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
3276 logPictureInPictureArgs(params);
3277 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003278 };
3279
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003280 if (isKeyguardLocked()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003281 // If the keyguard is showing or occluded, then try and dismiss it before
3282 // entering picture-in-picture (this will prompt the user to authenticate if the
3283 // device is currently locked).
3284 dismissKeyguard(token, new KeyguardDismissCallback() {
3285 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003286 public void onDismissSucceeded() {
3287 mH.post(enterPipRunnable);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003288 }
3289 }, null /* message */);
3290 } else {
3291 // Enter picture in picture immediately otherwise
3292 enterPipRunnable.run();
3293 }
3294 return true;
3295 }
3296 } finally {
3297 Binder.restoreCallingIdentity(origId);
3298 }
3299 }
3300
3301 @Override
3302 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
3303 final long origId = Binder.clearCallingIdentity();
3304 try {
3305 synchronized (mGlobalLock) {
3306 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3307 "setPictureInPictureParams", token, params);
3308
3309 // Only update the saved args from the args that are set
3310 r.pictureInPictureArgs.copyOnlySet(params);
3311 if (r.inPinnedWindowingMode()) {
3312 // If the activity is already in picture-in-picture, update the pinned stack now
3313 // if it is not already expanding to fullscreen. Otherwise, the arguments will
3314 // be used the next time the activity enters PiP
3315 final PinnedActivityStack stack = r.getStack();
3316 if (!stack.isAnimatingBoundsToFullscreen()) {
3317 stack.setPictureInPictureAspectRatio(
3318 r.pictureInPictureArgs.getAspectRatio());
3319 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
3320 }
3321 }
3322 logPictureInPictureArgs(params);
3323 }
3324 } finally {
3325 Binder.restoreCallingIdentity(origId);
3326 }
3327 }
3328
3329 @Override
3330 public int getMaxNumPictureInPictureActions(IBinder token) {
3331 // Currently, this is a static constant, but later, we may change this to be dependent on
3332 // the context of the activity
3333 return 3;
3334 }
3335
3336 private void logPictureInPictureArgs(PictureInPictureParams params) {
3337 if (params.hasSetActions()) {
3338 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
3339 params.getActions().size());
3340 }
3341 if (params.hasSetAspectRatio()) {
3342 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
3343 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
3344 MetricsLogger.action(lm);
3345 }
3346 }
3347
3348 /**
3349 * Checks the state of the system and the activity associated with the given {@param token} to
3350 * verify that picture-in-picture is supported for that activity.
3351 *
3352 * @return the activity record for the given {@param token} if all the checks pass.
3353 */
3354 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
3355 IBinder token, PictureInPictureParams params) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003356 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003357 throw new IllegalStateException(caller
3358 + ": Device doesn't support picture-in-picture mode.");
3359 }
3360
3361 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3362 if (r == null) {
3363 throw new IllegalStateException(caller
3364 + ": Can't find activity for token=" + token);
3365 }
3366
3367 if (!r.supportsPictureInPicture()) {
3368 throw new IllegalStateException(caller
3369 + ": Current activity does not support picture-in-picture.");
3370 }
3371
3372 if (params.hasSetAspectRatio()
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003373 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003374 params.getAspectRatio())) {
3375 final float minAspectRatio = mContext.getResources().getFloat(
3376 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
3377 final float maxAspectRatio = mContext.getResources().getFloat(
3378 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
3379 throw new IllegalArgumentException(String.format(caller
3380 + ": Aspect ratio is too extreme (must be between %f and %f).",
3381 minAspectRatio, maxAspectRatio));
3382 }
3383
3384 // Truncate the number of actions if necessary
3385 params.truncateActions(getMaxNumPictureInPictureActions(token));
3386
3387 return r;
3388 }
3389
3390 @Override
3391 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003392 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003393 synchronized (mGlobalLock) {
3394 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
3395 if (r == null) {
3396 throw new IllegalArgumentException("Activity does not exist; token="
3397 + activityToken);
3398 }
3399 return r.getUriPermissionsLocked().getExternalTokenLocked();
3400 }
3401 }
3402
3403 @Override
3404 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
3405 Rect tempDockedTaskInsetBounds,
3406 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003407 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003408 long ident = Binder.clearCallingIdentity();
3409 try {
3410 synchronized (mGlobalLock) {
3411 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
3412 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
3413 PRESERVE_WINDOWS);
3414 }
3415 } finally {
3416 Binder.restoreCallingIdentity(ident);
3417 }
3418 }
3419
3420 @Override
3421 public void setSplitScreenResizing(boolean resizing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003422 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003423 final long ident = Binder.clearCallingIdentity();
3424 try {
3425 synchronized (mGlobalLock) {
3426 mStackSupervisor.setSplitScreenResizing(resizing);
3427 }
3428 } finally {
3429 Binder.restoreCallingIdentity(ident);
3430 }
3431 }
3432
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003433 /**
3434 * Check that we have the features required for VR-related API calls, and throw an exception if
3435 * not.
3436 */
3437 void enforceSystemHasVrFeature() {
3438 if (!mContext.getPackageManager().hasSystemFeature(
3439 PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
3440 throw new UnsupportedOperationException("VR mode not supported on this device!");
3441 }
3442 }
3443
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003444 @Override
3445 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003446 enforceSystemHasVrFeature();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003447
3448 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3449
3450 ActivityRecord r;
3451 synchronized (mGlobalLock) {
3452 r = ActivityRecord.isInStackLocked(token);
3453 }
3454
3455 if (r == null) {
3456 throw new IllegalArgumentException();
3457 }
3458
3459 int err;
3460 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
3461 VrManagerInternal.NO_ERROR) {
3462 return err;
3463 }
3464
3465 // Clear the binder calling uid since this path may call moveToTask().
3466 final long callingId = Binder.clearCallingIdentity();
3467 try {
3468 synchronized (mGlobalLock) {
3469 r.requestedVrComponent = (enabled) ? packageName : null;
3470
3471 // Update associated state if this activity is currently focused
3472 if (r == mStackSupervisor.getResumedActivityLocked()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003473 applyUpdateVrModeLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003474 }
3475 return 0;
3476 }
3477 } finally {
3478 Binder.restoreCallingIdentity(callingId);
3479 }
3480 }
3481
3482 @Override
3483 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
3484 Slog.i(TAG, "Activity tried to startLocalVoiceInteraction");
3485 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003486 ActivityRecord activity = getFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003487 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
3488 throw new SecurityException("Only focused activity can call startVoiceInteraction");
3489 }
3490 if (mAm.mRunningVoice != null || activity.getTask().voiceSession != null
3491 || activity.voiceSession != null) {
3492 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
3493 return;
3494 }
3495 if (activity.pendingVoiceInteractionStart) {
3496 Slog.w(TAG, "Pending start of voice interaction already.");
3497 return;
3498 }
3499 activity.pendingVoiceInteractionStart = true;
3500 }
3501 LocalServices.getService(VoiceInteractionManagerInternal.class)
3502 .startLocalVoiceInteraction(callingActivity, options);
3503 }
3504
3505 @Override
3506 public void stopLocalVoiceInteraction(IBinder callingActivity) {
3507 LocalServices.getService(VoiceInteractionManagerInternal.class)
3508 .stopLocalVoiceInteraction(callingActivity);
3509 }
3510
3511 @Override
3512 public boolean supportsLocalVoiceInteraction() {
3513 return LocalServices.getService(VoiceInteractionManagerInternal.class)
3514 .supportsLocalVoiceInteraction();
3515 }
3516
3517 /** Notifies all listeners when the pinned stack animation starts. */
3518 @Override
3519 public void notifyPinnedStackAnimationStarted() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003520 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003521 }
3522
3523 /** Notifies all listeners when the pinned stack animation ends. */
3524 @Override
3525 public void notifyPinnedStackAnimationEnded() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003526 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003527 }
3528
3529 @Override
3530 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003531 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003532 final long ident = Binder.clearCallingIdentity();
3533 try {
3534 synchronized (mGlobalLock) {
3535 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
3536 }
3537 } finally {
3538 Binder.restoreCallingIdentity(ident);
3539 }
3540 }
3541
3542 @Override
3543 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003544 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003545
3546 synchronized (mGlobalLock) {
3547 // Check if display is initialized in AM.
3548 if (!mStackSupervisor.isDisplayAdded(displayId)) {
3549 // Call might come when display is not yet added or has already been removed.
3550 if (DEBUG_CONFIGURATION) {
3551 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
3552 + displayId);
3553 }
3554 return false;
3555 }
3556
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003557 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003558 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003559 values = mWindowManager.computeNewConfiguration(displayId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003560 }
3561
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003562 if (mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003563 // Update OOM levels based on display size.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003564 mAm.mProcessList.applyDisplaySize(mWindowManager);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003565 }
3566
3567 final long origId = Binder.clearCallingIdentity();
3568 try {
3569 if (values != null) {
3570 Settings.System.clearConfiguration(values);
3571 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003572 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003573 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
3574 return mTmpUpdateConfigurationResult.changes != 0;
3575 } finally {
3576 Binder.restoreCallingIdentity(origId);
3577 }
3578 }
3579 }
3580
3581 @Override
3582 public boolean updateConfiguration(Configuration values) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003583 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003584
3585 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003586 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003587 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003588 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003589 }
3590
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003591 if (mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003592 // Update OOM levels based on display size.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003593 mAm.mProcessList.applyDisplaySize(mWindowManager);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003594 }
3595
3596 final long origId = Binder.clearCallingIdentity();
3597 try {
3598 if (values != null) {
3599 Settings.System.clearConfiguration(values);
3600 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003601 updateConfigurationLocked(values, null, false, false /* persistent */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003602 UserHandle.USER_NULL, false /* deferResume */,
3603 mTmpUpdateConfigurationResult);
3604 return mTmpUpdateConfigurationResult.changes != 0;
3605 } finally {
3606 Binder.restoreCallingIdentity(origId);
3607 }
3608 }
3609 }
3610
3611 @Override
3612 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
3613 CharSequence message) {
3614 if (message != null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003615 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003616 Manifest.permission.SHOW_KEYGUARD_MESSAGE, "dismissKeyguard()");
3617 }
3618 final long callingId = Binder.clearCallingIdentity();
3619 try {
3620 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003621 mKeyguardController.dismissKeyguard(token, callback, message);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003622 }
3623 } finally {
3624 Binder.restoreCallingIdentity(callingId);
3625 }
3626 }
3627
3628 @Override
3629 public void cancelTaskWindowTransition(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003630 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003631 "cancelTaskWindowTransition()");
3632 final long ident = Binder.clearCallingIdentity();
3633 try {
3634 synchronized (mGlobalLock) {
3635 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
3636 MATCH_TASK_IN_STACKS_ONLY);
3637 if (task == null) {
3638 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
3639 return;
3640 }
3641 task.cancelWindowTransition();
3642 }
3643 } finally {
3644 Binder.restoreCallingIdentity(ident);
3645 }
3646 }
3647
3648 @Override
3649 public ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003650 enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003651 final long ident = Binder.clearCallingIdentity();
3652 try {
3653 final TaskRecord task;
3654 synchronized (mGlobalLock) {
3655 task = mStackSupervisor.anyTaskForIdLocked(taskId,
3656 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
3657 if (task == null) {
3658 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
3659 return null;
3660 }
3661 }
3662 // Don't call this while holding the lock as this operation might hit the disk.
3663 return task.getSnapshot(reducedResolution);
3664 } finally {
3665 Binder.restoreCallingIdentity(ident);
3666 }
3667 }
3668
3669 @Override
3670 public void setDisablePreviewScreenshots(IBinder token, boolean disable) {
3671 synchronized (mGlobalLock) {
3672 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3673 if (r == null) {
3674 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
3675 + token);
3676 return;
3677 }
3678 final long origId = Binder.clearCallingIdentity();
3679 try {
3680 r.setDisablePreviewScreenshots(disable);
3681 } finally {
3682 Binder.restoreCallingIdentity(origId);
3683 }
3684 }
3685 }
3686
3687 /** Return the user id of the last resumed activity. */
3688 @Override
3689 public @UserIdInt
3690 int getLastResumedActivityUserId() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003691 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003692 Manifest.permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
3693 synchronized (mGlobalLock) {
3694 if (mAm.mLastResumedActivity == null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003695 return getCurrentUserId();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003696 }
3697 return mAm.mLastResumedActivity.userId;
3698 }
3699 }
3700
3701 @Override
3702 public void updateLockTaskFeatures(int userId, int flags) {
3703 final int callingUid = Binder.getCallingUid();
3704 if (callingUid != 0 && callingUid != SYSTEM_UID) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003705 mAmInternal.enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003706 "updateLockTaskFeatures()");
3707 }
3708 synchronized (mGlobalLock) {
3709 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
3710 Integer.toHexString(flags));
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003711 getLockTaskController().updateLockTaskFeatures(userId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003712 }
3713 }
3714
3715 @Override
3716 public void setShowWhenLocked(IBinder token, boolean showWhenLocked) {
3717 synchronized (mGlobalLock) {
3718 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3719 if (r == null) {
3720 return;
3721 }
3722 final long origId = Binder.clearCallingIdentity();
3723 try {
3724 r.setShowWhenLocked(showWhenLocked);
3725 } finally {
3726 Binder.restoreCallingIdentity(origId);
3727 }
3728 }
3729 }
3730
3731 @Override
3732 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) {
3733 synchronized (mGlobalLock) {
3734 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3735 if (r == null) {
3736 return;
3737 }
3738 final long origId = Binder.clearCallingIdentity();
3739 try {
3740 r.setTurnScreenOn(turnScreenOn);
3741 } finally {
3742 Binder.restoreCallingIdentity(origId);
3743 }
3744 }
3745 }
3746
3747 @Override
3748 public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003749 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003750 "registerRemoteAnimations");
3751 definition.setCallingPid(Binder.getCallingPid());
3752 synchronized (mGlobalLock) {
3753 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3754 if (r == null) {
3755 return;
3756 }
3757 final long origId = Binder.clearCallingIdentity();
3758 try {
3759 r.registerRemoteAnimations(definition);
3760 } finally {
3761 Binder.restoreCallingIdentity(origId);
3762 }
3763 }
3764 }
3765
3766 @Override
3767 public void registerRemoteAnimationForNextActivityStart(String packageName,
3768 RemoteAnimationAdapter adapter) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003769 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003770 "registerRemoteAnimationForNextActivityStart");
3771 adapter.setCallingPid(Binder.getCallingPid());
3772 synchronized (mGlobalLock) {
3773 final long origId = Binder.clearCallingIdentity();
3774 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07003775 getActivityStartController().registerRemoteAnimationForNextActivityStart(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003776 packageName, adapter);
3777 } finally {
3778 Binder.restoreCallingIdentity(origId);
3779 }
3780 }
3781 }
3782
3783 /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
3784 @Override
3785 public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
3786 synchronized (mGlobalLock) {
3787 final long origId = Binder.clearCallingIdentity();
3788 try {
3789 mAm.mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
3790 } finally {
3791 Binder.restoreCallingIdentity(origId);
3792 }
3793 }
3794 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07003795
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003796 @Override
3797 public void setVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003798 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003799 synchronized (mGlobalLock) {
3800 synchronized (mAm.mPidsSelfLocked) {
3801 final int pid = Binder.getCallingPid();
3802 final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
3803 mVrController.setVrThreadLocked(tid, pid, proc);
3804 }
3805 }
3806 }
3807
3808 @Override
3809 public void setPersistentVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003810 if (checkCallingPermission(Manifest.permission.RESTRICTED_VR_ACCESS)
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003811 != PERMISSION_GRANTED) {
3812 final String msg = "Permission Denial: setPersistentVrThread() from pid="
3813 + Binder.getCallingPid()
3814 + ", uid=" + Binder.getCallingUid()
3815 + " requires " + Manifest.permission.RESTRICTED_VR_ACCESS;
3816 Slog.w(TAG, msg);
3817 throw new SecurityException(msg);
3818 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003819 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003820 synchronized (mGlobalLock) {
3821 synchronized (mAm.mPidsSelfLocked) {
3822 final int pid = Binder.getCallingPid();
3823 final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
3824 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
3825 }
3826 }
3827 }
3828
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003829 @Override
3830 public void stopAppSwitches() {
3831 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
3832 synchronized (mGlobalLock) {
3833 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME;
3834 mDidAppSwitch = false;
3835 getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
3836 }
3837 }
3838
3839 @Override
3840 public void resumeAppSwitches() {
3841 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
3842 synchronized (mGlobalLock) {
3843 // Note that we don't execute any pending app switches... we will
3844 // let those wait until either the timeout, or the next start
3845 // activity request.
3846 mAppSwitchesAllowedTime = 0;
3847 }
3848 }
3849
3850 void onStartActivitySetDidAppSwitch() {
3851 if (mDidAppSwitch) {
3852 // This is the second allowed switch since we stopped switches, so now just generally
3853 // allow switches. Use case:
3854 // - user presses home (switches disabled, switch to home, mDidAppSwitch now true);
3855 // - user taps a home icon (coming from home so allowed, we hit here and now allow
3856 // anyone to switch again).
3857 mAppSwitchesAllowedTime = 0;
3858 } else {
3859 mDidAppSwitch = true;
3860 }
3861 }
3862
3863 /** @return whether the system should disable UI modes incompatible with VR mode. */
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003864 boolean shouldDisableNonVrUiLocked() {
3865 return mVrController.shouldDisableNonVrUiLocked();
3866 }
3867
3868 void applyUpdateVrModeLocked(ActivityRecord r) {
3869 // VR apps are expected to run in a main display. If an app is turning on VR for
3870 // itself, but lives in a dynamic stack, then make sure that it is moved to the main
3871 // fullscreen stack before enabling VR Mode.
3872 // TODO: The goal of this code is to keep the VR app on the main display. When the
3873 // stack implementation changes in the future, keep in mind that the use of the fullscreen
3874 // stack is a means to move the activity to the main display and a moveActivityToDisplay()
3875 // option would be a better choice here.
3876 if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
3877 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
3878 + " to main stack for VR");
3879 final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
3880 WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
3881 moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
3882 }
3883 mH.post(() -> {
3884 if (!mVrController.onVrModeChanged(r)) {
3885 return;
3886 }
3887 synchronized (mGlobalLock) {
3888 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
3889 mWindowManager.disableNonVrUi(disableNonVrUi);
3890 if (disableNonVrUi) {
3891 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
3892 // then remove the pinned stack.
3893 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
3894 }
3895 }
3896 });
3897 }
3898
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003899 ActivityStack getFocusedStack() {
3900 return mStackSupervisor.getFocusedStack();
3901 }
3902
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003903 /** Pokes the task persister. */
3904 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
3905 mRecentTasks.notifyTaskPersisterLocked(task, flush);
3906 }
3907
3908 void onTopProcChangedLocked(ProcessRecord proc) {
3909 mVrController.onTopProcChangedLocked(proc);
3910 }
3911
3912 boolean isKeyguardLocked() {
3913 return mKeyguardController.isKeyguardLocked();
3914 }
3915
3916 boolean isNextTransitionForward() {
3917 int transit = mWindowManager.getPendingAppTransition();
3918 return transit == TRANSIT_ACTIVITY_OPEN
3919 || transit == TRANSIT_TASK_OPEN
3920 || transit == TRANSIT_TASK_TO_FRONT;
3921 }
3922
3923 void dumpVrControllerLocked(PrintWriter pw) {
3924 pw.println(" mVrController=" + mVrController);
3925 }
3926
3927 void writeVrControllerToProto(ProtoOutputStream proto, long fieldId) {
3928 mVrController.writeToProto(proto, fieldId);
3929 }
3930
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003931 int getCurrentUserId() {
3932 return mAmInternal.getCurrentUserId();
3933 }
3934
3935 private void enforceNotIsolatedCaller(String caller) {
3936 if (UserHandle.isIsolated(Binder.getCallingUid())) {
3937 throw new SecurityException("Isolated process not allowed to call " + caller);
3938 }
3939 }
3940
3941 /**
3942 * Current global configuration information. Contains general settings for the entire system,
3943 * also corresponds to the merged configuration of the default display.
3944 */
3945 Configuration getGlobalConfiguration() {
3946 return mStackSupervisor.getConfiguration();
3947 }
3948
3949 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
3950 boolean initLocale) {
3951 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
3952 }
3953
3954 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
3955 boolean initLocale, boolean deferResume) {
3956 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
3957 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
3958 UserHandle.USER_NULL, deferResume);
3959 }
3960
3961 void updatePersistentConfiguration(Configuration values, @UserIdInt int userId) {
3962 final long origId = Binder.clearCallingIdentity();
3963 try {
3964 synchronized (mGlobalLock) {
3965 updateConfigurationLocked(values, null, false, true, userId,
3966 false /* deferResume */);
3967 }
3968 } finally {
3969 Binder.restoreCallingIdentity(origId);
3970 }
3971 }
3972
3973 void updateUserConfiguration() {
3974 synchronized (mGlobalLock) {
3975 final Configuration configuration = new Configuration(getGlobalConfiguration());
3976 final int currentUserId = mAmInternal.getCurrentUserId();
3977 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
3978 currentUserId, Settings.System.canWrite(mContext));
3979 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
3980 false /* persistent */, currentUserId, false /* deferResume */);
3981 }
3982 }
3983
3984 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
3985 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
3986 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
3987 deferResume, null /* result */);
3988 }
3989
3990 /**
3991 * Do either or both things: (1) change the current configuration, and (2)
3992 * make sure the given activity is running with the (now) current
3993 * configuration. Returns true if the activity has been left running, or
3994 * false if <var>starting</var> is being destroyed to match the new
3995 * configuration.
3996 *
3997 * @param userId is only used when persistent parameter is set to true to persist configuration
3998 * for that particular user
3999 */
4000 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4001 boolean initLocale, boolean persistent, int userId, boolean deferResume,
4002 ActivityTaskManagerService.UpdateConfigurationResult result) {
4003 int changes = 0;
4004 boolean kept = true;
4005
4006 if (mWindowManager != null) {
4007 mWindowManager.deferSurfaceLayout();
4008 }
4009 try {
4010 if (values != null) {
4011 changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
4012 deferResume);
4013 }
4014
4015 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4016 } finally {
4017 if (mWindowManager != null) {
4018 mWindowManager.continueSurfaceLayout();
4019 }
4020 }
4021
4022 if (result != null) {
4023 result.changes = changes;
4024 result.activityRelaunched = !kept;
4025 }
4026 return kept;
4027 }
4028
4029 /**
4030 * Returns true if this configuration change is interesting enough to send an
4031 * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
4032 */
4033 private static boolean isSplitConfigurationChange(int configDiff) {
4034 return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
4035 }
4036
4037 /** Update default (global) configuration and notify listeners about changes. */
4038 private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
4039 boolean persistent, int userId, boolean deferResume) {
4040 mTempConfig.setTo(getGlobalConfiguration());
4041 final int changes = mTempConfig.updateFrom(values);
4042 if (changes == 0) {
4043 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
4044 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
4045 // performDisplayOverrideConfigUpdate in order to send the new display configuration
4046 // (even if there are no actual changes) to unfreeze the window.
4047 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
4048 return 0;
4049 }
4050
4051 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
4052 "Updating global configuration to: " + values);
4053
4054 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
4055 StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
4056 values.colorMode,
4057 values.densityDpi,
4058 values.fontScale,
4059 values.hardKeyboardHidden,
4060 values.keyboard,
4061 values.keyboardHidden,
4062 values.mcc,
4063 values.mnc,
4064 values.navigation,
4065 values.navigationHidden,
4066 values.orientation,
4067 values.screenHeightDp,
4068 values.screenLayout,
4069 values.screenWidthDp,
4070 values.smallestScreenWidthDp,
4071 values.touchscreen,
4072 values.uiMode);
4073
4074
4075 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
4076 final LocaleList locales = values.getLocales();
4077 int bestLocaleIndex = 0;
4078 if (locales.size() > 1) {
4079 if (mSupportedSystemLocales == null) {
4080 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
4081 }
4082 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
4083 }
4084 SystemProperties.set("persist.sys.locale",
4085 locales.get(bestLocaleIndex).toLanguageTag());
4086 LocaleList.setDefault(locales, bestLocaleIndex);
4087 mAm.mHandler.sendMessage(mAm.mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
4088 locales.get(bestLocaleIndex)));
4089 }
4090
4091 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
4092 mTempConfig.seq = mConfigurationSeq;
4093
4094 // Update stored global config and notify everyone about the change.
4095 mStackSupervisor.onConfigurationChanged(mTempConfig);
4096
4097 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
4098 // TODO(multi-display): Update UsageEvents#Event to include displayId.
4099 mAm.mUsageStatsService.reportConfigurationChange(
4100 mTempConfig, mAmInternal.getCurrentUserId());
4101
4102 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
4103 mAm.updateShouldShowDialogsLocked(mTempConfig);
4104
4105 AttributeCache ac = AttributeCache.instance();
4106 if (ac != null) {
4107 ac.updateConfiguration(mTempConfig);
4108 }
4109
4110 // Make sure all resources in our process are updated right now, so that anyone who is going
4111 // to retrieve resource values after we return will be sure to get the new ones. This is
4112 // especially important during boot, where the first config change needs to guarantee all
4113 // resources have that config before following boot code is executed.
4114 mAm.mSystemThread.applyConfigurationToResources(mTempConfig);
4115
4116 // We need another copy of global config because we're scheduling some calls instead of
4117 // running them in place. We need to be sure that object we send will be handled unchanged.
4118 final Configuration configCopy = new Configuration(mTempConfig);
4119 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
4120 Message msg = mAm.mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
4121 msg.obj = configCopy;
4122 msg.arg1 = userId;
4123 mAm.mHandler.sendMessage(msg);
4124 }
4125
4126 for (int i = mAm.mLruProcesses.size() - 1; i >= 0; i--) {
4127 ProcessRecord app = mAm.mLruProcesses.get(i);
4128 try {
4129 if (app.thread != null) {
4130 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
4131 + app.processName + " new config " + configCopy);
4132 getLifecycleManager().scheduleTransaction(app.thread,
4133 ConfigurationChangeItem.obtain(configCopy));
4134 }
4135 } catch (Exception e) {
4136 Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
4137 }
4138 }
4139
4140 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
4141 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
4142 | Intent.FLAG_RECEIVER_FOREGROUND
4143 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4144 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4145 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4146 UserHandle.USER_ALL);
4147 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
4148 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
4149 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
4150 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
4151 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4152 if (initLocale || !mAm.mProcessesReady) {
4153 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
4154 }
4155 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4156 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4157 UserHandle.USER_ALL);
4158 }
4159
4160 // Send a broadcast to PackageInstallers if the configuration change is interesting
4161 // for the purposes of installing additional splits.
4162 if (!initLocale && isSplitConfigurationChange(changes)) {
4163 intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
4164 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
4165 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
4166
4167 // Typically only app stores will have this permission.
4168 String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES };
4169 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions,
4170 OP_NONE, null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
4171 }
4172
4173 // Override configuration of the default display duplicates global config, so we need to
4174 // update it also. This will also notify WindowManager about changes.
4175 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
4176 DEFAULT_DISPLAY);
4177
4178 return changes;
4179 }
4180
4181 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
4182 boolean deferResume, int displayId) {
4183 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
4184 displayId, null /* result */);
4185 }
4186
4187 /**
4188 * Updates override configuration specific for the selected display. If no config is provided,
4189 * new one will be computed in WM based on current display info.
4190 */
4191 boolean updateDisplayOverrideConfigurationLocked(Configuration values,
4192 ActivityRecord starting, boolean deferResume, int displayId,
4193 ActivityTaskManagerService.UpdateConfigurationResult result) {
4194 int changes = 0;
4195 boolean kept = true;
4196
4197 if (mWindowManager != null) {
4198 mWindowManager.deferSurfaceLayout();
4199 }
4200 try {
4201 if (values != null) {
4202 if (displayId == DEFAULT_DISPLAY) {
4203 // Override configuration of the default display duplicates global config, so
4204 // we're calling global config update instead for default display. It will also
4205 // apply the correct override config.
4206 changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
4207 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
4208 } else {
4209 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
4210 }
4211 }
4212
4213 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4214 } finally {
4215 if (mWindowManager != null) {
4216 mWindowManager.continueSurfaceLayout();
4217 }
4218 }
4219
4220 if (result != null) {
4221 result.changes = changes;
4222 result.activityRelaunched = !kept;
4223 }
4224 return kept;
4225 }
4226
4227 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
4228 int displayId) {
4229 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
4230 final int changes = mTempConfig.updateFrom(values);
4231 if (changes != 0) {
4232 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
4233 + mTempConfig + " for displayId=" + displayId);
4234 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
4235
4236 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
4237 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
4238 mAm.mAppWarnings.onDensityChanged();
4239
4240 mAm.killAllBackgroundProcessesExcept(N,
4241 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
4242 }
4243 }
4244
4245 // Update the configuration with WM first and check if any of the stacks need to be resized
4246 // due to the configuration change. If so, resize the stacks now and do any relaunches if
4247 // necessary. This way we don't need to relaunch again afterwards in
4248 // ensureActivityConfiguration().
4249 if (mWindowManager != null) {
4250 final int[] resizedStacks =
4251 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
4252 if (resizedStacks != null) {
4253 for (int stackId : resizedStacks) {
4254 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
4255 }
4256 }
4257 }
4258
4259 return changes;
4260 }
4261
4262 /** Helper method that requests bounds from WM and applies them to stack. */
4263 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
4264 final Rect newStackBounds = new Rect();
4265 final ActivityStack stack = mStackSupervisor.getStack(stackId);
4266
4267 // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
4268 if (stack == null) {
4269 final StringWriter writer = new StringWriter();
4270 final PrintWriter printWriter = new PrintWriter(writer);
4271 mStackSupervisor.dumpDisplays(printWriter);
4272 printWriter.flush();
4273
4274 Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
4275 }
4276
4277 stack.getBoundsForNewConfiguration(newStackBounds);
4278 mStackSupervisor.resizeStackLocked(
4279 stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
4280 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
4281 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
4282 }
4283
4284 /** Applies latest configuration and/or visibility updates if needed. */
4285 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
4286 boolean kept = true;
4287 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
4288 // mainStack is null during startup.
4289 if (mainStack != null) {
4290 if (changes != 0 && starting == null) {
4291 // If the configuration changed, and the caller is not already
4292 // in the process of starting an activity, then find the top
4293 // activity to check if its configuration needs to change.
4294 starting = mainStack.topRunningActivityLocked();
4295 }
4296
4297 if (starting != null) {
4298 kept = starting.ensureActivityConfiguration(changes,
4299 false /* preserveWindow */);
4300 // And we need to make sure at this point that all other activities
4301 // are made visible with the correct configuration.
4302 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
4303 !PRESERVE_WINDOWS);
4304 }
4305 }
4306
4307 return kept;
4308 }
4309
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004310 final class H extends Handler {
4311 public H(Looper looper) {
4312 super(looper, null, true);
4313 }
4314 }
4315
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004316 final class UiHandler extends Handler {
4317
4318 public UiHandler() {
4319 super(com.android.server.UiThread.get().getLooper(), null, true);
4320 }
4321 }
4322
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004323 final class LocalService extends ActivityTaskManagerInternal {
4324 @Override
4325 public SleepToken acquireSleepToken(String tag, int displayId) {
4326 Preconditions.checkNotNull(tag);
4327 return mAm.acquireSleepToken(tag, displayId);
4328 }
4329
4330 @Override
4331 public ComponentName getHomeActivityForUser(int userId) {
4332 synchronized (mGlobalLock) {
4333 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
4334 return homeActivity == null ? null : homeActivity.realActivity;
4335 }
4336 }
4337
4338 @Override
4339 public void onLocalVoiceInteractionStarted(IBinder activity,
4340 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4341 synchronized (mGlobalLock) {
4342 mAm.onLocalVoiceInteractionStartedLocked(activity, voiceSession, voiceInteractor);
4343 }
4344 }
4345
4346 @Override
4347 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
4348 synchronized (mGlobalLock) {
4349 mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
4350 reasons, timestamp);
4351 }
4352 }
4353
4354 @Override
4355 public void notifyAppTransitionFinished() {
4356 synchronized (mGlobalLock) {
4357 mStackSupervisor.notifyAppTransitionDone();
4358 }
4359 }
4360
4361 @Override
4362 public void notifyAppTransitionCancelled() {
4363 synchronized (mGlobalLock) {
4364 mStackSupervisor.notifyAppTransitionDone();
4365 }
4366 }
4367
4368 @Override
4369 public List<IBinder> getTopVisibleActivities() {
4370 synchronized (mGlobalLock) {
4371 return mStackSupervisor.getTopVisibleActivities();
4372 }
4373 }
4374
4375 @Override
4376 public void notifyDockedStackMinimizedChanged(boolean minimized) {
4377 synchronized (mGlobalLock) {
4378 mStackSupervisor.setDockedStackMinimized(minimized);
4379 }
4380 }
4381
4382 @Override
4383 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
4384 Bundle bOptions) {
4385 Preconditions.checkNotNull(intents, "intents");
4386 final String[] resolvedTypes = new String[intents.length];
4387
4388 // UID of the package on user userId.
4389 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
4390 // packageUid may not be initialized.
4391 int packageUid = 0;
4392 final long ident = Binder.clearCallingIdentity();
4393
4394 try {
4395 for (int i = 0; i < intents.length; i++) {
4396 resolvedTypes[i] =
4397 intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
4398 }
4399
4400 packageUid = AppGlobals.getPackageManager().getPackageUid(
4401 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
4402 } catch (RemoteException e) {
4403 // Shouldn't happen.
4404 } finally {
4405 Binder.restoreCallingIdentity(ident);
4406 }
4407
4408 synchronized (mGlobalLock) {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07004409 return getActivityStartController().startActivitiesInPackage(
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004410 packageUid, packageName,
4411 intents, resolvedTypes, null /* resultTo */,
4412 SafeActivityOptions.fromBundle(bOptions), userId,
4413 false /* validateIncomingUser */);
4414 }
4415 }
4416
4417 @Override
4418 public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
4419 Intent intent, Bundle options, int userId) {
4420 return ActivityTaskManagerService.this.startActivityAsUser(
4421 caller, callerPacakge, intent,
4422 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4423 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
4424 false /*validateIncomingUser*/);
4425 }
4426
4427 @Override
4428 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
4429 synchronized (mGlobalLock) {
4430
4431 // We might change the visibilities here, so prepare an empty app transition which
4432 // might be overridden later if we actually change visibilities.
4433 final boolean wasTransitionSet =
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004434 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004435 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004436 mWindowManager.prepareAppTransition(TRANSIT_NONE,
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004437 false /* alwaysKeepCurrent */);
4438 }
4439 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4440
4441 // If there was a transition set already we don't want to interfere with it as we
4442 // might be starting it too early.
4443 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004444 mWindowManager.executeAppTransition();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004445 }
4446 }
4447 if (callback != null) {
4448 callback.run();
4449 }
4450 }
4451
4452 @Override
4453 public void notifyKeyguardTrustedChanged() {
4454 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004455 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004456 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4457 }
4458 }
4459 }
4460
4461 /**
4462 * Called after virtual display Id is updated by
4463 * {@link com.android.server.vr.Vr2dDisplay} with a specific
4464 * {@param vrVr2dDisplayId}.
4465 */
4466 @Override
4467 public void setVr2dDisplayId(int vr2dDisplayId) {
4468 if (DEBUG_STACK) Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
4469 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004470 mVr2dDisplayId = vr2dDisplayId;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004471 }
4472 }
4473
4474 @Override
4475 public void setFocusedActivity(IBinder token) {
4476 synchronized (mGlobalLock) {
4477 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
4478 if (r == null) {
4479 throw new IllegalArgumentException(
4480 "setFocusedActivity: No activity record matching token=" + token);
4481 }
4482 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
4483 r, "setFocusedActivity")) {
4484 mStackSupervisor.resumeFocusedStackTopActivityLocked();
4485 }
4486 }
4487 }
4488
4489 @Override
4490 public boolean hasRunningActivity(int uid, @Nullable String packageName) {
4491 if (packageName == null) return false;
4492
4493 synchronized (mGlobalLock) {
4494 for (int i = 0; i < mAm.mLruProcesses.size(); i++) {
4495 final ProcessRecord processRecord = mAm.mLruProcesses.get(i);
4496 if (processRecord.uid == uid) {
4497 for (int j = 0; j < processRecord.activities.size(); j++) {
4498 final ActivityRecord activityRecord = processRecord.activities.get(j);
4499 if (packageName.equals(activityRecord.packageName)) {
4500 return true;
4501 }
4502 }
4503 }
4504 }
4505 }
4506 return false;
4507 }
4508
4509 @Override
4510 public void registerScreenObserver(ScreenObserver observer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004511 mScreenObservers.add(observer);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004512 }
4513
4514 @Override
4515 public boolean isCallerRecents(int callingUid) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07004516 return getRecentTasks().isCallerRecents(callingUid);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004517 }
4518
4519 @Override
4520 public boolean isRecentsComponentHomeActivity(int userId) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07004521 return getRecentTasks().isRecentsComponentHomeActivity(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004522 }
4523
4524 @Override
4525 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
4526 ActivityTaskManagerService.this.cancelRecentsAnimation(restoreHomeStackPosition);
4527 }
4528
4529 @Override
4530 public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004531 ActivityTaskManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004532 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004533
4534 @Override
4535 public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
4536 synchronized (mGlobalLock) {
4537 mActiveVoiceInteractionServiceComponent = component;
4538 }
4539 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004540
4541 @Override
4542 public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
4543 if (!mAmInternal.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
4544 return;
4545 }
4546 synchronized (mGlobalLock) {
4547 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
4548 if (types == null) {
4549 if (uid < 0) {
4550 return;
4551 }
4552 types = new ArrayMap<>();
4553 mAllowAppSwitchUids.put(userId, types);
4554 }
4555 if (uid < 0) {
4556 types.remove(type);
4557 } else {
4558 types.put(type, uid);
4559 }
4560 }
4561 }
4562
4563 @Override
4564 public void onUserStopped(int userId) {
4565 synchronized (mGlobalLock) {
4566 getRecentTasks().unloadUserDataFromMemoryLocked(userId);
4567 mAllowAppSwitchUids.remove(userId);
4568 }
4569 }
4570
4571 @Override
4572 public boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
4573 synchronized (mGlobalLock) {
4574 return ActivityTaskManagerService.this.isGetTasksAllowed(
4575 caller, callingPid, callingUid);
4576 }
4577 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004578 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07004579}