blob: bd502df17ba2aef2512eb33f508d1025e31d7ab6 [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;
Garfield Tane0846042018-07-26 13:42:04 -070030import static android.content.pm.PackageManager.FEATURE_PC;
Wale Ogunwalef6733932018-06-27 05:14:34 -070031import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
32import static android.provider.Settings.Global.HIDE_ERROR_DIALOGS;
33import static android.provider.Settings.System.FONT_SCALE;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070034import static com.android.server.am.ActivityManagerService.dumpStackTraces;
Wale Ogunwalef6733932018-06-27 05:14:34 -070035import static com.android.server.am.ActivityTaskManagerService.H.REPORT_TIME_TRACKER_MSG;
36import static com.android.server.am.ActivityTaskManagerService.UiHandler.DISMISS_DIALOG_UI_MSG;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070037import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT;
38import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_DATA;
39import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
40import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070041import static android.app.ActivityTaskManager.RESIZE_MODE_PRESERVE_WINDOW;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070042import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070043import static android.app.AppOpsManager.OP_NONE;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070044import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070045import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
46import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070047import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
48import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070049import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070050import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070051import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070052import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
53import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070054import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070055import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070056import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
57import static android.os.Build.VERSION_CODES.N;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070058import static android.os.Process.SYSTEM_UID;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070059import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
60import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
61import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
62import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070063import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
64import static android.view.Display.DEFAULT_DISPLAY;
65import static android.view.Display.INVALID_DISPLAY;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070066import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
Wale Ogunwale6767eae2018-05-03 15:52:51 -070067import static android.view.WindowManager.TRANSIT_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070068import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070069import static android.view.WindowManager.TRANSIT_TASK_OPEN;
70import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070071import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070072import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
73import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
74import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
75import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070076import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070077import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070078import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070079import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070080import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070081import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
82import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
83import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070084import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070085import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
86import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070087import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
88import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070089import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070090import static com.android.server.am.ActivityManagerService.ANIMATE;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070091import static com.android.server.am.ActivityManagerService.MY_PID;
92import static com.android.server.am.ActivityManagerService.SEND_LOCALE_TO_MOUNT_DAEMON_MSG;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070093import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070094import static com.android.server.am.ActivityManagerService.UPDATE_CONFIGURATION_MSG;
95import static com.android.server.am.ActivityManagerService.checkComponentPermission;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070096import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070097import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070098import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
99import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
100import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
101import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
102import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
103import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
104import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700105import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700106import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
107import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
108import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700109
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700110import android.Manifest;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700111import android.annotation.NonNull;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700112import android.annotation.Nullable;
113import android.annotation.UserIdInt;
114import android.app.Activity;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700115import android.app.ActivityManager;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700116import android.app.ActivityManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700117import android.app.ActivityOptions;
118import android.app.ActivityTaskManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700119import android.app.ActivityThread;
120import android.app.AlertDialog;
121import android.app.Dialog;
122import android.content.DialogInterface;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700123import android.content.pm.IPackageManager;
124import android.content.pm.PackageManagerInternal;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700125import android.database.ContentObserver;
126import android.os.IUserManager;
127import android.os.PowerManager;
128import android.os.ServiceManager;
129import android.os.Trace;
130import android.os.UserManager;
131import android.os.WorkSource;
132import android.view.WindowManager;
133import com.android.internal.R;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700134import com.android.internal.app.IAppOpsService;
135import com.android.server.AppOpsService;
Wale Ogunwale008163e2018-07-23 23:11:08 -0700136import com.android.server.SystemServiceManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700137import com.android.server.pm.UserManagerService;
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700138import com.android.server.uri.UriGrantsManagerInternal;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700139import com.android.server.wm.ActivityTaskManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700140import android.app.AppGlobals;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700141import android.app.IActivityController;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700142import android.app.IActivityTaskManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700143import android.app.IApplicationThread;
144import android.app.IAssistDataReceiver;
145import android.app.ITaskStackListener;
146import android.app.PictureInPictureParams;
147import android.app.ProfilerInfo;
148import android.app.RemoteAction;
149import android.app.WaitResult;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700150import android.app.WindowConfiguration;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700151import android.app.admin.DevicePolicyCache;
152import android.app.assist.AssistContent;
153import android.app.assist.AssistStructure;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700154import android.app.servertransaction.ConfigurationChangeItem;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700155import android.app.usage.UsageEvents;
156import android.content.ActivityNotFoundException;
157import android.content.ComponentName;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700158import android.content.ContentResolver;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700159import android.content.Context;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700160import android.content.IIntentSender;
161import android.content.Intent;
162import android.content.pm.ActivityInfo;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700163import android.content.pm.ApplicationInfo;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700164import android.content.pm.PackageManager;
165import android.content.pm.ParceledListSlice;
166import android.content.pm.ResolveInfo;
167import android.content.res.Configuration;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700168import android.content.res.Resources;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700169import android.graphics.Bitmap;
170import android.graphics.Point;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700171import android.graphics.Rect;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700172import android.metrics.LogMaker;
173import android.net.Uri;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700174import android.os.Binder;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700175import android.os.Build;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700176import android.os.Bundle;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700177import android.os.FileUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700178import android.os.Handler;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700179import android.os.IBinder;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700180import android.os.LocaleList;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700181import android.os.Looper;
182import android.os.Message;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700183import android.os.PersistableBundle;
184import android.os.RemoteException;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700185import android.os.StrictMode;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700186import android.os.SystemClock;
187import android.os.SystemProperties;
188import android.os.UpdateLock;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700189import android.os.UserHandle;
190import android.provider.Settings;
191import android.service.voice.IVoiceInteractionSession;
192import android.service.voice.VoiceInteractionManagerInternal;
193import android.telecom.TelecomManager;
194import android.text.TextUtils;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700195import android.text.format.Time;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700196import android.util.ArrayMap;
197import android.util.EventLog;
198import android.util.Log;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700199import android.util.Slog;
200
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700201import android.util.SparseArray;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700202import android.util.SparseIntArray;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700203import android.util.StatsLog;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700204import android.util.TimeUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700205import android.util.proto.ProtoOutputStream;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700206import android.view.IRecentsAnimationRunner;
207import android.view.RemoteAnimationAdapter;
208import android.view.RemoteAnimationDefinition;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700209
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700210import com.android.internal.annotations.VisibleForTesting;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700211import com.android.internal.app.AssistUtils;
212import com.android.internal.app.IVoiceInteractor;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700213import com.android.internal.app.ProcessMap;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700214import com.android.internal.logging.MetricsLogger;
215import com.android.internal.os.logging.MetricsLoggerWrapper;
216import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
217import com.android.internal.policy.IKeyguardDismissCallback;
218import com.android.internal.policy.KeyguardDismissCallback;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700219import com.android.internal.util.Preconditions;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700220import com.android.server.AttributeCache;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700221import com.android.server.LocalServices;
222import com.android.server.SystemService;
223import com.android.server.Watchdog;
224import com.android.server.vr.VrManagerInternal;
225import com.android.server.wm.PinnedStackWindowController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700226import com.android.server.wm.WindowManagerService;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700227
228import java.io.File;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700229import java.io.FileOutputStream;
230import java.io.IOException;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700231import java.io.PrintWriter;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700232import java.io.StringWriter;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700233import java.util.ArrayList;
234import java.util.List;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700235import java.util.Locale;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700236
237/**
238 * System service for managing activities and their containers (task, stacks, displays,... ).
239 *
240 * {@hide}
241 */
242public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
243 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityTaskManagerService" : TAG_AM;
244 private static final String TAG_STACK = TAG + POSTFIX_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700245 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
246 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
247 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
248 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
249 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700250 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700251
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700252 // How long we wait until we timeout on key dispatching.
253 private static final int KEY_DISPATCHING_TIMEOUT_MS = 5 * 1000;
254 // How long we wait until we timeout on key dispatching during instrumentation.
255 private static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS = 60 * 1000;
256
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700257 Context mContext;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700258 /**
259 * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
260 * change at runtime. Use mContext for non-UI purposes.
261 */
262 final Context mUiContext;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700263 H mH;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700264 UiHandler mUiHandler;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700265 ActivityManagerService mAm;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700266 ActivityManagerInternal mAmInternal;
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700267 UriGrantsManagerInternal mUgmInternal;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700268 private PackageManagerInternal mPmInternal;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700269 /* Global service lock used by the package the owns this service. */
270 Object mGlobalLock;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700271 ActivityStackSupervisor mStackSupervisor;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700272 WindowManagerService mWindowManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700273 private UserManagerService mUserManager;
274 private AppOpsService mAppOpsService;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700275 /** All processes currently running that might have a window organized by name. */
276 final ProcessMap<WindowProcessController> mProcessNames = new ProcessMap<>();
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700277 /** All processes we currently have running mapped by pid */
278 final SparseArray<WindowProcessController> mPidMap = new SparseArray<>();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700279 /** This is the process holding what we currently consider to be the "home" activity. */
280 WindowProcessController mHomeProcess;
281 /**
282 * This is the process holding the activity the user last visited that is in a different process
283 * from the one they are currently in.
284 */
285 WindowProcessController mPreviousProcess;
286 /** The time at which the previous process was last visible. */
287 long mPreviousProcessVisibleTime;
288
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700289 /** List of intents that were used to start the most recent tasks. */
290 private RecentTasks mRecentTasks;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700291 /** State of external calls telling us if the device is awake or asleep. */
292 private boolean mKeyguardShown = false;
293
294 // Wrapper around VoiceInteractionServiceManager
295 private AssistUtils mAssistUtils;
296
297 // VoiceInteraction session ID that changes for each new request except when
298 // being called for multi-window assist in a single session.
299 private int mViSessionId = 1000;
300
301 // How long to wait in getAssistContextExtras for the activity and foreground services
302 // to respond with the result.
303 private static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
304
305 // How long top wait when going through the modern assist (which doesn't need to block
306 // on getting this result before starting to launch its UI).
307 private static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
308
309 // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
310 private static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
311
312 private final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
313
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700314 // Keeps track of the active voice interaction service component, notified from
315 // VoiceInteractionManagerService
316 ComponentName mActiveVoiceInteractionServiceComponent;
317
318 private VrController mVrController;
319 KeyguardController mKeyguardController;
320 private final ClientLifecycleManager mLifecycleManager;
321 private TaskChangeNotificationController mTaskChangeNotificationController;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700322 /** The controller for all operations related to locktask. */
323 private LockTaskController mLockTaskController;
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700324 private ActivityStartController mActivityStartController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700325
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700326 boolean mSuppressResizeConfigChanges;
327
328 private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
329 new UpdateConfigurationResult();
330
331 static final class UpdateConfigurationResult {
332 // Configuration changes that were updated.
333 int changes;
334 // If the activity was relaunched to match the new configuration.
335 boolean activityRelaunched;
336
337 void reset() {
338 changes = 0;
339 activityRelaunched = false;
340 }
341 }
342
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700343 /** Current sequencing integer of the configuration, for skipping old configurations. */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700344 private int mConfigurationSeq;
345 // To cache the list of supported system locales
346 private String[] mSupportedSystemLocales = null;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700347
348 /**
349 * Temp object used when global and/or display override configuration is updated. It is also
350 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
351 * anyone...
352 */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700353 private Configuration mTempConfig = new Configuration();
354
Wale Ogunwalef6733932018-06-27 05:14:34 -0700355 /** Temporary to avoid allocations. */
356 final StringBuilder mStringBuilder = new StringBuilder(256);
357
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700358 // Amount of time after a call to stopAppSwitches() during which we will
359 // prevent further untrusted switches from happening.
360 private static final long APP_SWITCH_DELAY_TIME = 5 * 1000;
361
362 /**
363 * The time at which we will allow normal application switches again,
364 * after a call to {@link #stopAppSwitches()}.
365 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700366 private long mAppSwitchesAllowedTime;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700367 /**
368 * This is set to true after the first switch after mAppSwitchesAllowedTime
369 * is set; any switches after that will clear the time.
370 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700371 private boolean mDidAppSwitch;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700372
373 IActivityController mController = null;
374 boolean mControllerIsAMonkey = false;
375
376 /**
377 * Used to retain an update lock when the foreground activity is in
378 * immersive mode.
379 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700380 private final UpdateLock mUpdateLock = new UpdateLock("immersive");
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700381
382 /**
383 * Packages that are being allowed to perform unrestricted app switches. Mapping is
384 * User -> Type -> uid.
385 */
386 final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
387
388 /** The dimensions of the thumbnails in the Recents UI. */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700389 private int mThumbnailWidth;
390 private int mThumbnailHeight;
391 private float mFullscreenThumbnailScale;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700392
393 /**
394 * Flag that indicates if multi-window is enabled.
395 *
396 * For any particular form of multi-window to be enabled, generic multi-window must be enabled
397 * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
398 * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
399 * At least one of the forms of multi-window must be enabled in order for this flag to be
400 * initialized to 'true'.
401 *
402 * @see #mSupportsSplitScreenMultiWindow
403 * @see #mSupportsFreeformWindowManagement
404 * @see #mSupportsPictureInPicture
405 * @see #mSupportsMultiDisplay
406 */
407 boolean mSupportsMultiWindow;
408 boolean mSupportsSplitScreenMultiWindow;
409 boolean mSupportsFreeformWindowManagement;
410 boolean mSupportsPictureInPicture;
411 boolean mSupportsMultiDisplay;
412 boolean mForceResizableActivities;
413
414 final List<ActivityTaskManagerInternal.ScreenObserver> mScreenObservers = new ArrayList<>();
415
416 // VR Vr2d Display Id.
417 int mVr2dDisplayId = INVALID_DISPLAY;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700418
Wale Ogunwalef6733932018-06-27 05:14:34 -0700419 /**
420 * Set while we are wanting to sleep, to prevent any
421 * activities from being started/resumed.
422 *
423 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
424 *
425 * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
426 * while in the sleep state until there is a pending transition out of sleep, in which case
427 * mSleeping is set to false, and remains false while awake.
428 *
429 * Whether mSleeping can quickly toggled between true/false without the device actually
430 * display changing states is undefined.
431 */
432 private boolean mSleeping = false;
433
434 /**
435 * The process state used for processes that are running the top activities.
436 * This changes between TOP and TOP_SLEEPING to following mSleeping.
437 */
438 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
439
440 // Whether we should show our dialogs (ANR, crash, etc) or just perform their default action
441 // automatically. Important for devices without direct input devices.
442 private boolean mShowDialogs = true;
443
444 /** Set if we are shutting down the system, similar to sleeping. */
445 boolean mShuttingDown = false;
446
447 /**
448 * We want to hold a wake lock while running a voice interaction session, since
449 * this may happen with the screen off and we need to keep the CPU running to
450 * be able to continue to interact with the user.
451 */
452 PowerManager.WakeLock mVoiceWakeLock;
453
454 /**
455 * Set while we are running a voice interaction. This overrides sleeping while it is active.
456 */
457 IVoiceInteractionSession mRunningVoice;
458
459 /**
460 * The last resumed activity. This is identical to the current resumed activity most
461 * of the time but could be different when we're pausing one activity before we resume
462 * another activity.
463 */
464 ActivityRecord mLastResumedActivity;
465
466 /**
467 * The activity that is currently being traced as the active resumed activity.
468 *
469 * @see #updateResumedAppTrace
470 */
471 private @Nullable ActivityRecord mTracedResumedActivity;
472
473 /** If non-null, we are tracking the time the user spends in the currently focused app. */
474 AppTimeTracker mCurAppTimeTracker;
475
Wale Ogunwale008163e2018-07-23 23:11:08 -0700476 private AppWarnings mAppWarnings;
477
Wale Ogunwalef6733932018-06-27 05:14:34 -0700478 private FontScaleSettingObserver mFontScaleSettingObserver;
479
480 private final class FontScaleSettingObserver extends ContentObserver {
481 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
482 private final Uri mHideErrorDialogsUri = Settings.Global.getUriFor(HIDE_ERROR_DIALOGS);
483
484 public FontScaleSettingObserver() {
485 super(mH);
486 final ContentResolver resolver = mContext.getContentResolver();
487 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
488 resolver.registerContentObserver(mHideErrorDialogsUri, false, this,
489 UserHandle.USER_ALL);
490 }
491
492 @Override
493 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
494 if (mFontScaleUri.equals(uri)) {
495 updateFontScaleIfNeeded(userId);
496 } else if (mHideErrorDialogsUri.equals(uri)) {
497 synchronized (mGlobalLock) {
498 updateShouldShowDialogsLocked(getGlobalConfiguration());
499 }
500 }
501 }
502 }
503
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700504 ActivityTaskManagerService(Context context) {
505 mContext = context;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700506 mUiContext = ActivityThread.currentActivityThread().getSystemUiContext();
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700507 mLifecycleManager = new ClientLifecycleManager();
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700508 }
509
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700510 void onSystemReady() {
511 mAssistUtils = new AssistUtils(mContext);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700512 mVrController.onSystemReady();
513 mRecentTasks.onSystemReadyLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700514 }
515
Wale Ogunwalef6733932018-06-27 05:14:34 -0700516 void onInitPowerManagement() {
517 mStackSupervisor.initPowerManagement();
518 final PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
519 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
520 mVoiceWakeLock.setReferenceCounted(false);
521 }
522
523 void installSystemProviders() {
524 mFontScaleSettingObserver = new FontScaleSettingObserver();
525 }
526
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700527 void retrieveSettings(ContentResolver resolver) {
528 final boolean freeformWindowManagement =
529 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
530 || Settings.Global.getInt(
531 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
532
533 final boolean supportsMultiWindow = ActivityTaskManager.supportsMultiWindow(mContext);
534 final boolean supportsPictureInPicture = supportsMultiWindow &&
535 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
536 final boolean supportsSplitScreenMultiWindow =
537 ActivityTaskManager.supportsSplitScreenMultiWindow(mContext);
538 final boolean supportsMultiDisplay = mContext.getPackageManager()
539 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
540 final boolean alwaysFinishActivities =
541 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
542 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
543 final boolean forceResizable = Settings.Global.getInt(
544 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
Garfield Tane0846042018-07-26 13:42:04 -0700545 final boolean isPc = mContext.getPackageManager().hasSystemFeature(FEATURE_PC);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700546
547 // Transfer any global setting for forcing RTL layout, into a System Property
548 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
549
550 final Configuration configuration = new Configuration();
551 Settings.System.getConfiguration(resolver, configuration);
552 if (forceRtl) {
553 // This will take care of setting the correct layout direction flags
554 configuration.setLayoutDirection(configuration.locale);
555 }
556
557 synchronized (mGlobalLock) {
558 mForceResizableActivities = forceResizable;
559 final boolean multiWindowFormEnabled = freeformWindowManagement
560 || supportsSplitScreenMultiWindow
561 || supportsPictureInPicture
562 || supportsMultiDisplay;
563 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
564 mSupportsMultiWindow = true;
565 mSupportsFreeformWindowManagement = freeformWindowManagement;
566 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
567 mSupportsPictureInPicture = supportsPictureInPicture;
568 mSupportsMultiDisplay = supportsMultiDisplay;
569 } else {
570 mSupportsMultiWindow = false;
571 mSupportsFreeformWindowManagement = false;
572 mSupportsSplitScreenMultiWindow = false;
573 mSupportsPictureInPicture = false;
574 mSupportsMultiDisplay = false;
575 }
576 mWindowManager.setForceResizableTasks(mForceResizableActivities);
577 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
Garfield Tane0846042018-07-26 13:42:04 -0700578 mWindowManager.setSupportsFreeformWindowManagement(mSupportsFreeformWindowManagement);
579 mWindowManager.setIsPc(isPc);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700580 // This happens before any activities are started, so we can change global configuration
581 // in-place.
582 updateConfigurationLocked(configuration, null, true);
583 final Configuration globalConfig = getGlobalConfiguration();
584 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
585
586 // Load resources only after the current configuration has been set.
587 final Resources res = mContext.getResources();
588 mThumbnailWidth = res.getDimensionPixelSize(
589 com.android.internal.R.dimen.thumbnail_width);
590 mThumbnailHeight = res.getDimensionPixelSize(
591 com.android.internal.R.dimen.thumbnail_height);
592
593 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
594 mFullscreenThumbnailScale = (float) res
595 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
596 (float) globalConfig.screenWidthDp;
597 } else {
598 mFullscreenThumbnailScale = res.getFraction(
599 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
600 }
601 }
602 }
603
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700604 // TODO: Will be converted to WM lock once transition is complete.
605 void setActivityManagerService(ActivityManagerService am) {
606 mAm = am;
607 mGlobalLock = mAm;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700608 mH = new H(mAm.mHandlerThread.getLooper());
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700609 mUiHandler = new UiHandler();
Wale Ogunwale008163e2018-07-23 23:11:08 -0700610 mAppWarnings = new AppWarnings(
611 this, mUiContext, mH, mUiHandler, SystemServiceManager.ensureSystemDir());
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700612
613 mTempConfig.setToDefaults();
614 mTempConfig.setLocales(LocaleList.getDefault());
615 mConfigurationSeq = mTempConfig.seq = 1;
616 mStackSupervisor = createStackSupervisor();
617 mStackSupervisor.onConfigurationChanged(mTempConfig);
618
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700619 mTaskChangeNotificationController =
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700620 new TaskChangeNotificationController(mGlobalLock, mStackSupervisor, mH);
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700621 mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mH);
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700622 mActivityStartController = new ActivityStartController(this);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700623 mRecentTasks = createRecentTasks();
624 mStackSupervisor.setRecentTasks(mRecentTasks);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700625 mVrController = new VrController(mGlobalLock);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700626 mKeyguardController = mStackSupervisor.getKeyguardController();
627 }
628
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700629 void onActivityManagerInternalAdded() {
630 mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700631 mUgmInternal = LocalServices.getService(UriGrantsManagerInternal.class);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700632 }
633
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700634 protected ActivityStackSupervisor createStackSupervisor() {
635 final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mH.getLooper());
636 supervisor.initialize();
637 return supervisor;
638 }
639
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700640 void setWindowManager(WindowManagerService wm) {
641 mWindowManager = wm;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700642 mLockTaskController.setWindowManager(wm);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700643 }
644
Wale Ogunwalef6733932018-06-27 05:14:34 -0700645 UserManagerService getUserManager() {
646 if (mUserManager == null) {
647 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
648 mUserManager = (UserManagerService) IUserManager.Stub.asInterface(b);
649 }
650 return mUserManager;
651 }
652
653 AppOpsService getAppOpsService() {
654 if (mAppOpsService == null) {
655 IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
656 mAppOpsService = (AppOpsService) IAppOpsService.Stub.asInterface(b);
657 }
658 return mAppOpsService;
659 }
660
661 boolean hasUserRestriction(String restriction, int userId) {
662 return getUserManager().hasUserRestriction(restriction, userId);
663 }
664
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700665 protected RecentTasks createRecentTasks() {
666 return new RecentTasks(this, mStackSupervisor);
667 }
668
669 RecentTasks getRecentTasks() {
670 return mRecentTasks;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700671 }
672
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700673 ClientLifecycleManager getLifecycleManager() {
674 return mLifecycleManager;
675 }
676
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700677 ActivityStartController getActivityStartController() {
678 return mActivityStartController;
679 }
680
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700681 TaskChangeNotificationController getTaskChangeNotificationController() {
682 return mTaskChangeNotificationController;
683 }
684
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700685 LockTaskController getLockTaskController() {
686 return mLockTaskController;
687 }
688
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700689 private void start() {
690 LocalServices.addService(ActivityTaskManagerInternal.class, new LocalService());
691 }
692
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700693 public static final class Lifecycle extends SystemService {
694 private final ActivityTaskManagerService mService;
695
696 public Lifecycle(Context context) {
697 super(context);
698 mService = new ActivityTaskManagerService(context);
699 }
700
701 @Override
702 public void onStart() {
703 publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700704 mService.start();
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700705 }
706
707 public ActivityTaskManagerService getService() {
708 return mService;
709 }
710 }
711
712 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700713 public final int startActivity(IApplicationThread caller, String callingPackage,
714 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
715 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
716 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
717 resultWho, requestCode, startFlags, profilerInfo, bOptions,
718 UserHandle.getCallingUserId());
719 }
720
721 @Override
722 public final int startActivities(IApplicationThread caller, String callingPackage,
723 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
724 int userId) {
725 final String reason = "startActivities";
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700726 enforceNotIsolatedCaller(reason);
727 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, reason);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700728 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700729 return getActivityStartController().startActivities(caller, -1, callingPackage, intents,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700730 resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId, reason);
731 }
732
733 @Override
734 public int startActivityAsUser(IApplicationThread caller, String callingPackage,
735 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
736 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
737 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
738 resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
739 true /*validateIncomingUser*/);
740 }
741
742 int startActivityAsUser(IApplicationThread caller, String callingPackage,
743 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
744 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
745 boolean validateIncomingUser) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700746 enforceNotIsolatedCaller("startActivityAsUser");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700747
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700748 userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700749 Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
750
751 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700752 return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700753 .setCaller(caller)
754 .setCallingPackage(callingPackage)
755 .setResolvedType(resolvedType)
756 .setResultTo(resultTo)
757 .setResultWho(resultWho)
758 .setRequestCode(requestCode)
759 .setStartFlags(startFlags)
760 .setProfilerInfo(profilerInfo)
761 .setActivityOptions(bOptions)
762 .setMayWait(userId)
763 .execute();
764
765 }
766
767 @Override
768 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
769 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700770 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions) {
771 enforceNotIsolatedCaller("startActivityIntentSender");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700772 // Refuse possible leaked file descriptors
773 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
774 throw new IllegalArgumentException("File descriptors passed in Intent");
775 }
776
777 if (!(target instanceof PendingIntentRecord)) {
778 throw new IllegalArgumentException("Bad PendingIntent object");
779 }
780
781 PendingIntentRecord pir = (PendingIntentRecord)target;
782
783 synchronized (mGlobalLock) {
784 // If this is coming from the currently resumed activity, it is
785 // effectively saying that app switches are allowed at this point.
Andrii Kulian5f750bc2018-07-17 08:57:23 -0700786 final ActivityStack stack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700787 if (stack.mResumedActivity != null &&
788 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700789 mAppSwitchesAllowedTime = 0;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700790 }
791 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700792 return pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700793 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700794 }
795
796 @Override
797 public boolean startNextMatchingActivity(IBinder callingActivity, Intent intent,
798 Bundle bOptions) {
799 // Refuse possible leaked file descriptors
800 if (intent != null && intent.hasFileDescriptors()) {
801 throw new IllegalArgumentException("File descriptors passed in Intent");
802 }
803 SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
804
805 synchronized (mGlobalLock) {
806 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
807 if (r == null) {
808 SafeActivityOptions.abort(options);
809 return false;
810 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700811 if (!r.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700812 // The caller is not running... d'oh!
813 SafeActivityOptions.abort(options);
814 return false;
815 }
816 intent = new Intent(intent);
817 // The caller is not allowed to change the data.
818 intent.setDataAndType(r.intent.getData(), r.intent.getType());
819 // And we are resetting to find the next component...
820 intent.setComponent(null);
821
822 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
823
824 ActivityInfo aInfo = null;
825 try {
826 List<ResolveInfo> resolves =
827 AppGlobals.getPackageManager().queryIntentActivities(
828 intent, r.resolvedType,
829 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
830 UserHandle.getCallingUserId()).getList();
831
832 // Look for the original activity in the list...
833 final int N = resolves != null ? resolves.size() : 0;
834 for (int i=0; i<N; i++) {
835 ResolveInfo rInfo = resolves.get(i);
836 if (rInfo.activityInfo.packageName.equals(r.packageName)
837 && rInfo.activityInfo.name.equals(r.info.name)) {
838 // We found the current one... the next matching is
839 // after it.
840 i++;
841 if (i<N) {
842 aInfo = resolves.get(i).activityInfo;
843 }
844 if (debug) {
845 Slog.v(TAG, "Next matching activity: found current " + r.packageName
846 + "/" + r.info.name);
847 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
848 ? "null" : aInfo.packageName + "/" + aInfo.name));
849 }
850 break;
851 }
852 }
853 } catch (RemoteException e) {
854 }
855
856 if (aInfo == null) {
857 // Nobody who is next!
858 SafeActivityOptions.abort(options);
859 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
860 return false;
861 }
862
863 intent.setComponent(new ComponentName(
864 aInfo.applicationInfo.packageName, aInfo.name));
865 intent.setFlags(intent.getFlags()&~(
866 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
867 Intent.FLAG_ACTIVITY_CLEAR_TOP|
868 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
869 FLAG_ACTIVITY_NEW_TASK));
870
871 // Okay now we need to start the new activity, replacing the currently running activity.
872 // This is a little tricky because we want to start the new one as if the current one is
873 // finished, but not finish the current one first so that there is no flicker.
874 // And thus...
875 final boolean wasFinishing = r.finishing;
876 r.finishing = true;
877
878 // Propagate reply information over to the new activity.
879 final ActivityRecord resultTo = r.resultTo;
880 final String resultWho = r.resultWho;
881 final int requestCode = r.requestCode;
882 r.resultTo = null;
883 if (resultTo != null) {
884 resultTo.removeResultsLocked(r, resultWho, requestCode);
885 }
886
887 final long origId = Binder.clearCallingIdentity();
888 // TODO(b/64750076): Check if calling pid should really be -1.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700889 final int res = getActivityStartController()
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700890 .obtainStarter(intent, "startNextMatchingActivity")
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700891 .setCaller(r.app.getThread())
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700892 .setResolvedType(r.resolvedType)
893 .setActivityInfo(aInfo)
894 .setResultTo(resultTo != null ? resultTo.appToken : null)
895 .setResultWho(resultWho)
896 .setRequestCode(requestCode)
897 .setCallingPid(-1)
898 .setCallingUid(r.launchedFromUid)
899 .setCallingPackage(r.launchedFromPackage)
900 .setRealCallingPid(-1)
901 .setRealCallingUid(r.launchedFromUid)
902 .setActivityOptions(options)
903 .execute();
904 Binder.restoreCallingIdentity(origId);
905
906 r.finishing = wasFinishing;
907 if (res != ActivityManager.START_SUCCESS) {
908 return false;
909 }
910 return true;
911 }
912 }
913
914 @Override
915 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
916 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
917 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
918 final WaitResult res = new WaitResult();
919 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700920 enforceNotIsolatedCaller("startActivityAndWait");
921 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
922 userId, "startActivityAndWait");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700923 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700924 getActivityStartController().obtainStarter(intent, "startActivityAndWait")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700925 .setCaller(caller)
926 .setCallingPackage(callingPackage)
927 .setResolvedType(resolvedType)
928 .setResultTo(resultTo)
929 .setResultWho(resultWho)
930 .setRequestCode(requestCode)
931 .setStartFlags(startFlags)
932 .setActivityOptions(bOptions)
933 .setMayWait(userId)
934 .setProfilerInfo(profilerInfo)
935 .setWaitResult(res)
936 .execute();
937 }
938 return res;
939 }
940
941 @Override
942 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
943 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
944 int startFlags, Configuration config, Bundle bOptions, int userId) {
945 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700946 enforceNotIsolatedCaller("startActivityWithConfig");
947 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
948 "startActivityWithConfig");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700949 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700950 return getActivityStartController().obtainStarter(intent, "startActivityWithConfig")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700951 .setCaller(caller)
952 .setCallingPackage(callingPackage)
953 .setResolvedType(resolvedType)
954 .setResultTo(resultTo)
955 .setResultWho(resultWho)
956 .setRequestCode(requestCode)
957 .setStartFlags(startFlags)
958 .setGlobalConfiguration(config)
959 .setActivityOptions(bOptions)
960 .setMayWait(userId)
961 .execute();
962 }
963 }
964
965 @Override
966 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
967 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
968 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
969 int userId) {
970
971 // This is very dangerous -- it allows you to perform a start activity (including
972 // permission grants) as any app that may launch one of your own activities. So
973 // we will only allow this to be done from activities that are part of the core framework,
974 // and then only when they are running as the system.
975 final ActivityRecord sourceRecord;
976 final int targetUid;
977 final String targetPackage;
978 final boolean isResolver;
979 synchronized (mGlobalLock) {
980 if (resultTo == null) {
981 throw new SecurityException("Must be called from an activity");
982 }
983 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
984 if (sourceRecord == null) {
985 throw new SecurityException("Called with bad activity token: " + resultTo);
986 }
987 if (!sourceRecord.info.packageName.equals("android")) {
988 throw new SecurityException(
989 "Must be called from an activity that is declared in the android package");
990 }
991 if (sourceRecord.app == null) {
992 throw new SecurityException("Called without a process attached to activity");
993 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700994 if (UserHandle.getAppId(sourceRecord.app.mUid) != SYSTEM_UID) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700995 // This is still okay, as long as this activity is running under the
996 // uid of the original calling activity.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700997 if (sourceRecord.app.mUid != sourceRecord.launchedFromUid) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700998 throw new SecurityException(
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700999 "Calling activity in uid " + sourceRecord.app.mUid
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001000 + " must be system uid or original calling uid "
1001 + sourceRecord.launchedFromUid);
1002 }
1003 }
1004 if (ignoreTargetSecurity) {
1005 if (intent.getComponent() == null) {
1006 throw new SecurityException(
1007 "Component must be specified with ignoreTargetSecurity");
1008 }
1009 if (intent.getSelector() != null) {
1010 throw new SecurityException(
1011 "Selector not allowed with ignoreTargetSecurity");
1012 }
1013 }
1014 targetUid = sourceRecord.launchedFromUid;
1015 targetPackage = sourceRecord.launchedFromPackage;
1016 isResolver = sourceRecord.isResolverOrChildActivity();
1017 }
1018
1019 if (userId == UserHandle.USER_NULL) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001020 userId = UserHandle.getUserId(sourceRecord.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001021 }
1022
1023 // TODO: Switch to user app stacks here.
1024 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001025 return getActivityStartController().obtainStarter(intent, "startActivityAsCaller")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001026 .setCallingUid(targetUid)
1027 .setCallingPackage(targetPackage)
1028 .setResolvedType(resolvedType)
1029 .setResultTo(resultTo)
1030 .setResultWho(resultWho)
1031 .setRequestCode(requestCode)
1032 .setStartFlags(startFlags)
1033 .setActivityOptions(bOptions)
1034 .setMayWait(userId)
1035 .setIgnoreTargetSecurity(ignoreTargetSecurity)
1036 .setFilterCallingUid(isResolver ? 0 /* system */ : targetUid)
1037 .execute();
1038 } catch (SecurityException e) {
1039 // XXX need to figure out how to propagate to original app.
1040 // A SecurityException here is generally actually a fault of the original
1041 // calling activity (such as a fairly granting permissions), so propagate it
1042 // back to them.
1043 /*
1044 StringBuilder msg = new StringBuilder();
1045 msg.append("While launching");
1046 msg.append(intent.toString());
1047 msg.append(": ");
1048 msg.append(e.getMessage());
1049 */
1050 throw e;
1051 }
1052 }
1053
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001054 int handleIncomingUser(int callingPid, int callingUid, int userId, String name) {
1055 return mAmInternal.handleIncomingUser(callingPid, callingUid, userId, false /* allowAll */,
1056 ALLOW_FULL_ONLY, name, null /* callerPackage */);
1057 }
1058
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001059 @Override
1060 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
1061 Intent intent, String resolvedType, IVoiceInteractionSession session,
1062 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
1063 Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001064 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001065 if (session == null || interactor == null) {
1066 throw new NullPointerException("null session or interactor");
1067 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001068 userId = handleIncomingUser(callingPid, callingUid, userId, "startVoiceActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001069 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001070 return getActivityStartController().obtainStarter(intent, "startVoiceActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001071 .setCallingUid(callingUid)
1072 .setCallingPackage(callingPackage)
1073 .setResolvedType(resolvedType)
1074 .setVoiceSession(session)
1075 .setVoiceInteractor(interactor)
1076 .setStartFlags(startFlags)
1077 .setProfilerInfo(profilerInfo)
1078 .setActivityOptions(bOptions)
1079 .setMayWait(userId)
1080 .execute();
1081 }
1082
1083 @Override
1084 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
1085 Intent intent, String resolvedType, Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001086 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
1087 userId = handleIncomingUser(callingPid, callingUid, userId, "startAssistantActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001088
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001089 return getActivityStartController().obtainStarter(intent, "startAssistantActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001090 .setCallingUid(callingUid)
1091 .setCallingPackage(callingPackage)
1092 .setResolvedType(resolvedType)
1093 .setActivityOptions(bOptions)
1094 .setMayWait(userId)
1095 .execute();
1096 }
1097
1098 @Override
1099 public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
1100 IRecentsAnimationRunner recentsAnimationRunner) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001101 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001102 final int callingPid = Binder.getCallingPid();
1103 final long origId = Binder.clearCallingIdentity();
1104 try {
1105 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07001106 final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
1107 final int recentsUid = mRecentTasks.getRecentsComponentUid();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001108
1109 // Start a new recents animation
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001110 final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
1111 getActivityStartController(), mWindowManager, callingPid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001112 anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
1113 recentsUid, assistDataReceiver);
1114 }
1115 } finally {
1116 Binder.restoreCallingIdentity(origId);
1117 }
1118 }
1119
1120 @Override
1121 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001122 enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001123 "startActivityFromRecents()");
1124
1125 final int callingPid = Binder.getCallingPid();
1126 final int callingUid = Binder.getCallingUid();
1127 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(bOptions);
1128 final long origId = Binder.clearCallingIdentity();
1129 try {
1130 synchronized (mGlobalLock) {
1131 return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
1132 safeOptions);
1133 }
1134 } finally {
1135 Binder.restoreCallingIdentity(origId);
1136 }
1137 }
1138
1139 /**
1140 * This is the internal entry point for handling Activity.finish().
1141 *
1142 * @param token The Binder token referencing the Activity we want to finish.
1143 * @param resultCode Result code, if any, from this Activity.
1144 * @param resultData Result data (Intent), if any, from this Activity.
1145 * @param finishTask Whether to finish the task associated with this Activity.
1146 *
1147 * @return Returns true if the activity successfully finished, or false if it is still running.
1148 */
1149 @Override
1150 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
1151 int finishTask) {
1152 // Refuse possible leaked file descriptors
1153 if (resultData != null && resultData.hasFileDescriptors()) {
1154 throw new IllegalArgumentException("File descriptors passed in Intent");
1155 }
1156
1157 synchronized (mGlobalLock) {
1158 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1159 if (r == null) {
1160 return true;
1161 }
1162 // Keep track of the root activity of the task before we finish it
1163 TaskRecord tr = r.getTask();
1164 ActivityRecord rootR = tr.getRootActivity();
1165 if (rootR == null) {
1166 Slog.w(TAG, "Finishing task with all activities already finished");
1167 }
1168 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
1169 // finish.
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001170 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001171 return false;
1172 }
1173
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001174 // TODO: There is a dup. of this block of code in ActivityStack.navigateUpToLocked
1175 // We should consolidate.
1176 if (mController != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001177 // Find the first activity that is not finishing.
1178 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
1179 if (next != null) {
1180 // ask watcher if this is allowed
1181 boolean resumeOK = true;
1182 try {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001183 resumeOK = mController.activityResuming(next.packageName);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001184 } catch (RemoteException e) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001185 mController = null;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001186 Watchdog.getInstance().setActivityController(null);
1187 }
1188
1189 if (!resumeOK) {
1190 Slog.i(TAG, "Not finishing activity because controller resumed");
1191 return false;
1192 }
1193 }
1194 }
1195 final long origId = Binder.clearCallingIdentity();
1196 try {
1197 boolean res;
1198 final boolean finishWithRootActivity =
1199 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
1200 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
1201 || (finishWithRootActivity && r == rootR)) {
1202 // If requested, remove the task that is associated to this activity only if it
1203 // was the root activity in the task. The result code and data is ignored
1204 // because we don't support returning them across task boundaries. Also, to
1205 // keep backwards compatibility we remove the task from recents when finishing
1206 // task with root activity.
1207 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
1208 finishWithRootActivity, "finish-activity");
1209 if (!res) {
1210 Slog.i(TAG, "Removing task failed to finish activity");
1211 }
Garfield Tan2746ab52018-07-25 12:33:01 -07001212 // Explicitly dismissing the activity so reset its relaunch flag.
1213 r.mRelaunchReason = ActivityRecord.RELAUNCH_REASON_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001214 } else {
1215 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
1216 resultData, "app-request", true);
1217 if (!res) {
1218 Slog.i(TAG, "Failed to finish by app-request");
1219 }
1220 }
1221 return res;
1222 } finally {
1223 Binder.restoreCallingIdentity(origId);
1224 }
1225 }
1226 }
1227
1228 @Override
1229 public boolean finishActivityAffinity(IBinder token) {
1230 synchronized (mGlobalLock) {
1231 final long origId = Binder.clearCallingIdentity();
1232 try {
1233 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1234 if (r == null) {
1235 return false;
1236 }
1237
1238 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
1239 // can finish.
1240 final TaskRecord task = r.getTask();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001241 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001242 return false;
1243 }
1244 return task.getStack().finishActivityAffinityLocked(r);
1245 } finally {
1246 Binder.restoreCallingIdentity(origId);
1247 }
1248 }
1249 }
1250
1251 @Override
1252 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
1253 final long origId = Binder.clearCallingIdentity();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001254 try {
1255 WindowProcessController proc = null;
1256 synchronized (mGlobalLock) {
1257 ActivityStack stack = ActivityRecord.getStackLocked(token);
1258 if (stack == null) {
1259 return;
1260 }
1261 final ActivityRecord r = mStackSupervisor.activityIdleInternalLocked(token,
1262 false /* fromTimeout */, false /* processPausingActivities */, config);
1263 if (r != null) {
1264 proc = r.app;
1265 }
1266 if (stopProfiling && proc != null) {
1267 proc.clearProfilerIfNeeded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001268 }
1269 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001270 } finally {
1271 Binder.restoreCallingIdentity(origId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001272 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001273 }
1274
1275 @Override
1276 public final void activityResumed(IBinder token) {
1277 final long origId = Binder.clearCallingIdentity();
1278 synchronized (mGlobalLock) {
1279 ActivityRecord.activityResumedLocked(token);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001280 mWindowManager.notifyAppResumedFinished(token);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001281 }
1282 Binder.restoreCallingIdentity(origId);
1283 }
1284
1285 @Override
1286 public final void activityPaused(IBinder token) {
1287 final long origId = Binder.clearCallingIdentity();
1288 synchronized (mGlobalLock) {
1289 ActivityStack stack = ActivityRecord.getStackLocked(token);
1290 if (stack != null) {
1291 stack.activityPausedLocked(token, false);
1292 }
1293 }
1294 Binder.restoreCallingIdentity(origId);
1295 }
1296
1297 @Override
1298 public final void activityStopped(IBinder token, Bundle icicle,
1299 PersistableBundle persistentState, CharSequence description) {
1300 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
1301
1302 // Refuse possible leaked file descriptors
1303 if (icicle != null && icicle.hasFileDescriptors()) {
1304 throw new IllegalArgumentException("File descriptors passed in Bundle");
1305 }
1306
1307 final long origId = Binder.clearCallingIdentity();
1308
1309 synchronized (mGlobalLock) {
1310 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1311 if (r != null) {
1312 r.activityStoppedLocked(icicle, persistentState, description);
1313 }
1314 }
1315
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001316 mAmInternal.trimApplications();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001317
1318 Binder.restoreCallingIdentity(origId);
1319 }
1320
1321 @Override
1322 public final void activityDestroyed(IBinder token) {
1323 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
1324 synchronized (mGlobalLock) {
1325 ActivityStack stack = ActivityRecord.getStackLocked(token);
1326 if (stack != null) {
1327 stack.activityDestroyedLocked(token, "activityDestroyed");
1328 }
1329 }
1330 }
1331
1332 @Override
1333 public final void activityRelaunched(IBinder token) {
1334 final long origId = Binder.clearCallingIdentity();
1335 synchronized (mGlobalLock) {
1336 mStackSupervisor.activityRelaunchedLocked(token);
1337 }
1338 Binder.restoreCallingIdentity(origId);
1339 }
1340
1341 public final void activitySlept(IBinder token) {
1342 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
1343
1344 final long origId = Binder.clearCallingIdentity();
1345
1346 synchronized (mGlobalLock) {
1347 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1348 if (r != null) {
1349 mStackSupervisor.activitySleptLocked(r);
1350 }
1351 }
1352
1353 Binder.restoreCallingIdentity(origId);
1354 }
1355
1356 @Override
1357 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
1358 synchronized (mGlobalLock) {
1359 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1360 if (r == null) {
1361 return;
1362 }
1363 final long origId = Binder.clearCallingIdentity();
1364 try {
1365 r.setRequestedOrientation(requestedOrientation);
1366 } finally {
1367 Binder.restoreCallingIdentity(origId);
1368 }
1369 }
1370 }
1371
1372 @Override
1373 public int getRequestedOrientation(IBinder token) {
1374 synchronized (mGlobalLock) {
1375 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1376 if (r == null) {
1377 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
1378 }
1379 return r.getRequestedOrientation();
1380 }
1381 }
1382
1383 @Override
1384 public void setImmersive(IBinder token, boolean immersive) {
1385 synchronized (mGlobalLock) {
1386 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1387 if (r == null) {
1388 throw new IllegalArgumentException();
1389 }
1390 r.immersive = immersive;
1391
1392 // update associated state if we're frontmost
Andrii Kulian52d255c2018-07-13 11:32:19 -07001393 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001394 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001395 applyUpdateLockStateLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001396 }
1397 }
1398 }
1399
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001400 void applyUpdateLockStateLocked(ActivityRecord r) {
1401 // Modifications to the UpdateLock state are done on our handler, outside
1402 // the activity manager's locks. The new state is determined based on the
1403 // state *now* of the relevant activity record. The object is passed to
1404 // the handler solely for logging detail, not to be consulted/modified.
1405 final boolean nextState = r != null && r.immersive;
1406 mH.post(() -> {
1407 if (mUpdateLock.isHeld() != nextState) {
1408 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1409 "Applying new update lock state '" + nextState + "' for " + r);
1410 if (nextState) {
1411 mUpdateLock.acquire();
1412 } else {
1413 mUpdateLock.release();
1414 }
1415 }
1416 });
1417 }
1418
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001419 @Override
1420 public boolean isImmersive(IBinder token) {
1421 synchronized (mGlobalLock) {
1422 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1423 if (r == null) {
1424 throw new IllegalArgumentException();
1425 }
1426 return r.immersive;
1427 }
1428 }
1429
1430 @Override
1431 public boolean isTopActivityImmersive() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001432 enforceNotIsolatedCaller("isTopActivityImmersive");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001433 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001434 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001435 return (r != null) ? r.immersive : false;
1436 }
1437 }
1438
1439 @Override
1440 public void overridePendingTransition(IBinder token, String packageName,
1441 int enterAnim, int exitAnim) {
1442 synchronized (mGlobalLock) {
1443 ActivityRecord self = ActivityRecord.isInStackLocked(token);
1444 if (self == null) {
1445 return;
1446 }
1447
1448 final long origId = Binder.clearCallingIdentity();
1449
1450 if (self.isState(
1451 ActivityStack.ActivityState.RESUMED, ActivityStack.ActivityState.PAUSING)) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001452 mWindowManager.overridePendingAppTransition(packageName,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001453 enterAnim, exitAnim, null);
1454 }
1455
1456 Binder.restoreCallingIdentity(origId);
1457 }
1458 }
1459
1460 @Override
1461 public int getFrontActivityScreenCompatMode() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001462 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
1463 ApplicationInfo ai;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001464 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001465 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001466 if (r == null) {
1467 return ActivityManager.COMPAT_MODE_UNKNOWN;
1468 }
1469 ai = r.info.applicationInfo;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001470 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001471
1472 return mAmInternal.getPackageScreenCompatMode(ai);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001473 }
1474
1475 @Override
1476 public void setFrontActivityScreenCompatMode(int mode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001477 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001478 "setFrontActivityScreenCompatMode");
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001479 ApplicationInfo ai;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001480 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001481 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001482 if (r == null) {
1483 Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity");
1484 return;
1485 }
1486 ai = r.info.applicationInfo;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001487 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001488
1489 mAmInternal.setPackageScreenCompatMode(ai, mode);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001490 }
1491
1492 @Override
1493 public int getLaunchedFromUid(IBinder activityToken) {
1494 ActivityRecord srec;
1495 synchronized (mGlobalLock) {
1496 srec = ActivityRecord.forTokenLocked(activityToken);
1497 }
1498 if (srec == null) {
1499 return -1;
1500 }
1501 return srec.launchedFromUid;
1502 }
1503
1504 @Override
1505 public String getLaunchedFromPackage(IBinder activityToken) {
1506 ActivityRecord srec;
1507 synchronized (mGlobalLock) {
1508 srec = ActivityRecord.forTokenLocked(activityToken);
1509 }
1510 if (srec == null) {
1511 return null;
1512 }
1513 return srec.launchedFromPackage;
1514 }
1515
1516 @Override
1517 public boolean convertFromTranslucent(IBinder token) {
1518 final long origId = Binder.clearCallingIdentity();
1519 try {
1520 synchronized (mGlobalLock) {
1521 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1522 if (r == null) {
1523 return false;
1524 }
1525 final boolean translucentChanged = r.changeWindowTranslucency(true);
1526 if (translucentChanged) {
1527 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
1528 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001529 mWindowManager.setAppFullscreen(token, true);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001530 return translucentChanged;
1531 }
1532 } finally {
1533 Binder.restoreCallingIdentity(origId);
1534 }
1535 }
1536
1537 @Override
1538 public boolean convertToTranslucent(IBinder token, Bundle options) {
1539 SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
1540 final long origId = Binder.clearCallingIdentity();
1541 try {
1542 synchronized (mGlobalLock) {
1543 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1544 if (r == null) {
1545 return false;
1546 }
1547 final TaskRecord task = r.getTask();
1548 int index = task.mActivities.lastIndexOf(r);
1549 if (index > 0) {
1550 ActivityRecord under = task.mActivities.get(index - 1);
1551 under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
1552 }
1553 final boolean translucentChanged = r.changeWindowTranslucency(false);
1554 if (translucentChanged) {
1555 r.getStack().convertActivityToTranslucent(r);
1556 }
1557 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001558 mWindowManager.setAppFullscreen(token, false);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001559 return translucentChanged;
1560 }
1561 } finally {
1562 Binder.restoreCallingIdentity(origId);
1563 }
1564 }
1565
1566 @Override
1567 public void notifyActivityDrawn(IBinder token) {
1568 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
1569 synchronized (mGlobalLock) {
1570 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
1571 if (r != null) {
1572 r.getStack().notifyActivityDrawnLocked(r);
1573 }
1574 }
1575 }
1576
1577 @Override
1578 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
1579 synchronized (mGlobalLock) {
1580 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1581 if (r == null) {
1582 return;
1583 }
1584 r.reportFullyDrawnLocked(restoredFromBundle);
1585 }
1586 }
1587
1588 @Override
1589 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
1590 synchronized (mGlobalLock) {
1591 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
1592 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
1593 return stack.mDisplayId;
1594 }
1595 return DEFAULT_DISPLAY;
1596 }
1597 }
1598
1599 @Override
1600 public ActivityManager.StackInfo getFocusedStackInfo() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001601 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001602 long ident = Binder.clearCallingIdentity();
1603 try {
1604 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001605 ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001606 if (focusedStack != null) {
1607 return mStackSupervisor.getStackInfo(focusedStack.mStackId);
1608 }
1609 return null;
1610 }
1611 } finally {
1612 Binder.restoreCallingIdentity(ident);
1613 }
1614 }
1615
1616 @Override
1617 public void setFocusedStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001618 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001619 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
1620 final long callingId = Binder.clearCallingIdentity();
1621 try {
1622 synchronized (mGlobalLock) {
1623 final ActivityStack stack = mStackSupervisor.getStack(stackId);
1624 if (stack == null) {
1625 Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
1626 return;
1627 }
1628 final ActivityRecord r = stack.topRunningActivityLocked();
1629 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
1630 r, "setFocusedStack")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08001631 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001632 }
1633 }
1634 } finally {
1635 Binder.restoreCallingIdentity(callingId);
1636 }
1637 }
1638
1639 @Override
1640 public void setFocusedTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001641 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001642 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
1643 final long callingId = Binder.clearCallingIdentity();
1644 try {
1645 synchronized (mGlobalLock) {
1646 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1647 if (task == null) {
1648 return;
1649 }
1650 final ActivityRecord r = task.topRunningActivityLocked();
1651 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08001652 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001653 }
1654 }
1655 } finally {
1656 Binder.restoreCallingIdentity(callingId);
1657 }
1658 }
1659
1660 @Override
1661 public boolean removeTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001662 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001663 synchronized (mGlobalLock) {
1664 final long ident = Binder.clearCallingIdentity();
1665 try {
1666 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
1667 "remove-task");
1668 } finally {
1669 Binder.restoreCallingIdentity(ident);
1670 }
1671 }
1672 }
1673
1674 @Override
1675 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
1676 synchronized (mGlobalLock) {
1677 final ActivityRecord srec = ActivityRecord.forTokenLocked(token);
1678 if (srec != null) {
1679 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
1680 }
1681 }
1682 return false;
1683 }
1684
1685 @Override
1686 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
1687 Intent resultData) {
1688
1689 synchronized (mGlobalLock) {
1690 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
1691 if (r != null) {
1692 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
1693 }
1694 return false;
1695 }
1696 }
1697
1698 /**
1699 * Attempts to move a task backwards in z-order (the order of activities within the task is
1700 * unchanged).
1701 *
1702 * There are several possible results of this call:
1703 * - if the task is locked, then we will show the lock toast
1704 * - if there is a task behind the provided task, then that task is made visible and resumed as
1705 * this task is moved to the back
1706 * - otherwise, if there are no other tasks in the stack:
1707 * - if this task is in the pinned stack, then we remove the stack completely, which will
1708 * have the effect of moving the task to the top or bottom of the fullscreen stack
1709 * (depending on whether it is visible)
1710 * - otherwise, we simply return home and hide this task
1711 *
1712 * @param token A reference to the activity we wish to move
1713 * @param nonRoot If false then this only works if the activity is the root
1714 * of a task; if true it will work for any activity in a task.
1715 * @return Returns true if the move completed, false if not.
1716 */
1717 @Override
1718 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001719 enforceNotIsolatedCaller("moveActivityTaskToBack");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001720 synchronized (mGlobalLock) {
1721 final long origId = Binder.clearCallingIdentity();
1722 try {
1723 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
1724 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1725 if (task != null) {
1726 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
1727 }
1728 } finally {
1729 Binder.restoreCallingIdentity(origId);
1730 }
1731 }
1732 return false;
1733 }
1734
1735 @Override
1736 public Rect getTaskBounds(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001737 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001738 long ident = Binder.clearCallingIdentity();
1739 Rect rect = new Rect();
1740 try {
1741 synchronized (mGlobalLock) {
1742 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
1743 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1744 if (task == null) {
1745 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
1746 return rect;
1747 }
1748 if (task.getStack() != null) {
1749 // Return the bounds from window manager since it will be adjusted for various
1750 // things like the presense of a docked stack for tasks that aren't resizeable.
1751 task.getWindowContainerBounds(rect);
1752 } else {
1753 // Task isn't in window manager yet since it isn't associated with a stack.
1754 // Return the persist value from activity manager
1755 if (!task.matchParentBounds()) {
1756 rect.set(task.getBounds());
1757 } else if (task.mLastNonFullscreenBounds != null) {
1758 rect.set(task.mLastNonFullscreenBounds);
1759 }
1760 }
1761 }
1762 } finally {
1763 Binder.restoreCallingIdentity(ident);
1764 }
1765 return rect;
1766 }
1767
1768 @Override
1769 public ActivityManager.TaskDescription getTaskDescription(int id) {
1770 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001771 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001772 MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
1773 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
1774 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1775 if (tr != null) {
1776 return tr.lastTaskDescription;
1777 }
1778 }
1779 return null;
1780 }
1781
1782 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001783 public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
1784 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
1785 setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
1786 toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
1787 return;
1788 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001789 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001790 synchronized (mGlobalLock) {
1791 final long ident = Binder.clearCallingIdentity();
1792 try {
1793 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1794 if (task == null) {
1795 Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
1796 return;
1797 }
1798
1799 if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
1800 + " to windowingMode=" + windowingMode + " toTop=" + toTop);
1801
1802 if (!task.isActivityTypeStandardOrUndefined()) {
1803 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
1804 + " non-standard task " + taskId + " to windowing mode="
1805 + windowingMode);
1806 }
1807
1808 final ActivityStack stack = task.getStack();
1809 if (toTop) {
1810 stack.moveToFront("setTaskWindowingMode", task);
1811 }
1812 stack.setWindowingMode(windowingMode);
1813 } finally {
1814 Binder.restoreCallingIdentity(ident);
1815 }
1816 }
1817 }
1818
1819 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001820 public String getCallingPackage(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001821 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001822 ActivityRecord r = getCallingRecordLocked(token);
1823 return r != null ? r.info.packageName : null;
1824 }
1825 }
1826
1827 @Override
1828 public ComponentName getCallingActivity(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001829 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001830 ActivityRecord r = getCallingRecordLocked(token);
1831 return r != null ? r.intent.getComponent() : null;
1832 }
1833 }
1834
1835 private ActivityRecord getCallingRecordLocked(IBinder token) {
1836 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1837 if (r == null) {
1838 return null;
1839 }
1840 return r.resultTo;
1841 }
1842
1843 @Override
1844 public void unhandledBack() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001845 mAmInternal.enforceCallingPermission(android.Manifest.permission.FORCE_BACK, "unhandledBack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001846
1847 synchronized (mGlobalLock) {
1848 final long origId = Binder.clearCallingIdentity();
1849 try {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001850 getTopDisplayFocusedStack().unhandledBackLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001851 } finally {
1852 Binder.restoreCallingIdentity(origId);
1853 }
1854 }
1855 }
1856
1857 /**
1858 * TODO: Add mController hook
1859 */
1860 @Override
1861 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001862 mAmInternal.enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001863
1864 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
1865 synchronized (mGlobalLock) {
1866 moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
1867 false /* fromRecents */);
1868 }
1869 }
1870
1871 void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
1872 boolean fromRecents) {
1873
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001874 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001875 Binder.getCallingUid(), -1, -1, "Task to front")) {
1876 SafeActivityOptions.abort(options);
1877 return;
1878 }
1879 final long origId = Binder.clearCallingIdentity();
1880 try {
1881 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1882 if (task == null) {
1883 Slog.d(TAG, "Could not find task for id: "+ taskId);
1884 return;
1885 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001886 if (getLockTaskController().isLockTaskModeViolation(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001887 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
1888 return;
1889 }
1890 ActivityOptions realOptions = options != null
1891 ? options.getOptions(mStackSupervisor)
1892 : null;
1893 mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
1894 false /* forceNonResizable */);
1895
1896 final ActivityRecord topActivity = task.getTopActivity();
1897 if (topActivity != null) {
1898
1899 // We are reshowing a task, use a starting window to hide the initial draw delay
1900 // so the transition can start earlier.
1901 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
1902 true /* taskSwitch */, fromRecents);
1903 }
1904 } finally {
1905 Binder.restoreCallingIdentity(origId);
1906 }
1907 SafeActivityOptions.abort(options);
1908 }
1909
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001910 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
1911 int callingPid, int callingUid, String name) {
1912 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
1913 return true;
1914 }
1915
1916 if (getRecentTasks().isCallerRecents(sourceUid)) {
1917 return true;
1918 }
1919
1920 int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
1921 if (perm == PackageManager.PERMISSION_GRANTED) {
1922 return true;
1923 }
1924 if (checkAllowAppSwitchUid(sourceUid)) {
1925 return true;
1926 }
1927
1928 // If the actual IPC caller is different from the logical source, then
1929 // also see if they are allowed to control app switches.
1930 if (callingUid != -1 && callingUid != sourceUid) {
1931 perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
1932 if (perm == PackageManager.PERMISSION_GRANTED) {
1933 return true;
1934 }
1935 if (checkAllowAppSwitchUid(callingUid)) {
1936 return true;
1937 }
1938 }
1939
1940 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
1941 return false;
1942 }
1943
1944 private boolean checkAllowAppSwitchUid(int uid) {
1945 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
1946 if (types != null) {
1947 for (int i = types.size() - 1; i >= 0; i--) {
1948 if (types.valueAt(i).intValue() == uid) {
1949 return true;
1950 }
1951 }
1952 }
1953 return false;
1954 }
1955
1956 @Override
1957 public void setActivityController(IActivityController controller, boolean imAMonkey) {
1958 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
1959 "setActivityController()");
1960 synchronized (mGlobalLock) {
1961 mController = controller;
1962 mControllerIsAMonkey = imAMonkey;
1963 Watchdog.getInstance().setActivityController(controller);
1964 }
1965 }
1966
1967 boolean isControllerAMonkey() {
1968 synchronized (mGlobalLock) {
1969 return mController != null && mControllerIsAMonkey;
1970 }
1971 }
1972
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001973 @Override
1974 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
1975 synchronized (mGlobalLock) {
1976 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
1977 }
1978 }
1979
1980 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001981 public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum) {
1982 return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
1983 }
1984
1985 @Override
1986 public List<ActivityManager.RunningTaskInfo> getFilteredTasks(int maxNum,
1987 @WindowConfiguration.ActivityType int ignoreActivityType,
1988 @WindowConfiguration.WindowingMode int ignoreWindowingMode) {
1989 final int callingUid = Binder.getCallingUid();
1990 ArrayList<ActivityManager.RunningTaskInfo> list = new ArrayList<>();
1991
1992 synchronized (mGlobalLock) {
1993 if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
1994
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001995 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001996 callingUid);
1997 mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
1998 ignoreWindowingMode, callingUid, allowed);
1999 }
2000
2001 return list;
2002 }
2003
2004 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002005 public final void finishSubActivity(IBinder token, String resultWho, int requestCode) {
2006 synchronized (mGlobalLock) {
2007 final long origId = Binder.clearCallingIdentity();
2008 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2009 if (r != null) {
2010 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
2011 }
2012 Binder.restoreCallingIdentity(origId);
2013 }
2014 }
2015
2016 @Override
2017 public boolean willActivityBeVisible(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002018 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002019 ActivityStack stack = ActivityRecord.getStackLocked(token);
2020 if (stack != null) {
2021 return stack.willActivityBeVisibleLocked(token);
2022 }
2023 return false;
2024 }
2025 }
2026
2027 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002028 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002029 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002030 synchronized (mGlobalLock) {
2031 final long ident = Binder.clearCallingIdentity();
2032 try {
2033 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2034 if (task == null) {
2035 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
2036 return;
2037 }
2038
2039 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
2040 + " to stackId=" + stackId + " toTop=" + toTop);
2041
2042 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2043 if (stack == null) {
2044 throw new IllegalStateException(
2045 "moveTaskToStack: No stack for stackId=" + stackId);
2046 }
2047 if (!stack.isActivityTypeStandardOrUndefined()) {
2048 throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
2049 + taskId + " to stack " + stackId);
2050 }
2051 if (stack.inSplitScreenPrimaryWindowingMode()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002052 mWindowManager.setDockedStackCreateState(
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002053 SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
2054 }
2055 task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
2056 "moveTaskToStack");
2057 } finally {
2058 Binder.restoreCallingIdentity(ident);
2059 }
2060 }
2061 }
2062
2063 @Override
2064 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
2065 boolean preserveWindows, boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002066 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002067
2068 final long ident = Binder.clearCallingIdentity();
2069 try {
2070 synchronized (mGlobalLock) {
2071 if (animate) {
2072 final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
2073 if (stack == null) {
2074 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2075 return;
2076 }
2077 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
2078 throw new IllegalArgumentException("Stack: " + stackId
2079 + " doesn't support animated resize.");
2080 }
2081 stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
2082 animationDuration, false /* fromFullscreen */);
2083 } else {
2084 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2085 if (stack == null) {
2086 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2087 return;
2088 }
2089 mStackSupervisor.resizeStackLocked(stack, destBounds,
2090 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
2091 preserveWindows, allowResizeInDockedMode, !DEFER_RESUME);
2092 }
2093 }
2094 } finally {
2095 Binder.restoreCallingIdentity(ident);
2096 }
2097 }
2098
2099 /**
2100 * Moves the specified task to the primary-split-screen stack.
2101 *
2102 * @param taskId Id of task to move.
2103 * @param createMode The mode the primary split screen stack should be created in if it doesn't
2104 * exist already. See
2105 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
2106 * and
2107 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
2108 * @param toTop If the task and stack should be moved to the top.
2109 * @param animate Whether we should play an animation for the moving the task.
2110 * @param initialBounds If the primary stack gets created, it will use these bounds for the
2111 * stack. Pass {@code null} to use default bounds.
2112 * @param showRecents If the recents activity should be shown on the other side of the task
2113 * going into split-screen mode.
2114 */
2115 @Override
2116 public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode,
2117 boolean toTop, boolean animate, Rect initialBounds, boolean showRecents) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002118 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002119 "setTaskWindowingModeSplitScreenPrimary()");
2120 synchronized (mGlobalLock) {
2121 final long ident = Binder.clearCallingIdentity();
2122 try {
2123 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2124 if (task == null) {
2125 Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
2126 return false;
2127 }
2128 if (DEBUG_STACK) Slog.d(TAG_STACK,
2129 "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
2130 + " to createMode=" + createMode + " toTop=" + toTop);
2131 if (!task.isActivityTypeStandardOrUndefined()) {
2132 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
2133 + " non-standard task " + taskId + " to split-screen windowing mode");
2134 }
2135
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002136 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002137 final int windowingMode = task.getWindowingMode();
2138 final ActivityStack stack = task.getStack();
2139 if (toTop) {
2140 stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
2141 }
2142 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
2143 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */);
2144 return windowingMode != task.getWindowingMode();
2145 } finally {
2146 Binder.restoreCallingIdentity(ident);
2147 }
2148 }
2149 }
2150
2151 /**
2152 * Removes stacks in the input windowing modes from the system if they are of activity type
2153 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
2154 */
2155 @Override
2156 public void removeStacksInWindowingModes(int[] windowingModes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002157 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002158 "removeStacksInWindowingModes()");
2159
2160 synchronized (mGlobalLock) {
2161 final long ident = Binder.clearCallingIdentity();
2162 try {
2163 mStackSupervisor.removeStacksInWindowingModes(windowingModes);
2164 } finally {
2165 Binder.restoreCallingIdentity(ident);
2166 }
2167 }
2168 }
2169
2170 @Override
2171 public void removeStacksWithActivityTypes(int[] activityTypes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002172 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002173 "removeStacksWithActivityTypes()");
2174
2175 synchronized (mGlobalLock) {
2176 final long ident = Binder.clearCallingIdentity();
2177 try {
2178 mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
2179 } finally {
2180 Binder.restoreCallingIdentity(ident);
2181 }
2182 }
2183 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002184
2185 @Override
2186 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
2187 int userId) {
2188 final int callingUid = Binder.getCallingUid();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002189 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, "getRecentTasks");
2190 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002191 callingUid);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002192 final boolean detailed = checkGetTasksPermission(
2193 android.Manifest.permission.GET_DETAILED_TASKS, Binder.getCallingPid(),
2194 UserHandle.getAppId(callingUid))
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002195 == PackageManager.PERMISSION_GRANTED;
2196
2197 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002198 return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002199 callingUid);
2200 }
2201 }
2202
2203 @Override
2204 public List<ActivityManager.StackInfo> getAllStackInfos() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002205 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002206 long ident = Binder.clearCallingIdentity();
2207 try {
2208 synchronized (mGlobalLock) {
2209 return mStackSupervisor.getAllStackInfosLocked();
2210 }
2211 } finally {
2212 Binder.restoreCallingIdentity(ident);
2213 }
2214 }
2215
2216 @Override
2217 public ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002218 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002219 long ident = Binder.clearCallingIdentity();
2220 try {
2221 synchronized (mGlobalLock) {
2222 return mStackSupervisor.getStackInfo(windowingMode, activityType);
2223 }
2224 } finally {
2225 Binder.restoreCallingIdentity(ident);
2226 }
2227 }
2228
2229 @Override
2230 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002231 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002232 final long callingUid = Binder.getCallingUid();
2233 final long origId = Binder.clearCallingIdentity();
2234 try {
2235 synchronized (mGlobalLock) {
2236 // Cancel the recents animation synchronously (do not hold the WM lock)
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002237 mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002238 ? REORDER_MOVE_TO_ORIGINAL_POSITION
2239 : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
2240 }
2241 } finally {
2242 Binder.restoreCallingIdentity(origId);
2243 }
2244 }
2245
2246 @Override
2247 public void startLockTaskModeByToken(IBinder token) {
2248 synchronized (mGlobalLock) {
2249 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2250 if (r == null) {
2251 return;
2252 }
2253 startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
2254 }
2255 }
2256
2257 @Override
2258 public void startSystemLockTaskMode(int taskId) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002259 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002260 // This makes inner call to look as if it was initiated by system.
2261 long ident = Binder.clearCallingIdentity();
2262 try {
2263 synchronized (mGlobalLock) {
2264 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2265
2266 // When starting lock task mode the stack must be in front and focused
2267 task.getStack().moveToFront("startSystemLockTaskMode");
2268 startLockTaskModeLocked(task, true /* isSystemCaller */);
2269 }
2270 } finally {
2271 Binder.restoreCallingIdentity(ident);
2272 }
2273 }
2274
2275 @Override
2276 public void stopLockTaskModeByToken(IBinder token) {
2277 synchronized (mGlobalLock) {
2278 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2279 if (r == null) {
2280 return;
2281 }
2282 stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
2283 }
2284 }
2285
2286 /**
2287 * This API should be called by SystemUI only when user perform certain action to dismiss
2288 * lock task mode. We should only dismiss pinned lock task mode in this case.
2289 */
2290 @Override
2291 public void stopSystemLockTaskMode() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002292 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002293 stopLockTaskModeInternal(null, true /* isSystemCaller */);
2294 }
2295
2296 private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
2297 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
2298 if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
2299 return;
2300 }
2301
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002302 final ActivityStack stack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002303 if (stack == null || task != stack.topTask()) {
2304 throw new IllegalArgumentException("Invalid task, not in foreground");
2305 }
2306
2307 // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
2308 // system or a specific app.
2309 // * System-initiated requests will only start the pinned mode (screen pinning)
2310 // * App-initiated requests
2311 // - will put the device in fully locked mode (LockTask), if the app is whitelisted
2312 // - will start the pinned mode, otherwise
2313 final int callingUid = Binder.getCallingUid();
2314 long ident = Binder.clearCallingIdentity();
2315 try {
2316 // When a task is locked, dismiss the pinned stack if it exists
2317 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2318
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002319 getLockTaskController().startLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002320 } finally {
2321 Binder.restoreCallingIdentity(ident);
2322 }
2323 }
2324
2325 private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
2326 final int callingUid = Binder.getCallingUid();
2327 long ident = Binder.clearCallingIdentity();
2328 try {
2329 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002330 getLockTaskController().stopLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002331 }
2332 // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
2333 // task and jumping straight into a call in the case of emergency call back.
2334 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
2335 if (tm != null) {
2336 tm.showInCallScreen(false);
2337 }
2338 } finally {
2339 Binder.restoreCallingIdentity(ident);
2340 }
2341 }
2342
2343 @Override
2344 public boolean isInLockTaskMode() {
2345 return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
2346 }
2347
2348 @Override
2349 public int getLockTaskModeState() {
2350 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002351 return getLockTaskController().getLockTaskModeState();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002352 }
2353 }
2354
2355 @Override
2356 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
2357 synchronized (mGlobalLock) {
2358 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2359 if (r != null) {
2360 r.setTaskDescription(td);
2361 final TaskRecord task = r.getTask();
2362 task.updateTaskDescription();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002363 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002364 }
2365 }
2366 }
2367
2368 @Override
2369 public Bundle getActivityOptions(IBinder token) {
2370 final long origId = Binder.clearCallingIdentity();
2371 try {
2372 synchronized (mGlobalLock) {
2373 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
2374 if (r != null) {
2375 final ActivityOptions activityOptions = r.takeOptionsLocked();
2376 return activityOptions == null ? null : activityOptions.toBundle();
2377 }
2378 return null;
2379 }
2380 } finally {
2381 Binder.restoreCallingIdentity(origId);
2382 }
2383 }
2384
2385 @Override
2386 public List<IBinder> getAppTasks(String callingPackage) {
2387 int callingUid = Binder.getCallingUid();
2388 long ident = Binder.clearCallingIdentity();
2389 try {
2390 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002391 return mRecentTasks.getAppTasksList(callingUid, callingPackage);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002392 }
2393 } finally {
2394 Binder.restoreCallingIdentity(ident);
2395 }
2396 }
2397
2398 @Override
2399 public void finishVoiceTask(IVoiceInteractionSession session) {
2400 synchronized (mGlobalLock) {
2401 final long origId = Binder.clearCallingIdentity();
2402 try {
2403 // TODO: VI Consider treating local voice interactions and voice tasks
2404 // differently here
2405 mStackSupervisor.finishVoiceTask(session);
2406 } finally {
2407 Binder.restoreCallingIdentity(origId);
2408 }
2409 }
2410
2411 }
2412
2413 @Override
2414 public boolean isTopOfTask(IBinder token) {
2415 synchronized (mGlobalLock) {
2416 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2417 if (r == null) {
2418 throw new IllegalArgumentException();
2419 }
2420 return r.getTask().getTopActivity() == r;
2421 }
2422 }
2423
2424 @Override
2425 public void notifyLaunchTaskBehindComplete(IBinder token) {
2426 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
2427 }
2428
2429 @Override
2430 public void notifyEnterAnimationComplete(IBinder token) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002431 mH.post(() -> {
2432 synchronized (mGlobalLock) {
2433 ActivityRecord r = ActivityRecord.forTokenLocked(token);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002434 if (r != null && r.attachedToProcess()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002435 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002436 r.app.getThread().scheduleEnterAnimationComplete(r.appToken);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002437 } catch (RemoteException e) {
2438 }
2439 }
2440 }
2441
2442 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002443 }
2444
2445 /** Called from an app when assist data is ready. */
2446 @Override
2447 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
2448 AssistContent content, Uri referrer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002449 PendingAssistExtras pae = (PendingAssistExtras) token;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002450 synchronized (pae) {
2451 pae.result = extras;
2452 pae.structure = structure;
2453 pae.content = content;
2454 if (referrer != null) {
2455 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
2456 }
2457 if (structure != null) {
2458 structure.setHomeActivity(pae.isHome);
2459 }
2460 pae.haveResult = true;
2461 pae.notifyAll();
2462 if (pae.intent == null && pae.receiver == null) {
2463 // Caller is just waiting for the result.
2464 return;
2465 }
2466 }
2467 // We are now ready to launch the assist activity.
2468 IAssistDataReceiver sendReceiver = null;
2469 Bundle sendBundle = null;
2470 synchronized (mGlobalLock) {
2471 buildAssistBundleLocked(pae, extras);
2472 boolean exists = mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002473 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002474 if (!exists) {
2475 // Timed out.
2476 return;
2477 }
2478
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002479 if ((sendReceiver = pae.receiver) != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002480 // Caller wants result sent back to them.
2481 sendBundle = new Bundle();
2482 sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
2483 sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
2484 sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
2485 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
2486 }
2487 }
2488 if (sendReceiver != null) {
2489 try {
2490 sendReceiver.onHandleAssistData(sendBundle);
2491 } catch (RemoteException e) {
2492 }
2493 return;
2494 }
2495
2496 final long ident = Binder.clearCallingIdentity();
2497 try {
2498 if (TextUtils.equals(pae.intent.getAction(),
2499 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
2500 pae.intent.putExtras(pae.extras);
2501 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
2502 } else {
2503 pae.intent.replaceExtras(pae.extras);
2504 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
2505 | Intent.FLAG_ACTIVITY_SINGLE_TOP
2506 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002507 mAmInternal.closeSystemDialogs("assist");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002508
2509 try {
2510 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
2511 } catch (ActivityNotFoundException e) {
2512 Slog.w(TAG, "No activity to handle assist action.", e);
2513 }
2514 }
2515 } finally {
2516 Binder.restoreCallingIdentity(ident);
2517 }
2518 }
2519
2520 @Override
2521 public int addAppTask(IBinder activityToken, Intent intent,
2522 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
2523 final int callingUid = Binder.getCallingUid();
2524 final long callingIdent = Binder.clearCallingIdentity();
2525
2526 try {
2527 synchronized (mGlobalLock) {
2528 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
2529 if (r == null) {
2530 throw new IllegalArgumentException("Activity does not exist; token="
2531 + activityToken);
2532 }
2533 ComponentName comp = intent.getComponent();
2534 if (comp == null) {
2535 throw new IllegalArgumentException("Intent " + intent
2536 + " must specify explicit component");
2537 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002538 if (thumbnail.getWidth() != mThumbnailWidth
2539 || thumbnail.getHeight() != mThumbnailHeight) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002540 throw new IllegalArgumentException("Bad thumbnail size: got "
2541 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002542 + mThumbnailWidth + "x" + mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002543 }
2544 if (intent.getSelector() != null) {
2545 intent.setSelector(null);
2546 }
2547 if (intent.getSourceBounds() != null) {
2548 intent.setSourceBounds(null);
2549 }
2550 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
2551 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
2552 // The caller has added this as an auto-remove task... that makes no
2553 // sense, so turn off auto-remove.
2554 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
2555 }
2556 }
2557 final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
2558 STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
2559 if (ainfo.applicationInfo.uid != callingUid) {
2560 throw new SecurityException(
2561 "Can't add task for another application: target uid="
2562 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
2563 }
2564
2565 final ActivityStack stack = r.getStack();
2566 final TaskRecord task = stack.createTaskRecord(
2567 mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent,
2568 null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002569 if (!mRecentTasks.addToBottom(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002570 // The app has too many tasks already and we can't add any more
2571 stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
2572 return INVALID_TASK_ID;
2573 }
2574 task.lastTaskDescription.copyFrom(description);
2575
2576 // TODO: Send the thumbnail to WM to store it.
2577
2578 return task.taskId;
2579 }
2580 } finally {
2581 Binder.restoreCallingIdentity(callingIdent);
2582 }
2583 }
2584
2585 @Override
2586 public Point getAppTaskThumbnailSize() {
2587 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002588 return new Point(mThumbnailWidth, mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002589 }
2590 }
2591
2592 @Override
2593 public void setTaskResizeable(int taskId, int resizeableMode) {
2594 synchronized (mGlobalLock) {
2595 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
2596 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
2597 if (task == null) {
2598 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
2599 return;
2600 }
2601 task.setResizeMode(resizeableMode);
2602 }
2603 }
2604
2605 @Override
2606 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002607 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002608 long ident = Binder.clearCallingIdentity();
2609 try {
2610 synchronized (mGlobalLock) {
2611 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2612 if (task == null) {
2613 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
2614 return;
2615 }
2616 // Place the task in the right stack if it isn't there already based on
2617 // the requested bounds.
2618 // The stack transition logic is:
2619 // - a null bounds on a freeform task moves that task to fullscreen
2620 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
2621 // that task to freeform
2622 // - otherwise the task is not moved
2623 ActivityStack stack = task.getStack();
2624 if (!task.getWindowConfiguration().canResizeTask()) {
2625 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
2626 }
2627 if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
2628 stack = stack.getDisplay().getOrCreateStack(
2629 WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
2630 } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
2631 stack = stack.getDisplay().getOrCreateStack(
2632 WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
2633 }
2634
2635 // Reparent the task to the right stack if necessary
2636 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
2637 if (stack != task.getStack()) {
2638 // Defer resume until the task is resized below
2639 task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
2640 DEFER_RESUME, "resizeTask");
2641 preserveWindow = false;
2642 }
2643
2644 // After reparenting (which only resizes the task to the stack bounds), resize the
2645 // task to the actual bounds provided
2646 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
2647 }
2648 } finally {
2649 Binder.restoreCallingIdentity(ident);
2650 }
2651 }
2652
2653 @Override
2654 public boolean releaseActivityInstance(IBinder token) {
2655 synchronized (mGlobalLock) {
2656 final long origId = Binder.clearCallingIdentity();
2657 try {
2658 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2659 if (r == null) {
2660 return false;
2661 }
2662 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
2663 } finally {
2664 Binder.restoreCallingIdentity(origId);
2665 }
2666 }
2667 }
2668
2669 @Override
2670 public void releaseSomeActivities(IApplicationThread appInt) {
2671 synchronized (mGlobalLock) {
2672 final long origId = Binder.clearCallingIdentity();
2673 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002674 WindowProcessController app =
2675 mAm.getRecordForAppLocked(appInt).getWindowProcessController();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002676 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
2677 } finally {
2678 Binder.restoreCallingIdentity(origId);
2679 }
2680 }
2681 }
2682
2683 @Override
2684 public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
2685 int secondaryDisplayShowing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002686 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002687 != PackageManager.PERMISSION_GRANTED) {
2688 throw new SecurityException("Requires permission "
2689 + android.Manifest.permission.DEVICE_POWER);
2690 }
2691
2692 synchronized (mGlobalLock) {
2693 long ident = Binder.clearCallingIdentity();
2694 if (mKeyguardShown != keyguardShowing) {
2695 mKeyguardShown = keyguardShowing;
2696 reportCurKeyguardUsageEventLocked(keyguardShowing);
2697 }
2698 try {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002699 mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002700 secondaryDisplayShowing);
2701 } finally {
2702 Binder.restoreCallingIdentity(ident);
2703 }
2704 }
2705
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002706 mH.post(() -> {
2707 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2708 mScreenObservers.get(i).onKeyguardStateChanged(keyguardShowing);
2709 }
2710 });
2711 }
2712
2713 void onScreenAwakeChanged(boolean isAwake) {
2714 mH.post(() -> {
2715 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2716 mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2717 }
2718 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002719 }
2720
2721 @Override
2722 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002723 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
2724 userId, "getTaskDescriptionIcon");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002725
2726 final File passedIconFile = new File(filePath);
2727 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
2728 passedIconFile.getName());
2729 if (!legitIconFile.getPath().equals(filePath)
2730 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
2731 throw new IllegalArgumentException("Bad file path: " + filePath
2732 + " passed for userId " + userId);
2733 }
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002734 return mRecentTasks.getTaskDescriptionIcon(filePath);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002735 }
2736
2737 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002738 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002739 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
2740 final ActivityOptions activityOptions = safeOptions != null
2741 ? safeOptions.getOptions(mStackSupervisor)
2742 : null;
2743 if (activityOptions == null
2744 || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
2745 || activityOptions.getCustomInPlaceResId() == 0) {
2746 throw new IllegalArgumentException("Expected in-place ActivityOption " +
2747 "with valid animation");
2748 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002749 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
2750 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002751 activityOptions.getCustomInPlaceResId());
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002752 mWindowManager.executeAppTransition();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002753 }
2754
2755 @Override
2756 public void removeStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002757 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002758 synchronized (mGlobalLock) {
2759 final long ident = Binder.clearCallingIdentity();
2760 try {
2761 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2762 if (stack == null) {
2763 Slog.w(TAG, "removeStack: No stack with id=" + stackId);
2764 return;
2765 }
2766 if (!stack.isActivityTypeStandardOrUndefined()) {
2767 throw new IllegalArgumentException(
2768 "Removing non-standard stack is not allowed.");
2769 }
2770 mStackSupervisor.removeStack(stack);
2771 } finally {
2772 Binder.restoreCallingIdentity(ident);
2773 }
2774 }
2775 }
2776
2777 @Override
2778 public void moveStackToDisplay(int stackId, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002779 mAmInternal.enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002780
2781 synchronized (mGlobalLock) {
2782 final long ident = Binder.clearCallingIdentity();
2783 try {
2784 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
2785 + " to displayId=" + displayId);
2786 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
2787 } finally {
2788 Binder.restoreCallingIdentity(ident);
2789 }
2790 }
2791 }
2792
2793 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002794 public void exitFreeformMode(IBinder token) {
2795 synchronized (mGlobalLock) {
2796 long ident = Binder.clearCallingIdentity();
2797 try {
2798 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2799 if (r == null) {
2800 throw new IllegalArgumentException(
2801 "exitFreeformMode: No activity record matching token=" + token);
2802 }
2803
2804 final ActivityStack stack = r.getStack();
2805 if (stack == null || !stack.inFreeformWindowingMode()) {
2806 throw new IllegalStateException(
2807 "exitFreeformMode: You can only go fullscreen from freeform.");
2808 }
2809
2810 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
2811 } finally {
2812 Binder.restoreCallingIdentity(ident);
2813 }
2814 }
2815 }
2816
2817 /** Sets the task stack listener that gets callbacks when a task stack changes. */
2818 @Override
2819 public void registerTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002820 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002821 "registerTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002822 mTaskChangeNotificationController.registerTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002823 }
2824
2825 /** Unregister a task stack listener so that it stops receiving callbacks. */
2826 @Override
2827 public void unregisterTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002828 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002829 "unregisterTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002830 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002831 }
2832
2833 private void reportCurKeyguardUsageEventLocked(boolean keyguardShowing) {
2834 mAm.reportGlobalUsageEventLocked(keyguardShowing
2835 ? UsageEvents.Event.KEYGUARD_SHOWN
2836 : UsageEvents.Event.KEYGUARD_HIDDEN);
2837 }
2838
2839 @Override
2840 public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
2841 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
2842 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
2843 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
2844 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
2845 }
2846
2847 @Override
2848 public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
2849 IBinder activityToken, int flags) {
2850 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
2851 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
2852 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
2853 }
2854
2855 @Override
2856 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
2857 Bundle args) {
2858 return enqueueAssistContext(requestType, intent, hint, null, null, null,
2859 true /* focused */, true /* newSessionId */, userHandle, args,
2860 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
2861 }
2862
2863 @Override
2864 public Bundle getAssistContextExtras(int requestType) {
2865 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
2866 null, null, true /* focused */, true /* newSessionId */,
2867 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
2868 if (pae == null) {
2869 return null;
2870 }
2871 synchronized (pae) {
2872 while (!pae.haveResult) {
2873 try {
2874 pae.wait();
2875 } catch (InterruptedException e) {
2876 }
2877 }
2878 }
2879 synchronized (mGlobalLock) {
2880 buildAssistBundleLocked(pae, pae.result);
2881 mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002882 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002883 }
2884 return pae.extras;
2885 }
2886
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002887 /**
2888 * Binder IPC calls go through the public entry point.
2889 * This can be called with or without the global lock held.
2890 */
2891 private static int checkCallingPermission(String permission) {
2892 return checkPermission(
2893 permission, Binder.getCallingPid(), UserHandle.getAppId(Binder.getCallingUid()));
2894 }
2895
2896 /** This can be called with or without the global lock held. */
2897 void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
2898 if (!getRecentTasks().isCallerRecents(Binder.getCallingUid())) {
2899 mAmInternal.enforceCallingPermission(permission, func);
2900 }
2901 }
2902
2903 @VisibleForTesting
2904 int checkGetTasksPermission(String permission, int pid, int uid) {
2905 return checkPermission(permission, pid, uid);
2906 }
2907
2908 static int checkPermission(String permission, int pid, int uid) {
2909 if (permission == null) {
2910 return PackageManager.PERMISSION_DENIED;
2911 }
2912 return checkComponentPermission(permission, pid, uid, -1, true);
2913 }
2914
2915 boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
2916 if (getRecentTasks().isCallerRecents(callingUid)) {
2917 // Always allow the recents component to get tasks
2918 return true;
2919 }
2920
2921 boolean allowed = checkGetTasksPermission(android.Manifest.permission.REAL_GET_TASKS,
2922 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
2923 if (!allowed) {
2924 if (checkGetTasksPermission(android.Manifest.permission.GET_TASKS,
2925 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
2926 // Temporary compatibility: some existing apps on the system image may
2927 // still be requesting the old permission and not switched to the new
2928 // one; if so, we'll still allow them full access. This means we need
2929 // to see if they are holding the old permission and are a system app.
2930 try {
2931 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
2932 allowed = true;
2933 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
2934 + " is using old GET_TASKS but privileged; allowing");
2935 }
2936 } catch (RemoteException e) {
2937 }
2938 }
2939 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
2940 + " does not hold REAL_GET_TASKS; limiting output");
2941 }
2942 return allowed;
2943 }
2944
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002945 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
2946 IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
2947 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
2948 int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002949 mAmInternal.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002950 "enqueueAssistContext()");
2951
2952 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002953 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002954 if (activity == null) {
2955 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
2956 return null;
2957 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002958 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002959 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
2960 return null;
2961 }
2962 if (focused) {
2963 if (activityToken != null) {
2964 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
2965 if (activity != caller) {
2966 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
2967 + " is not current top " + activity);
2968 return null;
2969 }
2970 }
2971 } else {
2972 activity = ActivityRecord.forTokenLocked(activityToken);
2973 if (activity == null) {
2974 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
2975 + " couldn't be found");
2976 return null;
2977 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002978 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002979 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
2980 return null;
2981 }
2982 }
2983
2984 PendingAssistExtras pae;
2985 Bundle extras = new Bundle();
2986 if (args != null) {
2987 extras.putAll(args);
2988 }
2989 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002990 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002991
2992 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
2993 userHandle);
2994 pae.isHome = activity.isActivityTypeHome();
2995
2996 // Increment the sessionId if necessary
2997 if (newSessionId) {
2998 mViSessionId++;
2999 }
3000 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003001 activity.app.getThread().requestAssistContextExtras(activity.appToken, pae,
3002 requestType, mViSessionId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003003 mPendingAssistExtras.add(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003004 mUiHandler.postDelayed(pae, timeout);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003005 } catch (RemoteException e) {
3006 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
3007 return null;
3008 }
3009 return pae;
3010 }
3011 }
3012
3013 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
3014 if (result != null) {
3015 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
3016 }
3017 if (pae.hint != null) {
3018 pae.extras.putBoolean(pae.hint, true);
3019 }
3020 }
3021
3022 private void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
3023 IAssistDataReceiver receiver;
3024 synchronized (mGlobalLock) {
3025 mPendingAssistExtras.remove(pae);
3026 receiver = pae.receiver;
3027 }
3028 if (receiver != null) {
3029 // Caller wants result sent back to them.
3030 Bundle sendBundle = new Bundle();
3031 // At least return the receiver extras
3032 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
3033 try {
3034 pae.receiver.onHandleAssistData(sendBundle);
3035 } catch (RemoteException e) {
3036 }
3037 }
3038 }
3039
3040 public class PendingAssistExtras extends Binder implements Runnable {
3041 public final ActivityRecord activity;
3042 public boolean isHome;
3043 public final Bundle extras;
3044 public final Intent intent;
3045 public final String hint;
3046 public final IAssistDataReceiver receiver;
3047 public final int userHandle;
3048 public boolean haveResult = false;
3049 public Bundle result = null;
3050 public AssistStructure structure = null;
3051 public AssistContent content = null;
3052 public Bundle receiverExtras;
3053
3054 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
3055 String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
3056 int _userHandle) {
3057 activity = _activity;
3058 extras = _extras;
3059 intent = _intent;
3060 hint = _hint;
3061 receiver = _receiver;
3062 receiverExtras = _receiverExtras;
3063 userHandle = _userHandle;
3064 }
3065
3066 @Override
3067 public void run() {
3068 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
3069 synchronized (this) {
3070 haveResult = true;
3071 notifyAll();
3072 }
3073 pendingAssistExtrasTimedOut(this);
3074 }
3075 }
3076
3077 @Override
3078 public boolean isAssistDataAllowedOnCurrentActivity() {
3079 int userId;
3080 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003081 final ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003082 if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
3083 return false;
3084 }
3085
3086 final ActivityRecord activity = focusedStack.getTopActivity();
3087 if (activity == null) {
3088 return false;
3089 }
3090 userId = activity.userId;
3091 }
3092 return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
3093 }
3094
3095 @Override
3096 public boolean showAssistFromActivity(IBinder token, Bundle args) {
3097 long ident = Binder.clearCallingIdentity();
3098 try {
3099 synchronized (mGlobalLock) {
3100 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003101 ActivityRecord top = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003102 if (top != caller) {
3103 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3104 + " is not current top " + top);
3105 return false;
3106 }
3107 if (!top.nowVisible) {
3108 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3109 + " is not visible");
3110 return false;
3111 }
3112 }
3113 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
3114 token);
3115 } finally {
3116 Binder.restoreCallingIdentity(ident);
3117 }
3118 }
3119
3120 @Override
3121 public boolean isRootVoiceInteraction(IBinder token) {
3122 synchronized (mGlobalLock) {
3123 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3124 if (r == null) {
3125 return false;
3126 }
3127 return r.rootVoiceInteraction;
3128 }
3129 }
3130
Wale Ogunwalef6733932018-06-27 05:14:34 -07003131 private void onLocalVoiceInteractionStartedLocked(IBinder activity,
3132 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
3133 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
3134 if (activityToCallback == null) return;
3135 activityToCallback.setVoiceSessionLocked(voiceSession);
3136
3137 // Inform the activity
3138 try {
3139 activityToCallback.app.getThread().scheduleLocalVoiceInteractionStarted(activity,
3140 voiceInteractor);
3141 long token = Binder.clearCallingIdentity();
3142 try {
3143 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
3144 } finally {
3145 Binder.restoreCallingIdentity(token);
3146 }
3147 // TODO: VI Should we cache the activity so that it's easier to find later
3148 // rather than scan through all the stacks and activities?
3149 } catch (RemoteException re) {
3150 activityToCallback.clearVoiceSessionLocked();
3151 // TODO: VI Should this terminate the voice session?
3152 }
3153 }
3154
3155 private void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
3156 Slog.d(TAG, "<<< startRunningVoiceLocked()");
3157 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
3158 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
3159 boolean wasRunningVoice = mRunningVoice != null;
3160 mRunningVoice = session;
3161 if (!wasRunningVoice) {
3162 mVoiceWakeLock.acquire();
3163 updateSleepIfNeededLocked();
3164 }
3165 }
3166 }
3167
3168 void finishRunningVoiceLocked() {
3169 if (mRunningVoice != null) {
3170 mRunningVoice = null;
3171 mVoiceWakeLock.release();
3172 updateSleepIfNeededLocked();
3173 }
3174 }
3175
3176 @Override
3177 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3178 synchronized (mGlobalLock) {
3179 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3180 if (keepAwake) {
3181 mVoiceWakeLock.acquire();
3182 } else {
3183 mVoiceWakeLock.release();
3184 }
3185 }
3186 }
3187 }
3188
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003189 @Override
3190 public ComponentName getActivityClassForToken(IBinder token) {
3191 synchronized (mGlobalLock) {
3192 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3193 if (r == null) {
3194 return null;
3195 }
3196 return r.intent.getComponent();
3197 }
3198 }
3199
3200 @Override
3201 public String getPackageForToken(IBinder token) {
3202 synchronized (mGlobalLock) {
3203 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3204 if (r == null) {
3205 return null;
3206 }
3207 return r.packageName;
3208 }
3209 }
3210
3211 @Override
3212 public void showLockTaskEscapeMessage(IBinder token) {
3213 synchronized (mGlobalLock) {
3214 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3215 if (r == null) {
3216 return;
3217 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003218 getLockTaskController().showLockTaskToast();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003219 }
3220 }
3221
3222 @Override
3223 public void keyguardGoingAway(int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003224 enforceNotIsolatedCaller("keyguardGoingAway");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003225 final long token = Binder.clearCallingIdentity();
3226 try {
3227 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003228 mKeyguardController.keyguardGoingAway(flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003229 }
3230 } finally {
3231 Binder.restoreCallingIdentity(token);
3232 }
3233 }
3234
3235 /**
3236 * Try to place task to provided position. The final position might be different depending on
3237 * current user and stacks state. The task will be moved to target stack if it's currently in
3238 * different stack.
3239 */
3240 @Override
3241 public void positionTaskInStack(int taskId, int stackId, int position) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003242 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003243 synchronized (mGlobalLock) {
3244 long ident = Binder.clearCallingIdentity();
3245 try {
3246 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
3247 + taskId + " in stackId=" + stackId + " at position=" + position);
3248 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3249 if (task == null) {
3250 throw new IllegalArgumentException("positionTaskInStack: no task for id="
3251 + taskId);
3252 }
3253
3254 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3255
3256 if (stack == null) {
3257 throw new IllegalArgumentException("positionTaskInStack: no stack for id="
3258 + stackId);
3259 }
3260 if (!stack.isActivityTypeStandardOrUndefined()) {
3261 throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
3262 + " the position of task " + taskId + " in/to non-standard stack");
3263 }
3264
3265 // TODO: Have the callers of this API call a separate reparent method if that is
3266 // what they intended to do vs. having this method also do reparenting.
3267 if (task.getStack() == stack) {
3268 // Change position in current stack.
3269 stack.positionChildAt(task, position);
3270 } else {
3271 // Reparent to new stack.
3272 task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
3273 !DEFER_RESUME, "positionTaskInStack");
3274 }
3275 } finally {
3276 Binder.restoreCallingIdentity(ident);
3277 }
3278 }
3279 }
3280
3281 @Override
3282 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
3283 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
3284 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
3285 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
3286 synchronized (mGlobalLock) {
3287 ActivityRecord record = ActivityRecord.isInStackLocked(token);
3288 if (record == null) {
3289 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
3290 + "found for: " + token);
3291 }
3292 record.setSizeConfigurations(horizontalSizeConfiguration,
3293 verticalSizeConfigurations, smallestSizeConfigurations);
3294 }
3295 }
3296
3297 /**
3298 * Dismisses split-screen multi-window mode.
3299 * @param toTop If true the current primary split-screen stack will be placed or left on top.
3300 */
3301 @Override
3302 public void dismissSplitScreenMode(boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003303 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003304 MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
3305 final long ident = Binder.clearCallingIdentity();
3306 try {
3307 synchronized (mGlobalLock) {
3308 final ActivityStack stack =
3309 mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
3310 if (stack == null) {
3311 Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
3312 return;
3313 }
3314
3315 if (toTop) {
3316 // Caller wants the current split-screen primary stack to be the top stack after
3317 // it goes fullscreen, so move it to the front.
3318 stack.moveToFront("dismissSplitScreenMode");
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003319 } else if (mStackSupervisor.isTopDisplayFocusedStack(stack)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003320 // In this case the current split-screen primary stack shouldn't be the top
3321 // stack after it goes fullscreen, but it current has focus, so we move the
3322 // focus to the top-most split-screen secondary stack next to it.
3323 final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
3324 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
3325 if (otherStack != null) {
3326 otherStack.moveToFront("dismissSplitScreenMode_other");
3327 }
3328 }
3329
3330 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
3331 }
3332 } finally {
3333 Binder.restoreCallingIdentity(ident);
3334 }
3335 }
3336
3337 /**
3338 * Dismisses Pip
3339 * @param animate True if the dismissal should be animated.
3340 * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
3341 * default animation duration should be used.
3342 */
3343 @Override
3344 public void dismissPip(boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003345 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003346 final long ident = Binder.clearCallingIdentity();
3347 try {
3348 synchronized (mGlobalLock) {
3349 final PinnedActivityStack stack =
3350 mStackSupervisor.getDefaultDisplay().getPinnedStack();
3351 if (stack == null) {
3352 Slog.w(TAG, "dismissPip: pinned stack not found.");
3353 return;
3354 }
3355 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
3356 throw new IllegalArgumentException("Stack: " + stack
3357 + " doesn't support animated resize.");
3358 }
3359 if (animate) {
3360 stack.animateResizePinnedStack(null /* sourceHintBounds */,
3361 null /* destBounds */, animationDuration, false /* fromFullscreen */);
3362 } else {
3363 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
3364 }
3365 }
3366 } finally {
3367 Binder.restoreCallingIdentity(ident);
3368 }
3369 }
3370
3371 @Override
3372 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003373 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003374 synchronized (mGlobalLock) {
3375 mSuppressResizeConfigChanges = suppress;
3376 }
3377 }
3378
3379 /**
3380 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
3381 * animated the stack to the fullscreen, but can also be called if we are relaunching an
3382 * activity and clearing the task at the same time.
3383 */
3384 @Override
3385 // TODO: API should just be about changing windowing modes...
3386 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003387 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003388 "moveTasksToFullscreenStack()");
3389 synchronized (mGlobalLock) {
3390 final long origId = Binder.clearCallingIdentity();
3391 try {
3392 final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
3393 if (stack != null){
3394 if (!stack.isActivityTypeStandardOrUndefined()) {
3395 throw new IllegalArgumentException(
3396 "You can't move tasks from non-standard stacks.");
3397 }
3398 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
3399 }
3400 } finally {
3401 Binder.restoreCallingIdentity(origId);
3402 }
3403 }
3404 }
3405
3406 /**
3407 * Moves the top activity in the input stackId to the pinned stack.
3408 *
3409 * @param stackId Id of stack to move the top activity to pinned stack.
3410 * @param bounds Bounds to use for pinned stack.
3411 *
3412 * @return True if the top activity of the input stack was successfully moved to the pinned
3413 * stack.
3414 */
3415 @Override
3416 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003417 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003418 "moveTopActivityToPinnedStack()");
3419 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003420 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003421 throw new IllegalStateException("moveTopActivityToPinnedStack:"
3422 + "Device doesn't support picture-in-picture mode");
3423 }
3424
3425 long ident = Binder.clearCallingIdentity();
3426 try {
3427 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
3428 } finally {
3429 Binder.restoreCallingIdentity(ident);
3430 }
3431 }
3432 }
3433
3434 @Override
3435 public boolean isInMultiWindowMode(IBinder token) {
3436 final long origId = Binder.clearCallingIdentity();
3437 try {
3438 synchronized (mGlobalLock) {
3439 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3440 if (r == null) {
3441 return false;
3442 }
3443 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
3444 return r.inMultiWindowMode();
3445 }
3446 } finally {
3447 Binder.restoreCallingIdentity(origId);
3448 }
3449 }
3450
3451 @Override
3452 public boolean isInPictureInPictureMode(IBinder token) {
3453 final long origId = Binder.clearCallingIdentity();
3454 try {
3455 synchronized (mGlobalLock) {
3456 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
3457 }
3458 } finally {
3459 Binder.restoreCallingIdentity(origId);
3460 }
3461 }
3462
3463 private boolean isInPictureInPictureMode(ActivityRecord r) {
3464 if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
3465 || r.getStack().isInStackLocked(r) == null) {
3466 return false;
3467 }
3468
3469 // If we are animating to fullscreen then we have already dispatched the PIP mode
3470 // changed, so we should reflect that check here as well.
3471 final PinnedActivityStack stack = r.getStack();
3472 final PinnedStackWindowController windowController = stack.getWindowContainerController();
3473 return !windowController.isAnimatingBoundsToFullscreen();
3474 }
3475
3476 @Override
3477 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
3478 final long origId = Binder.clearCallingIdentity();
3479 try {
3480 synchronized (mGlobalLock) {
3481 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3482 "enterPictureInPictureMode", token, params);
3483
3484 // If the activity is already in picture in picture mode, then just return early
3485 if (isInPictureInPictureMode(r)) {
3486 return true;
3487 }
3488
3489 // Activity supports picture-in-picture, now check that we can enter PiP at this
3490 // point, if it is
3491 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
3492 false /* beforeStopping */)) {
3493 return false;
3494 }
3495
3496 final Runnable enterPipRunnable = () -> {
Wale Ogunwalef276a6f2018-06-15 08:26:07 -07003497 synchronized (mGlobalLock) {
3498 // Only update the saved args from the args that are set
3499 r.pictureInPictureArgs.copyOnlySet(params);
3500 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
3501 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
3502 // Adjust the source bounds by the insets for the transition down
3503 final Rect sourceBounds = new Rect(
3504 r.pictureInPictureArgs.getSourceRectHint());
3505 mStackSupervisor.moveActivityToPinnedStackLocked(
3506 r, sourceBounds, aspectRatio, "enterPictureInPictureMode");
3507 final PinnedActivityStack stack = r.getStack();
3508 stack.setPictureInPictureAspectRatio(aspectRatio);
3509 stack.setPictureInPictureActions(actions);
3510 MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
3511 r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
3512 logPictureInPictureArgs(params);
3513 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003514 };
3515
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003516 if (isKeyguardLocked()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003517 // If the keyguard is showing or occluded, then try and dismiss it before
3518 // entering picture-in-picture (this will prompt the user to authenticate if the
3519 // device is currently locked).
3520 dismissKeyguard(token, new KeyguardDismissCallback() {
3521 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003522 public void onDismissSucceeded() {
3523 mH.post(enterPipRunnable);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003524 }
3525 }, null /* message */);
3526 } else {
3527 // Enter picture in picture immediately otherwise
3528 enterPipRunnable.run();
3529 }
3530 return true;
3531 }
3532 } finally {
3533 Binder.restoreCallingIdentity(origId);
3534 }
3535 }
3536
3537 @Override
3538 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
3539 final long origId = Binder.clearCallingIdentity();
3540 try {
3541 synchronized (mGlobalLock) {
3542 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3543 "setPictureInPictureParams", token, params);
3544
3545 // Only update the saved args from the args that are set
3546 r.pictureInPictureArgs.copyOnlySet(params);
3547 if (r.inPinnedWindowingMode()) {
3548 // If the activity is already in picture-in-picture, update the pinned stack now
3549 // if it is not already expanding to fullscreen. Otherwise, the arguments will
3550 // be used the next time the activity enters PiP
3551 final PinnedActivityStack stack = r.getStack();
3552 if (!stack.isAnimatingBoundsToFullscreen()) {
3553 stack.setPictureInPictureAspectRatio(
3554 r.pictureInPictureArgs.getAspectRatio());
3555 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
3556 }
3557 }
3558 logPictureInPictureArgs(params);
3559 }
3560 } finally {
3561 Binder.restoreCallingIdentity(origId);
3562 }
3563 }
3564
3565 @Override
3566 public int getMaxNumPictureInPictureActions(IBinder token) {
3567 // Currently, this is a static constant, but later, we may change this to be dependent on
3568 // the context of the activity
3569 return 3;
3570 }
3571
3572 private void logPictureInPictureArgs(PictureInPictureParams params) {
3573 if (params.hasSetActions()) {
3574 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
3575 params.getActions().size());
3576 }
3577 if (params.hasSetAspectRatio()) {
3578 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
3579 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
3580 MetricsLogger.action(lm);
3581 }
3582 }
3583
3584 /**
3585 * Checks the state of the system and the activity associated with the given {@param token} to
3586 * verify that picture-in-picture is supported for that activity.
3587 *
3588 * @return the activity record for the given {@param token} if all the checks pass.
3589 */
3590 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
3591 IBinder token, PictureInPictureParams params) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003592 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003593 throw new IllegalStateException(caller
3594 + ": Device doesn't support picture-in-picture mode.");
3595 }
3596
3597 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3598 if (r == null) {
3599 throw new IllegalStateException(caller
3600 + ": Can't find activity for token=" + token);
3601 }
3602
3603 if (!r.supportsPictureInPicture()) {
3604 throw new IllegalStateException(caller
3605 + ": Current activity does not support picture-in-picture.");
3606 }
3607
3608 if (params.hasSetAspectRatio()
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003609 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003610 params.getAspectRatio())) {
3611 final float minAspectRatio = mContext.getResources().getFloat(
3612 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
3613 final float maxAspectRatio = mContext.getResources().getFloat(
3614 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
3615 throw new IllegalArgumentException(String.format(caller
3616 + ": Aspect ratio is too extreme (must be between %f and %f).",
3617 minAspectRatio, maxAspectRatio));
3618 }
3619
3620 // Truncate the number of actions if necessary
3621 params.truncateActions(getMaxNumPictureInPictureActions(token));
3622
3623 return r;
3624 }
3625
3626 @Override
3627 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003628 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003629 synchronized (mGlobalLock) {
3630 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
3631 if (r == null) {
3632 throw new IllegalArgumentException("Activity does not exist; token="
3633 + activityToken);
3634 }
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07003635 return r.getUriPermissionsLocked().getExternalToken();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003636 }
3637 }
3638
3639 @Override
3640 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
3641 Rect tempDockedTaskInsetBounds,
3642 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003643 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003644 long ident = Binder.clearCallingIdentity();
3645 try {
3646 synchronized (mGlobalLock) {
3647 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
3648 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
3649 PRESERVE_WINDOWS);
3650 }
3651 } finally {
3652 Binder.restoreCallingIdentity(ident);
3653 }
3654 }
3655
3656 @Override
3657 public void setSplitScreenResizing(boolean resizing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003658 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003659 final long ident = Binder.clearCallingIdentity();
3660 try {
3661 synchronized (mGlobalLock) {
3662 mStackSupervisor.setSplitScreenResizing(resizing);
3663 }
3664 } finally {
3665 Binder.restoreCallingIdentity(ident);
3666 }
3667 }
3668
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003669 /**
3670 * Check that we have the features required for VR-related API calls, and throw an exception if
3671 * not.
3672 */
3673 void enforceSystemHasVrFeature() {
3674 if (!mContext.getPackageManager().hasSystemFeature(
3675 PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
3676 throw new UnsupportedOperationException("VR mode not supported on this device!");
3677 }
3678 }
3679
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003680 @Override
3681 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003682 enforceSystemHasVrFeature();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003683
3684 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3685
3686 ActivityRecord r;
3687 synchronized (mGlobalLock) {
3688 r = ActivityRecord.isInStackLocked(token);
3689 }
3690
3691 if (r == null) {
3692 throw new IllegalArgumentException();
3693 }
3694
3695 int err;
3696 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
3697 VrManagerInternal.NO_ERROR) {
3698 return err;
3699 }
3700
3701 // Clear the binder calling uid since this path may call moveToTask().
3702 final long callingId = Binder.clearCallingIdentity();
3703 try {
3704 synchronized (mGlobalLock) {
3705 r.requestedVrComponent = (enabled) ? packageName : null;
3706
3707 // Update associated state if this activity is currently focused
Andrii Kulian52d255c2018-07-13 11:32:19 -07003708 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003709 applyUpdateVrModeLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003710 }
3711 return 0;
3712 }
3713 } finally {
3714 Binder.restoreCallingIdentity(callingId);
3715 }
3716 }
3717
3718 @Override
3719 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
3720 Slog.i(TAG, "Activity tried to startLocalVoiceInteraction");
3721 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003722 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003723 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
3724 throw new SecurityException("Only focused activity can call startVoiceInteraction");
3725 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07003726 if (mRunningVoice != null || activity.getTask().voiceSession != null
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003727 || activity.voiceSession != null) {
3728 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
3729 return;
3730 }
3731 if (activity.pendingVoiceInteractionStart) {
3732 Slog.w(TAG, "Pending start of voice interaction already.");
3733 return;
3734 }
3735 activity.pendingVoiceInteractionStart = true;
3736 }
3737 LocalServices.getService(VoiceInteractionManagerInternal.class)
3738 .startLocalVoiceInteraction(callingActivity, options);
3739 }
3740
3741 @Override
3742 public void stopLocalVoiceInteraction(IBinder callingActivity) {
3743 LocalServices.getService(VoiceInteractionManagerInternal.class)
3744 .stopLocalVoiceInteraction(callingActivity);
3745 }
3746
3747 @Override
3748 public boolean supportsLocalVoiceInteraction() {
3749 return LocalServices.getService(VoiceInteractionManagerInternal.class)
3750 .supportsLocalVoiceInteraction();
3751 }
3752
3753 /** Notifies all listeners when the pinned stack animation starts. */
3754 @Override
3755 public void notifyPinnedStackAnimationStarted() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003756 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003757 }
3758
3759 /** Notifies all listeners when the pinned stack animation ends. */
3760 @Override
3761 public void notifyPinnedStackAnimationEnded() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003762 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003763 }
3764
3765 @Override
3766 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003767 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003768 final long ident = Binder.clearCallingIdentity();
3769 try {
3770 synchronized (mGlobalLock) {
3771 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
3772 }
3773 } finally {
3774 Binder.restoreCallingIdentity(ident);
3775 }
3776 }
3777
3778 @Override
3779 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003780 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003781
3782 synchronized (mGlobalLock) {
3783 // Check if display is initialized in AM.
3784 if (!mStackSupervisor.isDisplayAdded(displayId)) {
3785 // Call might come when display is not yet added or has already been removed.
3786 if (DEBUG_CONFIGURATION) {
3787 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
3788 + displayId);
3789 }
3790 return false;
3791 }
3792
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003793 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003794 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003795 values = mWindowManager.computeNewConfiguration(displayId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003796 }
3797
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003798 if (mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003799 // Update OOM levels based on display size.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003800 mAm.mProcessList.applyDisplaySize(mWindowManager);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003801 }
3802
3803 final long origId = Binder.clearCallingIdentity();
3804 try {
3805 if (values != null) {
3806 Settings.System.clearConfiguration(values);
3807 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003808 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003809 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
3810 return mTmpUpdateConfigurationResult.changes != 0;
3811 } finally {
3812 Binder.restoreCallingIdentity(origId);
3813 }
3814 }
3815 }
3816
3817 @Override
3818 public boolean updateConfiguration(Configuration values) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003819 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003820
3821 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003822 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003823 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003824 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003825 }
3826
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003827 if (mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003828 // Update OOM levels based on display size.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003829 mAm.mProcessList.applyDisplaySize(mWindowManager);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003830 }
3831
3832 final long origId = Binder.clearCallingIdentity();
3833 try {
3834 if (values != null) {
3835 Settings.System.clearConfiguration(values);
3836 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003837 updateConfigurationLocked(values, null, false, false /* persistent */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003838 UserHandle.USER_NULL, false /* deferResume */,
3839 mTmpUpdateConfigurationResult);
3840 return mTmpUpdateConfigurationResult.changes != 0;
3841 } finally {
3842 Binder.restoreCallingIdentity(origId);
3843 }
3844 }
3845 }
3846
3847 @Override
3848 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
3849 CharSequence message) {
3850 if (message != null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003851 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003852 Manifest.permission.SHOW_KEYGUARD_MESSAGE, "dismissKeyguard()");
3853 }
3854 final long callingId = Binder.clearCallingIdentity();
3855 try {
3856 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003857 mKeyguardController.dismissKeyguard(token, callback, message);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003858 }
3859 } finally {
3860 Binder.restoreCallingIdentity(callingId);
3861 }
3862 }
3863
3864 @Override
3865 public void cancelTaskWindowTransition(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003866 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003867 "cancelTaskWindowTransition()");
3868 final long ident = Binder.clearCallingIdentity();
3869 try {
3870 synchronized (mGlobalLock) {
3871 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
3872 MATCH_TASK_IN_STACKS_ONLY);
3873 if (task == null) {
3874 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
3875 return;
3876 }
3877 task.cancelWindowTransition();
3878 }
3879 } finally {
3880 Binder.restoreCallingIdentity(ident);
3881 }
3882 }
3883
3884 @Override
3885 public ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003886 enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003887 final long ident = Binder.clearCallingIdentity();
3888 try {
3889 final TaskRecord task;
3890 synchronized (mGlobalLock) {
3891 task = mStackSupervisor.anyTaskForIdLocked(taskId,
3892 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
3893 if (task == null) {
3894 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
3895 return null;
3896 }
3897 }
3898 // Don't call this while holding the lock as this operation might hit the disk.
3899 return task.getSnapshot(reducedResolution);
3900 } finally {
3901 Binder.restoreCallingIdentity(ident);
3902 }
3903 }
3904
3905 @Override
3906 public void setDisablePreviewScreenshots(IBinder token, boolean disable) {
3907 synchronized (mGlobalLock) {
3908 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3909 if (r == null) {
3910 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
3911 + token);
3912 return;
3913 }
3914 final long origId = Binder.clearCallingIdentity();
3915 try {
3916 r.setDisablePreviewScreenshots(disable);
3917 } finally {
3918 Binder.restoreCallingIdentity(origId);
3919 }
3920 }
3921 }
3922
3923 /** Return the user id of the last resumed activity. */
3924 @Override
3925 public @UserIdInt
3926 int getLastResumedActivityUserId() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003927 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003928 Manifest.permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
3929 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07003930 if (mLastResumedActivity == null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003931 return getCurrentUserId();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003932 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07003933 return mLastResumedActivity.userId;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003934 }
3935 }
3936
3937 @Override
3938 public void updateLockTaskFeatures(int userId, int flags) {
3939 final int callingUid = Binder.getCallingUid();
3940 if (callingUid != 0 && callingUid != SYSTEM_UID) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003941 mAmInternal.enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003942 "updateLockTaskFeatures()");
3943 }
3944 synchronized (mGlobalLock) {
3945 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
3946 Integer.toHexString(flags));
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003947 getLockTaskController().updateLockTaskFeatures(userId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003948 }
3949 }
3950
3951 @Override
3952 public void setShowWhenLocked(IBinder token, boolean showWhenLocked) {
3953 synchronized (mGlobalLock) {
3954 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3955 if (r == null) {
3956 return;
3957 }
3958 final long origId = Binder.clearCallingIdentity();
3959 try {
3960 r.setShowWhenLocked(showWhenLocked);
3961 } finally {
3962 Binder.restoreCallingIdentity(origId);
3963 }
3964 }
3965 }
3966
3967 @Override
3968 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) {
3969 synchronized (mGlobalLock) {
3970 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3971 if (r == null) {
3972 return;
3973 }
3974 final long origId = Binder.clearCallingIdentity();
3975 try {
3976 r.setTurnScreenOn(turnScreenOn);
3977 } finally {
3978 Binder.restoreCallingIdentity(origId);
3979 }
3980 }
3981 }
3982
3983 @Override
3984 public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003985 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003986 "registerRemoteAnimations");
3987 definition.setCallingPid(Binder.getCallingPid());
3988 synchronized (mGlobalLock) {
3989 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3990 if (r == null) {
3991 return;
3992 }
3993 final long origId = Binder.clearCallingIdentity();
3994 try {
3995 r.registerRemoteAnimations(definition);
3996 } finally {
3997 Binder.restoreCallingIdentity(origId);
3998 }
3999 }
4000 }
4001
4002 @Override
4003 public void registerRemoteAnimationForNextActivityStart(String packageName,
4004 RemoteAnimationAdapter adapter) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004005 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004006 "registerRemoteAnimationForNextActivityStart");
4007 adapter.setCallingPid(Binder.getCallingPid());
4008 synchronized (mGlobalLock) {
4009 final long origId = Binder.clearCallingIdentity();
4010 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07004011 getActivityStartController().registerRemoteAnimationForNextActivityStart(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004012 packageName, adapter);
4013 } finally {
4014 Binder.restoreCallingIdentity(origId);
4015 }
4016 }
4017 }
4018
4019 /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
4020 @Override
4021 public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
4022 synchronized (mGlobalLock) {
4023 final long origId = Binder.clearCallingIdentity();
4024 try {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004025 mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004026 } finally {
4027 Binder.restoreCallingIdentity(origId);
4028 }
4029 }
4030 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004031
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004032 @Override
4033 public void setVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004034 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004035 synchronized (mGlobalLock) {
4036 synchronized (mAm.mPidsSelfLocked) {
4037 final int pid = Binder.getCallingPid();
4038 final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004039 mVrController.setVrThreadLocked(tid, pid, proc.getWindowProcessController());
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004040 }
4041 }
4042 }
4043
4044 @Override
4045 public void setPersistentVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004046 if (checkCallingPermission(Manifest.permission.RESTRICTED_VR_ACCESS)
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004047 != PERMISSION_GRANTED) {
4048 final String msg = "Permission Denial: setPersistentVrThread() from pid="
4049 + Binder.getCallingPid()
4050 + ", uid=" + Binder.getCallingUid()
4051 + " requires " + Manifest.permission.RESTRICTED_VR_ACCESS;
4052 Slog.w(TAG, msg);
4053 throw new SecurityException(msg);
4054 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004055 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004056 synchronized (mGlobalLock) {
4057 synchronized (mAm.mPidsSelfLocked) {
4058 final int pid = Binder.getCallingPid();
4059 final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
4060 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
4061 }
4062 }
4063 }
4064
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004065 @Override
4066 public void stopAppSwitches() {
4067 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
4068 synchronized (mGlobalLock) {
4069 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME;
4070 mDidAppSwitch = false;
4071 getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
4072 }
4073 }
4074
4075 @Override
4076 public void resumeAppSwitches() {
4077 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
4078 synchronized (mGlobalLock) {
4079 // Note that we don't execute any pending app switches... we will
4080 // let those wait until either the timeout, or the next start
4081 // activity request.
4082 mAppSwitchesAllowedTime = 0;
4083 }
4084 }
4085
4086 void onStartActivitySetDidAppSwitch() {
4087 if (mDidAppSwitch) {
4088 // This is the second allowed switch since we stopped switches, so now just generally
4089 // allow switches. Use case:
4090 // - user presses home (switches disabled, switch to home, mDidAppSwitch now true);
4091 // - user taps a home icon (coming from home so allowed, we hit here and now allow
4092 // anyone to switch again).
4093 mAppSwitchesAllowedTime = 0;
4094 } else {
4095 mDidAppSwitch = true;
4096 }
4097 }
4098
4099 /** @return whether the system should disable UI modes incompatible with VR mode. */
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004100 boolean shouldDisableNonVrUiLocked() {
4101 return mVrController.shouldDisableNonVrUiLocked();
4102 }
4103
4104 void applyUpdateVrModeLocked(ActivityRecord r) {
4105 // VR apps are expected to run in a main display. If an app is turning on VR for
4106 // itself, but lives in a dynamic stack, then make sure that it is moved to the main
4107 // fullscreen stack before enabling VR Mode.
4108 // TODO: The goal of this code is to keep the VR app on the main display. When the
4109 // stack implementation changes in the future, keep in mind that the use of the fullscreen
4110 // stack is a means to move the activity to the main display and a moveActivityToDisplay()
4111 // option would be a better choice here.
4112 if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
4113 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
4114 + " to main stack for VR");
4115 final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
4116 WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
4117 moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
4118 }
4119 mH.post(() -> {
4120 if (!mVrController.onVrModeChanged(r)) {
4121 return;
4122 }
4123 synchronized (mGlobalLock) {
4124 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
4125 mWindowManager.disableNonVrUi(disableNonVrUi);
4126 if (disableNonVrUi) {
4127 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
4128 // then remove the pinned stack.
4129 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
4130 }
4131 }
4132 });
4133 }
4134
Andrii Kulian5f750bc2018-07-17 08:57:23 -07004135 ActivityStack getTopDisplayFocusedStack() {
4136 return mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004137 }
4138
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004139 /** Pokes the task persister. */
4140 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
4141 mRecentTasks.notifyTaskPersisterLocked(task, flush);
4142 }
4143
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004144 void onTopProcChangedLocked(WindowProcessController proc) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004145 mVrController.onTopProcChangedLocked(proc);
4146 }
4147
4148 boolean isKeyguardLocked() {
4149 return mKeyguardController.isKeyguardLocked();
4150 }
4151
4152 boolean isNextTransitionForward() {
4153 int transit = mWindowManager.getPendingAppTransition();
4154 return transit == TRANSIT_ACTIVITY_OPEN
4155 || transit == TRANSIT_TASK_OPEN
4156 || transit == TRANSIT_TASK_TO_FRONT;
4157 }
4158
Wale Ogunwalef6733932018-06-27 05:14:34 -07004159 void dumpSleepStates(PrintWriter pw, boolean testPssMode) {
4160 synchronized (mGlobalLock) {
4161 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
4162 if (mRunningVoice != null) {
4163 pw.println(" mRunningVoice=" + mRunningVoice);
4164 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
4165 }
4166 pw.println(" mSleeping=" + mSleeping);
4167 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + testPssMode);
4168 pw.println(" mVrController=" + mVrController);
4169 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004170 }
4171
Wale Ogunwalef6733932018-06-27 05:14:34 -07004172 void writeSleepStateToProto(ProtoOutputStream proto) {
4173 for (ActivityTaskManagerInternal.SleepToken st : mStackSupervisor.mSleepTokens) {
4174 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS,
4175 st.toString());
4176 }
4177
4178 if (mRunningVoice != null) {
4179 final long vrToken = proto.start(
4180 ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
4181 proto.write(ActivityManagerServiceDumpProcessesProto.Voice.SESSION,
4182 mRunningVoice.toString());
4183 mVoiceWakeLock.writeToProto(
4184 proto, ActivityManagerServiceDumpProcessesProto.Voice.WAKELOCK);
4185 proto.end(vrToken);
4186 }
4187
4188 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
4189 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN,
4190 mShuttingDown);
4191 mVrController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004192 }
4193
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004194 int getCurrentUserId() {
4195 return mAmInternal.getCurrentUserId();
4196 }
4197
4198 private void enforceNotIsolatedCaller(String caller) {
4199 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4200 throw new SecurityException("Isolated process not allowed to call " + caller);
4201 }
4202 }
4203
Wale Ogunwalef6733932018-06-27 05:14:34 -07004204 public Configuration getConfiguration() {
4205 Configuration ci;
4206 synchronized(mGlobalLock) {
4207 ci = new Configuration(getGlobalConfiguration());
4208 ci.userSetLocale = false;
4209 }
4210 return ci;
4211 }
4212
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004213 /**
4214 * Current global configuration information. Contains general settings for the entire system,
4215 * also corresponds to the merged configuration of the default display.
4216 */
4217 Configuration getGlobalConfiguration() {
4218 return mStackSupervisor.getConfiguration();
4219 }
4220
4221 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4222 boolean initLocale) {
4223 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
4224 }
4225
4226 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4227 boolean initLocale, boolean deferResume) {
4228 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
4229 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
4230 UserHandle.USER_NULL, deferResume);
4231 }
4232
4233 void updatePersistentConfiguration(Configuration values, @UserIdInt int userId) {
4234 final long origId = Binder.clearCallingIdentity();
4235 try {
4236 synchronized (mGlobalLock) {
4237 updateConfigurationLocked(values, null, false, true, userId,
4238 false /* deferResume */);
4239 }
4240 } finally {
4241 Binder.restoreCallingIdentity(origId);
4242 }
4243 }
4244
4245 void updateUserConfiguration() {
4246 synchronized (mGlobalLock) {
4247 final Configuration configuration = new Configuration(getGlobalConfiguration());
4248 final int currentUserId = mAmInternal.getCurrentUserId();
4249 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
4250 currentUserId, Settings.System.canWrite(mContext));
4251 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
4252 false /* persistent */, currentUserId, false /* deferResume */);
4253 }
4254 }
4255
4256 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4257 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
4258 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
4259 deferResume, null /* result */);
4260 }
4261
4262 /**
4263 * Do either or both things: (1) change the current configuration, and (2)
4264 * make sure the given activity is running with the (now) current
4265 * configuration. Returns true if the activity has been left running, or
4266 * false if <var>starting</var> is being destroyed to match the new
4267 * configuration.
4268 *
4269 * @param userId is only used when persistent parameter is set to true to persist configuration
4270 * for that particular user
4271 */
4272 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4273 boolean initLocale, boolean persistent, int userId, boolean deferResume,
4274 ActivityTaskManagerService.UpdateConfigurationResult result) {
4275 int changes = 0;
4276 boolean kept = true;
4277
4278 if (mWindowManager != null) {
4279 mWindowManager.deferSurfaceLayout();
4280 }
4281 try {
4282 if (values != null) {
4283 changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
4284 deferResume);
4285 }
4286
4287 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4288 } finally {
4289 if (mWindowManager != null) {
4290 mWindowManager.continueSurfaceLayout();
4291 }
4292 }
4293
4294 if (result != null) {
4295 result.changes = changes;
4296 result.activityRelaunched = !kept;
4297 }
4298 return kept;
4299 }
4300
4301 /**
4302 * Returns true if this configuration change is interesting enough to send an
4303 * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
4304 */
4305 private static boolean isSplitConfigurationChange(int configDiff) {
4306 return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
4307 }
4308
4309 /** Update default (global) configuration and notify listeners about changes. */
4310 private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
4311 boolean persistent, int userId, boolean deferResume) {
4312 mTempConfig.setTo(getGlobalConfiguration());
4313 final int changes = mTempConfig.updateFrom(values);
4314 if (changes == 0) {
4315 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
4316 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
4317 // performDisplayOverrideConfigUpdate in order to send the new display configuration
4318 // (even if there are no actual changes) to unfreeze the window.
4319 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
4320 return 0;
4321 }
4322
4323 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
4324 "Updating global configuration to: " + values);
4325
4326 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
4327 StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
4328 values.colorMode,
4329 values.densityDpi,
4330 values.fontScale,
4331 values.hardKeyboardHidden,
4332 values.keyboard,
4333 values.keyboardHidden,
4334 values.mcc,
4335 values.mnc,
4336 values.navigation,
4337 values.navigationHidden,
4338 values.orientation,
4339 values.screenHeightDp,
4340 values.screenLayout,
4341 values.screenWidthDp,
4342 values.smallestScreenWidthDp,
4343 values.touchscreen,
4344 values.uiMode);
4345
4346
4347 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
4348 final LocaleList locales = values.getLocales();
4349 int bestLocaleIndex = 0;
4350 if (locales.size() > 1) {
4351 if (mSupportedSystemLocales == null) {
4352 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
4353 }
4354 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
4355 }
4356 SystemProperties.set("persist.sys.locale",
4357 locales.get(bestLocaleIndex).toLanguageTag());
4358 LocaleList.setDefault(locales, bestLocaleIndex);
4359 mAm.mHandler.sendMessage(mAm.mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
4360 locales.get(bestLocaleIndex)));
4361 }
4362
4363 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
4364 mTempConfig.seq = mConfigurationSeq;
4365
4366 // Update stored global config and notify everyone about the change.
4367 mStackSupervisor.onConfigurationChanged(mTempConfig);
4368
4369 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
4370 // TODO(multi-display): Update UsageEvents#Event to include displayId.
4371 mAm.mUsageStatsService.reportConfigurationChange(
4372 mTempConfig, mAmInternal.getCurrentUserId());
4373
4374 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
Wale Ogunwalef6733932018-06-27 05:14:34 -07004375 updateShouldShowDialogsLocked(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004376
4377 AttributeCache ac = AttributeCache.instance();
4378 if (ac != null) {
4379 ac.updateConfiguration(mTempConfig);
4380 }
4381
4382 // Make sure all resources in our process are updated right now, so that anyone who is going
4383 // to retrieve resource values after we return will be sure to get the new ones. This is
4384 // especially important during boot, where the first config change needs to guarantee all
4385 // resources have that config before following boot code is executed.
4386 mAm.mSystemThread.applyConfigurationToResources(mTempConfig);
4387
4388 // We need another copy of global config because we're scheduling some calls instead of
4389 // running them in place. We need to be sure that object we send will be handled unchanged.
4390 final Configuration configCopy = new Configuration(mTempConfig);
4391 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
4392 Message msg = mAm.mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
4393 msg.obj = configCopy;
4394 msg.arg1 = userId;
4395 mAm.mHandler.sendMessage(msg);
4396 }
4397
4398 for (int i = mAm.mLruProcesses.size() - 1; i >= 0; i--) {
4399 ProcessRecord app = mAm.mLruProcesses.get(i);
4400 try {
4401 if (app.thread != null) {
4402 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
4403 + app.processName + " new config " + configCopy);
4404 getLifecycleManager().scheduleTransaction(app.thread,
4405 ConfigurationChangeItem.obtain(configCopy));
4406 }
4407 } catch (Exception e) {
4408 Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
4409 }
4410 }
4411
4412 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
4413 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
4414 | Intent.FLAG_RECEIVER_FOREGROUND
4415 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4416 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4417 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4418 UserHandle.USER_ALL);
4419 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
4420 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
4421 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
4422 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
4423 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4424 if (initLocale || !mAm.mProcessesReady) {
4425 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
4426 }
4427 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4428 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4429 UserHandle.USER_ALL);
4430 }
4431
4432 // Send a broadcast to PackageInstallers if the configuration change is interesting
4433 // for the purposes of installing additional splits.
4434 if (!initLocale && isSplitConfigurationChange(changes)) {
4435 intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
4436 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
4437 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
4438
4439 // Typically only app stores will have this permission.
4440 String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES };
4441 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions,
4442 OP_NONE, null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
4443 }
4444
4445 // Override configuration of the default display duplicates global config, so we need to
4446 // update it also. This will also notify WindowManager about changes.
4447 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
4448 DEFAULT_DISPLAY);
4449
4450 return changes;
4451 }
4452
4453 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
4454 boolean deferResume, int displayId) {
4455 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
4456 displayId, null /* result */);
4457 }
4458
4459 /**
4460 * Updates override configuration specific for the selected display. If no config is provided,
4461 * new one will be computed in WM based on current display info.
4462 */
4463 boolean updateDisplayOverrideConfigurationLocked(Configuration values,
4464 ActivityRecord starting, boolean deferResume, int displayId,
4465 ActivityTaskManagerService.UpdateConfigurationResult result) {
4466 int changes = 0;
4467 boolean kept = true;
4468
4469 if (mWindowManager != null) {
4470 mWindowManager.deferSurfaceLayout();
4471 }
4472 try {
4473 if (values != null) {
4474 if (displayId == DEFAULT_DISPLAY) {
4475 // Override configuration of the default display duplicates global config, so
4476 // we're calling global config update instead for default display. It will also
4477 // apply the correct override config.
4478 changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
4479 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
4480 } else {
4481 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
4482 }
4483 }
4484
4485 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4486 } finally {
4487 if (mWindowManager != null) {
4488 mWindowManager.continueSurfaceLayout();
4489 }
4490 }
4491
4492 if (result != null) {
4493 result.changes = changes;
4494 result.activityRelaunched = !kept;
4495 }
4496 return kept;
4497 }
4498
4499 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
4500 int displayId) {
4501 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
4502 final int changes = mTempConfig.updateFrom(values);
4503 if (changes != 0) {
4504 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
4505 + mTempConfig + " for displayId=" + displayId);
4506 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
4507
4508 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
4509 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004510 mAppWarnings.onDensityChanged();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004511
4512 mAm.killAllBackgroundProcessesExcept(N,
4513 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
4514 }
4515 }
4516
4517 // Update the configuration with WM first and check if any of the stacks need to be resized
4518 // due to the configuration change. If so, resize the stacks now and do any relaunches if
4519 // necessary. This way we don't need to relaunch again afterwards in
4520 // ensureActivityConfiguration().
4521 if (mWindowManager != null) {
4522 final int[] resizedStacks =
4523 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
4524 if (resizedStacks != null) {
4525 for (int stackId : resizedStacks) {
4526 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
4527 }
4528 }
4529 }
4530
4531 return changes;
4532 }
4533
Wale Ogunwalef6733932018-06-27 05:14:34 -07004534 private void updateEventDispatchingLocked(boolean booted) {
4535 mWindowManager.setEventDispatching(booted && !mShuttingDown);
4536 }
4537
4538 void enableScreenAfterBoot(boolean booted) {
4539 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4540 SystemClock.uptimeMillis());
4541 mWindowManager.enableScreenAfterBoot();
4542
4543 synchronized (mGlobalLock) {
4544 updateEventDispatchingLocked(booted);
4545 }
4546 }
4547
4548 boolean canShowErrorDialogs() {
4549 return mShowDialogs && !mSleeping && !mShuttingDown
4550 && !mKeyguardController.isKeyguardOrAodShowing(DEFAULT_DISPLAY)
4551 && !hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
Wale Ogunwale86b74462018-07-02 08:42:43 -07004552 mAmInternal.getCurrentUserId())
Wale Ogunwalef6733932018-06-27 05:14:34 -07004553 && !(UserManager.isDeviceInDemoMode(mContext)
Wale Ogunwale86b74462018-07-02 08:42:43 -07004554 && mAmInternal.getCurrentUser().isDemo());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004555 }
4556
Wale Ogunwale906f9c62018-07-23 11:23:44 -07004557 static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
4558 if (r == null || !r.hasProcess()) {
4559 return KEY_DISPATCHING_TIMEOUT_MS;
4560 }
4561 return getInputDispatchingTimeoutLocked(r.app);
4562 }
4563
4564 private static long getInputDispatchingTimeoutLocked(WindowProcessController r) {
4565 if (r != null && (r.isInstrumenting() || r.isUsingWrapper())) {
4566 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS;
4567 }
4568 return KEY_DISPATCHING_TIMEOUT_MS;
4569 }
4570
4571 long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
4572 if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
4573 throw new SecurityException("Requires permission " + FILTER_EVENTS);
4574 }
4575 WindowProcessController proc;
4576 long timeout;
4577 synchronized (mGlobalLock) {
4578 proc = mPidMap.get(pid);
4579 timeout = getInputDispatchingTimeoutLocked(proc);
4580 }
4581
4582 if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
4583 return -1;
4584 }
4585
4586 return timeout;
4587 }
4588
4589 /**
4590 * Handle input dispatching timeouts.
4591 * Returns whether input dispatching should be aborted or not.
4592 */
4593 boolean inputDispatchingTimedOut(final WindowProcessController proc,
4594 final ActivityRecord activity, final ActivityRecord parent,
4595 final boolean aboveSystem, String reason) {
4596 if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
4597 throw new SecurityException("Requires permission " + FILTER_EVENTS);
4598 }
4599
4600 final String annotation;
4601 if (reason == null) {
4602 annotation = "Input dispatching timed out";
4603 } else {
4604 annotation = "Input dispatching timed out (" + reason + ")";
4605 }
4606
4607 if (proc != null) {
4608 synchronized (mGlobalLock) {
4609 if (proc.isDebugging()) {
4610 return false;
4611 }
4612
4613 if (proc.isInstrumenting()) {
4614 Bundle info = new Bundle();
4615 info.putString("shortMsg", "keyDispatchingTimedOut");
4616 info.putString("longMsg", annotation);
4617 mAm.finishInstrumentationLocked(
4618 (ProcessRecord) proc.mOwner, Activity.RESULT_CANCELED, info);
4619 return true;
4620 }
4621 }
4622 mH.post(() -> {
4623 mAm.mAppErrors.appNotResponding(
4624 (ProcessRecord) proc.mOwner, activity, parent, aboveSystem, annotation);
4625 });
4626 }
4627
4628 return true;
4629 }
4630
Wale Ogunwalef6733932018-06-27 05:14:34 -07004631 /**
4632 * Decide based on the configuration whether we should show the ANR,
4633 * crash, etc dialogs. The idea is that if there is no affordance to
4634 * press the on-screen buttons, or the user experience would be more
4635 * greatly impacted than the crash itself, we shouldn't show the dialog.
4636 *
4637 * A thought: SystemUI might also want to get told about this, the Power
4638 * dialog / global actions also might want different behaviors.
4639 */
4640 private void updateShouldShowDialogsLocked(Configuration config) {
4641 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
4642 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
4643 && config.navigation == Configuration.NAVIGATION_NONAV);
4644 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
4645 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
4646 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
4647 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
4648 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
4649 final boolean hideDialogsSet = Settings.Global.getInt(mContext.getContentResolver(),
4650 HIDE_ERROR_DIALOGS, 0) != 0;
4651 mShowDialogs = inputMethodExists && uiModeSupportsDialogs && !hideDialogsSet;
4652 }
4653
4654 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
4655 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
4656 FONT_SCALE, 1.0f, userId);
4657
4658 synchronized (this) {
4659 if (getGlobalConfiguration().fontScale == scaleFactor) {
4660 return;
4661 }
4662
4663 final Configuration configuration
4664 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
4665 configuration.fontScale = scaleFactor;
4666 updatePersistentConfiguration(configuration, userId);
4667 }
4668 }
4669
4670 // Actually is sleeping or shutting down or whatever else in the future
4671 // is an inactive state.
4672 boolean isSleepingOrShuttingDownLocked() {
4673 return isSleepingLocked() || mShuttingDown;
4674 }
4675
4676 boolean isSleepingLocked() {
4677 return mSleeping;
4678 }
4679
4680 /**
4681 * Update AMS states when an activity is resumed. This should only be called by
4682 * {@link ActivityStack#onActivityStateChanged(
4683 * ActivityRecord, ActivityStack.ActivityState, String)} when an activity is resumed.
4684 */
4685 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
4686 final TaskRecord task = r.getTask();
4687 if (task.isActivityTypeStandard()) {
4688 if (mCurAppTimeTracker != r.appTimeTracker) {
4689 // We are switching app tracking. Complete the current one.
4690 if (mCurAppTimeTracker != null) {
4691 mCurAppTimeTracker.stop();
4692 mH.obtainMessage(
4693 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
4694 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
4695 mCurAppTimeTracker = null;
4696 }
4697 if (r.appTimeTracker != null) {
4698 mCurAppTimeTracker = r.appTimeTracker;
4699 startTimeTrackingFocusedActivityLocked();
4700 }
4701 } else {
4702 startTimeTrackingFocusedActivityLocked();
4703 }
4704 } else {
4705 r.appTimeTracker = null;
4706 }
4707 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
4708 // TODO: Probably not, because we don't want to resume voice on switching
4709 // back to this activity
4710 if (task.voiceInteractor != null) {
4711 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
4712 } else {
4713 finishRunningVoiceLocked();
4714
4715 if (mLastResumedActivity != null) {
4716 final IVoiceInteractionSession session;
4717
4718 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
4719 if (lastResumedActivityTask != null
4720 && lastResumedActivityTask.voiceSession != null) {
4721 session = lastResumedActivityTask.voiceSession;
4722 } else {
4723 session = mLastResumedActivity.voiceSession;
4724 }
4725
4726 if (session != null) {
4727 // We had been in a voice interaction session, but now focused has
4728 // move to something different. Just finish the session, we can't
4729 // return to it and retain the proper state and synchronization with
4730 // the voice interaction service.
4731 finishVoiceTask(session);
4732 }
4733 }
4734 }
4735
4736 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
4737 mAmInternal.sendForegroundProfileChanged(r.userId);
4738 }
4739 updateResumedAppTrace(r);
4740 mLastResumedActivity = r;
4741
Andrii Kulianab132ee2018-07-24 22:10:21 +08004742 // TODO(b/111541062): Support multiple focused apps in WM
Wale Ogunwalef6733932018-06-27 05:14:34 -07004743 mWindowManager.setFocusedApp(r.appToken, true);
4744
4745 applyUpdateLockStateLocked(r);
4746 applyUpdateVrModeLocked(r);
4747
4748 EventLogTags.writeAmSetResumedActivity(
4749 r == null ? -1 : r.userId,
4750 r == null ? "NULL" : r.shortComponentName,
4751 reason);
4752 }
4753
4754 ActivityTaskManagerInternal.SleepToken acquireSleepToken(String tag, int displayId) {
4755 synchronized (mGlobalLock) {
4756 final ActivityTaskManagerInternal.SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
4757 updateSleepIfNeededLocked();
4758 return token;
4759 }
4760 }
4761
4762 void updateSleepIfNeededLocked() {
4763 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
4764 final boolean wasSleeping = mSleeping;
4765 boolean updateOomAdj = false;
4766
4767 if (!shouldSleep) {
4768 // If wasSleeping is true, we need to wake up activity manager state from when
4769 // we started sleeping. In either case, we need to apply the sleep tokens, which
4770 // will wake up stacks or put them to sleep as appropriate.
4771 if (wasSleeping) {
4772 mSleeping = false;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07004773 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
4774 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__AWAKE);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004775 startTimeTrackingFocusedActivityLocked();
4776 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
4777 mStackSupervisor.comeOutOfSleepIfNeededLocked();
4778 }
4779 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
4780 if (wasSleeping) {
4781 updateOomAdj = true;
4782 }
4783 } else if (!mSleeping && shouldSleep) {
4784 mSleeping = true;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07004785 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
4786 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__ASLEEP);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004787 if (mCurAppTimeTracker != null) {
4788 mCurAppTimeTracker.stop();
4789 }
4790 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
4791 mStackSupervisor.goingToSleepLocked();
4792 updateResumedAppTrace(null /* resumed */);
4793 updateOomAdj = true;
4794 }
4795 if (updateOomAdj) {
4796 mH.post(mAmInternal::updateOomAdj);
4797 }
4798 }
4799
4800 void updateOomAdj() {
4801 mH.post(mAmInternal::updateOomAdj);
4802 }
4803
Andrii Kulian52d255c2018-07-13 11:32:19 -07004804 // TODO(b/111541062): Update app time tracking to make it aware of multiple resumed activities
Wale Ogunwalef6733932018-06-27 05:14:34 -07004805 private void startTimeTrackingFocusedActivityLocked() {
Andrii Kulian52d255c2018-07-13 11:32:19 -07004806 final ActivityRecord resumedActivity = mStackSupervisor.getTopResumedActivity();
Wale Ogunwalef6733932018-06-27 05:14:34 -07004807 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
4808 mCurAppTimeTracker.start(resumedActivity.packageName);
4809 }
4810 }
4811
4812 private void updateResumedAppTrace(@Nullable ActivityRecord resumed) {
4813 if (mTracedResumedActivity != null) {
4814 Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER,
4815 constructResumedTraceName(mTracedResumedActivity.packageName), 0);
4816 }
4817 if (resumed != null) {
4818 Trace.asyncTraceBegin(TRACE_TAG_ACTIVITY_MANAGER,
4819 constructResumedTraceName(resumed.packageName), 0);
4820 }
4821 mTracedResumedActivity = resumed;
4822 }
4823
4824 private String constructResumedTraceName(String packageName) {
4825 return "focused app: " + packageName;
4826 }
4827
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004828 /** Helper method that requests bounds from WM and applies them to stack. */
4829 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
4830 final Rect newStackBounds = new Rect();
4831 final ActivityStack stack = mStackSupervisor.getStack(stackId);
4832
4833 // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
4834 if (stack == null) {
4835 final StringWriter writer = new StringWriter();
4836 final PrintWriter printWriter = new PrintWriter(writer);
4837 mStackSupervisor.dumpDisplays(printWriter);
4838 printWriter.flush();
4839
4840 Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
4841 }
4842
4843 stack.getBoundsForNewConfiguration(newStackBounds);
4844 mStackSupervisor.resizeStackLocked(
4845 stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
4846 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
4847 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
4848 }
4849
4850 /** Applies latest configuration and/or visibility updates if needed. */
4851 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
4852 boolean kept = true;
Andrii Kulian5f750bc2018-07-17 08:57:23 -07004853 final ActivityStack mainStack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004854 // mainStack is null during startup.
4855 if (mainStack != null) {
4856 if (changes != 0 && starting == null) {
4857 // If the configuration changed, and the caller is not already
4858 // in the process of starting an activity, then find the top
4859 // activity to check if its configuration needs to change.
4860 starting = mainStack.topRunningActivityLocked();
4861 }
4862
4863 if (starting != null) {
4864 kept = starting.ensureActivityConfiguration(changes,
4865 false /* preserveWindow */);
4866 // And we need to make sure at this point that all other activities
4867 // are made visible with the correct configuration.
4868 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
4869 !PRESERVE_WINDOWS);
4870 }
4871 }
4872
4873 return kept;
4874 }
4875
Wale Ogunwale906f9c62018-07-23 11:23:44 -07004876 void scheduleAppGcsLocked() {
4877 mH.post(() -> mAmInternal.scheduleAppGcs());
4878 }
4879
4880 /**
4881 * Returns the PackageManager. Used by classes hosted by {@link ActivityTaskManagerService}. The
4882 * PackageManager could be unavailable at construction time and therefore needs to be accessed
4883 * on demand.
4884 */
4885 IPackageManager getPackageManager() {
4886 return AppGlobals.getPackageManager();
4887 }
4888
4889 PackageManagerInternal getPackageManagerInternalLocked() {
4890 if (mPmInternal == null) {
4891 mPmInternal = LocalServices.getService(PackageManagerInternal.class);
4892 }
4893 return mPmInternal;
4894 }
4895
Wale Ogunwale008163e2018-07-23 23:11:08 -07004896 AppWarnings getAppWarningsLocked() {
4897 return mAppWarnings;
4898 }
4899
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004900 void logAppTooSlow(WindowProcessController app, long startTime, String msg) {
4901 if (true || Build.IS_USER) {
4902 return;
4903 }
4904
4905 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4906 StrictMode.allowThreadDiskWrites();
4907 try {
4908 File tracesDir = new File("/data/anr");
4909 File tracesFile = null;
4910 try {
4911 tracesFile = File.createTempFile("app_slow", null, tracesDir);
4912
4913 StringBuilder sb = new StringBuilder();
4914 Time tobj = new Time();
4915 tobj.set(System.currentTimeMillis());
4916 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4917 sb.append(": ");
4918 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4919 sb.append(" since ");
4920 sb.append(msg);
4921 FileOutputStream fos = new FileOutputStream(tracesFile);
4922 fos.write(sb.toString().getBytes());
4923 if (app == null) {
4924 fos.write("\n*** No application process!".getBytes());
4925 }
4926 fos.close();
4927 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4928 } catch (IOException e) {
4929 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesFile, e);
4930 return;
4931 }
4932
4933 if (app != null && app.getPid() > 0) {
4934 ArrayList<Integer> firstPids = new ArrayList<Integer>();
4935 firstPids.add(app.getPid());
4936 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, null, null);
4937 }
4938
4939 File lastTracesFile = null;
4940 File curTracesFile = null;
4941 for (int i=9; i>=0; i--) {
4942 String name = String.format(Locale.US, "slow%02d.txt", i);
4943 curTracesFile = new File(tracesDir, name);
4944 if (curTracesFile.exists()) {
4945 if (lastTracesFile != null) {
4946 curTracesFile.renameTo(lastTracesFile);
4947 } else {
4948 curTracesFile.delete();
4949 }
4950 }
4951 lastTracesFile = curTracesFile;
4952 }
4953 tracesFile.renameTo(curTracesFile);
4954 } finally {
4955 StrictMode.setThreadPolicy(oldPolicy);
4956 }
4957 }
4958
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004959 final class H extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07004960 static final int REPORT_TIME_TRACKER_MSG = 1;
4961
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004962 public H(Looper looper) {
4963 super(looper, null, true);
4964 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004965
4966 @Override
4967 public void handleMessage(Message msg) {
4968 switch (msg.what) {
4969 case REPORT_TIME_TRACKER_MSG: {
4970 AppTimeTracker tracker = (AppTimeTracker) msg.obj;
4971 tracker.deliverResult(mContext);
4972 } break;
4973 }
4974 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004975 }
4976
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004977 final class UiHandler extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07004978 static final int DISMISS_DIALOG_UI_MSG = 1;
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004979
4980 public UiHandler() {
4981 super(com.android.server.UiThread.get().getLooper(), null, true);
4982 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004983
4984 @Override
4985 public void handleMessage(Message msg) {
4986 switch (msg.what) {
4987 case DISMISS_DIALOG_UI_MSG: {
4988 final Dialog d = (Dialog) msg.obj;
4989 d.dismiss();
4990 break;
4991 }
4992 }
4993 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004994 }
4995
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004996 final class LocalService extends ActivityTaskManagerInternal {
4997 @Override
4998 public SleepToken acquireSleepToken(String tag, int displayId) {
4999 Preconditions.checkNotNull(tag);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005000 return ActivityTaskManagerService.this.acquireSleepToken(tag, displayId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005001 }
5002
5003 @Override
5004 public ComponentName getHomeActivityForUser(int userId) {
5005 synchronized (mGlobalLock) {
5006 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
5007 return homeActivity == null ? null : homeActivity.realActivity;
5008 }
5009 }
5010
5011 @Override
5012 public void onLocalVoiceInteractionStarted(IBinder activity,
5013 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
5014 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005015 onLocalVoiceInteractionStartedLocked(activity, voiceSession, voiceInteractor);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005016 }
5017 }
5018
5019 @Override
5020 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
5021 synchronized (mGlobalLock) {
5022 mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
5023 reasons, timestamp);
5024 }
5025 }
5026
5027 @Override
5028 public void notifyAppTransitionFinished() {
5029 synchronized (mGlobalLock) {
5030 mStackSupervisor.notifyAppTransitionDone();
5031 }
5032 }
5033
5034 @Override
5035 public void notifyAppTransitionCancelled() {
5036 synchronized (mGlobalLock) {
5037 mStackSupervisor.notifyAppTransitionDone();
5038 }
5039 }
5040
5041 @Override
5042 public List<IBinder> getTopVisibleActivities() {
5043 synchronized (mGlobalLock) {
5044 return mStackSupervisor.getTopVisibleActivities();
5045 }
5046 }
5047
5048 @Override
5049 public void notifyDockedStackMinimizedChanged(boolean minimized) {
5050 synchronized (mGlobalLock) {
5051 mStackSupervisor.setDockedStackMinimized(minimized);
5052 }
5053 }
5054
5055 @Override
5056 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
5057 Bundle bOptions) {
5058 Preconditions.checkNotNull(intents, "intents");
5059 final String[] resolvedTypes = new String[intents.length];
5060
5061 // UID of the package on user userId.
5062 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
5063 // packageUid may not be initialized.
5064 int packageUid = 0;
5065 final long ident = Binder.clearCallingIdentity();
5066
5067 try {
5068 for (int i = 0; i < intents.length; i++) {
5069 resolvedTypes[i] =
5070 intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
5071 }
5072
5073 packageUid = AppGlobals.getPackageManager().getPackageUid(
5074 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
5075 } catch (RemoteException e) {
5076 // Shouldn't happen.
5077 } finally {
5078 Binder.restoreCallingIdentity(ident);
5079 }
5080
5081 synchronized (mGlobalLock) {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07005082 return getActivityStartController().startActivitiesInPackage(
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005083 packageUid, packageName,
5084 intents, resolvedTypes, null /* resultTo */,
5085 SafeActivityOptions.fromBundle(bOptions), userId,
5086 false /* validateIncomingUser */);
5087 }
5088 }
5089
5090 @Override
5091 public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
5092 Intent intent, Bundle options, int userId) {
5093 return ActivityTaskManagerService.this.startActivityAsUser(
5094 caller, callerPacakge, intent,
5095 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
5096 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
5097 false /*validateIncomingUser*/);
5098 }
5099
5100 @Override
5101 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
5102 synchronized (mGlobalLock) {
5103
5104 // We might change the visibilities here, so prepare an empty app transition which
5105 // might be overridden later if we actually change visibilities.
5106 final boolean wasTransitionSet =
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005107 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005108 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005109 mWindowManager.prepareAppTransition(TRANSIT_NONE,
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005110 false /* alwaysKeepCurrent */);
5111 }
5112 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5113
5114 // If there was a transition set already we don't want to interfere with it as we
5115 // might be starting it too early.
5116 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005117 mWindowManager.executeAppTransition();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005118 }
5119 }
5120 if (callback != null) {
5121 callback.run();
5122 }
5123 }
5124
5125 @Override
5126 public void notifyKeyguardTrustedChanged() {
5127 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005128 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005129 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5130 }
5131 }
5132 }
5133
5134 /**
5135 * Called after virtual display Id is updated by
5136 * {@link com.android.server.vr.Vr2dDisplay} with a specific
5137 * {@param vrVr2dDisplayId}.
5138 */
5139 @Override
5140 public void setVr2dDisplayId(int vr2dDisplayId) {
5141 if (DEBUG_STACK) Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
5142 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005143 mVr2dDisplayId = vr2dDisplayId;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005144 }
5145 }
5146
5147 @Override
5148 public void setFocusedActivity(IBinder token) {
5149 synchronized (mGlobalLock) {
5150 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
5151 if (r == null) {
5152 throw new IllegalArgumentException(
5153 "setFocusedActivity: No activity record matching token=" + token);
5154 }
5155 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
5156 r, "setFocusedActivity")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08005157 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005158 }
5159 }
5160 }
5161
5162 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005163 public void registerScreenObserver(ScreenObserver observer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005164 mScreenObservers.add(observer);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005165 }
5166
5167 @Override
5168 public boolean isCallerRecents(int callingUid) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005169 return getRecentTasks().isCallerRecents(callingUid);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005170 }
5171
5172 @Override
5173 public boolean isRecentsComponentHomeActivity(int userId) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005174 return getRecentTasks().isRecentsComponentHomeActivity(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005175 }
5176
5177 @Override
5178 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
5179 ActivityTaskManagerService.this.cancelRecentsAnimation(restoreHomeStackPosition);
5180 }
5181
5182 @Override
5183 public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005184 ActivityTaskManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005185 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005186
5187 @Override
5188 public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
5189 synchronized (mGlobalLock) {
5190 mActiveVoiceInteractionServiceComponent = component;
5191 }
5192 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005193
5194 @Override
5195 public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
5196 if (!mAmInternal.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
5197 return;
5198 }
5199 synchronized (mGlobalLock) {
5200 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
5201 if (types == null) {
5202 if (uid < 0) {
5203 return;
5204 }
5205 types = new ArrayMap<>();
5206 mAllowAppSwitchUids.put(userId, types);
5207 }
5208 if (uid < 0) {
5209 types.remove(type);
5210 } else {
5211 types.put(type, uid);
5212 }
5213 }
5214 }
5215
5216 @Override
5217 public void onUserStopped(int userId) {
5218 synchronized (mGlobalLock) {
5219 getRecentTasks().unloadUserDataFromMemoryLocked(userId);
5220 mAllowAppSwitchUids.remove(userId);
5221 }
5222 }
5223
5224 @Override
5225 public boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
5226 synchronized (mGlobalLock) {
5227 return ActivityTaskManagerService.this.isGetTasksAllowed(
5228 caller, callingPid, callingUid);
5229 }
5230 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005231
5232 @Override
5233 public void onProcessAdded(WindowProcessController proc) {
5234 synchronized (mGlobalLock) {
5235 mProcessNames.put(proc.mName, proc.mUid, proc);
5236 }
5237 }
5238
5239 @Override
5240 public void onProcessRemoved(String name, int uid) {
5241 synchronized (mGlobalLock) {
5242 mProcessNames.remove(name, uid);
5243 }
5244 }
5245
5246 @Override
5247 public void onCleanUpApplicationRecord(WindowProcessController proc) {
5248 synchronized (mGlobalLock) {
5249 if (proc == mHomeProcess) {
5250 mHomeProcess = null;
5251 }
5252 if (proc == mPreviousProcess) {
5253 mPreviousProcess = null;
5254 }
5255 }
5256 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005257
5258 @Override
5259 public int getTopProcessState() {
5260 synchronized (mGlobalLock) {
5261 return mTopProcessState;
5262 }
5263 }
5264
5265 @Override
5266 public boolean isSleeping() {
5267 synchronized (mGlobalLock) {
5268 return isSleepingLocked();
5269 }
5270 }
5271
5272 @Override
5273 public boolean isShuttingDown() {
5274 synchronized (mGlobalLock) {
5275 return mShuttingDown;
5276 }
5277 }
5278
5279 @Override
5280 public boolean shuttingDown(boolean booted, int timeout) {
5281 synchronized (mGlobalLock) {
5282 mShuttingDown = true;
5283 mStackSupervisor.prepareForShutdownLocked();
5284 updateEventDispatchingLocked(booted);
5285 return mStackSupervisor.shutdownLocked(timeout);
5286 }
5287 }
5288
5289 @Override
5290 public void enableScreenAfterBoot(boolean booted) {
5291 synchronized (mGlobalLock) {
5292 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5293 SystemClock.uptimeMillis());
5294 mWindowManager.enableScreenAfterBoot();
5295 updateEventDispatchingLocked(booted);
5296 }
5297 }
5298
5299 @Override
5300 public boolean showStrictModeViolationDialog() {
5301 synchronized (mGlobalLock) {
5302 return mShowDialogs && !mSleeping && !mShuttingDown;
5303 }
5304 }
5305
5306 @Override
5307 public void showSystemReadyErrorDialogsIfNeeded() {
5308 synchronized (mGlobalLock) {
5309 try {
5310 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
5311 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
5312 + " data partition or your device will be unstable.");
5313 mUiHandler.post(() -> {
5314 if (mShowDialogs) {
5315 AlertDialog d = new BaseErrorDialog(mUiContext);
5316 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5317 d.setCancelable(false);
5318 d.setTitle(mUiContext.getText(R.string.android_system_label));
5319 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
5320 d.setButton(DialogInterface.BUTTON_POSITIVE,
5321 mUiContext.getText(R.string.ok),
5322 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5323 d.show();
5324 }
5325 });
5326 }
5327 } catch (RemoteException e) {
5328 }
5329
5330 if (!Build.isBuildConsistent()) {
5331 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
5332 mUiHandler.post(() -> {
5333 if (mShowDialogs) {
5334 AlertDialog d = new BaseErrorDialog(mUiContext);
5335 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5336 d.setCancelable(false);
5337 d.setTitle(mUiContext.getText(R.string.android_system_label));
5338 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
5339 d.setButton(DialogInterface.BUTTON_POSITIVE,
5340 mUiContext.getText(R.string.ok),
5341 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5342 d.show();
5343 }
5344 });
5345 }
5346 }
5347 }
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005348
5349 @Override
5350 public long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason) {
5351 synchronized (mGlobalLock) {
5352 return ActivityTaskManagerService.this.inputDispatchingTimedOut(
5353 pid, aboveSystem, reason);
5354 }
5355 }
5356
5357 @Override
5358 public void onProcessMapped(int pid, WindowProcessController proc) {
5359 synchronized (mGlobalLock) {
5360 mPidMap.put(pid, proc);
5361 }
5362 }
5363
5364 @Override
5365 public void onProcessUnMapped(int pid) {
5366 synchronized (mGlobalLock) {
5367 mPidMap.remove(pid);
5368 }
5369 }
Wale Ogunwale008163e2018-07-23 23:11:08 -07005370
5371 @Override
5372 public void onPackageDataCleared(String name) {
5373 synchronized (mGlobalLock) {
5374 mAppWarnings.onPackageDataCleared(name);
5375 }
5376 }
5377
5378 @Override
5379 public void onPackageUninstalled(String name) {
5380 synchronized (mGlobalLock) {
5381 mAppWarnings.onPackageUninstalled(name);
5382 }
5383 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005384 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07005385}