blob: 91f2b5f6f00c54f5322827ebcd41d745eaee1f52 [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;
Wale Ogunwale906f9c62018-07-23 11:23:44 -070022import static android.Manifest.permission.FILTER_EVENTS;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070023import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070024import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070025import static android.Manifest.permission.READ_FRAME_BUFFER;
26import static android.Manifest.permission.REMOVE_TASKS;
27import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070028import static android.Manifest.permission.STOP_APP_SWITCHES;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070029import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
Wale Ogunwalef6733932018-06-27 05:14:34 -070030import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
31import static android.provider.Settings.Global.HIDE_ERROR_DIALOGS;
32import static android.provider.Settings.System.FONT_SCALE;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070033import static com.android.server.am.ActivityManagerService.dumpStackTraces;
Wale Ogunwalef6733932018-06-27 05:14:34 -070034import static com.android.server.am.ActivityTaskManagerService.H.REPORT_TIME_TRACKER_MSG;
35import static com.android.server.am.ActivityTaskManagerService.UiHandler.DISMISS_DIALOG_UI_MSG;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070036import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT;
37import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_DATA;
38import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
39import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070040import static android.app.ActivityTaskManager.RESIZE_MODE_PRESERVE_WINDOW;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070041import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070042import static android.app.AppOpsManager.OP_NONE;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070043import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070044import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
45import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070046import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
47import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070048import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070049import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070050import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070051import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
52import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070053import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070054import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070055import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
56import static android.os.Build.VERSION_CODES.N;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070057import static android.os.Process.SYSTEM_UID;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070058import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
59import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
60import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
61import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070062import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
63import static android.view.Display.DEFAULT_DISPLAY;
64import static android.view.Display.INVALID_DISPLAY;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070065import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
Wale Ogunwale6767eae2018-05-03 15:52:51 -070066import static android.view.WindowManager.TRANSIT_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070067import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070068import static android.view.WindowManager.TRANSIT_TASK_OPEN;
69import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070070import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070071import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
72import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
73import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
74import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070075import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070076import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070077import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070078import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070079import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070080import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
81import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
82import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070083import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070084import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
85import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070086import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
87import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070088import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070089import static com.android.server.am.ActivityManagerService.ANIMATE;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070090import static com.android.server.am.ActivityManagerService.MY_PID;
91import static com.android.server.am.ActivityManagerService.SEND_LOCALE_TO_MOUNT_DAEMON_MSG;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070092import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070093import static com.android.server.am.ActivityManagerService.UPDATE_CONFIGURATION_MSG;
94import static com.android.server.am.ActivityManagerService.checkComponentPermission;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070095import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070096import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070097import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
98import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
99import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
100import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
101import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
102import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
103import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700104import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700105import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
106import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
107import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700108
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700109import android.Manifest;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700110import android.annotation.NonNull;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700111import android.annotation.Nullable;
112import android.annotation.UserIdInt;
113import android.app.Activity;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700114import android.app.ActivityManager;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700115import android.app.ActivityManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700116import android.app.ActivityOptions;
117import android.app.ActivityTaskManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700118import android.app.ActivityThread;
119import android.app.AlertDialog;
120import android.app.Dialog;
121import android.content.DialogInterface;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700122import android.content.pm.IPackageManager;
123import android.content.pm.PackageManagerInternal;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700124import android.database.ContentObserver;
125import android.os.IUserManager;
126import android.os.PowerManager;
127import android.os.ServiceManager;
128import android.os.Trace;
129import android.os.UserManager;
130import android.os.WorkSource;
131import android.view.WindowManager;
132import com.android.internal.R;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700133import com.android.internal.app.IAppOpsService;
134import com.android.server.AppOpsService;
Wale Ogunwale008163e2018-07-23 23:11:08 -0700135import com.android.server.SystemServiceManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700136import com.android.server.pm.UserManagerService;
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700137import com.android.server.uri.UriGrantsManagerInternal;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700138import com.android.server.wm.ActivityTaskManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700139import android.app.AppGlobals;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700140import android.app.IActivityController;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700141import android.app.IActivityTaskManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700142import android.app.IApplicationThread;
143import android.app.IAssistDataReceiver;
144import android.app.ITaskStackListener;
145import android.app.PictureInPictureParams;
146import android.app.ProfilerInfo;
147import android.app.RemoteAction;
148import android.app.WaitResult;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700149import android.app.WindowConfiguration;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700150import android.app.admin.DevicePolicyCache;
151import android.app.assist.AssistContent;
152import android.app.assist.AssistStructure;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700153import android.app.servertransaction.ConfigurationChangeItem;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700154import android.app.usage.UsageEvents;
155import android.content.ActivityNotFoundException;
156import android.content.ComponentName;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700157import android.content.ContentResolver;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700158import android.content.Context;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700159import android.content.IIntentSender;
160import android.content.Intent;
161import android.content.pm.ActivityInfo;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700162import android.content.pm.ApplicationInfo;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700163import android.content.pm.PackageManager;
164import android.content.pm.ParceledListSlice;
165import android.content.pm.ResolveInfo;
166import android.content.res.Configuration;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700167import android.content.res.Resources;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700168import android.graphics.Bitmap;
169import android.graphics.Point;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700170import android.graphics.Rect;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700171import android.metrics.LogMaker;
172import android.net.Uri;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700173import android.os.Binder;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700174import android.os.Build;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700175import android.os.Bundle;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700176import android.os.FileUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700177import android.os.Handler;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700178import android.os.IBinder;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700179import android.os.LocaleList;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700180import android.os.Looper;
181import android.os.Message;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700182import android.os.PersistableBundle;
183import android.os.RemoteException;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700184import android.os.StrictMode;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700185import android.os.SystemClock;
186import android.os.SystemProperties;
187import android.os.UpdateLock;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700188import android.os.UserHandle;
189import android.provider.Settings;
190import android.service.voice.IVoiceInteractionSession;
191import android.service.voice.VoiceInteractionManagerInternal;
192import android.telecom.TelecomManager;
193import android.text.TextUtils;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700194import android.text.format.Time;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700195import android.util.ArrayMap;
196import android.util.EventLog;
197import android.util.Log;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700198import android.util.Slog;
199
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700200import android.util.SparseArray;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700201import android.util.SparseIntArray;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700202import android.util.StatsLog;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700203import android.util.TimeUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700204import android.util.proto.ProtoOutputStream;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700205import android.view.IRecentsAnimationRunner;
206import android.view.RemoteAnimationAdapter;
207import android.view.RemoteAnimationDefinition;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700208
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700209import com.android.internal.annotations.VisibleForTesting;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700210import com.android.internal.app.AssistUtils;
211import com.android.internal.app.IVoiceInteractor;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700212import com.android.internal.app.ProcessMap;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700213import com.android.internal.logging.MetricsLogger;
214import com.android.internal.os.logging.MetricsLoggerWrapper;
215import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
216import com.android.internal.policy.IKeyguardDismissCallback;
217import com.android.internal.policy.KeyguardDismissCallback;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700218import com.android.internal.util.Preconditions;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700219import com.android.server.AttributeCache;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700220import com.android.server.LocalServices;
221import com.android.server.SystemService;
222import com.android.server.Watchdog;
223import com.android.server.vr.VrManagerInternal;
224import com.android.server.wm.PinnedStackWindowController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700225import com.android.server.wm.WindowManagerService;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700226
227import java.io.File;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700228import java.io.FileOutputStream;
229import java.io.IOException;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700230import java.io.PrintWriter;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700231import java.io.StringWriter;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700232import java.util.ArrayList;
233import java.util.List;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700234import java.util.Locale;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700235
236/**
237 * System service for managing activities and their containers (task, stacks, displays,... ).
238 *
239 * {@hide}
240 */
241public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
242 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityTaskManagerService" : TAG_AM;
243 private static final String TAG_STACK = TAG + POSTFIX_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700244 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
245 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
246 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
247 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
248 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700249 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700250
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700251 // How long we wait until we timeout on key dispatching.
252 private static final int KEY_DISPATCHING_TIMEOUT_MS = 5 * 1000;
253 // How long we wait until we timeout on key dispatching during instrumentation.
254 private static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS = 60 * 1000;
255
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700256 Context mContext;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700257 /**
258 * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
259 * change at runtime. Use mContext for non-UI purposes.
260 */
261 final Context mUiContext;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700262 H mH;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700263 UiHandler mUiHandler;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700264 ActivityManagerService mAm;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700265 ActivityManagerInternal mAmInternal;
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700266 UriGrantsManagerInternal mUgmInternal;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700267 private PackageManagerInternal mPmInternal;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700268 /* Global service lock used by the package the owns this service. */
269 Object mGlobalLock;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700270 ActivityStackSupervisor mStackSupervisor;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700271 WindowManagerService mWindowManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700272 private UserManagerService mUserManager;
273 private AppOpsService mAppOpsService;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700274 /** All processes currently running that might have a window organized by name. */
275 final ProcessMap<WindowProcessController> mProcessNames = new ProcessMap<>();
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700276 /** All processes we currently have running mapped by pid */
277 final SparseArray<WindowProcessController> mPidMap = new SparseArray<>();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700278 /** This is the process holding what we currently consider to be the "home" activity. */
279 WindowProcessController mHomeProcess;
280 /**
281 * This is the process holding the activity the user last visited that is in a different process
282 * from the one they are currently in.
283 */
284 WindowProcessController mPreviousProcess;
285 /** The time at which the previous process was last visible. */
286 long mPreviousProcessVisibleTime;
287
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700288 /** List of intents that were used to start the most recent tasks. */
289 private RecentTasks mRecentTasks;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700290 /** State of external calls telling us if the device is awake or asleep. */
291 private boolean mKeyguardShown = false;
292
293 // Wrapper around VoiceInteractionServiceManager
294 private AssistUtils mAssistUtils;
295
296 // VoiceInteraction session ID that changes for each new request except when
297 // being called for multi-window assist in a single session.
298 private int mViSessionId = 1000;
299
300 // How long to wait in getAssistContextExtras for the activity and foreground services
301 // to respond with the result.
302 private static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
303
304 // How long top wait when going through the modern assist (which doesn't need to block
305 // on getting this result before starting to launch its UI).
306 private static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
307
308 // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
309 private static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
310
311 private final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
312
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700313 // Keeps track of the active voice interaction service component, notified from
314 // VoiceInteractionManagerService
315 ComponentName mActiveVoiceInteractionServiceComponent;
316
317 private VrController mVrController;
318 KeyguardController mKeyguardController;
319 private final ClientLifecycleManager mLifecycleManager;
320 private TaskChangeNotificationController mTaskChangeNotificationController;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700321 /** The controller for all operations related to locktask. */
322 private LockTaskController mLockTaskController;
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700323 private ActivityStartController mActivityStartController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700324
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700325 boolean mSuppressResizeConfigChanges;
326
327 private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
328 new UpdateConfigurationResult();
329
330 static final class UpdateConfigurationResult {
331 // Configuration changes that were updated.
332 int changes;
333 // If the activity was relaunched to match the new configuration.
334 boolean activityRelaunched;
335
336 void reset() {
337 changes = 0;
338 activityRelaunched = false;
339 }
340 }
341
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700342 /** Current sequencing integer of the configuration, for skipping old configurations. */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700343 private int mConfigurationSeq;
344 // To cache the list of supported system locales
345 private String[] mSupportedSystemLocales = null;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700346
347 /**
348 * Temp object used when global and/or display override configuration is updated. It is also
349 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
350 * anyone...
351 */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700352 private Configuration mTempConfig = new Configuration();
353
Wale Ogunwalef6733932018-06-27 05:14:34 -0700354 /** Temporary to avoid allocations. */
355 final StringBuilder mStringBuilder = new StringBuilder(256);
356
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700357 // Amount of time after a call to stopAppSwitches() during which we will
358 // prevent further untrusted switches from happening.
359 private static final long APP_SWITCH_DELAY_TIME = 5 * 1000;
360
361 /**
362 * The time at which we will allow normal application switches again,
363 * after a call to {@link #stopAppSwitches()}.
364 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700365 private long mAppSwitchesAllowedTime;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700366 /**
367 * This is set to true after the first switch after mAppSwitchesAllowedTime
368 * is set; any switches after that will clear the time.
369 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700370 private boolean mDidAppSwitch;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700371
372 IActivityController mController = null;
373 boolean mControllerIsAMonkey = false;
374
375 /**
376 * Used to retain an update lock when the foreground activity is in
377 * immersive mode.
378 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700379 private final UpdateLock mUpdateLock = new UpdateLock("immersive");
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700380
381 /**
382 * Packages that are being allowed to perform unrestricted app switches. Mapping is
383 * User -> Type -> uid.
384 */
385 final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
386
387 /** The dimensions of the thumbnails in the Recents UI. */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700388 private int mThumbnailWidth;
389 private int mThumbnailHeight;
390 private float mFullscreenThumbnailScale;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700391
392 /**
393 * Flag that indicates if multi-window is enabled.
394 *
395 * For any particular form of multi-window to be enabled, generic multi-window must be enabled
396 * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
397 * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
398 * At least one of the forms of multi-window must be enabled in order for this flag to be
399 * initialized to 'true'.
400 *
401 * @see #mSupportsSplitScreenMultiWindow
402 * @see #mSupportsFreeformWindowManagement
403 * @see #mSupportsPictureInPicture
404 * @see #mSupportsMultiDisplay
405 */
406 boolean mSupportsMultiWindow;
407 boolean mSupportsSplitScreenMultiWindow;
408 boolean mSupportsFreeformWindowManagement;
409 boolean mSupportsPictureInPicture;
410 boolean mSupportsMultiDisplay;
411 boolean mForceResizableActivities;
412
413 final List<ActivityTaskManagerInternal.ScreenObserver> mScreenObservers = new ArrayList<>();
414
415 // VR Vr2d Display Id.
416 int mVr2dDisplayId = INVALID_DISPLAY;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700417
Wale Ogunwalef6733932018-06-27 05:14:34 -0700418 /**
419 * Set while we are wanting to sleep, to prevent any
420 * activities from being started/resumed.
421 *
422 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
423 *
424 * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
425 * while in the sleep state until there is a pending transition out of sleep, in which case
426 * mSleeping is set to false, and remains false while awake.
427 *
428 * Whether mSleeping can quickly toggled between true/false without the device actually
429 * display changing states is undefined.
430 */
431 private boolean mSleeping = false;
432
433 /**
434 * The process state used for processes that are running the top activities.
435 * This changes between TOP and TOP_SLEEPING to following mSleeping.
436 */
437 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
438
439 // Whether we should show our dialogs (ANR, crash, etc) or just perform their default action
440 // automatically. Important for devices without direct input devices.
441 private boolean mShowDialogs = true;
442
443 /** Set if we are shutting down the system, similar to sleeping. */
444 boolean mShuttingDown = false;
445
446 /**
447 * We want to hold a wake lock while running a voice interaction session, since
448 * this may happen with the screen off and we need to keep the CPU running to
449 * be able to continue to interact with the user.
450 */
451 PowerManager.WakeLock mVoiceWakeLock;
452
453 /**
454 * Set while we are running a voice interaction. This overrides sleeping while it is active.
455 */
456 IVoiceInteractionSession mRunningVoice;
457
458 /**
459 * The last resumed activity. This is identical to the current resumed activity most
460 * of the time but could be different when we're pausing one activity before we resume
461 * another activity.
462 */
463 ActivityRecord mLastResumedActivity;
464
465 /**
466 * The activity that is currently being traced as the active resumed activity.
467 *
468 * @see #updateResumedAppTrace
469 */
470 private @Nullable ActivityRecord mTracedResumedActivity;
471
472 /** If non-null, we are tracking the time the user spends in the currently focused app. */
473 AppTimeTracker mCurAppTimeTracker;
474
Wale Ogunwale008163e2018-07-23 23:11:08 -0700475 private AppWarnings mAppWarnings;
476
Wale Ogunwalef6733932018-06-27 05:14:34 -0700477 private FontScaleSettingObserver mFontScaleSettingObserver;
478
479 private final class FontScaleSettingObserver extends ContentObserver {
480 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
481 private final Uri mHideErrorDialogsUri = Settings.Global.getUriFor(HIDE_ERROR_DIALOGS);
482
483 public FontScaleSettingObserver() {
484 super(mH);
485 final ContentResolver resolver = mContext.getContentResolver();
486 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
487 resolver.registerContentObserver(mHideErrorDialogsUri, false, this,
488 UserHandle.USER_ALL);
489 }
490
491 @Override
492 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
493 if (mFontScaleUri.equals(uri)) {
494 updateFontScaleIfNeeded(userId);
495 } else if (mHideErrorDialogsUri.equals(uri)) {
496 synchronized (mGlobalLock) {
497 updateShouldShowDialogsLocked(getGlobalConfiguration());
498 }
499 }
500 }
501 }
502
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700503 ActivityTaskManagerService(Context context) {
504 mContext = context;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700505 mUiContext = ActivityThread.currentActivityThread().getSystemUiContext();
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700506 mLifecycleManager = new ClientLifecycleManager();
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700507 }
508
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700509 void onSystemReady() {
510 mAssistUtils = new AssistUtils(mContext);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700511 mVrController.onSystemReady();
512 mRecentTasks.onSystemReadyLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700513 }
514
Wale Ogunwalef6733932018-06-27 05:14:34 -0700515 void onInitPowerManagement() {
516 mStackSupervisor.initPowerManagement();
517 final PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
518 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
519 mVoiceWakeLock.setReferenceCounted(false);
520 }
521
522 void installSystemProviders() {
523 mFontScaleSettingObserver = new FontScaleSettingObserver();
524 }
525
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700526 void retrieveSettings(ContentResolver resolver) {
527 final boolean freeformWindowManagement =
528 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
529 || Settings.Global.getInt(
530 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
531
532 final boolean supportsMultiWindow = ActivityTaskManager.supportsMultiWindow(mContext);
533 final boolean supportsPictureInPicture = supportsMultiWindow &&
534 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
535 final boolean supportsSplitScreenMultiWindow =
536 ActivityTaskManager.supportsSplitScreenMultiWindow(mContext);
537 final boolean supportsMultiDisplay = mContext.getPackageManager()
538 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
539 final boolean alwaysFinishActivities =
540 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
541 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
542 final boolean forceResizable = Settings.Global.getInt(
543 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
544
545 // Transfer any global setting for forcing RTL layout, into a System Property
546 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
547
548 final Configuration configuration = new Configuration();
549 Settings.System.getConfiguration(resolver, configuration);
550 if (forceRtl) {
551 // This will take care of setting the correct layout direction flags
552 configuration.setLayoutDirection(configuration.locale);
553 }
554
555 synchronized (mGlobalLock) {
556 mForceResizableActivities = forceResizable;
557 final boolean multiWindowFormEnabled = freeformWindowManagement
558 || supportsSplitScreenMultiWindow
559 || supportsPictureInPicture
560 || supportsMultiDisplay;
561 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
562 mSupportsMultiWindow = true;
563 mSupportsFreeformWindowManagement = freeformWindowManagement;
564 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
565 mSupportsPictureInPicture = supportsPictureInPicture;
566 mSupportsMultiDisplay = supportsMultiDisplay;
567 } else {
568 mSupportsMultiWindow = false;
569 mSupportsFreeformWindowManagement = false;
570 mSupportsSplitScreenMultiWindow = false;
571 mSupportsPictureInPicture = false;
572 mSupportsMultiDisplay = false;
573 }
574 mWindowManager.setForceResizableTasks(mForceResizableActivities);
575 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
576 // This happens before any activities are started, so we can change global configuration
577 // in-place.
578 updateConfigurationLocked(configuration, null, true);
579 final Configuration globalConfig = getGlobalConfiguration();
580 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
581
582 // Load resources only after the current configuration has been set.
583 final Resources res = mContext.getResources();
584 mThumbnailWidth = res.getDimensionPixelSize(
585 com.android.internal.R.dimen.thumbnail_width);
586 mThumbnailHeight = res.getDimensionPixelSize(
587 com.android.internal.R.dimen.thumbnail_height);
588
589 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
590 mFullscreenThumbnailScale = (float) res
591 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
592 (float) globalConfig.screenWidthDp;
593 } else {
594 mFullscreenThumbnailScale = res.getFraction(
595 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
596 }
597 }
598 }
599
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700600 // TODO: Will be converted to WM lock once transition is complete.
601 void setActivityManagerService(ActivityManagerService am) {
602 mAm = am;
603 mGlobalLock = mAm;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700604 mH = new H(mAm.mHandlerThread.getLooper());
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700605 mUiHandler = new UiHandler();
Wale Ogunwale008163e2018-07-23 23:11:08 -0700606 mAppWarnings = new AppWarnings(
607 this, mUiContext, mH, mUiHandler, SystemServiceManager.ensureSystemDir());
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700608
609 mTempConfig.setToDefaults();
610 mTempConfig.setLocales(LocaleList.getDefault());
611 mConfigurationSeq = mTempConfig.seq = 1;
612 mStackSupervisor = createStackSupervisor();
613 mStackSupervisor.onConfigurationChanged(mTempConfig);
614
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700615 mTaskChangeNotificationController =
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700616 new TaskChangeNotificationController(mGlobalLock, mStackSupervisor, mH);
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700617 mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mH);
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700618 mActivityStartController = new ActivityStartController(this);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700619 mRecentTasks = createRecentTasks();
620 mStackSupervisor.setRecentTasks(mRecentTasks);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700621 mVrController = new VrController(mGlobalLock);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700622 mKeyguardController = mStackSupervisor.getKeyguardController();
623 }
624
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700625 void onActivityManagerInternalAdded() {
626 mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700627 mUgmInternal = LocalServices.getService(UriGrantsManagerInternal.class);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700628 }
629
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700630 protected ActivityStackSupervisor createStackSupervisor() {
631 final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mH.getLooper());
632 supervisor.initialize();
633 return supervisor;
634 }
635
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700636 void setWindowManager(WindowManagerService wm) {
637 mWindowManager = wm;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700638 mLockTaskController.setWindowManager(wm);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700639 }
640
Wale Ogunwalef6733932018-06-27 05:14:34 -0700641 UserManagerService getUserManager() {
642 if (mUserManager == null) {
643 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
644 mUserManager = (UserManagerService) IUserManager.Stub.asInterface(b);
645 }
646 return mUserManager;
647 }
648
649 AppOpsService getAppOpsService() {
650 if (mAppOpsService == null) {
651 IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
652 mAppOpsService = (AppOpsService) IAppOpsService.Stub.asInterface(b);
653 }
654 return mAppOpsService;
655 }
656
657 boolean hasUserRestriction(String restriction, int userId) {
658 return getUserManager().hasUserRestriction(restriction, userId);
659 }
660
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700661 protected RecentTasks createRecentTasks() {
662 return new RecentTasks(this, mStackSupervisor);
663 }
664
665 RecentTasks getRecentTasks() {
666 return mRecentTasks;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700667 }
668
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700669 ClientLifecycleManager getLifecycleManager() {
670 return mLifecycleManager;
671 }
672
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700673 ActivityStartController getActivityStartController() {
674 return mActivityStartController;
675 }
676
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700677 TaskChangeNotificationController getTaskChangeNotificationController() {
678 return mTaskChangeNotificationController;
679 }
680
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700681 LockTaskController getLockTaskController() {
682 return mLockTaskController;
683 }
684
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700685 private void start() {
686 LocalServices.addService(ActivityTaskManagerInternal.class, new LocalService());
687 }
688
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700689 public static final class Lifecycle extends SystemService {
690 private final ActivityTaskManagerService mService;
691
692 public Lifecycle(Context context) {
693 super(context);
694 mService = new ActivityTaskManagerService(context);
695 }
696
697 @Override
698 public void onStart() {
699 publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700700 mService.start();
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700701 }
702
703 public ActivityTaskManagerService getService() {
704 return mService;
705 }
706 }
707
708 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700709 public final int startActivity(IApplicationThread caller, String callingPackage,
710 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
711 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
712 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
713 resultWho, requestCode, startFlags, profilerInfo, bOptions,
714 UserHandle.getCallingUserId());
715 }
716
717 @Override
718 public final int startActivities(IApplicationThread caller, String callingPackage,
719 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
720 int userId) {
721 final String reason = "startActivities";
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700722 enforceNotIsolatedCaller(reason);
723 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, reason);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700724 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700725 return getActivityStartController().startActivities(caller, -1, callingPackage, intents,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700726 resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId, reason);
727 }
728
729 @Override
730 public int startActivityAsUser(IApplicationThread caller, String callingPackage,
731 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
732 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
733 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
734 resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
735 true /*validateIncomingUser*/);
736 }
737
738 int startActivityAsUser(IApplicationThread caller, String callingPackage,
739 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
740 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
741 boolean validateIncomingUser) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700742 enforceNotIsolatedCaller("startActivityAsUser");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700743
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700744 userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700745 Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
746
747 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700748 return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700749 .setCaller(caller)
750 .setCallingPackage(callingPackage)
751 .setResolvedType(resolvedType)
752 .setResultTo(resultTo)
753 .setResultWho(resultWho)
754 .setRequestCode(requestCode)
755 .setStartFlags(startFlags)
756 .setProfilerInfo(profilerInfo)
757 .setActivityOptions(bOptions)
758 .setMayWait(userId)
759 .execute();
760
761 }
762
763 @Override
764 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
765 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700766 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions) {
767 enforceNotIsolatedCaller("startActivityIntentSender");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700768 // Refuse possible leaked file descriptors
769 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
770 throw new IllegalArgumentException("File descriptors passed in Intent");
771 }
772
773 if (!(target instanceof PendingIntentRecord)) {
774 throw new IllegalArgumentException("Bad PendingIntent object");
775 }
776
777 PendingIntentRecord pir = (PendingIntentRecord)target;
778
779 synchronized (mGlobalLock) {
780 // If this is coming from the currently resumed activity, it is
781 // effectively saying that app switches are allowed at this point.
Andrii Kulian5f750bc2018-07-17 08:57:23 -0700782 final ActivityStack stack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700783 if (stack.mResumedActivity != null &&
784 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700785 mAppSwitchesAllowedTime = 0;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700786 }
787 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700788 return pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700789 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700790 }
791
792 @Override
793 public boolean startNextMatchingActivity(IBinder callingActivity, Intent intent,
794 Bundle bOptions) {
795 // Refuse possible leaked file descriptors
796 if (intent != null && intent.hasFileDescriptors()) {
797 throw new IllegalArgumentException("File descriptors passed in Intent");
798 }
799 SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
800
801 synchronized (mGlobalLock) {
802 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
803 if (r == null) {
804 SafeActivityOptions.abort(options);
805 return false;
806 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700807 if (!r.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700808 // The caller is not running... d'oh!
809 SafeActivityOptions.abort(options);
810 return false;
811 }
812 intent = new Intent(intent);
813 // The caller is not allowed to change the data.
814 intent.setDataAndType(r.intent.getData(), r.intent.getType());
815 // And we are resetting to find the next component...
816 intent.setComponent(null);
817
818 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
819
820 ActivityInfo aInfo = null;
821 try {
822 List<ResolveInfo> resolves =
823 AppGlobals.getPackageManager().queryIntentActivities(
824 intent, r.resolvedType,
825 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
826 UserHandle.getCallingUserId()).getList();
827
828 // Look for the original activity in the list...
829 final int N = resolves != null ? resolves.size() : 0;
830 for (int i=0; i<N; i++) {
831 ResolveInfo rInfo = resolves.get(i);
832 if (rInfo.activityInfo.packageName.equals(r.packageName)
833 && rInfo.activityInfo.name.equals(r.info.name)) {
834 // We found the current one... the next matching is
835 // after it.
836 i++;
837 if (i<N) {
838 aInfo = resolves.get(i).activityInfo;
839 }
840 if (debug) {
841 Slog.v(TAG, "Next matching activity: found current " + r.packageName
842 + "/" + r.info.name);
843 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
844 ? "null" : aInfo.packageName + "/" + aInfo.name));
845 }
846 break;
847 }
848 }
849 } catch (RemoteException e) {
850 }
851
852 if (aInfo == null) {
853 // Nobody who is next!
854 SafeActivityOptions.abort(options);
855 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
856 return false;
857 }
858
859 intent.setComponent(new ComponentName(
860 aInfo.applicationInfo.packageName, aInfo.name));
861 intent.setFlags(intent.getFlags()&~(
862 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
863 Intent.FLAG_ACTIVITY_CLEAR_TOP|
864 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
865 FLAG_ACTIVITY_NEW_TASK));
866
867 // Okay now we need to start the new activity, replacing the currently running activity.
868 // This is a little tricky because we want to start the new one as if the current one is
869 // finished, but not finish the current one first so that there is no flicker.
870 // And thus...
871 final boolean wasFinishing = r.finishing;
872 r.finishing = true;
873
874 // Propagate reply information over to the new activity.
875 final ActivityRecord resultTo = r.resultTo;
876 final String resultWho = r.resultWho;
877 final int requestCode = r.requestCode;
878 r.resultTo = null;
879 if (resultTo != null) {
880 resultTo.removeResultsLocked(r, resultWho, requestCode);
881 }
882
883 final long origId = Binder.clearCallingIdentity();
884 // TODO(b/64750076): Check if calling pid should really be -1.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700885 final int res = getActivityStartController()
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700886 .obtainStarter(intent, "startNextMatchingActivity")
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700887 .setCaller(r.app.getThread())
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700888 .setResolvedType(r.resolvedType)
889 .setActivityInfo(aInfo)
890 .setResultTo(resultTo != null ? resultTo.appToken : null)
891 .setResultWho(resultWho)
892 .setRequestCode(requestCode)
893 .setCallingPid(-1)
894 .setCallingUid(r.launchedFromUid)
895 .setCallingPackage(r.launchedFromPackage)
896 .setRealCallingPid(-1)
897 .setRealCallingUid(r.launchedFromUid)
898 .setActivityOptions(options)
899 .execute();
900 Binder.restoreCallingIdentity(origId);
901
902 r.finishing = wasFinishing;
903 if (res != ActivityManager.START_SUCCESS) {
904 return false;
905 }
906 return true;
907 }
908 }
909
910 @Override
911 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
912 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
913 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
914 final WaitResult res = new WaitResult();
915 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700916 enforceNotIsolatedCaller("startActivityAndWait");
917 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
918 userId, "startActivityAndWait");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700919 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700920 getActivityStartController().obtainStarter(intent, "startActivityAndWait")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700921 .setCaller(caller)
922 .setCallingPackage(callingPackage)
923 .setResolvedType(resolvedType)
924 .setResultTo(resultTo)
925 .setResultWho(resultWho)
926 .setRequestCode(requestCode)
927 .setStartFlags(startFlags)
928 .setActivityOptions(bOptions)
929 .setMayWait(userId)
930 .setProfilerInfo(profilerInfo)
931 .setWaitResult(res)
932 .execute();
933 }
934 return res;
935 }
936
937 @Override
938 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
939 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
940 int startFlags, Configuration config, Bundle bOptions, int userId) {
941 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700942 enforceNotIsolatedCaller("startActivityWithConfig");
943 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
944 "startActivityWithConfig");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700945 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700946 return getActivityStartController().obtainStarter(intent, "startActivityWithConfig")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700947 .setCaller(caller)
948 .setCallingPackage(callingPackage)
949 .setResolvedType(resolvedType)
950 .setResultTo(resultTo)
951 .setResultWho(resultWho)
952 .setRequestCode(requestCode)
953 .setStartFlags(startFlags)
954 .setGlobalConfiguration(config)
955 .setActivityOptions(bOptions)
956 .setMayWait(userId)
957 .execute();
958 }
959 }
960
961 @Override
962 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
963 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
964 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
965 int userId) {
966
967 // This is very dangerous -- it allows you to perform a start activity (including
968 // permission grants) as any app that may launch one of your own activities. So
969 // we will only allow this to be done from activities that are part of the core framework,
970 // and then only when they are running as the system.
971 final ActivityRecord sourceRecord;
972 final int targetUid;
973 final String targetPackage;
974 final boolean isResolver;
975 synchronized (mGlobalLock) {
976 if (resultTo == null) {
977 throw new SecurityException("Must be called from an activity");
978 }
979 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
980 if (sourceRecord == null) {
981 throw new SecurityException("Called with bad activity token: " + resultTo);
982 }
983 if (!sourceRecord.info.packageName.equals("android")) {
984 throw new SecurityException(
985 "Must be called from an activity that is declared in the android package");
986 }
987 if (sourceRecord.app == null) {
988 throw new SecurityException("Called without a process attached to activity");
989 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700990 if (UserHandle.getAppId(sourceRecord.app.mUid) != SYSTEM_UID) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700991 // This is still okay, as long as this activity is running under the
992 // uid of the original calling activity.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700993 if (sourceRecord.app.mUid != sourceRecord.launchedFromUid) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700994 throw new SecurityException(
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700995 "Calling activity in uid " + sourceRecord.app.mUid
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700996 + " must be system uid or original calling uid "
997 + sourceRecord.launchedFromUid);
998 }
999 }
1000 if (ignoreTargetSecurity) {
1001 if (intent.getComponent() == null) {
1002 throw new SecurityException(
1003 "Component must be specified with ignoreTargetSecurity");
1004 }
1005 if (intent.getSelector() != null) {
1006 throw new SecurityException(
1007 "Selector not allowed with ignoreTargetSecurity");
1008 }
1009 }
1010 targetUid = sourceRecord.launchedFromUid;
1011 targetPackage = sourceRecord.launchedFromPackage;
1012 isResolver = sourceRecord.isResolverOrChildActivity();
1013 }
1014
1015 if (userId == UserHandle.USER_NULL) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001016 userId = UserHandle.getUserId(sourceRecord.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001017 }
1018
1019 // TODO: Switch to user app stacks here.
1020 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001021 return getActivityStartController().obtainStarter(intent, "startActivityAsCaller")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001022 .setCallingUid(targetUid)
1023 .setCallingPackage(targetPackage)
1024 .setResolvedType(resolvedType)
1025 .setResultTo(resultTo)
1026 .setResultWho(resultWho)
1027 .setRequestCode(requestCode)
1028 .setStartFlags(startFlags)
1029 .setActivityOptions(bOptions)
1030 .setMayWait(userId)
1031 .setIgnoreTargetSecurity(ignoreTargetSecurity)
1032 .setFilterCallingUid(isResolver ? 0 /* system */ : targetUid)
1033 .execute();
1034 } catch (SecurityException e) {
1035 // XXX need to figure out how to propagate to original app.
1036 // A SecurityException here is generally actually a fault of the original
1037 // calling activity (such as a fairly granting permissions), so propagate it
1038 // back to them.
1039 /*
1040 StringBuilder msg = new StringBuilder();
1041 msg.append("While launching");
1042 msg.append(intent.toString());
1043 msg.append(": ");
1044 msg.append(e.getMessage());
1045 */
1046 throw e;
1047 }
1048 }
1049
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001050 int handleIncomingUser(int callingPid, int callingUid, int userId, String name) {
1051 return mAmInternal.handleIncomingUser(callingPid, callingUid, userId, false /* allowAll */,
1052 ALLOW_FULL_ONLY, name, null /* callerPackage */);
1053 }
1054
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001055 @Override
1056 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
1057 Intent intent, String resolvedType, IVoiceInteractionSession session,
1058 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
1059 Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001060 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001061 if (session == null || interactor == null) {
1062 throw new NullPointerException("null session or interactor");
1063 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001064 userId = handleIncomingUser(callingPid, callingUid, userId, "startVoiceActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001065 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001066 return getActivityStartController().obtainStarter(intent, "startVoiceActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001067 .setCallingUid(callingUid)
1068 .setCallingPackage(callingPackage)
1069 .setResolvedType(resolvedType)
1070 .setVoiceSession(session)
1071 .setVoiceInteractor(interactor)
1072 .setStartFlags(startFlags)
1073 .setProfilerInfo(profilerInfo)
1074 .setActivityOptions(bOptions)
1075 .setMayWait(userId)
1076 .execute();
1077 }
1078
1079 @Override
1080 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
1081 Intent intent, String resolvedType, Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001082 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
1083 userId = handleIncomingUser(callingPid, callingUid, userId, "startAssistantActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001084
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001085 return getActivityStartController().obtainStarter(intent, "startAssistantActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001086 .setCallingUid(callingUid)
1087 .setCallingPackage(callingPackage)
1088 .setResolvedType(resolvedType)
1089 .setActivityOptions(bOptions)
1090 .setMayWait(userId)
1091 .execute();
1092 }
1093
1094 @Override
1095 public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
1096 IRecentsAnimationRunner recentsAnimationRunner) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001097 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001098 final int callingPid = Binder.getCallingPid();
1099 final long origId = Binder.clearCallingIdentity();
1100 try {
1101 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07001102 final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
1103 final int recentsUid = mRecentTasks.getRecentsComponentUid();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001104
1105 // Start a new recents animation
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001106 final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
1107 getActivityStartController(), mWindowManager, callingPid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001108 anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
1109 recentsUid, assistDataReceiver);
1110 }
1111 } finally {
1112 Binder.restoreCallingIdentity(origId);
1113 }
1114 }
1115
1116 @Override
1117 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001118 enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001119 "startActivityFromRecents()");
1120
1121 final int callingPid = Binder.getCallingPid();
1122 final int callingUid = Binder.getCallingUid();
1123 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(bOptions);
1124 final long origId = Binder.clearCallingIdentity();
1125 try {
1126 synchronized (mGlobalLock) {
1127 return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
1128 safeOptions);
1129 }
1130 } finally {
1131 Binder.restoreCallingIdentity(origId);
1132 }
1133 }
1134
1135 /**
1136 * This is the internal entry point for handling Activity.finish().
1137 *
1138 * @param token The Binder token referencing the Activity we want to finish.
1139 * @param resultCode Result code, if any, from this Activity.
1140 * @param resultData Result data (Intent), if any, from this Activity.
1141 * @param finishTask Whether to finish the task associated with this Activity.
1142 *
1143 * @return Returns true if the activity successfully finished, or false if it is still running.
1144 */
1145 @Override
1146 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
1147 int finishTask) {
1148 // Refuse possible leaked file descriptors
1149 if (resultData != null && resultData.hasFileDescriptors()) {
1150 throw new IllegalArgumentException("File descriptors passed in Intent");
1151 }
1152
1153 synchronized (mGlobalLock) {
1154 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1155 if (r == null) {
1156 return true;
1157 }
1158 // Keep track of the root activity of the task before we finish it
1159 TaskRecord tr = r.getTask();
1160 ActivityRecord rootR = tr.getRootActivity();
1161 if (rootR == null) {
1162 Slog.w(TAG, "Finishing task with all activities already finished");
1163 }
1164 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
1165 // finish.
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001166 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001167 return false;
1168 }
1169
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001170 // TODO: There is a dup. of this block of code in ActivityStack.navigateUpToLocked
1171 // We should consolidate.
1172 if (mController != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001173 // Find the first activity that is not finishing.
1174 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
1175 if (next != null) {
1176 // ask watcher if this is allowed
1177 boolean resumeOK = true;
1178 try {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001179 resumeOK = mController.activityResuming(next.packageName);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001180 } catch (RemoteException e) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001181 mController = null;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001182 Watchdog.getInstance().setActivityController(null);
1183 }
1184
1185 if (!resumeOK) {
1186 Slog.i(TAG, "Not finishing activity because controller resumed");
1187 return false;
1188 }
1189 }
1190 }
1191 final long origId = Binder.clearCallingIdentity();
1192 try {
1193 boolean res;
1194 final boolean finishWithRootActivity =
1195 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
1196 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
1197 || (finishWithRootActivity && r == rootR)) {
1198 // If requested, remove the task that is associated to this activity only if it
1199 // was the root activity in the task. The result code and data is ignored
1200 // because we don't support returning them across task boundaries. Also, to
1201 // keep backwards compatibility we remove the task from recents when finishing
1202 // task with root activity.
1203 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
1204 finishWithRootActivity, "finish-activity");
1205 if (!res) {
1206 Slog.i(TAG, "Removing task failed to finish activity");
1207 }
Garfield Tan2746ab52018-07-25 12:33:01 -07001208 // Explicitly dismissing the activity so reset its relaunch flag.
1209 r.mRelaunchReason = ActivityRecord.RELAUNCH_REASON_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001210 } else {
1211 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
1212 resultData, "app-request", true);
1213 if (!res) {
1214 Slog.i(TAG, "Failed to finish by app-request");
1215 }
1216 }
1217 return res;
1218 } finally {
1219 Binder.restoreCallingIdentity(origId);
1220 }
1221 }
1222 }
1223
1224 @Override
1225 public boolean finishActivityAffinity(IBinder token) {
1226 synchronized (mGlobalLock) {
1227 final long origId = Binder.clearCallingIdentity();
1228 try {
1229 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1230 if (r == null) {
1231 return false;
1232 }
1233
1234 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
1235 // can finish.
1236 final TaskRecord task = r.getTask();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001237 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001238 return false;
1239 }
1240 return task.getStack().finishActivityAffinityLocked(r);
1241 } finally {
1242 Binder.restoreCallingIdentity(origId);
1243 }
1244 }
1245 }
1246
1247 @Override
1248 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
1249 final long origId = Binder.clearCallingIdentity();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001250 try {
1251 WindowProcessController proc = null;
1252 synchronized (mGlobalLock) {
1253 ActivityStack stack = ActivityRecord.getStackLocked(token);
1254 if (stack == null) {
1255 return;
1256 }
1257 final ActivityRecord r = mStackSupervisor.activityIdleInternalLocked(token,
1258 false /* fromTimeout */, false /* processPausingActivities */, config);
1259 if (r != null) {
1260 proc = r.app;
1261 }
1262 if (stopProfiling && proc != null) {
1263 proc.clearProfilerIfNeeded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001264 }
1265 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001266 } finally {
1267 Binder.restoreCallingIdentity(origId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001268 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001269 }
1270
1271 @Override
1272 public final void activityResumed(IBinder token) {
1273 final long origId = Binder.clearCallingIdentity();
1274 synchronized (mGlobalLock) {
1275 ActivityRecord.activityResumedLocked(token);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001276 mWindowManager.notifyAppResumedFinished(token);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001277 }
1278 Binder.restoreCallingIdentity(origId);
1279 }
1280
1281 @Override
1282 public final void activityPaused(IBinder token) {
1283 final long origId = Binder.clearCallingIdentity();
1284 synchronized (mGlobalLock) {
1285 ActivityStack stack = ActivityRecord.getStackLocked(token);
1286 if (stack != null) {
1287 stack.activityPausedLocked(token, false);
1288 }
1289 }
1290 Binder.restoreCallingIdentity(origId);
1291 }
1292
1293 @Override
1294 public final void activityStopped(IBinder token, Bundle icicle,
1295 PersistableBundle persistentState, CharSequence description) {
1296 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
1297
1298 // Refuse possible leaked file descriptors
1299 if (icicle != null && icicle.hasFileDescriptors()) {
1300 throw new IllegalArgumentException("File descriptors passed in Bundle");
1301 }
1302
1303 final long origId = Binder.clearCallingIdentity();
1304
1305 synchronized (mGlobalLock) {
1306 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1307 if (r != null) {
1308 r.activityStoppedLocked(icicle, persistentState, description);
1309 }
1310 }
1311
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001312 mAmInternal.trimApplications();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001313
1314 Binder.restoreCallingIdentity(origId);
1315 }
1316
1317 @Override
1318 public final void activityDestroyed(IBinder token) {
1319 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
1320 synchronized (mGlobalLock) {
1321 ActivityStack stack = ActivityRecord.getStackLocked(token);
1322 if (stack != null) {
1323 stack.activityDestroyedLocked(token, "activityDestroyed");
1324 }
1325 }
1326 }
1327
1328 @Override
1329 public final void activityRelaunched(IBinder token) {
1330 final long origId = Binder.clearCallingIdentity();
1331 synchronized (mGlobalLock) {
1332 mStackSupervisor.activityRelaunchedLocked(token);
1333 }
1334 Binder.restoreCallingIdentity(origId);
1335 }
1336
1337 public final void activitySlept(IBinder token) {
1338 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
1339
1340 final long origId = Binder.clearCallingIdentity();
1341
1342 synchronized (mGlobalLock) {
1343 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1344 if (r != null) {
1345 mStackSupervisor.activitySleptLocked(r);
1346 }
1347 }
1348
1349 Binder.restoreCallingIdentity(origId);
1350 }
1351
1352 @Override
1353 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
1354 synchronized (mGlobalLock) {
1355 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1356 if (r == null) {
1357 return;
1358 }
1359 final long origId = Binder.clearCallingIdentity();
1360 try {
1361 r.setRequestedOrientation(requestedOrientation);
1362 } finally {
1363 Binder.restoreCallingIdentity(origId);
1364 }
1365 }
1366 }
1367
1368 @Override
1369 public int getRequestedOrientation(IBinder token) {
1370 synchronized (mGlobalLock) {
1371 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1372 if (r == null) {
1373 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
1374 }
1375 return r.getRequestedOrientation();
1376 }
1377 }
1378
1379 @Override
1380 public void setImmersive(IBinder token, boolean immersive) {
1381 synchronized (mGlobalLock) {
1382 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1383 if (r == null) {
1384 throw new IllegalArgumentException();
1385 }
1386 r.immersive = immersive;
1387
1388 // update associated state if we're frontmost
Andrii Kulian52d255c2018-07-13 11:32:19 -07001389 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001390 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001391 applyUpdateLockStateLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001392 }
1393 }
1394 }
1395
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001396 void applyUpdateLockStateLocked(ActivityRecord r) {
1397 // Modifications to the UpdateLock state are done on our handler, outside
1398 // the activity manager's locks. The new state is determined based on the
1399 // state *now* of the relevant activity record. The object is passed to
1400 // the handler solely for logging detail, not to be consulted/modified.
1401 final boolean nextState = r != null && r.immersive;
1402 mH.post(() -> {
1403 if (mUpdateLock.isHeld() != nextState) {
1404 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1405 "Applying new update lock state '" + nextState + "' for " + r);
1406 if (nextState) {
1407 mUpdateLock.acquire();
1408 } else {
1409 mUpdateLock.release();
1410 }
1411 }
1412 });
1413 }
1414
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001415 @Override
1416 public boolean isImmersive(IBinder token) {
1417 synchronized (mGlobalLock) {
1418 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1419 if (r == null) {
1420 throw new IllegalArgumentException();
1421 }
1422 return r.immersive;
1423 }
1424 }
1425
1426 @Override
1427 public boolean isTopActivityImmersive() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001428 enforceNotIsolatedCaller("isTopActivityImmersive");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001429 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001430 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001431 return (r != null) ? r.immersive : false;
1432 }
1433 }
1434
1435 @Override
1436 public void overridePendingTransition(IBinder token, String packageName,
1437 int enterAnim, int exitAnim) {
1438 synchronized (mGlobalLock) {
1439 ActivityRecord self = ActivityRecord.isInStackLocked(token);
1440 if (self == null) {
1441 return;
1442 }
1443
1444 final long origId = Binder.clearCallingIdentity();
1445
1446 if (self.isState(
1447 ActivityStack.ActivityState.RESUMED, ActivityStack.ActivityState.PAUSING)) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001448 mWindowManager.overridePendingAppTransition(packageName,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001449 enterAnim, exitAnim, null);
1450 }
1451
1452 Binder.restoreCallingIdentity(origId);
1453 }
1454 }
1455
1456 @Override
1457 public int getFrontActivityScreenCompatMode() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001458 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
1459 ApplicationInfo ai;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001460 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001461 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001462 if (r == null) {
1463 return ActivityManager.COMPAT_MODE_UNKNOWN;
1464 }
1465 ai = r.info.applicationInfo;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001466 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001467
1468 return mAmInternal.getPackageScreenCompatMode(ai);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001469 }
1470
1471 @Override
1472 public void setFrontActivityScreenCompatMode(int mode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001473 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001474 "setFrontActivityScreenCompatMode");
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001475 ApplicationInfo ai;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001476 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001477 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001478 if (r == null) {
1479 Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity");
1480 return;
1481 }
1482 ai = r.info.applicationInfo;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001483 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001484
1485 mAmInternal.setPackageScreenCompatMode(ai, mode);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001486 }
1487
1488 @Override
1489 public int getLaunchedFromUid(IBinder activityToken) {
1490 ActivityRecord srec;
1491 synchronized (mGlobalLock) {
1492 srec = ActivityRecord.forTokenLocked(activityToken);
1493 }
1494 if (srec == null) {
1495 return -1;
1496 }
1497 return srec.launchedFromUid;
1498 }
1499
1500 @Override
1501 public String getLaunchedFromPackage(IBinder activityToken) {
1502 ActivityRecord srec;
1503 synchronized (mGlobalLock) {
1504 srec = ActivityRecord.forTokenLocked(activityToken);
1505 }
1506 if (srec == null) {
1507 return null;
1508 }
1509 return srec.launchedFromPackage;
1510 }
1511
1512 @Override
1513 public boolean convertFromTranslucent(IBinder token) {
1514 final long origId = Binder.clearCallingIdentity();
1515 try {
1516 synchronized (mGlobalLock) {
1517 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1518 if (r == null) {
1519 return false;
1520 }
1521 final boolean translucentChanged = r.changeWindowTranslucency(true);
1522 if (translucentChanged) {
1523 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
1524 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001525 mWindowManager.setAppFullscreen(token, true);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001526 return translucentChanged;
1527 }
1528 } finally {
1529 Binder.restoreCallingIdentity(origId);
1530 }
1531 }
1532
1533 @Override
1534 public boolean convertToTranslucent(IBinder token, Bundle options) {
1535 SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
1536 final long origId = Binder.clearCallingIdentity();
1537 try {
1538 synchronized (mGlobalLock) {
1539 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1540 if (r == null) {
1541 return false;
1542 }
1543 final TaskRecord task = r.getTask();
1544 int index = task.mActivities.lastIndexOf(r);
1545 if (index > 0) {
1546 ActivityRecord under = task.mActivities.get(index - 1);
1547 under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
1548 }
1549 final boolean translucentChanged = r.changeWindowTranslucency(false);
1550 if (translucentChanged) {
1551 r.getStack().convertActivityToTranslucent(r);
1552 }
1553 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001554 mWindowManager.setAppFullscreen(token, false);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001555 return translucentChanged;
1556 }
1557 } finally {
1558 Binder.restoreCallingIdentity(origId);
1559 }
1560 }
1561
1562 @Override
1563 public void notifyActivityDrawn(IBinder token) {
1564 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
1565 synchronized (mGlobalLock) {
1566 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
1567 if (r != null) {
1568 r.getStack().notifyActivityDrawnLocked(r);
1569 }
1570 }
1571 }
1572
1573 @Override
1574 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
1575 synchronized (mGlobalLock) {
1576 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1577 if (r == null) {
1578 return;
1579 }
1580 r.reportFullyDrawnLocked(restoredFromBundle);
1581 }
1582 }
1583
1584 @Override
1585 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
1586 synchronized (mGlobalLock) {
1587 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
1588 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
1589 return stack.mDisplayId;
1590 }
1591 return DEFAULT_DISPLAY;
1592 }
1593 }
1594
1595 @Override
1596 public ActivityManager.StackInfo getFocusedStackInfo() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001597 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001598 long ident = Binder.clearCallingIdentity();
1599 try {
1600 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001601 ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001602 if (focusedStack != null) {
1603 return mStackSupervisor.getStackInfo(focusedStack.mStackId);
1604 }
1605 return null;
1606 }
1607 } finally {
1608 Binder.restoreCallingIdentity(ident);
1609 }
1610 }
1611
1612 @Override
1613 public void setFocusedStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001614 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001615 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
1616 final long callingId = Binder.clearCallingIdentity();
1617 try {
1618 synchronized (mGlobalLock) {
1619 final ActivityStack stack = mStackSupervisor.getStack(stackId);
1620 if (stack == null) {
1621 Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
1622 return;
1623 }
1624 final ActivityRecord r = stack.topRunningActivityLocked();
1625 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
1626 r, "setFocusedStack")) {
1627 mStackSupervisor.resumeFocusedStackTopActivityLocked();
1628 }
1629 }
1630 } finally {
1631 Binder.restoreCallingIdentity(callingId);
1632 }
1633 }
1634
1635 @Override
1636 public void setFocusedTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001637 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001638 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
1639 final long callingId = Binder.clearCallingIdentity();
1640 try {
1641 synchronized (mGlobalLock) {
1642 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1643 if (task == null) {
1644 return;
1645 }
1646 final ActivityRecord r = task.topRunningActivityLocked();
1647 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
1648 mStackSupervisor.resumeFocusedStackTopActivityLocked();
1649 }
1650 }
1651 } finally {
1652 Binder.restoreCallingIdentity(callingId);
1653 }
1654 }
1655
1656 @Override
1657 public boolean removeTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001658 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001659 synchronized (mGlobalLock) {
1660 final long ident = Binder.clearCallingIdentity();
1661 try {
1662 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
1663 "remove-task");
1664 } finally {
1665 Binder.restoreCallingIdentity(ident);
1666 }
1667 }
1668 }
1669
1670 @Override
1671 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
1672 synchronized (mGlobalLock) {
1673 final ActivityRecord srec = ActivityRecord.forTokenLocked(token);
1674 if (srec != null) {
1675 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
1676 }
1677 }
1678 return false;
1679 }
1680
1681 @Override
1682 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
1683 Intent resultData) {
1684
1685 synchronized (mGlobalLock) {
1686 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
1687 if (r != null) {
1688 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
1689 }
1690 return false;
1691 }
1692 }
1693
1694 /**
1695 * Attempts to move a task backwards in z-order (the order of activities within the task is
1696 * unchanged).
1697 *
1698 * There are several possible results of this call:
1699 * - if the task is locked, then we will show the lock toast
1700 * - if there is a task behind the provided task, then that task is made visible and resumed as
1701 * this task is moved to the back
1702 * - otherwise, if there are no other tasks in the stack:
1703 * - if this task is in the pinned stack, then we remove the stack completely, which will
1704 * have the effect of moving the task to the top or bottom of the fullscreen stack
1705 * (depending on whether it is visible)
1706 * - otherwise, we simply return home and hide this task
1707 *
1708 * @param token A reference to the activity we wish to move
1709 * @param nonRoot If false then this only works if the activity is the root
1710 * of a task; if true it will work for any activity in a task.
1711 * @return Returns true if the move completed, false if not.
1712 */
1713 @Override
1714 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001715 enforceNotIsolatedCaller("moveActivityTaskToBack");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001716 synchronized (mGlobalLock) {
1717 final long origId = Binder.clearCallingIdentity();
1718 try {
1719 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
1720 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1721 if (task != null) {
1722 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
1723 }
1724 } finally {
1725 Binder.restoreCallingIdentity(origId);
1726 }
1727 }
1728 return false;
1729 }
1730
1731 @Override
1732 public Rect getTaskBounds(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001733 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001734 long ident = Binder.clearCallingIdentity();
1735 Rect rect = new Rect();
1736 try {
1737 synchronized (mGlobalLock) {
1738 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
1739 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1740 if (task == null) {
1741 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
1742 return rect;
1743 }
1744 if (task.getStack() != null) {
1745 // Return the bounds from window manager since it will be adjusted for various
1746 // things like the presense of a docked stack for tasks that aren't resizeable.
1747 task.getWindowContainerBounds(rect);
1748 } else {
1749 // Task isn't in window manager yet since it isn't associated with a stack.
1750 // Return the persist value from activity manager
1751 if (!task.matchParentBounds()) {
1752 rect.set(task.getBounds());
1753 } else if (task.mLastNonFullscreenBounds != null) {
1754 rect.set(task.mLastNonFullscreenBounds);
1755 }
1756 }
1757 }
1758 } finally {
1759 Binder.restoreCallingIdentity(ident);
1760 }
1761 return rect;
1762 }
1763
1764 @Override
1765 public ActivityManager.TaskDescription getTaskDescription(int id) {
1766 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001767 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001768 MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
1769 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
1770 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1771 if (tr != null) {
1772 return tr.lastTaskDescription;
1773 }
1774 }
1775 return null;
1776 }
1777
1778 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001779 public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
1780 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
1781 setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
1782 toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
1783 return;
1784 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001785 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001786 synchronized (mGlobalLock) {
1787 final long ident = Binder.clearCallingIdentity();
1788 try {
1789 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1790 if (task == null) {
1791 Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
1792 return;
1793 }
1794
1795 if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
1796 + " to windowingMode=" + windowingMode + " toTop=" + toTop);
1797
1798 if (!task.isActivityTypeStandardOrUndefined()) {
1799 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
1800 + " non-standard task " + taskId + " to windowing mode="
1801 + windowingMode);
1802 }
1803
1804 final ActivityStack stack = task.getStack();
1805 if (toTop) {
1806 stack.moveToFront("setTaskWindowingMode", task);
1807 }
1808 stack.setWindowingMode(windowingMode);
1809 } finally {
1810 Binder.restoreCallingIdentity(ident);
1811 }
1812 }
1813 }
1814
1815 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001816 public String getCallingPackage(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001817 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001818 ActivityRecord r = getCallingRecordLocked(token);
1819 return r != null ? r.info.packageName : null;
1820 }
1821 }
1822
1823 @Override
1824 public ComponentName getCallingActivity(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001825 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001826 ActivityRecord r = getCallingRecordLocked(token);
1827 return r != null ? r.intent.getComponent() : null;
1828 }
1829 }
1830
1831 private ActivityRecord getCallingRecordLocked(IBinder token) {
1832 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1833 if (r == null) {
1834 return null;
1835 }
1836 return r.resultTo;
1837 }
1838
1839 @Override
1840 public void unhandledBack() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001841 mAmInternal.enforceCallingPermission(android.Manifest.permission.FORCE_BACK, "unhandledBack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001842
1843 synchronized (mGlobalLock) {
1844 final long origId = Binder.clearCallingIdentity();
1845 try {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001846 getTopDisplayFocusedStack().unhandledBackLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001847 } finally {
1848 Binder.restoreCallingIdentity(origId);
1849 }
1850 }
1851 }
1852
1853 /**
1854 * TODO: Add mController hook
1855 */
1856 @Override
1857 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001858 mAmInternal.enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001859
1860 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
1861 synchronized (mGlobalLock) {
1862 moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
1863 false /* fromRecents */);
1864 }
1865 }
1866
1867 void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
1868 boolean fromRecents) {
1869
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001870 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001871 Binder.getCallingUid(), -1, -1, "Task to front")) {
1872 SafeActivityOptions.abort(options);
1873 return;
1874 }
1875 final long origId = Binder.clearCallingIdentity();
1876 try {
1877 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1878 if (task == null) {
1879 Slog.d(TAG, "Could not find task for id: "+ taskId);
1880 return;
1881 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001882 if (getLockTaskController().isLockTaskModeViolation(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001883 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
1884 return;
1885 }
1886 ActivityOptions realOptions = options != null
1887 ? options.getOptions(mStackSupervisor)
1888 : null;
1889 mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
1890 false /* forceNonResizable */);
1891
1892 final ActivityRecord topActivity = task.getTopActivity();
1893 if (topActivity != null) {
1894
1895 // We are reshowing a task, use a starting window to hide the initial draw delay
1896 // so the transition can start earlier.
1897 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
1898 true /* taskSwitch */, fromRecents);
1899 }
1900 } finally {
1901 Binder.restoreCallingIdentity(origId);
1902 }
1903 SafeActivityOptions.abort(options);
1904 }
1905
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001906 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
1907 int callingPid, int callingUid, String name) {
1908 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
1909 return true;
1910 }
1911
1912 if (getRecentTasks().isCallerRecents(sourceUid)) {
1913 return true;
1914 }
1915
1916 int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
1917 if (perm == PackageManager.PERMISSION_GRANTED) {
1918 return true;
1919 }
1920 if (checkAllowAppSwitchUid(sourceUid)) {
1921 return true;
1922 }
1923
1924 // If the actual IPC caller is different from the logical source, then
1925 // also see if they are allowed to control app switches.
1926 if (callingUid != -1 && callingUid != sourceUid) {
1927 perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
1928 if (perm == PackageManager.PERMISSION_GRANTED) {
1929 return true;
1930 }
1931 if (checkAllowAppSwitchUid(callingUid)) {
1932 return true;
1933 }
1934 }
1935
1936 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
1937 return false;
1938 }
1939
1940 private boolean checkAllowAppSwitchUid(int uid) {
1941 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
1942 if (types != null) {
1943 for (int i = types.size() - 1; i >= 0; i--) {
1944 if (types.valueAt(i).intValue() == uid) {
1945 return true;
1946 }
1947 }
1948 }
1949 return false;
1950 }
1951
1952 @Override
1953 public void setActivityController(IActivityController controller, boolean imAMonkey) {
1954 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
1955 "setActivityController()");
1956 synchronized (mGlobalLock) {
1957 mController = controller;
1958 mControllerIsAMonkey = imAMonkey;
1959 Watchdog.getInstance().setActivityController(controller);
1960 }
1961 }
1962
1963 boolean isControllerAMonkey() {
1964 synchronized (mGlobalLock) {
1965 return mController != null && mControllerIsAMonkey;
1966 }
1967 }
1968
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001969 @Override
1970 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
1971 synchronized (mGlobalLock) {
1972 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
1973 }
1974 }
1975
1976 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001977 public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum) {
1978 return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
1979 }
1980
1981 @Override
1982 public List<ActivityManager.RunningTaskInfo> getFilteredTasks(int maxNum,
1983 @WindowConfiguration.ActivityType int ignoreActivityType,
1984 @WindowConfiguration.WindowingMode int ignoreWindowingMode) {
1985 final int callingUid = Binder.getCallingUid();
1986 ArrayList<ActivityManager.RunningTaskInfo> list = new ArrayList<>();
1987
1988 synchronized (mGlobalLock) {
1989 if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
1990
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001991 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001992 callingUid);
1993 mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
1994 ignoreWindowingMode, callingUid, allowed);
1995 }
1996
1997 return list;
1998 }
1999
2000 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002001 public final void finishSubActivity(IBinder token, String resultWho, int requestCode) {
2002 synchronized (mGlobalLock) {
2003 final long origId = Binder.clearCallingIdentity();
2004 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2005 if (r != null) {
2006 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
2007 }
2008 Binder.restoreCallingIdentity(origId);
2009 }
2010 }
2011
2012 @Override
2013 public boolean willActivityBeVisible(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002014 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002015 ActivityStack stack = ActivityRecord.getStackLocked(token);
2016 if (stack != null) {
2017 return stack.willActivityBeVisibleLocked(token);
2018 }
2019 return false;
2020 }
2021 }
2022
2023 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002024 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002025 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002026 synchronized (mGlobalLock) {
2027 final long ident = Binder.clearCallingIdentity();
2028 try {
2029 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2030 if (task == null) {
2031 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
2032 return;
2033 }
2034
2035 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
2036 + " to stackId=" + stackId + " toTop=" + toTop);
2037
2038 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2039 if (stack == null) {
2040 throw new IllegalStateException(
2041 "moveTaskToStack: No stack for stackId=" + stackId);
2042 }
2043 if (!stack.isActivityTypeStandardOrUndefined()) {
2044 throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
2045 + taskId + " to stack " + stackId);
2046 }
2047 if (stack.inSplitScreenPrimaryWindowingMode()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002048 mWindowManager.setDockedStackCreateState(
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002049 SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
2050 }
2051 task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
2052 "moveTaskToStack");
2053 } finally {
2054 Binder.restoreCallingIdentity(ident);
2055 }
2056 }
2057 }
2058
2059 @Override
2060 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
2061 boolean preserveWindows, boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002062 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002063
2064 final long ident = Binder.clearCallingIdentity();
2065 try {
2066 synchronized (mGlobalLock) {
2067 if (animate) {
2068 final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
2069 if (stack == null) {
2070 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2071 return;
2072 }
2073 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
2074 throw new IllegalArgumentException("Stack: " + stackId
2075 + " doesn't support animated resize.");
2076 }
2077 stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
2078 animationDuration, false /* fromFullscreen */);
2079 } else {
2080 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2081 if (stack == null) {
2082 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2083 return;
2084 }
2085 mStackSupervisor.resizeStackLocked(stack, destBounds,
2086 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
2087 preserveWindows, allowResizeInDockedMode, !DEFER_RESUME);
2088 }
2089 }
2090 } finally {
2091 Binder.restoreCallingIdentity(ident);
2092 }
2093 }
2094
2095 /**
2096 * Moves the specified task to the primary-split-screen stack.
2097 *
2098 * @param taskId Id of task to move.
2099 * @param createMode The mode the primary split screen stack should be created in if it doesn't
2100 * exist already. See
2101 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
2102 * and
2103 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
2104 * @param toTop If the task and stack should be moved to the top.
2105 * @param animate Whether we should play an animation for the moving the task.
2106 * @param initialBounds If the primary stack gets created, it will use these bounds for the
2107 * stack. Pass {@code null} to use default bounds.
2108 * @param showRecents If the recents activity should be shown on the other side of the task
2109 * going into split-screen mode.
2110 */
2111 @Override
2112 public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode,
2113 boolean toTop, boolean animate, Rect initialBounds, boolean showRecents) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002114 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002115 "setTaskWindowingModeSplitScreenPrimary()");
2116 synchronized (mGlobalLock) {
2117 final long ident = Binder.clearCallingIdentity();
2118 try {
2119 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2120 if (task == null) {
2121 Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
2122 return false;
2123 }
2124 if (DEBUG_STACK) Slog.d(TAG_STACK,
2125 "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
2126 + " to createMode=" + createMode + " toTop=" + toTop);
2127 if (!task.isActivityTypeStandardOrUndefined()) {
2128 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
2129 + " non-standard task " + taskId + " to split-screen windowing mode");
2130 }
2131
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002132 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002133 final int windowingMode = task.getWindowingMode();
2134 final ActivityStack stack = task.getStack();
2135 if (toTop) {
2136 stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
2137 }
2138 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
2139 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */);
2140 return windowingMode != task.getWindowingMode();
2141 } finally {
2142 Binder.restoreCallingIdentity(ident);
2143 }
2144 }
2145 }
2146
2147 /**
2148 * Removes stacks in the input windowing modes from the system if they are of activity type
2149 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
2150 */
2151 @Override
2152 public void removeStacksInWindowingModes(int[] windowingModes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002153 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002154 "removeStacksInWindowingModes()");
2155
2156 synchronized (mGlobalLock) {
2157 final long ident = Binder.clearCallingIdentity();
2158 try {
2159 mStackSupervisor.removeStacksInWindowingModes(windowingModes);
2160 } finally {
2161 Binder.restoreCallingIdentity(ident);
2162 }
2163 }
2164 }
2165
2166 @Override
2167 public void removeStacksWithActivityTypes(int[] activityTypes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002168 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002169 "removeStacksWithActivityTypes()");
2170
2171 synchronized (mGlobalLock) {
2172 final long ident = Binder.clearCallingIdentity();
2173 try {
2174 mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
2175 } finally {
2176 Binder.restoreCallingIdentity(ident);
2177 }
2178 }
2179 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002180
2181 @Override
2182 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
2183 int userId) {
2184 final int callingUid = Binder.getCallingUid();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002185 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, "getRecentTasks");
2186 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002187 callingUid);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002188 final boolean detailed = checkGetTasksPermission(
2189 android.Manifest.permission.GET_DETAILED_TASKS, Binder.getCallingPid(),
2190 UserHandle.getAppId(callingUid))
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002191 == PackageManager.PERMISSION_GRANTED;
2192
2193 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002194 return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002195 callingUid);
2196 }
2197 }
2198
2199 @Override
2200 public List<ActivityManager.StackInfo> getAllStackInfos() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002201 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002202 long ident = Binder.clearCallingIdentity();
2203 try {
2204 synchronized (mGlobalLock) {
2205 return mStackSupervisor.getAllStackInfosLocked();
2206 }
2207 } finally {
2208 Binder.restoreCallingIdentity(ident);
2209 }
2210 }
2211
2212 @Override
2213 public ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002214 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002215 long ident = Binder.clearCallingIdentity();
2216 try {
2217 synchronized (mGlobalLock) {
2218 return mStackSupervisor.getStackInfo(windowingMode, activityType);
2219 }
2220 } finally {
2221 Binder.restoreCallingIdentity(ident);
2222 }
2223 }
2224
2225 @Override
2226 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002227 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002228 final long callingUid = Binder.getCallingUid();
2229 final long origId = Binder.clearCallingIdentity();
2230 try {
2231 synchronized (mGlobalLock) {
2232 // Cancel the recents animation synchronously (do not hold the WM lock)
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002233 mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002234 ? REORDER_MOVE_TO_ORIGINAL_POSITION
2235 : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
2236 }
2237 } finally {
2238 Binder.restoreCallingIdentity(origId);
2239 }
2240 }
2241
2242 @Override
2243 public void startLockTaskModeByToken(IBinder token) {
2244 synchronized (mGlobalLock) {
2245 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2246 if (r == null) {
2247 return;
2248 }
2249 startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
2250 }
2251 }
2252
2253 @Override
2254 public void startSystemLockTaskMode(int taskId) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002255 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002256 // This makes inner call to look as if it was initiated by system.
2257 long ident = Binder.clearCallingIdentity();
2258 try {
2259 synchronized (mGlobalLock) {
2260 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2261
2262 // When starting lock task mode the stack must be in front and focused
2263 task.getStack().moveToFront("startSystemLockTaskMode");
2264 startLockTaskModeLocked(task, true /* isSystemCaller */);
2265 }
2266 } finally {
2267 Binder.restoreCallingIdentity(ident);
2268 }
2269 }
2270
2271 @Override
2272 public void stopLockTaskModeByToken(IBinder token) {
2273 synchronized (mGlobalLock) {
2274 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2275 if (r == null) {
2276 return;
2277 }
2278 stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
2279 }
2280 }
2281
2282 /**
2283 * This API should be called by SystemUI only when user perform certain action to dismiss
2284 * lock task mode. We should only dismiss pinned lock task mode in this case.
2285 */
2286 @Override
2287 public void stopSystemLockTaskMode() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002288 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002289 stopLockTaskModeInternal(null, true /* isSystemCaller */);
2290 }
2291
2292 private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
2293 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
2294 if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
2295 return;
2296 }
2297
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002298 final ActivityStack stack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002299 if (stack == null || task != stack.topTask()) {
2300 throw new IllegalArgumentException("Invalid task, not in foreground");
2301 }
2302
2303 // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
2304 // system or a specific app.
2305 // * System-initiated requests will only start the pinned mode (screen pinning)
2306 // * App-initiated requests
2307 // - will put the device in fully locked mode (LockTask), if the app is whitelisted
2308 // - will start the pinned mode, otherwise
2309 final int callingUid = Binder.getCallingUid();
2310 long ident = Binder.clearCallingIdentity();
2311 try {
2312 // When a task is locked, dismiss the pinned stack if it exists
2313 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2314
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002315 getLockTaskController().startLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002316 } finally {
2317 Binder.restoreCallingIdentity(ident);
2318 }
2319 }
2320
2321 private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
2322 final int callingUid = Binder.getCallingUid();
2323 long ident = Binder.clearCallingIdentity();
2324 try {
2325 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002326 getLockTaskController().stopLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002327 }
2328 // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
2329 // task and jumping straight into a call in the case of emergency call back.
2330 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
2331 if (tm != null) {
2332 tm.showInCallScreen(false);
2333 }
2334 } finally {
2335 Binder.restoreCallingIdentity(ident);
2336 }
2337 }
2338
2339 @Override
2340 public boolean isInLockTaskMode() {
2341 return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
2342 }
2343
2344 @Override
2345 public int getLockTaskModeState() {
2346 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002347 return getLockTaskController().getLockTaskModeState();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002348 }
2349 }
2350
2351 @Override
2352 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
2353 synchronized (mGlobalLock) {
2354 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2355 if (r != null) {
2356 r.setTaskDescription(td);
2357 final TaskRecord task = r.getTask();
2358 task.updateTaskDescription();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002359 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002360 }
2361 }
2362 }
2363
2364 @Override
2365 public Bundle getActivityOptions(IBinder token) {
2366 final long origId = Binder.clearCallingIdentity();
2367 try {
2368 synchronized (mGlobalLock) {
2369 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
2370 if (r != null) {
2371 final ActivityOptions activityOptions = r.takeOptionsLocked();
2372 return activityOptions == null ? null : activityOptions.toBundle();
2373 }
2374 return null;
2375 }
2376 } finally {
2377 Binder.restoreCallingIdentity(origId);
2378 }
2379 }
2380
2381 @Override
2382 public List<IBinder> getAppTasks(String callingPackage) {
2383 int callingUid = Binder.getCallingUid();
2384 long ident = Binder.clearCallingIdentity();
2385 try {
2386 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002387 return mRecentTasks.getAppTasksList(callingUid, callingPackage);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002388 }
2389 } finally {
2390 Binder.restoreCallingIdentity(ident);
2391 }
2392 }
2393
2394 @Override
2395 public void finishVoiceTask(IVoiceInteractionSession session) {
2396 synchronized (mGlobalLock) {
2397 final long origId = Binder.clearCallingIdentity();
2398 try {
2399 // TODO: VI Consider treating local voice interactions and voice tasks
2400 // differently here
2401 mStackSupervisor.finishVoiceTask(session);
2402 } finally {
2403 Binder.restoreCallingIdentity(origId);
2404 }
2405 }
2406
2407 }
2408
2409 @Override
2410 public boolean isTopOfTask(IBinder token) {
2411 synchronized (mGlobalLock) {
2412 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2413 if (r == null) {
2414 throw new IllegalArgumentException();
2415 }
2416 return r.getTask().getTopActivity() == r;
2417 }
2418 }
2419
2420 @Override
2421 public void notifyLaunchTaskBehindComplete(IBinder token) {
2422 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
2423 }
2424
2425 @Override
2426 public void notifyEnterAnimationComplete(IBinder token) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002427 mH.post(() -> {
2428 synchronized (mGlobalLock) {
2429 ActivityRecord r = ActivityRecord.forTokenLocked(token);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002430 if (r != null && r.attachedToProcess()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002431 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002432 r.app.getThread().scheduleEnterAnimationComplete(r.appToken);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002433 } catch (RemoteException e) {
2434 }
2435 }
2436 }
2437
2438 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002439 }
2440
2441 /** Called from an app when assist data is ready. */
2442 @Override
2443 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
2444 AssistContent content, Uri referrer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002445 PendingAssistExtras pae = (PendingAssistExtras) token;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002446 synchronized (pae) {
2447 pae.result = extras;
2448 pae.structure = structure;
2449 pae.content = content;
2450 if (referrer != null) {
2451 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
2452 }
2453 if (structure != null) {
2454 structure.setHomeActivity(pae.isHome);
2455 }
2456 pae.haveResult = true;
2457 pae.notifyAll();
2458 if (pae.intent == null && pae.receiver == null) {
2459 // Caller is just waiting for the result.
2460 return;
2461 }
2462 }
2463 // We are now ready to launch the assist activity.
2464 IAssistDataReceiver sendReceiver = null;
2465 Bundle sendBundle = null;
2466 synchronized (mGlobalLock) {
2467 buildAssistBundleLocked(pae, extras);
2468 boolean exists = mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002469 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002470 if (!exists) {
2471 // Timed out.
2472 return;
2473 }
2474
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002475 if ((sendReceiver = pae.receiver) != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002476 // Caller wants result sent back to them.
2477 sendBundle = new Bundle();
2478 sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
2479 sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
2480 sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
2481 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
2482 }
2483 }
2484 if (sendReceiver != null) {
2485 try {
2486 sendReceiver.onHandleAssistData(sendBundle);
2487 } catch (RemoteException e) {
2488 }
2489 return;
2490 }
2491
2492 final long ident = Binder.clearCallingIdentity();
2493 try {
2494 if (TextUtils.equals(pae.intent.getAction(),
2495 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
2496 pae.intent.putExtras(pae.extras);
2497 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
2498 } else {
2499 pae.intent.replaceExtras(pae.extras);
2500 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
2501 | Intent.FLAG_ACTIVITY_SINGLE_TOP
2502 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002503 mAmInternal.closeSystemDialogs("assist");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002504
2505 try {
2506 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
2507 } catch (ActivityNotFoundException e) {
2508 Slog.w(TAG, "No activity to handle assist action.", e);
2509 }
2510 }
2511 } finally {
2512 Binder.restoreCallingIdentity(ident);
2513 }
2514 }
2515
2516 @Override
2517 public int addAppTask(IBinder activityToken, Intent intent,
2518 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
2519 final int callingUid = Binder.getCallingUid();
2520 final long callingIdent = Binder.clearCallingIdentity();
2521
2522 try {
2523 synchronized (mGlobalLock) {
2524 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
2525 if (r == null) {
2526 throw new IllegalArgumentException("Activity does not exist; token="
2527 + activityToken);
2528 }
2529 ComponentName comp = intent.getComponent();
2530 if (comp == null) {
2531 throw new IllegalArgumentException("Intent " + intent
2532 + " must specify explicit component");
2533 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002534 if (thumbnail.getWidth() != mThumbnailWidth
2535 || thumbnail.getHeight() != mThumbnailHeight) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002536 throw new IllegalArgumentException("Bad thumbnail size: got "
2537 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002538 + mThumbnailWidth + "x" + mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002539 }
2540 if (intent.getSelector() != null) {
2541 intent.setSelector(null);
2542 }
2543 if (intent.getSourceBounds() != null) {
2544 intent.setSourceBounds(null);
2545 }
2546 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
2547 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
2548 // The caller has added this as an auto-remove task... that makes no
2549 // sense, so turn off auto-remove.
2550 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
2551 }
2552 }
2553 final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
2554 STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
2555 if (ainfo.applicationInfo.uid != callingUid) {
2556 throw new SecurityException(
2557 "Can't add task for another application: target uid="
2558 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
2559 }
2560
2561 final ActivityStack stack = r.getStack();
2562 final TaskRecord task = stack.createTaskRecord(
2563 mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent,
2564 null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002565 if (!mRecentTasks.addToBottom(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002566 // The app has too many tasks already and we can't add any more
2567 stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
2568 return INVALID_TASK_ID;
2569 }
2570 task.lastTaskDescription.copyFrom(description);
2571
2572 // TODO: Send the thumbnail to WM to store it.
2573
2574 return task.taskId;
2575 }
2576 } finally {
2577 Binder.restoreCallingIdentity(callingIdent);
2578 }
2579 }
2580
2581 @Override
2582 public Point getAppTaskThumbnailSize() {
2583 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002584 return new Point(mThumbnailWidth, mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002585 }
2586 }
2587
2588 @Override
2589 public void setTaskResizeable(int taskId, int resizeableMode) {
2590 synchronized (mGlobalLock) {
2591 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
2592 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
2593 if (task == null) {
2594 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
2595 return;
2596 }
2597 task.setResizeMode(resizeableMode);
2598 }
2599 }
2600
2601 @Override
2602 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002603 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002604 long ident = Binder.clearCallingIdentity();
2605 try {
2606 synchronized (mGlobalLock) {
2607 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2608 if (task == null) {
2609 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
2610 return;
2611 }
2612 // Place the task in the right stack if it isn't there already based on
2613 // the requested bounds.
2614 // The stack transition logic is:
2615 // - a null bounds on a freeform task moves that task to fullscreen
2616 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
2617 // that task to freeform
2618 // - otherwise the task is not moved
2619 ActivityStack stack = task.getStack();
2620 if (!task.getWindowConfiguration().canResizeTask()) {
2621 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
2622 }
2623 if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
2624 stack = stack.getDisplay().getOrCreateStack(
2625 WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
2626 } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
2627 stack = stack.getDisplay().getOrCreateStack(
2628 WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
2629 }
2630
2631 // Reparent the task to the right stack if necessary
2632 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
2633 if (stack != task.getStack()) {
2634 // Defer resume until the task is resized below
2635 task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
2636 DEFER_RESUME, "resizeTask");
2637 preserveWindow = false;
2638 }
2639
2640 // After reparenting (which only resizes the task to the stack bounds), resize the
2641 // task to the actual bounds provided
2642 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
2643 }
2644 } finally {
2645 Binder.restoreCallingIdentity(ident);
2646 }
2647 }
2648
2649 @Override
2650 public boolean releaseActivityInstance(IBinder token) {
2651 synchronized (mGlobalLock) {
2652 final long origId = Binder.clearCallingIdentity();
2653 try {
2654 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2655 if (r == null) {
2656 return false;
2657 }
2658 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
2659 } finally {
2660 Binder.restoreCallingIdentity(origId);
2661 }
2662 }
2663 }
2664
2665 @Override
2666 public void releaseSomeActivities(IApplicationThread appInt) {
2667 synchronized (mGlobalLock) {
2668 final long origId = Binder.clearCallingIdentity();
2669 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002670 WindowProcessController app =
2671 mAm.getRecordForAppLocked(appInt).getWindowProcessController();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002672 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
2673 } finally {
2674 Binder.restoreCallingIdentity(origId);
2675 }
2676 }
2677 }
2678
2679 @Override
2680 public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
2681 int secondaryDisplayShowing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002682 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002683 != PackageManager.PERMISSION_GRANTED) {
2684 throw new SecurityException("Requires permission "
2685 + android.Manifest.permission.DEVICE_POWER);
2686 }
2687
2688 synchronized (mGlobalLock) {
2689 long ident = Binder.clearCallingIdentity();
2690 if (mKeyguardShown != keyguardShowing) {
2691 mKeyguardShown = keyguardShowing;
2692 reportCurKeyguardUsageEventLocked(keyguardShowing);
2693 }
2694 try {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002695 mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002696 secondaryDisplayShowing);
2697 } finally {
2698 Binder.restoreCallingIdentity(ident);
2699 }
2700 }
2701
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002702 mH.post(() -> {
2703 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2704 mScreenObservers.get(i).onKeyguardStateChanged(keyguardShowing);
2705 }
2706 });
2707 }
2708
2709 void onScreenAwakeChanged(boolean isAwake) {
2710 mH.post(() -> {
2711 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2712 mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2713 }
2714 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002715 }
2716
2717 @Override
2718 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002719 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
2720 userId, "getTaskDescriptionIcon");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002721
2722 final File passedIconFile = new File(filePath);
2723 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
2724 passedIconFile.getName());
2725 if (!legitIconFile.getPath().equals(filePath)
2726 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
2727 throw new IllegalArgumentException("Bad file path: " + filePath
2728 + " passed for userId " + userId);
2729 }
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002730 return mRecentTasks.getTaskDescriptionIcon(filePath);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002731 }
2732
2733 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002734 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002735 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
2736 final ActivityOptions activityOptions = safeOptions != null
2737 ? safeOptions.getOptions(mStackSupervisor)
2738 : null;
2739 if (activityOptions == null
2740 || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
2741 || activityOptions.getCustomInPlaceResId() == 0) {
2742 throw new IllegalArgumentException("Expected in-place ActivityOption " +
2743 "with valid animation");
2744 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002745 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
2746 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002747 activityOptions.getCustomInPlaceResId());
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002748 mWindowManager.executeAppTransition();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002749 }
2750
2751 @Override
2752 public void removeStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002753 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002754 synchronized (mGlobalLock) {
2755 final long ident = Binder.clearCallingIdentity();
2756 try {
2757 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2758 if (stack == null) {
2759 Slog.w(TAG, "removeStack: No stack with id=" + stackId);
2760 return;
2761 }
2762 if (!stack.isActivityTypeStandardOrUndefined()) {
2763 throw new IllegalArgumentException(
2764 "Removing non-standard stack is not allowed.");
2765 }
2766 mStackSupervisor.removeStack(stack);
2767 } finally {
2768 Binder.restoreCallingIdentity(ident);
2769 }
2770 }
2771 }
2772
2773 @Override
2774 public void moveStackToDisplay(int stackId, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002775 mAmInternal.enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002776
2777 synchronized (mGlobalLock) {
2778 final long ident = Binder.clearCallingIdentity();
2779 try {
2780 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
2781 + " to displayId=" + displayId);
2782 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
2783 } finally {
2784 Binder.restoreCallingIdentity(ident);
2785 }
2786 }
2787 }
2788
2789 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002790 public void exitFreeformMode(IBinder token) {
2791 synchronized (mGlobalLock) {
2792 long ident = Binder.clearCallingIdentity();
2793 try {
2794 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2795 if (r == null) {
2796 throw new IllegalArgumentException(
2797 "exitFreeformMode: No activity record matching token=" + token);
2798 }
2799
2800 final ActivityStack stack = r.getStack();
2801 if (stack == null || !stack.inFreeformWindowingMode()) {
2802 throw new IllegalStateException(
2803 "exitFreeformMode: You can only go fullscreen from freeform.");
2804 }
2805
2806 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
2807 } finally {
2808 Binder.restoreCallingIdentity(ident);
2809 }
2810 }
2811 }
2812
2813 /** Sets the task stack listener that gets callbacks when a task stack changes. */
2814 @Override
2815 public void registerTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002816 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002817 "registerTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002818 mTaskChangeNotificationController.registerTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002819 }
2820
2821 /** Unregister a task stack listener so that it stops receiving callbacks. */
2822 @Override
2823 public void unregisterTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002824 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002825 "unregisterTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002826 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002827 }
2828
2829 private void reportCurKeyguardUsageEventLocked(boolean keyguardShowing) {
2830 mAm.reportGlobalUsageEventLocked(keyguardShowing
2831 ? UsageEvents.Event.KEYGUARD_SHOWN
2832 : UsageEvents.Event.KEYGUARD_HIDDEN);
2833 }
2834
2835 @Override
2836 public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
2837 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
2838 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
2839 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
2840 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
2841 }
2842
2843 @Override
2844 public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
2845 IBinder activityToken, int flags) {
2846 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
2847 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
2848 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
2849 }
2850
2851 @Override
2852 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
2853 Bundle args) {
2854 return enqueueAssistContext(requestType, intent, hint, null, null, null,
2855 true /* focused */, true /* newSessionId */, userHandle, args,
2856 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
2857 }
2858
2859 @Override
2860 public Bundle getAssistContextExtras(int requestType) {
2861 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
2862 null, null, true /* focused */, true /* newSessionId */,
2863 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
2864 if (pae == null) {
2865 return null;
2866 }
2867 synchronized (pae) {
2868 while (!pae.haveResult) {
2869 try {
2870 pae.wait();
2871 } catch (InterruptedException e) {
2872 }
2873 }
2874 }
2875 synchronized (mGlobalLock) {
2876 buildAssistBundleLocked(pae, pae.result);
2877 mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002878 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002879 }
2880 return pae.extras;
2881 }
2882
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002883 /**
2884 * Binder IPC calls go through the public entry point.
2885 * This can be called with or without the global lock held.
2886 */
2887 private static int checkCallingPermission(String permission) {
2888 return checkPermission(
2889 permission, Binder.getCallingPid(), UserHandle.getAppId(Binder.getCallingUid()));
2890 }
2891
2892 /** This can be called with or without the global lock held. */
2893 void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
2894 if (!getRecentTasks().isCallerRecents(Binder.getCallingUid())) {
2895 mAmInternal.enforceCallingPermission(permission, func);
2896 }
2897 }
2898
2899 @VisibleForTesting
2900 int checkGetTasksPermission(String permission, int pid, int uid) {
2901 return checkPermission(permission, pid, uid);
2902 }
2903
2904 static int checkPermission(String permission, int pid, int uid) {
2905 if (permission == null) {
2906 return PackageManager.PERMISSION_DENIED;
2907 }
2908 return checkComponentPermission(permission, pid, uid, -1, true);
2909 }
2910
2911 boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
2912 if (getRecentTasks().isCallerRecents(callingUid)) {
2913 // Always allow the recents component to get tasks
2914 return true;
2915 }
2916
2917 boolean allowed = checkGetTasksPermission(android.Manifest.permission.REAL_GET_TASKS,
2918 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
2919 if (!allowed) {
2920 if (checkGetTasksPermission(android.Manifest.permission.GET_TASKS,
2921 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
2922 // Temporary compatibility: some existing apps on the system image may
2923 // still be requesting the old permission and not switched to the new
2924 // one; if so, we'll still allow them full access. This means we need
2925 // to see if they are holding the old permission and are a system app.
2926 try {
2927 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
2928 allowed = true;
2929 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
2930 + " is using old GET_TASKS but privileged; allowing");
2931 }
2932 } catch (RemoteException e) {
2933 }
2934 }
2935 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
2936 + " does not hold REAL_GET_TASKS; limiting output");
2937 }
2938 return allowed;
2939 }
2940
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002941 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
2942 IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
2943 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
2944 int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002945 mAmInternal.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002946 "enqueueAssistContext()");
2947
2948 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002949 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002950 if (activity == null) {
2951 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
2952 return null;
2953 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002954 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002955 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
2956 return null;
2957 }
2958 if (focused) {
2959 if (activityToken != null) {
2960 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
2961 if (activity != caller) {
2962 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
2963 + " is not current top " + activity);
2964 return null;
2965 }
2966 }
2967 } else {
2968 activity = ActivityRecord.forTokenLocked(activityToken);
2969 if (activity == null) {
2970 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
2971 + " couldn't be found");
2972 return null;
2973 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002974 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002975 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
2976 return null;
2977 }
2978 }
2979
2980 PendingAssistExtras pae;
2981 Bundle extras = new Bundle();
2982 if (args != null) {
2983 extras.putAll(args);
2984 }
2985 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002986 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002987
2988 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
2989 userHandle);
2990 pae.isHome = activity.isActivityTypeHome();
2991
2992 // Increment the sessionId if necessary
2993 if (newSessionId) {
2994 mViSessionId++;
2995 }
2996 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002997 activity.app.getThread().requestAssistContextExtras(activity.appToken, pae,
2998 requestType, mViSessionId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002999 mPendingAssistExtras.add(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003000 mUiHandler.postDelayed(pae, timeout);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003001 } catch (RemoteException e) {
3002 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
3003 return null;
3004 }
3005 return pae;
3006 }
3007 }
3008
3009 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
3010 if (result != null) {
3011 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
3012 }
3013 if (pae.hint != null) {
3014 pae.extras.putBoolean(pae.hint, true);
3015 }
3016 }
3017
3018 private void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
3019 IAssistDataReceiver receiver;
3020 synchronized (mGlobalLock) {
3021 mPendingAssistExtras.remove(pae);
3022 receiver = pae.receiver;
3023 }
3024 if (receiver != null) {
3025 // Caller wants result sent back to them.
3026 Bundle sendBundle = new Bundle();
3027 // At least return the receiver extras
3028 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
3029 try {
3030 pae.receiver.onHandleAssistData(sendBundle);
3031 } catch (RemoteException e) {
3032 }
3033 }
3034 }
3035
3036 public class PendingAssistExtras extends Binder implements Runnable {
3037 public final ActivityRecord activity;
3038 public boolean isHome;
3039 public final Bundle extras;
3040 public final Intent intent;
3041 public final String hint;
3042 public final IAssistDataReceiver receiver;
3043 public final int userHandle;
3044 public boolean haveResult = false;
3045 public Bundle result = null;
3046 public AssistStructure structure = null;
3047 public AssistContent content = null;
3048 public Bundle receiverExtras;
3049
3050 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
3051 String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
3052 int _userHandle) {
3053 activity = _activity;
3054 extras = _extras;
3055 intent = _intent;
3056 hint = _hint;
3057 receiver = _receiver;
3058 receiverExtras = _receiverExtras;
3059 userHandle = _userHandle;
3060 }
3061
3062 @Override
3063 public void run() {
3064 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
3065 synchronized (this) {
3066 haveResult = true;
3067 notifyAll();
3068 }
3069 pendingAssistExtrasTimedOut(this);
3070 }
3071 }
3072
3073 @Override
3074 public boolean isAssistDataAllowedOnCurrentActivity() {
3075 int userId;
3076 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003077 final ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003078 if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
3079 return false;
3080 }
3081
3082 final ActivityRecord activity = focusedStack.getTopActivity();
3083 if (activity == null) {
3084 return false;
3085 }
3086 userId = activity.userId;
3087 }
3088 return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
3089 }
3090
3091 @Override
3092 public boolean showAssistFromActivity(IBinder token, Bundle args) {
3093 long ident = Binder.clearCallingIdentity();
3094 try {
3095 synchronized (mGlobalLock) {
3096 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003097 ActivityRecord top = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003098 if (top != caller) {
3099 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3100 + " is not current top " + top);
3101 return false;
3102 }
3103 if (!top.nowVisible) {
3104 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3105 + " is not visible");
3106 return false;
3107 }
3108 }
3109 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
3110 token);
3111 } finally {
3112 Binder.restoreCallingIdentity(ident);
3113 }
3114 }
3115
3116 @Override
3117 public boolean isRootVoiceInteraction(IBinder token) {
3118 synchronized (mGlobalLock) {
3119 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3120 if (r == null) {
3121 return false;
3122 }
3123 return r.rootVoiceInteraction;
3124 }
3125 }
3126
Wale Ogunwalef6733932018-06-27 05:14:34 -07003127 private void onLocalVoiceInteractionStartedLocked(IBinder activity,
3128 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
3129 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
3130 if (activityToCallback == null) return;
3131 activityToCallback.setVoiceSessionLocked(voiceSession);
3132
3133 // Inform the activity
3134 try {
3135 activityToCallback.app.getThread().scheduleLocalVoiceInteractionStarted(activity,
3136 voiceInteractor);
3137 long token = Binder.clearCallingIdentity();
3138 try {
3139 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
3140 } finally {
3141 Binder.restoreCallingIdentity(token);
3142 }
3143 // TODO: VI Should we cache the activity so that it's easier to find later
3144 // rather than scan through all the stacks and activities?
3145 } catch (RemoteException re) {
3146 activityToCallback.clearVoiceSessionLocked();
3147 // TODO: VI Should this terminate the voice session?
3148 }
3149 }
3150
3151 private void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
3152 Slog.d(TAG, "<<< startRunningVoiceLocked()");
3153 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
3154 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
3155 boolean wasRunningVoice = mRunningVoice != null;
3156 mRunningVoice = session;
3157 if (!wasRunningVoice) {
3158 mVoiceWakeLock.acquire();
3159 updateSleepIfNeededLocked();
3160 }
3161 }
3162 }
3163
3164 void finishRunningVoiceLocked() {
3165 if (mRunningVoice != null) {
3166 mRunningVoice = null;
3167 mVoiceWakeLock.release();
3168 updateSleepIfNeededLocked();
3169 }
3170 }
3171
3172 @Override
3173 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3174 synchronized (mGlobalLock) {
3175 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3176 if (keepAwake) {
3177 mVoiceWakeLock.acquire();
3178 } else {
3179 mVoiceWakeLock.release();
3180 }
3181 }
3182 }
3183 }
3184
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003185 @Override
3186 public ComponentName getActivityClassForToken(IBinder token) {
3187 synchronized (mGlobalLock) {
3188 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3189 if (r == null) {
3190 return null;
3191 }
3192 return r.intent.getComponent();
3193 }
3194 }
3195
3196 @Override
3197 public String getPackageForToken(IBinder token) {
3198 synchronized (mGlobalLock) {
3199 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3200 if (r == null) {
3201 return null;
3202 }
3203 return r.packageName;
3204 }
3205 }
3206
3207 @Override
3208 public void showLockTaskEscapeMessage(IBinder token) {
3209 synchronized (mGlobalLock) {
3210 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3211 if (r == null) {
3212 return;
3213 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003214 getLockTaskController().showLockTaskToast();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003215 }
3216 }
3217
3218 @Override
3219 public void keyguardGoingAway(int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003220 enforceNotIsolatedCaller("keyguardGoingAway");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003221 final long token = Binder.clearCallingIdentity();
3222 try {
3223 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003224 mKeyguardController.keyguardGoingAway(flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003225 }
3226 } finally {
3227 Binder.restoreCallingIdentity(token);
3228 }
3229 }
3230
3231 /**
3232 * Try to place task to provided position. The final position might be different depending on
3233 * current user and stacks state. The task will be moved to target stack if it's currently in
3234 * different stack.
3235 */
3236 @Override
3237 public void positionTaskInStack(int taskId, int stackId, int position) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003238 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003239 synchronized (mGlobalLock) {
3240 long ident = Binder.clearCallingIdentity();
3241 try {
3242 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
3243 + taskId + " in stackId=" + stackId + " at position=" + position);
3244 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3245 if (task == null) {
3246 throw new IllegalArgumentException("positionTaskInStack: no task for id="
3247 + taskId);
3248 }
3249
3250 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3251
3252 if (stack == null) {
3253 throw new IllegalArgumentException("positionTaskInStack: no stack for id="
3254 + stackId);
3255 }
3256 if (!stack.isActivityTypeStandardOrUndefined()) {
3257 throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
3258 + " the position of task " + taskId + " in/to non-standard stack");
3259 }
3260
3261 // TODO: Have the callers of this API call a separate reparent method if that is
3262 // what they intended to do vs. having this method also do reparenting.
3263 if (task.getStack() == stack) {
3264 // Change position in current stack.
3265 stack.positionChildAt(task, position);
3266 } else {
3267 // Reparent to new stack.
3268 task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
3269 !DEFER_RESUME, "positionTaskInStack");
3270 }
3271 } finally {
3272 Binder.restoreCallingIdentity(ident);
3273 }
3274 }
3275 }
3276
3277 @Override
3278 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
3279 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
3280 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
3281 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
3282 synchronized (mGlobalLock) {
3283 ActivityRecord record = ActivityRecord.isInStackLocked(token);
3284 if (record == null) {
3285 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
3286 + "found for: " + token);
3287 }
3288 record.setSizeConfigurations(horizontalSizeConfiguration,
3289 verticalSizeConfigurations, smallestSizeConfigurations);
3290 }
3291 }
3292
3293 /**
3294 * Dismisses split-screen multi-window mode.
3295 * @param toTop If true the current primary split-screen stack will be placed or left on top.
3296 */
3297 @Override
3298 public void dismissSplitScreenMode(boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003299 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003300 MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
3301 final long ident = Binder.clearCallingIdentity();
3302 try {
3303 synchronized (mGlobalLock) {
3304 final ActivityStack stack =
3305 mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
3306 if (stack == null) {
3307 Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
3308 return;
3309 }
3310
3311 if (toTop) {
3312 // Caller wants the current split-screen primary stack to be the top stack after
3313 // it goes fullscreen, so move it to the front.
3314 stack.moveToFront("dismissSplitScreenMode");
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003315 } else if (mStackSupervisor.isTopDisplayFocusedStack(stack)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003316 // In this case the current split-screen primary stack shouldn't be the top
3317 // stack after it goes fullscreen, but it current has focus, so we move the
3318 // focus to the top-most split-screen secondary stack next to it.
3319 final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
3320 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
3321 if (otherStack != null) {
3322 otherStack.moveToFront("dismissSplitScreenMode_other");
3323 }
3324 }
3325
3326 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
3327 }
3328 } finally {
3329 Binder.restoreCallingIdentity(ident);
3330 }
3331 }
3332
3333 /**
3334 * Dismisses Pip
3335 * @param animate True if the dismissal should be animated.
3336 * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
3337 * default animation duration should be used.
3338 */
3339 @Override
3340 public void dismissPip(boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003341 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003342 final long ident = Binder.clearCallingIdentity();
3343 try {
3344 synchronized (mGlobalLock) {
3345 final PinnedActivityStack stack =
3346 mStackSupervisor.getDefaultDisplay().getPinnedStack();
3347 if (stack == null) {
3348 Slog.w(TAG, "dismissPip: pinned stack not found.");
3349 return;
3350 }
3351 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
3352 throw new IllegalArgumentException("Stack: " + stack
3353 + " doesn't support animated resize.");
3354 }
3355 if (animate) {
3356 stack.animateResizePinnedStack(null /* sourceHintBounds */,
3357 null /* destBounds */, animationDuration, false /* fromFullscreen */);
3358 } else {
3359 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
3360 }
3361 }
3362 } finally {
3363 Binder.restoreCallingIdentity(ident);
3364 }
3365 }
3366
3367 @Override
3368 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003369 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003370 synchronized (mGlobalLock) {
3371 mSuppressResizeConfigChanges = suppress;
3372 }
3373 }
3374
3375 /**
3376 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
3377 * animated the stack to the fullscreen, but can also be called if we are relaunching an
3378 * activity and clearing the task at the same time.
3379 */
3380 @Override
3381 // TODO: API should just be about changing windowing modes...
3382 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003383 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003384 "moveTasksToFullscreenStack()");
3385 synchronized (mGlobalLock) {
3386 final long origId = Binder.clearCallingIdentity();
3387 try {
3388 final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
3389 if (stack != null){
3390 if (!stack.isActivityTypeStandardOrUndefined()) {
3391 throw new IllegalArgumentException(
3392 "You can't move tasks from non-standard stacks.");
3393 }
3394 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
3395 }
3396 } finally {
3397 Binder.restoreCallingIdentity(origId);
3398 }
3399 }
3400 }
3401
3402 /**
3403 * Moves the top activity in the input stackId to the pinned stack.
3404 *
3405 * @param stackId Id of stack to move the top activity to pinned stack.
3406 * @param bounds Bounds to use for pinned stack.
3407 *
3408 * @return True if the top activity of the input stack was successfully moved to the pinned
3409 * stack.
3410 */
3411 @Override
3412 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003413 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003414 "moveTopActivityToPinnedStack()");
3415 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003416 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003417 throw new IllegalStateException("moveTopActivityToPinnedStack:"
3418 + "Device doesn't support picture-in-picture mode");
3419 }
3420
3421 long ident = Binder.clearCallingIdentity();
3422 try {
3423 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
3424 } finally {
3425 Binder.restoreCallingIdentity(ident);
3426 }
3427 }
3428 }
3429
3430 @Override
3431 public boolean isInMultiWindowMode(IBinder token) {
3432 final long origId = Binder.clearCallingIdentity();
3433 try {
3434 synchronized (mGlobalLock) {
3435 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3436 if (r == null) {
3437 return false;
3438 }
3439 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
3440 return r.inMultiWindowMode();
3441 }
3442 } finally {
3443 Binder.restoreCallingIdentity(origId);
3444 }
3445 }
3446
3447 @Override
3448 public boolean isInPictureInPictureMode(IBinder token) {
3449 final long origId = Binder.clearCallingIdentity();
3450 try {
3451 synchronized (mGlobalLock) {
3452 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
3453 }
3454 } finally {
3455 Binder.restoreCallingIdentity(origId);
3456 }
3457 }
3458
3459 private boolean isInPictureInPictureMode(ActivityRecord r) {
3460 if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
3461 || r.getStack().isInStackLocked(r) == null) {
3462 return false;
3463 }
3464
3465 // If we are animating to fullscreen then we have already dispatched the PIP mode
3466 // changed, so we should reflect that check here as well.
3467 final PinnedActivityStack stack = r.getStack();
3468 final PinnedStackWindowController windowController = stack.getWindowContainerController();
3469 return !windowController.isAnimatingBoundsToFullscreen();
3470 }
3471
3472 @Override
3473 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
3474 final long origId = Binder.clearCallingIdentity();
3475 try {
3476 synchronized (mGlobalLock) {
3477 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3478 "enterPictureInPictureMode", token, params);
3479
3480 // If the activity is already in picture in picture mode, then just return early
3481 if (isInPictureInPictureMode(r)) {
3482 return true;
3483 }
3484
3485 // Activity supports picture-in-picture, now check that we can enter PiP at this
3486 // point, if it is
3487 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
3488 false /* beforeStopping */)) {
3489 return false;
3490 }
3491
3492 final Runnable enterPipRunnable = () -> {
Wale Ogunwalef276a6f2018-06-15 08:26:07 -07003493 synchronized (mGlobalLock) {
3494 // Only update the saved args from the args that are set
3495 r.pictureInPictureArgs.copyOnlySet(params);
3496 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
3497 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
3498 // Adjust the source bounds by the insets for the transition down
3499 final Rect sourceBounds = new Rect(
3500 r.pictureInPictureArgs.getSourceRectHint());
3501 mStackSupervisor.moveActivityToPinnedStackLocked(
3502 r, sourceBounds, aspectRatio, "enterPictureInPictureMode");
3503 final PinnedActivityStack stack = r.getStack();
3504 stack.setPictureInPictureAspectRatio(aspectRatio);
3505 stack.setPictureInPictureActions(actions);
3506 MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
3507 r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
3508 logPictureInPictureArgs(params);
3509 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003510 };
3511
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003512 if (isKeyguardLocked()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003513 // If the keyguard is showing or occluded, then try and dismiss it before
3514 // entering picture-in-picture (this will prompt the user to authenticate if the
3515 // device is currently locked).
3516 dismissKeyguard(token, new KeyguardDismissCallback() {
3517 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003518 public void onDismissSucceeded() {
3519 mH.post(enterPipRunnable);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003520 }
3521 }, null /* message */);
3522 } else {
3523 // Enter picture in picture immediately otherwise
3524 enterPipRunnable.run();
3525 }
3526 return true;
3527 }
3528 } finally {
3529 Binder.restoreCallingIdentity(origId);
3530 }
3531 }
3532
3533 @Override
3534 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
3535 final long origId = Binder.clearCallingIdentity();
3536 try {
3537 synchronized (mGlobalLock) {
3538 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3539 "setPictureInPictureParams", token, params);
3540
3541 // Only update the saved args from the args that are set
3542 r.pictureInPictureArgs.copyOnlySet(params);
3543 if (r.inPinnedWindowingMode()) {
3544 // If the activity is already in picture-in-picture, update the pinned stack now
3545 // if it is not already expanding to fullscreen. Otherwise, the arguments will
3546 // be used the next time the activity enters PiP
3547 final PinnedActivityStack stack = r.getStack();
3548 if (!stack.isAnimatingBoundsToFullscreen()) {
3549 stack.setPictureInPictureAspectRatio(
3550 r.pictureInPictureArgs.getAspectRatio());
3551 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
3552 }
3553 }
3554 logPictureInPictureArgs(params);
3555 }
3556 } finally {
3557 Binder.restoreCallingIdentity(origId);
3558 }
3559 }
3560
3561 @Override
3562 public int getMaxNumPictureInPictureActions(IBinder token) {
3563 // Currently, this is a static constant, but later, we may change this to be dependent on
3564 // the context of the activity
3565 return 3;
3566 }
3567
3568 private void logPictureInPictureArgs(PictureInPictureParams params) {
3569 if (params.hasSetActions()) {
3570 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
3571 params.getActions().size());
3572 }
3573 if (params.hasSetAspectRatio()) {
3574 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
3575 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
3576 MetricsLogger.action(lm);
3577 }
3578 }
3579
3580 /**
3581 * Checks the state of the system and the activity associated with the given {@param token} to
3582 * verify that picture-in-picture is supported for that activity.
3583 *
3584 * @return the activity record for the given {@param token} if all the checks pass.
3585 */
3586 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
3587 IBinder token, PictureInPictureParams params) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003588 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003589 throw new IllegalStateException(caller
3590 + ": Device doesn't support picture-in-picture mode.");
3591 }
3592
3593 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3594 if (r == null) {
3595 throw new IllegalStateException(caller
3596 + ": Can't find activity for token=" + token);
3597 }
3598
3599 if (!r.supportsPictureInPicture()) {
3600 throw new IllegalStateException(caller
3601 + ": Current activity does not support picture-in-picture.");
3602 }
3603
3604 if (params.hasSetAspectRatio()
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003605 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003606 params.getAspectRatio())) {
3607 final float minAspectRatio = mContext.getResources().getFloat(
3608 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
3609 final float maxAspectRatio = mContext.getResources().getFloat(
3610 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
3611 throw new IllegalArgumentException(String.format(caller
3612 + ": Aspect ratio is too extreme (must be between %f and %f).",
3613 minAspectRatio, maxAspectRatio));
3614 }
3615
3616 // Truncate the number of actions if necessary
3617 params.truncateActions(getMaxNumPictureInPictureActions(token));
3618
3619 return r;
3620 }
3621
3622 @Override
3623 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003624 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003625 synchronized (mGlobalLock) {
3626 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
3627 if (r == null) {
3628 throw new IllegalArgumentException("Activity does not exist; token="
3629 + activityToken);
3630 }
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07003631 return r.getUriPermissionsLocked().getExternalToken();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003632 }
3633 }
3634
3635 @Override
3636 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
3637 Rect tempDockedTaskInsetBounds,
3638 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003639 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003640 long ident = Binder.clearCallingIdentity();
3641 try {
3642 synchronized (mGlobalLock) {
3643 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
3644 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
3645 PRESERVE_WINDOWS);
3646 }
3647 } finally {
3648 Binder.restoreCallingIdentity(ident);
3649 }
3650 }
3651
3652 @Override
3653 public void setSplitScreenResizing(boolean resizing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003654 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003655 final long ident = Binder.clearCallingIdentity();
3656 try {
3657 synchronized (mGlobalLock) {
3658 mStackSupervisor.setSplitScreenResizing(resizing);
3659 }
3660 } finally {
3661 Binder.restoreCallingIdentity(ident);
3662 }
3663 }
3664
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003665 /**
3666 * Check that we have the features required for VR-related API calls, and throw an exception if
3667 * not.
3668 */
3669 void enforceSystemHasVrFeature() {
3670 if (!mContext.getPackageManager().hasSystemFeature(
3671 PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
3672 throw new UnsupportedOperationException("VR mode not supported on this device!");
3673 }
3674 }
3675
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003676 @Override
3677 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003678 enforceSystemHasVrFeature();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003679
3680 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3681
3682 ActivityRecord r;
3683 synchronized (mGlobalLock) {
3684 r = ActivityRecord.isInStackLocked(token);
3685 }
3686
3687 if (r == null) {
3688 throw new IllegalArgumentException();
3689 }
3690
3691 int err;
3692 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
3693 VrManagerInternal.NO_ERROR) {
3694 return err;
3695 }
3696
3697 // Clear the binder calling uid since this path may call moveToTask().
3698 final long callingId = Binder.clearCallingIdentity();
3699 try {
3700 synchronized (mGlobalLock) {
3701 r.requestedVrComponent = (enabled) ? packageName : null;
3702
3703 // Update associated state if this activity is currently focused
Andrii Kulian52d255c2018-07-13 11:32:19 -07003704 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003705 applyUpdateVrModeLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003706 }
3707 return 0;
3708 }
3709 } finally {
3710 Binder.restoreCallingIdentity(callingId);
3711 }
3712 }
3713
3714 @Override
3715 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
3716 Slog.i(TAG, "Activity tried to startLocalVoiceInteraction");
3717 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003718 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003719 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
3720 throw new SecurityException("Only focused activity can call startVoiceInteraction");
3721 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07003722 if (mRunningVoice != null || activity.getTask().voiceSession != null
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003723 || activity.voiceSession != null) {
3724 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
3725 return;
3726 }
3727 if (activity.pendingVoiceInteractionStart) {
3728 Slog.w(TAG, "Pending start of voice interaction already.");
3729 return;
3730 }
3731 activity.pendingVoiceInteractionStart = true;
3732 }
3733 LocalServices.getService(VoiceInteractionManagerInternal.class)
3734 .startLocalVoiceInteraction(callingActivity, options);
3735 }
3736
3737 @Override
3738 public void stopLocalVoiceInteraction(IBinder callingActivity) {
3739 LocalServices.getService(VoiceInteractionManagerInternal.class)
3740 .stopLocalVoiceInteraction(callingActivity);
3741 }
3742
3743 @Override
3744 public boolean supportsLocalVoiceInteraction() {
3745 return LocalServices.getService(VoiceInteractionManagerInternal.class)
3746 .supportsLocalVoiceInteraction();
3747 }
3748
3749 /** Notifies all listeners when the pinned stack animation starts. */
3750 @Override
3751 public void notifyPinnedStackAnimationStarted() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003752 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003753 }
3754
3755 /** Notifies all listeners when the pinned stack animation ends. */
3756 @Override
3757 public void notifyPinnedStackAnimationEnded() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003758 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003759 }
3760
3761 @Override
3762 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003763 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003764 final long ident = Binder.clearCallingIdentity();
3765 try {
3766 synchronized (mGlobalLock) {
3767 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
3768 }
3769 } finally {
3770 Binder.restoreCallingIdentity(ident);
3771 }
3772 }
3773
3774 @Override
3775 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003776 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003777
3778 synchronized (mGlobalLock) {
3779 // Check if display is initialized in AM.
3780 if (!mStackSupervisor.isDisplayAdded(displayId)) {
3781 // Call might come when display is not yet added or has already been removed.
3782 if (DEBUG_CONFIGURATION) {
3783 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
3784 + displayId);
3785 }
3786 return false;
3787 }
3788
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003789 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003790 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003791 values = mWindowManager.computeNewConfiguration(displayId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003792 }
3793
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003794 if (mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003795 // Update OOM levels based on display size.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003796 mAm.mProcessList.applyDisplaySize(mWindowManager);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003797 }
3798
3799 final long origId = Binder.clearCallingIdentity();
3800 try {
3801 if (values != null) {
3802 Settings.System.clearConfiguration(values);
3803 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003804 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003805 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
3806 return mTmpUpdateConfigurationResult.changes != 0;
3807 } finally {
3808 Binder.restoreCallingIdentity(origId);
3809 }
3810 }
3811 }
3812
3813 @Override
3814 public boolean updateConfiguration(Configuration values) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003815 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003816
3817 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003818 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003819 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003820 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003821 }
3822
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003823 if (mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003824 // Update OOM levels based on display size.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003825 mAm.mProcessList.applyDisplaySize(mWindowManager);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003826 }
3827
3828 final long origId = Binder.clearCallingIdentity();
3829 try {
3830 if (values != null) {
3831 Settings.System.clearConfiguration(values);
3832 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003833 updateConfigurationLocked(values, null, false, false /* persistent */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003834 UserHandle.USER_NULL, false /* deferResume */,
3835 mTmpUpdateConfigurationResult);
3836 return mTmpUpdateConfigurationResult.changes != 0;
3837 } finally {
3838 Binder.restoreCallingIdentity(origId);
3839 }
3840 }
3841 }
3842
3843 @Override
3844 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
3845 CharSequence message) {
3846 if (message != null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003847 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003848 Manifest.permission.SHOW_KEYGUARD_MESSAGE, "dismissKeyguard()");
3849 }
3850 final long callingId = Binder.clearCallingIdentity();
3851 try {
3852 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003853 mKeyguardController.dismissKeyguard(token, callback, message);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003854 }
3855 } finally {
3856 Binder.restoreCallingIdentity(callingId);
3857 }
3858 }
3859
3860 @Override
3861 public void cancelTaskWindowTransition(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003862 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003863 "cancelTaskWindowTransition()");
3864 final long ident = Binder.clearCallingIdentity();
3865 try {
3866 synchronized (mGlobalLock) {
3867 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
3868 MATCH_TASK_IN_STACKS_ONLY);
3869 if (task == null) {
3870 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
3871 return;
3872 }
3873 task.cancelWindowTransition();
3874 }
3875 } finally {
3876 Binder.restoreCallingIdentity(ident);
3877 }
3878 }
3879
3880 @Override
3881 public ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003882 enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003883 final long ident = Binder.clearCallingIdentity();
3884 try {
3885 final TaskRecord task;
3886 synchronized (mGlobalLock) {
3887 task = mStackSupervisor.anyTaskForIdLocked(taskId,
3888 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
3889 if (task == null) {
3890 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
3891 return null;
3892 }
3893 }
3894 // Don't call this while holding the lock as this operation might hit the disk.
3895 return task.getSnapshot(reducedResolution);
3896 } finally {
3897 Binder.restoreCallingIdentity(ident);
3898 }
3899 }
3900
3901 @Override
3902 public void setDisablePreviewScreenshots(IBinder token, boolean disable) {
3903 synchronized (mGlobalLock) {
3904 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3905 if (r == null) {
3906 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
3907 + token);
3908 return;
3909 }
3910 final long origId = Binder.clearCallingIdentity();
3911 try {
3912 r.setDisablePreviewScreenshots(disable);
3913 } finally {
3914 Binder.restoreCallingIdentity(origId);
3915 }
3916 }
3917 }
3918
3919 /** Return the user id of the last resumed activity. */
3920 @Override
3921 public @UserIdInt
3922 int getLastResumedActivityUserId() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003923 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003924 Manifest.permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
3925 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07003926 if (mLastResumedActivity == null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003927 return getCurrentUserId();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003928 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07003929 return mLastResumedActivity.userId;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003930 }
3931 }
3932
3933 @Override
3934 public void updateLockTaskFeatures(int userId, int flags) {
3935 final int callingUid = Binder.getCallingUid();
3936 if (callingUid != 0 && callingUid != SYSTEM_UID) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003937 mAmInternal.enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003938 "updateLockTaskFeatures()");
3939 }
3940 synchronized (mGlobalLock) {
3941 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
3942 Integer.toHexString(flags));
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003943 getLockTaskController().updateLockTaskFeatures(userId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003944 }
3945 }
3946
3947 @Override
3948 public void setShowWhenLocked(IBinder token, boolean showWhenLocked) {
3949 synchronized (mGlobalLock) {
3950 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3951 if (r == null) {
3952 return;
3953 }
3954 final long origId = Binder.clearCallingIdentity();
3955 try {
3956 r.setShowWhenLocked(showWhenLocked);
3957 } finally {
3958 Binder.restoreCallingIdentity(origId);
3959 }
3960 }
3961 }
3962
3963 @Override
3964 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) {
3965 synchronized (mGlobalLock) {
3966 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3967 if (r == null) {
3968 return;
3969 }
3970 final long origId = Binder.clearCallingIdentity();
3971 try {
3972 r.setTurnScreenOn(turnScreenOn);
3973 } finally {
3974 Binder.restoreCallingIdentity(origId);
3975 }
3976 }
3977 }
3978
3979 @Override
3980 public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003981 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003982 "registerRemoteAnimations");
3983 definition.setCallingPid(Binder.getCallingPid());
3984 synchronized (mGlobalLock) {
3985 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3986 if (r == null) {
3987 return;
3988 }
3989 final long origId = Binder.clearCallingIdentity();
3990 try {
3991 r.registerRemoteAnimations(definition);
3992 } finally {
3993 Binder.restoreCallingIdentity(origId);
3994 }
3995 }
3996 }
3997
3998 @Override
3999 public void registerRemoteAnimationForNextActivityStart(String packageName,
4000 RemoteAnimationAdapter adapter) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004001 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004002 "registerRemoteAnimationForNextActivityStart");
4003 adapter.setCallingPid(Binder.getCallingPid());
4004 synchronized (mGlobalLock) {
4005 final long origId = Binder.clearCallingIdentity();
4006 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07004007 getActivityStartController().registerRemoteAnimationForNextActivityStart(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004008 packageName, adapter);
4009 } finally {
4010 Binder.restoreCallingIdentity(origId);
4011 }
4012 }
4013 }
4014
4015 /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
4016 @Override
4017 public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
4018 synchronized (mGlobalLock) {
4019 final long origId = Binder.clearCallingIdentity();
4020 try {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004021 mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004022 } finally {
4023 Binder.restoreCallingIdentity(origId);
4024 }
4025 }
4026 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004027
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004028 @Override
4029 public void setVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004030 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004031 synchronized (mGlobalLock) {
4032 synchronized (mAm.mPidsSelfLocked) {
4033 final int pid = Binder.getCallingPid();
4034 final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004035 mVrController.setVrThreadLocked(tid, pid, proc.getWindowProcessController());
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004036 }
4037 }
4038 }
4039
4040 @Override
4041 public void setPersistentVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004042 if (checkCallingPermission(Manifest.permission.RESTRICTED_VR_ACCESS)
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004043 != PERMISSION_GRANTED) {
4044 final String msg = "Permission Denial: setPersistentVrThread() from pid="
4045 + Binder.getCallingPid()
4046 + ", uid=" + Binder.getCallingUid()
4047 + " requires " + Manifest.permission.RESTRICTED_VR_ACCESS;
4048 Slog.w(TAG, msg);
4049 throw new SecurityException(msg);
4050 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004051 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004052 synchronized (mGlobalLock) {
4053 synchronized (mAm.mPidsSelfLocked) {
4054 final int pid = Binder.getCallingPid();
4055 final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
4056 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
4057 }
4058 }
4059 }
4060
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004061 @Override
4062 public void stopAppSwitches() {
4063 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
4064 synchronized (mGlobalLock) {
4065 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME;
4066 mDidAppSwitch = false;
4067 getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
4068 }
4069 }
4070
4071 @Override
4072 public void resumeAppSwitches() {
4073 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
4074 synchronized (mGlobalLock) {
4075 // Note that we don't execute any pending app switches... we will
4076 // let those wait until either the timeout, or the next start
4077 // activity request.
4078 mAppSwitchesAllowedTime = 0;
4079 }
4080 }
4081
4082 void onStartActivitySetDidAppSwitch() {
4083 if (mDidAppSwitch) {
4084 // This is the second allowed switch since we stopped switches, so now just generally
4085 // allow switches. Use case:
4086 // - user presses home (switches disabled, switch to home, mDidAppSwitch now true);
4087 // - user taps a home icon (coming from home so allowed, we hit here and now allow
4088 // anyone to switch again).
4089 mAppSwitchesAllowedTime = 0;
4090 } else {
4091 mDidAppSwitch = true;
4092 }
4093 }
4094
4095 /** @return whether the system should disable UI modes incompatible with VR mode. */
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004096 boolean shouldDisableNonVrUiLocked() {
4097 return mVrController.shouldDisableNonVrUiLocked();
4098 }
4099
4100 void applyUpdateVrModeLocked(ActivityRecord r) {
4101 // VR apps are expected to run in a main display. If an app is turning on VR for
4102 // itself, but lives in a dynamic stack, then make sure that it is moved to the main
4103 // fullscreen stack before enabling VR Mode.
4104 // TODO: The goal of this code is to keep the VR app on the main display. When the
4105 // stack implementation changes in the future, keep in mind that the use of the fullscreen
4106 // stack is a means to move the activity to the main display and a moveActivityToDisplay()
4107 // option would be a better choice here.
4108 if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
4109 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
4110 + " to main stack for VR");
4111 final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
4112 WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
4113 moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
4114 }
4115 mH.post(() -> {
4116 if (!mVrController.onVrModeChanged(r)) {
4117 return;
4118 }
4119 synchronized (mGlobalLock) {
4120 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
4121 mWindowManager.disableNonVrUi(disableNonVrUi);
4122 if (disableNonVrUi) {
4123 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
4124 // then remove the pinned stack.
4125 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
4126 }
4127 }
4128 });
4129 }
4130
Andrii Kulian5f750bc2018-07-17 08:57:23 -07004131 ActivityStack getTopDisplayFocusedStack() {
4132 return mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004133 }
4134
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004135 /** Pokes the task persister. */
4136 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
4137 mRecentTasks.notifyTaskPersisterLocked(task, flush);
4138 }
4139
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004140 void onTopProcChangedLocked(WindowProcessController proc) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004141 mVrController.onTopProcChangedLocked(proc);
4142 }
4143
4144 boolean isKeyguardLocked() {
4145 return mKeyguardController.isKeyguardLocked();
4146 }
4147
4148 boolean isNextTransitionForward() {
4149 int transit = mWindowManager.getPendingAppTransition();
4150 return transit == TRANSIT_ACTIVITY_OPEN
4151 || transit == TRANSIT_TASK_OPEN
4152 || transit == TRANSIT_TASK_TO_FRONT;
4153 }
4154
Wale Ogunwalef6733932018-06-27 05:14:34 -07004155 void dumpSleepStates(PrintWriter pw, boolean testPssMode) {
4156 synchronized (mGlobalLock) {
4157 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
4158 if (mRunningVoice != null) {
4159 pw.println(" mRunningVoice=" + mRunningVoice);
4160 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
4161 }
4162 pw.println(" mSleeping=" + mSleeping);
4163 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + testPssMode);
4164 pw.println(" mVrController=" + mVrController);
4165 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004166 }
4167
Wale Ogunwalef6733932018-06-27 05:14:34 -07004168 void writeSleepStateToProto(ProtoOutputStream proto) {
4169 for (ActivityTaskManagerInternal.SleepToken st : mStackSupervisor.mSleepTokens) {
4170 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS,
4171 st.toString());
4172 }
4173
4174 if (mRunningVoice != null) {
4175 final long vrToken = proto.start(
4176 ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
4177 proto.write(ActivityManagerServiceDumpProcessesProto.Voice.SESSION,
4178 mRunningVoice.toString());
4179 mVoiceWakeLock.writeToProto(
4180 proto, ActivityManagerServiceDumpProcessesProto.Voice.WAKELOCK);
4181 proto.end(vrToken);
4182 }
4183
4184 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
4185 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN,
4186 mShuttingDown);
4187 mVrController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004188 }
4189
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004190 int getCurrentUserId() {
4191 return mAmInternal.getCurrentUserId();
4192 }
4193
4194 private void enforceNotIsolatedCaller(String caller) {
4195 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4196 throw new SecurityException("Isolated process not allowed to call " + caller);
4197 }
4198 }
4199
Wale Ogunwalef6733932018-06-27 05:14:34 -07004200 public Configuration getConfiguration() {
4201 Configuration ci;
4202 synchronized(mGlobalLock) {
4203 ci = new Configuration(getGlobalConfiguration());
4204 ci.userSetLocale = false;
4205 }
4206 return ci;
4207 }
4208
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004209 /**
4210 * Current global configuration information. Contains general settings for the entire system,
4211 * also corresponds to the merged configuration of the default display.
4212 */
4213 Configuration getGlobalConfiguration() {
4214 return mStackSupervisor.getConfiguration();
4215 }
4216
4217 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4218 boolean initLocale) {
4219 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
4220 }
4221
4222 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4223 boolean initLocale, boolean deferResume) {
4224 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
4225 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
4226 UserHandle.USER_NULL, deferResume);
4227 }
4228
4229 void updatePersistentConfiguration(Configuration values, @UserIdInt int userId) {
4230 final long origId = Binder.clearCallingIdentity();
4231 try {
4232 synchronized (mGlobalLock) {
4233 updateConfigurationLocked(values, null, false, true, userId,
4234 false /* deferResume */);
4235 }
4236 } finally {
4237 Binder.restoreCallingIdentity(origId);
4238 }
4239 }
4240
4241 void updateUserConfiguration() {
4242 synchronized (mGlobalLock) {
4243 final Configuration configuration = new Configuration(getGlobalConfiguration());
4244 final int currentUserId = mAmInternal.getCurrentUserId();
4245 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
4246 currentUserId, Settings.System.canWrite(mContext));
4247 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
4248 false /* persistent */, currentUserId, false /* deferResume */);
4249 }
4250 }
4251
4252 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4253 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
4254 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
4255 deferResume, null /* result */);
4256 }
4257
4258 /**
4259 * Do either or both things: (1) change the current configuration, and (2)
4260 * make sure the given activity is running with the (now) current
4261 * configuration. Returns true if the activity has been left running, or
4262 * false if <var>starting</var> is being destroyed to match the new
4263 * configuration.
4264 *
4265 * @param userId is only used when persistent parameter is set to true to persist configuration
4266 * for that particular user
4267 */
4268 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4269 boolean initLocale, boolean persistent, int userId, boolean deferResume,
4270 ActivityTaskManagerService.UpdateConfigurationResult result) {
4271 int changes = 0;
4272 boolean kept = true;
4273
4274 if (mWindowManager != null) {
4275 mWindowManager.deferSurfaceLayout();
4276 }
4277 try {
4278 if (values != null) {
4279 changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
4280 deferResume);
4281 }
4282
4283 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4284 } finally {
4285 if (mWindowManager != null) {
4286 mWindowManager.continueSurfaceLayout();
4287 }
4288 }
4289
4290 if (result != null) {
4291 result.changes = changes;
4292 result.activityRelaunched = !kept;
4293 }
4294 return kept;
4295 }
4296
4297 /**
4298 * Returns true if this configuration change is interesting enough to send an
4299 * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
4300 */
4301 private static boolean isSplitConfigurationChange(int configDiff) {
4302 return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
4303 }
4304
4305 /** Update default (global) configuration and notify listeners about changes. */
4306 private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
4307 boolean persistent, int userId, boolean deferResume) {
4308 mTempConfig.setTo(getGlobalConfiguration());
4309 final int changes = mTempConfig.updateFrom(values);
4310 if (changes == 0) {
4311 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
4312 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
4313 // performDisplayOverrideConfigUpdate in order to send the new display configuration
4314 // (even if there are no actual changes) to unfreeze the window.
4315 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
4316 return 0;
4317 }
4318
4319 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
4320 "Updating global configuration to: " + values);
4321
4322 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
4323 StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
4324 values.colorMode,
4325 values.densityDpi,
4326 values.fontScale,
4327 values.hardKeyboardHidden,
4328 values.keyboard,
4329 values.keyboardHidden,
4330 values.mcc,
4331 values.mnc,
4332 values.navigation,
4333 values.navigationHidden,
4334 values.orientation,
4335 values.screenHeightDp,
4336 values.screenLayout,
4337 values.screenWidthDp,
4338 values.smallestScreenWidthDp,
4339 values.touchscreen,
4340 values.uiMode);
4341
4342
4343 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
4344 final LocaleList locales = values.getLocales();
4345 int bestLocaleIndex = 0;
4346 if (locales.size() > 1) {
4347 if (mSupportedSystemLocales == null) {
4348 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
4349 }
4350 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
4351 }
4352 SystemProperties.set("persist.sys.locale",
4353 locales.get(bestLocaleIndex).toLanguageTag());
4354 LocaleList.setDefault(locales, bestLocaleIndex);
4355 mAm.mHandler.sendMessage(mAm.mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
4356 locales.get(bestLocaleIndex)));
4357 }
4358
4359 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
4360 mTempConfig.seq = mConfigurationSeq;
4361
4362 // Update stored global config and notify everyone about the change.
4363 mStackSupervisor.onConfigurationChanged(mTempConfig);
4364
4365 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
4366 // TODO(multi-display): Update UsageEvents#Event to include displayId.
4367 mAm.mUsageStatsService.reportConfigurationChange(
4368 mTempConfig, mAmInternal.getCurrentUserId());
4369
4370 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
Wale Ogunwalef6733932018-06-27 05:14:34 -07004371 updateShouldShowDialogsLocked(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004372
4373 AttributeCache ac = AttributeCache.instance();
4374 if (ac != null) {
4375 ac.updateConfiguration(mTempConfig);
4376 }
4377
4378 // Make sure all resources in our process are updated right now, so that anyone who is going
4379 // to retrieve resource values after we return will be sure to get the new ones. This is
4380 // especially important during boot, where the first config change needs to guarantee all
4381 // resources have that config before following boot code is executed.
4382 mAm.mSystemThread.applyConfigurationToResources(mTempConfig);
4383
4384 // We need another copy of global config because we're scheduling some calls instead of
4385 // running them in place. We need to be sure that object we send will be handled unchanged.
4386 final Configuration configCopy = new Configuration(mTempConfig);
4387 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
4388 Message msg = mAm.mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
4389 msg.obj = configCopy;
4390 msg.arg1 = userId;
4391 mAm.mHandler.sendMessage(msg);
4392 }
4393
4394 for (int i = mAm.mLruProcesses.size() - 1; i >= 0; i--) {
4395 ProcessRecord app = mAm.mLruProcesses.get(i);
4396 try {
4397 if (app.thread != null) {
4398 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
4399 + app.processName + " new config " + configCopy);
4400 getLifecycleManager().scheduleTransaction(app.thread,
4401 ConfigurationChangeItem.obtain(configCopy));
4402 }
4403 } catch (Exception e) {
4404 Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
4405 }
4406 }
4407
4408 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
4409 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
4410 | Intent.FLAG_RECEIVER_FOREGROUND
4411 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4412 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4413 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4414 UserHandle.USER_ALL);
4415 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
4416 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
4417 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
4418 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
4419 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4420 if (initLocale || !mAm.mProcessesReady) {
4421 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
4422 }
4423 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4424 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4425 UserHandle.USER_ALL);
4426 }
4427
4428 // Send a broadcast to PackageInstallers if the configuration change is interesting
4429 // for the purposes of installing additional splits.
4430 if (!initLocale && isSplitConfigurationChange(changes)) {
4431 intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
4432 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
4433 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
4434
4435 // Typically only app stores will have this permission.
4436 String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES };
4437 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions,
4438 OP_NONE, null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
4439 }
4440
4441 // Override configuration of the default display duplicates global config, so we need to
4442 // update it also. This will also notify WindowManager about changes.
4443 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
4444 DEFAULT_DISPLAY);
4445
4446 return changes;
4447 }
4448
4449 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
4450 boolean deferResume, int displayId) {
4451 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
4452 displayId, null /* result */);
4453 }
4454
4455 /**
4456 * Updates override configuration specific for the selected display. If no config is provided,
4457 * new one will be computed in WM based on current display info.
4458 */
4459 boolean updateDisplayOverrideConfigurationLocked(Configuration values,
4460 ActivityRecord starting, boolean deferResume, int displayId,
4461 ActivityTaskManagerService.UpdateConfigurationResult result) {
4462 int changes = 0;
4463 boolean kept = true;
4464
4465 if (mWindowManager != null) {
4466 mWindowManager.deferSurfaceLayout();
4467 }
4468 try {
4469 if (values != null) {
4470 if (displayId == DEFAULT_DISPLAY) {
4471 // Override configuration of the default display duplicates global config, so
4472 // we're calling global config update instead for default display. It will also
4473 // apply the correct override config.
4474 changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
4475 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
4476 } else {
4477 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
4478 }
4479 }
4480
4481 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4482 } finally {
4483 if (mWindowManager != null) {
4484 mWindowManager.continueSurfaceLayout();
4485 }
4486 }
4487
4488 if (result != null) {
4489 result.changes = changes;
4490 result.activityRelaunched = !kept;
4491 }
4492 return kept;
4493 }
4494
4495 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
4496 int displayId) {
4497 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
4498 final int changes = mTempConfig.updateFrom(values);
4499 if (changes != 0) {
4500 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
4501 + mTempConfig + " for displayId=" + displayId);
4502 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
4503
4504 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
4505 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004506 mAppWarnings.onDensityChanged();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004507
4508 mAm.killAllBackgroundProcessesExcept(N,
4509 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
4510 }
4511 }
4512
4513 // Update the configuration with WM first and check if any of the stacks need to be resized
4514 // due to the configuration change. If so, resize the stacks now and do any relaunches if
4515 // necessary. This way we don't need to relaunch again afterwards in
4516 // ensureActivityConfiguration().
4517 if (mWindowManager != null) {
4518 final int[] resizedStacks =
4519 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
4520 if (resizedStacks != null) {
4521 for (int stackId : resizedStacks) {
4522 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
4523 }
4524 }
4525 }
4526
4527 return changes;
4528 }
4529
Wale Ogunwalef6733932018-06-27 05:14:34 -07004530 private void updateEventDispatchingLocked(boolean booted) {
4531 mWindowManager.setEventDispatching(booted && !mShuttingDown);
4532 }
4533
4534 void enableScreenAfterBoot(boolean booted) {
4535 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4536 SystemClock.uptimeMillis());
4537 mWindowManager.enableScreenAfterBoot();
4538
4539 synchronized (mGlobalLock) {
4540 updateEventDispatchingLocked(booted);
4541 }
4542 }
4543
4544 boolean canShowErrorDialogs() {
4545 return mShowDialogs && !mSleeping && !mShuttingDown
4546 && !mKeyguardController.isKeyguardOrAodShowing(DEFAULT_DISPLAY)
4547 && !hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
Wale Ogunwale86b74462018-07-02 08:42:43 -07004548 mAmInternal.getCurrentUserId())
Wale Ogunwalef6733932018-06-27 05:14:34 -07004549 && !(UserManager.isDeviceInDemoMode(mContext)
Wale Ogunwale86b74462018-07-02 08:42:43 -07004550 && mAmInternal.getCurrentUser().isDemo());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004551 }
4552
Wale Ogunwale906f9c62018-07-23 11:23:44 -07004553 static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
4554 if (r == null || !r.hasProcess()) {
4555 return KEY_DISPATCHING_TIMEOUT_MS;
4556 }
4557 return getInputDispatchingTimeoutLocked(r.app);
4558 }
4559
4560 private static long getInputDispatchingTimeoutLocked(WindowProcessController r) {
4561 if (r != null && (r.isInstrumenting() || r.isUsingWrapper())) {
4562 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS;
4563 }
4564 return KEY_DISPATCHING_TIMEOUT_MS;
4565 }
4566
4567 long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
4568 if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
4569 throw new SecurityException("Requires permission " + FILTER_EVENTS);
4570 }
4571 WindowProcessController proc;
4572 long timeout;
4573 synchronized (mGlobalLock) {
4574 proc = mPidMap.get(pid);
4575 timeout = getInputDispatchingTimeoutLocked(proc);
4576 }
4577
4578 if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
4579 return -1;
4580 }
4581
4582 return timeout;
4583 }
4584
4585 /**
4586 * Handle input dispatching timeouts.
4587 * Returns whether input dispatching should be aborted or not.
4588 */
4589 boolean inputDispatchingTimedOut(final WindowProcessController proc,
4590 final ActivityRecord activity, final ActivityRecord parent,
4591 final boolean aboveSystem, String reason) {
4592 if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
4593 throw new SecurityException("Requires permission " + FILTER_EVENTS);
4594 }
4595
4596 final String annotation;
4597 if (reason == null) {
4598 annotation = "Input dispatching timed out";
4599 } else {
4600 annotation = "Input dispatching timed out (" + reason + ")";
4601 }
4602
4603 if (proc != null) {
4604 synchronized (mGlobalLock) {
4605 if (proc.isDebugging()) {
4606 return false;
4607 }
4608
4609 if (proc.isInstrumenting()) {
4610 Bundle info = new Bundle();
4611 info.putString("shortMsg", "keyDispatchingTimedOut");
4612 info.putString("longMsg", annotation);
4613 mAm.finishInstrumentationLocked(
4614 (ProcessRecord) proc.mOwner, Activity.RESULT_CANCELED, info);
4615 return true;
4616 }
4617 }
4618 mH.post(() -> {
4619 mAm.mAppErrors.appNotResponding(
4620 (ProcessRecord) proc.mOwner, activity, parent, aboveSystem, annotation);
4621 });
4622 }
4623
4624 return true;
4625 }
4626
Wale Ogunwalef6733932018-06-27 05:14:34 -07004627 /**
4628 * Decide based on the configuration whether we should show the ANR,
4629 * crash, etc dialogs. The idea is that if there is no affordance to
4630 * press the on-screen buttons, or the user experience would be more
4631 * greatly impacted than the crash itself, we shouldn't show the dialog.
4632 *
4633 * A thought: SystemUI might also want to get told about this, the Power
4634 * dialog / global actions also might want different behaviors.
4635 */
4636 private void updateShouldShowDialogsLocked(Configuration config) {
4637 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
4638 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
4639 && config.navigation == Configuration.NAVIGATION_NONAV);
4640 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
4641 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
4642 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
4643 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
4644 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
4645 final boolean hideDialogsSet = Settings.Global.getInt(mContext.getContentResolver(),
4646 HIDE_ERROR_DIALOGS, 0) != 0;
4647 mShowDialogs = inputMethodExists && uiModeSupportsDialogs && !hideDialogsSet;
4648 }
4649
4650 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
4651 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
4652 FONT_SCALE, 1.0f, userId);
4653
4654 synchronized (this) {
4655 if (getGlobalConfiguration().fontScale == scaleFactor) {
4656 return;
4657 }
4658
4659 final Configuration configuration
4660 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
4661 configuration.fontScale = scaleFactor;
4662 updatePersistentConfiguration(configuration, userId);
4663 }
4664 }
4665
4666 // Actually is sleeping or shutting down or whatever else in the future
4667 // is an inactive state.
4668 boolean isSleepingOrShuttingDownLocked() {
4669 return isSleepingLocked() || mShuttingDown;
4670 }
4671
4672 boolean isSleepingLocked() {
4673 return mSleeping;
4674 }
4675
4676 /**
4677 * Update AMS states when an activity is resumed. This should only be called by
4678 * {@link ActivityStack#onActivityStateChanged(
4679 * ActivityRecord, ActivityStack.ActivityState, String)} when an activity is resumed.
4680 */
4681 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
4682 final TaskRecord task = r.getTask();
4683 if (task.isActivityTypeStandard()) {
4684 if (mCurAppTimeTracker != r.appTimeTracker) {
4685 // We are switching app tracking. Complete the current one.
4686 if (mCurAppTimeTracker != null) {
4687 mCurAppTimeTracker.stop();
4688 mH.obtainMessage(
4689 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
4690 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
4691 mCurAppTimeTracker = null;
4692 }
4693 if (r.appTimeTracker != null) {
4694 mCurAppTimeTracker = r.appTimeTracker;
4695 startTimeTrackingFocusedActivityLocked();
4696 }
4697 } else {
4698 startTimeTrackingFocusedActivityLocked();
4699 }
4700 } else {
4701 r.appTimeTracker = null;
4702 }
4703 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
4704 // TODO: Probably not, because we don't want to resume voice on switching
4705 // back to this activity
4706 if (task.voiceInteractor != null) {
4707 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
4708 } else {
4709 finishRunningVoiceLocked();
4710
4711 if (mLastResumedActivity != null) {
4712 final IVoiceInteractionSession session;
4713
4714 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
4715 if (lastResumedActivityTask != null
4716 && lastResumedActivityTask.voiceSession != null) {
4717 session = lastResumedActivityTask.voiceSession;
4718 } else {
4719 session = mLastResumedActivity.voiceSession;
4720 }
4721
4722 if (session != null) {
4723 // We had been in a voice interaction session, but now focused has
4724 // move to something different. Just finish the session, we can't
4725 // return to it and retain the proper state and synchronization with
4726 // the voice interaction service.
4727 finishVoiceTask(session);
4728 }
4729 }
4730 }
4731
4732 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
4733 mAmInternal.sendForegroundProfileChanged(r.userId);
4734 }
4735 updateResumedAppTrace(r);
4736 mLastResumedActivity = r;
4737
4738 mWindowManager.setFocusedApp(r.appToken, true);
4739
4740 applyUpdateLockStateLocked(r);
4741 applyUpdateVrModeLocked(r);
4742
4743 EventLogTags.writeAmSetResumedActivity(
4744 r == null ? -1 : r.userId,
4745 r == null ? "NULL" : r.shortComponentName,
4746 reason);
4747 }
4748
4749 ActivityTaskManagerInternal.SleepToken acquireSleepToken(String tag, int displayId) {
4750 synchronized (mGlobalLock) {
4751 final ActivityTaskManagerInternal.SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
4752 updateSleepIfNeededLocked();
4753 return token;
4754 }
4755 }
4756
4757 void updateSleepIfNeededLocked() {
4758 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
4759 final boolean wasSleeping = mSleeping;
4760 boolean updateOomAdj = false;
4761
4762 if (!shouldSleep) {
4763 // If wasSleeping is true, we need to wake up activity manager state from when
4764 // we started sleeping. In either case, we need to apply the sleep tokens, which
4765 // will wake up stacks or put them to sleep as appropriate.
4766 if (wasSleeping) {
4767 mSleeping = false;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07004768 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
4769 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__AWAKE);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004770 startTimeTrackingFocusedActivityLocked();
4771 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
4772 mStackSupervisor.comeOutOfSleepIfNeededLocked();
4773 }
4774 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
4775 if (wasSleeping) {
4776 updateOomAdj = true;
4777 }
4778 } else if (!mSleeping && shouldSleep) {
4779 mSleeping = true;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07004780 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
4781 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__ASLEEP);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004782 if (mCurAppTimeTracker != null) {
4783 mCurAppTimeTracker.stop();
4784 }
4785 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
4786 mStackSupervisor.goingToSleepLocked();
4787 updateResumedAppTrace(null /* resumed */);
4788 updateOomAdj = true;
4789 }
4790 if (updateOomAdj) {
4791 mH.post(mAmInternal::updateOomAdj);
4792 }
4793 }
4794
4795 void updateOomAdj() {
4796 mH.post(mAmInternal::updateOomAdj);
4797 }
4798
Andrii Kulian52d255c2018-07-13 11:32:19 -07004799 // TODO(b/111541062): Update app time tracking to make it aware of multiple resumed activities
Wale Ogunwalef6733932018-06-27 05:14:34 -07004800 private void startTimeTrackingFocusedActivityLocked() {
Andrii Kulian52d255c2018-07-13 11:32:19 -07004801 final ActivityRecord resumedActivity = mStackSupervisor.getTopResumedActivity();
Wale Ogunwalef6733932018-06-27 05:14:34 -07004802 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
4803 mCurAppTimeTracker.start(resumedActivity.packageName);
4804 }
4805 }
4806
4807 private void updateResumedAppTrace(@Nullable ActivityRecord resumed) {
4808 if (mTracedResumedActivity != null) {
4809 Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER,
4810 constructResumedTraceName(mTracedResumedActivity.packageName), 0);
4811 }
4812 if (resumed != null) {
4813 Trace.asyncTraceBegin(TRACE_TAG_ACTIVITY_MANAGER,
4814 constructResumedTraceName(resumed.packageName), 0);
4815 }
4816 mTracedResumedActivity = resumed;
4817 }
4818
4819 private String constructResumedTraceName(String packageName) {
4820 return "focused app: " + packageName;
4821 }
4822
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004823 /** Helper method that requests bounds from WM and applies them to stack. */
4824 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
4825 final Rect newStackBounds = new Rect();
4826 final ActivityStack stack = mStackSupervisor.getStack(stackId);
4827
4828 // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
4829 if (stack == null) {
4830 final StringWriter writer = new StringWriter();
4831 final PrintWriter printWriter = new PrintWriter(writer);
4832 mStackSupervisor.dumpDisplays(printWriter);
4833 printWriter.flush();
4834
4835 Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
4836 }
4837
4838 stack.getBoundsForNewConfiguration(newStackBounds);
4839 mStackSupervisor.resizeStackLocked(
4840 stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
4841 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
4842 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
4843 }
4844
4845 /** Applies latest configuration and/or visibility updates if needed. */
4846 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
4847 boolean kept = true;
Andrii Kulian5f750bc2018-07-17 08:57:23 -07004848 final ActivityStack mainStack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004849 // mainStack is null during startup.
4850 if (mainStack != null) {
4851 if (changes != 0 && starting == null) {
4852 // If the configuration changed, and the caller is not already
4853 // in the process of starting an activity, then find the top
4854 // activity to check if its configuration needs to change.
4855 starting = mainStack.topRunningActivityLocked();
4856 }
4857
4858 if (starting != null) {
4859 kept = starting.ensureActivityConfiguration(changes,
4860 false /* preserveWindow */);
4861 // And we need to make sure at this point that all other activities
4862 // are made visible with the correct configuration.
4863 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
4864 !PRESERVE_WINDOWS);
4865 }
4866 }
4867
4868 return kept;
4869 }
4870
Wale Ogunwale906f9c62018-07-23 11:23:44 -07004871 void scheduleAppGcsLocked() {
4872 mH.post(() -> mAmInternal.scheduleAppGcs());
4873 }
4874
4875 /**
4876 * Returns the PackageManager. Used by classes hosted by {@link ActivityTaskManagerService}. The
4877 * PackageManager could be unavailable at construction time and therefore needs to be accessed
4878 * on demand.
4879 */
4880 IPackageManager getPackageManager() {
4881 return AppGlobals.getPackageManager();
4882 }
4883
4884 PackageManagerInternal getPackageManagerInternalLocked() {
4885 if (mPmInternal == null) {
4886 mPmInternal = LocalServices.getService(PackageManagerInternal.class);
4887 }
4888 return mPmInternal;
4889 }
4890
Wale Ogunwale008163e2018-07-23 23:11:08 -07004891 AppWarnings getAppWarningsLocked() {
4892 return mAppWarnings;
4893 }
4894
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004895 void logAppTooSlow(WindowProcessController app, long startTime, String msg) {
4896 if (true || Build.IS_USER) {
4897 return;
4898 }
4899
4900 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4901 StrictMode.allowThreadDiskWrites();
4902 try {
4903 File tracesDir = new File("/data/anr");
4904 File tracesFile = null;
4905 try {
4906 tracesFile = File.createTempFile("app_slow", null, tracesDir);
4907
4908 StringBuilder sb = new StringBuilder();
4909 Time tobj = new Time();
4910 tobj.set(System.currentTimeMillis());
4911 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4912 sb.append(": ");
4913 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4914 sb.append(" since ");
4915 sb.append(msg);
4916 FileOutputStream fos = new FileOutputStream(tracesFile);
4917 fos.write(sb.toString().getBytes());
4918 if (app == null) {
4919 fos.write("\n*** No application process!".getBytes());
4920 }
4921 fos.close();
4922 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4923 } catch (IOException e) {
4924 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesFile, e);
4925 return;
4926 }
4927
4928 if (app != null && app.getPid() > 0) {
4929 ArrayList<Integer> firstPids = new ArrayList<Integer>();
4930 firstPids.add(app.getPid());
4931 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, null, null);
4932 }
4933
4934 File lastTracesFile = null;
4935 File curTracesFile = null;
4936 for (int i=9; i>=0; i--) {
4937 String name = String.format(Locale.US, "slow%02d.txt", i);
4938 curTracesFile = new File(tracesDir, name);
4939 if (curTracesFile.exists()) {
4940 if (lastTracesFile != null) {
4941 curTracesFile.renameTo(lastTracesFile);
4942 } else {
4943 curTracesFile.delete();
4944 }
4945 }
4946 lastTracesFile = curTracesFile;
4947 }
4948 tracesFile.renameTo(curTracesFile);
4949 } finally {
4950 StrictMode.setThreadPolicy(oldPolicy);
4951 }
4952 }
4953
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004954 final class H extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07004955 static final int REPORT_TIME_TRACKER_MSG = 1;
4956
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004957 public H(Looper looper) {
4958 super(looper, null, true);
4959 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004960
4961 @Override
4962 public void handleMessage(Message msg) {
4963 switch (msg.what) {
4964 case REPORT_TIME_TRACKER_MSG: {
4965 AppTimeTracker tracker = (AppTimeTracker) msg.obj;
4966 tracker.deliverResult(mContext);
4967 } break;
4968 }
4969 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004970 }
4971
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004972 final class UiHandler extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07004973 static final int DISMISS_DIALOG_UI_MSG = 1;
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004974
4975 public UiHandler() {
4976 super(com.android.server.UiThread.get().getLooper(), null, true);
4977 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004978
4979 @Override
4980 public void handleMessage(Message msg) {
4981 switch (msg.what) {
4982 case DISMISS_DIALOG_UI_MSG: {
4983 final Dialog d = (Dialog) msg.obj;
4984 d.dismiss();
4985 break;
4986 }
4987 }
4988 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004989 }
4990
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004991 final class LocalService extends ActivityTaskManagerInternal {
4992 @Override
4993 public SleepToken acquireSleepToken(String tag, int displayId) {
4994 Preconditions.checkNotNull(tag);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004995 return ActivityTaskManagerService.this.acquireSleepToken(tag, displayId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004996 }
4997
4998 @Override
4999 public ComponentName getHomeActivityForUser(int userId) {
5000 synchronized (mGlobalLock) {
5001 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
5002 return homeActivity == null ? null : homeActivity.realActivity;
5003 }
5004 }
5005
5006 @Override
5007 public void onLocalVoiceInteractionStarted(IBinder activity,
5008 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
5009 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005010 onLocalVoiceInteractionStartedLocked(activity, voiceSession, voiceInteractor);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005011 }
5012 }
5013
5014 @Override
5015 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
5016 synchronized (mGlobalLock) {
5017 mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
5018 reasons, timestamp);
5019 }
5020 }
5021
5022 @Override
5023 public void notifyAppTransitionFinished() {
5024 synchronized (mGlobalLock) {
5025 mStackSupervisor.notifyAppTransitionDone();
5026 }
5027 }
5028
5029 @Override
5030 public void notifyAppTransitionCancelled() {
5031 synchronized (mGlobalLock) {
5032 mStackSupervisor.notifyAppTransitionDone();
5033 }
5034 }
5035
5036 @Override
5037 public List<IBinder> getTopVisibleActivities() {
5038 synchronized (mGlobalLock) {
5039 return mStackSupervisor.getTopVisibleActivities();
5040 }
5041 }
5042
5043 @Override
5044 public void notifyDockedStackMinimizedChanged(boolean minimized) {
5045 synchronized (mGlobalLock) {
5046 mStackSupervisor.setDockedStackMinimized(minimized);
5047 }
5048 }
5049
5050 @Override
5051 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
5052 Bundle bOptions) {
5053 Preconditions.checkNotNull(intents, "intents");
5054 final String[] resolvedTypes = new String[intents.length];
5055
5056 // UID of the package on user userId.
5057 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
5058 // packageUid may not be initialized.
5059 int packageUid = 0;
5060 final long ident = Binder.clearCallingIdentity();
5061
5062 try {
5063 for (int i = 0; i < intents.length; i++) {
5064 resolvedTypes[i] =
5065 intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
5066 }
5067
5068 packageUid = AppGlobals.getPackageManager().getPackageUid(
5069 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
5070 } catch (RemoteException e) {
5071 // Shouldn't happen.
5072 } finally {
5073 Binder.restoreCallingIdentity(ident);
5074 }
5075
5076 synchronized (mGlobalLock) {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07005077 return getActivityStartController().startActivitiesInPackage(
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005078 packageUid, packageName,
5079 intents, resolvedTypes, null /* resultTo */,
5080 SafeActivityOptions.fromBundle(bOptions), userId,
5081 false /* validateIncomingUser */);
5082 }
5083 }
5084
5085 @Override
5086 public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
5087 Intent intent, Bundle options, int userId) {
5088 return ActivityTaskManagerService.this.startActivityAsUser(
5089 caller, callerPacakge, intent,
5090 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
5091 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
5092 false /*validateIncomingUser*/);
5093 }
5094
5095 @Override
5096 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
5097 synchronized (mGlobalLock) {
5098
5099 // We might change the visibilities here, so prepare an empty app transition which
5100 // might be overridden later if we actually change visibilities.
5101 final boolean wasTransitionSet =
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005102 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005103 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005104 mWindowManager.prepareAppTransition(TRANSIT_NONE,
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005105 false /* alwaysKeepCurrent */);
5106 }
5107 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5108
5109 // If there was a transition set already we don't want to interfere with it as we
5110 // might be starting it too early.
5111 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005112 mWindowManager.executeAppTransition();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005113 }
5114 }
5115 if (callback != null) {
5116 callback.run();
5117 }
5118 }
5119
5120 @Override
5121 public void notifyKeyguardTrustedChanged() {
5122 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005123 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005124 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5125 }
5126 }
5127 }
5128
5129 /**
5130 * Called after virtual display Id is updated by
5131 * {@link com.android.server.vr.Vr2dDisplay} with a specific
5132 * {@param vrVr2dDisplayId}.
5133 */
5134 @Override
5135 public void setVr2dDisplayId(int vr2dDisplayId) {
5136 if (DEBUG_STACK) Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
5137 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005138 mVr2dDisplayId = vr2dDisplayId;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005139 }
5140 }
5141
5142 @Override
5143 public void setFocusedActivity(IBinder token) {
5144 synchronized (mGlobalLock) {
5145 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
5146 if (r == null) {
5147 throw new IllegalArgumentException(
5148 "setFocusedActivity: No activity record matching token=" + token);
5149 }
5150 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
5151 r, "setFocusedActivity")) {
5152 mStackSupervisor.resumeFocusedStackTopActivityLocked();
5153 }
5154 }
5155 }
5156
5157 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005158 public void registerScreenObserver(ScreenObserver observer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005159 mScreenObservers.add(observer);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005160 }
5161
5162 @Override
5163 public boolean isCallerRecents(int callingUid) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005164 return getRecentTasks().isCallerRecents(callingUid);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005165 }
5166
5167 @Override
5168 public boolean isRecentsComponentHomeActivity(int userId) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005169 return getRecentTasks().isRecentsComponentHomeActivity(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005170 }
5171
5172 @Override
5173 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
5174 ActivityTaskManagerService.this.cancelRecentsAnimation(restoreHomeStackPosition);
5175 }
5176
5177 @Override
5178 public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005179 ActivityTaskManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005180 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005181
5182 @Override
5183 public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
5184 synchronized (mGlobalLock) {
5185 mActiveVoiceInteractionServiceComponent = component;
5186 }
5187 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005188
5189 @Override
5190 public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
5191 if (!mAmInternal.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
5192 return;
5193 }
5194 synchronized (mGlobalLock) {
5195 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
5196 if (types == null) {
5197 if (uid < 0) {
5198 return;
5199 }
5200 types = new ArrayMap<>();
5201 mAllowAppSwitchUids.put(userId, types);
5202 }
5203 if (uid < 0) {
5204 types.remove(type);
5205 } else {
5206 types.put(type, uid);
5207 }
5208 }
5209 }
5210
5211 @Override
5212 public void onUserStopped(int userId) {
5213 synchronized (mGlobalLock) {
5214 getRecentTasks().unloadUserDataFromMemoryLocked(userId);
5215 mAllowAppSwitchUids.remove(userId);
5216 }
5217 }
5218
5219 @Override
5220 public boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
5221 synchronized (mGlobalLock) {
5222 return ActivityTaskManagerService.this.isGetTasksAllowed(
5223 caller, callingPid, callingUid);
5224 }
5225 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005226
5227 @Override
5228 public void onProcessAdded(WindowProcessController proc) {
5229 synchronized (mGlobalLock) {
5230 mProcessNames.put(proc.mName, proc.mUid, proc);
5231 }
5232 }
5233
5234 @Override
5235 public void onProcessRemoved(String name, int uid) {
5236 synchronized (mGlobalLock) {
5237 mProcessNames.remove(name, uid);
5238 }
5239 }
5240
5241 @Override
5242 public void onCleanUpApplicationRecord(WindowProcessController proc) {
5243 synchronized (mGlobalLock) {
5244 if (proc == mHomeProcess) {
5245 mHomeProcess = null;
5246 }
5247 if (proc == mPreviousProcess) {
5248 mPreviousProcess = null;
5249 }
5250 }
5251 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005252
5253 @Override
5254 public int getTopProcessState() {
5255 synchronized (mGlobalLock) {
5256 return mTopProcessState;
5257 }
5258 }
5259
5260 @Override
5261 public boolean isSleeping() {
5262 synchronized (mGlobalLock) {
5263 return isSleepingLocked();
5264 }
5265 }
5266
5267 @Override
5268 public boolean isShuttingDown() {
5269 synchronized (mGlobalLock) {
5270 return mShuttingDown;
5271 }
5272 }
5273
5274 @Override
5275 public boolean shuttingDown(boolean booted, int timeout) {
5276 synchronized (mGlobalLock) {
5277 mShuttingDown = true;
5278 mStackSupervisor.prepareForShutdownLocked();
5279 updateEventDispatchingLocked(booted);
5280 return mStackSupervisor.shutdownLocked(timeout);
5281 }
5282 }
5283
5284 @Override
5285 public void enableScreenAfterBoot(boolean booted) {
5286 synchronized (mGlobalLock) {
5287 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5288 SystemClock.uptimeMillis());
5289 mWindowManager.enableScreenAfterBoot();
5290 updateEventDispatchingLocked(booted);
5291 }
5292 }
5293
5294 @Override
5295 public boolean showStrictModeViolationDialog() {
5296 synchronized (mGlobalLock) {
5297 return mShowDialogs && !mSleeping && !mShuttingDown;
5298 }
5299 }
5300
5301 @Override
5302 public void showSystemReadyErrorDialogsIfNeeded() {
5303 synchronized (mGlobalLock) {
5304 try {
5305 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
5306 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
5307 + " data partition or your device will be unstable.");
5308 mUiHandler.post(() -> {
5309 if (mShowDialogs) {
5310 AlertDialog d = new BaseErrorDialog(mUiContext);
5311 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5312 d.setCancelable(false);
5313 d.setTitle(mUiContext.getText(R.string.android_system_label));
5314 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
5315 d.setButton(DialogInterface.BUTTON_POSITIVE,
5316 mUiContext.getText(R.string.ok),
5317 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5318 d.show();
5319 }
5320 });
5321 }
5322 } catch (RemoteException e) {
5323 }
5324
5325 if (!Build.isBuildConsistent()) {
5326 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
5327 mUiHandler.post(() -> {
5328 if (mShowDialogs) {
5329 AlertDialog d = new BaseErrorDialog(mUiContext);
5330 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5331 d.setCancelable(false);
5332 d.setTitle(mUiContext.getText(R.string.android_system_label));
5333 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
5334 d.setButton(DialogInterface.BUTTON_POSITIVE,
5335 mUiContext.getText(R.string.ok),
5336 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5337 d.show();
5338 }
5339 });
5340 }
5341 }
5342 }
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005343
5344 @Override
5345 public long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason) {
5346 synchronized (mGlobalLock) {
5347 return ActivityTaskManagerService.this.inputDispatchingTimedOut(
5348 pid, aboveSystem, reason);
5349 }
5350 }
5351
5352 @Override
5353 public void onProcessMapped(int pid, WindowProcessController proc) {
5354 synchronized (mGlobalLock) {
5355 mPidMap.put(pid, proc);
5356 }
5357 }
5358
5359 @Override
5360 public void onProcessUnMapped(int pid) {
5361 synchronized (mGlobalLock) {
5362 mPidMap.remove(pid);
5363 }
5364 }
Wale Ogunwale008163e2018-07-23 23:11:08 -07005365
5366 @Override
5367 public void onPackageDataCleared(String name) {
5368 synchronized (mGlobalLock) {
5369 mAppWarnings.onPackageDataCleared(name);
5370 }
5371 }
5372
5373 @Override
5374 public void onPackageUninstalled(String name) {
5375 synchronized (mGlobalLock) {
5376 mAppWarnings.onPackageUninstalled(name);
5377 }
5378 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005379 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07005380}