blob: 8ab4a37a32254e5371f43791e8467a15876368b3 [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")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08001627 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001628 }
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")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08001648 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001649 }
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
Winson Chunge6439102018-07-30 15:48:01 -07001671 public void removeAllVisibleRecentTasks() {
1672 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeAllVisibleRecentTasks()");
1673 synchronized (mGlobalLock) {
1674 final long ident = Binder.clearCallingIdentity();
1675 try {
1676 getRecentTasks().removeAllVisibleTasks();
1677 } finally {
1678 Binder.restoreCallingIdentity(ident);
1679 }
1680 }
1681 }
1682
1683 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001684 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
1685 synchronized (mGlobalLock) {
1686 final ActivityRecord srec = ActivityRecord.forTokenLocked(token);
1687 if (srec != null) {
1688 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
1689 }
1690 }
1691 return false;
1692 }
1693
1694 @Override
1695 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
1696 Intent resultData) {
1697
1698 synchronized (mGlobalLock) {
1699 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
1700 if (r != null) {
1701 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
1702 }
1703 return false;
1704 }
1705 }
1706
1707 /**
1708 * Attempts to move a task backwards in z-order (the order of activities within the task is
1709 * unchanged).
1710 *
1711 * There are several possible results of this call:
1712 * - if the task is locked, then we will show the lock toast
1713 * - if there is a task behind the provided task, then that task is made visible and resumed as
1714 * this task is moved to the back
1715 * - otherwise, if there are no other tasks in the stack:
1716 * - if this task is in the pinned stack, then we remove the stack completely, which will
1717 * have the effect of moving the task to the top or bottom of the fullscreen stack
1718 * (depending on whether it is visible)
1719 * - otherwise, we simply return home and hide this task
1720 *
1721 * @param token A reference to the activity we wish to move
1722 * @param nonRoot If false then this only works if the activity is the root
1723 * of a task; if true it will work for any activity in a task.
1724 * @return Returns true if the move completed, false if not.
1725 */
1726 @Override
1727 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001728 enforceNotIsolatedCaller("moveActivityTaskToBack");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001729 synchronized (mGlobalLock) {
1730 final long origId = Binder.clearCallingIdentity();
1731 try {
1732 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
1733 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1734 if (task != null) {
1735 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
1736 }
1737 } finally {
1738 Binder.restoreCallingIdentity(origId);
1739 }
1740 }
1741 return false;
1742 }
1743
1744 @Override
1745 public Rect getTaskBounds(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001746 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001747 long ident = Binder.clearCallingIdentity();
1748 Rect rect = new Rect();
1749 try {
1750 synchronized (mGlobalLock) {
1751 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
1752 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1753 if (task == null) {
1754 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
1755 return rect;
1756 }
1757 if (task.getStack() != null) {
1758 // Return the bounds from window manager since it will be adjusted for various
1759 // things like the presense of a docked stack for tasks that aren't resizeable.
1760 task.getWindowContainerBounds(rect);
1761 } else {
1762 // Task isn't in window manager yet since it isn't associated with a stack.
1763 // Return the persist value from activity manager
1764 if (!task.matchParentBounds()) {
1765 rect.set(task.getBounds());
1766 } else if (task.mLastNonFullscreenBounds != null) {
1767 rect.set(task.mLastNonFullscreenBounds);
1768 }
1769 }
1770 }
1771 } finally {
1772 Binder.restoreCallingIdentity(ident);
1773 }
1774 return rect;
1775 }
1776
1777 @Override
1778 public ActivityManager.TaskDescription getTaskDescription(int id) {
1779 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001780 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001781 MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
1782 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
1783 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1784 if (tr != null) {
1785 return tr.lastTaskDescription;
1786 }
1787 }
1788 return null;
1789 }
1790
1791 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001792 public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
1793 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
1794 setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
1795 toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
1796 return;
1797 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001798 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001799 synchronized (mGlobalLock) {
1800 final long ident = Binder.clearCallingIdentity();
1801 try {
1802 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1803 if (task == null) {
1804 Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
1805 return;
1806 }
1807
1808 if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
1809 + " to windowingMode=" + windowingMode + " toTop=" + toTop);
1810
1811 if (!task.isActivityTypeStandardOrUndefined()) {
1812 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
1813 + " non-standard task " + taskId + " to windowing mode="
1814 + windowingMode);
1815 }
1816
1817 final ActivityStack stack = task.getStack();
1818 if (toTop) {
1819 stack.moveToFront("setTaskWindowingMode", task);
1820 }
1821 stack.setWindowingMode(windowingMode);
1822 } finally {
1823 Binder.restoreCallingIdentity(ident);
1824 }
1825 }
1826 }
1827
1828 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001829 public String getCallingPackage(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001830 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001831 ActivityRecord r = getCallingRecordLocked(token);
1832 return r != null ? r.info.packageName : null;
1833 }
1834 }
1835
1836 @Override
1837 public ComponentName getCallingActivity(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001838 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001839 ActivityRecord r = getCallingRecordLocked(token);
1840 return r != null ? r.intent.getComponent() : null;
1841 }
1842 }
1843
1844 private ActivityRecord getCallingRecordLocked(IBinder token) {
1845 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1846 if (r == null) {
1847 return null;
1848 }
1849 return r.resultTo;
1850 }
1851
1852 @Override
1853 public void unhandledBack() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001854 mAmInternal.enforceCallingPermission(android.Manifest.permission.FORCE_BACK, "unhandledBack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001855
1856 synchronized (mGlobalLock) {
1857 final long origId = Binder.clearCallingIdentity();
1858 try {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001859 getTopDisplayFocusedStack().unhandledBackLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001860 } finally {
1861 Binder.restoreCallingIdentity(origId);
1862 }
1863 }
1864 }
1865
1866 /**
1867 * TODO: Add mController hook
1868 */
1869 @Override
1870 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001871 mAmInternal.enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001872
1873 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
1874 synchronized (mGlobalLock) {
1875 moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
1876 false /* fromRecents */);
1877 }
1878 }
1879
1880 void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
1881 boolean fromRecents) {
1882
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001883 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001884 Binder.getCallingUid(), -1, -1, "Task to front")) {
1885 SafeActivityOptions.abort(options);
1886 return;
1887 }
1888 final long origId = Binder.clearCallingIdentity();
1889 try {
1890 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1891 if (task == null) {
1892 Slog.d(TAG, "Could not find task for id: "+ taskId);
1893 return;
1894 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001895 if (getLockTaskController().isLockTaskModeViolation(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001896 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
1897 return;
1898 }
1899 ActivityOptions realOptions = options != null
1900 ? options.getOptions(mStackSupervisor)
1901 : null;
1902 mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
1903 false /* forceNonResizable */);
1904
1905 final ActivityRecord topActivity = task.getTopActivity();
1906 if (topActivity != null) {
1907
1908 // We are reshowing a task, use a starting window to hide the initial draw delay
1909 // so the transition can start earlier.
1910 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
1911 true /* taskSwitch */, fromRecents);
1912 }
1913 } finally {
1914 Binder.restoreCallingIdentity(origId);
1915 }
1916 SafeActivityOptions.abort(options);
1917 }
1918
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001919 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
1920 int callingPid, int callingUid, String name) {
1921 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
1922 return true;
1923 }
1924
1925 if (getRecentTasks().isCallerRecents(sourceUid)) {
1926 return true;
1927 }
1928
1929 int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
1930 if (perm == PackageManager.PERMISSION_GRANTED) {
1931 return true;
1932 }
1933 if (checkAllowAppSwitchUid(sourceUid)) {
1934 return true;
1935 }
1936
1937 // If the actual IPC caller is different from the logical source, then
1938 // also see if they are allowed to control app switches.
1939 if (callingUid != -1 && callingUid != sourceUid) {
1940 perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
1941 if (perm == PackageManager.PERMISSION_GRANTED) {
1942 return true;
1943 }
1944 if (checkAllowAppSwitchUid(callingUid)) {
1945 return true;
1946 }
1947 }
1948
1949 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
1950 return false;
1951 }
1952
1953 private boolean checkAllowAppSwitchUid(int uid) {
1954 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
1955 if (types != null) {
1956 for (int i = types.size() - 1; i >= 0; i--) {
1957 if (types.valueAt(i).intValue() == uid) {
1958 return true;
1959 }
1960 }
1961 }
1962 return false;
1963 }
1964
1965 @Override
1966 public void setActivityController(IActivityController controller, boolean imAMonkey) {
1967 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
1968 "setActivityController()");
1969 synchronized (mGlobalLock) {
1970 mController = controller;
1971 mControllerIsAMonkey = imAMonkey;
1972 Watchdog.getInstance().setActivityController(controller);
1973 }
1974 }
1975
1976 boolean isControllerAMonkey() {
1977 synchronized (mGlobalLock) {
1978 return mController != null && mControllerIsAMonkey;
1979 }
1980 }
1981
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001982 @Override
1983 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
1984 synchronized (mGlobalLock) {
1985 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
1986 }
1987 }
1988
1989 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001990 public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum) {
1991 return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
1992 }
1993
1994 @Override
1995 public List<ActivityManager.RunningTaskInfo> getFilteredTasks(int maxNum,
1996 @WindowConfiguration.ActivityType int ignoreActivityType,
1997 @WindowConfiguration.WindowingMode int ignoreWindowingMode) {
1998 final int callingUid = Binder.getCallingUid();
1999 ArrayList<ActivityManager.RunningTaskInfo> list = new ArrayList<>();
2000
2001 synchronized (mGlobalLock) {
2002 if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
2003
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002004 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002005 callingUid);
2006 mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
2007 ignoreWindowingMode, callingUid, allowed);
2008 }
2009
2010 return list;
2011 }
2012
2013 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002014 public final void finishSubActivity(IBinder token, String resultWho, int requestCode) {
2015 synchronized (mGlobalLock) {
2016 final long origId = Binder.clearCallingIdentity();
2017 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2018 if (r != null) {
2019 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
2020 }
2021 Binder.restoreCallingIdentity(origId);
2022 }
2023 }
2024
2025 @Override
2026 public boolean willActivityBeVisible(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002027 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002028 ActivityStack stack = ActivityRecord.getStackLocked(token);
2029 if (stack != null) {
2030 return stack.willActivityBeVisibleLocked(token);
2031 }
2032 return false;
2033 }
2034 }
2035
2036 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002037 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002038 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002039 synchronized (mGlobalLock) {
2040 final long ident = Binder.clearCallingIdentity();
2041 try {
2042 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2043 if (task == null) {
2044 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
2045 return;
2046 }
2047
2048 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
2049 + " to stackId=" + stackId + " toTop=" + toTop);
2050
2051 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2052 if (stack == null) {
2053 throw new IllegalStateException(
2054 "moveTaskToStack: No stack for stackId=" + stackId);
2055 }
2056 if (!stack.isActivityTypeStandardOrUndefined()) {
2057 throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
2058 + taskId + " to stack " + stackId);
2059 }
2060 if (stack.inSplitScreenPrimaryWindowingMode()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002061 mWindowManager.setDockedStackCreateState(
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002062 SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
2063 }
2064 task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
2065 "moveTaskToStack");
2066 } finally {
2067 Binder.restoreCallingIdentity(ident);
2068 }
2069 }
2070 }
2071
2072 @Override
2073 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
2074 boolean preserveWindows, boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002075 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002076
2077 final long ident = Binder.clearCallingIdentity();
2078 try {
2079 synchronized (mGlobalLock) {
2080 if (animate) {
2081 final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
2082 if (stack == null) {
2083 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2084 return;
2085 }
2086 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
2087 throw new IllegalArgumentException("Stack: " + stackId
2088 + " doesn't support animated resize.");
2089 }
2090 stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
2091 animationDuration, false /* fromFullscreen */);
2092 } else {
2093 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2094 if (stack == null) {
2095 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2096 return;
2097 }
2098 mStackSupervisor.resizeStackLocked(stack, destBounds,
2099 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
2100 preserveWindows, allowResizeInDockedMode, !DEFER_RESUME);
2101 }
2102 }
2103 } finally {
2104 Binder.restoreCallingIdentity(ident);
2105 }
2106 }
2107
2108 /**
2109 * Moves the specified task to the primary-split-screen stack.
2110 *
2111 * @param taskId Id of task to move.
2112 * @param createMode The mode the primary split screen stack should be created in if it doesn't
2113 * exist already. See
2114 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
2115 * and
2116 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
2117 * @param toTop If the task and stack should be moved to the top.
2118 * @param animate Whether we should play an animation for the moving the task.
2119 * @param initialBounds If the primary stack gets created, it will use these bounds for the
2120 * stack. Pass {@code null} to use default bounds.
2121 * @param showRecents If the recents activity should be shown on the other side of the task
2122 * going into split-screen mode.
2123 */
2124 @Override
2125 public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode,
2126 boolean toTop, boolean animate, Rect initialBounds, boolean showRecents) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002127 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002128 "setTaskWindowingModeSplitScreenPrimary()");
2129 synchronized (mGlobalLock) {
2130 final long ident = Binder.clearCallingIdentity();
2131 try {
2132 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2133 if (task == null) {
2134 Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
2135 return false;
2136 }
2137 if (DEBUG_STACK) Slog.d(TAG_STACK,
2138 "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
2139 + " to createMode=" + createMode + " toTop=" + toTop);
2140 if (!task.isActivityTypeStandardOrUndefined()) {
2141 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
2142 + " non-standard task " + taskId + " to split-screen windowing mode");
2143 }
2144
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002145 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002146 final int windowingMode = task.getWindowingMode();
2147 final ActivityStack stack = task.getStack();
2148 if (toTop) {
2149 stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
2150 }
2151 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
2152 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */);
2153 return windowingMode != task.getWindowingMode();
2154 } finally {
2155 Binder.restoreCallingIdentity(ident);
2156 }
2157 }
2158 }
2159
2160 /**
2161 * Removes stacks in the input windowing modes from the system if they are of activity type
2162 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
2163 */
2164 @Override
2165 public void removeStacksInWindowingModes(int[] windowingModes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002166 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002167 "removeStacksInWindowingModes()");
2168
2169 synchronized (mGlobalLock) {
2170 final long ident = Binder.clearCallingIdentity();
2171 try {
2172 mStackSupervisor.removeStacksInWindowingModes(windowingModes);
2173 } finally {
2174 Binder.restoreCallingIdentity(ident);
2175 }
2176 }
2177 }
2178
2179 @Override
2180 public void removeStacksWithActivityTypes(int[] activityTypes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002181 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002182 "removeStacksWithActivityTypes()");
2183
2184 synchronized (mGlobalLock) {
2185 final long ident = Binder.clearCallingIdentity();
2186 try {
2187 mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
2188 } finally {
2189 Binder.restoreCallingIdentity(ident);
2190 }
2191 }
2192 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002193
2194 @Override
2195 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
2196 int userId) {
2197 final int callingUid = Binder.getCallingUid();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002198 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, "getRecentTasks");
2199 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002200 callingUid);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002201 final boolean detailed = checkGetTasksPermission(
2202 android.Manifest.permission.GET_DETAILED_TASKS, Binder.getCallingPid(),
2203 UserHandle.getAppId(callingUid))
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002204 == PackageManager.PERMISSION_GRANTED;
2205
2206 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002207 return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002208 callingUid);
2209 }
2210 }
2211
2212 @Override
2213 public List<ActivityManager.StackInfo> getAllStackInfos() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002214 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002215 long ident = Binder.clearCallingIdentity();
2216 try {
2217 synchronized (mGlobalLock) {
2218 return mStackSupervisor.getAllStackInfosLocked();
2219 }
2220 } finally {
2221 Binder.restoreCallingIdentity(ident);
2222 }
2223 }
2224
2225 @Override
2226 public ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002227 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002228 long ident = Binder.clearCallingIdentity();
2229 try {
2230 synchronized (mGlobalLock) {
2231 return mStackSupervisor.getStackInfo(windowingMode, activityType);
2232 }
2233 } finally {
2234 Binder.restoreCallingIdentity(ident);
2235 }
2236 }
2237
2238 @Override
2239 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002240 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002241 final long callingUid = Binder.getCallingUid();
2242 final long origId = Binder.clearCallingIdentity();
2243 try {
2244 synchronized (mGlobalLock) {
2245 // Cancel the recents animation synchronously (do not hold the WM lock)
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002246 mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002247 ? REORDER_MOVE_TO_ORIGINAL_POSITION
2248 : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
2249 }
2250 } finally {
2251 Binder.restoreCallingIdentity(origId);
2252 }
2253 }
2254
2255 @Override
2256 public void startLockTaskModeByToken(IBinder token) {
2257 synchronized (mGlobalLock) {
2258 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2259 if (r == null) {
2260 return;
2261 }
2262 startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
2263 }
2264 }
2265
2266 @Override
2267 public void startSystemLockTaskMode(int taskId) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002268 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002269 // This makes inner call to look as if it was initiated by system.
2270 long ident = Binder.clearCallingIdentity();
2271 try {
2272 synchronized (mGlobalLock) {
2273 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2274
2275 // When starting lock task mode the stack must be in front and focused
2276 task.getStack().moveToFront("startSystemLockTaskMode");
2277 startLockTaskModeLocked(task, true /* isSystemCaller */);
2278 }
2279 } finally {
2280 Binder.restoreCallingIdentity(ident);
2281 }
2282 }
2283
2284 @Override
2285 public void stopLockTaskModeByToken(IBinder token) {
2286 synchronized (mGlobalLock) {
2287 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2288 if (r == null) {
2289 return;
2290 }
2291 stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
2292 }
2293 }
2294
2295 /**
2296 * This API should be called by SystemUI only when user perform certain action to dismiss
2297 * lock task mode. We should only dismiss pinned lock task mode in this case.
2298 */
2299 @Override
2300 public void stopSystemLockTaskMode() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002301 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002302 stopLockTaskModeInternal(null, true /* isSystemCaller */);
2303 }
2304
2305 private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
2306 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
2307 if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
2308 return;
2309 }
2310
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002311 final ActivityStack stack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002312 if (stack == null || task != stack.topTask()) {
2313 throw new IllegalArgumentException("Invalid task, not in foreground");
2314 }
2315
2316 // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
2317 // system or a specific app.
2318 // * System-initiated requests will only start the pinned mode (screen pinning)
2319 // * App-initiated requests
2320 // - will put the device in fully locked mode (LockTask), if the app is whitelisted
2321 // - will start the pinned mode, otherwise
2322 final int callingUid = Binder.getCallingUid();
2323 long ident = Binder.clearCallingIdentity();
2324 try {
2325 // When a task is locked, dismiss the pinned stack if it exists
2326 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2327
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002328 getLockTaskController().startLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002329 } finally {
2330 Binder.restoreCallingIdentity(ident);
2331 }
2332 }
2333
2334 private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
2335 final int callingUid = Binder.getCallingUid();
2336 long ident = Binder.clearCallingIdentity();
2337 try {
2338 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002339 getLockTaskController().stopLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002340 }
2341 // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
2342 // task and jumping straight into a call in the case of emergency call back.
2343 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
2344 if (tm != null) {
2345 tm.showInCallScreen(false);
2346 }
2347 } finally {
2348 Binder.restoreCallingIdentity(ident);
2349 }
2350 }
2351
2352 @Override
2353 public boolean isInLockTaskMode() {
2354 return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
2355 }
2356
2357 @Override
2358 public int getLockTaskModeState() {
2359 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002360 return getLockTaskController().getLockTaskModeState();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002361 }
2362 }
2363
2364 @Override
2365 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
2366 synchronized (mGlobalLock) {
2367 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2368 if (r != null) {
2369 r.setTaskDescription(td);
2370 final TaskRecord task = r.getTask();
2371 task.updateTaskDescription();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002372 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002373 }
2374 }
2375 }
2376
2377 @Override
2378 public Bundle getActivityOptions(IBinder token) {
2379 final long origId = Binder.clearCallingIdentity();
2380 try {
2381 synchronized (mGlobalLock) {
2382 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
2383 if (r != null) {
2384 final ActivityOptions activityOptions = r.takeOptionsLocked();
2385 return activityOptions == null ? null : activityOptions.toBundle();
2386 }
2387 return null;
2388 }
2389 } finally {
2390 Binder.restoreCallingIdentity(origId);
2391 }
2392 }
2393
2394 @Override
2395 public List<IBinder> getAppTasks(String callingPackage) {
2396 int callingUid = Binder.getCallingUid();
2397 long ident = Binder.clearCallingIdentity();
2398 try {
2399 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002400 return mRecentTasks.getAppTasksList(callingUid, callingPackage);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002401 }
2402 } finally {
2403 Binder.restoreCallingIdentity(ident);
2404 }
2405 }
2406
2407 @Override
2408 public void finishVoiceTask(IVoiceInteractionSession session) {
2409 synchronized (mGlobalLock) {
2410 final long origId = Binder.clearCallingIdentity();
2411 try {
2412 // TODO: VI Consider treating local voice interactions and voice tasks
2413 // differently here
2414 mStackSupervisor.finishVoiceTask(session);
2415 } finally {
2416 Binder.restoreCallingIdentity(origId);
2417 }
2418 }
2419
2420 }
2421
2422 @Override
2423 public boolean isTopOfTask(IBinder token) {
2424 synchronized (mGlobalLock) {
2425 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2426 if (r == null) {
2427 throw new IllegalArgumentException();
2428 }
2429 return r.getTask().getTopActivity() == r;
2430 }
2431 }
2432
2433 @Override
2434 public void notifyLaunchTaskBehindComplete(IBinder token) {
2435 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
2436 }
2437
2438 @Override
2439 public void notifyEnterAnimationComplete(IBinder token) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002440 mH.post(() -> {
2441 synchronized (mGlobalLock) {
2442 ActivityRecord r = ActivityRecord.forTokenLocked(token);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002443 if (r != null && r.attachedToProcess()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002444 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002445 r.app.getThread().scheduleEnterAnimationComplete(r.appToken);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002446 } catch (RemoteException e) {
2447 }
2448 }
2449 }
2450
2451 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002452 }
2453
2454 /** Called from an app when assist data is ready. */
2455 @Override
2456 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
2457 AssistContent content, Uri referrer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002458 PendingAssistExtras pae = (PendingAssistExtras) token;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002459 synchronized (pae) {
2460 pae.result = extras;
2461 pae.structure = structure;
2462 pae.content = content;
2463 if (referrer != null) {
2464 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
2465 }
2466 if (structure != null) {
2467 structure.setHomeActivity(pae.isHome);
2468 }
2469 pae.haveResult = true;
2470 pae.notifyAll();
2471 if (pae.intent == null && pae.receiver == null) {
2472 // Caller is just waiting for the result.
2473 return;
2474 }
2475 }
2476 // We are now ready to launch the assist activity.
2477 IAssistDataReceiver sendReceiver = null;
2478 Bundle sendBundle = null;
2479 synchronized (mGlobalLock) {
2480 buildAssistBundleLocked(pae, extras);
2481 boolean exists = mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002482 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002483 if (!exists) {
2484 // Timed out.
2485 return;
2486 }
2487
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002488 if ((sendReceiver = pae.receiver) != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002489 // Caller wants result sent back to them.
2490 sendBundle = new Bundle();
2491 sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
2492 sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
2493 sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
2494 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
2495 }
2496 }
2497 if (sendReceiver != null) {
2498 try {
2499 sendReceiver.onHandleAssistData(sendBundle);
2500 } catch (RemoteException e) {
2501 }
2502 return;
2503 }
2504
2505 final long ident = Binder.clearCallingIdentity();
2506 try {
2507 if (TextUtils.equals(pae.intent.getAction(),
2508 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
2509 pae.intent.putExtras(pae.extras);
2510 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
2511 } else {
2512 pae.intent.replaceExtras(pae.extras);
2513 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
2514 | Intent.FLAG_ACTIVITY_SINGLE_TOP
2515 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002516 mAmInternal.closeSystemDialogs("assist");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002517
2518 try {
2519 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
2520 } catch (ActivityNotFoundException e) {
2521 Slog.w(TAG, "No activity to handle assist action.", e);
2522 }
2523 }
2524 } finally {
2525 Binder.restoreCallingIdentity(ident);
2526 }
2527 }
2528
2529 @Override
2530 public int addAppTask(IBinder activityToken, Intent intent,
2531 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
2532 final int callingUid = Binder.getCallingUid();
2533 final long callingIdent = Binder.clearCallingIdentity();
2534
2535 try {
2536 synchronized (mGlobalLock) {
2537 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
2538 if (r == null) {
2539 throw new IllegalArgumentException("Activity does not exist; token="
2540 + activityToken);
2541 }
2542 ComponentName comp = intent.getComponent();
2543 if (comp == null) {
2544 throw new IllegalArgumentException("Intent " + intent
2545 + " must specify explicit component");
2546 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002547 if (thumbnail.getWidth() != mThumbnailWidth
2548 || thumbnail.getHeight() != mThumbnailHeight) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002549 throw new IllegalArgumentException("Bad thumbnail size: got "
2550 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002551 + mThumbnailWidth + "x" + mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002552 }
2553 if (intent.getSelector() != null) {
2554 intent.setSelector(null);
2555 }
2556 if (intent.getSourceBounds() != null) {
2557 intent.setSourceBounds(null);
2558 }
2559 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
2560 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
2561 // The caller has added this as an auto-remove task... that makes no
2562 // sense, so turn off auto-remove.
2563 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
2564 }
2565 }
2566 final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
2567 STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
2568 if (ainfo.applicationInfo.uid != callingUid) {
2569 throw new SecurityException(
2570 "Can't add task for another application: target uid="
2571 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
2572 }
2573
2574 final ActivityStack stack = r.getStack();
2575 final TaskRecord task = stack.createTaskRecord(
2576 mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent,
2577 null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002578 if (!mRecentTasks.addToBottom(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002579 // The app has too many tasks already and we can't add any more
2580 stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
2581 return INVALID_TASK_ID;
2582 }
2583 task.lastTaskDescription.copyFrom(description);
2584
2585 // TODO: Send the thumbnail to WM to store it.
2586
2587 return task.taskId;
2588 }
2589 } finally {
2590 Binder.restoreCallingIdentity(callingIdent);
2591 }
2592 }
2593
2594 @Override
2595 public Point getAppTaskThumbnailSize() {
2596 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002597 return new Point(mThumbnailWidth, mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002598 }
2599 }
2600
2601 @Override
2602 public void setTaskResizeable(int taskId, int resizeableMode) {
2603 synchronized (mGlobalLock) {
2604 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
2605 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
2606 if (task == null) {
2607 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
2608 return;
2609 }
2610 task.setResizeMode(resizeableMode);
2611 }
2612 }
2613
2614 @Override
2615 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002616 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002617 long ident = Binder.clearCallingIdentity();
2618 try {
2619 synchronized (mGlobalLock) {
2620 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2621 if (task == null) {
2622 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
2623 return;
2624 }
2625 // Place the task in the right stack if it isn't there already based on
2626 // the requested bounds.
2627 // The stack transition logic is:
2628 // - a null bounds on a freeform task moves that task to fullscreen
2629 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
2630 // that task to freeform
2631 // - otherwise the task is not moved
2632 ActivityStack stack = task.getStack();
2633 if (!task.getWindowConfiguration().canResizeTask()) {
2634 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
2635 }
2636 if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
2637 stack = stack.getDisplay().getOrCreateStack(
2638 WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
2639 } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
2640 stack = stack.getDisplay().getOrCreateStack(
2641 WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
2642 }
2643
2644 // Reparent the task to the right stack if necessary
2645 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
2646 if (stack != task.getStack()) {
2647 // Defer resume until the task is resized below
2648 task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
2649 DEFER_RESUME, "resizeTask");
2650 preserveWindow = false;
2651 }
2652
2653 // After reparenting (which only resizes the task to the stack bounds), resize the
2654 // task to the actual bounds provided
2655 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
2656 }
2657 } finally {
2658 Binder.restoreCallingIdentity(ident);
2659 }
2660 }
2661
2662 @Override
2663 public boolean releaseActivityInstance(IBinder token) {
2664 synchronized (mGlobalLock) {
2665 final long origId = Binder.clearCallingIdentity();
2666 try {
2667 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2668 if (r == null) {
2669 return false;
2670 }
2671 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
2672 } finally {
2673 Binder.restoreCallingIdentity(origId);
2674 }
2675 }
2676 }
2677
2678 @Override
2679 public void releaseSomeActivities(IApplicationThread appInt) {
2680 synchronized (mGlobalLock) {
2681 final long origId = Binder.clearCallingIdentity();
2682 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002683 WindowProcessController app =
2684 mAm.getRecordForAppLocked(appInt).getWindowProcessController();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002685 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
2686 } finally {
2687 Binder.restoreCallingIdentity(origId);
2688 }
2689 }
2690 }
2691
2692 @Override
2693 public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
2694 int secondaryDisplayShowing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002695 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002696 != PackageManager.PERMISSION_GRANTED) {
2697 throw new SecurityException("Requires permission "
2698 + android.Manifest.permission.DEVICE_POWER);
2699 }
2700
2701 synchronized (mGlobalLock) {
2702 long ident = Binder.clearCallingIdentity();
2703 if (mKeyguardShown != keyguardShowing) {
2704 mKeyguardShown = keyguardShowing;
2705 reportCurKeyguardUsageEventLocked(keyguardShowing);
2706 }
2707 try {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002708 mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002709 secondaryDisplayShowing);
2710 } finally {
2711 Binder.restoreCallingIdentity(ident);
2712 }
2713 }
2714
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002715 mH.post(() -> {
2716 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2717 mScreenObservers.get(i).onKeyguardStateChanged(keyguardShowing);
2718 }
2719 });
2720 }
2721
2722 void onScreenAwakeChanged(boolean isAwake) {
2723 mH.post(() -> {
2724 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2725 mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2726 }
2727 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002728 }
2729
2730 @Override
2731 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002732 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
2733 userId, "getTaskDescriptionIcon");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002734
2735 final File passedIconFile = new File(filePath);
2736 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
2737 passedIconFile.getName());
2738 if (!legitIconFile.getPath().equals(filePath)
2739 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
2740 throw new IllegalArgumentException("Bad file path: " + filePath
2741 + " passed for userId " + userId);
2742 }
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002743 return mRecentTasks.getTaskDescriptionIcon(filePath);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002744 }
2745
2746 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002747 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002748 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
2749 final ActivityOptions activityOptions = safeOptions != null
2750 ? safeOptions.getOptions(mStackSupervisor)
2751 : null;
2752 if (activityOptions == null
2753 || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
2754 || activityOptions.getCustomInPlaceResId() == 0) {
2755 throw new IllegalArgumentException("Expected in-place ActivityOption " +
2756 "with valid animation");
2757 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002758 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
2759 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002760 activityOptions.getCustomInPlaceResId());
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002761 mWindowManager.executeAppTransition();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002762 }
2763
2764 @Override
2765 public void removeStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002766 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002767 synchronized (mGlobalLock) {
2768 final long ident = Binder.clearCallingIdentity();
2769 try {
2770 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2771 if (stack == null) {
2772 Slog.w(TAG, "removeStack: No stack with id=" + stackId);
2773 return;
2774 }
2775 if (!stack.isActivityTypeStandardOrUndefined()) {
2776 throw new IllegalArgumentException(
2777 "Removing non-standard stack is not allowed.");
2778 }
2779 mStackSupervisor.removeStack(stack);
2780 } finally {
2781 Binder.restoreCallingIdentity(ident);
2782 }
2783 }
2784 }
2785
2786 @Override
2787 public void moveStackToDisplay(int stackId, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002788 mAmInternal.enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002789
2790 synchronized (mGlobalLock) {
2791 final long ident = Binder.clearCallingIdentity();
2792 try {
2793 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
2794 + " to displayId=" + displayId);
2795 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
2796 } finally {
2797 Binder.restoreCallingIdentity(ident);
2798 }
2799 }
2800 }
2801
2802 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002803 public void exitFreeformMode(IBinder token) {
2804 synchronized (mGlobalLock) {
2805 long ident = Binder.clearCallingIdentity();
2806 try {
2807 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2808 if (r == null) {
2809 throw new IllegalArgumentException(
2810 "exitFreeformMode: No activity record matching token=" + token);
2811 }
2812
2813 final ActivityStack stack = r.getStack();
2814 if (stack == null || !stack.inFreeformWindowingMode()) {
2815 throw new IllegalStateException(
2816 "exitFreeformMode: You can only go fullscreen from freeform.");
2817 }
2818
2819 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
2820 } finally {
2821 Binder.restoreCallingIdentity(ident);
2822 }
2823 }
2824 }
2825
2826 /** Sets the task stack listener that gets callbacks when a task stack changes. */
2827 @Override
2828 public void registerTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002829 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002830 "registerTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002831 mTaskChangeNotificationController.registerTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002832 }
2833
2834 /** Unregister a task stack listener so that it stops receiving callbacks. */
2835 @Override
2836 public void unregisterTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002837 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002838 "unregisterTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002839 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002840 }
2841
2842 private void reportCurKeyguardUsageEventLocked(boolean keyguardShowing) {
2843 mAm.reportGlobalUsageEventLocked(keyguardShowing
2844 ? UsageEvents.Event.KEYGUARD_SHOWN
2845 : UsageEvents.Event.KEYGUARD_HIDDEN);
2846 }
2847
2848 @Override
2849 public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
2850 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
2851 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
2852 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
2853 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
2854 }
2855
2856 @Override
2857 public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
2858 IBinder activityToken, int flags) {
2859 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
2860 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
2861 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
2862 }
2863
2864 @Override
2865 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
2866 Bundle args) {
2867 return enqueueAssistContext(requestType, intent, hint, null, null, null,
2868 true /* focused */, true /* newSessionId */, userHandle, args,
2869 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
2870 }
2871
2872 @Override
2873 public Bundle getAssistContextExtras(int requestType) {
2874 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
2875 null, null, true /* focused */, true /* newSessionId */,
2876 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
2877 if (pae == null) {
2878 return null;
2879 }
2880 synchronized (pae) {
2881 while (!pae.haveResult) {
2882 try {
2883 pae.wait();
2884 } catch (InterruptedException e) {
2885 }
2886 }
2887 }
2888 synchronized (mGlobalLock) {
2889 buildAssistBundleLocked(pae, pae.result);
2890 mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002891 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002892 }
2893 return pae.extras;
2894 }
2895
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002896 /**
2897 * Binder IPC calls go through the public entry point.
2898 * This can be called with or without the global lock held.
2899 */
2900 private static int checkCallingPermission(String permission) {
2901 return checkPermission(
2902 permission, Binder.getCallingPid(), UserHandle.getAppId(Binder.getCallingUid()));
2903 }
2904
2905 /** This can be called with or without the global lock held. */
2906 void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
2907 if (!getRecentTasks().isCallerRecents(Binder.getCallingUid())) {
2908 mAmInternal.enforceCallingPermission(permission, func);
2909 }
2910 }
2911
2912 @VisibleForTesting
2913 int checkGetTasksPermission(String permission, int pid, int uid) {
2914 return checkPermission(permission, pid, uid);
2915 }
2916
2917 static int checkPermission(String permission, int pid, int uid) {
2918 if (permission == null) {
2919 return PackageManager.PERMISSION_DENIED;
2920 }
2921 return checkComponentPermission(permission, pid, uid, -1, true);
2922 }
2923
2924 boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
2925 if (getRecentTasks().isCallerRecents(callingUid)) {
2926 // Always allow the recents component to get tasks
2927 return true;
2928 }
2929
2930 boolean allowed = checkGetTasksPermission(android.Manifest.permission.REAL_GET_TASKS,
2931 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
2932 if (!allowed) {
2933 if (checkGetTasksPermission(android.Manifest.permission.GET_TASKS,
2934 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
2935 // Temporary compatibility: some existing apps on the system image may
2936 // still be requesting the old permission and not switched to the new
2937 // one; if so, we'll still allow them full access. This means we need
2938 // to see if they are holding the old permission and are a system app.
2939 try {
2940 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
2941 allowed = true;
2942 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
2943 + " is using old GET_TASKS but privileged; allowing");
2944 }
2945 } catch (RemoteException e) {
2946 }
2947 }
2948 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
2949 + " does not hold REAL_GET_TASKS; limiting output");
2950 }
2951 return allowed;
2952 }
2953
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002954 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
2955 IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
2956 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
2957 int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002958 mAmInternal.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002959 "enqueueAssistContext()");
2960
2961 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002962 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002963 if (activity == null) {
2964 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
2965 return null;
2966 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002967 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002968 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
2969 return null;
2970 }
2971 if (focused) {
2972 if (activityToken != null) {
2973 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
2974 if (activity != caller) {
2975 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
2976 + " is not current top " + activity);
2977 return null;
2978 }
2979 }
2980 } else {
2981 activity = ActivityRecord.forTokenLocked(activityToken);
2982 if (activity == null) {
2983 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
2984 + " couldn't be found");
2985 return null;
2986 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002987 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002988 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
2989 return null;
2990 }
2991 }
2992
2993 PendingAssistExtras pae;
2994 Bundle extras = new Bundle();
2995 if (args != null) {
2996 extras.putAll(args);
2997 }
2998 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002999 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003000
3001 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
3002 userHandle);
3003 pae.isHome = activity.isActivityTypeHome();
3004
3005 // Increment the sessionId if necessary
3006 if (newSessionId) {
3007 mViSessionId++;
3008 }
3009 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003010 activity.app.getThread().requestAssistContextExtras(activity.appToken, pae,
3011 requestType, mViSessionId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003012 mPendingAssistExtras.add(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003013 mUiHandler.postDelayed(pae, timeout);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003014 } catch (RemoteException e) {
3015 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
3016 return null;
3017 }
3018 return pae;
3019 }
3020 }
3021
3022 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
3023 if (result != null) {
3024 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
3025 }
3026 if (pae.hint != null) {
3027 pae.extras.putBoolean(pae.hint, true);
3028 }
3029 }
3030
3031 private void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
3032 IAssistDataReceiver receiver;
3033 synchronized (mGlobalLock) {
3034 mPendingAssistExtras.remove(pae);
3035 receiver = pae.receiver;
3036 }
3037 if (receiver != null) {
3038 // Caller wants result sent back to them.
3039 Bundle sendBundle = new Bundle();
3040 // At least return the receiver extras
3041 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
3042 try {
3043 pae.receiver.onHandleAssistData(sendBundle);
3044 } catch (RemoteException e) {
3045 }
3046 }
3047 }
3048
3049 public class PendingAssistExtras extends Binder implements Runnable {
3050 public final ActivityRecord activity;
3051 public boolean isHome;
3052 public final Bundle extras;
3053 public final Intent intent;
3054 public final String hint;
3055 public final IAssistDataReceiver receiver;
3056 public final int userHandle;
3057 public boolean haveResult = false;
3058 public Bundle result = null;
3059 public AssistStructure structure = null;
3060 public AssistContent content = null;
3061 public Bundle receiverExtras;
3062
3063 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
3064 String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
3065 int _userHandle) {
3066 activity = _activity;
3067 extras = _extras;
3068 intent = _intent;
3069 hint = _hint;
3070 receiver = _receiver;
3071 receiverExtras = _receiverExtras;
3072 userHandle = _userHandle;
3073 }
3074
3075 @Override
3076 public void run() {
3077 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
3078 synchronized (this) {
3079 haveResult = true;
3080 notifyAll();
3081 }
3082 pendingAssistExtrasTimedOut(this);
3083 }
3084 }
3085
3086 @Override
3087 public boolean isAssistDataAllowedOnCurrentActivity() {
3088 int userId;
3089 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003090 final ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003091 if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
3092 return false;
3093 }
3094
3095 final ActivityRecord activity = focusedStack.getTopActivity();
3096 if (activity == null) {
3097 return false;
3098 }
3099 userId = activity.userId;
3100 }
3101 return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
3102 }
3103
3104 @Override
3105 public boolean showAssistFromActivity(IBinder token, Bundle args) {
3106 long ident = Binder.clearCallingIdentity();
3107 try {
3108 synchronized (mGlobalLock) {
3109 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003110 ActivityRecord top = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003111 if (top != caller) {
3112 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3113 + " is not current top " + top);
3114 return false;
3115 }
3116 if (!top.nowVisible) {
3117 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3118 + " is not visible");
3119 return false;
3120 }
3121 }
3122 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
3123 token);
3124 } finally {
3125 Binder.restoreCallingIdentity(ident);
3126 }
3127 }
3128
3129 @Override
3130 public boolean isRootVoiceInteraction(IBinder token) {
3131 synchronized (mGlobalLock) {
3132 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3133 if (r == null) {
3134 return false;
3135 }
3136 return r.rootVoiceInteraction;
3137 }
3138 }
3139
Wale Ogunwalef6733932018-06-27 05:14:34 -07003140 private void onLocalVoiceInteractionStartedLocked(IBinder activity,
3141 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
3142 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
3143 if (activityToCallback == null) return;
3144 activityToCallback.setVoiceSessionLocked(voiceSession);
3145
3146 // Inform the activity
3147 try {
3148 activityToCallback.app.getThread().scheduleLocalVoiceInteractionStarted(activity,
3149 voiceInteractor);
3150 long token = Binder.clearCallingIdentity();
3151 try {
3152 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
3153 } finally {
3154 Binder.restoreCallingIdentity(token);
3155 }
3156 // TODO: VI Should we cache the activity so that it's easier to find later
3157 // rather than scan through all the stacks and activities?
3158 } catch (RemoteException re) {
3159 activityToCallback.clearVoiceSessionLocked();
3160 // TODO: VI Should this terminate the voice session?
3161 }
3162 }
3163
3164 private void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
3165 Slog.d(TAG, "<<< startRunningVoiceLocked()");
3166 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
3167 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
3168 boolean wasRunningVoice = mRunningVoice != null;
3169 mRunningVoice = session;
3170 if (!wasRunningVoice) {
3171 mVoiceWakeLock.acquire();
3172 updateSleepIfNeededLocked();
3173 }
3174 }
3175 }
3176
3177 void finishRunningVoiceLocked() {
3178 if (mRunningVoice != null) {
3179 mRunningVoice = null;
3180 mVoiceWakeLock.release();
3181 updateSleepIfNeededLocked();
3182 }
3183 }
3184
3185 @Override
3186 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3187 synchronized (mGlobalLock) {
3188 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3189 if (keepAwake) {
3190 mVoiceWakeLock.acquire();
3191 } else {
3192 mVoiceWakeLock.release();
3193 }
3194 }
3195 }
3196 }
3197
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003198 @Override
3199 public ComponentName getActivityClassForToken(IBinder token) {
3200 synchronized (mGlobalLock) {
3201 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3202 if (r == null) {
3203 return null;
3204 }
3205 return r.intent.getComponent();
3206 }
3207 }
3208
3209 @Override
3210 public String getPackageForToken(IBinder token) {
3211 synchronized (mGlobalLock) {
3212 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3213 if (r == null) {
3214 return null;
3215 }
3216 return r.packageName;
3217 }
3218 }
3219
3220 @Override
3221 public void showLockTaskEscapeMessage(IBinder token) {
3222 synchronized (mGlobalLock) {
3223 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3224 if (r == null) {
3225 return;
3226 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003227 getLockTaskController().showLockTaskToast();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003228 }
3229 }
3230
3231 @Override
3232 public void keyguardGoingAway(int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003233 enforceNotIsolatedCaller("keyguardGoingAway");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003234 final long token = Binder.clearCallingIdentity();
3235 try {
3236 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003237 mKeyguardController.keyguardGoingAway(flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003238 }
3239 } finally {
3240 Binder.restoreCallingIdentity(token);
3241 }
3242 }
3243
3244 /**
3245 * Try to place task to provided position. The final position might be different depending on
3246 * current user and stacks state. The task will be moved to target stack if it's currently in
3247 * different stack.
3248 */
3249 @Override
3250 public void positionTaskInStack(int taskId, int stackId, int position) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003251 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003252 synchronized (mGlobalLock) {
3253 long ident = Binder.clearCallingIdentity();
3254 try {
3255 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
3256 + taskId + " in stackId=" + stackId + " at position=" + position);
3257 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3258 if (task == null) {
3259 throw new IllegalArgumentException("positionTaskInStack: no task for id="
3260 + taskId);
3261 }
3262
3263 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3264
3265 if (stack == null) {
3266 throw new IllegalArgumentException("positionTaskInStack: no stack for id="
3267 + stackId);
3268 }
3269 if (!stack.isActivityTypeStandardOrUndefined()) {
3270 throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
3271 + " the position of task " + taskId + " in/to non-standard stack");
3272 }
3273
3274 // TODO: Have the callers of this API call a separate reparent method if that is
3275 // what they intended to do vs. having this method also do reparenting.
3276 if (task.getStack() == stack) {
3277 // Change position in current stack.
3278 stack.positionChildAt(task, position);
3279 } else {
3280 // Reparent to new stack.
3281 task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
3282 !DEFER_RESUME, "positionTaskInStack");
3283 }
3284 } finally {
3285 Binder.restoreCallingIdentity(ident);
3286 }
3287 }
3288 }
3289
3290 @Override
3291 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
3292 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
3293 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
3294 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
3295 synchronized (mGlobalLock) {
3296 ActivityRecord record = ActivityRecord.isInStackLocked(token);
3297 if (record == null) {
3298 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
3299 + "found for: " + token);
3300 }
3301 record.setSizeConfigurations(horizontalSizeConfiguration,
3302 verticalSizeConfigurations, smallestSizeConfigurations);
3303 }
3304 }
3305
3306 /**
3307 * Dismisses split-screen multi-window mode.
3308 * @param toTop If true the current primary split-screen stack will be placed or left on top.
3309 */
3310 @Override
3311 public void dismissSplitScreenMode(boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003312 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003313 MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
3314 final long ident = Binder.clearCallingIdentity();
3315 try {
3316 synchronized (mGlobalLock) {
3317 final ActivityStack stack =
3318 mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
3319 if (stack == null) {
3320 Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
3321 return;
3322 }
3323
3324 if (toTop) {
3325 // Caller wants the current split-screen primary stack to be the top stack after
3326 // it goes fullscreen, so move it to the front.
3327 stack.moveToFront("dismissSplitScreenMode");
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003328 } else if (mStackSupervisor.isTopDisplayFocusedStack(stack)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003329 // In this case the current split-screen primary stack shouldn't be the top
3330 // stack after it goes fullscreen, but it current has focus, so we move the
3331 // focus to the top-most split-screen secondary stack next to it.
3332 final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
3333 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
3334 if (otherStack != null) {
3335 otherStack.moveToFront("dismissSplitScreenMode_other");
3336 }
3337 }
3338
3339 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
3340 }
3341 } finally {
3342 Binder.restoreCallingIdentity(ident);
3343 }
3344 }
3345
3346 /**
3347 * Dismisses Pip
3348 * @param animate True if the dismissal should be animated.
3349 * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
3350 * default animation duration should be used.
3351 */
3352 @Override
3353 public void dismissPip(boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003354 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003355 final long ident = Binder.clearCallingIdentity();
3356 try {
3357 synchronized (mGlobalLock) {
3358 final PinnedActivityStack stack =
3359 mStackSupervisor.getDefaultDisplay().getPinnedStack();
3360 if (stack == null) {
3361 Slog.w(TAG, "dismissPip: pinned stack not found.");
3362 return;
3363 }
3364 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
3365 throw new IllegalArgumentException("Stack: " + stack
3366 + " doesn't support animated resize.");
3367 }
3368 if (animate) {
3369 stack.animateResizePinnedStack(null /* sourceHintBounds */,
3370 null /* destBounds */, animationDuration, false /* fromFullscreen */);
3371 } else {
3372 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
3373 }
3374 }
3375 } finally {
3376 Binder.restoreCallingIdentity(ident);
3377 }
3378 }
3379
3380 @Override
3381 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003382 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003383 synchronized (mGlobalLock) {
3384 mSuppressResizeConfigChanges = suppress;
3385 }
3386 }
3387
3388 /**
3389 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
3390 * animated the stack to the fullscreen, but can also be called if we are relaunching an
3391 * activity and clearing the task at the same time.
3392 */
3393 @Override
3394 // TODO: API should just be about changing windowing modes...
3395 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003396 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003397 "moveTasksToFullscreenStack()");
3398 synchronized (mGlobalLock) {
3399 final long origId = Binder.clearCallingIdentity();
3400 try {
3401 final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
3402 if (stack != null){
3403 if (!stack.isActivityTypeStandardOrUndefined()) {
3404 throw new IllegalArgumentException(
3405 "You can't move tasks from non-standard stacks.");
3406 }
3407 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
3408 }
3409 } finally {
3410 Binder.restoreCallingIdentity(origId);
3411 }
3412 }
3413 }
3414
3415 /**
3416 * Moves the top activity in the input stackId to the pinned stack.
3417 *
3418 * @param stackId Id of stack to move the top activity to pinned stack.
3419 * @param bounds Bounds to use for pinned stack.
3420 *
3421 * @return True if the top activity of the input stack was successfully moved to the pinned
3422 * stack.
3423 */
3424 @Override
3425 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003426 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003427 "moveTopActivityToPinnedStack()");
3428 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003429 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003430 throw new IllegalStateException("moveTopActivityToPinnedStack:"
3431 + "Device doesn't support picture-in-picture mode");
3432 }
3433
3434 long ident = Binder.clearCallingIdentity();
3435 try {
3436 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
3437 } finally {
3438 Binder.restoreCallingIdentity(ident);
3439 }
3440 }
3441 }
3442
3443 @Override
3444 public boolean isInMultiWindowMode(IBinder token) {
3445 final long origId = Binder.clearCallingIdentity();
3446 try {
3447 synchronized (mGlobalLock) {
3448 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3449 if (r == null) {
3450 return false;
3451 }
3452 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
3453 return r.inMultiWindowMode();
3454 }
3455 } finally {
3456 Binder.restoreCallingIdentity(origId);
3457 }
3458 }
3459
3460 @Override
3461 public boolean isInPictureInPictureMode(IBinder token) {
3462 final long origId = Binder.clearCallingIdentity();
3463 try {
3464 synchronized (mGlobalLock) {
3465 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
3466 }
3467 } finally {
3468 Binder.restoreCallingIdentity(origId);
3469 }
3470 }
3471
3472 private boolean isInPictureInPictureMode(ActivityRecord r) {
3473 if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
3474 || r.getStack().isInStackLocked(r) == null) {
3475 return false;
3476 }
3477
3478 // If we are animating to fullscreen then we have already dispatched the PIP mode
3479 // changed, so we should reflect that check here as well.
3480 final PinnedActivityStack stack = r.getStack();
3481 final PinnedStackWindowController windowController = stack.getWindowContainerController();
3482 return !windowController.isAnimatingBoundsToFullscreen();
3483 }
3484
3485 @Override
3486 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
3487 final long origId = Binder.clearCallingIdentity();
3488 try {
3489 synchronized (mGlobalLock) {
3490 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3491 "enterPictureInPictureMode", token, params);
3492
3493 // If the activity is already in picture in picture mode, then just return early
3494 if (isInPictureInPictureMode(r)) {
3495 return true;
3496 }
3497
3498 // Activity supports picture-in-picture, now check that we can enter PiP at this
3499 // point, if it is
3500 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
3501 false /* beforeStopping */)) {
3502 return false;
3503 }
3504
3505 final Runnable enterPipRunnable = () -> {
Wale Ogunwalef276a6f2018-06-15 08:26:07 -07003506 synchronized (mGlobalLock) {
3507 // Only update the saved args from the args that are set
3508 r.pictureInPictureArgs.copyOnlySet(params);
3509 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
3510 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
3511 // Adjust the source bounds by the insets for the transition down
3512 final Rect sourceBounds = new Rect(
3513 r.pictureInPictureArgs.getSourceRectHint());
3514 mStackSupervisor.moveActivityToPinnedStackLocked(
3515 r, sourceBounds, aspectRatio, "enterPictureInPictureMode");
3516 final PinnedActivityStack stack = r.getStack();
3517 stack.setPictureInPictureAspectRatio(aspectRatio);
3518 stack.setPictureInPictureActions(actions);
3519 MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
3520 r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
3521 logPictureInPictureArgs(params);
3522 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003523 };
3524
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003525 if (isKeyguardLocked()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003526 // If the keyguard is showing or occluded, then try and dismiss it before
3527 // entering picture-in-picture (this will prompt the user to authenticate if the
3528 // device is currently locked).
3529 dismissKeyguard(token, new KeyguardDismissCallback() {
3530 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003531 public void onDismissSucceeded() {
3532 mH.post(enterPipRunnable);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003533 }
3534 }, null /* message */);
3535 } else {
3536 // Enter picture in picture immediately otherwise
3537 enterPipRunnable.run();
3538 }
3539 return true;
3540 }
3541 } finally {
3542 Binder.restoreCallingIdentity(origId);
3543 }
3544 }
3545
3546 @Override
3547 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
3548 final long origId = Binder.clearCallingIdentity();
3549 try {
3550 synchronized (mGlobalLock) {
3551 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3552 "setPictureInPictureParams", token, params);
3553
3554 // Only update the saved args from the args that are set
3555 r.pictureInPictureArgs.copyOnlySet(params);
3556 if (r.inPinnedWindowingMode()) {
3557 // If the activity is already in picture-in-picture, update the pinned stack now
3558 // if it is not already expanding to fullscreen. Otherwise, the arguments will
3559 // be used the next time the activity enters PiP
3560 final PinnedActivityStack stack = r.getStack();
3561 if (!stack.isAnimatingBoundsToFullscreen()) {
3562 stack.setPictureInPictureAspectRatio(
3563 r.pictureInPictureArgs.getAspectRatio());
3564 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
3565 }
3566 }
3567 logPictureInPictureArgs(params);
3568 }
3569 } finally {
3570 Binder.restoreCallingIdentity(origId);
3571 }
3572 }
3573
3574 @Override
3575 public int getMaxNumPictureInPictureActions(IBinder token) {
3576 // Currently, this is a static constant, but later, we may change this to be dependent on
3577 // the context of the activity
3578 return 3;
3579 }
3580
3581 private void logPictureInPictureArgs(PictureInPictureParams params) {
3582 if (params.hasSetActions()) {
3583 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
3584 params.getActions().size());
3585 }
3586 if (params.hasSetAspectRatio()) {
3587 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
3588 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
3589 MetricsLogger.action(lm);
3590 }
3591 }
3592
3593 /**
3594 * Checks the state of the system and the activity associated with the given {@param token} to
3595 * verify that picture-in-picture is supported for that activity.
3596 *
3597 * @return the activity record for the given {@param token} if all the checks pass.
3598 */
3599 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
3600 IBinder token, PictureInPictureParams params) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003601 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003602 throw new IllegalStateException(caller
3603 + ": Device doesn't support picture-in-picture mode.");
3604 }
3605
3606 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3607 if (r == null) {
3608 throw new IllegalStateException(caller
3609 + ": Can't find activity for token=" + token);
3610 }
3611
3612 if (!r.supportsPictureInPicture()) {
3613 throw new IllegalStateException(caller
3614 + ": Current activity does not support picture-in-picture.");
3615 }
3616
3617 if (params.hasSetAspectRatio()
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003618 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003619 params.getAspectRatio())) {
3620 final float minAspectRatio = mContext.getResources().getFloat(
3621 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
3622 final float maxAspectRatio = mContext.getResources().getFloat(
3623 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
3624 throw new IllegalArgumentException(String.format(caller
3625 + ": Aspect ratio is too extreme (must be between %f and %f).",
3626 minAspectRatio, maxAspectRatio));
3627 }
3628
3629 // Truncate the number of actions if necessary
3630 params.truncateActions(getMaxNumPictureInPictureActions(token));
3631
3632 return r;
3633 }
3634
3635 @Override
3636 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003637 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003638 synchronized (mGlobalLock) {
3639 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
3640 if (r == null) {
3641 throw new IllegalArgumentException("Activity does not exist; token="
3642 + activityToken);
3643 }
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07003644 return r.getUriPermissionsLocked().getExternalToken();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003645 }
3646 }
3647
3648 @Override
3649 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
3650 Rect tempDockedTaskInsetBounds,
3651 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003652 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003653 long ident = Binder.clearCallingIdentity();
3654 try {
3655 synchronized (mGlobalLock) {
3656 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
3657 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
3658 PRESERVE_WINDOWS);
3659 }
3660 } finally {
3661 Binder.restoreCallingIdentity(ident);
3662 }
3663 }
3664
3665 @Override
3666 public void setSplitScreenResizing(boolean resizing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003667 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003668 final long ident = Binder.clearCallingIdentity();
3669 try {
3670 synchronized (mGlobalLock) {
3671 mStackSupervisor.setSplitScreenResizing(resizing);
3672 }
3673 } finally {
3674 Binder.restoreCallingIdentity(ident);
3675 }
3676 }
3677
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003678 /**
3679 * Check that we have the features required for VR-related API calls, and throw an exception if
3680 * not.
3681 */
3682 void enforceSystemHasVrFeature() {
3683 if (!mContext.getPackageManager().hasSystemFeature(
3684 PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
3685 throw new UnsupportedOperationException("VR mode not supported on this device!");
3686 }
3687 }
3688
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003689 @Override
3690 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003691 enforceSystemHasVrFeature();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003692
3693 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3694
3695 ActivityRecord r;
3696 synchronized (mGlobalLock) {
3697 r = ActivityRecord.isInStackLocked(token);
3698 }
3699
3700 if (r == null) {
3701 throw new IllegalArgumentException();
3702 }
3703
3704 int err;
3705 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
3706 VrManagerInternal.NO_ERROR) {
3707 return err;
3708 }
3709
3710 // Clear the binder calling uid since this path may call moveToTask().
3711 final long callingId = Binder.clearCallingIdentity();
3712 try {
3713 synchronized (mGlobalLock) {
3714 r.requestedVrComponent = (enabled) ? packageName : null;
3715
3716 // Update associated state if this activity is currently focused
Andrii Kulian52d255c2018-07-13 11:32:19 -07003717 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003718 applyUpdateVrModeLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003719 }
3720 return 0;
3721 }
3722 } finally {
3723 Binder.restoreCallingIdentity(callingId);
3724 }
3725 }
3726
3727 @Override
3728 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
3729 Slog.i(TAG, "Activity tried to startLocalVoiceInteraction");
3730 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003731 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003732 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
3733 throw new SecurityException("Only focused activity can call startVoiceInteraction");
3734 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07003735 if (mRunningVoice != null || activity.getTask().voiceSession != null
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003736 || activity.voiceSession != null) {
3737 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
3738 return;
3739 }
3740 if (activity.pendingVoiceInteractionStart) {
3741 Slog.w(TAG, "Pending start of voice interaction already.");
3742 return;
3743 }
3744 activity.pendingVoiceInteractionStart = true;
3745 }
3746 LocalServices.getService(VoiceInteractionManagerInternal.class)
3747 .startLocalVoiceInteraction(callingActivity, options);
3748 }
3749
3750 @Override
3751 public void stopLocalVoiceInteraction(IBinder callingActivity) {
3752 LocalServices.getService(VoiceInteractionManagerInternal.class)
3753 .stopLocalVoiceInteraction(callingActivity);
3754 }
3755
3756 @Override
3757 public boolean supportsLocalVoiceInteraction() {
3758 return LocalServices.getService(VoiceInteractionManagerInternal.class)
3759 .supportsLocalVoiceInteraction();
3760 }
3761
3762 /** Notifies all listeners when the pinned stack animation starts. */
3763 @Override
3764 public void notifyPinnedStackAnimationStarted() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003765 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003766 }
3767
3768 /** Notifies all listeners when the pinned stack animation ends. */
3769 @Override
3770 public void notifyPinnedStackAnimationEnded() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003771 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003772 }
3773
3774 @Override
3775 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003776 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003777 final long ident = Binder.clearCallingIdentity();
3778 try {
3779 synchronized (mGlobalLock) {
3780 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
3781 }
3782 } finally {
3783 Binder.restoreCallingIdentity(ident);
3784 }
3785 }
3786
3787 @Override
3788 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003789 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003790
3791 synchronized (mGlobalLock) {
3792 // Check if display is initialized in AM.
3793 if (!mStackSupervisor.isDisplayAdded(displayId)) {
3794 // Call might come when display is not yet added or has already been removed.
3795 if (DEBUG_CONFIGURATION) {
3796 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
3797 + displayId);
3798 }
3799 return false;
3800 }
3801
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003802 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003803 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003804 values = mWindowManager.computeNewConfiguration(displayId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003805 }
3806
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003807 if (mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003808 // Update OOM levels based on display size.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003809 mAm.mProcessList.applyDisplaySize(mWindowManager);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003810 }
3811
3812 final long origId = Binder.clearCallingIdentity();
3813 try {
3814 if (values != null) {
3815 Settings.System.clearConfiguration(values);
3816 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003817 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003818 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
3819 return mTmpUpdateConfigurationResult.changes != 0;
3820 } finally {
3821 Binder.restoreCallingIdentity(origId);
3822 }
3823 }
3824 }
3825
3826 @Override
3827 public boolean updateConfiguration(Configuration values) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003828 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003829
3830 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003831 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003832 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003833 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003834 }
3835
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003836 if (mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003837 // Update OOM levels based on display size.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003838 mAm.mProcessList.applyDisplaySize(mWindowManager);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003839 }
3840
3841 final long origId = Binder.clearCallingIdentity();
3842 try {
3843 if (values != null) {
3844 Settings.System.clearConfiguration(values);
3845 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003846 updateConfigurationLocked(values, null, false, false /* persistent */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003847 UserHandle.USER_NULL, false /* deferResume */,
3848 mTmpUpdateConfigurationResult);
3849 return mTmpUpdateConfigurationResult.changes != 0;
3850 } finally {
3851 Binder.restoreCallingIdentity(origId);
3852 }
3853 }
3854 }
3855
3856 @Override
3857 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
3858 CharSequence message) {
3859 if (message != null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003860 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003861 Manifest.permission.SHOW_KEYGUARD_MESSAGE, "dismissKeyguard()");
3862 }
3863 final long callingId = Binder.clearCallingIdentity();
3864 try {
3865 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003866 mKeyguardController.dismissKeyguard(token, callback, message);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003867 }
3868 } finally {
3869 Binder.restoreCallingIdentity(callingId);
3870 }
3871 }
3872
3873 @Override
3874 public void cancelTaskWindowTransition(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003875 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003876 "cancelTaskWindowTransition()");
3877 final long ident = Binder.clearCallingIdentity();
3878 try {
3879 synchronized (mGlobalLock) {
3880 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
3881 MATCH_TASK_IN_STACKS_ONLY);
3882 if (task == null) {
3883 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
3884 return;
3885 }
3886 task.cancelWindowTransition();
3887 }
3888 } finally {
3889 Binder.restoreCallingIdentity(ident);
3890 }
3891 }
3892
3893 @Override
3894 public ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003895 enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003896 final long ident = Binder.clearCallingIdentity();
3897 try {
3898 final TaskRecord task;
3899 synchronized (mGlobalLock) {
3900 task = mStackSupervisor.anyTaskForIdLocked(taskId,
3901 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
3902 if (task == null) {
3903 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
3904 return null;
3905 }
3906 }
3907 // Don't call this while holding the lock as this operation might hit the disk.
3908 return task.getSnapshot(reducedResolution);
3909 } finally {
3910 Binder.restoreCallingIdentity(ident);
3911 }
3912 }
3913
3914 @Override
3915 public void setDisablePreviewScreenshots(IBinder token, boolean disable) {
3916 synchronized (mGlobalLock) {
3917 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3918 if (r == null) {
3919 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
3920 + token);
3921 return;
3922 }
3923 final long origId = Binder.clearCallingIdentity();
3924 try {
3925 r.setDisablePreviewScreenshots(disable);
3926 } finally {
3927 Binder.restoreCallingIdentity(origId);
3928 }
3929 }
3930 }
3931
3932 /** Return the user id of the last resumed activity. */
3933 @Override
3934 public @UserIdInt
3935 int getLastResumedActivityUserId() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003936 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003937 Manifest.permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
3938 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07003939 if (mLastResumedActivity == null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003940 return getCurrentUserId();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003941 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07003942 return mLastResumedActivity.userId;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003943 }
3944 }
3945
3946 @Override
3947 public void updateLockTaskFeatures(int userId, int flags) {
3948 final int callingUid = Binder.getCallingUid();
3949 if (callingUid != 0 && callingUid != SYSTEM_UID) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003950 mAmInternal.enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003951 "updateLockTaskFeatures()");
3952 }
3953 synchronized (mGlobalLock) {
3954 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
3955 Integer.toHexString(flags));
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003956 getLockTaskController().updateLockTaskFeatures(userId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003957 }
3958 }
3959
3960 @Override
3961 public void setShowWhenLocked(IBinder token, boolean showWhenLocked) {
3962 synchronized (mGlobalLock) {
3963 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3964 if (r == null) {
3965 return;
3966 }
3967 final long origId = Binder.clearCallingIdentity();
3968 try {
3969 r.setShowWhenLocked(showWhenLocked);
3970 } finally {
3971 Binder.restoreCallingIdentity(origId);
3972 }
3973 }
3974 }
3975
3976 @Override
3977 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) {
3978 synchronized (mGlobalLock) {
3979 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3980 if (r == null) {
3981 return;
3982 }
3983 final long origId = Binder.clearCallingIdentity();
3984 try {
3985 r.setTurnScreenOn(turnScreenOn);
3986 } finally {
3987 Binder.restoreCallingIdentity(origId);
3988 }
3989 }
3990 }
3991
3992 @Override
3993 public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003994 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003995 "registerRemoteAnimations");
3996 definition.setCallingPid(Binder.getCallingPid());
3997 synchronized (mGlobalLock) {
3998 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3999 if (r == null) {
4000 return;
4001 }
4002 final long origId = Binder.clearCallingIdentity();
4003 try {
4004 r.registerRemoteAnimations(definition);
4005 } finally {
4006 Binder.restoreCallingIdentity(origId);
4007 }
4008 }
4009 }
4010
4011 @Override
4012 public void registerRemoteAnimationForNextActivityStart(String packageName,
4013 RemoteAnimationAdapter adapter) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004014 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004015 "registerRemoteAnimationForNextActivityStart");
4016 adapter.setCallingPid(Binder.getCallingPid());
4017 synchronized (mGlobalLock) {
4018 final long origId = Binder.clearCallingIdentity();
4019 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07004020 getActivityStartController().registerRemoteAnimationForNextActivityStart(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004021 packageName, adapter);
4022 } finally {
4023 Binder.restoreCallingIdentity(origId);
4024 }
4025 }
4026 }
4027
4028 /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
4029 @Override
4030 public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
4031 synchronized (mGlobalLock) {
4032 final long origId = Binder.clearCallingIdentity();
4033 try {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004034 mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004035 } finally {
4036 Binder.restoreCallingIdentity(origId);
4037 }
4038 }
4039 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004040
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004041 @Override
4042 public void setVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004043 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004044 synchronized (mGlobalLock) {
4045 synchronized (mAm.mPidsSelfLocked) {
4046 final int pid = Binder.getCallingPid();
4047 final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004048 mVrController.setVrThreadLocked(tid, pid, proc.getWindowProcessController());
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004049 }
4050 }
4051 }
4052
4053 @Override
4054 public void setPersistentVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004055 if (checkCallingPermission(Manifest.permission.RESTRICTED_VR_ACCESS)
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004056 != PERMISSION_GRANTED) {
4057 final String msg = "Permission Denial: setPersistentVrThread() from pid="
4058 + Binder.getCallingPid()
4059 + ", uid=" + Binder.getCallingUid()
4060 + " requires " + Manifest.permission.RESTRICTED_VR_ACCESS;
4061 Slog.w(TAG, msg);
4062 throw new SecurityException(msg);
4063 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004064 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004065 synchronized (mGlobalLock) {
4066 synchronized (mAm.mPidsSelfLocked) {
4067 final int pid = Binder.getCallingPid();
4068 final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
4069 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
4070 }
4071 }
4072 }
4073
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004074 @Override
4075 public void stopAppSwitches() {
4076 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
4077 synchronized (mGlobalLock) {
4078 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME;
4079 mDidAppSwitch = false;
4080 getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
4081 }
4082 }
4083
4084 @Override
4085 public void resumeAppSwitches() {
4086 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
4087 synchronized (mGlobalLock) {
4088 // Note that we don't execute any pending app switches... we will
4089 // let those wait until either the timeout, or the next start
4090 // activity request.
4091 mAppSwitchesAllowedTime = 0;
4092 }
4093 }
4094
4095 void onStartActivitySetDidAppSwitch() {
4096 if (mDidAppSwitch) {
4097 // This is the second allowed switch since we stopped switches, so now just generally
4098 // allow switches. Use case:
4099 // - user presses home (switches disabled, switch to home, mDidAppSwitch now true);
4100 // - user taps a home icon (coming from home so allowed, we hit here and now allow
4101 // anyone to switch again).
4102 mAppSwitchesAllowedTime = 0;
4103 } else {
4104 mDidAppSwitch = true;
4105 }
4106 }
4107
4108 /** @return whether the system should disable UI modes incompatible with VR mode. */
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004109 boolean shouldDisableNonVrUiLocked() {
4110 return mVrController.shouldDisableNonVrUiLocked();
4111 }
4112
4113 void applyUpdateVrModeLocked(ActivityRecord r) {
4114 // VR apps are expected to run in a main display. If an app is turning on VR for
4115 // itself, but lives in a dynamic stack, then make sure that it is moved to the main
4116 // fullscreen stack before enabling VR Mode.
4117 // TODO: The goal of this code is to keep the VR app on the main display. When the
4118 // stack implementation changes in the future, keep in mind that the use of the fullscreen
4119 // stack is a means to move the activity to the main display and a moveActivityToDisplay()
4120 // option would be a better choice here.
4121 if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
4122 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
4123 + " to main stack for VR");
4124 final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
4125 WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
4126 moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
4127 }
4128 mH.post(() -> {
4129 if (!mVrController.onVrModeChanged(r)) {
4130 return;
4131 }
4132 synchronized (mGlobalLock) {
4133 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
4134 mWindowManager.disableNonVrUi(disableNonVrUi);
4135 if (disableNonVrUi) {
4136 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
4137 // then remove the pinned stack.
4138 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
4139 }
4140 }
4141 });
4142 }
4143
Andrii Kulian5f750bc2018-07-17 08:57:23 -07004144 ActivityStack getTopDisplayFocusedStack() {
4145 return mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004146 }
4147
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004148 /** Pokes the task persister. */
4149 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
4150 mRecentTasks.notifyTaskPersisterLocked(task, flush);
4151 }
4152
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004153 void onTopProcChangedLocked(WindowProcessController proc) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004154 mVrController.onTopProcChangedLocked(proc);
4155 }
4156
4157 boolean isKeyguardLocked() {
4158 return mKeyguardController.isKeyguardLocked();
4159 }
4160
4161 boolean isNextTransitionForward() {
4162 int transit = mWindowManager.getPendingAppTransition();
4163 return transit == TRANSIT_ACTIVITY_OPEN
4164 || transit == TRANSIT_TASK_OPEN
4165 || transit == TRANSIT_TASK_TO_FRONT;
4166 }
4167
Wale Ogunwalef6733932018-06-27 05:14:34 -07004168 void dumpSleepStates(PrintWriter pw, boolean testPssMode) {
4169 synchronized (mGlobalLock) {
4170 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
4171 if (mRunningVoice != null) {
4172 pw.println(" mRunningVoice=" + mRunningVoice);
4173 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
4174 }
4175 pw.println(" mSleeping=" + mSleeping);
4176 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + testPssMode);
4177 pw.println(" mVrController=" + mVrController);
4178 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004179 }
4180
Wale Ogunwalef6733932018-06-27 05:14:34 -07004181 void writeSleepStateToProto(ProtoOutputStream proto) {
4182 for (ActivityTaskManagerInternal.SleepToken st : mStackSupervisor.mSleepTokens) {
4183 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS,
4184 st.toString());
4185 }
4186
4187 if (mRunningVoice != null) {
4188 final long vrToken = proto.start(
4189 ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
4190 proto.write(ActivityManagerServiceDumpProcessesProto.Voice.SESSION,
4191 mRunningVoice.toString());
4192 mVoiceWakeLock.writeToProto(
4193 proto, ActivityManagerServiceDumpProcessesProto.Voice.WAKELOCK);
4194 proto.end(vrToken);
4195 }
4196
4197 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
4198 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN,
4199 mShuttingDown);
4200 mVrController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004201 }
4202
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004203 int getCurrentUserId() {
4204 return mAmInternal.getCurrentUserId();
4205 }
4206
4207 private void enforceNotIsolatedCaller(String caller) {
4208 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4209 throw new SecurityException("Isolated process not allowed to call " + caller);
4210 }
4211 }
4212
Wale Ogunwalef6733932018-06-27 05:14:34 -07004213 public Configuration getConfiguration() {
4214 Configuration ci;
4215 synchronized(mGlobalLock) {
4216 ci = new Configuration(getGlobalConfiguration());
4217 ci.userSetLocale = false;
4218 }
4219 return ci;
4220 }
4221
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004222 /**
4223 * Current global configuration information. Contains general settings for the entire system,
4224 * also corresponds to the merged configuration of the default display.
4225 */
4226 Configuration getGlobalConfiguration() {
4227 return mStackSupervisor.getConfiguration();
4228 }
4229
4230 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4231 boolean initLocale) {
4232 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
4233 }
4234
4235 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4236 boolean initLocale, boolean deferResume) {
4237 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
4238 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
4239 UserHandle.USER_NULL, deferResume);
4240 }
4241
4242 void updatePersistentConfiguration(Configuration values, @UserIdInt int userId) {
4243 final long origId = Binder.clearCallingIdentity();
4244 try {
4245 synchronized (mGlobalLock) {
4246 updateConfigurationLocked(values, null, false, true, userId,
4247 false /* deferResume */);
4248 }
4249 } finally {
4250 Binder.restoreCallingIdentity(origId);
4251 }
4252 }
4253
4254 void updateUserConfiguration() {
4255 synchronized (mGlobalLock) {
4256 final Configuration configuration = new Configuration(getGlobalConfiguration());
4257 final int currentUserId = mAmInternal.getCurrentUserId();
4258 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
4259 currentUserId, Settings.System.canWrite(mContext));
4260 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
4261 false /* persistent */, currentUserId, false /* deferResume */);
4262 }
4263 }
4264
4265 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4266 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
4267 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
4268 deferResume, null /* result */);
4269 }
4270
4271 /**
4272 * Do either or both things: (1) change the current configuration, and (2)
4273 * make sure the given activity is running with the (now) current
4274 * configuration. Returns true if the activity has been left running, or
4275 * false if <var>starting</var> is being destroyed to match the new
4276 * configuration.
4277 *
4278 * @param userId is only used when persistent parameter is set to true to persist configuration
4279 * for that particular user
4280 */
4281 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4282 boolean initLocale, boolean persistent, int userId, boolean deferResume,
4283 ActivityTaskManagerService.UpdateConfigurationResult result) {
4284 int changes = 0;
4285 boolean kept = true;
4286
4287 if (mWindowManager != null) {
4288 mWindowManager.deferSurfaceLayout();
4289 }
4290 try {
4291 if (values != null) {
4292 changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
4293 deferResume);
4294 }
4295
4296 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4297 } finally {
4298 if (mWindowManager != null) {
4299 mWindowManager.continueSurfaceLayout();
4300 }
4301 }
4302
4303 if (result != null) {
4304 result.changes = changes;
4305 result.activityRelaunched = !kept;
4306 }
4307 return kept;
4308 }
4309
4310 /**
4311 * Returns true if this configuration change is interesting enough to send an
4312 * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
4313 */
4314 private static boolean isSplitConfigurationChange(int configDiff) {
4315 return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
4316 }
4317
4318 /** Update default (global) configuration and notify listeners about changes. */
4319 private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
4320 boolean persistent, int userId, boolean deferResume) {
4321 mTempConfig.setTo(getGlobalConfiguration());
4322 final int changes = mTempConfig.updateFrom(values);
4323 if (changes == 0) {
4324 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
4325 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
4326 // performDisplayOverrideConfigUpdate in order to send the new display configuration
4327 // (even if there are no actual changes) to unfreeze the window.
4328 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
4329 return 0;
4330 }
4331
4332 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
4333 "Updating global configuration to: " + values);
4334
4335 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
4336 StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
4337 values.colorMode,
4338 values.densityDpi,
4339 values.fontScale,
4340 values.hardKeyboardHidden,
4341 values.keyboard,
4342 values.keyboardHidden,
4343 values.mcc,
4344 values.mnc,
4345 values.navigation,
4346 values.navigationHidden,
4347 values.orientation,
4348 values.screenHeightDp,
4349 values.screenLayout,
4350 values.screenWidthDp,
4351 values.smallestScreenWidthDp,
4352 values.touchscreen,
4353 values.uiMode);
4354
4355
4356 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
4357 final LocaleList locales = values.getLocales();
4358 int bestLocaleIndex = 0;
4359 if (locales.size() > 1) {
4360 if (mSupportedSystemLocales == null) {
4361 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
4362 }
4363 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
4364 }
4365 SystemProperties.set("persist.sys.locale",
4366 locales.get(bestLocaleIndex).toLanguageTag());
4367 LocaleList.setDefault(locales, bestLocaleIndex);
4368 mAm.mHandler.sendMessage(mAm.mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
4369 locales.get(bestLocaleIndex)));
4370 }
4371
4372 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
4373 mTempConfig.seq = mConfigurationSeq;
4374
4375 // Update stored global config and notify everyone about the change.
4376 mStackSupervisor.onConfigurationChanged(mTempConfig);
4377
4378 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
4379 // TODO(multi-display): Update UsageEvents#Event to include displayId.
4380 mAm.mUsageStatsService.reportConfigurationChange(
4381 mTempConfig, mAmInternal.getCurrentUserId());
4382
4383 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
Wale Ogunwalef6733932018-06-27 05:14:34 -07004384 updateShouldShowDialogsLocked(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004385
4386 AttributeCache ac = AttributeCache.instance();
4387 if (ac != null) {
4388 ac.updateConfiguration(mTempConfig);
4389 }
4390
4391 // Make sure all resources in our process are updated right now, so that anyone who is going
4392 // to retrieve resource values after we return will be sure to get the new ones. This is
4393 // especially important during boot, where the first config change needs to guarantee all
4394 // resources have that config before following boot code is executed.
4395 mAm.mSystemThread.applyConfigurationToResources(mTempConfig);
4396
4397 // We need another copy of global config because we're scheduling some calls instead of
4398 // running them in place. We need to be sure that object we send will be handled unchanged.
4399 final Configuration configCopy = new Configuration(mTempConfig);
4400 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
4401 Message msg = mAm.mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
4402 msg.obj = configCopy;
4403 msg.arg1 = userId;
4404 mAm.mHandler.sendMessage(msg);
4405 }
4406
4407 for (int i = mAm.mLruProcesses.size() - 1; i >= 0; i--) {
4408 ProcessRecord app = mAm.mLruProcesses.get(i);
4409 try {
4410 if (app.thread != null) {
4411 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
4412 + app.processName + " new config " + configCopy);
4413 getLifecycleManager().scheduleTransaction(app.thread,
4414 ConfigurationChangeItem.obtain(configCopy));
4415 }
4416 } catch (Exception e) {
4417 Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
4418 }
4419 }
4420
4421 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
4422 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
4423 | Intent.FLAG_RECEIVER_FOREGROUND
4424 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4425 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4426 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4427 UserHandle.USER_ALL);
4428 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
4429 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
4430 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
4431 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
4432 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4433 if (initLocale || !mAm.mProcessesReady) {
4434 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
4435 }
4436 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4437 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4438 UserHandle.USER_ALL);
4439 }
4440
4441 // Send a broadcast to PackageInstallers if the configuration change is interesting
4442 // for the purposes of installing additional splits.
4443 if (!initLocale && isSplitConfigurationChange(changes)) {
4444 intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
4445 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
4446 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
4447
4448 // Typically only app stores will have this permission.
4449 String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES };
4450 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions,
4451 OP_NONE, null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
4452 }
4453
4454 // Override configuration of the default display duplicates global config, so we need to
4455 // update it also. This will also notify WindowManager about changes.
4456 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
4457 DEFAULT_DISPLAY);
4458
4459 return changes;
4460 }
4461
4462 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
4463 boolean deferResume, int displayId) {
4464 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
4465 displayId, null /* result */);
4466 }
4467
4468 /**
4469 * Updates override configuration specific for the selected display. If no config is provided,
4470 * new one will be computed in WM based on current display info.
4471 */
4472 boolean updateDisplayOverrideConfigurationLocked(Configuration values,
4473 ActivityRecord starting, boolean deferResume, int displayId,
4474 ActivityTaskManagerService.UpdateConfigurationResult result) {
4475 int changes = 0;
4476 boolean kept = true;
4477
4478 if (mWindowManager != null) {
4479 mWindowManager.deferSurfaceLayout();
4480 }
4481 try {
4482 if (values != null) {
4483 if (displayId == DEFAULT_DISPLAY) {
4484 // Override configuration of the default display duplicates global config, so
4485 // we're calling global config update instead for default display. It will also
4486 // apply the correct override config.
4487 changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
4488 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
4489 } else {
4490 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
4491 }
4492 }
4493
4494 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4495 } finally {
4496 if (mWindowManager != null) {
4497 mWindowManager.continueSurfaceLayout();
4498 }
4499 }
4500
4501 if (result != null) {
4502 result.changes = changes;
4503 result.activityRelaunched = !kept;
4504 }
4505 return kept;
4506 }
4507
4508 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
4509 int displayId) {
4510 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
4511 final int changes = mTempConfig.updateFrom(values);
4512 if (changes != 0) {
4513 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
4514 + mTempConfig + " for displayId=" + displayId);
4515 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
4516
4517 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
4518 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004519 mAppWarnings.onDensityChanged();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004520
4521 mAm.killAllBackgroundProcessesExcept(N,
4522 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
4523 }
4524 }
4525
4526 // Update the configuration with WM first and check if any of the stacks need to be resized
4527 // due to the configuration change. If so, resize the stacks now and do any relaunches if
4528 // necessary. This way we don't need to relaunch again afterwards in
4529 // ensureActivityConfiguration().
4530 if (mWindowManager != null) {
4531 final int[] resizedStacks =
4532 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
4533 if (resizedStacks != null) {
4534 for (int stackId : resizedStacks) {
4535 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
4536 }
4537 }
4538 }
4539
4540 return changes;
4541 }
4542
Wale Ogunwalef6733932018-06-27 05:14:34 -07004543 private void updateEventDispatchingLocked(boolean booted) {
4544 mWindowManager.setEventDispatching(booted && !mShuttingDown);
4545 }
4546
4547 void enableScreenAfterBoot(boolean booted) {
4548 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4549 SystemClock.uptimeMillis());
4550 mWindowManager.enableScreenAfterBoot();
4551
4552 synchronized (mGlobalLock) {
4553 updateEventDispatchingLocked(booted);
4554 }
4555 }
4556
4557 boolean canShowErrorDialogs() {
4558 return mShowDialogs && !mSleeping && !mShuttingDown
4559 && !mKeyguardController.isKeyguardOrAodShowing(DEFAULT_DISPLAY)
4560 && !hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
Wale Ogunwale86b74462018-07-02 08:42:43 -07004561 mAmInternal.getCurrentUserId())
Wale Ogunwalef6733932018-06-27 05:14:34 -07004562 && !(UserManager.isDeviceInDemoMode(mContext)
Wale Ogunwale86b74462018-07-02 08:42:43 -07004563 && mAmInternal.getCurrentUser().isDemo());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004564 }
4565
Wale Ogunwale906f9c62018-07-23 11:23:44 -07004566 static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
4567 if (r == null || !r.hasProcess()) {
4568 return KEY_DISPATCHING_TIMEOUT_MS;
4569 }
4570 return getInputDispatchingTimeoutLocked(r.app);
4571 }
4572
4573 private static long getInputDispatchingTimeoutLocked(WindowProcessController r) {
4574 if (r != null && (r.isInstrumenting() || r.isUsingWrapper())) {
4575 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS;
4576 }
4577 return KEY_DISPATCHING_TIMEOUT_MS;
4578 }
4579
4580 long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
4581 if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
4582 throw new SecurityException("Requires permission " + FILTER_EVENTS);
4583 }
4584 WindowProcessController proc;
4585 long timeout;
4586 synchronized (mGlobalLock) {
4587 proc = mPidMap.get(pid);
4588 timeout = getInputDispatchingTimeoutLocked(proc);
4589 }
4590
4591 if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
4592 return -1;
4593 }
4594
4595 return timeout;
4596 }
4597
4598 /**
4599 * Handle input dispatching timeouts.
4600 * Returns whether input dispatching should be aborted or not.
4601 */
4602 boolean inputDispatchingTimedOut(final WindowProcessController proc,
4603 final ActivityRecord activity, final ActivityRecord parent,
4604 final boolean aboveSystem, String reason) {
4605 if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
4606 throw new SecurityException("Requires permission " + FILTER_EVENTS);
4607 }
4608
4609 final String annotation;
4610 if (reason == null) {
4611 annotation = "Input dispatching timed out";
4612 } else {
4613 annotation = "Input dispatching timed out (" + reason + ")";
4614 }
4615
4616 if (proc != null) {
4617 synchronized (mGlobalLock) {
4618 if (proc.isDebugging()) {
4619 return false;
4620 }
4621
4622 if (proc.isInstrumenting()) {
4623 Bundle info = new Bundle();
4624 info.putString("shortMsg", "keyDispatchingTimedOut");
4625 info.putString("longMsg", annotation);
4626 mAm.finishInstrumentationLocked(
4627 (ProcessRecord) proc.mOwner, Activity.RESULT_CANCELED, info);
4628 return true;
4629 }
4630 }
4631 mH.post(() -> {
4632 mAm.mAppErrors.appNotResponding(
4633 (ProcessRecord) proc.mOwner, activity, parent, aboveSystem, annotation);
4634 });
4635 }
4636
4637 return true;
4638 }
4639
Wale Ogunwalef6733932018-06-27 05:14:34 -07004640 /**
4641 * Decide based on the configuration whether we should show the ANR,
4642 * crash, etc dialogs. The idea is that if there is no affordance to
4643 * press the on-screen buttons, or the user experience would be more
4644 * greatly impacted than the crash itself, we shouldn't show the dialog.
4645 *
4646 * A thought: SystemUI might also want to get told about this, the Power
4647 * dialog / global actions also might want different behaviors.
4648 */
4649 private void updateShouldShowDialogsLocked(Configuration config) {
4650 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
4651 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
4652 && config.navigation == Configuration.NAVIGATION_NONAV);
4653 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
4654 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
4655 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
4656 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
4657 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
4658 final boolean hideDialogsSet = Settings.Global.getInt(mContext.getContentResolver(),
4659 HIDE_ERROR_DIALOGS, 0) != 0;
4660 mShowDialogs = inputMethodExists && uiModeSupportsDialogs && !hideDialogsSet;
4661 }
4662
4663 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
4664 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
4665 FONT_SCALE, 1.0f, userId);
4666
4667 synchronized (this) {
4668 if (getGlobalConfiguration().fontScale == scaleFactor) {
4669 return;
4670 }
4671
4672 final Configuration configuration
4673 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
4674 configuration.fontScale = scaleFactor;
4675 updatePersistentConfiguration(configuration, userId);
4676 }
4677 }
4678
4679 // Actually is sleeping or shutting down or whatever else in the future
4680 // is an inactive state.
4681 boolean isSleepingOrShuttingDownLocked() {
4682 return isSleepingLocked() || mShuttingDown;
4683 }
4684
4685 boolean isSleepingLocked() {
4686 return mSleeping;
4687 }
4688
4689 /**
4690 * Update AMS states when an activity is resumed. This should only be called by
4691 * {@link ActivityStack#onActivityStateChanged(
4692 * ActivityRecord, ActivityStack.ActivityState, String)} when an activity is resumed.
4693 */
4694 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
4695 final TaskRecord task = r.getTask();
4696 if (task.isActivityTypeStandard()) {
4697 if (mCurAppTimeTracker != r.appTimeTracker) {
4698 // We are switching app tracking. Complete the current one.
4699 if (mCurAppTimeTracker != null) {
4700 mCurAppTimeTracker.stop();
4701 mH.obtainMessage(
4702 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
4703 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
4704 mCurAppTimeTracker = null;
4705 }
4706 if (r.appTimeTracker != null) {
4707 mCurAppTimeTracker = r.appTimeTracker;
4708 startTimeTrackingFocusedActivityLocked();
4709 }
4710 } else {
4711 startTimeTrackingFocusedActivityLocked();
4712 }
4713 } else {
4714 r.appTimeTracker = null;
4715 }
4716 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
4717 // TODO: Probably not, because we don't want to resume voice on switching
4718 // back to this activity
4719 if (task.voiceInteractor != null) {
4720 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
4721 } else {
4722 finishRunningVoiceLocked();
4723
4724 if (mLastResumedActivity != null) {
4725 final IVoiceInteractionSession session;
4726
4727 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
4728 if (lastResumedActivityTask != null
4729 && lastResumedActivityTask.voiceSession != null) {
4730 session = lastResumedActivityTask.voiceSession;
4731 } else {
4732 session = mLastResumedActivity.voiceSession;
4733 }
4734
4735 if (session != null) {
4736 // We had been in a voice interaction session, but now focused has
4737 // move to something different. Just finish the session, we can't
4738 // return to it and retain the proper state and synchronization with
4739 // the voice interaction service.
4740 finishVoiceTask(session);
4741 }
4742 }
4743 }
4744
4745 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
4746 mAmInternal.sendForegroundProfileChanged(r.userId);
4747 }
4748 updateResumedAppTrace(r);
4749 mLastResumedActivity = r;
4750
Andrii Kulianab132ee2018-07-24 22:10:21 +08004751 // TODO(b/111541062): Support multiple focused apps in WM
Wale Ogunwalef6733932018-06-27 05:14:34 -07004752 mWindowManager.setFocusedApp(r.appToken, true);
4753
4754 applyUpdateLockStateLocked(r);
4755 applyUpdateVrModeLocked(r);
4756
4757 EventLogTags.writeAmSetResumedActivity(
4758 r == null ? -1 : r.userId,
4759 r == null ? "NULL" : r.shortComponentName,
4760 reason);
4761 }
4762
4763 ActivityTaskManagerInternal.SleepToken acquireSleepToken(String tag, int displayId) {
4764 synchronized (mGlobalLock) {
4765 final ActivityTaskManagerInternal.SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
4766 updateSleepIfNeededLocked();
4767 return token;
4768 }
4769 }
4770
4771 void updateSleepIfNeededLocked() {
4772 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
4773 final boolean wasSleeping = mSleeping;
4774 boolean updateOomAdj = false;
4775
4776 if (!shouldSleep) {
4777 // If wasSleeping is true, we need to wake up activity manager state from when
4778 // we started sleeping. In either case, we need to apply the sleep tokens, which
4779 // will wake up stacks or put them to sleep as appropriate.
4780 if (wasSleeping) {
4781 mSleeping = false;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07004782 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
4783 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__AWAKE);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004784 startTimeTrackingFocusedActivityLocked();
4785 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
4786 mStackSupervisor.comeOutOfSleepIfNeededLocked();
4787 }
4788 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
4789 if (wasSleeping) {
4790 updateOomAdj = true;
4791 }
4792 } else if (!mSleeping && shouldSleep) {
4793 mSleeping = true;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07004794 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
4795 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__ASLEEP);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004796 if (mCurAppTimeTracker != null) {
4797 mCurAppTimeTracker.stop();
4798 }
4799 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
4800 mStackSupervisor.goingToSleepLocked();
4801 updateResumedAppTrace(null /* resumed */);
4802 updateOomAdj = true;
4803 }
4804 if (updateOomAdj) {
4805 mH.post(mAmInternal::updateOomAdj);
4806 }
4807 }
4808
4809 void updateOomAdj() {
4810 mH.post(mAmInternal::updateOomAdj);
4811 }
4812
Andrii Kulian52d255c2018-07-13 11:32:19 -07004813 // TODO(b/111541062): Update app time tracking to make it aware of multiple resumed activities
Wale Ogunwalef6733932018-06-27 05:14:34 -07004814 private void startTimeTrackingFocusedActivityLocked() {
Andrii Kulian52d255c2018-07-13 11:32:19 -07004815 final ActivityRecord resumedActivity = mStackSupervisor.getTopResumedActivity();
Wale Ogunwalef6733932018-06-27 05:14:34 -07004816 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
4817 mCurAppTimeTracker.start(resumedActivity.packageName);
4818 }
4819 }
4820
4821 private void updateResumedAppTrace(@Nullable ActivityRecord resumed) {
4822 if (mTracedResumedActivity != null) {
4823 Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER,
4824 constructResumedTraceName(mTracedResumedActivity.packageName), 0);
4825 }
4826 if (resumed != null) {
4827 Trace.asyncTraceBegin(TRACE_TAG_ACTIVITY_MANAGER,
4828 constructResumedTraceName(resumed.packageName), 0);
4829 }
4830 mTracedResumedActivity = resumed;
4831 }
4832
4833 private String constructResumedTraceName(String packageName) {
4834 return "focused app: " + packageName;
4835 }
4836
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004837 /** Helper method that requests bounds from WM and applies them to stack. */
4838 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
4839 final Rect newStackBounds = new Rect();
4840 final ActivityStack stack = mStackSupervisor.getStack(stackId);
4841
4842 // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
4843 if (stack == null) {
4844 final StringWriter writer = new StringWriter();
4845 final PrintWriter printWriter = new PrintWriter(writer);
4846 mStackSupervisor.dumpDisplays(printWriter);
4847 printWriter.flush();
4848
4849 Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
4850 }
4851
4852 stack.getBoundsForNewConfiguration(newStackBounds);
4853 mStackSupervisor.resizeStackLocked(
4854 stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
4855 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
4856 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
4857 }
4858
4859 /** Applies latest configuration and/or visibility updates if needed. */
4860 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
4861 boolean kept = true;
Andrii Kulian5f750bc2018-07-17 08:57:23 -07004862 final ActivityStack mainStack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004863 // mainStack is null during startup.
4864 if (mainStack != null) {
4865 if (changes != 0 && starting == null) {
4866 // If the configuration changed, and the caller is not already
4867 // in the process of starting an activity, then find the top
4868 // activity to check if its configuration needs to change.
4869 starting = mainStack.topRunningActivityLocked();
4870 }
4871
4872 if (starting != null) {
4873 kept = starting.ensureActivityConfiguration(changes,
4874 false /* preserveWindow */);
4875 // And we need to make sure at this point that all other activities
4876 // are made visible with the correct configuration.
4877 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
4878 !PRESERVE_WINDOWS);
4879 }
4880 }
4881
4882 return kept;
4883 }
4884
Wale Ogunwale906f9c62018-07-23 11:23:44 -07004885 void scheduleAppGcsLocked() {
4886 mH.post(() -> mAmInternal.scheduleAppGcs());
4887 }
4888
4889 /**
4890 * Returns the PackageManager. Used by classes hosted by {@link ActivityTaskManagerService}. The
4891 * PackageManager could be unavailable at construction time and therefore needs to be accessed
4892 * on demand.
4893 */
4894 IPackageManager getPackageManager() {
4895 return AppGlobals.getPackageManager();
4896 }
4897
4898 PackageManagerInternal getPackageManagerInternalLocked() {
4899 if (mPmInternal == null) {
4900 mPmInternal = LocalServices.getService(PackageManagerInternal.class);
4901 }
4902 return mPmInternal;
4903 }
4904
Wale Ogunwale008163e2018-07-23 23:11:08 -07004905 AppWarnings getAppWarningsLocked() {
4906 return mAppWarnings;
4907 }
4908
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004909 void logAppTooSlow(WindowProcessController app, long startTime, String msg) {
4910 if (true || Build.IS_USER) {
4911 return;
4912 }
4913
4914 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4915 StrictMode.allowThreadDiskWrites();
4916 try {
4917 File tracesDir = new File("/data/anr");
4918 File tracesFile = null;
4919 try {
4920 tracesFile = File.createTempFile("app_slow", null, tracesDir);
4921
4922 StringBuilder sb = new StringBuilder();
4923 Time tobj = new Time();
4924 tobj.set(System.currentTimeMillis());
4925 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4926 sb.append(": ");
4927 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4928 sb.append(" since ");
4929 sb.append(msg);
4930 FileOutputStream fos = new FileOutputStream(tracesFile);
4931 fos.write(sb.toString().getBytes());
4932 if (app == null) {
4933 fos.write("\n*** No application process!".getBytes());
4934 }
4935 fos.close();
4936 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4937 } catch (IOException e) {
4938 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesFile, e);
4939 return;
4940 }
4941
4942 if (app != null && app.getPid() > 0) {
4943 ArrayList<Integer> firstPids = new ArrayList<Integer>();
4944 firstPids.add(app.getPid());
4945 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, null, null);
4946 }
4947
4948 File lastTracesFile = null;
4949 File curTracesFile = null;
4950 for (int i=9; i>=0; i--) {
4951 String name = String.format(Locale.US, "slow%02d.txt", i);
4952 curTracesFile = new File(tracesDir, name);
4953 if (curTracesFile.exists()) {
4954 if (lastTracesFile != null) {
4955 curTracesFile.renameTo(lastTracesFile);
4956 } else {
4957 curTracesFile.delete();
4958 }
4959 }
4960 lastTracesFile = curTracesFile;
4961 }
4962 tracesFile.renameTo(curTracesFile);
4963 } finally {
4964 StrictMode.setThreadPolicy(oldPolicy);
4965 }
4966 }
4967
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004968 final class H extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07004969 static final int REPORT_TIME_TRACKER_MSG = 1;
4970
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004971 public H(Looper looper) {
4972 super(looper, null, true);
4973 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004974
4975 @Override
4976 public void handleMessage(Message msg) {
4977 switch (msg.what) {
4978 case REPORT_TIME_TRACKER_MSG: {
4979 AppTimeTracker tracker = (AppTimeTracker) msg.obj;
4980 tracker.deliverResult(mContext);
4981 } break;
4982 }
4983 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004984 }
4985
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004986 final class UiHandler extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07004987 static final int DISMISS_DIALOG_UI_MSG = 1;
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004988
4989 public UiHandler() {
4990 super(com.android.server.UiThread.get().getLooper(), null, true);
4991 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004992
4993 @Override
4994 public void handleMessage(Message msg) {
4995 switch (msg.what) {
4996 case DISMISS_DIALOG_UI_MSG: {
4997 final Dialog d = (Dialog) msg.obj;
4998 d.dismiss();
4999 break;
5000 }
5001 }
5002 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005003 }
5004
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005005 final class LocalService extends ActivityTaskManagerInternal {
5006 @Override
5007 public SleepToken acquireSleepToken(String tag, int displayId) {
5008 Preconditions.checkNotNull(tag);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005009 return ActivityTaskManagerService.this.acquireSleepToken(tag, displayId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005010 }
5011
5012 @Override
5013 public ComponentName getHomeActivityForUser(int userId) {
5014 synchronized (mGlobalLock) {
5015 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
5016 return homeActivity == null ? null : homeActivity.realActivity;
5017 }
5018 }
5019
5020 @Override
5021 public void onLocalVoiceInteractionStarted(IBinder activity,
5022 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
5023 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005024 onLocalVoiceInteractionStartedLocked(activity, voiceSession, voiceInteractor);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005025 }
5026 }
5027
5028 @Override
5029 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
5030 synchronized (mGlobalLock) {
5031 mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
5032 reasons, timestamp);
5033 }
5034 }
5035
5036 @Override
5037 public void notifyAppTransitionFinished() {
5038 synchronized (mGlobalLock) {
5039 mStackSupervisor.notifyAppTransitionDone();
5040 }
5041 }
5042
5043 @Override
5044 public void notifyAppTransitionCancelled() {
5045 synchronized (mGlobalLock) {
5046 mStackSupervisor.notifyAppTransitionDone();
5047 }
5048 }
5049
5050 @Override
5051 public List<IBinder> getTopVisibleActivities() {
5052 synchronized (mGlobalLock) {
5053 return mStackSupervisor.getTopVisibleActivities();
5054 }
5055 }
5056
5057 @Override
5058 public void notifyDockedStackMinimizedChanged(boolean minimized) {
5059 synchronized (mGlobalLock) {
5060 mStackSupervisor.setDockedStackMinimized(minimized);
5061 }
5062 }
5063
5064 @Override
5065 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
5066 Bundle bOptions) {
5067 Preconditions.checkNotNull(intents, "intents");
5068 final String[] resolvedTypes = new String[intents.length];
5069
5070 // UID of the package on user userId.
5071 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
5072 // packageUid may not be initialized.
5073 int packageUid = 0;
5074 final long ident = Binder.clearCallingIdentity();
5075
5076 try {
5077 for (int i = 0; i < intents.length; i++) {
5078 resolvedTypes[i] =
5079 intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
5080 }
5081
5082 packageUid = AppGlobals.getPackageManager().getPackageUid(
5083 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
5084 } catch (RemoteException e) {
5085 // Shouldn't happen.
5086 } finally {
5087 Binder.restoreCallingIdentity(ident);
5088 }
5089
5090 synchronized (mGlobalLock) {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07005091 return getActivityStartController().startActivitiesInPackage(
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005092 packageUid, packageName,
5093 intents, resolvedTypes, null /* resultTo */,
5094 SafeActivityOptions.fromBundle(bOptions), userId,
5095 false /* validateIncomingUser */);
5096 }
5097 }
5098
5099 @Override
5100 public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
5101 Intent intent, Bundle options, int userId) {
5102 return ActivityTaskManagerService.this.startActivityAsUser(
5103 caller, callerPacakge, intent,
5104 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
5105 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
5106 false /*validateIncomingUser*/);
5107 }
5108
5109 @Override
5110 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
5111 synchronized (mGlobalLock) {
5112
5113 // We might change the visibilities here, so prepare an empty app transition which
5114 // might be overridden later if we actually change visibilities.
5115 final boolean wasTransitionSet =
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005116 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005117 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005118 mWindowManager.prepareAppTransition(TRANSIT_NONE,
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005119 false /* alwaysKeepCurrent */);
5120 }
5121 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5122
5123 // If there was a transition set already we don't want to interfere with it as we
5124 // might be starting it too early.
5125 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005126 mWindowManager.executeAppTransition();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005127 }
5128 }
5129 if (callback != null) {
5130 callback.run();
5131 }
5132 }
5133
5134 @Override
5135 public void notifyKeyguardTrustedChanged() {
5136 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005137 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005138 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5139 }
5140 }
5141 }
5142
5143 /**
5144 * Called after virtual display Id is updated by
5145 * {@link com.android.server.vr.Vr2dDisplay} with a specific
5146 * {@param vrVr2dDisplayId}.
5147 */
5148 @Override
5149 public void setVr2dDisplayId(int vr2dDisplayId) {
5150 if (DEBUG_STACK) Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
5151 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005152 mVr2dDisplayId = vr2dDisplayId;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005153 }
5154 }
5155
5156 @Override
5157 public void setFocusedActivity(IBinder token) {
5158 synchronized (mGlobalLock) {
5159 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
5160 if (r == null) {
5161 throw new IllegalArgumentException(
5162 "setFocusedActivity: No activity record matching token=" + token);
5163 }
5164 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
5165 r, "setFocusedActivity")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08005166 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005167 }
5168 }
5169 }
5170
5171 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005172 public void registerScreenObserver(ScreenObserver observer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005173 mScreenObservers.add(observer);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005174 }
5175
5176 @Override
5177 public boolean isCallerRecents(int callingUid) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005178 return getRecentTasks().isCallerRecents(callingUid);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005179 }
5180
5181 @Override
5182 public boolean isRecentsComponentHomeActivity(int userId) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005183 return getRecentTasks().isRecentsComponentHomeActivity(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005184 }
5185
5186 @Override
5187 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
5188 ActivityTaskManagerService.this.cancelRecentsAnimation(restoreHomeStackPosition);
5189 }
5190
5191 @Override
5192 public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005193 ActivityTaskManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005194 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005195
5196 @Override
5197 public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
5198 synchronized (mGlobalLock) {
5199 mActiveVoiceInteractionServiceComponent = component;
5200 }
5201 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005202
5203 @Override
5204 public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
5205 if (!mAmInternal.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
5206 return;
5207 }
5208 synchronized (mGlobalLock) {
5209 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
5210 if (types == null) {
5211 if (uid < 0) {
5212 return;
5213 }
5214 types = new ArrayMap<>();
5215 mAllowAppSwitchUids.put(userId, types);
5216 }
5217 if (uid < 0) {
5218 types.remove(type);
5219 } else {
5220 types.put(type, uid);
5221 }
5222 }
5223 }
5224
5225 @Override
5226 public void onUserStopped(int userId) {
5227 synchronized (mGlobalLock) {
5228 getRecentTasks().unloadUserDataFromMemoryLocked(userId);
5229 mAllowAppSwitchUids.remove(userId);
5230 }
5231 }
5232
5233 @Override
5234 public boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
5235 synchronized (mGlobalLock) {
5236 return ActivityTaskManagerService.this.isGetTasksAllowed(
5237 caller, callingPid, callingUid);
5238 }
5239 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005240
5241 @Override
5242 public void onProcessAdded(WindowProcessController proc) {
5243 synchronized (mGlobalLock) {
5244 mProcessNames.put(proc.mName, proc.mUid, proc);
5245 }
5246 }
5247
5248 @Override
5249 public void onProcessRemoved(String name, int uid) {
5250 synchronized (mGlobalLock) {
5251 mProcessNames.remove(name, uid);
5252 }
5253 }
5254
5255 @Override
5256 public void onCleanUpApplicationRecord(WindowProcessController proc) {
5257 synchronized (mGlobalLock) {
5258 if (proc == mHomeProcess) {
5259 mHomeProcess = null;
5260 }
5261 if (proc == mPreviousProcess) {
5262 mPreviousProcess = null;
5263 }
5264 }
5265 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005266
5267 @Override
5268 public int getTopProcessState() {
5269 synchronized (mGlobalLock) {
5270 return mTopProcessState;
5271 }
5272 }
5273
5274 @Override
5275 public boolean isSleeping() {
5276 synchronized (mGlobalLock) {
5277 return isSleepingLocked();
5278 }
5279 }
5280
5281 @Override
5282 public boolean isShuttingDown() {
5283 synchronized (mGlobalLock) {
5284 return mShuttingDown;
5285 }
5286 }
5287
5288 @Override
5289 public boolean shuttingDown(boolean booted, int timeout) {
5290 synchronized (mGlobalLock) {
5291 mShuttingDown = true;
5292 mStackSupervisor.prepareForShutdownLocked();
5293 updateEventDispatchingLocked(booted);
5294 return mStackSupervisor.shutdownLocked(timeout);
5295 }
5296 }
5297
5298 @Override
5299 public void enableScreenAfterBoot(boolean booted) {
5300 synchronized (mGlobalLock) {
5301 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5302 SystemClock.uptimeMillis());
5303 mWindowManager.enableScreenAfterBoot();
5304 updateEventDispatchingLocked(booted);
5305 }
5306 }
5307
5308 @Override
5309 public boolean showStrictModeViolationDialog() {
5310 synchronized (mGlobalLock) {
5311 return mShowDialogs && !mSleeping && !mShuttingDown;
5312 }
5313 }
5314
5315 @Override
5316 public void showSystemReadyErrorDialogsIfNeeded() {
5317 synchronized (mGlobalLock) {
5318 try {
5319 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
5320 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
5321 + " data partition or your device will be unstable.");
5322 mUiHandler.post(() -> {
5323 if (mShowDialogs) {
5324 AlertDialog d = new BaseErrorDialog(mUiContext);
5325 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5326 d.setCancelable(false);
5327 d.setTitle(mUiContext.getText(R.string.android_system_label));
5328 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
5329 d.setButton(DialogInterface.BUTTON_POSITIVE,
5330 mUiContext.getText(R.string.ok),
5331 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5332 d.show();
5333 }
5334 });
5335 }
5336 } catch (RemoteException e) {
5337 }
5338
5339 if (!Build.isBuildConsistent()) {
5340 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
5341 mUiHandler.post(() -> {
5342 if (mShowDialogs) {
5343 AlertDialog d = new BaseErrorDialog(mUiContext);
5344 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5345 d.setCancelable(false);
5346 d.setTitle(mUiContext.getText(R.string.android_system_label));
5347 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
5348 d.setButton(DialogInterface.BUTTON_POSITIVE,
5349 mUiContext.getText(R.string.ok),
5350 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5351 d.show();
5352 }
5353 });
5354 }
5355 }
5356 }
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005357
5358 @Override
5359 public long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason) {
5360 synchronized (mGlobalLock) {
5361 return ActivityTaskManagerService.this.inputDispatchingTimedOut(
5362 pid, aboveSystem, reason);
5363 }
5364 }
5365
5366 @Override
5367 public void onProcessMapped(int pid, WindowProcessController proc) {
5368 synchronized (mGlobalLock) {
5369 mPidMap.put(pid, proc);
5370 }
5371 }
5372
5373 @Override
5374 public void onProcessUnMapped(int pid) {
5375 synchronized (mGlobalLock) {
5376 mPidMap.remove(pid);
5377 }
5378 }
Wale Ogunwale008163e2018-07-23 23:11:08 -07005379
5380 @Override
5381 public void onPackageDataCleared(String name) {
5382 synchronized (mGlobalLock) {
5383 mAppWarnings.onPackageDataCleared(name);
5384 }
5385 }
5386
5387 @Override
5388 public void onPackageUninstalled(String name) {
5389 synchronized (mGlobalLock) {
5390 mAppWarnings.onPackageUninstalled(name);
5391 }
5392 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005393 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07005394}