blob: 6ef08e53638865b7f59a4f5114aebc007bda06a5 [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
1671 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
1672 synchronized (mGlobalLock) {
1673 final ActivityRecord srec = ActivityRecord.forTokenLocked(token);
1674 if (srec != null) {
1675 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
1676 }
1677 }
1678 return false;
1679 }
1680
1681 @Override
1682 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
1683 Intent resultData) {
1684
1685 synchronized (mGlobalLock) {
1686 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
1687 if (r != null) {
1688 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
1689 }
1690 return false;
1691 }
1692 }
1693
1694 /**
1695 * Attempts to move a task backwards in z-order (the order of activities within the task is
1696 * unchanged).
1697 *
1698 * There are several possible results of this call:
1699 * - if the task is locked, then we will show the lock toast
1700 * - if there is a task behind the provided task, then that task is made visible and resumed as
1701 * this task is moved to the back
1702 * - otherwise, if there are no other tasks in the stack:
1703 * - if this task is in the pinned stack, then we remove the stack completely, which will
1704 * have the effect of moving the task to the top or bottom of the fullscreen stack
1705 * (depending on whether it is visible)
1706 * - otherwise, we simply return home and hide this task
1707 *
1708 * @param token A reference to the activity we wish to move
1709 * @param nonRoot If false then this only works if the activity is the root
1710 * of a task; if true it will work for any activity in a task.
1711 * @return Returns true if the move completed, false if not.
1712 */
1713 @Override
1714 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001715 enforceNotIsolatedCaller("moveActivityTaskToBack");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001716 synchronized (mGlobalLock) {
1717 final long origId = Binder.clearCallingIdentity();
1718 try {
1719 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
1720 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1721 if (task != null) {
1722 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
1723 }
1724 } finally {
1725 Binder.restoreCallingIdentity(origId);
1726 }
1727 }
1728 return false;
1729 }
1730
1731 @Override
1732 public Rect getTaskBounds(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001733 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001734 long ident = Binder.clearCallingIdentity();
1735 Rect rect = new Rect();
1736 try {
1737 synchronized (mGlobalLock) {
1738 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
1739 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1740 if (task == null) {
1741 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
1742 return rect;
1743 }
1744 if (task.getStack() != null) {
1745 // Return the bounds from window manager since it will be adjusted for various
1746 // things like the presense of a docked stack for tasks that aren't resizeable.
1747 task.getWindowContainerBounds(rect);
1748 } else {
1749 // Task isn't in window manager yet since it isn't associated with a stack.
1750 // Return the persist value from activity manager
1751 if (!task.matchParentBounds()) {
1752 rect.set(task.getBounds());
1753 } else if (task.mLastNonFullscreenBounds != null) {
1754 rect.set(task.mLastNonFullscreenBounds);
1755 }
1756 }
1757 }
1758 } finally {
1759 Binder.restoreCallingIdentity(ident);
1760 }
1761 return rect;
1762 }
1763
1764 @Override
1765 public ActivityManager.TaskDescription getTaskDescription(int id) {
1766 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001767 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001768 MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
1769 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
1770 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1771 if (tr != null) {
1772 return tr.lastTaskDescription;
1773 }
1774 }
1775 return null;
1776 }
1777
1778 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001779 public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
1780 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
1781 setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
1782 toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
1783 return;
1784 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001785 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001786 synchronized (mGlobalLock) {
1787 final long ident = Binder.clearCallingIdentity();
1788 try {
1789 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1790 if (task == null) {
1791 Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
1792 return;
1793 }
1794
1795 if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
1796 + " to windowingMode=" + windowingMode + " toTop=" + toTop);
1797
1798 if (!task.isActivityTypeStandardOrUndefined()) {
1799 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
1800 + " non-standard task " + taskId + " to windowing mode="
1801 + windowingMode);
1802 }
1803
1804 final ActivityStack stack = task.getStack();
1805 if (toTop) {
1806 stack.moveToFront("setTaskWindowingMode", task);
1807 }
1808 stack.setWindowingMode(windowingMode);
1809 } finally {
1810 Binder.restoreCallingIdentity(ident);
1811 }
1812 }
1813 }
1814
1815 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001816 public String getCallingPackage(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001817 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001818 ActivityRecord r = getCallingRecordLocked(token);
1819 return r != null ? r.info.packageName : null;
1820 }
1821 }
1822
1823 @Override
1824 public ComponentName getCallingActivity(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001825 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001826 ActivityRecord r = getCallingRecordLocked(token);
1827 return r != null ? r.intent.getComponent() : null;
1828 }
1829 }
1830
1831 private ActivityRecord getCallingRecordLocked(IBinder token) {
1832 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1833 if (r == null) {
1834 return null;
1835 }
1836 return r.resultTo;
1837 }
1838
1839 @Override
1840 public void unhandledBack() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001841 mAmInternal.enforceCallingPermission(android.Manifest.permission.FORCE_BACK, "unhandledBack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001842
1843 synchronized (mGlobalLock) {
1844 final long origId = Binder.clearCallingIdentity();
1845 try {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001846 getTopDisplayFocusedStack().unhandledBackLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001847 } finally {
1848 Binder.restoreCallingIdentity(origId);
1849 }
1850 }
1851 }
1852
1853 /**
1854 * TODO: Add mController hook
1855 */
1856 @Override
1857 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001858 mAmInternal.enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001859
1860 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
1861 synchronized (mGlobalLock) {
1862 moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
1863 false /* fromRecents */);
1864 }
1865 }
1866
1867 void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
1868 boolean fromRecents) {
1869
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001870 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001871 Binder.getCallingUid(), -1, -1, "Task to front")) {
1872 SafeActivityOptions.abort(options);
1873 return;
1874 }
1875 final long origId = Binder.clearCallingIdentity();
1876 try {
1877 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1878 if (task == null) {
1879 Slog.d(TAG, "Could not find task for id: "+ taskId);
1880 return;
1881 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001882 if (getLockTaskController().isLockTaskModeViolation(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001883 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
1884 return;
1885 }
1886 ActivityOptions realOptions = options != null
1887 ? options.getOptions(mStackSupervisor)
1888 : null;
1889 mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
1890 false /* forceNonResizable */);
1891
1892 final ActivityRecord topActivity = task.getTopActivity();
1893 if (topActivity != null) {
1894
1895 // We are reshowing a task, use a starting window to hide the initial draw delay
1896 // so the transition can start earlier.
1897 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
1898 true /* taskSwitch */, fromRecents);
1899 }
1900 } finally {
1901 Binder.restoreCallingIdentity(origId);
1902 }
1903 SafeActivityOptions.abort(options);
1904 }
1905
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001906 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
1907 int callingPid, int callingUid, String name) {
1908 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
1909 return true;
1910 }
1911
1912 if (getRecentTasks().isCallerRecents(sourceUid)) {
1913 return true;
1914 }
1915
1916 int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
1917 if (perm == PackageManager.PERMISSION_GRANTED) {
1918 return true;
1919 }
1920 if (checkAllowAppSwitchUid(sourceUid)) {
1921 return true;
1922 }
1923
1924 // If the actual IPC caller is different from the logical source, then
1925 // also see if they are allowed to control app switches.
1926 if (callingUid != -1 && callingUid != sourceUid) {
1927 perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
1928 if (perm == PackageManager.PERMISSION_GRANTED) {
1929 return true;
1930 }
1931 if (checkAllowAppSwitchUid(callingUid)) {
1932 return true;
1933 }
1934 }
1935
1936 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
1937 return false;
1938 }
1939
1940 private boolean checkAllowAppSwitchUid(int uid) {
1941 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
1942 if (types != null) {
1943 for (int i = types.size() - 1; i >= 0; i--) {
1944 if (types.valueAt(i).intValue() == uid) {
1945 return true;
1946 }
1947 }
1948 }
1949 return false;
1950 }
1951
1952 @Override
1953 public void setActivityController(IActivityController controller, boolean imAMonkey) {
1954 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
1955 "setActivityController()");
1956 synchronized (mGlobalLock) {
1957 mController = controller;
1958 mControllerIsAMonkey = imAMonkey;
1959 Watchdog.getInstance().setActivityController(controller);
1960 }
1961 }
1962
1963 boolean isControllerAMonkey() {
1964 synchronized (mGlobalLock) {
1965 return mController != null && mControllerIsAMonkey;
1966 }
1967 }
1968
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001969 @Override
1970 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
1971 synchronized (mGlobalLock) {
1972 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
1973 }
1974 }
1975
1976 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001977 public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum) {
1978 return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
1979 }
1980
1981 @Override
1982 public List<ActivityManager.RunningTaskInfo> getFilteredTasks(int maxNum,
1983 @WindowConfiguration.ActivityType int ignoreActivityType,
1984 @WindowConfiguration.WindowingMode int ignoreWindowingMode) {
1985 final int callingUid = Binder.getCallingUid();
1986 ArrayList<ActivityManager.RunningTaskInfo> list = new ArrayList<>();
1987
1988 synchronized (mGlobalLock) {
1989 if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
1990
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001991 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001992 callingUid);
1993 mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
1994 ignoreWindowingMode, callingUid, allowed);
1995 }
1996
1997 return list;
1998 }
1999
2000 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002001 public final void finishSubActivity(IBinder token, String resultWho, int requestCode) {
2002 synchronized (mGlobalLock) {
2003 final long origId = Binder.clearCallingIdentity();
2004 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2005 if (r != null) {
2006 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
2007 }
2008 Binder.restoreCallingIdentity(origId);
2009 }
2010 }
2011
2012 @Override
2013 public boolean willActivityBeVisible(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002014 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002015 ActivityStack stack = ActivityRecord.getStackLocked(token);
2016 if (stack != null) {
2017 return stack.willActivityBeVisibleLocked(token);
2018 }
2019 return false;
2020 }
2021 }
2022
2023 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002024 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002025 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002026 synchronized (mGlobalLock) {
2027 final long ident = Binder.clearCallingIdentity();
2028 try {
2029 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2030 if (task == null) {
2031 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
2032 return;
2033 }
2034
2035 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
2036 + " to stackId=" + stackId + " toTop=" + toTop);
2037
2038 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2039 if (stack == null) {
2040 throw new IllegalStateException(
2041 "moveTaskToStack: No stack for stackId=" + stackId);
2042 }
2043 if (!stack.isActivityTypeStandardOrUndefined()) {
2044 throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
2045 + taskId + " to stack " + stackId);
2046 }
2047 if (stack.inSplitScreenPrimaryWindowingMode()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002048 mWindowManager.setDockedStackCreateState(
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002049 SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
2050 }
2051 task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
2052 "moveTaskToStack");
2053 } finally {
2054 Binder.restoreCallingIdentity(ident);
2055 }
2056 }
2057 }
2058
2059 @Override
2060 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
2061 boolean preserveWindows, boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002062 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002063
2064 final long ident = Binder.clearCallingIdentity();
2065 try {
2066 synchronized (mGlobalLock) {
2067 if (animate) {
2068 final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
2069 if (stack == null) {
2070 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2071 return;
2072 }
2073 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
2074 throw new IllegalArgumentException("Stack: " + stackId
2075 + " doesn't support animated resize.");
2076 }
2077 stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
2078 animationDuration, false /* fromFullscreen */);
2079 } else {
2080 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2081 if (stack == null) {
2082 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2083 return;
2084 }
2085 mStackSupervisor.resizeStackLocked(stack, destBounds,
2086 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
2087 preserveWindows, allowResizeInDockedMode, !DEFER_RESUME);
2088 }
2089 }
2090 } finally {
2091 Binder.restoreCallingIdentity(ident);
2092 }
2093 }
2094
2095 /**
2096 * Moves the specified task to the primary-split-screen stack.
2097 *
2098 * @param taskId Id of task to move.
2099 * @param createMode The mode the primary split screen stack should be created in if it doesn't
2100 * exist already. See
2101 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
2102 * and
2103 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
2104 * @param toTop If the task and stack should be moved to the top.
2105 * @param animate Whether we should play an animation for the moving the task.
2106 * @param initialBounds If the primary stack gets created, it will use these bounds for the
2107 * stack. Pass {@code null} to use default bounds.
2108 * @param showRecents If the recents activity should be shown on the other side of the task
2109 * going into split-screen mode.
2110 */
2111 @Override
2112 public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode,
2113 boolean toTop, boolean animate, Rect initialBounds, boolean showRecents) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002114 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002115 "setTaskWindowingModeSplitScreenPrimary()");
2116 synchronized (mGlobalLock) {
2117 final long ident = Binder.clearCallingIdentity();
2118 try {
2119 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2120 if (task == null) {
2121 Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
2122 return false;
2123 }
2124 if (DEBUG_STACK) Slog.d(TAG_STACK,
2125 "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
2126 + " to createMode=" + createMode + " toTop=" + toTop);
2127 if (!task.isActivityTypeStandardOrUndefined()) {
2128 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
2129 + " non-standard task " + taskId + " to split-screen windowing mode");
2130 }
2131
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002132 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002133 final int windowingMode = task.getWindowingMode();
2134 final ActivityStack stack = task.getStack();
2135 if (toTop) {
2136 stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
2137 }
2138 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
2139 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */);
2140 return windowingMode != task.getWindowingMode();
2141 } finally {
2142 Binder.restoreCallingIdentity(ident);
2143 }
2144 }
2145 }
2146
2147 /**
2148 * Removes stacks in the input windowing modes from the system if they are of activity type
2149 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
2150 */
2151 @Override
2152 public void removeStacksInWindowingModes(int[] windowingModes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002153 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002154 "removeStacksInWindowingModes()");
2155
2156 synchronized (mGlobalLock) {
2157 final long ident = Binder.clearCallingIdentity();
2158 try {
2159 mStackSupervisor.removeStacksInWindowingModes(windowingModes);
2160 } finally {
2161 Binder.restoreCallingIdentity(ident);
2162 }
2163 }
2164 }
2165
2166 @Override
2167 public void removeStacksWithActivityTypes(int[] activityTypes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002168 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002169 "removeStacksWithActivityTypes()");
2170
2171 synchronized (mGlobalLock) {
2172 final long ident = Binder.clearCallingIdentity();
2173 try {
2174 mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
2175 } finally {
2176 Binder.restoreCallingIdentity(ident);
2177 }
2178 }
2179 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002180
2181 @Override
2182 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
2183 int userId) {
2184 final int callingUid = Binder.getCallingUid();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002185 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, "getRecentTasks");
2186 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002187 callingUid);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002188 final boolean detailed = checkGetTasksPermission(
2189 android.Manifest.permission.GET_DETAILED_TASKS, Binder.getCallingPid(),
2190 UserHandle.getAppId(callingUid))
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002191 == PackageManager.PERMISSION_GRANTED;
2192
2193 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002194 return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002195 callingUid);
2196 }
2197 }
2198
2199 @Override
2200 public List<ActivityManager.StackInfo> getAllStackInfos() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002201 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002202 long ident = Binder.clearCallingIdentity();
2203 try {
2204 synchronized (mGlobalLock) {
2205 return mStackSupervisor.getAllStackInfosLocked();
2206 }
2207 } finally {
2208 Binder.restoreCallingIdentity(ident);
2209 }
2210 }
2211
2212 @Override
2213 public ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002214 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002215 long ident = Binder.clearCallingIdentity();
2216 try {
2217 synchronized (mGlobalLock) {
2218 return mStackSupervisor.getStackInfo(windowingMode, activityType);
2219 }
2220 } finally {
2221 Binder.restoreCallingIdentity(ident);
2222 }
2223 }
2224
2225 @Override
2226 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002227 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002228 final long callingUid = Binder.getCallingUid();
2229 final long origId = Binder.clearCallingIdentity();
2230 try {
2231 synchronized (mGlobalLock) {
2232 // Cancel the recents animation synchronously (do not hold the WM lock)
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002233 mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002234 ? REORDER_MOVE_TO_ORIGINAL_POSITION
2235 : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
2236 }
2237 } finally {
2238 Binder.restoreCallingIdentity(origId);
2239 }
2240 }
2241
2242 @Override
2243 public void startLockTaskModeByToken(IBinder token) {
2244 synchronized (mGlobalLock) {
2245 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2246 if (r == null) {
2247 return;
2248 }
2249 startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
2250 }
2251 }
2252
2253 @Override
2254 public void startSystemLockTaskMode(int taskId) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002255 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002256 // This makes inner call to look as if it was initiated by system.
2257 long ident = Binder.clearCallingIdentity();
2258 try {
2259 synchronized (mGlobalLock) {
2260 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2261
2262 // When starting lock task mode the stack must be in front and focused
2263 task.getStack().moveToFront("startSystemLockTaskMode");
2264 startLockTaskModeLocked(task, true /* isSystemCaller */);
2265 }
2266 } finally {
2267 Binder.restoreCallingIdentity(ident);
2268 }
2269 }
2270
2271 @Override
2272 public void stopLockTaskModeByToken(IBinder token) {
2273 synchronized (mGlobalLock) {
2274 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2275 if (r == null) {
2276 return;
2277 }
2278 stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
2279 }
2280 }
2281
2282 /**
2283 * This API should be called by SystemUI only when user perform certain action to dismiss
2284 * lock task mode. We should only dismiss pinned lock task mode in this case.
2285 */
2286 @Override
2287 public void stopSystemLockTaskMode() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002288 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002289 stopLockTaskModeInternal(null, true /* isSystemCaller */);
2290 }
2291
2292 private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
2293 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
2294 if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
2295 return;
2296 }
2297
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002298 final ActivityStack stack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002299 if (stack == null || task != stack.topTask()) {
2300 throw new IllegalArgumentException("Invalid task, not in foreground");
2301 }
2302
2303 // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
2304 // system or a specific app.
2305 // * System-initiated requests will only start the pinned mode (screen pinning)
2306 // * App-initiated requests
2307 // - will put the device in fully locked mode (LockTask), if the app is whitelisted
2308 // - will start the pinned mode, otherwise
2309 final int callingUid = Binder.getCallingUid();
2310 long ident = Binder.clearCallingIdentity();
2311 try {
2312 // When a task is locked, dismiss the pinned stack if it exists
2313 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2314
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002315 getLockTaskController().startLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002316 } finally {
2317 Binder.restoreCallingIdentity(ident);
2318 }
2319 }
2320
2321 private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
2322 final int callingUid = Binder.getCallingUid();
2323 long ident = Binder.clearCallingIdentity();
2324 try {
2325 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002326 getLockTaskController().stopLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002327 }
2328 // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
2329 // task and jumping straight into a call in the case of emergency call back.
2330 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
2331 if (tm != null) {
2332 tm.showInCallScreen(false);
2333 }
2334 } finally {
2335 Binder.restoreCallingIdentity(ident);
2336 }
2337 }
2338
2339 @Override
2340 public boolean isInLockTaskMode() {
2341 return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
2342 }
2343
2344 @Override
2345 public int getLockTaskModeState() {
2346 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002347 return getLockTaskController().getLockTaskModeState();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002348 }
2349 }
2350
2351 @Override
2352 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
2353 synchronized (mGlobalLock) {
2354 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2355 if (r != null) {
2356 r.setTaskDescription(td);
2357 final TaskRecord task = r.getTask();
2358 task.updateTaskDescription();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002359 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002360 }
2361 }
2362 }
2363
2364 @Override
2365 public Bundle getActivityOptions(IBinder token) {
2366 final long origId = Binder.clearCallingIdentity();
2367 try {
2368 synchronized (mGlobalLock) {
2369 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
2370 if (r != null) {
2371 final ActivityOptions activityOptions = r.takeOptionsLocked();
2372 return activityOptions == null ? null : activityOptions.toBundle();
2373 }
2374 return null;
2375 }
2376 } finally {
2377 Binder.restoreCallingIdentity(origId);
2378 }
2379 }
2380
2381 @Override
2382 public List<IBinder> getAppTasks(String callingPackage) {
2383 int callingUid = Binder.getCallingUid();
2384 long ident = Binder.clearCallingIdentity();
2385 try {
2386 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002387 return mRecentTasks.getAppTasksList(callingUid, callingPackage);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002388 }
2389 } finally {
2390 Binder.restoreCallingIdentity(ident);
2391 }
2392 }
2393
2394 @Override
2395 public void finishVoiceTask(IVoiceInteractionSession session) {
2396 synchronized (mGlobalLock) {
2397 final long origId = Binder.clearCallingIdentity();
2398 try {
2399 // TODO: VI Consider treating local voice interactions and voice tasks
2400 // differently here
2401 mStackSupervisor.finishVoiceTask(session);
2402 } finally {
2403 Binder.restoreCallingIdentity(origId);
2404 }
2405 }
2406
2407 }
2408
2409 @Override
2410 public boolean isTopOfTask(IBinder token) {
2411 synchronized (mGlobalLock) {
2412 ActivityRecord r = ActivityRecord.isInStackLocked(token);
Riddle Hsu66b74a82018-07-26 00:20:12 +08002413 return r != null && r.getTask().getTopActivity() == r;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002414 }
2415 }
2416
2417 @Override
2418 public void notifyLaunchTaskBehindComplete(IBinder token) {
2419 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
2420 }
2421
2422 @Override
2423 public void notifyEnterAnimationComplete(IBinder token) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002424 mH.post(() -> {
2425 synchronized (mGlobalLock) {
2426 ActivityRecord r = ActivityRecord.forTokenLocked(token);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002427 if (r != null && r.attachedToProcess()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002428 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002429 r.app.getThread().scheduleEnterAnimationComplete(r.appToken);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002430 } catch (RemoteException e) {
2431 }
2432 }
2433 }
2434
2435 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002436 }
2437
2438 /** Called from an app when assist data is ready. */
2439 @Override
2440 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
2441 AssistContent content, Uri referrer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002442 PendingAssistExtras pae = (PendingAssistExtras) token;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002443 synchronized (pae) {
2444 pae.result = extras;
2445 pae.structure = structure;
2446 pae.content = content;
2447 if (referrer != null) {
2448 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
2449 }
2450 if (structure != null) {
2451 structure.setHomeActivity(pae.isHome);
2452 }
2453 pae.haveResult = true;
2454 pae.notifyAll();
2455 if (pae.intent == null && pae.receiver == null) {
2456 // Caller is just waiting for the result.
2457 return;
2458 }
2459 }
2460 // We are now ready to launch the assist activity.
2461 IAssistDataReceiver sendReceiver = null;
2462 Bundle sendBundle = null;
2463 synchronized (mGlobalLock) {
2464 buildAssistBundleLocked(pae, extras);
2465 boolean exists = mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002466 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002467 if (!exists) {
2468 // Timed out.
2469 return;
2470 }
2471
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002472 if ((sendReceiver = pae.receiver) != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002473 // Caller wants result sent back to them.
2474 sendBundle = new Bundle();
2475 sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
2476 sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
2477 sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
2478 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
2479 }
2480 }
2481 if (sendReceiver != null) {
2482 try {
2483 sendReceiver.onHandleAssistData(sendBundle);
2484 } catch (RemoteException e) {
2485 }
2486 return;
2487 }
2488
2489 final long ident = Binder.clearCallingIdentity();
2490 try {
2491 if (TextUtils.equals(pae.intent.getAction(),
2492 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
2493 pae.intent.putExtras(pae.extras);
2494 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
2495 } else {
2496 pae.intent.replaceExtras(pae.extras);
2497 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
2498 | Intent.FLAG_ACTIVITY_SINGLE_TOP
2499 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002500 mAmInternal.closeSystemDialogs("assist");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002501
2502 try {
2503 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
2504 } catch (ActivityNotFoundException e) {
2505 Slog.w(TAG, "No activity to handle assist action.", e);
2506 }
2507 }
2508 } finally {
2509 Binder.restoreCallingIdentity(ident);
2510 }
2511 }
2512
2513 @Override
2514 public int addAppTask(IBinder activityToken, Intent intent,
2515 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
2516 final int callingUid = Binder.getCallingUid();
2517 final long callingIdent = Binder.clearCallingIdentity();
2518
2519 try {
2520 synchronized (mGlobalLock) {
2521 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
2522 if (r == null) {
2523 throw new IllegalArgumentException("Activity does not exist; token="
2524 + activityToken);
2525 }
2526 ComponentName comp = intent.getComponent();
2527 if (comp == null) {
2528 throw new IllegalArgumentException("Intent " + intent
2529 + " must specify explicit component");
2530 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002531 if (thumbnail.getWidth() != mThumbnailWidth
2532 || thumbnail.getHeight() != mThumbnailHeight) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002533 throw new IllegalArgumentException("Bad thumbnail size: got "
2534 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002535 + mThumbnailWidth + "x" + mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002536 }
2537 if (intent.getSelector() != null) {
2538 intent.setSelector(null);
2539 }
2540 if (intent.getSourceBounds() != null) {
2541 intent.setSourceBounds(null);
2542 }
2543 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
2544 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
2545 // The caller has added this as an auto-remove task... that makes no
2546 // sense, so turn off auto-remove.
2547 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
2548 }
2549 }
2550 final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
2551 STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
2552 if (ainfo.applicationInfo.uid != callingUid) {
2553 throw new SecurityException(
2554 "Can't add task for another application: target uid="
2555 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
2556 }
2557
2558 final ActivityStack stack = r.getStack();
2559 final TaskRecord task = stack.createTaskRecord(
2560 mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent,
2561 null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002562 if (!mRecentTasks.addToBottom(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002563 // The app has too many tasks already and we can't add any more
2564 stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
2565 return INVALID_TASK_ID;
2566 }
2567 task.lastTaskDescription.copyFrom(description);
2568
2569 // TODO: Send the thumbnail to WM to store it.
2570
2571 return task.taskId;
2572 }
2573 } finally {
2574 Binder.restoreCallingIdentity(callingIdent);
2575 }
2576 }
2577
2578 @Override
2579 public Point getAppTaskThumbnailSize() {
2580 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002581 return new Point(mThumbnailWidth, mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002582 }
2583 }
2584
2585 @Override
2586 public void setTaskResizeable(int taskId, int resizeableMode) {
2587 synchronized (mGlobalLock) {
2588 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
2589 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
2590 if (task == null) {
2591 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
2592 return;
2593 }
2594 task.setResizeMode(resizeableMode);
2595 }
2596 }
2597
2598 @Override
2599 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002600 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002601 long ident = Binder.clearCallingIdentity();
2602 try {
2603 synchronized (mGlobalLock) {
2604 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2605 if (task == null) {
2606 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
2607 return;
2608 }
2609 // Place the task in the right stack if it isn't there already based on
2610 // the requested bounds.
2611 // The stack transition logic is:
2612 // - a null bounds on a freeform task moves that task to fullscreen
2613 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
2614 // that task to freeform
2615 // - otherwise the task is not moved
2616 ActivityStack stack = task.getStack();
2617 if (!task.getWindowConfiguration().canResizeTask()) {
2618 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
2619 }
2620 if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
2621 stack = stack.getDisplay().getOrCreateStack(
2622 WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
2623 } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
2624 stack = stack.getDisplay().getOrCreateStack(
2625 WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
2626 }
2627
2628 // Reparent the task to the right stack if necessary
2629 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
2630 if (stack != task.getStack()) {
2631 // Defer resume until the task is resized below
2632 task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
2633 DEFER_RESUME, "resizeTask");
2634 preserveWindow = false;
2635 }
2636
2637 // After reparenting (which only resizes the task to the stack bounds), resize the
2638 // task to the actual bounds provided
2639 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
2640 }
2641 } finally {
2642 Binder.restoreCallingIdentity(ident);
2643 }
2644 }
2645
2646 @Override
2647 public boolean releaseActivityInstance(IBinder token) {
2648 synchronized (mGlobalLock) {
2649 final long origId = Binder.clearCallingIdentity();
2650 try {
2651 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2652 if (r == null) {
2653 return false;
2654 }
2655 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
2656 } finally {
2657 Binder.restoreCallingIdentity(origId);
2658 }
2659 }
2660 }
2661
2662 @Override
2663 public void releaseSomeActivities(IApplicationThread appInt) {
2664 synchronized (mGlobalLock) {
2665 final long origId = Binder.clearCallingIdentity();
2666 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002667 WindowProcessController app =
2668 mAm.getRecordForAppLocked(appInt).getWindowProcessController();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002669 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
2670 } finally {
2671 Binder.restoreCallingIdentity(origId);
2672 }
2673 }
2674 }
2675
2676 @Override
2677 public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
2678 int secondaryDisplayShowing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002679 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002680 != PackageManager.PERMISSION_GRANTED) {
2681 throw new SecurityException("Requires permission "
2682 + android.Manifest.permission.DEVICE_POWER);
2683 }
2684
2685 synchronized (mGlobalLock) {
2686 long ident = Binder.clearCallingIdentity();
2687 if (mKeyguardShown != keyguardShowing) {
2688 mKeyguardShown = keyguardShowing;
2689 reportCurKeyguardUsageEventLocked(keyguardShowing);
2690 }
2691 try {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002692 mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002693 secondaryDisplayShowing);
2694 } finally {
2695 Binder.restoreCallingIdentity(ident);
2696 }
2697 }
2698
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002699 mH.post(() -> {
2700 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2701 mScreenObservers.get(i).onKeyguardStateChanged(keyguardShowing);
2702 }
2703 });
2704 }
2705
2706 void onScreenAwakeChanged(boolean isAwake) {
2707 mH.post(() -> {
2708 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2709 mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2710 }
2711 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002712 }
2713
2714 @Override
2715 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002716 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
2717 userId, "getTaskDescriptionIcon");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002718
2719 final File passedIconFile = new File(filePath);
2720 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
2721 passedIconFile.getName());
2722 if (!legitIconFile.getPath().equals(filePath)
2723 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
2724 throw new IllegalArgumentException("Bad file path: " + filePath
2725 + " passed for userId " + userId);
2726 }
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002727 return mRecentTasks.getTaskDescriptionIcon(filePath);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002728 }
2729
2730 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002731 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002732 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
2733 final ActivityOptions activityOptions = safeOptions != null
2734 ? safeOptions.getOptions(mStackSupervisor)
2735 : null;
2736 if (activityOptions == null
2737 || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
2738 || activityOptions.getCustomInPlaceResId() == 0) {
2739 throw new IllegalArgumentException("Expected in-place ActivityOption " +
2740 "with valid animation");
2741 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002742 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
2743 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002744 activityOptions.getCustomInPlaceResId());
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002745 mWindowManager.executeAppTransition();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002746 }
2747
2748 @Override
2749 public void removeStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002750 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002751 synchronized (mGlobalLock) {
2752 final long ident = Binder.clearCallingIdentity();
2753 try {
2754 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2755 if (stack == null) {
2756 Slog.w(TAG, "removeStack: No stack with id=" + stackId);
2757 return;
2758 }
2759 if (!stack.isActivityTypeStandardOrUndefined()) {
2760 throw new IllegalArgumentException(
2761 "Removing non-standard stack is not allowed.");
2762 }
2763 mStackSupervisor.removeStack(stack);
2764 } finally {
2765 Binder.restoreCallingIdentity(ident);
2766 }
2767 }
2768 }
2769
2770 @Override
2771 public void moveStackToDisplay(int stackId, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002772 mAmInternal.enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002773
2774 synchronized (mGlobalLock) {
2775 final long ident = Binder.clearCallingIdentity();
2776 try {
2777 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
2778 + " to displayId=" + displayId);
2779 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
2780 } finally {
2781 Binder.restoreCallingIdentity(ident);
2782 }
2783 }
2784 }
2785
2786 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002787 public void exitFreeformMode(IBinder token) {
2788 synchronized (mGlobalLock) {
2789 long ident = Binder.clearCallingIdentity();
2790 try {
2791 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2792 if (r == null) {
2793 throw new IllegalArgumentException(
2794 "exitFreeformMode: No activity record matching token=" + token);
2795 }
2796
2797 final ActivityStack stack = r.getStack();
2798 if (stack == null || !stack.inFreeformWindowingMode()) {
2799 throw new IllegalStateException(
2800 "exitFreeformMode: You can only go fullscreen from freeform.");
2801 }
2802
2803 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
2804 } finally {
2805 Binder.restoreCallingIdentity(ident);
2806 }
2807 }
2808 }
2809
2810 /** Sets the task stack listener that gets callbacks when a task stack changes. */
2811 @Override
2812 public void registerTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002813 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002814 "registerTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002815 mTaskChangeNotificationController.registerTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002816 }
2817
2818 /** Unregister a task stack listener so that it stops receiving callbacks. */
2819 @Override
2820 public void unregisterTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002821 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002822 "unregisterTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002823 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002824 }
2825
2826 private void reportCurKeyguardUsageEventLocked(boolean keyguardShowing) {
2827 mAm.reportGlobalUsageEventLocked(keyguardShowing
2828 ? UsageEvents.Event.KEYGUARD_SHOWN
2829 : UsageEvents.Event.KEYGUARD_HIDDEN);
2830 }
2831
2832 @Override
2833 public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
2834 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
2835 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
2836 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
2837 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
2838 }
2839
2840 @Override
2841 public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
2842 IBinder activityToken, int flags) {
2843 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
2844 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
2845 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
2846 }
2847
2848 @Override
2849 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
2850 Bundle args) {
2851 return enqueueAssistContext(requestType, intent, hint, null, null, null,
2852 true /* focused */, true /* newSessionId */, userHandle, args,
2853 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
2854 }
2855
2856 @Override
2857 public Bundle getAssistContextExtras(int requestType) {
2858 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
2859 null, null, true /* focused */, true /* newSessionId */,
2860 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
2861 if (pae == null) {
2862 return null;
2863 }
2864 synchronized (pae) {
2865 while (!pae.haveResult) {
2866 try {
2867 pae.wait();
2868 } catch (InterruptedException e) {
2869 }
2870 }
2871 }
2872 synchronized (mGlobalLock) {
2873 buildAssistBundleLocked(pae, pae.result);
2874 mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002875 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002876 }
2877 return pae.extras;
2878 }
2879
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002880 /**
2881 * Binder IPC calls go through the public entry point.
2882 * This can be called with or without the global lock held.
2883 */
2884 private static int checkCallingPermission(String permission) {
2885 return checkPermission(
2886 permission, Binder.getCallingPid(), UserHandle.getAppId(Binder.getCallingUid()));
2887 }
2888
2889 /** This can be called with or without the global lock held. */
2890 void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
2891 if (!getRecentTasks().isCallerRecents(Binder.getCallingUid())) {
2892 mAmInternal.enforceCallingPermission(permission, func);
2893 }
2894 }
2895
2896 @VisibleForTesting
2897 int checkGetTasksPermission(String permission, int pid, int uid) {
2898 return checkPermission(permission, pid, uid);
2899 }
2900
2901 static int checkPermission(String permission, int pid, int uid) {
2902 if (permission == null) {
2903 return PackageManager.PERMISSION_DENIED;
2904 }
2905 return checkComponentPermission(permission, pid, uid, -1, true);
2906 }
2907
2908 boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
2909 if (getRecentTasks().isCallerRecents(callingUid)) {
2910 // Always allow the recents component to get tasks
2911 return true;
2912 }
2913
2914 boolean allowed = checkGetTasksPermission(android.Manifest.permission.REAL_GET_TASKS,
2915 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
2916 if (!allowed) {
2917 if (checkGetTasksPermission(android.Manifest.permission.GET_TASKS,
2918 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
2919 // Temporary compatibility: some existing apps on the system image may
2920 // still be requesting the old permission and not switched to the new
2921 // one; if so, we'll still allow them full access. This means we need
2922 // to see if they are holding the old permission and are a system app.
2923 try {
2924 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
2925 allowed = true;
2926 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
2927 + " is using old GET_TASKS but privileged; allowing");
2928 }
2929 } catch (RemoteException e) {
2930 }
2931 }
2932 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
2933 + " does not hold REAL_GET_TASKS; limiting output");
2934 }
2935 return allowed;
2936 }
2937
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002938 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
2939 IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
2940 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
2941 int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002942 mAmInternal.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002943 "enqueueAssistContext()");
2944
2945 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002946 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002947 if (activity == null) {
2948 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
2949 return null;
2950 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002951 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002952 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
2953 return null;
2954 }
2955 if (focused) {
2956 if (activityToken != null) {
2957 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
2958 if (activity != caller) {
2959 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
2960 + " is not current top " + activity);
2961 return null;
2962 }
2963 }
2964 } else {
2965 activity = ActivityRecord.forTokenLocked(activityToken);
2966 if (activity == null) {
2967 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
2968 + " couldn't be found");
2969 return null;
2970 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002971 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002972 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
2973 return null;
2974 }
2975 }
2976
2977 PendingAssistExtras pae;
2978 Bundle extras = new Bundle();
2979 if (args != null) {
2980 extras.putAll(args);
2981 }
2982 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002983 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002984
2985 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
2986 userHandle);
2987 pae.isHome = activity.isActivityTypeHome();
2988
2989 // Increment the sessionId if necessary
2990 if (newSessionId) {
2991 mViSessionId++;
2992 }
2993 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002994 activity.app.getThread().requestAssistContextExtras(activity.appToken, pae,
2995 requestType, mViSessionId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002996 mPendingAssistExtras.add(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002997 mUiHandler.postDelayed(pae, timeout);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002998 } catch (RemoteException e) {
2999 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
3000 return null;
3001 }
3002 return pae;
3003 }
3004 }
3005
3006 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
3007 if (result != null) {
3008 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
3009 }
3010 if (pae.hint != null) {
3011 pae.extras.putBoolean(pae.hint, true);
3012 }
3013 }
3014
3015 private void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
3016 IAssistDataReceiver receiver;
3017 synchronized (mGlobalLock) {
3018 mPendingAssistExtras.remove(pae);
3019 receiver = pae.receiver;
3020 }
3021 if (receiver != null) {
3022 // Caller wants result sent back to them.
3023 Bundle sendBundle = new Bundle();
3024 // At least return the receiver extras
3025 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
3026 try {
3027 pae.receiver.onHandleAssistData(sendBundle);
3028 } catch (RemoteException e) {
3029 }
3030 }
3031 }
3032
3033 public class PendingAssistExtras extends Binder implements Runnable {
3034 public final ActivityRecord activity;
3035 public boolean isHome;
3036 public final Bundle extras;
3037 public final Intent intent;
3038 public final String hint;
3039 public final IAssistDataReceiver receiver;
3040 public final int userHandle;
3041 public boolean haveResult = false;
3042 public Bundle result = null;
3043 public AssistStructure structure = null;
3044 public AssistContent content = null;
3045 public Bundle receiverExtras;
3046
3047 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
3048 String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
3049 int _userHandle) {
3050 activity = _activity;
3051 extras = _extras;
3052 intent = _intent;
3053 hint = _hint;
3054 receiver = _receiver;
3055 receiverExtras = _receiverExtras;
3056 userHandle = _userHandle;
3057 }
3058
3059 @Override
3060 public void run() {
3061 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
3062 synchronized (this) {
3063 haveResult = true;
3064 notifyAll();
3065 }
3066 pendingAssistExtrasTimedOut(this);
3067 }
3068 }
3069
3070 @Override
3071 public boolean isAssistDataAllowedOnCurrentActivity() {
3072 int userId;
3073 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003074 final ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003075 if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
3076 return false;
3077 }
3078
3079 final ActivityRecord activity = focusedStack.getTopActivity();
3080 if (activity == null) {
3081 return false;
3082 }
3083 userId = activity.userId;
3084 }
3085 return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
3086 }
3087
3088 @Override
3089 public boolean showAssistFromActivity(IBinder token, Bundle args) {
3090 long ident = Binder.clearCallingIdentity();
3091 try {
3092 synchronized (mGlobalLock) {
3093 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003094 ActivityRecord top = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003095 if (top != caller) {
3096 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3097 + " is not current top " + top);
3098 return false;
3099 }
3100 if (!top.nowVisible) {
3101 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3102 + " is not visible");
3103 return false;
3104 }
3105 }
3106 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
3107 token);
3108 } finally {
3109 Binder.restoreCallingIdentity(ident);
3110 }
3111 }
3112
3113 @Override
3114 public boolean isRootVoiceInteraction(IBinder token) {
3115 synchronized (mGlobalLock) {
3116 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3117 if (r == null) {
3118 return false;
3119 }
3120 return r.rootVoiceInteraction;
3121 }
3122 }
3123
Wale Ogunwalef6733932018-06-27 05:14:34 -07003124 private void onLocalVoiceInteractionStartedLocked(IBinder activity,
3125 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
3126 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
3127 if (activityToCallback == null) return;
3128 activityToCallback.setVoiceSessionLocked(voiceSession);
3129
3130 // Inform the activity
3131 try {
3132 activityToCallback.app.getThread().scheduleLocalVoiceInteractionStarted(activity,
3133 voiceInteractor);
3134 long token = Binder.clearCallingIdentity();
3135 try {
3136 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
3137 } finally {
3138 Binder.restoreCallingIdentity(token);
3139 }
3140 // TODO: VI Should we cache the activity so that it's easier to find later
3141 // rather than scan through all the stacks and activities?
3142 } catch (RemoteException re) {
3143 activityToCallback.clearVoiceSessionLocked();
3144 // TODO: VI Should this terminate the voice session?
3145 }
3146 }
3147
3148 private void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
3149 Slog.d(TAG, "<<< startRunningVoiceLocked()");
3150 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
3151 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
3152 boolean wasRunningVoice = mRunningVoice != null;
3153 mRunningVoice = session;
3154 if (!wasRunningVoice) {
3155 mVoiceWakeLock.acquire();
3156 updateSleepIfNeededLocked();
3157 }
3158 }
3159 }
3160
3161 void finishRunningVoiceLocked() {
3162 if (mRunningVoice != null) {
3163 mRunningVoice = null;
3164 mVoiceWakeLock.release();
3165 updateSleepIfNeededLocked();
3166 }
3167 }
3168
3169 @Override
3170 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3171 synchronized (mGlobalLock) {
3172 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3173 if (keepAwake) {
3174 mVoiceWakeLock.acquire();
3175 } else {
3176 mVoiceWakeLock.release();
3177 }
3178 }
3179 }
3180 }
3181
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003182 @Override
3183 public ComponentName getActivityClassForToken(IBinder token) {
3184 synchronized (mGlobalLock) {
3185 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3186 if (r == null) {
3187 return null;
3188 }
3189 return r.intent.getComponent();
3190 }
3191 }
3192
3193 @Override
3194 public String getPackageForToken(IBinder token) {
3195 synchronized (mGlobalLock) {
3196 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3197 if (r == null) {
3198 return null;
3199 }
3200 return r.packageName;
3201 }
3202 }
3203
3204 @Override
3205 public void showLockTaskEscapeMessage(IBinder token) {
3206 synchronized (mGlobalLock) {
3207 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3208 if (r == null) {
3209 return;
3210 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003211 getLockTaskController().showLockTaskToast();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003212 }
3213 }
3214
3215 @Override
3216 public void keyguardGoingAway(int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003217 enforceNotIsolatedCaller("keyguardGoingAway");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003218 final long token = Binder.clearCallingIdentity();
3219 try {
3220 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003221 mKeyguardController.keyguardGoingAway(flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003222 }
3223 } finally {
3224 Binder.restoreCallingIdentity(token);
3225 }
3226 }
3227
3228 /**
3229 * Try to place task to provided position. The final position might be different depending on
3230 * current user and stacks state. The task will be moved to target stack if it's currently in
3231 * different stack.
3232 */
3233 @Override
3234 public void positionTaskInStack(int taskId, int stackId, int position) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003235 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003236 synchronized (mGlobalLock) {
3237 long ident = Binder.clearCallingIdentity();
3238 try {
3239 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
3240 + taskId + " in stackId=" + stackId + " at position=" + position);
3241 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3242 if (task == null) {
3243 throw new IllegalArgumentException("positionTaskInStack: no task for id="
3244 + taskId);
3245 }
3246
3247 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3248
3249 if (stack == null) {
3250 throw new IllegalArgumentException("positionTaskInStack: no stack for id="
3251 + stackId);
3252 }
3253 if (!stack.isActivityTypeStandardOrUndefined()) {
3254 throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
3255 + " the position of task " + taskId + " in/to non-standard stack");
3256 }
3257
3258 // TODO: Have the callers of this API call a separate reparent method if that is
3259 // what they intended to do vs. having this method also do reparenting.
3260 if (task.getStack() == stack) {
3261 // Change position in current stack.
3262 stack.positionChildAt(task, position);
3263 } else {
3264 // Reparent to new stack.
3265 task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
3266 !DEFER_RESUME, "positionTaskInStack");
3267 }
3268 } finally {
3269 Binder.restoreCallingIdentity(ident);
3270 }
3271 }
3272 }
3273
3274 @Override
3275 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
3276 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
3277 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
3278 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
3279 synchronized (mGlobalLock) {
3280 ActivityRecord record = ActivityRecord.isInStackLocked(token);
3281 if (record == null) {
3282 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
3283 + "found for: " + token);
3284 }
3285 record.setSizeConfigurations(horizontalSizeConfiguration,
3286 verticalSizeConfigurations, smallestSizeConfigurations);
3287 }
3288 }
3289
3290 /**
3291 * Dismisses split-screen multi-window mode.
3292 * @param toTop If true the current primary split-screen stack will be placed or left on top.
3293 */
3294 @Override
3295 public void dismissSplitScreenMode(boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003296 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003297 MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
3298 final long ident = Binder.clearCallingIdentity();
3299 try {
3300 synchronized (mGlobalLock) {
3301 final ActivityStack stack =
3302 mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
3303 if (stack == null) {
3304 Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
3305 return;
3306 }
3307
3308 if (toTop) {
3309 // Caller wants the current split-screen primary stack to be the top stack after
3310 // it goes fullscreen, so move it to the front.
3311 stack.moveToFront("dismissSplitScreenMode");
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003312 } else if (mStackSupervisor.isTopDisplayFocusedStack(stack)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003313 // In this case the current split-screen primary stack shouldn't be the top
3314 // stack after it goes fullscreen, but it current has focus, so we move the
3315 // focus to the top-most split-screen secondary stack next to it.
3316 final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
3317 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
3318 if (otherStack != null) {
3319 otherStack.moveToFront("dismissSplitScreenMode_other");
3320 }
3321 }
3322
3323 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
3324 }
3325 } finally {
3326 Binder.restoreCallingIdentity(ident);
3327 }
3328 }
3329
3330 /**
3331 * Dismisses Pip
3332 * @param animate True if the dismissal should be animated.
3333 * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
3334 * default animation duration should be used.
3335 */
3336 @Override
3337 public void dismissPip(boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003338 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003339 final long ident = Binder.clearCallingIdentity();
3340 try {
3341 synchronized (mGlobalLock) {
3342 final PinnedActivityStack stack =
3343 mStackSupervisor.getDefaultDisplay().getPinnedStack();
3344 if (stack == null) {
3345 Slog.w(TAG, "dismissPip: pinned stack not found.");
3346 return;
3347 }
3348 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
3349 throw new IllegalArgumentException("Stack: " + stack
3350 + " doesn't support animated resize.");
3351 }
3352 if (animate) {
3353 stack.animateResizePinnedStack(null /* sourceHintBounds */,
3354 null /* destBounds */, animationDuration, false /* fromFullscreen */);
3355 } else {
3356 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
3357 }
3358 }
3359 } finally {
3360 Binder.restoreCallingIdentity(ident);
3361 }
3362 }
3363
3364 @Override
3365 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003366 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003367 synchronized (mGlobalLock) {
3368 mSuppressResizeConfigChanges = suppress;
3369 }
3370 }
3371
3372 /**
3373 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
3374 * animated the stack to the fullscreen, but can also be called if we are relaunching an
3375 * activity and clearing the task at the same time.
3376 */
3377 @Override
3378 // TODO: API should just be about changing windowing modes...
3379 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003380 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003381 "moveTasksToFullscreenStack()");
3382 synchronized (mGlobalLock) {
3383 final long origId = Binder.clearCallingIdentity();
3384 try {
3385 final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
3386 if (stack != null){
3387 if (!stack.isActivityTypeStandardOrUndefined()) {
3388 throw new IllegalArgumentException(
3389 "You can't move tasks from non-standard stacks.");
3390 }
3391 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
3392 }
3393 } finally {
3394 Binder.restoreCallingIdentity(origId);
3395 }
3396 }
3397 }
3398
3399 /**
3400 * Moves the top activity in the input stackId to the pinned stack.
3401 *
3402 * @param stackId Id of stack to move the top activity to pinned stack.
3403 * @param bounds Bounds to use for pinned stack.
3404 *
3405 * @return True if the top activity of the input stack was successfully moved to the pinned
3406 * stack.
3407 */
3408 @Override
3409 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003410 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003411 "moveTopActivityToPinnedStack()");
3412 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003413 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003414 throw new IllegalStateException("moveTopActivityToPinnedStack:"
3415 + "Device doesn't support picture-in-picture mode");
3416 }
3417
3418 long ident = Binder.clearCallingIdentity();
3419 try {
3420 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
3421 } finally {
3422 Binder.restoreCallingIdentity(ident);
3423 }
3424 }
3425 }
3426
3427 @Override
3428 public boolean isInMultiWindowMode(IBinder token) {
3429 final long origId = Binder.clearCallingIdentity();
3430 try {
3431 synchronized (mGlobalLock) {
3432 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3433 if (r == null) {
3434 return false;
3435 }
3436 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
3437 return r.inMultiWindowMode();
3438 }
3439 } finally {
3440 Binder.restoreCallingIdentity(origId);
3441 }
3442 }
3443
3444 @Override
3445 public boolean isInPictureInPictureMode(IBinder token) {
3446 final long origId = Binder.clearCallingIdentity();
3447 try {
3448 synchronized (mGlobalLock) {
3449 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
3450 }
3451 } finally {
3452 Binder.restoreCallingIdentity(origId);
3453 }
3454 }
3455
3456 private boolean isInPictureInPictureMode(ActivityRecord r) {
3457 if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
3458 || r.getStack().isInStackLocked(r) == null) {
3459 return false;
3460 }
3461
3462 // If we are animating to fullscreen then we have already dispatched the PIP mode
3463 // changed, so we should reflect that check here as well.
3464 final PinnedActivityStack stack = r.getStack();
3465 final PinnedStackWindowController windowController = stack.getWindowContainerController();
3466 return !windowController.isAnimatingBoundsToFullscreen();
3467 }
3468
3469 @Override
3470 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
3471 final long origId = Binder.clearCallingIdentity();
3472 try {
3473 synchronized (mGlobalLock) {
3474 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3475 "enterPictureInPictureMode", token, params);
3476
3477 // If the activity is already in picture in picture mode, then just return early
3478 if (isInPictureInPictureMode(r)) {
3479 return true;
3480 }
3481
3482 // Activity supports picture-in-picture, now check that we can enter PiP at this
3483 // point, if it is
3484 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
3485 false /* beforeStopping */)) {
3486 return false;
3487 }
3488
3489 final Runnable enterPipRunnable = () -> {
Wale Ogunwalef276a6f2018-06-15 08:26:07 -07003490 synchronized (mGlobalLock) {
3491 // Only update the saved args from the args that are set
3492 r.pictureInPictureArgs.copyOnlySet(params);
3493 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
3494 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
3495 // Adjust the source bounds by the insets for the transition down
3496 final Rect sourceBounds = new Rect(
3497 r.pictureInPictureArgs.getSourceRectHint());
3498 mStackSupervisor.moveActivityToPinnedStackLocked(
3499 r, sourceBounds, aspectRatio, "enterPictureInPictureMode");
3500 final PinnedActivityStack stack = r.getStack();
3501 stack.setPictureInPictureAspectRatio(aspectRatio);
3502 stack.setPictureInPictureActions(actions);
3503 MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
3504 r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
3505 logPictureInPictureArgs(params);
3506 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003507 };
3508
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003509 if (isKeyguardLocked()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003510 // If the keyguard is showing or occluded, then try and dismiss it before
3511 // entering picture-in-picture (this will prompt the user to authenticate if the
3512 // device is currently locked).
3513 dismissKeyguard(token, new KeyguardDismissCallback() {
3514 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003515 public void onDismissSucceeded() {
3516 mH.post(enterPipRunnable);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003517 }
3518 }, null /* message */);
3519 } else {
3520 // Enter picture in picture immediately otherwise
3521 enterPipRunnable.run();
3522 }
3523 return true;
3524 }
3525 } finally {
3526 Binder.restoreCallingIdentity(origId);
3527 }
3528 }
3529
3530 @Override
3531 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
3532 final long origId = Binder.clearCallingIdentity();
3533 try {
3534 synchronized (mGlobalLock) {
3535 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3536 "setPictureInPictureParams", token, params);
3537
3538 // Only update the saved args from the args that are set
3539 r.pictureInPictureArgs.copyOnlySet(params);
3540 if (r.inPinnedWindowingMode()) {
3541 // If the activity is already in picture-in-picture, update the pinned stack now
3542 // if it is not already expanding to fullscreen. Otherwise, the arguments will
3543 // be used the next time the activity enters PiP
3544 final PinnedActivityStack stack = r.getStack();
3545 if (!stack.isAnimatingBoundsToFullscreen()) {
3546 stack.setPictureInPictureAspectRatio(
3547 r.pictureInPictureArgs.getAspectRatio());
3548 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
3549 }
3550 }
3551 logPictureInPictureArgs(params);
3552 }
3553 } finally {
3554 Binder.restoreCallingIdentity(origId);
3555 }
3556 }
3557
3558 @Override
3559 public int getMaxNumPictureInPictureActions(IBinder token) {
3560 // Currently, this is a static constant, but later, we may change this to be dependent on
3561 // the context of the activity
3562 return 3;
3563 }
3564
3565 private void logPictureInPictureArgs(PictureInPictureParams params) {
3566 if (params.hasSetActions()) {
3567 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
3568 params.getActions().size());
3569 }
3570 if (params.hasSetAspectRatio()) {
3571 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
3572 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
3573 MetricsLogger.action(lm);
3574 }
3575 }
3576
3577 /**
3578 * Checks the state of the system and the activity associated with the given {@param token} to
3579 * verify that picture-in-picture is supported for that activity.
3580 *
3581 * @return the activity record for the given {@param token} if all the checks pass.
3582 */
3583 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
3584 IBinder token, PictureInPictureParams params) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003585 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003586 throw new IllegalStateException(caller
3587 + ": Device doesn't support picture-in-picture mode.");
3588 }
3589
3590 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3591 if (r == null) {
3592 throw new IllegalStateException(caller
3593 + ": Can't find activity for token=" + token);
3594 }
3595
3596 if (!r.supportsPictureInPicture()) {
3597 throw new IllegalStateException(caller
3598 + ": Current activity does not support picture-in-picture.");
3599 }
3600
3601 if (params.hasSetAspectRatio()
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003602 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003603 params.getAspectRatio())) {
3604 final float minAspectRatio = mContext.getResources().getFloat(
3605 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
3606 final float maxAspectRatio = mContext.getResources().getFloat(
3607 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
3608 throw new IllegalArgumentException(String.format(caller
3609 + ": Aspect ratio is too extreme (must be between %f and %f).",
3610 minAspectRatio, maxAspectRatio));
3611 }
3612
3613 // Truncate the number of actions if necessary
3614 params.truncateActions(getMaxNumPictureInPictureActions(token));
3615
3616 return r;
3617 }
3618
3619 @Override
3620 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003621 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003622 synchronized (mGlobalLock) {
3623 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
3624 if (r == null) {
3625 throw new IllegalArgumentException("Activity does not exist; token="
3626 + activityToken);
3627 }
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07003628 return r.getUriPermissionsLocked().getExternalToken();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003629 }
3630 }
3631
3632 @Override
3633 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
3634 Rect tempDockedTaskInsetBounds,
3635 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003636 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003637 long ident = Binder.clearCallingIdentity();
3638 try {
3639 synchronized (mGlobalLock) {
3640 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
3641 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
3642 PRESERVE_WINDOWS);
3643 }
3644 } finally {
3645 Binder.restoreCallingIdentity(ident);
3646 }
3647 }
3648
3649 @Override
3650 public void setSplitScreenResizing(boolean resizing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003651 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003652 final long ident = Binder.clearCallingIdentity();
3653 try {
3654 synchronized (mGlobalLock) {
3655 mStackSupervisor.setSplitScreenResizing(resizing);
3656 }
3657 } finally {
3658 Binder.restoreCallingIdentity(ident);
3659 }
3660 }
3661
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003662 /**
3663 * Check that we have the features required for VR-related API calls, and throw an exception if
3664 * not.
3665 */
3666 void enforceSystemHasVrFeature() {
3667 if (!mContext.getPackageManager().hasSystemFeature(
3668 PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
3669 throw new UnsupportedOperationException("VR mode not supported on this device!");
3670 }
3671 }
3672
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003673 @Override
3674 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003675 enforceSystemHasVrFeature();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003676
3677 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3678
3679 ActivityRecord r;
3680 synchronized (mGlobalLock) {
3681 r = ActivityRecord.isInStackLocked(token);
3682 }
3683
3684 if (r == null) {
3685 throw new IllegalArgumentException();
3686 }
3687
3688 int err;
3689 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
3690 VrManagerInternal.NO_ERROR) {
3691 return err;
3692 }
3693
3694 // Clear the binder calling uid since this path may call moveToTask().
3695 final long callingId = Binder.clearCallingIdentity();
3696 try {
3697 synchronized (mGlobalLock) {
3698 r.requestedVrComponent = (enabled) ? packageName : null;
3699
3700 // Update associated state if this activity is currently focused
Andrii Kulian52d255c2018-07-13 11:32:19 -07003701 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003702 applyUpdateVrModeLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003703 }
3704 return 0;
3705 }
3706 } finally {
3707 Binder.restoreCallingIdentity(callingId);
3708 }
3709 }
3710
3711 @Override
3712 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
3713 Slog.i(TAG, "Activity tried to startLocalVoiceInteraction");
3714 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003715 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003716 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
3717 throw new SecurityException("Only focused activity can call startVoiceInteraction");
3718 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07003719 if (mRunningVoice != null || activity.getTask().voiceSession != null
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003720 || activity.voiceSession != null) {
3721 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
3722 return;
3723 }
3724 if (activity.pendingVoiceInteractionStart) {
3725 Slog.w(TAG, "Pending start of voice interaction already.");
3726 return;
3727 }
3728 activity.pendingVoiceInteractionStart = true;
3729 }
3730 LocalServices.getService(VoiceInteractionManagerInternal.class)
3731 .startLocalVoiceInteraction(callingActivity, options);
3732 }
3733
3734 @Override
3735 public void stopLocalVoiceInteraction(IBinder callingActivity) {
3736 LocalServices.getService(VoiceInteractionManagerInternal.class)
3737 .stopLocalVoiceInteraction(callingActivity);
3738 }
3739
3740 @Override
3741 public boolean supportsLocalVoiceInteraction() {
3742 return LocalServices.getService(VoiceInteractionManagerInternal.class)
3743 .supportsLocalVoiceInteraction();
3744 }
3745
3746 /** Notifies all listeners when the pinned stack animation starts. */
3747 @Override
3748 public void notifyPinnedStackAnimationStarted() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003749 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003750 }
3751
3752 /** Notifies all listeners when the pinned stack animation ends. */
3753 @Override
3754 public void notifyPinnedStackAnimationEnded() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003755 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003756 }
3757
3758 @Override
3759 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003760 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003761 final long ident = Binder.clearCallingIdentity();
3762 try {
3763 synchronized (mGlobalLock) {
3764 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
3765 }
3766 } finally {
3767 Binder.restoreCallingIdentity(ident);
3768 }
3769 }
3770
3771 @Override
3772 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003773 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003774
3775 synchronized (mGlobalLock) {
3776 // Check if display is initialized in AM.
3777 if (!mStackSupervisor.isDisplayAdded(displayId)) {
3778 // Call might come when display is not yet added or has already been removed.
3779 if (DEBUG_CONFIGURATION) {
3780 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
3781 + displayId);
3782 }
3783 return false;
3784 }
3785
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003786 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003787 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003788 values = mWindowManager.computeNewConfiguration(displayId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003789 }
3790
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003791 if (mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003792 // Update OOM levels based on display size.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003793 mAm.mProcessList.applyDisplaySize(mWindowManager);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003794 }
3795
3796 final long origId = Binder.clearCallingIdentity();
3797 try {
3798 if (values != null) {
3799 Settings.System.clearConfiguration(values);
3800 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003801 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003802 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
3803 return mTmpUpdateConfigurationResult.changes != 0;
3804 } finally {
3805 Binder.restoreCallingIdentity(origId);
3806 }
3807 }
3808 }
3809
3810 @Override
3811 public boolean updateConfiguration(Configuration values) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003812 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003813
3814 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003815 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003816 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003817 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003818 }
3819
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003820 if (mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003821 // Update OOM levels based on display size.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003822 mAm.mProcessList.applyDisplaySize(mWindowManager);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003823 }
3824
3825 final long origId = Binder.clearCallingIdentity();
3826 try {
3827 if (values != null) {
3828 Settings.System.clearConfiguration(values);
3829 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003830 updateConfigurationLocked(values, null, false, false /* persistent */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003831 UserHandle.USER_NULL, false /* deferResume */,
3832 mTmpUpdateConfigurationResult);
3833 return mTmpUpdateConfigurationResult.changes != 0;
3834 } finally {
3835 Binder.restoreCallingIdentity(origId);
3836 }
3837 }
3838 }
3839
3840 @Override
3841 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
3842 CharSequence message) {
3843 if (message != null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003844 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003845 Manifest.permission.SHOW_KEYGUARD_MESSAGE, "dismissKeyguard()");
3846 }
3847 final long callingId = Binder.clearCallingIdentity();
3848 try {
3849 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003850 mKeyguardController.dismissKeyguard(token, callback, message);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003851 }
3852 } finally {
3853 Binder.restoreCallingIdentity(callingId);
3854 }
3855 }
3856
3857 @Override
3858 public void cancelTaskWindowTransition(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003859 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003860 "cancelTaskWindowTransition()");
3861 final long ident = Binder.clearCallingIdentity();
3862 try {
3863 synchronized (mGlobalLock) {
3864 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
3865 MATCH_TASK_IN_STACKS_ONLY);
3866 if (task == null) {
3867 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
3868 return;
3869 }
3870 task.cancelWindowTransition();
3871 }
3872 } finally {
3873 Binder.restoreCallingIdentity(ident);
3874 }
3875 }
3876
3877 @Override
3878 public ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003879 enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003880 final long ident = Binder.clearCallingIdentity();
3881 try {
3882 final TaskRecord task;
3883 synchronized (mGlobalLock) {
3884 task = mStackSupervisor.anyTaskForIdLocked(taskId,
3885 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
3886 if (task == null) {
3887 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
3888 return null;
3889 }
3890 }
3891 // Don't call this while holding the lock as this operation might hit the disk.
3892 return task.getSnapshot(reducedResolution);
3893 } finally {
3894 Binder.restoreCallingIdentity(ident);
3895 }
3896 }
3897
3898 @Override
3899 public void setDisablePreviewScreenshots(IBinder token, boolean disable) {
3900 synchronized (mGlobalLock) {
3901 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3902 if (r == null) {
3903 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
3904 + token);
3905 return;
3906 }
3907 final long origId = Binder.clearCallingIdentity();
3908 try {
3909 r.setDisablePreviewScreenshots(disable);
3910 } finally {
3911 Binder.restoreCallingIdentity(origId);
3912 }
3913 }
3914 }
3915
3916 /** Return the user id of the last resumed activity. */
3917 @Override
3918 public @UserIdInt
3919 int getLastResumedActivityUserId() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003920 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003921 Manifest.permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
3922 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07003923 if (mLastResumedActivity == null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003924 return getCurrentUserId();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003925 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07003926 return mLastResumedActivity.userId;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003927 }
3928 }
3929
3930 @Override
3931 public void updateLockTaskFeatures(int userId, int flags) {
3932 final int callingUid = Binder.getCallingUid();
3933 if (callingUid != 0 && callingUid != SYSTEM_UID) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003934 mAmInternal.enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003935 "updateLockTaskFeatures()");
3936 }
3937 synchronized (mGlobalLock) {
3938 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
3939 Integer.toHexString(flags));
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003940 getLockTaskController().updateLockTaskFeatures(userId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003941 }
3942 }
3943
3944 @Override
3945 public void setShowWhenLocked(IBinder token, boolean showWhenLocked) {
3946 synchronized (mGlobalLock) {
3947 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3948 if (r == null) {
3949 return;
3950 }
3951 final long origId = Binder.clearCallingIdentity();
3952 try {
3953 r.setShowWhenLocked(showWhenLocked);
3954 } finally {
3955 Binder.restoreCallingIdentity(origId);
3956 }
3957 }
3958 }
3959
3960 @Override
3961 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) {
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.setTurnScreenOn(turnScreenOn);
3970 } finally {
3971 Binder.restoreCallingIdentity(origId);
3972 }
3973 }
3974 }
3975
3976 @Override
3977 public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003978 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003979 "registerRemoteAnimations");
3980 definition.setCallingPid(Binder.getCallingPid());
3981 synchronized (mGlobalLock) {
3982 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3983 if (r == null) {
3984 return;
3985 }
3986 final long origId = Binder.clearCallingIdentity();
3987 try {
3988 r.registerRemoteAnimations(definition);
3989 } finally {
3990 Binder.restoreCallingIdentity(origId);
3991 }
3992 }
3993 }
3994
3995 @Override
3996 public void registerRemoteAnimationForNextActivityStart(String packageName,
3997 RemoteAnimationAdapter adapter) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003998 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003999 "registerRemoteAnimationForNextActivityStart");
4000 adapter.setCallingPid(Binder.getCallingPid());
4001 synchronized (mGlobalLock) {
4002 final long origId = Binder.clearCallingIdentity();
4003 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07004004 getActivityStartController().registerRemoteAnimationForNextActivityStart(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004005 packageName, adapter);
4006 } finally {
4007 Binder.restoreCallingIdentity(origId);
4008 }
4009 }
4010 }
4011
4012 /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
4013 @Override
4014 public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
4015 synchronized (mGlobalLock) {
4016 final long origId = Binder.clearCallingIdentity();
4017 try {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004018 mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004019 } finally {
4020 Binder.restoreCallingIdentity(origId);
4021 }
4022 }
4023 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004024
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004025 @Override
4026 public void setVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004027 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004028 synchronized (mGlobalLock) {
4029 synchronized (mAm.mPidsSelfLocked) {
4030 final int pid = Binder.getCallingPid();
4031 final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004032 mVrController.setVrThreadLocked(tid, pid, proc.getWindowProcessController());
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004033 }
4034 }
4035 }
4036
4037 @Override
4038 public void setPersistentVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004039 if (checkCallingPermission(Manifest.permission.RESTRICTED_VR_ACCESS)
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004040 != PERMISSION_GRANTED) {
4041 final String msg = "Permission Denial: setPersistentVrThread() from pid="
4042 + Binder.getCallingPid()
4043 + ", uid=" + Binder.getCallingUid()
4044 + " requires " + Manifest.permission.RESTRICTED_VR_ACCESS;
4045 Slog.w(TAG, msg);
4046 throw new SecurityException(msg);
4047 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004048 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004049 synchronized (mGlobalLock) {
4050 synchronized (mAm.mPidsSelfLocked) {
4051 final int pid = Binder.getCallingPid();
4052 final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
4053 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
4054 }
4055 }
4056 }
4057
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004058 @Override
4059 public void stopAppSwitches() {
4060 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
4061 synchronized (mGlobalLock) {
4062 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME;
4063 mDidAppSwitch = false;
4064 getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
4065 }
4066 }
4067
4068 @Override
4069 public void resumeAppSwitches() {
4070 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
4071 synchronized (mGlobalLock) {
4072 // Note that we don't execute any pending app switches... we will
4073 // let those wait until either the timeout, or the next start
4074 // activity request.
4075 mAppSwitchesAllowedTime = 0;
4076 }
4077 }
4078
4079 void onStartActivitySetDidAppSwitch() {
4080 if (mDidAppSwitch) {
4081 // This is the second allowed switch since we stopped switches, so now just generally
4082 // allow switches. Use case:
4083 // - user presses home (switches disabled, switch to home, mDidAppSwitch now true);
4084 // - user taps a home icon (coming from home so allowed, we hit here and now allow
4085 // anyone to switch again).
4086 mAppSwitchesAllowedTime = 0;
4087 } else {
4088 mDidAppSwitch = true;
4089 }
4090 }
4091
4092 /** @return whether the system should disable UI modes incompatible with VR mode. */
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004093 boolean shouldDisableNonVrUiLocked() {
4094 return mVrController.shouldDisableNonVrUiLocked();
4095 }
4096
4097 void applyUpdateVrModeLocked(ActivityRecord r) {
4098 // VR apps are expected to run in a main display. If an app is turning on VR for
4099 // itself, but lives in a dynamic stack, then make sure that it is moved to the main
4100 // fullscreen stack before enabling VR Mode.
4101 // TODO: The goal of this code is to keep the VR app on the main display. When the
4102 // stack implementation changes in the future, keep in mind that the use of the fullscreen
4103 // stack is a means to move the activity to the main display and a moveActivityToDisplay()
4104 // option would be a better choice here.
4105 if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
4106 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
4107 + " to main stack for VR");
4108 final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
4109 WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
4110 moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
4111 }
4112 mH.post(() -> {
4113 if (!mVrController.onVrModeChanged(r)) {
4114 return;
4115 }
4116 synchronized (mGlobalLock) {
4117 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
4118 mWindowManager.disableNonVrUi(disableNonVrUi);
4119 if (disableNonVrUi) {
4120 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
4121 // then remove the pinned stack.
4122 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
4123 }
4124 }
4125 });
4126 }
4127
Andrii Kulian5f750bc2018-07-17 08:57:23 -07004128 ActivityStack getTopDisplayFocusedStack() {
4129 return mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004130 }
4131
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004132 /** Pokes the task persister. */
4133 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
4134 mRecentTasks.notifyTaskPersisterLocked(task, flush);
4135 }
4136
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004137 void onTopProcChangedLocked(WindowProcessController proc) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004138 mVrController.onTopProcChangedLocked(proc);
4139 }
4140
4141 boolean isKeyguardLocked() {
4142 return mKeyguardController.isKeyguardLocked();
4143 }
4144
4145 boolean isNextTransitionForward() {
4146 int transit = mWindowManager.getPendingAppTransition();
4147 return transit == TRANSIT_ACTIVITY_OPEN
4148 || transit == TRANSIT_TASK_OPEN
4149 || transit == TRANSIT_TASK_TO_FRONT;
4150 }
4151
Wale Ogunwalef6733932018-06-27 05:14:34 -07004152 void dumpSleepStates(PrintWriter pw, boolean testPssMode) {
4153 synchronized (mGlobalLock) {
4154 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
4155 if (mRunningVoice != null) {
4156 pw.println(" mRunningVoice=" + mRunningVoice);
4157 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
4158 }
4159 pw.println(" mSleeping=" + mSleeping);
4160 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + testPssMode);
4161 pw.println(" mVrController=" + mVrController);
4162 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004163 }
4164
Wale Ogunwalef6733932018-06-27 05:14:34 -07004165 void writeSleepStateToProto(ProtoOutputStream proto) {
4166 for (ActivityTaskManagerInternal.SleepToken st : mStackSupervisor.mSleepTokens) {
4167 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS,
4168 st.toString());
4169 }
4170
4171 if (mRunningVoice != null) {
4172 final long vrToken = proto.start(
4173 ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
4174 proto.write(ActivityManagerServiceDumpProcessesProto.Voice.SESSION,
4175 mRunningVoice.toString());
4176 mVoiceWakeLock.writeToProto(
4177 proto, ActivityManagerServiceDumpProcessesProto.Voice.WAKELOCK);
4178 proto.end(vrToken);
4179 }
4180
4181 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
4182 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN,
4183 mShuttingDown);
4184 mVrController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004185 }
4186
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004187 int getCurrentUserId() {
4188 return mAmInternal.getCurrentUserId();
4189 }
4190
4191 private void enforceNotIsolatedCaller(String caller) {
4192 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4193 throw new SecurityException("Isolated process not allowed to call " + caller);
4194 }
4195 }
4196
Wale Ogunwalef6733932018-06-27 05:14:34 -07004197 public Configuration getConfiguration() {
4198 Configuration ci;
4199 synchronized(mGlobalLock) {
4200 ci = new Configuration(getGlobalConfiguration());
4201 ci.userSetLocale = false;
4202 }
4203 return ci;
4204 }
4205
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004206 /**
4207 * Current global configuration information. Contains general settings for the entire system,
4208 * also corresponds to the merged configuration of the default display.
4209 */
4210 Configuration getGlobalConfiguration() {
4211 return mStackSupervisor.getConfiguration();
4212 }
4213
4214 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4215 boolean initLocale) {
4216 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
4217 }
4218
4219 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4220 boolean initLocale, boolean deferResume) {
4221 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
4222 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
4223 UserHandle.USER_NULL, deferResume);
4224 }
4225
4226 void updatePersistentConfiguration(Configuration values, @UserIdInt int userId) {
4227 final long origId = Binder.clearCallingIdentity();
4228 try {
4229 synchronized (mGlobalLock) {
4230 updateConfigurationLocked(values, null, false, true, userId,
4231 false /* deferResume */);
4232 }
4233 } finally {
4234 Binder.restoreCallingIdentity(origId);
4235 }
4236 }
4237
4238 void updateUserConfiguration() {
4239 synchronized (mGlobalLock) {
4240 final Configuration configuration = new Configuration(getGlobalConfiguration());
4241 final int currentUserId = mAmInternal.getCurrentUserId();
4242 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
4243 currentUserId, Settings.System.canWrite(mContext));
4244 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
4245 false /* persistent */, currentUserId, false /* deferResume */);
4246 }
4247 }
4248
4249 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4250 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
4251 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
4252 deferResume, null /* result */);
4253 }
4254
4255 /**
4256 * Do either or both things: (1) change the current configuration, and (2)
4257 * make sure the given activity is running with the (now) current
4258 * configuration. Returns true if the activity has been left running, or
4259 * false if <var>starting</var> is being destroyed to match the new
4260 * configuration.
4261 *
4262 * @param userId is only used when persistent parameter is set to true to persist configuration
4263 * for that particular user
4264 */
4265 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4266 boolean initLocale, boolean persistent, int userId, boolean deferResume,
4267 ActivityTaskManagerService.UpdateConfigurationResult result) {
4268 int changes = 0;
4269 boolean kept = true;
4270
4271 if (mWindowManager != null) {
4272 mWindowManager.deferSurfaceLayout();
4273 }
4274 try {
4275 if (values != null) {
4276 changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
4277 deferResume);
4278 }
4279
4280 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4281 } finally {
4282 if (mWindowManager != null) {
4283 mWindowManager.continueSurfaceLayout();
4284 }
4285 }
4286
4287 if (result != null) {
4288 result.changes = changes;
4289 result.activityRelaunched = !kept;
4290 }
4291 return kept;
4292 }
4293
4294 /**
4295 * Returns true if this configuration change is interesting enough to send an
4296 * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
4297 */
4298 private static boolean isSplitConfigurationChange(int configDiff) {
4299 return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
4300 }
4301
4302 /** Update default (global) configuration and notify listeners about changes. */
4303 private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
4304 boolean persistent, int userId, boolean deferResume) {
4305 mTempConfig.setTo(getGlobalConfiguration());
4306 final int changes = mTempConfig.updateFrom(values);
4307 if (changes == 0) {
4308 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
4309 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
4310 // performDisplayOverrideConfigUpdate in order to send the new display configuration
4311 // (even if there are no actual changes) to unfreeze the window.
4312 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
4313 return 0;
4314 }
4315
4316 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
4317 "Updating global configuration to: " + values);
4318
4319 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
4320 StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
4321 values.colorMode,
4322 values.densityDpi,
4323 values.fontScale,
4324 values.hardKeyboardHidden,
4325 values.keyboard,
4326 values.keyboardHidden,
4327 values.mcc,
4328 values.mnc,
4329 values.navigation,
4330 values.navigationHidden,
4331 values.orientation,
4332 values.screenHeightDp,
4333 values.screenLayout,
4334 values.screenWidthDp,
4335 values.smallestScreenWidthDp,
4336 values.touchscreen,
4337 values.uiMode);
4338
4339
4340 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
4341 final LocaleList locales = values.getLocales();
4342 int bestLocaleIndex = 0;
4343 if (locales.size() > 1) {
4344 if (mSupportedSystemLocales == null) {
4345 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
4346 }
4347 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
4348 }
4349 SystemProperties.set("persist.sys.locale",
4350 locales.get(bestLocaleIndex).toLanguageTag());
4351 LocaleList.setDefault(locales, bestLocaleIndex);
4352 mAm.mHandler.sendMessage(mAm.mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
4353 locales.get(bestLocaleIndex)));
4354 }
4355
4356 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
4357 mTempConfig.seq = mConfigurationSeq;
4358
4359 // Update stored global config and notify everyone about the change.
4360 mStackSupervisor.onConfigurationChanged(mTempConfig);
4361
4362 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
4363 // TODO(multi-display): Update UsageEvents#Event to include displayId.
4364 mAm.mUsageStatsService.reportConfigurationChange(
4365 mTempConfig, mAmInternal.getCurrentUserId());
4366
4367 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
Wale Ogunwalef6733932018-06-27 05:14:34 -07004368 updateShouldShowDialogsLocked(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004369
4370 AttributeCache ac = AttributeCache.instance();
4371 if (ac != null) {
4372 ac.updateConfiguration(mTempConfig);
4373 }
4374
4375 // Make sure all resources in our process are updated right now, so that anyone who is going
4376 // to retrieve resource values after we return will be sure to get the new ones. This is
4377 // especially important during boot, where the first config change needs to guarantee all
4378 // resources have that config before following boot code is executed.
4379 mAm.mSystemThread.applyConfigurationToResources(mTempConfig);
4380
4381 // We need another copy of global config because we're scheduling some calls instead of
4382 // running them in place. We need to be sure that object we send will be handled unchanged.
4383 final Configuration configCopy = new Configuration(mTempConfig);
4384 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
4385 Message msg = mAm.mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
4386 msg.obj = configCopy;
4387 msg.arg1 = userId;
4388 mAm.mHandler.sendMessage(msg);
4389 }
4390
4391 for (int i = mAm.mLruProcesses.size() - 1; i >= 0; i--) {
4392 ProcessRecord app = mAm.mLruProcesses.get(i);
4393 try {
4394 if (app.thread != null) {
4395 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
4396 + app.processName + " new config " + configCopy);
4397 getLifecycleManager().scheduleTransaction(app.thread,
4398 ConfigurationChangeItem.obtain(configCopy));
4399 }
4400 } catch (Exception e) {
4401 Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
4402 }
4403 }
4404
4405 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
4406 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
4407 | Intent.FLAG_RECEIVER_FOREGROUND
4408 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4409 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4410 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4411 UserHandle.USER_ALL);
4412 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
4413 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
4414 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
4415 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
4416 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4417 if (initLocale || !mAm.mProcessesReady) {
4418 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
4419 }
4420 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4421 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4422 UserHandle.USER_ALL);
4423 }
4424
4425 // Send a broadcast to PackageInstallers if the configuration change is interesting
4426 // for the purposes of installing additional splits.
4427 if (!initLocale && isSplitConfigurationChange(changes)) {
4428 intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
4429 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
4430 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
4431
4432 // Typically only app stores will have this permission.
4433 String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES };
4434 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions,
4435 OP_NONE, null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
4436 }
4437
4438 // Override configuration of the default display duplicates global config, so we need to
4439 // update it also. This will also notify WindowManager about changes.
4440 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
4441 DEFAULT_DISPLAY);
4442
4443 return changes;
4444 }
4445
4446 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
4447 boolean deferResume, int displayId) {
4448 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
4449 displayId, null /* result */);
4450 }
4451
4452 /**
4453 * Updates override configuration specific for the selected display. If no config is provided,
4454 * new one will be computed in WM based on current display info.
4455 */
4456 boolean updateDisplayOverrideConfigurationLocked(Configuration values,
4457 ActivityRecord starting, boolean deferResume, int displayId,
4458 ActivityTaskManagerService.UpdateConfigurationResult result) {
4459 int changes = 0;
4460 boolean kept = true;
4461
4462 if (mWindowManager != null) {
4463 mWindowManager.deferSurfaceLayout();
4464 }
4465 try {
4466 if (values != null) {
4467 if (displayId == DEFAULT_DISPLAY) {
4468 // Override configuration of the default display duplicates global config, so
4469 // we're calling global config update instead for default display. It will also
4470 // apply the correct override config.
4471 changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
4472 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
4473 } else {
4474 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
4475 }
4476 }
4477
4478 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4479 } finally {
4480 if (mWindowManager != null) {
4481 mWindowManager.continueSurfaceLayout();
4482 }
4483 }
4484
4485 if (result != null) {
4486 result.changes = changes;
4487 result.activityRelaunched = !kept;
4488 }
4489 return kept;
4490 }
4491
4492 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
4493 int displayId) {
4494 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
4495 final int changes = mTempConfig.updateFrom(values);
4496 if (changes != 0) {
4497 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
4498 + mTempConfig + " for displayId=" + displayId);
4499 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
4500
4501 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
4502 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004503 mAppWarnings.onDensityChanged();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004504
4505 mAm.killAllBackgroundProcessesExcept(N,
4506 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
4507 }
4508 }
4509
4510 // Update the configuration with WM first and check if any of the stacks need to be resized
4511 // due to the configuration change. If so, resize the stacks now and do any relaunches if
4512 // necessary. This way we don't need to relaunch again afterwards in
4513 // ensureActivityConfiguration().
4514 if (mWindowManager != null) {
4515 final int[] resizedStacks =
4516 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
4517 if (resizedStacks != null) {
4518 for (int stackId : resizedStacks) {
4519 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
4520 }
4521 }
4522 }
4523
4524 return changes;
4525 }
4526
Wale Ogunwalef6733932018-06-27 05:14:34 -07004527 private void updateEventDispatchingLocked(boolean booted) {
4528 mWindowManager.setEventDispatching(booted && !mShuttingDown);
4529 }
4530
4531 void enableScreenAfterBoot(boolean booted) {
4532 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4533 SystemClock.uptimeMillis());
4534 mWindowManager.enableScreenAfterBoot();
4535
4536 synchronized (mGlobalLock) {
4537 updateEventDispatchingLocked(booted);
4538 }
4539 }
4540
4541 boolean canShowErrorDialogs() {
4542 return mShowDialogs && !mSleeping && !mShuttingDown
4543 && !mKeyguardController.isKeyguardOrAodShowing(DEFAULT_DISPLAY)
4544 && !hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
Wale Ogunwale86b74462018-07-02 08:42:43 -07004545 mAmInternal.getCurrentUserId())
Wale Ogunwalef6733932018-06-27 05:14:34 -07004546 && !(UserManager.isDeviceInDemoMode(mContext)
Wale Ogunwale86b74462018-07-02 08:42:43 -07004547 && mAmInternal.getCurrentUser().isDemo());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004548 }
4549
Wale Ogunwale906f9c62018-07-23 11:23:44 -07004550 static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
4551 if (r == null || !r.hasProcess()) {
4552 return KEY_DISPATCHING_TIMEOUT_MS;
4553 }
4554 return getInputDispatchingTimeoutLocked(r.app);
4555 }
4556
4557 private static long getInputDispatchingTimeoutLocked(WindowProcessController r) {
4558 if (r != null && (r.isInstrumenting() || r.isUsingWrapper())) {
4559 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS;
4560 }
4561 return KEY_DISPATCHING_TIMEOUT_MS;
4562 }
4563
4564 long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
4565 if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
4566 throw new SecurityException("Requires permission " + FILTER_EVENTS);
4567 }
4568 WindowProcessController proc;
4569 long timeout;
4570 synchronized (mGlobalLock) {
4571 proc = mPidMap.get(pid);
4572 timeout = getInputDispatchingTimeoutLocked(proc);
4573 }
4574
4575 if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
4576 return -1;
4577 }
4578
4579 return timeout;
4580 }
4581
4582 /**
4583 * Handle input dispatching timeouts.
4584 * Returns whether input dispatching should be aborted or not.
4585 */
4586 boolean inputDispatchingTimedOut(final WindowProcessController proc,
4587 final ActivityRecord activity, final ActivityRecord parent,
4588 final boolean aboveSystem, String reason) {
4589 if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
4590 throw new SecurityException("Requires permission " + FILTER_EVENTS);
4591 }
4592
4593 final String annotation;
4594 if (reason == null) {
4595 annotation = "Input dispatching timed out";
4596 } else {
4597 annotation = "Input dispatching timed out (" + reason + ")";
4598 }
4599
4600 if (proc != null) {
4601 synchronized (mGlobalLock) {
4602 if (proc.isDebugging()) {
4603 return false;
4604 }
4605
4606 if (proc.isInstrumenting()) {
4607 Bundle info = new Bundle();
4608 info.putString("shortMsg", "keyDispatchingTimedOut");
4609 info.putString("longMsg", annotation);
4610 mAm.finishInstrumentationLocked(
4611 (ProcessRecord) proc.mOwner, Activity.RESULT_CANCELED, info);
4612 return true;
4613 }
4614 }
4615 mH.post(() -> {
4616 mAm.mAppErrors.appNotResponding(
4617 (ProcessRecord) proc.mOwner, activity, parent, aboveSystem, annotation);
4618 });
4619 }
4620
4621 return true;
4622 }
4623
Wale Ogunwalef6733932018-06-27 05:14:34 -07004624 /**
4625 * Decide based on the configuration whether we should show the ANR,
4626 * crash, etc dialogs. The idea is that if there is no affordance to
4627 * press the on-screen buttons, or the user experience would be more
4628 * greatly impacted than the crash itself, we shouldn't show the dialog.
4629 *
4630 * A thought: SystemUI might also want to get told about this, the Power
4631 * dialog / global actions also might want different behaviors.
4632 */
4633 private void updateShouldShowDialogsLocked(Configuration config) {
4634 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
4635 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
4636 && config.navigation == Configuration.NAVIGATION_NONAV);
4637 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
4638 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
4639 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
4640 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
4641 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
4642 final boolean hideDialogsSet = Settings.Global.getInt(mContext.getContentResolver(),
4643 HIDE_ERROR_DIALOGS, 0) != 0;
4644 mShowDialogs = inputMethodExists && uiModeSupportsDialogs && !hideDialogsSet;
4645 }
4646
4647 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
4648 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
4649 FONT_SCALE, 1.0f, userId);
4650
4651 synchronized (this) {
4652 if (getGlobalConfiguration().fontScale == scaleFactor) {
4653 return;
4654 }
4655
4656 final Configuration configuration
4657 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
4658 configuration.fontScale = scaleFactor;
4659 updatePersistentConfiguration(configuration, userId);
4660 }
4661 }
4662
4663 // Actually is sleeping or shutting down or whatever else in the future
4664 // is an inactive state.
4665 boolean isSleepingOrShuttingDownLocked() {
4666 return isSleepingLocked() || mShuttingDown;
4667 }
4668
4669 boolean isSleepingLocked() {
4670 return mSleeping;
4671 }
4672
4673 /**
4674 * Update AMS states when an activity is resumed. This should only be called by
4675 * {@link ActivityStack#onActivityStateChanged(
4676 * ActivityRecord, ActivityStack.ActivityState, String)} when an activity is resumed.
4677 */
4678 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
4679 final TaskRecord task = r.getTask();
4680 if (task.isActivityTypeStandard()) {
4681 if (mCurAppTimeTracker != r.appTimeTracker) {
4682 // We are switching app tracking. Complete the current one.
4683 if (mCurAppTimeTracker != null) {
4684 mCurAppTimeTracker.stop();
4685 mH.obtainMessage(
4686 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
4687 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
4688 mCurAppTimeTracker = null;
4689 }
4690 if (r.appTimeTracker != null) {
4691 mCurAppTimeTracker = r.appTimeTracker;
4692 startTimeTrackingFocusedActivityLocked();
4693 }
4694 } else {
4695 startTimeTrackingFocusedActivityLocked();
4696 }
4697 } else {
4698 r.appTimeTracker = null;
4699 }
4700 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
4701 // TODO: Probably not, because we don't want to resume voice on switching
4702 // back to this activity
4703 if (task.voiceInteractor != null) {
4704 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
4705 } else {
4706 finishRunningVoiceLocked();
4707
4708 if (mLastResumedActivity != null) {
4709 final IVoiceInteractionSession session;
4710
4711 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
4712 if (lastResumedActivityTask != null
4713 && lastResumedActivityTask.voiceSession != null) {
4714 session = lastResumedActivityTask.voiceSession;
4715 } else {
4716 session = mLastResumedActivity.voiceSession;
4717 }
4718
4719 if (session != null) {
4720 // We had been in a voice interaction session, but now focused has
4721 // move to something different. Just finish the session, we can't
4722 // return to it and retain the proper state and synchronization with
4723 // the voice interaction service.
4724 finishVoiceTask(session);
4725 }
4726 }
4727 }
4728
4729 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
4730 mAmInternal.sendForegroundProfileChanged(r.userId);
4731 }
4732 updateResumedAppTrace(r);
4733 mLastResumedActivity = r;
4734
Riddle Hsu3026e8d2018-08-03 15:50:53 +08004735 // TODO(b/111361570): Support multiple focused apps in WM
Wale Ogunwalef6733932018-06-27 05:14:34 -07004736 mWindowManager.setFocusedApp(r.appToken, true);
4737
4738 applyUpdateLockStateLocked(r);
4739 applyUpdateVrModeLocked(r);
4740
4741 EventLogTags.writeAmSetResumedActivity(
4742 r == null ? -1 : r.userId,
4743 r == null ? "NULL" : r.shortComponentName,
4744 reason);
4745 }
4746
4747 ActivityTaskManagerInternal.SleepToken acquireSleepToken(String tag, int displayId) {
4748 synchronized (mGlobalLock) {
4749 final ActivityTaskManagerInternal.SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
4750 updateSleepIfNeededLocked();
4751 return token;
4752 }
4753 }
4754
4755 void updateSleepIfNeededLocked() {
4756 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
4757 final boolean wasSleeping = mSleeping;
4758 boolean updateOomAdj = false;
4759
4760 if (!shouldSleep) {
4761 // If wasSleeping is true, we need to wake up activity manager state from when
4762 // we started sleeping. In either case, we need to apply the sleep tokens, which
4763 // will wake up stacks or put them to sleep as appropriate.
4764 if (wasSleeping) {
4765 mSleeping = false;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07004766 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
4767 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__AWAKE);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004768 startTimeTrackingFocusedActivityLocked();
4769 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
4770 mStackSupervisor.comeOutOfSleepIfNeededLocked();
4771 }
4772 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
4773 if (wasSleeping) {
4774 updateOomAdj = true;
4775 }
4776 } else if (!mSleeping && shouldSleep) {
4777 mSleeping = true;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07004778 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
4779 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__ASLEEP);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004780 if (mCurAppTimeTracker != null) {
4781 mCurAppTimeTracker.stop();
4782 }
4783 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
4784 mStackSupervisor.goingToSleepLocked();
4785 updateResumedAppTrace(null /* resumed */);
4786 updateOomAdj = true;
4787 }
4788 if (updateOomAdj) {
4789 mH.post(mAmInternal::updateOomAdj);
4790 }
4791 }
4792
4793 void updateOomAdj() {
4794 mH.post(mAmInternal::updateOomAdj);
4795 }
4796
Andrii Kulian52d255c2018-07-13 11:32:19 -07004797 // TODO(b/111541062): Update app time tracking to make it aware of multiple resumed activities
Wale Ogunwalef6733932018-06-27 05:14:34 -07004798 private void startTimeTrackingFocusedActivityLocked() {
Andrii Kulian52d255c2018-07-13 11:32:19 -07004799 final ActivityRecord resumedActivity = mStackSupervisor.getTopResumedActivity();
Wale Ogunwalef6733932018-06-27 05:14:34 -07004800 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
4801 mCurAppTimeTracker.start(resumedActivity.packageName);
4802 }
4803 }
4804
4805 private void updateResumedAppTrace(@Nullable ActivityRecord resumed) {
4806 if (mTracedResumedActivity != null) {
4807 Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER,
4808 constructResumedTraceName(mTracedResumedActivity.packageName), 0);
4809 }
4810 if (resumed != null) {
4811 Trace.asyncTraceBegin(TRACE_TAG_ACTIVITY_MANAGER,
4812 constructResumedTraceName(resumed.packageName), 0);
4813 }
4814 mTracedResumedActivity = resumed;
4815 }
4816
4817 private String constructResumedTraceName(String packageName) {
4818 return "focused app: " + packageName;
4819 }
4820
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004821 /** Helper method that requests bounds from WM and applies them to stack. */
4822 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
4823 final Rect newStackBounds = new Rect();
4824 final ActivityStack stack = mStackSupervisor.getStack(stackId);
4825
4826 // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
4827 if (stack == null) {
4828 final StringWriter writer = new StringWriter();
4829 final PrintWriter printWriter = new PrintWriter(writer);
4830 mStackSupervisor.dumpDisplays(printWriter);
4831 printWriter.flush();
4832
4833 Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
4834 }
4835
4836 stack.getBoundsForNewConfiguration(newStackBounds);
4837 mStackSupervisor.resizeStackLocked(
4838 stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
4839 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
4840 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
4841 }
4842
4843 /** Applies latest configuration and/or visibility updates if needed. */
4844 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
4845 boolean kept = true;
Andrii Kulian5f750bc2018-07-17 08:57:23 -07004846 final ActivityStack mainStack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004847 // mainStack is null during startup.
4848 if (mainStack != null) {
4849 if (changes != 0 && starting == null) {
4850 // If the configuration changed, and the caller is not already
4851 // in the process of starting an activity, then find the top
4852 // activity to check if its configuration needs to change.
4853 starting = mainStack.topRunningActivityLocked();
4854 }
4855
4856 if (starting != null) {
4857 kept = starting.ensureActivityConfiguration(changes,
4858 false /* preserveWindow */);
4859 // And we need to make sure at this point that all other activities
4860 // are made visible with the correct configuration.
4861 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
4862 !PRESERVE_WINDOWS);
4863 }
4864 }
4865
4866 return kept;
4867 }
4868
Wale Ogunwale906f9c62018-07-23 11:23:44 -07004869 void scheduleAppGcsLocked() {
4870 mH.post(() -> mAmInternal.scheduleAppGcs());
4871 }
4872
4873 /**
4874 * Returns the PackageManager. Used by classes hosted by {@link ActivityTaskManagerService}. The
4875 * PackageManager could be unavailable at construction time and therefore needs to be accessed
4876 * on demand.
4877 */
4878 IPackageManager getPackageManager() {
4879 return AppGlobals.getPackageManager();
4880 }
4881
4882 PackageManagerInternal getPackageManagerInternalLocked() {
4883 if (mPmInternal == null) {
4884 mPmInternal = LocalServices.getService(PackageManagerInternal.class);
4885 }
4886 return mPmInternal;
4887 }
4888
Wale Ogunwale008163e2018-07-23 23:11:08 -07004889 AppWarnings getAppWarningsLocked() {
4890 return mAppWarnings;
4891 }
4892
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004893 void logAppTooSlow(WindowProcessController app, long startTime, String msg) {
4894 if (true || Build.IS_USER) {
4895 return;
4896 }
4897
4898 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4899 StrictMode.allowThreadDiskWrites();
4900 try {
4901 File tracesDir = new File("/data/anr");
4902 File tracesFile = null;
4903 try {
4904 tracesFile = File.createTempFile("app_slow", null, tracesDir);
4905
4906 StringBuilder sb = new StringBuilder();
4907 Time tobj = new Time();
4908 tobj.set(System.currentTimeMillis());
4909 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4910 sb.append(": ");
4911 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4912 sb.append(" since ");
4913 sb.append(msg);
4914 FileOutputStream fos = new FileOutputStream(tracesFile);
4915 fos.write(sb.toString().getBytes());
4916 if (app == null) {
4917 fos.write("\n*** No application process!".getBytes());
4918 }
4919 fos.close();
4920 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4921 } catch (IOException e) {
4922 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesFile, e);
4923 return;
4924 }
4925
4926 if (app != null && app.getPid() > 0) {
4927 ArrayList<Integer> firstPids = new ArrayList<Integer>();
4928 firstPids.add(app.getPid());
4929 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, null, null);
4930 }
4931
4932 File lastTracesFile = null;
4933 File curTracesFile = null;
4934 for (int i=9; i>=0; i--) {
4935 String name = String.format(Locale.US, "slow%02d.txt", i);
4936 curTracesFile = new File(tracesDir, name);
4937 if (curTracesFile.exists()) {
4938 if (lastTracesFile != null) {
4939 curTracesFile.renameTo(lastTracesFile);
4940 } else {
4941 curTracesFile.delete();
4942 }
4943 }
4944 lastTracesFile = curTracesFile;
4945 }
4946 tracesFile.renameTo(curTracesFile);
4947 } finally {
4948 StrictMode.setThreadPolicy(oldPolicy);
4949 }
4950 }
4951
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004952 final class H extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07004953 static final int REPORT_TIME_TRACKER_MSG = 1;
4954
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004955 public H(Looper looper) {
4956 super(looper, null, true);
4957 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004958
4959 @Override
4960 public void handleMessage(Message msg) {
4961 switch (msg.what) {
4962 case REPORT_TIME_TRACKER_MSG: {
4963 AppTimeTracker tracker = (AppTimeTracker) msg.obj;
4964 tracker.deliverResult(mContext);
4965 } break;
4966 }
4967 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004968 }
4969
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004970 final class UiHandler extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07004971 static final int DISMISS_DIALOG_UI_MSG = 1;
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004972
4973 public UiHandler() {
4974 super(com.android.server.UiThread.get().getLooper(), null, true);
4975 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004976
4977 @Override
4978 public void handleMessage(Message msg) {
4979 switch (msg.what) {
4980 case DISMISS_DIALOG_UI_MSG: {
4981 final Dialog d = (Dialog) msg.obj;
4982 d.dismiss();
4983 break;
4984 }
4985 }
4986 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004987 }
4988
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004989 final class LocalService extends ActivityTaskManagerInternal {
4990 @Override
4991 public SleepToken acquireSleepToken(String tag, int displayId) {
4992 Preconditions.checkNotNull(tag);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004993 return ActivityTaskManagerService.this.acquireSleepToken(tag, displayId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004994 }
4995
4996 @Override
4997 public ComponentName getHomeActivityForUser(int userId) {
4998 synchronized (mGlobalLock) {
4999 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
5000 return homeActivity == null ? null : homeActivity.realActivity;
5001 }
5002 }
5003
5004 @Override
5005 public void onLocalVoiceInteractionStarted(IBinder activity,
5006 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
5007 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005008 onLocalVoiceInteractionStartedLocked(activity, voiceSession, voiceInteractor);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005009 }
5010 }
5011
5012 @Override
5013 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
5014 synchronized (mGlobalLock) {
5015 mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
5016 reasons, timestamp);
5017 }
5018 }
5019
5020 @Override
5021 public void notifyAppTransitionFinished() {
5022 synchronized (mGlobalLock) {
5023 mStackSupervisor.notifyAppTransitionDone();
5024 }
5025 }
5026
5027 @Override
5028 public void notifyAppTransitionCancelled() {
5029 synchronized (mGlobalLock) {
5030 mStackSupervisor.notifyAppTransitionDone();
5031 }
5032 }
5033
5034 @Override
5035 public List<IBinder> getTopVisibleActivities() {
5036 synchronized (mGlobalLock) {
5037 return mStackSupervisor.getTopVisibleActivities();
5038 }
5039 }
5040
5041 @Override
5042 public void notifyDockedStackMinimizedChanged(boolean minimized) {
5043 synchronized (mGlobalLock) {
5044 mStackSupervisor.setDockedStackMinimized(minimized);
5045 }
5046 }
5047
5048 @Override
5049 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
5050 Bundle bOptions) {
5051 Preconditions.checkNotNull(intents, "intents");
5052 final String[] resolvedTypes = new String[intents.length];
5053
5054 // UID of the package on user userId.
5055 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
5056 // packageUid may not be initialized.
5057 int packageUid = 0;
5058 final long ident = Binder.clearCallingIdentity();
5059
5060 try {
5061 for (int i = 0; i < intents.length; i++) {
5062 resolvedTypes[i] =
5063 intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
5064 }
5065
5066 packageUid = AppGlobals.getPackageManager().getPackageUid(
5067 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
5068 } catch (RemoteException e) {
5069 // Shouldn't happen.
5070 } finally {
5071 Binder.restoreCallingIdentity(ident);
5072 }
5073
5074 synchronized (mGlobalLock) {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07005075 return getActivityStartController().startActivitiesInPackage(
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005076 packageUid, packageName,
5077 intents, resolvedTypes, null /* resultTo */,
5078 SafeActivityOptions.fromBundle(bOptions), userId,
5079 false /* validateIncomingUser */);
5080 }
5081 }
5082
5083 @Override
5084 public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
5085 Intent intent, Bundle options, int userId) {
5086 return ActivityTaskManagerService.this.startActivityAsUser(
5087 caller, callerPacakge, intent,
5088 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
5089 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
5090 false /*validateIncomingUser*/);
5091 }
5092
5093 @Override
5094 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
5095 synchronized (mGlobalLock) {
5096
5097 // We might change the visibilities here, so prepare an empty app transition which
5098 // might be overridden later if we actually change visibilities.
5099 final boolean wasTransitionSet =
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005100 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005101 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005102 mWindowManager.prepareAppTransition(TRANSIT_NONE,
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005103 false /* alwaysKeepCurrent */);
5104 }
5105 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5106
5107 // If there was a transition set already we don't want to interfere with it as we
5108 // might be starting it too early.
5109 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005110 mWindowManager.executeAppTransition();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005111 }
5112 }
5113 if (callback != null) {
5114 callback.run();
5115 }
5116 }
5117
5118 @Override
5119 public void notifyKeyguardTrustedChanged() {
5120 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005121 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005122 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5123 }
5124 }
5125 }
5126
5127 /**
5128 * Called after virtual display Id is updated by
5129 * {@link com.android.server.vr.Vr2dDisplay} with a specific
5130 * {@param vrVr2dDisplayId}.
5131 */
5132 @Override
5133 public void setVr2dDisplayId(int vr2dDisplayId) {
5134 if (DEBUG_STACK) Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
5135 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005136 mVr2dDisplayId = vr2dDisplayId;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005137 }
5138 }
5139
5140 @Override
5141 public void setFocusedActivity(IBinder token) {
5142 synchronized (mGlobalLock) {
5143 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
5144 if (r == null) {
5145 throw new IllegalArgumentException(
5146 "setFocusedActivity: No activity record matching token=" + token);
5147 }
5148 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
5149 r, "setFocusedActivity")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08005150 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005151 }
5152 }
5153 }
5154
5155 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005156 public void registerScreenObserver(ScreenObserver observer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005157 mScreenObservers.add(observer);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005158 }
5159
5160 @Override
5161 public boolean isCallerRecents(int callingUid) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005162 return getRecentTasks().isCallerRecents(callingUid);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005163 }
5164
5165 @Override
5166 public boolean isRecentsComponentHomeActivity(int userId) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005167 return getRecentTasks().isRecentsComponentHomeActivity(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005168 }
5169
5170 @Override
5171 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
5172 ActivityTaskManagerService.this.cancelRecentsAnimation(restoreHomeStackPosition);
5173 }
5174
5175 @Override
5176 public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005177 ActivityTaskManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005178 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005179
5180 @Override
5181 public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
5182 synchronized (mGlobalLock) {
5183 mActiveVoiceInteractionServiceComponent = component;
5184 }
5185 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005186
5187 @Override
5188 public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
5189 if (!mAmInternal.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
5190 return;
5191 }
5192 synchronized (mGlobalLock) {
5193 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
5194 if (types == null) {
5195 if (uid < 0) {
5196 return;
5197 }
5198 types = new ArrayMap<>();
5199 mAllowAppSwitchUids.put(userId, types);
5200 }
5201 if (uid < 0) {
5202 types.remove(type);
5203 } else {
5204 types.put(type, uid);
5205 }
5206 }
5207 }
5208
5209 @Override
5210 public void onUserStopped(int userId) {
5211 synchronized (mGlobalLock) {
5212 getRecentTasks().unloadUserDataFromMemoryLocked(userId);
5213 mAllowAppSwitchUids.remove(userId);
5214 }
5215 }
5216
5217 @Override
5218 public boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
5219 synchronized (mGlobalLock) {
5220 return ActivityTaskManagerService.this.isGetTasksAllowed(
5221 caller, callingPid, callingUid);
5222 }
5223 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005224
5225 @Override
5226 public void onProcessAdded(WindowProcessController proc) {
5227 synchronized (mGlobalLock) {
5228 mProcessNames.put(proc.mName, proc.mUid, proc);
5229 }
5230 }
5231
5232 @Override
5233 public void onProcessRemoved(String name, int uid) {
5234 synchronized (mGlobalLock) {
5235 mProcessNames.remove(name, uid);
5236 }
5237 }
5238
5239 @Override
5240 public void onCleanUpApplicationRecord(WindowProcessController proc) {
5241 synchronized (mGlobalLock) {
5242 if (proc == mHomeProcess) {
5243 mHomeProcess = null;
5244 }
5245 if (proc == mPreviousProcess) {
5246 mPreviousProcess = null;
5247 }
5248 }
5249 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005250
5251 @Override
5252 public int getTopProcessState() {
5253 synchronized (mGlobalLock) {
5254 return mTopProcessState;
5255 }
5256 }
5257
5258 @Override
5259 public boolean isSleeping() {
5260 synchronized (mGlobalLock) {
5261 return isSleepingLocked();
5262 }
5263 }
5264
5265 @Override
5266 public boolean isShuttingDown() {
5267 synchronized (mGlobalLock) {
5268 return mShuttingDown;
5269 }
5270 }
5271
5272 @Override
5273 public boolean shuttingDown(boolean booted, int timeout) {
5274 synchronized (mGlobalLock) {
5275 mShuttingDown = true;
5276 mStackSupervisor.prepareForShutdownLocked();
5277 updateEventDispatchingLocked(booted);
5278 return mStackSupervisor.shutdownLocked(timeout);
5279 }
5280 }
5281
5282 @Override
5283 public void enableScreenAfterBoot(boolean booted) {
5284 synchronized (mGlobalLock) {
5285 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5286 SystemClock.uptimeMillis());
5287 mWindowManager.enableScreenAfterBoot();
5288 updateEventDispatchingLocked(booted);
5289 }
5290 }
5291
5292 @Override
5293 public boolean showStrictModeViolationDialog() {
5294 synchronized (mGlobalLock) {
5295 return mShowDialogs && !mSleeping && !mShuttingDown;
5296 }
5297 }
5298
5299 @Override
5300 public void showSystemReadyErrorDialogsIfNeeded() {
5301 synchronized (mGlobalLock) {
5302 try {
5303 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
5304 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
5305 + " data partition or your device will be unstable.");
5306 mUiHandler.post(() -> {
5307 if (mShowDialogs) {
5308 AlertDialog d = new BaseErrorDialog(mUiContext);
5309 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5310 d.setCancelable(false);
5311 d.setTitle(mUiContext.getText(R.string.android_system_label));
5312 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
5313 d.setButton(DialogInterface.BUTTON_POSITIVE,
5314 mUiContext.getText(R.string.ok),
5315 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5316 d.show();
5317 }
5318 });
5319 }
5320 } catch (RemoteException e) {
5321 }
5322
5323 if (!Build.isBuildConsistent()) {
5324 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
5325 mUiHandler.post(() -> {
5326 if (mShowDialogs) {
5327 AlertDialog d = new BaseErrorDialog(mUiContext);
5328 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5329 d.setCancelable(false);
5330 d.setTitle(mUiContext.getText(R.string.android_system_label));
5331 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
5332 d.setButton(DialogInterface.BUTTON_POSITIVE,
5333 mUiContext.getText(R.string.ok),
5334 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5335 d.show();
5336 }
5337 });
5338 }
5339 }
5340 }
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005341
5342 @Override
5343 public long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason) {
5344 synchronized (mGlobalLock) {
5345 return ActivityTaskManagerService.this.inputDispatchingTimedOut(
5346 pid, aboveSystem, reason);
5347 }
5348 }
5349
5350 @Override
5351 public void onProcessMapped(int pid, WindowProcessController proc) {
5352 synchronized (mGlobalLock) {
5353 mPidMap.put(pid, proc);
5354 }
5355 }
5356
5357 @Override
5358 public void onProcessUnMapped(int pid) {
5359 synchronized (mGlobalLock) {
5360 mPidMap.remove(pid);
5361 }
5362 }
Wale Ogunwale008163e2018-07-23 23:11:08 -07005363
5364 @Override
5365 public void onPackageDataCleared(String name) {
5366 synchronized (mGlobalLock) {
5367 mAppWarnings.onPackageDataCleared(name);
5368 }
5369 }
5370
5371 @Override
5372 public void onPackageUninstalled(String name) {
5373 synchronized (mGlobalLock) {
5374 mAppWarnings.onPackageUninstalled(name);
5375 }
5376 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005377 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07005378}