blob: d47fb4401e5b50c092b3e31ad27ad35cefc0171f [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 Ogunwale9e4f3e02018-05-17 09:35:39 -070029import static com.android.server.am.ActivityManagerService.dumpStackTraces;
30import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT;
31import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_DATA;
32import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
33import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070034import static android.app.ActivityTaskManager.INVALID_STACK_ID;
35import static android.app.ActivityTaskManager.RESIZE_MODE_PRESERVE_WINDOW;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070036import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070037import static android.app.AppOpsManager.OP_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070038import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070039import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070040import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
41import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
42import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070043import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
44import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070045import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070046import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070047import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070048import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
49import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070050import 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;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070059import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
60import static android.view.Display.DEFAULT_DISPLAY;
61import static android.view.Display.INVALID_DISPLAY;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070062import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
Wale Ogunwale6767eae2018-05-03 15:52:51 -070063import static android.view.WindowManager.TRANSIT_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070064import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070065import static android.view.WindowManager.TRANSIT_TASK_OPEN;
66import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070067import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070068import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
69import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
70import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
71import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
Wale Ogunwale6767eae2018-05-03 15:52:51 -070072import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070073import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070074import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070075import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070076import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070077import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070078import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
79import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
80import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070081import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070082import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
83import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070084import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
85import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070086import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070087import static com.android.server.am.ActivityManagerService.ANIMATE;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070088import static com.android.server.am.ActivityManagerService.MY_PID;
89import static com.android.server.am.ActivityManagerService.SEND_LOCALE_TO_MOUNT_DAEMON_MSG;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070090import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070091import static com.android.server.am.ActivityManagerService.UPDATE_CONFIGURATION_MSG;
92import static com.android.server.am.ActivityManagerService.checkComponentPermission;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070093import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070094import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070095import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
96import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
97import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
98import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
99import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
100import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
101import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700102import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700103import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
104import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
105import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700106
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700107import android.Manifest;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700108import android.annotation.NonNull;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700109import android.annotation.Nullable;
110import android.annotation.UserIdInt;
111import android.app.Activity;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700112import android.app.ActivityManager;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700113import android.app.ActivityManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700114import android.app.ActivityOptions;
115import android.app.ActivityTaskManager;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700116import com.android.server.wm.ActivityTaskManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700117import android.app.AppGlobals;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700118import android.app.IActivityController;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700119import android.app.IActivityTaskManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700120import android.app.IApplicationThread;
121import android.app.IAssistDataReceiver;
122import android.app.ITaskStackListener;
123import android.app.PictureInPictureParams;
124import android.app.ProfilerInfo;
125import android.app.RemoteAction;
126import android.app.WaitResult;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700127import android.app.WindowConfiguration;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700128import android.app.admin.DevicePolicyCache;
129import android.app.assist.AssistContent;
130import android.app.assist.AssistStructure;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700131import android.app.servertransaction.ConfigurationChangeItem;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700132import android.app.usage.UsageEvents;
133import android.content.ActivityNotFoundException;
134import android.content.ComponentName;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700135import android.content.ContentResolver;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700136import android.content.Context;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700137import android.content.IIntentSender;
138import android.content.Intent;
139import android.content.pm.ActivityInfo;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700140import android.content.pm.ApplicationInfo;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700141import android.content.pm.PackageManager;
142import android.content.pm.ParceledListSlice;
143import android.content.pm.ResolveInfo;
144import android.content.res.Configuration;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700145import android.content.res.Resources;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700146import android.graphics.Bitmap;
147import android.graphics.Point;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700148import android.graphics.Rect;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700149import android.metrics.LogMaker;
150import android.net.Uri;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700151import android.os.Binder;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700152import android.os.Build;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700153import android.os.Bundle;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700154import android.os.FileUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700155import android.os.Handler;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700156import android.os.IBinder;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700157import android.os.LocaleList;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700158import android.os.Looper;
159import android.os.Message;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700160import android.os.PersistableBundle;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700161import android.os.Process;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700162import android.os.RemoteException;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700163import android.os.StrictMode;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700164import android.os.SystemClock;
165import android.os.SystemProperties;
166import android.os.UpdateLock;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700167import android.os.UserHandle;
168import android.provider.Settings;
169import android.service.voice.IVoiceInteractionSession;
170import android.service.voice.VoiceInteractionManagerInternal;
171import android.telecom.TelecomManager;
172import android.text.TextUtils;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700173import android.text.format.Time;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700174import android.util.ArrayMap;
175import android.util.EventLog;
176import android.util.Log;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700177import android.util.Slog;
178
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700179import android.util.SparseArray;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700180import android.util.SparseIntArray;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700181import android.util.StatsLog;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700182import android.util.TimeUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700183import android.util.proto.ProtoOutputStream;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700184import android.view.IRecentsAnimationRunner;
185import android.view.RemoteAnimationAdapter;
186import android.view.RemoteAnimationDefinition;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700187
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700188import com.android.internal.annotations.VisibleForTesting;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700189import com.android.internal.app.AssistUtils;
190import com.android.internal.app.IVoiceInteractor;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700191import com.android.internal.app.ProcessMap;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700192import com.android.internal.logging.MetricsLogger;
193import com.android.internal.os.logging.MetricsLoggerWrapper;
194import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
195import com.android.internal.policy.IKeyguardDismissCallback;
196import com.android.internal.policy.KeyguardDismissCallback;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700197import com.android.internal.util.Preconditions;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700198import com.android.server.AttributeCache;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700199import com.android.server.LocalServices;
200import com.android.server.SystemService;
201import com.android.server.Watchdog;
202import com.android.server.vr.VrManagerInternal;
203import com.android.server.wm.PinnedStackWindowController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700204import com.android.server.wm.WindowManagerService;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700205
206import java.io.File;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700207import java.io.FileOutputStream;
208import java.io.IOException;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700209import java.io.PrintWriter;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700210import java.io.StringWriter;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700211import java.util.ArrayList;
212import java.util.List;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700213import java.util.Locale;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700214
215/**
216 * System service for managing activities and their containers (task, stacks, displays,... ).
217 *
218 * {@hide}
219 */
220public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
221 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityTaskManagerService" : TAG_AM;
222 private static final String TAG_STACK = TAG + POSTFIX_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700223 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
224 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
225 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
226 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
227 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700228 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700229
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700230 Context mContext;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700231 H mH;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700232 UiHandler mUiHandler;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700233 ActivityManagerService mAm;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700234 ActivityManagerInternal mAmInternal;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700235 /* Global service lock used by the package the owns this service. */
236 Object mGlobalLock;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700237 ActivityStackSupervisor mStackSupervisor;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700238 WindowManagerService mWindowManager;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700239 /** All processes currently running that might have a window organized by name. */
240 final ProcessMap<WindowProcessController> mProcessNames = new ProcessMap<>();
241 /** This is the process holding what we currently consider to be the "home" activity. */
242 WindowProcessController mHomeProcess;
243 /**
244 * This is the process holding the activity the user last visited that is in a different process
245 * from the one they are currently in.
246 */
247 WindowProcessController mPreviousProcess;
248 /** The time at which the previous process was last visible. */
249 long mPreviousProcessVisibleTime;
250
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700251 /** List of intents that were used to start the most recent tasks. */
252 private RecentTasks mRecentTasks;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700253 /** State of external calls telling us if the device is awake or asleep. */
254 private boolean mKeyguardShown = false;
255
256 // Wrapper around VoiceInteractionServiceManager
257 private AssistUtils mAssistUtils;
258
259 // VoiceInteraction session ID that changes for each new request except when
260 // being called for multi-window assist in a single session.
261 private int mViSessionId = 1000;
262
263 // How long to wait in getAssistContextExtras for the activity and foreground services
264 // to respond with the result.
265 private static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
266
267 // How long top wait when going through the modern assist (which doesn't need to block
268 // on getting this result before starting to launch its UI).
269 private static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
270
271 // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
272 private static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
273
274 private final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
275
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700276 // Keeps track of the active voice interaction service component, notified from
277 // VoiceInteractionManagerService
278 ComponentName mActiveVoiceInteractionServiceComponent;
279
280 private VrController mVrController;
281 KeyguardController mKeyguardController;
282 private final ClientLifecycleManager mLifecycleManager;
283 private TaskChangeNotificationController mTaskChangeNotificationController;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700284 /** The controller for all operations related to locktask. */
285 private LockTaskController mLockTaskController;
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700286 private ActivityStartController mActivityStartController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700287
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700288 boolean mSuppressResizeConfigChanges;
289
290 private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
291 new UpdateConfigurationResult();
292
293 static final class UpdateConfigurationResult {
294 // Configuration changes that were updated.
295 int changes;
296 // If the activity was relaunched to match the new configuration.
297 boolean activityRelaunched;
298
299 void reset() {
300 changes = 0;
301 activityRelaunched = false;
302 }
303 }
304
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700305 /** Current sequencing integer of the configuration, for skipping old configurations. */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700306 private int mConfigurationSeq;
307 // To cache the list of supported system locales
308 private String[] mSupportedSystemLocales = null;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700309
310 /**
311 * Temp object used when global and/or display override configuration is updated. It is also
312 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
313 * anyone...
314 */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700315 private Configuration mTempConfig = new Configuration();
316
317 // Amount of time after a call to stopAppSwitches() during which we will
318 // prevent further untrusted switches from happening.
319 private static final long APP_SWITCH_DELAY_TIME = 5 * 1000;
320
321 /**
322 * The time at which we will allow normal application switches again,
323 * after a call to {@link #stopAppSwitches()}.
324 */
325 long mAppSwitchesAllowedTime;
326 /**
327 * This is set to true after the first switch after mAppSwitchesAllowedTime
328 * is set; any switches after that will clear the time.
329 */
330 boolean mDidAppSwitch;
331
332 IActivityController mController = null;
333 boolean mControllerIsAMonkey = false;
334
335 /**
336 * Used to retain an update lock when the foreground activity is in
337 * immersive mode.
338 */
339 final UpdateLock mUpdateLock = new UpdateLock("immersive");
340
341 /**
342 * Packages that are being allowed to perform unrestricted app switches. Mapping is
343 * User -> Type -> uid.
344 */
345 final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
346
347 /** The dimensions of the thumbnails in the Recents UI. */
348 int mThumbnailWidth;
349 int mThumbnailHeight;
350 float mFullscreenThumbnailScale;
351
352 /**
353 * Flag that indicates if multi-window is enabled.
354 *
355 * For any particular form of multi-window to be enabled, generic multi-window must be enabled
356 * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
357 * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
358 * At least one of the forms of multi-window must be enabled in order for this flag to be
359 * initialized to 'true'.
360 *
361 * @see #mSupportsSplitScreenMultiWindow
362 * @see #mSupportsFreeformWindowManagement
363 * @see #mSupportsPictureInPicture
364 * @see #mSupportsMultiDisplay
365 */
366 boolean mSupportsMultiWindow;
367 boolean mSupportsSplitScreenMultiWindow;
368 boolean mSupportsFreeformWindowManagement;
369 boolean mSupportsPictureInPicture;
370 boolean mSupportsMultiDisplay;
371 boolean mForceResizableActivities;
372
373 final List<ActivityTaskManagerInternal.ScreenObserver> mScreenObservers = new ArrayList<>();
374
375 // VR Vr2d Display Id.
376 int mVr2dDisplayId = INVALID_DISPLAY;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700377
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700378 ActivityTaskManagerService(Context context) {
379 mContext = context;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700380 mLifecycleManager = new ClientLifecycleManager();
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700381 }
382
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700383 void onSystemReady() {
384 mAssistUtils = new AssistUtils(mContext);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700385 mVrController.onSystemReady();
386 mRecentTasks.onSystemReadyLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700387 }
388
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700389 void retrieveSettings(ContentResolver resolver) {
390 final boolean freeformWindowManagement =
391 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
392 || Settings.Global.getInt(
393 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
394
395 final boolean supportsMultiWindow = ActivityTaskManager.supportsMultiWindow(mContext);
396 final boolean supportsPictureInPicture = supportsMultiWindow &&
397 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
398 final boolean supportsSplitScreenMultiWindow =
399 ActivityTaskManager.supportsSplitScreenMultiWindow(mContext);
400 final boolean supportsMultiDisplay = mContext.getPackageManager()
401 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
402 final boolean alwaysFinishActivities =
403 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
404 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
405 final boolean forceResizable = Settings.Global.getInt(
406 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
407
408 // Transfer any global setting for forcing RTL layout, into a System Property
409 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
410
411 final Configuration configuration = new Configuration();
412 Settings.System.getConfiguration(resolver, configuration);
413 if (forceRtl) {
414 // This will take care of setting the correct layout direction flags
415 configuration.setLayoutDirection(configuration.locale);
416 }
417
418 synchronized (mGlobalLock) {
419 mForceResizableActivities = forceResizable;
420 final boolean multiWindowFormEnabled = freeformWindowManagement
421 || supportsSplitScreenMultiWindow
422 || supportsPictureInPicture
423 || supportsMultiDisplay;
424 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
425 mSupportsMultiWindow = true;
426 mSupportsFreeformWindowManagement = freeformWindowManagement;
427 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
428 mSupportsPictureInPicture = supportsPictureInPicture;
429 mSupportsMultiDisplay = supportsMultiDisplay;
430 } else {
431 mSupportsMultiWindow = false;
432 mSupportsFreeformWindowManagement = false;
433 mSupportsSplitScreenMultiWindow = false;
434 mSupportsPictureInPicture = false;
435 mSupportsMultiDisplay = false;
436 }
437 mWindowManager.setForceResizableTasks(mForceResizableActivities);
438 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
439 // This happens before any activities are started, so we can change global configuration
440 // in-place.
441 updateConfigurationLocked(configuration, null, true);
442 final Configuration globalConfig = getGlobalConfiguration();
443 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
444
445 // Load resources only after the current configuration has been set.
446 final Resources res = mContext.getResources();
447 mThumbnailWidth = res.getDimensionPixelSize(
448 com.android.internal.R.dimen.thumbnail_width);
449 mThumbnailHeight = res.getDimensionPixelSize(
450 com.android.internal.R.dimen.thumbnail_height);
451
452 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
453 mFullscreenThumbnailScale = (float) res
454 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
455 (float) globalConfig.screenWidthDp;
456 } else {
457 mFullscreenThumbnailScale = res.getFraction(
458 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
459 }
460 }
461 }
462
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700463 // TODO: Will be converted to WM lock once transition is complete.
464 void setActivityManagerService(ActivityManagerService am) {
465 mAm = am;
466 mGlobalLock = mAm;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700467 mH = new H(mAm.mHandlerThread.getLooper());
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700468 mUiHandler = new UiHandler();
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700469
470 mTempConfig.setToDefaults();
471 mTempConfig.setLocales(LocaleList.getDefault());
472 mConfigurationSeq = mTempConfig.seq = 1;
473 mStackSupervisor = createStackSupervisor();
474 mStackSupervisor.onConfigurationChanged(mTempConfig);
475
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700476 mTaskChangeNotificationController =
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700477 new TaskChangeNotificationController(mGlobalLock, mStackSupervisor, mH);
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700478 mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mH);
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700479 mActivityStartController = new ActivityStartController(this);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700480 mRecentTasks = createRecentTasks();
481 mStackSupervisor.setRecentTasks(mRecentTasks);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700482 mVrController = new VrController(mGlobalLock);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700483 mKeyguardController = mStackSupervisor.getKeyguardController();
484 }
485
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700486 void onActivityManagerInternalAdded() {
487 mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
488 }
489
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700490 protected ActivityStackSupervisor createStackSupervisor() {
491 final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mH.getLooper());
492 supervisor.initialize();
493 return supervisor;
494 }
495
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700496 void setWindowManager(WindowManagerService wm) {
497 mWindowManager = wm;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700498 mLockTaskController.setWindowManager(wm);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700499 }
500
501 protected RecentTasks createRecentTasks() {
502 return new RecentTasks(this, mStackSupervisor);
503 }
504
505 RecentTasks getRecentTasks() {
506 return mRecentTasks;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700507 }
508
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700509 ClientLifecycleManager getLifecycleManager() {
510 return mLifecycleManager;
511 }
512
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700513 ActivityStartController getActivityStartController() {
514 return mActivityStartController;
515 }
516
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700517 TaskChangeNotificationController getTaskChangeNotificationController() {
518 return mTaskChangeNotificationController;
519 }
520
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700521 LockTaskController getLockTaskController() {
522 return mLockTaskController;
523 }
524
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700525 private void start() {
526 LocalServices.addService(ActivityTaskManagerInternal.class, new LocalService());
527 }
528
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700529 public static final class Lifecycle extends SystemService {
530 private final ActivityTaskManagerService mService;
531
532 public Lifecycle(Context context) {
533 super(context);
534 mService = new ActivityTaskManagerService(context);
535 }
536
537 @Override
538 public void onStart() {
539 publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700540 mService.start();
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700541 }
542
543 public ActivityTaskManagerService getService() {
544 return mService;
545 }
546 }
547
548 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700549 public final int startActivity(IApplicationThread caller, String callingPackage,
550 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
551 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
552 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
553 resultWho, requestCode, startFlags, profilerInfo, bOptions,
554 UserHandle.getCallingUserId());
555 }
556
557 @Override
558 public final int startActivities(IApplicationThread caller, String callingPackage,
559 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
560 int userId) {
561 final String reason = "startActivities";
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700562 enforceNotIsolatedCaller(reason);
563 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, reason);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700564 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700565 return getActivityStartController().startActivities(caller, -1, callingPackage, intents,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700566 resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId, reason);
567 }
568
569 @Override
570 public int startActivityAsUser(IApplicationThread caller, String callingPackage,
571 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
572 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
573 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
574 resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
575 true /*validateIncomingUser*/);
576 }
577
578 int startActivityAsUser(IApplicationThread caller, String callingPackage,
579 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
580 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
581 boolean validateIncomingUser) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700582 enforceNotIsolatedCaller("startActivityAsUser");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700583
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700584 userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700585 Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
586
587 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700588 return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700589 .setCaller(caller)
590 .setCallingPackage(callingPackage)
591 .setResolvedType(resolvedType)
592 .setResultTo(resultTo)
593 .setResultWho(resultWho)
594 .setRequestCode(requestCode)
595 .setStartFlags(startFlags)
596 .setProfilerInfo(profilerInfo)
597 .setActivityOptions(bOptions)
598 .setMayWait(userId)
599 .execute();
600
601 }
602
603 @Override
604 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
605 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700606 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions) {
607 enforceNotIsolatedCaller("startActivityIntentSender");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700608 // Refuse possible leaked file descriptors
609 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
610 throw new IllegalArgumentException("File descriptors passed in Intent");
611 }
612
613 if (!(target instanceof PendingIntentRecord)) {
614 throw new IllegalArgumentException("Bad PendingIntent object");
615 }
616
617 PendingIntentRecord pir = (PendingIntentRecord)target;
618
619 synchronized (mGlobalLock) {
620 // If this is coming from the currently resumed activity, it is
621 // effectively saying that app switches are allowed at this point.
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700622 final ActivityStack stack = getFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700623 if (stack.mResumedActivity != null &&
624 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700625 mAppSwitchesAllowedTime = 0;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700626 }
627 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700628 return pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700629 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700630 }
631
632 @Override
633 public boolean startNextMatchingActivity(IBinder callingActivity, Intent intent,
634 Bundle bOptions) {
635 // Refuse possible leaked file descriptors
636 if (intent != null && intent.hasFileDescriptors()) {
637 throw new IllegalArgumentException("File descriptors passed in Intent");
638 }
639 SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
640
641 synchronized (mGlobalLock) {
642 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
643 if (r == null) {
644 SafeActivityOptions.abort(options);
645 return false;
646 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700647 if (!r.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700648 // The caller is not running... d'oh!
649 SafeActivityOptions.abort(options);
650 return false;
651 }
652 intent = new Intent(intent);
653 // The caller is not allowed to change the data.
654 intent.setDataAndType(r.intent.getData(), r.intent.getType());
655 // And we are resetting to find the next component...
656 intent.setComponent(null);
657
658 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
659
660 ActivityInfo aInfo = null;
661 try {
662 List<ResolveInfo> resolves =
663 AppGlobals.getPackageManager().queryIntentActivities(
664 intent, r.resolvedType,
665 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
666 UserHandle.getCallingUserId()).getList();
667
668 // Look for the original activity in the list...
669 final int N = resolves != null ? resolves.size() : 0;
670 for (int i=0; i<N; i++) {
671 ResolveInfo rInfo = resolves.get(i);
672 if (rInfo.activityInfo.packageName.equals(r.packageName)
673 && rInfo.activityInfo.name.equals(r.info.name)) {
674 // We found the current one... the next matching is
675 // after it.
676 i++;
677 if (i<N) {
678 aInfo = resolves.get(i).activityInfo;
679 }
680 if (debug) {
681 Slog.v(TAG, "Next matching activity: found current " + r.packageName
682 + "/" + r.info.name);
683 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
684 ? "null" : aInfo.packageName + "/" + aInfo.name));
685 }
686 break;
687 }
688 }
689 } catch (RemoteException e) {
690 }
691
692 if (aInfo == null) {
693 // Nobody who is next!
694 SafeActivityOptions.abort(options);
695 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
696 return false;
697 }
698
699 intent.setComponent(new ComponentName(
700 aInfo.applicationInfo.packageName, aInfo.name));
701 intent.setFlags(intent.getFlags()&~(
702 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
703 Intent.FLAG_ACTIVITY_CLEAR_TOP|
704 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
705 FLAG_ACTIVITY_NEW_TASK));
706
707 // Okay now we need to start the new activity, replacing the currently running activity.
708 // This is a little tricky because we want to start the new one as if the current one is
709 // finished, but not finish the current one first so that there is no flicker.
710 // And thus...
711 final boolean wasFinishing = r.finishing;
712 r.finishing = true;
713
714 // Propagate reply information over to the new activity.
715 final ActivityRecord resultTo = r.resultTo;
716 final String resultWho = r.resultWho;
717 final int requestCode = r.requestCode;
718 r.resultTo = null;
719 if (resultTo != null) {
720 resultTo.removeResultsLocked(r, resultWho, requestCode);
721 }
722
723 final long origId = Binder.clearCallingIdentity();
724 // TODO(b/64750076): Check if calling pid should really be -1.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700725 final int res = getActivityStartController()
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700726 .obtainStarter(intent, "startNextMatchingActivity")
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700727 .setCaller(r.app.getThread())
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700728 .setResolvedType(r.resolvedType)
729 .setActivityInfo(aInfo)
730 .setResultTo(resultTo != null ? resultTo.appToken : null)
731 .setResultWho(resultWho)
732 .setRequestCode(requestCode)
733 .setCallingPid(-1)
734 .setCallingUid(r.launchedFromUid)
735 .setCallingPackage(r.launchedFromPackage)
736 .setRealCallingPid(-1)
737 .setRealCallingUid(r.launchedFromUid)
738 .setActivityOptions(options)
739 .execute();
740 Binder.restoreCallingIdentity(origId);
741
742 r.finishing = wasFinishing;
743 if (res != ActivityManager.START_SUCCESS) {
744 return false;
745 }
746 return true;
747 }
748 }
749
750 @Override
751 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
752 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
753 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
754 final WaitResult res = new WaitResult();
755 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700756 enforceNotIsolatedCaller("startActivityAndWait");
757 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
758 userId, "startActivityAndWait");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700759 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700760 getActivityStartController().obtainStarter(intent, "startActivityAndWait")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700761 .setCaller(caller)
762 .setCallingPackage(callingPackage)
763 .setResolvedType(resolvedType)
764 .setResultTo(resultTo)
765 .setResultWho(resultWho)
766 .setRequestCode(requestCode)
767 .setStartFlags(startFlags)
768 .setActivityOptions(bOptions)
769 .setMayWait(userId)
770 .setProfilerInfo(profilerInfo)
771 .setWaitResult(res)
772 .execute();
773 }
774 return res;
775 }
776
777 @Override
778 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
779 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
780 int startFlags, Configuration config, Bundle bOptions, int userId) {
781 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700782 enforceNotIsolatedCaller("startActivityWithConfig");
783 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
784 "startActivityWithConfig");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700785 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700786 return getActivityStartController().obtainStarter(intent, "startActivityWithConfig")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700787 .setCaller(caller)
788 .setCallingPackage(callingPackage)
789 .setResolvedType(resolvedType)
790 .setResultTo(resultTo)
791 .setResultWho(resultWho)
792 .setRequestCode(requestCode)
793 .setStartFlags(startFlags)
794 .setGlobalConfiguration(config)
795 .setActivityOptions(bOptions)
796 .setMayWait(userId)
797 .execute();
798 }
799 }
800
801 @Override
802 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
803 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
804 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
805 int userId) {
806
807 // This is very dangerous -- it allows you to perform a start activity (including
808 // permission grants) as any app that may launch one of your own activities. So
809 // we will only allow this to be done from activities that are part of the core framework,
810 // and then only when they are running as the system.
811 final ActivityRecord sourceRecord;
812 final int targetUid;
813 final String targetPackage;
814 final boolean isResolver;
815 synchronized (mGlobalLock) {
816 if (resultTo == null) {
817 throw new SecurityException("Must be called from an activity");
818 }
819 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
820 if (sourceRecord == null) {
821 throw new SecurityException("Called with bad activity token: " + resultTo);
822 }
823 if (!sourceRecord.info.packageName.equals("android")) {
824 throw new SecurityException(
825 "Must be called from an activity that is declared in the android package");
826 }
827 if (sourceRecord.app == null) {
828 throw new SecurityException("Called without a process attached to activity");
829 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700830 if (UserHandle.getAppId(sourceRecord.app.mUid) != SYSTEM_UID) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700831 // This is still okay, as long as this activity is running under the
832 // uid of the original calling activity.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700833 if (sourceRecord.app.mUid != sourceRecord.launchedFromUid) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700834 throw new SecurityException(
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700835 "Calling activity in uid " + sourceRecord.app.mUid
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700836 + " must be system uid or original calling uid "
837 + sourceRecord.launchedFromUid);
838 }
839 }
840 if (ignoreTargetSecurity) {
841 if (intent.getComponent() == null) {
842 throw new SecurityException(
843 "Component must be specified with ignoreTargetSecurity");
844 }
845 if (intent.getSelector() != null) {
846 throw new SecurityException(
847 "Selector not allowed with ignoreTargetSecurity");
848 }
849 }
850 targetUid = sourceRecord.launchedFromUid;
851 targetPackage = sourceRecord.launchedFromPackage;
852 isResolver = sourceRecord.isResolverOrChildActivity();
853 }
854
855 if (userId == UserHandle.USER_NULL) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700856 userId = UserHandle.getUserId(sourceRecord.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700857 }
858
859 // TODO: Switch to user app stacks here.
860 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700861 return getActivityStartController().obtainStarter(intent, "startActivityAsCaller")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700862 .setCallingUid(targetUid)
863 .setCallingPackage(targetPackage)
864 .setResolvedType(resolvedType)
865 .setResultTo(resultTo)
866 .setResultWho(resultWho)
867 .setRequestCode(requestCode)
868 .setStartFlags(startFlags)
869 .setActivityOptions(bOptions)
870 .setMayWait(userId)
871 .setIgnoreTargetSecurity(ignoreTargetSecurity)
872 .setFilterCallingUid(isResolver ? 0 /* system */ : targetUid)
873 .execute();
874 } catch (SecurityException e) {
875 // XXX need to figure out how to propagate to original app.
876 // A SecurityException here is generally actually a fault of the original
877 // calling activity (such as a fairly granting permissions), so propagate it
878 // back to them.
879 /*
880 StringBuilder msg = new StringBuilder();
881 msg.append("While launching");
882 msg.append(intent.toString());
883 msg.append(": ");
884 msg.append(e.getMessage());
885 */
886 throw e;
887 }
888 }
889
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700890 int handleIncomingUser(int callingPid, int callingUid, int userId, String name) {
891 return mAmInternal.handleIncomingUser(callingPid, callingUid, userId, false /* allowAll */,
892 ALLOW_FULL_ONLY, name, null /* callerPackage */);
893 }
894
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700895 @Override
896 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
897 Intent intent, String resolvedType, IVoiceInteractionSession session,
898 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
899 Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700900 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700901 if (session == null || interactor == null) {
902 throw new NullPointerException("null session or interactor");
903 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700904 userId = handleIncomingUser(callingPid, callingUid, userId, "startVoiceActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700905 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700906 return getActivityStartController().obtainStarter(intent, "startVoiceActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700907 .setCallingUid(callingUid)
908 .setCallingPackage(callingPackage)
909 .setResolvedType(resolvedType)
910 .setVoiceSession(session)
911 .setVoiceInteractor(interactor)
912 .setStartFlags(startFlags)
913 .setProfilerInfo(profilerInfo)
914 .setActivityOptions(bOptions)
915 .setMayWait(userId)
916 .execute();
917 }
918
919 @Override
920 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
921 Intent intent, String resolvedType, Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700922 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
923 userId = handleIncomingUser(callingPid, callingUid, userId, "startAssistantActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700924
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700925 return getActivityStartController().obtainStarter(intent, "startAssistantActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700926 .setCallingUid(callingUid)
927 .setCallingPackage(callingPackage)
928 .setResolvedType(resolvedType)
929 .setActivityOptions(bOptions)
930 .setMayWait(userId)
931 .execute();
932 }
933
934 @Override
935 public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
936 IRecentsAnimationRunner recentsAnimationRunner) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700937 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700938 final int callingPid = Binder.getCallingPid();
939 final long origId = Binder.clearCallingIdentity();
940 try {
941 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700942 final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
943 final int recentsUid = mRecentTasks.getRecentsComponentUid();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700944
945 // Start a new recents animation
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700946 final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
947 getActivityStartController(), mWindowManager, callingPid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700948 anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
949 recentsUid, assistDataReceiver);
950 }
951 } finally {
952 Binder.restoreCallingIdentity(origId);
953 }
954 }
955
956 @Override
957 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700958 enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700959 "startActivityFromRecents()");
960
961 final int callingPid = Binder.getCallingPid();
962 final int callingUid = Binder.getCallingUid();
963 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(bOptions);
964 final long origId = Binder.clearCallingIdentity();
965 try {
966 synchronized (mGlobalLock) {
967 return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
968 safeOptions);
969 }
970 } finally {
971 Binder.restoreCallingIdentity(origId);
972 }
973 }
974
975 /**
976 * This is the internal entry point for handling Activity.finish().
977 *
978 * @param token The Binder token referencing the Activity we want to finish.
979 * @param resultCode Result code, if any, from this Activity.
980 * @param resultData Result data (Intent), if any, from this Activity.
981 * @param finishTask Whether to finish the task associated with this Activity.
982 *
983 * @return Returns true if the activity successfully finished, or false if it is still running.
984 */
985 @Override
986 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
987 int finishTask) {
988 // Refuse possible leaked file descriptors
989 if (resultData != null && resultData.hasFileDescriptors()) {
990 throw new IllegalArgumentException("File descriptors passed in Intent");
991 }
992
993 synchronized (mGlobalLock) {
994 ActivityRecord r = ActivityRecord.isInStackLocked(token);
995 if (r == null) {
996 return true;
997 }
998 // Keep track of the root activity of the task before we finish it
999 TaskRecord tr = r.getTask();
1000 ActivityRecord rootR = tr.getRootActivity();
1001 if (rootR == null) {
1002 Slog.w(TAG, "Finishing task with all activities already finished");
1003 }
1004 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
1005 // finish.
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001006 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001007 return false;
1008 }
1009
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001010 // TODO: There is a dup. of this block of code in ActivityStack.navigateUpToLocked
1011 // We should consolidate.
1012 if (mController != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001013 // Find the first activity that is not finishing.
1014 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
1015 if (next != null) {
1016 // ask watcher if this is allowed
1017 boolean resumeOK = true;
1018 try {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001019 resumeOK = mController.activityResuming(next.packageName);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001020 } catch (RemoteException e) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001021 mController = null;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001022 Watchdog.getInstance().setActivityController(null);
1023 }
1024
1025 if (!resumeOK) {
1026 Slog.i(TAG, "Not finishing activity because controller resumed");
1027 return false;
1028 }
1029 }
1030 }
1031 final long origId = Binder.clearCallingIdentity();
1032 try {
1033 boolean res;
1034 final boolean finishWithRootActivity =
1035 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
1036 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
1037 || (finishWithRootActivity && r == rootR)) {
1038 // If requested, remove the task that is associated to this activity only if it
1039 // was the root activity in the task. The result code and data is ignored
1040 // because we don't support returning them across task boundaries. Also, to
1041 // keep backwards compatibility we remove the task from recents when finishing
1042 // task with root activity.
1043 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
1044 finishWithRootActivity, "finish-activity");
1045 if (!res) {
1046 Slog.i(TAG, "Removing task failed to finish activity");
1047 }
1048 } else {
1049 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
1050 resultData, "app-request", true);
1051 if (!res) {
1052 Slog.i(TAG, "Failed to finish by app-request");
1053 }
1054 }
1055 return res;
1056 } finally {
1057 Binder.restoreCallingIdentity(origId);
1058 }
1059 }
1060 }
1061
1062 @Override
1063 public boolean finishActivityAffinity(IBinder token) {
1064 synchronized (mGlobalLock) {
1065 final long origId = Binder.clearCallingIdentity();
1066 try {
1067 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1068 if (r == null) {
1069 return false;
1070 }
1071
1072 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
1073 // can finish.
1074 final TaskRecord task = r.getTask();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001075 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001076 return false;
1077 }
1078 return task.getStack().finishActivityAffinityLocked(r);
1079 } finally {
1080 Binder.restoreCallingIdentity(origId);
1081 }
1082 }
1083 }
1084
1085 @Override
1086 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
1087 final long origId = Binder.clearCallingIdentity();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001088 try {
1089 WindowProcessController proc = null;
1090 synchronized (mGlobalLock) {
1091 ActivityStack stack = ActivityRecord.getStackLocked(token);
1092 if (stack == null) {
1093 return;
1094 }
1095 final ActivityRecord r = mStackSupervisor.activityIdleInternalLocked(token,
1096 false /* fromTimeout */, false /* processPausingActivities */, config);
1097 if (r != null) {
1098 proc = r.app;
1099 }
1100 if (stopProfiling && proc != null) {
1101 proc.clearProfilerIfNeeded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001102 }
1103 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001104 } finally {
1105 Binder.restoreCallingIdentity(origId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001106 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001107 }
1108
1109 @Override
1110 public final void activityResumed(IBinder token) {
1111 final long origId = Binder.clearCallingIdentity();
1112 synchronized (mGlobalLock) {
1113 ActivityRecord.activityResumedLocked(token);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001114 mWindowManager.notifyAppResumedFinished(token);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001115 }
1116 Binder.restoreCallingIdentity(origId);
1117 }
1118
1119 @Override
1120 public final void activityPaused(IBinder token) {
1121 final long origId = Binder.clearCallingIdentity();
1122 synchronized (mGlobalLock) {
1123 ActivityStack stack = ActivityRecord.getStackLocked(token);
1124 if (stack != null) {
1125 stack.activityPausedLocked(token, false);
1126 }
1127 }
1128 Binder.restoreCallingIdentity(origId);
1129 }
1130
1131 @Override
1132 public final void activityStopped(IBinder token, Bundle icicle,
1133 PersistableBundle persistentState, CharSequence description) {
1134 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
1135
1136 // Refuse possible leaked file descriptors
1137 if (icicle != null && icicle.hasFileDescriptors()) {
1138 throw new IllegalArgumentException("File descriptors passed in Bundle");
1139 }
1140
1141 final long origId = Binder.clearCallingIdentity();
1142
1143 synchronized (mGlobalLock) {
1144 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1145 if (r != null) {
1146 r.activityStoppedLocked(icicle, persistentState, description);
1147 }
1148 }
1149
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001150 mAmInternal.trimApplications();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001151
1152 Binder.restoreCallingIdentity(origId);
1153 }
1154
1155 @Override
1156 public final void activityDestroyed(IBinder token) {
1157 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
1158 synchronized (mGlobalLock) {
1159 ActivityStack stack = ActivityRecord.getStackLocked(token);
1160 if (stack != null) {
1161 stack.activityDestroyedLocked(token, "activityDestroyed");
1162 }
1163 }
1164 }
1165
1166 @Override
1167 public final void activityRelaunched(IBinder token) {
1168 final long origId = Binder.clearCallingIdentity();
1169 synchronized (mGlobalLock) {
1170 mStackSupervisor.activityRelaunchedLocked(token);
1171 }
1172 Binder.restoreCallingIdentity(origId);
1173 }
1174
1175 public final void activitySlept(IBinder token) {
1176 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
1177
1178 final long origId = Binder.clearCallingIdentity();
1179
1180 synchronized (mGlobalLock) {
1181 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1182 if (r != null) {
1183 mStackSupervisor.activitySleptLocked(r);
1184 }
1185 }
1186
1187 Binder.restoreCallingIdentity(origId);
1188 }
1189
1190 @Override
1191 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
1192 synchronized (mGlobalLock) {
1193 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1194 if (r == null) {
1195 return;
1196 }
1197 final long origId = Binder.clearCallingIdentity();
1198 try {
1199 r.setRequestedOrientation(requestedOrientation);
1200 } finally {
1201 Binder.restoreCallingIdentity(origId);
1202 }
1203 }
1204 }
1205
1206 @Override
1207 public int getRequestedOrientation(IBinder token) {
1208 synchronized (mGlobalLock) {
1209 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1210 if (r == null) {
1211 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
1212 }
1213 return r.getRequestedOrientation();
1214 }
1215 }
1216
1217 @Override
1218 public void setImmersive(IBinder token, boolean immersive) {
1219 synchronized (mGlobalLock) {
1220 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1221 if (r == null) {
1222 throw new IllegalArgumentException();
1223 }
1224 r.immersive = immersive;
1225
1226 // update associated state if we're frontmost
1227 if (r == mStackSupervisor.getResumedActivityLocked()) {
1228 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001229 applyUpdateLockStateLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001230 }
1231 }
1232 }
1233
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001234 void applyUpdateLockStateLocked(ActivityRecord r) {
1235 // Modifications to the UpdateLock state are done on our handler, outside
1236 // the activity manager's locks. The new state is determined based on the
1237 // state *now* of the relevant activity record. The object is passed to
1238 // the handler solely for logging detail, not to be consulted/modified.
1239 final boolean nextState = r != null && r.immersive;
1240 mH.post(() -> {
1241 if (mUpdateLock.isHeld() != nextState) {
1242 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1243 "Applying new update lock state '" + nextState + "' for " + r);
1244 if (nextState) {
1245 mUpdateLock.acquire();
1246 } else {
1247 mUpdateLock.release();
1248 }
1249 }
1250 });
1251 }
1252
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001253 @Override
1254 public boolean isImmersive(IBinder token) {
1255 synchronized (mGlobalLock) {
1256 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1257 if (r == null) {
1258 throw new IllegalArgumentException();
1259 }
1260 return r.immersive;
1261 }
1262 }
1263
1264 @Override
1265 public boolean isTopActivityImmersive() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001266 enforceNotIsolatedCaller("isTopActivityImmersive");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001267 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001268 final ActivityRecord r = getFocusedStack().topRunningActivityLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001269 return (r != null) ? r.immersive : false;
1270 }
1271 }
1272
1273 @Override
1274 public void overridePendingTransition(IBinder token, String packageName,
1275 int enterAnim, int exitAnim) {
1276 synchronized (mGlobalLock) {
1277 ActivityRecord self = ActivityRecord.isInStackLocked(token);
1278 if (self == null) {
1279 return;
1280 }
1281
1282 final long origId = Binder.clearCallingIdentity();
1283
1284 if (self.isState(
1285 ActivityStack.ActivityState.RESUMED, ActivityStack.ActivityState.PAUSING)) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001286 mWindowManager.overridePendingAppTransition(packageName,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001287 enterAnim, exitAnim, null);
1288 }
1289
1290 Binder.restoreCallingIdentity(origId);
1291 }
1292 }
1293
1294 @Override
1295 public int getFrontActivityScreenCompatMode() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001296 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
1297 ApplicationInfo ai;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001298 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001299 final ActivityRecord r = getFocusedStack().topRunningActivityLocked();
1300 if (r == null) {
1301 return ActivityManager.COMPAT_MODE_UNKNOWN;
1302 }
1303 ai = r.info.applicationInfo;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001304 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001305
1306 return mAmInternal.getPackageScreenCompatMode(ai);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001307 }
1308
1309 @Override
1310 public void setFrontActivityScreenCompatMode(int mode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001311 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001312 "setFrontActivityScreenCompatMode");
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001313 ApplicationInfo ai;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001314 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001315 final ActivityRecord r = getFocusedStack().topRunningActivityLocked();
1316 if (r == null) {
1317 Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity");
1318 return;
1319 }
1320 ai = r.info.applicationInfo;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001321 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001322
1323 mAmInternal.setPackageScreenCompatMode(ai, mode);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001324 }
1325
1326 @Override
1327 public int getLaunchedFromUid(IBinder activityToken) {
1328 ActivityRecord srec;
1329 synchronized (mGlobalLock) {
1330 srec = ActivityRecord.forTokenLocked(activityToken);
1331 }
1332 if (srec == null) {
1333 return -1;
1334 }
1335 return srec.launchedFromUid;
1336 }
1337
1338 @Override
1339 public String getLaunchedFromPackage(IBinder activityToken) {
1340 ActivityRecord srec;
1341 synchronized (mGlobalLock) {
1342 srec = ActivityRecord.forTokenLocked(activityToken);
1343 }
1344 if (srec == null) {
1345 return null;
1346 }
1347 return srec.launchedFromPackage;
1348 }
1349
1350 @Override
1351 public boolean convertFromTranslucent(IBinder token) {
1352 final long origId = Binder.clearCallingIdentity();
1353 try {
1354 synchronized (mGlobalLock) {
1355 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1356 if (r == null) {
1357 return false;
1358 }
1359 final boolean translucentChanged = r.changeWindowTranslucency(true);
1360 if (translucentChanged) {
1361 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
1362 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001363 mWindowManager.setAppFullscreen(token, true);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001364 return translucentChanged;
1365 }
1366 } finally {
1367 Binder.restoreCallingIdentity(origId);
1368 }
1369 }
1370
1371 @Override
1372 public boolean convertToTranslucent(IBinder token, Bundle options) {
1373 SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
1374 final long origId = Binder.clearCallingIdentity();
1375 try {
1376 synchronized (mGlobalLock) {
1377 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1378 if (r == null) {
1379 return false;
1380 }
1381 final TaskRecord task = r.getTask();
1382 int index = task.mActivities.lastIndexOf(r);
1383 if (index > 0) {
1384 ActivityRecord under = task.mActivities.get(index - 1);
1385 under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
1386 }
1387 final boolean translucentChanged = r.changeWindowTranslucency(false);
1388 if (translucentChanged) {
1389 r.getStack().convertActivityToTranslucent(r);
1390 }
1391 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001392 mWindowManager.setAppFullscreen(token, false);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001393 return translucentChanged;
1394 }
1395 } finally {
1396 Binder.restoreCallingIdentity(origId);
1397 }
1398 }
1399
1400 @Override
1401 public void notifyActivityDrawn(IBinder token) {
1402 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
1403 synchronized (mGlobalLock) {
1404 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
1405 if (r != null) {
1406 r.getStack().notifyActivityDrawnLocked(r);
1407 }
1408 }
1409 }
1410
1411 @Override
1412 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
1413 synchronized (mGlobalLock) {
1414 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1415 if (r == null) {
1416 return;
1417 }
1418 r.reportFullyDrawnLocked(restoredFromBundle);
1419 }
1420 }
1421
1422 @Override
1423 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
1424 synchronized (mGlobalLock) {
1425 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
1426 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
1427 return stack.mDisplayId;
1428 }
1429 return DEFAULT_DISPLAY;
1430 }
1431 }
1432
1433 @Override
1434 public ActivityManager.StackInfo getFocusedStackInfo() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001435 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001436 long ident = Binder.clearCallingIdentity();
1437 try {
1438 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001439 ActivityStack focusedStack = getFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001440 if (focusedStack != null) {
1441 return mStackSupervisor.getStackInfo(focusedStack.mStackId);
1442 }
1443 return null;
1444 }
1445 } finally {
1446 Binder.restoreCallingIdentity(ident);
1447 }
1448 }
1449
1450 @Override
1451 public void setFocusedStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001452 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001453 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
1454 final long callingId = Binder.clearCallingIdentity();
1455 try {
1456 synchronized (mGlobalLock) {
1457 final ActivityStack stack = mStackSupervisor.getStack(stackId);
1458 if (stack == null) {
1459 Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
1460 return;
1461 }
1462 final ActivityRecord r = stack.topRunningActivityLocked();
1463 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
1464 r, "setFocusedStack")) {
1465 mStackSupervisor.resumeFocusedStackTopActivityLocked();
1466 }
1467 }
1468 } finally {
1469 Binder.restoreCallingIdentity(callingId);
1470 }
1471 }
1472
1473 @Override
1474 public void setFocusedTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001475 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001476 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
1477 final long callingId = Binder.clearCallingIdentity();
1478 try {
1479 synchronized (mGlobalLock) {
1480 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1481 if (task == null) {
1482 return;
1483 }
1484 final ActivityRecord r = task.topRunningActivityLocked();
1485 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
1486 mStackSupervisor.resumeFocusedStackTopActivityLocked();
1487 }
1488 }
1489 } finally {
1490 Binder.restoreCallingIdentity(callingId);
1491 }
1492 }
1493
1494 @Override
1495 public boolean removeTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001496 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001497 synchronized (mGlobalLock) {
1498 final long ident = Binder.clearCallingIdentity();
1499 try {
1500 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
1501 "remove-task");
1502 } finally {
1503 Binder.restoreCallingIdentity(ident);
1504 }
1505 }
1506 }
1507
1508 @Override
1509 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
1510 synchronized (mGlobalLock) {
1511 final ActivityRecord srec = ActivityRecord.forTokenLocked(token);
1512 if (srec != null) {
1513 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
1514 }
1515 }
1516 return false;
1517 }
1518
1519 @Override
1520 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
1521 Intent resultData) {
1522
1523 synchronized (mGlobalLock) {
1524 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
1525 if (r != null) {
1526 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
1527 }
1528 return false;
1529 }
1530 }
1531
1532 /**
1533 * Attempts to move a task backwards in z-order (the order of activities within the task is
1534 * unchanged).
1535 *
1536 * There are several possible results of this call:
1537 * - if the task is locked, then we will show the lock toast
1538 * - if there is a task behind the provided task, then that task is made visible and resumed as
1539 * this task is moved to the back
1540 * - otherwise, if there are no other tasks in the stack:
1541 * - if this task is in the pinned stack, then we remove the stack completely, which will
1542 * have the effect of moving the task to the top or bottom of the fullscreen stack
1543 * (depending on whether it is visible)
1544 * - otherwise, we simply return home and hide this task
1545 *
1546 * @param token A reference to the activity we wish to move
1547 * @param nonRoot If false then this only works if the activity is the root
1548 * of a task; if true it will work for any activity in a task.
1549 * @return Returns true if the move completed, false if not.
1550 */
1551 @Override
1552 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001553 enforceNotIsolatedCaller("moveActivityTaskToBack");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001554 synchronized (mGlobalLock) {
1555 final long origId = Binder.clearCallingIdentity();
1556 try {
1557 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
1558 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1559 if (task != null) {
1560 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
1561 }
1562 } finally {
1563 Binder.restoreCallingIdentity(origId);
1564 }
1565 }
1566 return false;
1567 }
1568
1569 @Override
1570 public Rect getTaskBounds(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001571 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001572 long ident = Binder.clearCallingIdentity();
1573 Rect rect = new Rect();
1574 try {
1575 synchronized (mGlobalLock) {
1576 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
1577 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1578 if (task == null) {
1579 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
1580 return rect;
1581 }
1582 if (task.getStack() != null) {
1583 // Return the bounds from window manager since it will be adjusted for various
1584 // things like the presense of a docked stack for tasks that aren't resizeable.
1585 task.getWindowContainerBounds(rect);
1586 } else {
1587 // Task isn't in window manager yet since it isn't associated with a stack.
1588 // Return the persist value from activity manager
1589 if (!task.matchParentBounds()) {
1590 rect.set(task.getBounds());
1591 } else if (task.mLastNonFullscreenBounds != null) {
1592 rect.set(task.mLastNonFullscreenBounds);
1593 }
1594 }
1595 }
1596 } finally {
1597 Binder.restoreCallingIdentity(ident);
1598 }
1599 return rect;
1600 }
1601
1602 @Override
1603 public ActivityManager.TaskDescription getTaskDescription(int id) {
1604 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001605 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001606 MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
1607 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
1608 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1609 if (tr != null) {
1610 return tr.lastTaskDescription;
1611 }
1612 }
1613 return null;
1614 }
1615
1616 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001617 public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
1618 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
1619 setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
1620 toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
1621 return;
1622 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001623 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001624 synchronized (mGlobalLock) {
1625 final long ident = Binder.clearCallingIdentity();
1626 try {
1627 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1628 if (task == null) {
1629 Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
1630 return;
1631 }
1632
1633 if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
1634 + " to windowingMode=" + windowingMode + " toTop=" + toTop);
1635
1636 if (!task.isActivityTypeStandardOrUndefined()) {
1637 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
1638 + " non-standard task " + taskId + " to windowing mode="
1639 + windowingMode);
1640 }
1641
1642 final ActivityStack stack = task.getStack();
1643 if (toTop) {
1644 stack.moveToFront("setTaskWindowingMode", task);
1645 }
1646 stack.setWindowingMode(windowingMode);
1647 } finally {
1648 Binder.restoreCallingIdentity(ident);
1649 }
1650 }
1651 }
1652
1653 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001654 public String getCallingPackage(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001655 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001656 ActivityRecord r = getCallingRecordLocked(token);
1657 return r != null ? r.info.packageName : null;
1658 }
1659 }
1660
1661 @Override
1662 public ComponentName getCallingActivity(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001663 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001664 ActivityRecord r = getCallingRecordLocked(token);
1665 return r != null ? r.intent.getComponent() : null;
1666 }
1667 }
1668
1669 private ActivityRecord getCallingRecordLocked(IBinder token) {
1670 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1671 if (r == null) {
1672 return null;
1673 }
1674 return r.resultTo;
1675 }
1676
1677 @Override
1678 public void unhandledBack() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001679 mAmInternal.enforceCallingPermission(android.Manifest.permission.FORCE_BACK, "unhandledBack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001680
1681 synchronized (mGlobalLock) {
1682 final long origId = Binder.clearCallingIdentity();
1683 try {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001684 getFocusedStack().unhandledBackLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001685 } finally {
1686 Binder.restoreCallingIdentity(origId);
1687 }
1688 }
1689 }
1690
1691 /**
1692 * TODO: Add mController hook
1693 */
1694 @Override
1695 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001696 mAmInternal.enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001697
1698 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
1699 synchronized (mGlobalLock) {
1700 moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
1701 false /* fromRecents */);
1702 }
1703 }
1704
1705 void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
1706 boolean fromRecents) {
1707
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001708 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001709 Binder.getCallingUid(), -1, -1, "Task to front")) {
1710 SafeActivityOptions.abort(options);
1711 return;
1712 }
1713 final long origId = Binder.clearCallingIdentity();
1714 try {
1715 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1716 if (task == null) {
1717 Slog.d(TAG, "Could not find task for id: "+ taskId);
1718 return;
1719 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001720 if (getLockTaskController().isLockTaskModeViolation(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001721 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
1722 return;
1723 }
1724 ActivityOptions realOptions = options != null
1725 ? options.getOptions(mStackSupervisor)
1726 : null;
1727 mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
1728 false /* forceNonResizable */);
1729
1730 final ActivityRecord topActivity = task.getTopActivity();
1731 if (topActivity != null) {
1732
1733 // We are reshowing a task, use a starting window to hide the initial draw delay
1734 // so the transition can start earlier.
1735 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
1736 true /* taskSwitch */, fromRecents);
1737 }
1738 } finally {
1739 Binder.restoreCallingIdentity(origId);
1740 }
1741 SafeActivityOptions.abort(options);
1742 }
1743
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001744 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
1745 int callingPid, int callingUid, String name) {
1746 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
1747 return true;
1748 }
1749
1750 if (getRecentTasks().isCallerRecents(sourceUid)) {
1751 return true;
1752 }
1753
1754 int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
1755 if (perm == PackageManager.PERMISSION_GRANTED) {
1756 return true;
1757 }
1758 if (checkAllowAppSwitchUid(sourceUid)) {
1759 return true;
1760 }
1761
1762 // If the actual IPC caller is different from the logical source, then
1763 // also see if they are allowed to control app switches.
1764 if (callingUid != -1 && callingUid != sourceUid) {
1765 perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
1766 if (perm == PackageManager.PERMISSION_GRANTED) {
1767 return true;
1768 }
1769 if (checkAllowAppSwitchUid(callingUid)) {
1770 return true;
1771 }
1772 }
1773
1774 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
1775 return false;
1776 }
1777
1778 private boolean checkAllowAppSwitchUid(int uid) {
1779 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
1780 if (types != null) {
1781 for (int i = types.size() - 1; i >= 0; i--) {
1782 if (types.valueAt(i).intValue() == uid) {
1783 return true;
1784 }
1785 }
1786 }
1787 return false;
1788 }
1789
1790 @Override
1791 public void setActivityController(IActivityController controller, boolean imAMonkey) {
1792 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
1793 "setActivityController()");
1794 synchronized (mGlobalLock) {
1795 mController = controller;
1796 mControllerIsAMonkey = imAMonkey;
1797 Watchdog.getInstance().setActivityController(controller);
1798 }
1799 }
1800
1801 boolean isControllerAMonkey() {
1802 synchronized (mGlobalLock) {
1803 return mController != null && mControllerIsAMonkey;
1804 }
1805 }
1806
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001807 @Override
1808 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
1809 synchronized (mGlobalLock) {
1810 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
1811 }
1812 }
1813
1814 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001815 public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum) {
1816 return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
1817 }
1818
1819 @Override
1820 public List<ActivityManager.RunningTaskInfo> getFilteredTasks(int maxNum,
1821 @WindowConfiguration.ActivityType int ignoreActivityType,
1822 @WindowConfiguration.WindowingMode int ignoreWindowingMode) {
1823 final int callingUid = Binder.getCallingUid();
1824 ArrayList<ActivityManager.RunningTaskInfo> list = new ArrayList<>();
1825
1826 synchronized (mGlobalLock) {
1827 if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
1828
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001829 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001830 callingUid);
1831 mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
1832 ignoreWindowingMode, callingUid, allowed);
1833 }
1834
1835 return list;
1836 }
1837
1838 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001839 public final void finishSubActivity(IBinder token, String resultWho, int requestCode) {
1840 synchronized (mGlobalLock) {
1841 final long origId = Binder.clearCallingIdentity();
1842 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1843 if (r != null) {
1844 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
1845 }
1846 Binder.restoreCallingIdentity(origId);
1847 }
1848 }
1849
1850 @Override
1851 public boolean willActivityBeVisible(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001852 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001853 ActivityStack stack = ActivityRecord.getStackLocked(token);
1854 if (stack != null) {
1855 return stack.willActivityBeVisibleLocked(token);
1856 }
1857 return false;
1858 }
1859 }
1860
1861 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001862 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001863 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001864 synchronized (mGlobalLock) {
1865 final long ident = Binder.clearCallingIdentity();
1866 try {
1867 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1868 if (task == null) {
1869 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
1870 return;
1871 }
1872
1873 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
1874 + " to stackId=" + stackId + " toTop=" + toTop);
1875
1876 final ActivityStack stack = mStackSupervisor.getStack(stackId);
1877 if (stack == null) {
1878 throw new IllegalStateException(
1879 "moveTaskToStack: No stack for stackId=" + stackId);
1880 }
1881 if (!stack.isActivityTypeStandardOrUndefined()) {
1882 throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
1883 + taskId + " to stack " + stackId);
1884 }
1885 if (stack.inSplitScreenPrimaryWindowingMode()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001886 mWindowManager.setDockedStackCreateState(
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001887 SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
1888 }
1889 task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
1890 "moveTaskToStack");
1891 } finally {
1892 Binder.restoreCallingIdentity(ident);
1893 }
1894 }
1895 }
1896
1897 @Override
1898 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
1899 boolean preserveWindows, boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001900 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001901
1902 final long ident = Binder.clearCallingIdentity();
1903 try {
1904 synchronized (mGlobalLock) {
1905 if (animate) {
1906 final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
1907 if (stack == null) {
1908 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
1909 return;
1910 }
1911 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
1912 throw new IllegalArgumentException("Stack: " + stackId
1913 + " doesn't support animated resize.");
1914 }
1915 stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
1916 animationDuration, false /* fromFullscreen */);
1917 } else {
1918 final ActivityStack stack = mStackSupervisor.getStack(stackId);
1919 if (stack == null) {
1920 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
1921 return;
1922 }
1923 mStackSupervisor.resizeStackLocked(stack, destBounds,
1924 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
1925 preserveWindows, allowResizeInDockedMode, !DEFER_RESUME);
1926 }
1927 }
1928 } finally {
1929 Binder.restoreCallingIdentity(ident);
1930 }
1931 }
1932
1933 /**
1934 * Moves the specified task to the primary-split-screen stack.
1935 *
1936 * @param taskId Id of task to move.
1937 * @param createMode The mode the primary split screen stack should be created in if it doesn't
1938 * exist already. See
1939 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
1940 * and
1941 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
1942 * @param toTop If the task and stack should be moved to the top.
1943 * @param animate Whether we should play an animation for the moving the task.
1944 * @param initialBounds If the primary stack gets created, it will use these bounds for the
1945 * stack. Pass {@code null} to use default bounds.
1946 * @param showRecents If the recents activity should be shown on the other side of the task
1947 * going into split-screen mode.
1948 */
1949 @Override
1950 public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode,
1951 boolean toTop, boolean animate, Rect initialBounds, boolean showRecents) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001952 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001953 "setTaskWindowingModeSplitScreenPrimary()");
1954 synchronized (mGlobalLock) {
1955 final long ident = Binder.clearCallingIdentity();
1956 try {
1957 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1958 if (task == null) {
1959 Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
1960 return false;
1961 }
1962 if (DEBUG_STACK) Slog.d(TAG_STACK,
1963 "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
1964 + " to createMode=" + createMode + " toTop=" + toTop);
1965 if (!task.isActivityTypeStandardOrUndefined()) {
1966 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
1967 + " non-standard task " + taskId + " to split-screen windowing mode");
1968 }
1969
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001970 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001971 final int windowingMode = task.getWindowingMode();
1972 final ActivityStack stack = task.getStack();
1973 if (toTop) {
1974 stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
1975 }
1976 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
1977 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */);
1978 return windowingMode != task.getWindowingMode();
1979 } finally {
1980 Binder.restoreCallingIdentity(ident);
1981 }
1982 }
1983 }
1984
1985 /**
1986 * Removes stacks in the input windowing modes from the system if they are of activity type
1987 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
1988 */
1989 @Override
1990 public void removeStacksInWindowingModes(int[] windowingModes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001991 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001992 "removeStacksInWindowingModes()");
1993
1994 synchronized (mGlobalLock) {
1995 final long ident = Binder.clearCallingIdentity();
1996 try {
1997 mStackSupervisor.removeStacksInWindowingModes(windowingModes);
1998 } finally {
1999 Binder.restoreCallingIdentity(ident);
2000 }
2001 }
2002 }
2003
2004 @Override
2005 public void removeStacksWithActivityTypes(int[] activityTypes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002006 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002007 "removeStacksWithActivityTypes()");
2008
2009 synchronized (mGlobalLock) {
2010 final long ident = Binder.clearCallingIdentity();
2011 try {
2012 mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
2013 } finally {
2014 Binder.restoreCallingIdentity(ident);
2015 }
2016 }
2017 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002018
2019 @Override
2020 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
2021 int userId) {
2022 final int callingUid = Binder.getCallingUid();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002023 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, "getRecentTasks");
2024 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002025 callingUid);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002026 final boolean detailed = checkGetTasksPermission(
2027 android.Manifest.permission.GET_DETAILED_TASKS, Binder.getCallingPid(),
2028 UserHandle.getAppId(callingUid))
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002029 == PackageManager.PERMISSION_GRANTED;
2030
2031 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002032 return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002033 callingUid);
2034 }
2035 }
2036
2037 @Override
2038 public List<ActivityManager.StackInfo> getAllStackInfos() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002039 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002040 long ident = Binder.clearCallingIdentity();
2041 try {
2042 synchronized (mGlobalLock) {
2043 return mStackSupervisor.getAllStackInfosLocked();
2044 }
2045 } finally {
2046 Binder.restoreCallingIdentity(ident);
2047 }
2048 }
2049
2050 @Override
2051 public ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002052 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002053 long ident = Binder.clearCallingIdentity();
2054 try {
2055 synchronized (mGlobalLock) {
2056 return mStackSupervisor.getStackInfo(windowingMode, activityType);
2057 }
2058 } finally {
2059 Binder.restoreCallingIdentity(ident);
2060 }
2061 }
2062
2063 @Override
2064 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002065 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002066 final long callingUid = Binder.getCallingUid();
2067 final long origId = Binder.clearCallingIdentity();
2068 try {
2069 synchronized (mGlobalLock) {
2070 // Cancel the recents animation synchronously (do not hold the WM lock)
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002071 mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002072 ? REORDER_MOVE_TO_ORIGINAL_POSITION
2073 : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
2074 }
2075 } finally {
2076 Binder.restoreCallingIdentity(origId);
2077 }
2078 }
2079
2080 @Override
2081 public void startLockTaskModeByToken(IBinder token) {
2082 synchronized (mGlobalLock) {
2083 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2084 if (r == null) {
2085 return;
2086 }
2087 startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
2088 }
2089 }
2090
2091 @Override
2092 public void startSystemLockTaskMode(int taskId) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002093 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002094 // This makes inner call to look as if it was initiated by system.
2095 long ident = Binder.clearCallingIdentity();
2096 try {
2097 synchronized (mGlobalLock) {
2098 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2099
2100 // When starting lock task mode the stack must be in front and focused
2101 task.getStack().moveToFront("startSystemLockTaskMode");
2102 startLockTaskModeLocked(task, true /* isSystemCaller */);
2103 }
2104 } finally {
2105 Binder.restoreCallingIdentity(ident);
2106 }
2107 }
2108
2109 @Override
2110 public void stopLockTaskModeByToken(IBinder token) {
2111 synchronized (mGlobalLock) {
2112 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2113 if (r == null) {
2114 return;
2115 }
2116 stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
2117 }
2118 }
2119
2120 /**
2121 * This API should be called by SystemUI only when user perform certain action to dismiss
2122 * lock task mode. We should only dismiss pinned lock task mode in this case.
2123 */
2124 @Override
2125 public void stopSystemLockTaskMode() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002126 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002127 stopLockTaskModeInternal(null, true /* isSystemCaller */);
2128 }
2129
2130 private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
2131 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
2132 if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
2133 return;
2134 }
2135
2136 final ActivityStack stack = mStackSupervisor.getFocusedStack();
2137 if (stack == null || task != stack.topTask()) {
2138 throw new IllegalArgumentException("Invalid task, not in foreground");
2139 }
2140
2141 // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
2142 // system or a specific app.
2143 // * System-initiated requests will only start the pinned mode (screen pinning)
2144 // * App-initiated requests
2145 // - will put the device in fully locked mode (LockTask), if the app is whitelisted
2146 // - will start the pinned mode, otherwise
2147 final int callingUid = Binder.getCallingUid();
2148 long ident = Binder.clearCallingIdentity();
2149 try {
2150 // When a task is locked, dismiss the pinned stack if it exists
2151 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2152
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002153 getLockTaskController().startLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002154 } finally {
2155 Binder.restoreCallingIdentity(ident);
2156 }
2157 }
2158
2159 private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
2160 final int callingUid = Binder.getCallingUid();
2161 long ident = Binder.clearCallingIdentity();
2162 try {
2163 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002164 getLockTaskController().stopLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002165 }
2166 // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
2167 // task and jumping straight into a call in the case of emergency call back.
2168 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
2169 if (tm != null) {
2170 tm.showInCallScreen(false);
2171 }
2172 } finally {
2173 Binder.restoreCallingIdentity(ident);
2174 }
2175 }
2176
2177 @Override
2178 public boolean isInLockTaskMode() {
2179 return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
2180 }
2181
2182 @Override
2183 public int getLockTaskModeState() {
2184 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002185 return getLockTaskController().getLockTaskModeState();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002186 }
2187 }
2188
2189 @Override
2190 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
2191 synchronized (mGlobalLock) {
2192 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2193 if (r != null) {
2194 r.setTaskDescription(td);
2195 final TaskRecord task = r.getTask();
2196 task.updateTaskDescription();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002197 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002198 }
2199 }
2200 }
2201
2202 @Override
2203 public Bundle getActivityOptions(IBinder token) {
2204 final long origId = Binder.clearCallingIdentity();
2205 try {
2206 synchronized (mGlobalLock) {
2207 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
2208 if (r != null) {
2209 final ActivityOptions activityOptions = r.takeOptionsLocked();
2210 return activityOptions == null ? null : activityOptions.toBundle();
2211 }
2212 return null;
2213 }
2214 } finally {
2215 Binder.restoreCallingIdentity(origId);
2216 }
2217 }
2218
2219 @Override
2220 public List<IBinder> getAppTasks(String callingPackage) {
2221 int callingUid = Binder.getCallingUid();
2222 long ident = Binder.clearCallingIdentity();
2223 try {
2224 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002225 return mRecentTasks.getAppTasksList(callingUid, callingPackage);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002226 }
2227 } finally {
2228 Binder.restoreCallingIdentity(ident);
2229 }
2230 }
2231
2232 @Override
2233 public void finishVoiceTask(IVoiceInteractionSession session) {
2234 synchronized (mGlobalLock) {
2235 final long origId = Binder.clearCallingIdentity();
2236 try {
2237 // TODO: VI Consider treating local voice interactions and voice tasks
2238 // differently here
2239 mStackSupervisor.finishVoiceTask(session);
2240 } finally {
2241 Binder.restoreCallingIdentity(origId);
2242 }
2243 }
2244
2245 }
2246
2247 @Override
2248 public boolean isTopOfTask(IBinder token) {
2249 synchronized (mGlobalLock) {
2250 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2251 if (r == null) {
2252 throw new IllegalArgumentException();
2253 }
2254 return r.getTask().getTopActivity() == r;
2255 }
2256 }
2257
2258 @Override
2259 public void notifyLaunchTaskBehindComplete(IBinder token) {
2260 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
2261 }
2262
2263 @Override
2264 public void notifyEnterAnimationComplete(IBinder token) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002265 mH.post(() -> {
2266 synchronized (mGlobalLock) {
2267 ActivityRecord r = ActivityRecord.forTokenLocked(token);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002268 if (r != null && r.attachedToProcess()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002269 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002270 r.app.getThread().scheduleEnterAnimationComplete(r.appToken);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002271 } catch (RemoteException e) {
2272 }
2273 }
2274 }
2275
2276 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002277 }
2278
2279 /** Called from an app when assist data is ready. */
2280 @Override
2281 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
2282 AssistContent content, Uri referrer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002283 PendingAssistExtras pae = (PendingAssistExtras) token;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002284 synchronized (pae) {
2285 pae.result = extras;
2286 pae.structure = structure;
2287 pae.content = content;
2288 if (referrer != null) {
2289 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
2290 }
2291 if (structure != null) {
2292 structure.setHomeActivity(pae.isHome);
2293 }
2294 pae.haveResult = true;
2295 pae.notifyAll();
2296 if (pae.intent == null && pae.receiver == null) {
2297 // Caller is just waiting for the result.
2298 return;
2299 }
2300 }
2301 // We are now ready to launch the assist activity.
2302 IAssistDataReceiver sendReceiver = null;
2303 Bundle sendBundle = null;
2304 synchronized (mGlobalLock) {
2305 buildAssistBundleLocked(pae, extras);
2306 boolean exists = mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002307 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002308 if (!exists) {
2309 // Timed out.
2310 return;
2311 }
2312
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002313 if ((sendReceiver = pae.receiver) != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002314 // Caller wants result sent back to them.
2315 sendBundle = new Bundle();
2316 sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
2317 sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
2318 sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
2319 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
2320 }
2321 }
2322 if (sendReceiver != null) {
2323 try {
2324 sendReceiver.onHandleAssistData(sendBundle);
2325 } catch (RemoteException e) {
2326 }
2327 return;
2328 }
2329
2330 final long ident = Binder.clearCallingIdentity();
2331 try {
2332 if (TextUtils.equals(pae.intent.getAction(),
2333 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
2334 pae.intent.putExtras(pae.extras);
2335 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
2336 } else {
2337 pae.intent.replaceExtras(pae.extras);
2338 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
2339 | Intent.FLAG_ACTIVITY_SINGLE_TOP
2340 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002341 mAmInternal.closeSystemDialogs("assist");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002342
2343 try {
2344 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
2345 } catch (ActivityNotFoundException e) {
2346 Slog.w(TAG, "No activity to handle assist action.", e);
2347 }
2348 }
2349 } finally {
2350 Binder.restoreCallingIdentity(ident);
2351 }
2352 }
2353
2354 @Override
2355 public int addAppTask(IBinder activityToken, Intent intent,
2356 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
2357 final int callingUid = Binder.getCallingUid();
2358 final long callingIdent = Binder.clearCallingIdentity();
2359
2360 try {
2361 synchronized (mGlobalLock) {
2362 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
2363 if (r == null) {
2364 throw new IllegalArgumentException("Activity does not exist; token="
2365 + activityToken);
2366 }
2367 ComponentName comp = intent.getComponent();
2368 if (comp == null) {
2369 throw new IllegalArgumentException("Intent " + intent
2370 + " must specify explicit component");
2371 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002372 if (thumbnail.getWidth() != mThumbnailWidth
2373 || thumbnail.getHeight() != mThumbnailHeight) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002374 throw new IllegalArgumentException("Bad thumbnail size: got "
2375 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002376 + mThumbnailWidth + "x" + mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002377 }
2378 if (intent.getSelector() != null) {
2379 intent.setSelector(null);
2380 }
2381 if (intent.getSourceBounds() != null) {
2382 intent.setSourceBounds(null);
2383 }
2384 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
2385 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
2386 // The caller has added this as an auto-remove task... that makes no
2387 // sense, so turn off auto-remove.
2388 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
2389 }
2390 }
2391 final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
2392 STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
2393 if (ainfo.applicationInfo.uid != callingUid) {
2394 throw new SecurityException(
2395 "Can't add task for another application: target uid="
2396 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
2397 }
2398
2399 final ActivityStack stack = r.getStack();
2400 final TaskRecord task = stack.createTaskRecord(
2401 mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent,
2402 null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002403 if (!mRecentTasks.addToBottom(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002404 // The app has too many tasks already and we can't add any more
2405 stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
2406 return INVALID_TASK_ID;
2407 }
2408 task.lastTaskDescription.copyFrom(description);
2409
2410 // TODO: Send the thumbnail to WM to store it.
2411
2412 return task.taskId;
2413 }
2414 } finally {
2415 Binder.restoreCallingIdentity(callingIdent);
2416 }
2417 }
2418
2419 @Override
2420 public Point getAppTaskThumbnailSize() {
2421 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002422 return new Point(mThumbnailWidth, mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002423 }
2424 }
2425
2426 @Override
2427 public void setTaskResizeable(int taskId, int resizeableMode) {
2428 synchronized (mGlobalLock) {
2429 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
2430 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
2431 if (task == null) {
2432 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
2433 return;
2434 }
2435 task.setResizeMode(resizeableMode);
2436 }
2437 }
2438
2439 @Override
2440 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002441 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002442 long ident = Binder.clearCallingIdentity();
2443 try {
2444 synchronized (mGlobalLock) {
2445 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2446 if (task == null) {
2447 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
2448 return;
2449 }
2450 // Place the task in the right stack if it isn't there already based on
2451 // the requested bounds.
2452 // The stack transition logic is:
2453 // - a null bounds on a freeform task moves that task to fullscreen
2454 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
2455 // that task to freeform
2456 // - otherwise the task is not moved
2457 ActivityStack stack = task.getStack();
2458 if (!task.getWindowConfiguration().canResizeTask()) {
2459 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
2460 }
2461 if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
2462 stack = stack.getDisplay().getOrCreateStack(
2463 WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
2464 } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
2465 stack = stack.getDisplay().getOrCreateStack(
2466 WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
2467 }
2468
2469 // Reparent the task to the right stack if necessary
2470 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
2471 if (stack != task.getStack()) {
2472 // Defer resume until the task is resized below
2473 task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
2474 DEFER_RESUME, "resizeTask");
2475 preserveWindow = false;
2476 }
2477
2478 // After reparenting (which only resizes the task to the stack bounds), resize the
2479 // task to the actual bounds provided
2480 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
2481 }
2482 } finally {
2483 Binder.restoreCallingIdentity(ident);
2484 }
2485 }
2486
2487 @Override
2488 public boolean releaseActivityInstance(IBinder token) {
2489 synchronized (mGlobalLock) {
2490 final long origId = Binder.clearCallingIdentity();
2491 try {
2492 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2493 if (r == null) {
2494 return false;
2495 }
2496 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
2497 } finally {
2498 Binder.restoreCallingIdentity(origId);
2499 }
2500 }
2501 }
2502
2503 @Override
2504 public void releaseSomeActivities(IApplicationThread appInt) {
2505 synchronized (mGlobalLock) {
2506 final long origId = Binder.clearCallingIdentity();
2507 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002508 WindowProcessController app =
2509 mAm.getRecordForAppLocked(appInt).getWindowProcessController();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002510 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
2511 } finally {
2512 Binder.restoreCallingIdentity(origId);
2513 }
2514 }
2515 }
2516
2517 @Override
2518 public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
2519 int secondaryDisplayShowing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002520 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002521 != PackageManager.PERMISSION_GRANTED) {
2522 throw new SecurityException("Requires permission "
2523 + android.Manifest.permission.DEVICE_POWER);
2524 }
2525
2526 synchronized (mGlobalLock) {
2527 long ident = Binder.clearCallingIdentity();
2528 if (mKeyguardShown != keyguardShowing) {
2529 mKeyguardShown = keyguardShowing;
2530 reportCurKeyguardUsageEventLocked(keyguardShowing);
2531 }
2532 try {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002533 mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002534 secondaryDisplayShowing);
2535 } finally {
2536 Binder.restoreCallingIdentity(ident);
2537 }
2538 }
2539
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002540 mH.post(() -> {
2541 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2542 mScreenObservers.get(i).onKeyguardStateChanged(keyguardShowing);
2543 }
2544 });
2545 }
2546
2547 void onScreenAwakeChanged(boolean isAwake) {
2548 mH.post(() -> {
2549 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2550 mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2551 }
2552 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002553 }
2554
2555 @Override
2556 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002557 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
2558 userId, "getTaskDescriptionIcon");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002559
2560 final File passedIconFile = new File(filePath);
2561 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
2562 passedIconFile.getName());
2563 if (!legitIconFile.getPath().equals(filePath)
2564 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
2565 throw new IllegalArgumentException("Bad file path: " + filePath
2566 + " passed for userId " + userId);
2567 }
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002568 return mRecentTasks.getTaskDescriptionIcon(filePath);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002569 }
2570
2571 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002572 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002573 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
2574 final ActivityOptions activityOptions = safeOptions != null
2575 ? safeOptions.getOptions(mStackSupervisor)
2576 : null;
2577 if (activityOptions == null
2578 || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
2579 || activityOptions.getCustomInPlaceResId() == 0) {
2580 throw new IllegalArgumentException("Expected in-place ActivityOption " +
2581 "with valid animation");
2582 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002583 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
2584 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002585 activityOptions.getCustomInPlaceResId());
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002586 mWindowManager.executeAppTransition();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002587 }
2588
2589 @Override
2590 public void removeStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002591 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002592 synchronized (mGlobalLock) {
2593 final long ident = Binder.clearCallingIdentity();
2594 try {
2595 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2596 if (stack == null) {
2597 Slog.w(TAG, "removeStack: No stack with id=" + stackId);
2598 return;
2599 }
2600 if (!stack.isActivityTypeStandardOrUndefined()) {
2601 throw new IllegalArgumentException(
2602 "Removing non-standard stack is not allowed.");
2603 }
2604 mStackSupervisor.removeStack(stack);
2605 } finally {
2606 Binder.restoreCallingIdentity(ident);
2607 }
2608 }
2609 }
2610
2611 @Override
2612 public void moveStackToDisplay(int stackId, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002613 mAmInternal.enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002614
2615 synchronized (mGlobalLock) {
2616 final long ident = Binder.clearCallingIdentity();
2617 try {
2618 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
2619 + " to displayId=" + displayId);
2620 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
2621 } finally {
2622 Binder.restoreCallingIdentity(ident);
2623 }
2624 }
2625 }
2626
2627 @Override
2628 public int createStackOnDisplay(int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002629 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002630 synchronized (mGlobalLock) {
2631 final ActivityDisplay display =
2632 mStackSupervisor.getActivityDisplayOrCreateLocked(displayId);
2633 if (display == null) {
2634 return INVALID_STACK_ID;
2635 }
2636 // TODO(multi-display): Have the caller pass in the windowing mode and activity type.
2637 final ActivityStack stack = display.createStack(
2638 WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
2639 ON_TOP);
2640 return (stack != null) ? stack.mStackId : INVALID_STACK_ID;
2641 }
2642 }
2643
2644 @Override
2645 public void exitFreeformMode(IBinder token) {
2646 synchronized (mGlobalLock) {
2647 long ident = Binder.clearCallingIdentity();
2648 try {
2649 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2650 if (r == null) {
2651 throw new IllegalArgumentException(
2652 "exitFreeformMode: No activity record matching token=" + token);
2653 }
2654
2655 final ActivityStack stack = r.getStack();
2656 if (stack == null || !stack.inFreeformWindowingMode()) {
2657 throw new IllegalStateException(
2658 "exitFreeformMode: You can only go fullscreen from freeform.");
2659 }
2660
2661 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
2662 } finally {
2663 Binder.restoreCallingIdentity(ident);
2664 }
2665 }
2666 }
2667
2668 /** Sets the task stack listener that gets callbacks when a task stack changes. */
2669 @Override
2670 public void registerTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002671 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002672 "registerTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002673 mTaskChangeNotificationController.registerTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002674 }
2675
2676 /** Unregister a task stack listener so that it stops receiving callbacks. */
2677 @Override
2678 public void unregisterTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002679 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002680 "unregisterTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002681 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002682 }
2683
2684 private void reportCurKeyguardUsageEventLocked(boolean keyguardShowing) {
2685 mAm.reportGlobalUsageEventLocked(keyguardShowing
2686 ? UsageEvents.Event.KEYGUARD_SHOWN
2687 : UsageEvents.Event.KEYGUARD_HIDDEN);
2688 }
2689
2690 @Override
2691 public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
2692 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
2693 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
2694 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
2695 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
2696 }
2697
2698 @Override
2699 public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
2700 IBinder activityToken, int flags) {
2701 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
2702 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
2703 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
2704 }
2705
2706 @Override
2707 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
2708 Bundle args) {
2709 return enqueueAssistContext(requestType, intent, hint, null, null, null,
2710 true /* focused */, true /* newSessionId */, userHandle, args,
2711 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
2712 }
2713
2714 @Override
2715 public Bundle getAssistContextExtras(int requestType) {
2716 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
2717 null, null, true /* focused */, true /* newSessionId */,
2718 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
2719 if (pae == null) {
2720 return null;
2721 }
2722 synchronized (pae) {
2723 while (!pae.haveResult) {
2724 try {
2725 pae.wait();
2726 } catch (InterruptedException e) {
2727 }
2728 }
2729 }
2730 synchronized (mGlobalLock) {
2731 buildAssistBundleLocked(pae, pae.result);
2732 mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002733 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002734 }
2735 return pae.extras;
2736 }
2737
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002738 /**
2739 * Binder IPC calls go through the public entry point.
2740 * This can be called with or without the global lock held.
2741 */
2742 private static int checkCallingPermission(String permission) {
2743 return checkPermission(
2744 permission, Binder.getCallingPid(), UserHandle.getAppId(Binder.getCallingUid()));
2745 }
2746
2747 /** This can be called with or without the global lock held. */
2748 void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
2749 if (!getRecentTasks().isCallerRecents(Binder.getCallingUid())) {
2750 mAmInternal.enforceCallingPermission(permission, func);
2751 }
2752 }
2753
2754 @VisibleForTesting
2755 int checkGetTasksPermission(String permission, int pid, int uid) {
2756 return checkPermission(permission, pid, uid);
2757 }
2758
2759 static int checkPermission(String permission, int pid, int uid) {
2760 if (permission == null) {
2761 return PackageManager.PERMISSION_DENIED;
2762 }
2763 return checkComponentPermission(permission, pid, uid, -1, true);
2764 }
2765
2766 boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
2767 if (getRecentTasks().isCallerRecents(callingUid)) {
2768 // Always allow the recents component to get tasks
2769 return true;
2770 }
2771
2772 boolean allowed = checkGetTasksPermission(android.Manifest.permission.REAL_GET_TASKS,
2773 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
2774 if (!allowed) {
2775 if (checkGetTasksPermission(android.Manifest.permission.GET_TASKS,
2776 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
2777 // Temporary compatibility: some existing apps on the system image may
2778 // still be requesting the old permission and not switched to the new
2779 // one; if so, we'll still allow them full access. This means we need
2780 // to see if they are holding the old permission and are a system app.
2781 try {
2782 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
2783 allowed = true;
2784 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
2785 + " is using old GET_TASKS but privileged; allowing");
2786 }
2787 } catch (RemoteException e) {
2788 }
2789 }
2790 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
2791 + " does not hold REAL_GET_TASKS; limiting output");
2792 }
2793 return allowed;
2794 }
2795
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002796 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
2797 IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
2798 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
2799 int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002800 mAmInternal.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002801 "enqueueAssistContext()");
2802
2803 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002804 ActivityRecord activity = getFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002805 if (activity == null) {
2806 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
2807 return null;
2808 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002809 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002810 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
2811 return null;
2812 }
2813 if (focused) {
2814 if (activityToken != null) {
2815 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
2816 if (activity != caller) {
2817 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
2818 + " is not current top " + activity);
2819 return null;
2820 }
2821 }
2822 } else {
2823 activity = ActivityRecord.forTokenLocked(activityToken);
2824 if (activity == null) {
2825 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
2826 + " couldn't be found");
2827 return null;
2828 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002829 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002830 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
2831 return null;
2832 }
2833 }
2834
2835 PendingAssistExtras pae;
2836 Bundle extras = new Bundle();
2837 if (args != null) {
2838 extras.putAll(args);
2839 }
2840 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002841 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002842
2843 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
2844 userHandle);
2845 pae.isHome = activity.isActivityTypeHome();
2846
2847 // Increment the sessionId if necessary
2848 if (newSessionId) {
2849 mViSessionId++;
2850 }
2851 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002852 activity.app.getThread().requestAssistContextExtras(activity.appToken, pae,
2853 requestType, mViSessionId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002854 mPendingAssistExtras.add(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002855 mUiHandler.postDelayed(pae, timeout);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002856 } catch (RemoteException e) {
2857 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
2858 return null;
2859 }
2860 return pae;
2861 }
2862 }
2863
2864 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
2865 if (result != null) {
2866 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
2867 }
2868 if (pae.hint != null) {
2869 pae.extras.putBoolean(pae.hint, true);
2870 }
2871 }
2872
2873 private void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
2874 IAssistDataReceiver receiver;
2875 synchronized (mGlobalLock) {
2876 mPendingAssistExtras.remove(pae);
2877 receiver = pae.receiver;
2878 }
2879 if (receiver != null) {
2880 // Caller wants result sent back to them.
2881 Bundle sendBundle = new Bundle();
2882 // At least return the receiver extras
2883 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
2884 try {
2885 pae.receiver.onHandleAssistData(sendBundle);
2886 } catch (RemoteException e) {
2887 }
2888 }
2889 }
2890
2891 public class PendingAssistExtras extends Binder implements Runnable {
2892 public final ActivityRecord activity;
2893 public boolean isHome;
2894 public final Bundle extras;
2895 public final Intent intent;
2896 public final String hint;
2897 public final IAssistDataReceiver receiver;
2898 public final int userHandle;
2899 public boolean haveResult = false;
2900 public Bundle result = null;
2901 public AssistStructure structure = null;
2902 public AssistContent content = null;
2903 public Bundle receiverExtras;
2904
2905 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
2906 String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
2907 int _userHandle) {
2908 activity = _activity;
2909 extras = _extras;
2910 intent = _intent;
2911 hint = _hint;
2912 receiver = _receiver;
2913 receiverExtras = _receiverExtras;
2914 userHandle = _userHandle;
2915 }
2916
2917 @Override
2918 public void run() {
2919 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
2920 synchronized (this) {
2921 haveResult = true;
2922 notifyAll();
2923 }
2924 pendingAssistExtrasTimedOut(this);
2925 }
2926 }
2927
2928 @Override
2929 public boolean isAssistDataAllowedOnCurrentActivity() {
2930 int userId;
2931 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002932 final ActivityStack focusedStack = getFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002933 if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
2934 return false;
2935 }
2936
2937 final ActivityRecord activity = focusedStack.getTopActivity();
2938 if (activity == null) {
2939 return false;
2940 }
2941 userId = activity.userId;
2942 }
2943 return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
2944 }
2945
2946 @Override
2947 public boolean showAssistFromActivity(IBinder token, Bundle args) {
2948 long ident = Binder.clearCallingIdentity();
2949 try {
2950 synchronized (mGlobalLock) {
2951 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002952 ActivityRecord top = getFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002953 if (top != caller) {
2954 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
2955 + " is not current top " + top);
2956 return false;
2957 }
2958 if (!top.nowVisible) {
2959 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
2960 + " is not visible");
2961 return false;
2962 }
2963 }
2964 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
2965 token);
2966 } finally {
2967 Binder.restoreCallingIdentity(ident);
2968 }
2969 }
2970
2971 @Override
2972 public boolean isRootVoiceInteraction(IBinder token) {
2973 synchronized (mGlobalLock) {
2974 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2975 if (r == null) {
2976 return false;
2977 }
2978 return r.rootVoiceInteraction;
2979 }
2980 }
2981
2982 @Override
2983 public ComponentName getActivityClassForToken(IBinder token) {
2984 synchronized (mGlobalLock) {
2985 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2986 if (r == null) {
2987 return null;
2988 }
2989 return r.intent.getComponent();
2990 }
2991 }
2992
2993 @Override
2994 public String getPackageForToken(IBinder token) {
2995 synchronized (mGlobalLock) {
2996 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2997 if (r == null) {
2998 return null;
2999 }
3000 return r.packageName;
3001 }
3002 }
3003
3004 @Override
3005 public void showLockTaskEscapeMessage(IBinder token) {
3006 synchronized (mGlobalLock) {
3007 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3008 if (r == null) {
3009 return;
3010 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003011 getLockTaskController().showLockTaskToast();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003012 }
3013 }
3014
3015 @Override
3016 public void keyguardGoingAway(int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003017 enforceNotIsolatedCaller("keyguardGoingAway");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003018 final long token = Binder.clearCallingIdentity();
3019 try {
3020 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003021 mKeyguardController.keyguardGoingAway(flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003022 }
3023 } finally {
3024 Binder.restoreCallingIdentity(token);
3025 }
3026 }
3027
3028 /**
3029 * Try to place task to provided position. The final position might be different depending on
3030 * current user and stacks state. The task will be moved to target stack if it's currently in
3031 * different stack.
3032 */
3033 @Override
3034 public void positionTaskInStack(int taskId, int stackId, int position) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003035 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003036 synchronized (mGlobalLock) {
3037 long ident = Binder.clearCallingIdentity();
3038 try {
3039 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
3040 + taskId + " in stackId=" + stackId + " at position=" + position);
3041 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3042 if (task == null) {
3043 throw new IllegalArgumentException("positionTaskInStack: no task for id="
3044 + taskId);
3045 }
3046
3047 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3048
3049 if (stack == null) {
3050 throw new IllegalArgumentException("positionTaskInStack: no stack for id="
3051 + stackId);
3052 }
3053 if (!stack.isActivityTypeStandardOrUndefined()) {
3054 throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
3055 + " the position of task " + taskId + " in/to non-standard stack");
3056 }
3057
3058 // TODO: Have the callers of this API call a separate reparent method if that is
3059 // what they intended to do vs. having this method also do reparenting.
3060 if (task.getStack() == stack) {
3061 // Change position in current stack.
3062 stack.positionChildAt(task, position);
3063 } else {
3064 // Reparent to new stack.
3065 task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
3066 !DEFER_RESUME, "positionTaskInStack");
3067 }
3068 } finally {
3069 Binder.restoreCallingIdentity(ident);
3070 }
3071 }
3072 }
3073
3074 @Override
3075 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
3076 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
3077 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
3078 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
3079 synchronized (mGlobalLock) {
3080 ActivityRecord record = ActivityRecord.isInStackLocked(token);
3081 if (record == null) {
3082 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
3083 + "found for: " + token);
3084 }
3085 record.setSizeConfigurations(horizontalSizeConfiguration,
3086 verticalSizeConfigurations, smallestSizeConfigurations);
3087 }
3088 }
3089
3090 /**
3091 * Dismisses split-screen multi-window mode.
3092 * @param toTop If true the current primary split-screen stack will be placed or left on top.
3093 */
3094 @Override
3095 public void dismissSplitScreenMode(boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003096 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003097 MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
3098 final long ident = Binder.clearCallingIdentity();
3099 try {
3100 synchronized (mGlobalLock) {
3101 final ActivityStack stack =
3102 mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
3103 if (stack == null) {
3104 Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
3105 return;
3106 }
3107
3108 if (toTop) {
3109 // Caller wants the current split-screen primary stack to be the top stack after
3110 // it goes fullscreen, so move it to the front.
3111 stack.moveToFront("dismissSplitScreenMode");
3112 } else if (mStackSupervisor.isFocusedStack(stack)) {
3113 // In this case the current split-screen primary stack shouldn't be the top
3114 // stack after it goes fullscreen, but it current has focus, so we move the
3115 // focus to the top-most split-screen secondary stack next to it.
3116 final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
3117 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
3118 if (otherStack != null) {
3119 otherStack.moveToFront("dismissSplitScreenMode_other");
3120 }
3121 }
3122
3123 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
3124 }
3125 } finally {
3126 Binder.restoreCallingIdentity(ident);
3127 }
3128 }
3129
3130 /**
3131 * Dismisses Pip
3132 * @param animate True if the dismissal should be animated.
3133 * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
3134 * default animation duration should be used.
3135 */
3136 @Override
3137 public void dismissPip(boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003138 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003139 final long ident = Binder.clearCallingIdentity();
3140 try {
3141 synchronized (mGlobalLock) {
3142 final PinnedActivityStack stack =
3143 mStackSupervisor.getDefaultDisplay().getPinnedStack();
3144 if (stack == null) {
3145 Slog.w(TAG, "dismissPip: pinned stack not found.");
3146 return;
3147 }
3148 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
3149 throw new IllegalArgumentException("Stack: " + stack
3150 + " doesn't support animated resize.");
3151 }
3152 if (animate) {
3153 stack.animateResizePinnedStack(null /* sourceHintBounds */,
3154 null /* destBounds */, animationDuration, false /* fromFullscreen */);
3155 } else {
3156 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
3157 }
3158 }
3159 } finally {
3160 Binder.restoreCallingIdentity(ident);
3161 }
3162 }
3163
3164 @Override
3165 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003166 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003167 synchronized (mGlobalLock) {
3168 mSuppressResizeConfigChanges = suppress;
3169 }
3170 }
3171
3172 /**
3173 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
3174 * animated the stack to the fullscreen, but can also be called if we are relaunching an
3175 * activity and clearing the task at the same time.
3176 */
3177 @Override
3178 // TODO: API should just be about changing windowing modes...
3179 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003180 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003181 "moveTasksToFullscreenStack()");
3182 synchronized (mGlobalLock) {
3183 final long origId = Binder.clearCallingIdentity();
3184 try {
3185 final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
3186 if (stack != null){
3187 if (!stack.isActivityTypeStandardOrUndefined()) {
3188 throw new IllegalArgumentException(
3189 "You can't move tasks from non-standard stacks.");
3190 }
3191 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
3192 }
3193 } finally {
3194 Binder.restoreCallingIdentity(origId);
3195 }
3196 }
3197 }
3198
3199 /**
3200 * Moves the top activity in the input stackId to the pinned stack.
3201 *
3202 * @param stackId Id of stack to move the top activity to pinned stack.
3203 * @param bounds Bounds to use for pinned stack.
3204 *
3205 * @return True if the top activity of the input stack was successfully moved to the pinned
3206 * stack.
3207 */
3208 @Override
3209 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003210 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003211 "moveTopActivityToPinnedStack()");
3212 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003213 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003214 throw new IllegalStateException("moveTopActivityToPinnedStack:"
3215 + "Device doesn't support picture-in-picture mode");
3216 }
3217
3218 long ident = Binder.clearCallingIdentity();
3219 try {
3220 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
3221 } finally {
3222 Binder.restoreCallingIdentity(ident);
3223 }
3224 }
3225 }
3226
3227 @Override
3228 public boolean isInMultiWindowMode(IBinder token) {
3229 final long origId = Binder.clearCallingIdentity();
3230 try {
3231 synchronized (mGlobalLock) {
3232 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3233 if (r == null) {
3234 return false;
3235 }
3236 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
3237 return r.inMultiWindowMode();
3238 }
3239 } finally {
3240 Binder.restoreCallingIdentity(origId);
3241 }
3242 }
3243
3244 @Override
3245 public boolean isInPictureInPictureMode(IBinder token) {
3246 final long origId = Binder.clearCallingIdentity();
3247 try {
3248 synchronized (mGlobalLock) {
3249 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
3250 }
3251 } finally {
3252 Binder.restoreCallingIdentity(origId);
3253 }
3254 }
3255
3256 private boolean isInPictureInPictureMode(ActivityRecord r) {
3257 if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
3258 || r.getStack().isInStackLocked(r) == null) {
3259 return false;
3260 }
3261
3262 // If we are animating to fullscreen then we have already dispatched the PIP mode
3263 // changed, so we should reflect that check here as well.
3264 final PinnedActivityStack stack = r.getStack();
3265 final PinnedStackWindowController windowController = stack.getWindowContainerController();
3266 return !windowController.isAnimatingBoundsToFullscreen();
3267 }
3268
3269 @Override
3270 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
3271 final long origId = Binder.clearCallingIdentity();
3272 try {
3273 synchronized (mGlobalLock) {
3274 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3275 "enterPictureInPictureMode", token, params);
3276
3277 // If the activity is already in picture in picture mode, then just return early
3278 if (isInPictureInPictureMode(r)) {
3279 return true;
3280 }
3281
3282 // Activity supports picture-in-picture, now check that we can enter PiP at this
3283 // point, if it is
3284 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
3285 false /* beforeStopping */)) {
3286 return false;
3287 }
3288
3289 final Runnable enterPipRunnable = () -> {
Wale Ogunwalef276a6f2018-06-15 08:26:07 -07003290 synchronized (mGlobalLock) {
3291 // Only update the saved args from the args that are set
3292 r.pictureInPictureArgs.copyOnlySet(params);
3293 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
3294 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
3295 // Adjust the source bounds by the insets for the transition down
3296 final Rect sourceBounds = new Rect(
3297 r.pictureInPictureArgs.getSourceRectHint());
3298 mStackSupervisor.moveActivityToPinnedStackLocked(
3299 r, sourceBounds, aspectRatio, "enterPictureInPictureMode");
3300 final PinnedActivityStack stack = r.getStack();
3301 stack.setPictureInPictureAspectRatio(aspectRatio);
3302 stack.setPictureInPictureActions(actions);
3303 MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
3304 r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
3305 logPictureInPictureArgs(params);
3306 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003307 };
3308
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003309 if (isKeyguardLocked()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003310 // If the keyguard is showing or occluded, then try and dismiss it before
3311 // entering picture-in-picture (this will prompt the user to authenticate if the
3312 // device is currently locked).
3313 dismissKeyguard(token, new KeyguardDismissCallback() {
3314 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003315 public void onDismissSucceeded() {
3316 mH.post(enterPipRunnable);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003317 }
3318 }, null /* message */);
3319 } else {
3320 // Enter picture in picture immediately otherwise
3321 enterPipRunnable.run();
3322 }
3323 return true;
3324 }
3325 } finally {
3326 Binder.restoreCallingIdentity(origId);
3327 }
3328 }
3329
3330 @Override
3331 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
3332 final long origId = Binder.clearCallingIdentity();
3333 try {
3334 synchronized (mGlobalLock) {
3335 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3336 "setPictureInPictureParams", token, params);
3337
3338 // Only update the saved args from the args that are set
3339 r.pictureInPictureArgs.copyOnlySet(params);
3340 if (r.inPinnedWindowingMode()) {
3341 // If the activity is already in picture-in-picture, update the pinned stack now
3342 // if it is not already expanding to fullscreen. Otherwise, the arguments will
3343 // be used the next time the activity enters PiP
3344 final PinnedActivityStack stack = r.getStack();
3345 if (!stack.isAnimatingBoundsToFullscreen()) {
3346 stack.setPictureInPictureAspectRatio(
3347 r.pictureInPictureArgs.getAspectRatio());
3348 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
3349 }
3350 }
3351 logPictureInPictureArgs(params);
3352 }
3353 } finally {
3354 Binder.restoreCallingIdentity(origId);
3355 }
3356 }
3357
3358 @Override
3359 public int getMaxNumPictureInPictureActions(IBinder token) {
3360 // Currently, this is a static constant, but later, we may change this to be dependent on
3361 // the context of the activity
3362 return 3;
3363 }
3364
3365 private void logPictureInPictureArgs(PictureInPictureParams params) {
3366 if (params.hasSetActions()) {
3367 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
3368 params.getActions().size());
3369 }
3370 if (params.hasSetAspectRatio()) {
3371 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
3372 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
3373 MetricsLogger.action(lm);
3374 }
3375 }
3376
3377 /**
3378 * Checks the state of the system and the activity associated with the given {@param token} to
3379 * verify that picture-in-picture is supported for that activity.
3380 *
3381 * @return the activity record for the given {@param token} if all the checks pass.
3382 */
3383 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
3384 IBinder token, PictureInPictureParams params) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003385 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003386 throw new IllegalStateException(caller
3387 + ": Device doesn't support picture-in-picture mode.");
3388 }
3389
3390 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3391 if (r == null) {
3392 throw new IllegalStateException(caller
3393 + ": Can't find activity for token=" + token);
3394 }
3395
3396 if (!r.supportsPictureInPicture()) {
3397 throw new IllegalStateException(caller
3398 + ": Current activity does not support picture-in-picture.");
3399 }
3400
3401 if (params.hasSetAspectRatio()
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003402 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003403 params.getAspectRatio())) {
3404 final float minAspectRatio = mContext.getResources().getFloat(
3405 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
3406 final float maxAspectRatio = mContext.getResources().getFloat(
3407 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
3408 throw new IllegalArgumentException(String.format(caller
3409 + ": Aspect ratio is too extreme (must be between %f and %f).",
3410 minAspectRatio, maxAspectRatio));
3411 }
3412
3413 // Truncate the number of actions if necessary
3414 params.truncateActions(getMaxNumPictureInPictureActions(token));
3415
3416 return r;
3417 }
3418
3419 @Override
3420 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003421 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003422 synchronized (mGlobalLock) {
3423 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
3424 if (r == null) {
3425 throw new IllegalArgumentException("Activity does not exist; token="
3426 + activityToken);
3427 }
3428 return r.getUriPermissionsLocked().getExternalTokenLocked();
3429 }
3430 }
3431
3432 @Override
3433 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
3434 Rect tempDockedTaskInsetBounds,
3435 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003436 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003437 long ident = Binder.clearCallingIdentity();
3438 try {
3439 synchronized (mGlobalLock) {
3440 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
3441 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
3442 PRESERVE_WINDOWS);
3443 }
3444 } finally {
3445 Binder.restoreCallingIdentity(ident);
3446 }
3447 }
3448
3449 @Override
3450 public void setSplitScreenResizing(boolean resizing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003451 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003452 final long ident = Binder.clearCallingIdentity();
3453 try {
3454 synchronized (mGlobalLock) {
3455 mStackSupervisor.setSplitScreenResizing(resizing);
3456 }
3457 } finally {
3458 Binder.restoreCallingIdentity(ident);
3459 }
3460 }
3461
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003462 /**
3463 * Check that we have the features required for VR-related API calls, and throw an exception if
3464 * not.
3465 */
3466 void enforceSystemHasVrFeature() {
3467 if (!mContext.getPackageManager().hasSystemFeature(
3468 PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
3469 throw new UnsupportedOperationException("VR mode not supported on this device!");
3470 }
3471 }
3472
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003473 @Override
3474 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003475 enforceSystemHasVrFeature();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003476
3477 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3478
3479 ActivityRecord r;
3480 synchronized (mGlobalLock) {
3481 r = ActivityRecord.isInStackLocked(token);
3482 }
3483
3484 if (r == null) {
3485 throw new IllegalArgumentException();
3486 }
3487
3488 int err;
3489 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
3490 VrManagerInternal.NO_ERROR) {
3491 return err;
3492 }
3493
3494 // Clear the binder calling uid since this path may call moveToTask().
3495 final long callingId = Binder.clearCallingIdentity();
3496 try {
3497 synchronized (mGlobalLock) {
3498 r.requestedVrComponent = (enabled) ? packageName : null;
3499
3500 // Update associated state if this activity is currently focused
3501 if (r == mStackSupervisor.getResumedActivityLocked()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003502 applyUpdateVrModeLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003503 }
3504 return 0;
3505 }
3506 } finally {
3507 Binder.restoreCallingIdentity(callingId);
3508 }
3509 }
3510
3511 @Override
3512 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
3513 Slog.i(TAG, "Activity tried to startLocalVoiceInteraction");
3514 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003515 ActivityRecord activity = getFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003516 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
3517 throw new SecurityException("Only focused activity can call startVoiceInteraction");
3518 }
3519 if (mAm.mRunningVoice != null || activity.getTask().voiceSession != null
3520 || activity.voiceSession != null) {
3521 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
3522 return;
3523 }
3524 if (activity.pendingVoiceInteractionStart) {
3525 Slog.w(TAG, "Pending start of voice interaction already.");
3526 return;
3527 }
3528 activity.pendingVoiceInteractionStart = true;
3529 }
3530 LocalServices.getService(VoiceInteractionManagerInternal.class)
3531 .startLocalVoiceInteraction(callingActivity, options);
3532 }
3533
3534 @Override
3535 public void stopLocalVoiceInteraction(IBinder callingActivity) {
3536 LocalServices.getService(VoiceInteractionManagerInternal.class)
3537 .stopLocalVoiceInteraction(callingActivity);
3538 }
3539
3540 @Override
3541 public boolean supportsLocalVoiceInteraction() {
3542 return LocalServices.getService(VoiceInteractionManagerInternal.class)
3543 .supportsLocalVoiceInteraction();
3544 }
3545
3546 /** Notifies all listeners when the pinned stack animation starts. */
3547 @Override
3548 public void notifyPinnedStackAnimationStarted() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003549 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003550 }
3551
3552 /** Notifies all listeners when the pinned stack animation ends. */
3553 @Override
3554 public void notifyPinnedStackAnimationEnded() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003555 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003556 }
3557
3558 @Override
3559 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003560 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003561 final long ident = Binder.clearCallingIdentity();
3562 try {
3563 synchronized (mGlobalLock) {
3564 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
3565 }
3566 } finally {
3567 Binder.restoreCallingIdentity(ident);
3568 }
3569 }
3570
3571 @Override
3572 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003573 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003574
3575 synchronized (mGlobalLock) {
3576 // Check if display is initialized in AM.
3577 if (!mStackSupervisor.isDisplayAdded(displayId)) {
3578 // Call might come when display is not yet added or has already been removed.
3579 if (DEBUG_CONFIGURATION) {
3580 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
3581 + displayId);
3582 }
3583 return false;
3584 }
3585
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(displayId);
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 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003602 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
3603 return mTmpUpdateConfigurationResult.changes != 0;
3604 } finally {
3605 Binder.restoreCallingIdentity(origId);
3606 }
3607 }
3608 }
3609
3610 @Override
3611 public boolean updateConfiguration(Configuration values) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003612 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003613
3614 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003615 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003616 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003617 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003618 }
3619
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003620 if (mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003621 // Update OOM levels based on display size.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003622 mAm.mProcessList.applyDisplaySize(mWindowManager);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003623 }
3624
3625 final long origId = Binder.clearCallingIdentity();
3626 try {
3627 if (values != null) {
3628 Settings.System.clearConfiguration(values);
3629 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003630 updateConfigurationLocked(values, null, false, false /* persistent */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003631 UserHandle.USER_NULL, false /* deferResume */,
3632 mTmpUpdateConfigurationResult);
3633 return mTmpUpdateConfigurationResult.changes != 0;
3634 } finally {
3635 Binder.restoreCallingIdentity(origId);
3636 }
3637 }
3638 }
3639
3640 @Override
3641 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
3642 CharSequence message) {
3643 if (message != null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003644 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003645 Manifest.permission.SHOW_KEYGUARD_MESSAGE, "dismissKeyguard()");
3646 }
3647 final long callingId = Binder.clearCallingIdentity();
3648 try {
3649 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003650 mKeyguardController.dismissKeyguard(token, callback, message);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003651 }
3652 } finally {
3653 Binder.restoreCallingIdentity(callingId);
3654 }
3655 }
3656
3657 @Override
3658 public void cancelTaskWindowTransition(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003659 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003660 "cancelTaskWindowTransition()");
3661 final long ident = Binder.clearCallingIdentity();
3662 try {
3663 synchronized (mGlobalLock) {
3664 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
3665 MATCH_TASK_IN_STACKS_ONLY);
3666 if (task == null) {
3667 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
3668 return;
3669 }
3670 task.cancelWindowTransition();
3671 }
3672 } finally {
3673 Binder.restoreCallingIdentity(ident);
3674 }
3675 }
3676
3677 @Override
3678 public ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003679 enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003680 final long ident = Binder.clearCallingIdentity();
3681 try {
3682 final TaskRecord task;
3683 synchronized (mGlobalLock) {
3684 task = mStackSupervisor.anyTaskForIdLocked(taskId,
3685 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
3686 if (task == null) {
3687 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
3688 return null;
3689 }
3690 }
3691 // Don't call this while holding the lock as this operation might hit the disk.
3692 return task.getSnapshot(reducedResolution);
3693 } finally {
3694 Binder.restoreCallingIdentity(ident);
3695 }
3696 }
3697
3698 @Override
3699 public void setDisablePreviewScreenshots(IBinder token, boolean disable) {
3700 synchronized (mGlobalLock) {
3701 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3702 if (r == null) {
3703 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
3704 + token);
3705 return;
3706 }
3707 final long origId = Binder.clearCallingIdentity();
3708 try {
3709 r.setDisablePreviewScreenshots(disable);
3710 } finally {
3711 Binder.restoreCallingIdentity(origId);
3712 }
3713 }
3714 }
3715
3716 /** Return the user id of the last resumed activity. */
3717 @Override
3718 public @UserIdInt
3719 int getLastResumedActivityUserId() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003720 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003721 Manifest.permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
3722 synchronized (mGlobalLock) {
3723 if (mAm.mLastResumedActivity == null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003724 return getCurrentUserId();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003725 }
3726 return mAm.mLastResumedActivity.userId;
3727 }
3728 }
3729
3730 @Override
3731 public void updateLockTaskFeatures(int userId, int flags) {
3732 final int callingUid = Binder.getCallingUid();
3733 if (callingUid != 0 && callingUid != SYSTEM_UID) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003734 mAmInternal.enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003735 "updateLockTaskFeatures()");
3736 }
3737 synchronized (mGlobalLock) {
3738 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
3739 Integer.toHexString(flags));
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003740 getLockTaskController().updateLockTaskFeatures(userId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003741 }
3742 }
3743
3744 @Override
3745 public void setShowWhenLocked(IBinder token, boolean showWhenLocked) {
3746 synchronized (mGlobalLock) {
3747 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3748 if (r == null) {
3749 return;
3750 }
3751 final long origId = Binder.clearCallingIdentity();
3752 try {
3753 r.setShowWhenLocked(showWhenLocked);
3754 } finally {
3755 Binder.restoreCallingIdentity(origId);
3756 }
3757 }
3758 }
3759
3760 @Override
3761 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) {
3762 synchronized (mGlobalLock) {
3763 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3764 if (r == null) {
3765 return;
3766 }
3767 final long origId = Binder.clearCallingIdentity();
3768 try {
3769 r.setTurnScreenOn(turnScreenOn);
3770 } finally {
3771 Binder.restoreCallingIdentity(origId);
3772 }
3773 }
3774 }
3775
3776 @Override
3777 public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003778 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003779 "registerRemoteAnimations");
3780 definition.setCallingPid(Binder.getCallingPid());
3781 synchronized (mGlobalLock) {
3782 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3783 if (r == null) {
3784 return;
3785 }
3786 final long origId = Binder.clearCallingIdentity();
3787 try {
3788 r.registerRemoteAnimations(definition);
3789 } finally {
3790 Binder.restoreCallingIdentity(origId);
3791 }
3792 }
3793 }
3794
3795 @Override
3796 public void registerRemoteAnimationForNextActivityStart(String packageName,
3797 RemoteAnimationAdapter adapter) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003798 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003799 "registerRemoteAnimationForNextActivityStart");
3800 adapter.setCallingPid(Binder.getCallingPid());
3801 synchronized (mGlobalLock) {
3802 final long origId = Binder.clearCallingIdentity();
3803 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07003804 getActivityStartController().registerRemoteAnimationForNextActivityStart(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003805 packageName, adapter);
3806 } finally {
3807 Binder.restoreCallingIdentity(origId);
3808 }
3809 }
3810 }
3811
3812 /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
3813 @Override
3814 public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
3815 synchronized (mGlobalLock) {
3816 final long origId = Binder.clearCallingIdentity();
3817 try {
3818 mAm.mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
3819 } finally {
3820 Binder.restoreCallingIdentity(origId);
3821 }
3822 }
3823 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07003824
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003825 @Override
3826 public void setVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003827 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003828 synchronized (mGlobalLock) {
3829 synchronized (mAm.mPidsSelfLocked) {
3830 final int pid = Binder.getCallingPid();
3831 final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003832 mVrController.setVrThreadLocked(tid, pid, proc.getWindowProcessController());
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003833 }
3834 }
3835 }
3836
3837 @Override
3838 public void setPersistentVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003839 if (checkCallingPermission(Manifest.permission.RESTRICTED_VR_ACCESS)
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003840 != PERMISSION_GRANTED) {
3841 final String msg = "Permission Denial: setPersistentVrThread() from pid="
3842 + Binder.getCallingPid()
3843 + ", uid=" + Binder.getCallingUid()
3844 + " requires " + Manifest.permission.RESTRICTED_VR_ACCESS;
3845 Slog.w(TAG, msg);
3846 throw new SecurityException(msg);
3847 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003848 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003849 synchronized (mGlobalLock) {
3850 synchronized (mAm.mPidsSelfLocked) {
3851 final int pid = Binder.getCallingPid();
3852 final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
3853 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
3854 }
3855 }
3856 }
3857
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003858 @Override
3859 public void stopAppSwitches() {
3860 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
3861 synchronized (mGlobalLock) {
3862 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME;
3863 mDidAppSwitch = false;
3864 getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
3865 }
3866 }
3867
3868 @Override
3869 public void resumeAppSwitches() {
3870 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
3871 synchronized (mGlobalLock) {
3872 // Note that we don't execute any pending app switches... we will
3873 // let those wait until either the timeout, or the next start
3874 // activity request.
3875 mAppSwitchesAllowedTime = 0;
3876 }
3877 }
3878
3879 void onStartActivitySetDidAppSwitch() {
3880 if (mDidAppSwitch) {
3881 // This is the second allowed switch since we stopped switches, so now just generally
3882 // allow switches. Use case:
3883 // - user presses home (switches disabled, switch to home, mDidAppSwitch now true);
3884 // - user taps a home icon (coming from home so allowed, we hit here and now allow
3885 // anyone to switch again).
3886 mAppSwitchesAllowedTime = 0;
3887 } else {
3888 mDidAppSwitch = true;
3889 }
3890 }
3891
3892 /** @return whether the system should disable UI modes incompatible with VR mode. */
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003893 boolean shouldDisableNonVrUiLocked() {
3894 return mVrController.shouldDisableNonVrUiLocked();
3895 }
3896
3897 void applyUpdateVrModeLocked(ActivityRecord r) {
3898 // VR apps are expected to run in a main display. If an app is turning on VR for
3899 // itself, but lives in a dynamic stack, then make sure that it is moved to the main
3900 // fullscreen stack before enabling VR Mode.
3901 // TODO: The goal of this code is to keep the VR app on the main display. When the
3902 // stack implementation changes in the future, keep in mind that the use of the fullscreen
3903 // stack is a means to move the activity to the main display and a moveActivityToDisplay()
3904 // option would be a better choice here.
3905 if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
3906 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
3907 + " to main stack for VR");
3908 final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
3909 WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
3910 moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
3911 }
3912 mH.post(() -> {
3913 if (!mVrController.onVrModeChanged(r)) {
3914 return;
3915 }
3916 synchronized (mGlobalLock) {
3917 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
3918 mWindowManager.disableNonVrUi(disableNonVrUi);
3919 if (disableNonVrUi) {
3920 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
3921 // then remove the pinned stack.
3922 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
3923 }
3924 }
3925 });
3926 }
3927
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003928 ActivityStack getFocusedStack() {
3929 return mStackSupervisor.getFocusedStack();
3930 }
3931
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003932 /** Pokes the task persister. */
3933 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
3934 mRecentTasks.notifyTaskPersisterLocked(task, flush);
3935 }
3936
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003937 void onTopProcChangedLocked(WindowProcessController proc) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003938 mVrController.onTopProcChangedLocked(proc);
3939 }
3940
3941 boolean isKeyguardLocked() {
3942 return mKeyguardController.isKeyguardLocked();
3943 }
3944
3945 boolean isNextTransitionForward() {
3946 int transit = mWindowManager.getPendingAppTransition();
3947 return transit == TRANSIT_ACTIVITY_OPEN
3948 || transit == TRANSIT_TASK_OPEN
3949 || transit == TRANSIT_TASK_TO_FRONT;
3950 }
3951
3952 void dumpVrControllerLocked(PrintWriter pw) {
3953 pw.println(" mVrController=" + mVrController);
3954 }
3955
3956 void writeVrControllerToProto(ProtoOutputStream proto, long fieldId) {
3957 mVrController.writeToProto(proto, fieldId);
3958 }
3959
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003960 int getCurrentUserId() {
3961 return mAmInternal.getCurrentUserId();
3962 }
3963
3964 private void enforceNotIsolatedCaller(String caller) {
3965 if (UserHandle.isIsolated(Binder.getCallingUid())) {
3966 throw new SecurityException("Isolated process not allowed to call " + caller);
3967 }
3968 }
3969
3970 /**
3971 * Current global configuration information. Contains general settings for the entire system,
3972 * also corresponds to the merged configuration of the default display.
3973 */
3974 Configuration getGlobalConfiguration() {
3975 return mStackSupervisor.getConfiguration();
3976 }
3977
3978 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
3979 boolean initLocale) {
3980 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
3981 }
3982
3983 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
3984 boolean initLocale, boolean deferResume) {
3985 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
3986 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
3987 UserHandle.USER_NULL, deferResume);
3988 }
3989
3990 void updatePersistentConfiguration(Configuration values, @UserIdInt int userId) {
3991 final long origId = Binder.clearCallingIdentity();
3992 try {
3993 synchronized (mGlobalLock) {
3994 updateConfigurationLocked(values, null, false, true, userId,
3995 false /* deferResume */);
3996 }
3997 } finally {
3998 Binder.restoreCallingIdentity(origId);
3999 }
4000 }
4001
4002 void updateUserConfiguration() {
4003 synchronized (mGlobalLock) {
4004 final Configuration configuration = new Configuration(getGlobalConfiguration());
4005 final int currentUserId = mAmInternal.getCurrentUserId();
4006 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
4007 currentUserId, Settings.System.canWrite(mContext));
4008 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
4009 false /* persistent */, currentUserId, false /* deferResume */);
4010 }
4011 }
4012
4013 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4014 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
4015 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
4016 deferResume, null /* result */);
4017 }
4018
4019 /**
4020 * Do either or both things: (1) change the current configuration, and (2)
4021 * make sure the given activity is running with the (now) current
4022 * configuration. Returns true if the activity has been left running, or
4023 * false if <var>starting</var> is being destroyed to match the new
4024 * configuration.
4025 *
4026 * @param userId is only used when persistent parameter is set to true to persist configuration
4027 * for that particular user
4028 */
4029 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4030 boolean initLocale, boolean persistent, int userId, boolean deferResume,
4031 ActivityTaskManagerService.UpdateConfigurationResult result) {
4032 int changes = 0;
4033 boolean kept = true;
4034
4035 if (mWindowManager != null) {
4036 mWindowManager.deferSurfaceLayout();
4037 }
4038 try {
4039 if (values != null) {
4040 changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
4041 deferResume);
4042 }
4043
4044 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4045 } finally {
4046 if (mWindowManager != null) {
4047 mWindowManager.continueSurfaceLayout();
4048 }
4049 }
4050
4051 if (result != null) {
4052 result.changes = changes;
4053 result.activityRelaunched = !kept;
4054 }
4055 return kept;
4056 }
4057
4058 /**
4059 * Returns true if this configuration change is interesting enough to send an
4060 * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
4061 */
4062 private static boolean isSplitConfigurationChange(int configDiff) {
4063 return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
4064 }
4065
4066 /** Update default (global) configuration and notify listeners about changes. */
4067 private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
4068 boolean persistent, int userId, boolean deferResume) {
4069 mTempConfig.setTo(getGlobalConfiguration());
4070 final int changes = mTempConfig.updateFrom(values);
4071 if (changes == 0) {
4072 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
4073 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
4074 // performDisplayOverrideConfigUpdate in order to send the new display configuration
4075 // (even if there are no actual changes) to unfreeze the window.
4076 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
4077 return 0;
4078 }
4079
4080 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
4081 "Updating global configuration to: " + values);
4082
4083 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
4084 StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
4085 values.colorMode,
4086 values.densityDpi,
4087 values.fontScale,
4088 values.hardKeyboardHidden,
4089 values.keyboard,
4090 values.keyboardHidden,
4091 values.mcc,
4092 values.mnc,
4093 values.navigation,
4094 values.navigationHidden,
4095 values.orientation,
4096 values.screenHeightDp,
4097 values.screenLayout,
4098 values.screenWidthDp,
4099 values.smallestScreenWidthDp,
4100 values.touchscreen,
4101 values.uiMode);
4102
4103
4104 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
4105 final LocaleList locales = values.getLocales();
4106 int bestLocaleIndex = 0;
4107 if (locales.size() > 1) {
4108 if (mSupportedSystemLocales == null) {
4109 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
4110 }
4111 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
4112 }
4113 SystemProperties.set("persist.sys.locale",
4114 locales.get(bestLocaleIndex).toLanguageTag());
4115 LocaleList.setDefault(locales, bestLocaleIndex);
4116 mAm.mHandler.sendMessage(mAm.mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
4117 locales.get(bestLocaleIndex)));
4118 }
4119
4120 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
4121 mTempConfig.seq = mConfigurationSeq;
4122
4123 // Update stored global config and notify everyone about the change.
4124 mStackSupervisor.onConfigurationChanged(mTempConfig);
4125
4126 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
4127 // TODO(multi-display): Update UsageEvents#Event to include displayId.
4128 mAm.mUsageStatsService.reportConfigurationChange(
4129 mTempConfig, mAmInternal.getCurrentUserId());
4130
4131 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
4132 mAm.updateShouldShowDialogsLocked(mTempConfig);
4133
4134 AttributeCache ac = AttributeCache.instance();
4135 if (ac != null) {
4136 ac.updateConfiguration(mTempConfig);
4137 }
4138
4139 // Make sure all resources in our process are updated right now, so that anyone who is going
4140 // to retrieve resource values after we return will be sure to get the new ones. This is
4141 // especially important during boot, where the first config change needs to guarantee all
4142 // resources have that config before following boot code is executed.
4143 mAm.mSystemThread.applyConfigurationToResources(mTempConfig);
4144
4145 // We need another copy of global config because we're scheduling some calls instead of
4146 // running them in place. We need to be sure that object we send will be handled unchanged.
4147 final Configuration configCopy = new Configuration(mTempConfig);
4148 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
4149 Message msg = mAm.mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
4150 msg.obj = configCopy;
4151 msg.arg1 = userId;
4152 mAm.mHandler.sendMessage(msg);
4153 }
4154
4155 for (int i = mAm.mLruProcesses.size() - 1; i >= 0; i--) {
4156 ProcessRecord app = mAm.mLruProcesses.get(i);
4157 try {
4158 if (app.thread != null) {
4159 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
4160 + app.processName + " new config " + configCopy);
4161 getLifecycleManager().scheduleTransaction(app.thread,
4162 ConfigurationChangeItem.obtain(configCopy));
4163 }
4164 } catch (Exception e) {
4165 Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
4166 }
4167 }
4168
4169 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
4170 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
4171 | Intent.FLAG_RECEIVER_FOREGROUND
4172 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4173 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4174 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4175 UserHandle.USER_ALL);
4176 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
4177 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
4178 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
4179 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
4180 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4181 if (initLocale || !mAm.mProcessesReady) {
4182 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
4183 }
4184 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4185 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4186 UserHandle.USER_ALL);
4187 }
4188
4189 // Send a broadcast to PackageInstallers if the configuration change is interesting
4190 // for the purposes of installing additional splits.
4191 if (!initLocale && isSplitConfigurationChange(changes)) {
4192 intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
4193 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
4194 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
4195
4196 // Typically only app stores will have this permission.
4197 String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES };
4198 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions,
4199 OP_NONE, null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
4200 }
4201
4202 // Override configuration of the default display duplicates global config, so we need to
4203 // update it also. This will also notify WindowManager about changes.
4204 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
4205 DEFAULT_DISPLAY);
4206
4207 return changes;
4208 }
4209
4210 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
4211 boolean deferResume, int displayId) {
4212 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
4213 displayId, null /* result */);
4214 }
4215
4216 /**
4217 * Updates override configuration specific for the selected display. If no config is provided,
4218 * new one will be computed in WM based on current display info.
4219 */
4220 boolean updateDisplayOverrideConfigurationLocked(Configuration values,
4221 ActivityRecord starting, boolean deferResume, int displayId,
4222 ActivityTaskManagerService.UpdateConfigurationResult result) {
4223 int changes = 0;
4224 boolean kept = true;
4225
4226 if (mWindowManager != null) {
4227 mWindowManager.deferSurfaceLayout();
4228 }
4229 try {
4230 if (values != null) {
4231 if (displayId == DEFAULT_DISPLAY) {
4232 // Override configuration of the default display duplicates global config, so
4233 // we're calling global config update instead for default display. It will also
4234 // apply the correct override config.
4235 changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
4236 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
4237 } else {
4238 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
4239 }
4240 }
4241
4242 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4243 } finally {
4244 if (mWindowManager != null) {
4245 mWindowManager.continueSurfaceLayout();
4246 }
4247 }
4248
4249 if (result != null) {
4250 result.changes = changes;
4251 result.activityRelaunched = !kept;
4252 }
4253 return kept;
4254 }
4255
4256 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
4257 int displayId) {
4258 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
4259 final int changes = mTempConfig.updateFrom(values);
4260 if (changes != 0) {
4261 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
4262 + mTempConfig + " for displayId=" + displayId);
4263 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
4264
4265 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
4266 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
4267 mAm.mAppWarnings.onDensityChanged();
4268
4269 mAm.killAllBackgroundProcessesExcept(N,
4270 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
4271 }
4272 }
4273
4274 // Update the configuration with WM first and check if any of the stacks need to be resized
4275 // due to the configuration change. If so, resize the stacks now and do any relaunches if
4276 // necessary. This way we don't need to relaunch again afterwards in
4277 // ensureActivityConfiguration().
4278 if (mWindowManager != null) {
4279 final int[] resizedStacks =
4280 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
4281 if (resizedStacks != null) {
4282 for (int stackId : resizedStacks) {
4283 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
4284 }
4285 }
4286 }
4287
4288 return changes;
4289 }
4290
4291 /** Helper method that requests bounds from WM and applies them to stack. */
4292 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
4293 final Rect newStackBounds = new Rect();
4294 final ActivityStack stack = mStackSupervisor.getStack(stackId);
4295
4296 // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
4297 if (stack == null) {
4298 final StringWriter writer = new StringWriter();
4299 final PrintWriter printWriter = new PrintWriter(writer);
4300 mStackSupervisor.dumpDisplays(printWriter);
4301 printWriter.flush();
4302
4303 Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
4304 }
4305
4306 stack.getBoundsForNewConfiguration(newStackBounds);
4307 mStackSupervisor.resizeStackLocked(
4308 stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
4309 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
4310 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
4311 }
4312
4313 /** Applies latest configuration and/or visibility updates if needed. */
4314 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
4315 boolean kept = true;
4316 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
4317 // mainStack is null during startup.
4318 if (mainStack != null) {
4319 if (changes != 0 && starting == null) {
4320 // If the configuration changed, and the caller is not already
4321 // in the process of starting an activity, then find the top
4322 // activity to check if its configuration needs to change.
4323 starting = mainStack.topRunningActivityLocked();
4324 }
4325
4326 if (starting != null) {
4327 kept = starting.ensureActivityConfiguration(changes,
4328 false /* preserveWindow */);
4329 // And we need to make sure at this point that all other activities
4330 // are made visible with the correct configuration.
4331 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
4332 !PRESERVE_WINDOWS);
4333 }
4334 }
4335
4336 return kept;
4337 }
4338
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004339 void logAppTooSlow(WindowProcessController app, long startTime, String msg) {
4340 if (true || Build.IS_USER) {
4341 return;
4342 }
4343
4344 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4345 StrictMode.allowThreadDiskWrites();
4346 try {
4347 File tracesDir = new File("/data/anr");
4348 File tracesFile = null;
4349 try {
4350 tracesFile = File.createTempFile("app_slow", null, tracesDir);
4351
4352 StringBuilder sb = new StringBuilder();
4353 Time tobj = new Time();
4354 tobj.set(System.currentTimeMillis());
4355 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4356 sb.append(": ");
4357 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4358 sb.append(" since ");
4359 sb.append(msg);
4360 FileOutputStream fos = new FileOutputStream(tracesFile);
4361 fos.write(sb.toString().getBytes());
4362 if (app == null) {
4363 fos.write("\n*** No application process!".getBytes());
4364 }
4365 fos.close();
4366 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4367 } catch (IOException e) {
4368 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesFile, e);
4369 return;
4370 }
4371
4372 if (app != null && app.getPid() > 0) {
4373 ArrayList<Integer> firstPids = new ArrayList<Integer>();
4374 firstPids.add(app.getPid());
4375 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, null, null);
4376 }
4377
4378 File lastTracesFile = null;
4379 File curTracesFile = null;
4380 for (int i=9; i>=0; i--) {
4381 String name = String.format(Locale.US, "slow%02d.txt", i);
4382 curTracesFile = new File(tracesDir, name);
4383 if (curTracesFile.exists()) {
4384 if (lastTracesFile != null) {
4385 curTracesFile.renameTo(lastTracesFile);
4386 } else {
4387 curTracesFile.delete();
4388 }
4389 }
4390 lastTracesFile = curTracesFile;
4391 }
4392 tracesFile.renameTo(curTracesFile);
4393 } finally {
4394 StrictMode.setThreadPolicy(oldPolicy);
4395 }
4396 }
4397
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004398 final class H extends Handler {
4399 public H(Looper looper) {
4400 super(looper, null, true);
4401 }
4402 }
4403
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004404 final class UiHandler extends Handler {
4405
4406 public UiHandler() {
4407 super(com.android.server.UiThread.get().getLooper(), null, true);
4408 }
4409 }
4410
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004411 final class LocalService extends ActivityTaskManagerInternal {
4412 @Override
4413 public SleepToken acquireSleepToken(String tag, int displayId) {
4414 Preconditions.checkNotNull(tag);
4415 return mAm.acquireSleepToken(tag, displayId);
4416 }
4417
4418 @Override
4419 public ComponentName getHomeActivityForUser(int userId) {
4420 synchronized (mGlobalLock) {
4421 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
4422 return homeActivity == null ? null : homeActivity.realActivity;
4423 }
4424 }
4425
4426 @Override
4427 public void onLocalVoiceInteractionStarted(IBinder activity,
4428 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4429 synchronized (mGlobalLock) {
4430 mAm.onLocalVoiceInteractionStartedLocked(activity, voiceSession, voiceInteractor);
4431 }
4432 }
4433
4434 @Override
4435 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
4436 synchronized (mGlobalLock) {
4437 mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
4438 reasons, timestamp);
4439 }
4440 }
4441
4442 @Override
4443 public void notifyAppTransitionFinished() {
4444 synchronized (mGlobalLock) {
4445 mStackSupervisor.notifyAppTransitionDone();
4446 }
4447 }
4448
4449 @Override
4450 public void notifyAppTransitionCancelled() {
4451 synchronized (mGlobalLock) {
4452 mStackSupervisor.notifyAppTransitionDone();
4453 }
4454 }
4455
4456 @Override
4457 public List<IBinder> getTopVisibleActivities() {
4458 synchronized (mGlobalLock) {
4459 return mStackSupervisor.getTopVisibleActivities();
4460 }
4461 }
4462
4463 @Override
4464 public void notifyDockedStackMinimizedChanged(boolean minimized) {
4465 synchronized (mGlobalLock) {
4466 mStackSupervisor.setDockedStackMinimized(minimized);
4467 }
4468 }
4469
4470 @Override
4471 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
4472 Bundle bOptions) {
4473 Preconditions.checkNotNull(intents, "intents");
4474 final String[] resolvedTypes = new String[intents.length];
4475
4476 // UID of the package on user userId.
4477 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
4478 // packageUid may not be initialized.
4479 int packageUid = 0;
4480 final long ident = Binder.clearCallingIdentity();
4481
4482 try {
4483 for (int i = 0; i < intents.length; i++) {
4484 resolvedTypes[i] =
4485 intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
4486 }
4487
4488 packageUid = AppGlobals.getPackageManager().getPackageUid(
4489 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
4490 } catch (RemoteException e) {
4491 // Shouldn't happen.
4492 } finally {
4493 Binder.restoreCallingIdentity(ident);
4494 }
4495
4496 synchronized (mGlobalLock) {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07004497 return getActivityStartController().startActivitiesInPackage(
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004498 packageUid, packageName,
4499 intents, resolvedTypes, null /* resultTo */,
4500 SafeActivityOptions.fromBundle(bOptions), userId,
4501 false /* validateIncomingUser */);
4502 }
4503 }
4504
4505 @Override
4506 public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
4507 Intent intent, Bundle options, int userId) {
4508 return ActivityTaskManagerService.this.startActivityAsUser(
4509 caller, callerPacakge, intent,
4510 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4511 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
4512 false /*validateIncomingUser*/);
4513 }
4514
4515 @Override
4516 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
4517 synchronized (mGlobalLock) {
4518
4519 // We might change the visibilities here, so prepare an empty app transition which
4520 // might be overridden later if we actually change visibilities.
4521 final boolean wasTransitionSet =
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004522 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004523 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004524 mWindowManager.prepareAppTransition(TRANSIT_NONE,
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004525 false /* alwaysKeepCurrent */);
4526 }
4527 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4528
4529 // If there was a transition set already we don't want to interfere with it as we
4530 // might be starting it too early.
4531 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004532 mWindowManager.executeAppTransition();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004533 }
4534 }
4535 if (callback != null) {
4536 callback.run();
4537 }
4538 }
4539
4540 @Override
4541 public void notifyKeyguardTrustedChanged() {
4542 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004543 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004544 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4545 }
4546 }
4547 }
4548
4549 /**
4550 * Called after virtual display Id is updated by
4551 * {@link com.android.server.vr.Vr2dDisplay} with a specific
4552 * {@param vrVr2dDisplayId}.
4553 */
4554 @Override
4555 public void setVr2dDisplayId(int vr2dDisplayId) {
4556 if (DEBUG_STACK) Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
4557 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004558 mVr2dDisplayId = vr2dDisplayId;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004559 }
4560 }
4561
4562 @Override
4563 public void setFocusedActivity(IBinder token) {
4564 synchronized (mGlobalLock) {
4565 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
4566 if (r == null) {
4567 throw new IllegalArgumentException(
4568 "setFocusedActivity: No activity record matching token=" + token);
4569 }
4570 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
4571 r, "setFocusedActivity")) {
4572 mStackSupervisor.resumeFocusedStackTopActivityLocked();
4573 }
4574 }
4575 }
4576
4577 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004578 public void registerScreenObserver(ScreenObserver observer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004579 mScreenObservers.add(observer);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004580 }
4581
4582 @Override
4583 public boolean isCallerRecents(int callingUid) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07004584 return getRecentTasks().isCallerRecents(callingUid);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004585 }
4586
4587 @Override
4588 public boolean isRecentsComponentHomeActivity(int userId) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07004589 return getRecentTasks().isRecentsComponentHomeActivity(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004590 }
4591
4592 @Override
4593 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
4594 ActivityTaskManagerService.this.cancelRecentsAnimation(restoreHomeStackPosition);
4595 }
4596
4597 @Override
4598 public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004599 ActivityTaskManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004600 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004601
4602 @Override
4603 public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
4604 synchronized (mGlobalLock) {
4605 mActiveVoiceInteractionServiceComponent = component;
4606 }
4607 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004608
4609 @Override
4610 public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
4611 if (!mAmInternal.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
4612 return;
4613 }
4614 synchronized (mGlobalLock) {
4615 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
4616 if (types == null) {
4617 if (uid < 0) {
4618 return;
4619 }
4620 types = new ArrayMap<>();
4621 mAllowAppSwitchUids.put(userId, types);
4622 }
4623 if (uid < 0) {
4624 types.remove(type);
4625 } else {
4626 types.put(type, uid);
4627 }
4628 }
4629 }
4630
4631 @Override
4632 public void onUserStopped(int userId) {
4633 synchronized (mGlobalLock) {
4634 getRecentTasks().unloadUserDataFromMemoryLocked(userId);
4635 mAllowAppSwitchUids.remove(userId);
4636 }
4637 }
4638
4639 @Override
4640 public boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
4641 synchronized (mGlobalLock) {
4642 return ActivityTaskManagerService.this.isGetTasksAllowed(
4643 caller, callingPid, callingUid);
4644 }
4645 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004646
4647 @Override
4648 public void onProcessAdded(WindowProcessController proc) {
4649 synchronized (mGlobalLock) {
4650 mProcessNames.put(proc.mName, proc.mUid, proc);
4651 }
4652 }
4653
4654 @Override
4655 public void onProcessRemoved(String name, int uid) {
4656 synchronized (mGlobalLock) {
4657 mProcessNames.remove(name, uid);
4658 }
4659 }
4660
4661 @Override
4662 public void onCleanUpApplicationRecord(WindowProcessController proc) {
4663 synchronized (mGlobalLock) {
4664 if (proc == mHomeProcess) {
4665 mHomeProcess = null;
4666 }
4667 if (proc == mPreviousProcess) {
4668 mPreviousProcess = null;
4669 }
4670 }
4671 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004672 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07004673}