blob: ab1ba6cce2f58225c946e6f5a6f0eceae353a0ca [file] [log] [blame]
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.server.am;
18
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070019import static android.Manifest.permission.BIND_VOICE_INTERACTION;
20import static android.Manifest.permission.CHANGE_CONFIGURATION;
21import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
22import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070023import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070024import static android.Manifest.permission.READ_FRAME_BUFFER;
25import static android.Manifest.permission.REMOVE_TASKS;
26import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070027import static android.Manifest.permission.STOP_APP_SWITCHES;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070028import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
Wale Ogunwalef6733932018-06-27 05:14:34 -070029import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
30import static android.provider.Settings.Global.HIDE_ERROR_DIALOGS;
31import static android.provider.Settings.System.FONT_SCALE;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070032import static com.android.server.am.ActivityManagerService.dumpStackTraces;
Wale Ogunwalef6733932018-06-27 05:14:34 -070033import static com.android.server.am.ActivityTaskManagerService.H.REPORT_TIME_TRACKER_MSG;
34import static com.android.server.am.ActivityTaskManagerService.UiHandler.DISMISS_DIALOG_UI_MSG;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070035import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT;
36import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_DATA;
37import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
38import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070039import static android.app.ActivityTaskManager.INVALID_STACK_ID;
40import static android.app.ActivityTaskManager.RESIZE_MODE_PRESERVE_WINDOW;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070041import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070042import static android.app.AppOpsManager.OP_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070043import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
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;
47import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070048import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
49import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070050import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070051import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070052import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070053import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
54import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070055import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070056import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070057import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
58import static android.os.Build.VERSION_CODES.N;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070059import static android.os.Process.SYSTEM_UID;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070060import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
61import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
62import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
63import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070064import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
65import static android.view.Display.DEFAULT_DISPLAY;
66import static android.view.Display.INVALID_DISPLAY;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070067import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
Wale Ogunwale6767eae2018-05-03 15:52:51 -070068import static android.view.WindowManager.TRANSIT_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070069import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070070import static android.view.WindowManager.TRANSIT_TASK_OPEN;
71import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070072import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070073import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
74import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
75import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
76import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
Wale Ogunwale6767eae2018-05-03 15:52:51 -070077import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070078import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070079import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070080import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070081import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070082import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070083import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
84import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
85import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070086import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070087import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
88import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070089import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
90import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070091import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070092import static com.android.server.am.ActivityManagerService.ANIMATE;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070093import static com.android.server.am.ActivityManagerService.MY_PID;
94import static com.android.server.am.ActivityManagerService.SEND_LOCALE_TO_MOUNT_DAEMON_MSG;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070095import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070096import static com.android.server.am.ActivityManagerService.UPDATE_CONFIGURATION_MSG;
97import static com.android.server.am.ActivityManagerService.checkComponentPermission;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070098import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070099import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700100import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
101import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
102import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
103import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
104import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
105import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
106import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700107import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700108import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
109import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
110import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700111
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700112import android.Manifest;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700113import android.annotation.NonNull;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700114import android.annotation.Nullable;
115import android.annotation.UserIdInt;
116import android.app.Activity;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700117import android.app.ActivityManager;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700118import android.app.ActivityManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700119import android.app.ActivityOptions;
120import android.app.ActivityTaskManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700121import android.app.ActivityThread;
122import android.app.AlertDialog;
123import android.app.Dialog;
124import android.content.DialogInterface;
125import 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;
134import com.android.internal.annotations.GuardedBy;
135import com.android.internal.app.IAppOpsService;
136import com.android.server.AppOpsService;
137import 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;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700184import android.os.Process;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700185import android.os.RemoteException;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700186import android.os.StrictMode;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700187import android.os.SystemClock;
188import android.os.SystemProperties;
189import android.os.UpdateLock;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700190import android.os.UserHandle;
191import android.provider.Settings;
192import android.service.voice.IVoiceInteractionSession;
193import android.service.voice.VoiceInteractionManagerInternal;
194import android.telecom.TelecomManager;
195import android.text.TextUtils;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700196import android.text.format.Time;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700197import android.util.ArrayMap;
198import android.util.EventLog;
199import android.util.Log;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700200import android.util.Slog;
201
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700202import android.util.SparseArray;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700203import android.util.SparseIntArray;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700204import android.util.StatsLog;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700205import android.util.TimeUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700206import android.util.proto.ProtoOutputStream;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700207import android.view.IRecentsAnimationRunner;
208import android.view.RemoteAnimationAdapter;
209import android.view.RemoteAnimationDefinition;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700210
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700211import com.android.internal.annotations.VisibleForTesting;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700212import com.android.internal.app.AssistUtils;
213import com.android.internal.app.IVoiceInteractor;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700214import com.android.internal.app.ProcessMap;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700215import com.android.internal.logging.MetricsLogger;
216import com.android.internal.os.logging.MetricsLoggerWrapper;
217import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
218import com.android.internal.policy.IKeyguardDismissCallback;
219import com.android.internal.policy.KeyguardDismissCallback;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700220import com.android.internal.util.Preconditions;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700221import com.android.server.AttributeCache;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700222import com.android.server.LocalServices;
223import com.android.server.SystemService;
224import com.android.server.Watchdog;
225import com.android.server.vr.VrManagerInternal;
226import com.android.server.wm.PinnedStackWindowController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700227import com.android.server.wm.WindowManagerService;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700228
229import java.io.File;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700230import java.io.FileOutputStream;
231import java.io.IOException;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700232import java.io.PrintWriter;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700233import java.io.StringWriter;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700234import java.util.ArrayList;
235import java.util.List;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700236import java.util.Locale;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700237
238/**
239 * System service for managing activities and their containers (task, stacks, displays,... ).
240 *
241 * {@hide}
242 */
243public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
244 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityTaskManagerService" : TAG_AM;
245 private static final String TAG_STACK = TAG + POSTFIX_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700246 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
247 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
248 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
249 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
250 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700251 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700252
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700253 Context mContext;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700254 /**
255 * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
256 * change at runtime. Use mContext for non-UI purposes.
257 */
258 final Context mUiContext;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700259 H mH;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700260 UiHandler mUiHandler;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700261 ActivityManagerService mAm;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700262 ActivityManagerInternal mAmInternal;
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700263 UriGrantsManagerInternal mUgmInternal;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700264 /* Global service lock used by the package the owns this service. */
265 Object mGlobalLock;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700266 ActivityStackSupervisor mStackSupervisor;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700267 WindowManagerService mWindowManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700268 private UserManagerService mUserManager;
269 private AppOpsService mAppOpsService;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700270 /** All processes currently running that might have a window organized by name. */
271 final ProcessMap<WindowProcessController> mProcessNames = new ProcessMap<>();
272 /** This is the process holding what we currently consider to be the "home" activity. */
273 WindowProcessController mHomeProcess;
274 /**
275 * This is the process holding the activity the user last visited that is in a different process
276 * from the one they are currently in.
277 */
278 WindowProcessController mPreviousProcess;
279 /** The time at which the previous process was last visible. */
280 long mPreviousProcessVisibleTime;
281
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700282 /** List of intents that were used to start the most recent tasks. */
283 private RecentTasks mRecentTasks;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700284 /** State of external calls telling us if the device is awake or asleep. */
285 private boolean mKeyguardShown = false;
286
287 // Wrapper around VoiceInteractionServiceManager
288 private AssistUtils mAssistUtils;
289
290 // VoiceInteraction session ID that changes for each new request except when
291 // being called for multi-window assist in a single session.
292 private int mViSessionId = 1000;
293
294 // How long to wait in getAssistContextExtras for the activity and foreground services
295 // to respond with the result.
296 private static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
297
298 // How long top wait when going through the modern assist (which doesn't need to block
299 // on getting this result before starting to launch its UI).
300 private static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
301
302 // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
303 private static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
304
305 private final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
306
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700307 // Keeps track of the active voice interaction service component, notified from
308 // VoiceInteractionManagerService
309 ComponentName mActiveVoiceInteractionServiceComponent;
310
311 private VrController mVrController;
312 KeyguardController mKeyguardController;
313 private final ClientLifecycleManager mLifecycleManager;
314 private TaskChangeNotificationController mTaskChangeNotificationController;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700315 /** The controller for all operations related to locktask. */
316 private LockTaskController mLockTaskController;
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700317 private ActivityStartController mActivityStartController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700318
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700319 boolean mSuppressResizeConfigChanges;
320
321 private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
322 new UpdateConfigurationResult();
323
324 static final class UpdateConfigurationResult {
325 // Configuration changes that were updated.
326 int changes;
327 // If the activity was relaunched to match the new configuration.
328 boolean activityRelaunched;
329
330 void reset() {
331 changes = 0;
332 activityRelaunched = false;
333 }
334 }
335
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700336 /** Current sequencing integer of the configuration, for skipping old configurations. */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700337 private int mConfigurationSeq;
338 // To cache the list of supported system locales
339 private String[] mSupportedSystemLocales = null;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700340
341 /**
342 * Temp object used when global and/or display override configuration is updated. It is also
343 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
344 * anyone...
345 */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700346 private Configuration mTempConfig = new Configuration();
347
Wale Ogunwalef6733932018-06-27 05:14:34 -0700348 /** Temporary to avoid allocations. */
349 final StringBuilder mStringBuilder = new StringBuilder(256);
350
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700351 // Amount of time after a call to stopAppSwitches() during which we will
352 // prevent further untrusted switches from happening.
353 private static final long APP_SWITCH_DELAY_TIME = 5 * 1000;
354
355 /**
356 * The time at which we will allow normal application switches again,
357 * after a call to {@link #stopAppSwitches()}.
358 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700359 private long mAppSwitchesAllowedTime;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700360 /**
361 * This is set to true after the first switch after mAppSwitchesAllowedTime
362 * is set; any switches after that will clear the time.
363 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700364 private boolean mDidAppSwitch;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700365
366 IActivityController mController = null;
367 boolean mControllerIsAMonkey = false;
368
369 /**
370 * Used to retain an update lock when the foreground activity is in
371 * immersive mode.
372 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700373 private final UpdateLock mUpdateLock = new UpdateLock("immersive");
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700374
375 /**
376 * Packages that are being allowed to perform unrestricted app switches. Mapping is
377 * User -> Type -> uid.
378 */
379 final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
380
381 /** The dimensions of the thumbnails in the Recents UI. */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700382 private int mThumbnailWidth;
383 private int mThumbnailHeight;
384 private float mFullscreenThumbnailScale;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700385
386 /**
387 * Flag that indicates if multi-window is enabled.
388 *
389 * For any particular form of multi-window to be enabled, generic multi-window must be enabled
390 * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
391 * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
392 * At least one of the forms of multi-window must be enabled in order for this flag to be
393 * initialized to 'true'.
394 *
395 * @see #mSupportsSplitScreenMultiWindow
396 * @see #mSupportsFreeformWindowManagement
397 * @see #mSupportsPictureInPicture
398 * @see #mSupportsMultiDisplay
399 */
400 boolean mSupportsMultiWindow;
401 boolean mSupportsSplitScreenMultiWindow;
402 boolean mSupportsFreeformWindowManagement;
403 boolean mSupportsPictureInPicture;
404 boolean mSupportsMultiDisplay;
405 boolean mForceResizableActivities;
406
407 final List<ActivityTaskManagerInternal.ScreenObserver> mScreenObservers = new ArrayList<>();
408
409 // VR Vr2d Display Id.
410 int mVr2dDisplayId = INVALID_DISPLAY;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700411
Wale Ogunwalef6733932018-06-27 05:14:34 -0700412 /**
413 * Set while we are wanting to sleep, to prevent any
414 * activities from being started/resumed.
415 *
416 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
417 *
418 * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
419 * while in the sleep state until there is a pending transition out of sleep, in which case
420 * mSleeping is set to false, and remains false while awake.
421 *
422 * Whether mSleeping can quickly toggled between true/false without the device actually
423 * display changing states is undefined.
424 */
425 private boolean mSleeping = false;
426
427 /**
428 * The process state used for processes that are running the top activities.
429 * This changes between TOP and TOP_SLEEPING to following mSleeping.
430 */
431 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
432
433 // Whether we should show our dialogs (ANR, crash, etc) or just perform their default action
434 // automatically. Important for devices without direct input devices.
435 private boolean mShowDialogs = true;
436
437 /** Set if we are shutting down the system, similar to sleeping. */
438 boolean mShuttingDown = false;
439
440 /**
441 * We want to hold a wake lock while running a voice interaction session, since
442 * this may happen with the screen off and we need to keep the CPU running to
443 * be able to continue to interact with the user.
444 */
445 PowerManager.WakeLock mVoiceWakeLock;
446
447 /**
448 * Set while we are running a voice interaction. This overrides sleeping while it is active.
449 */
450 IVoiceInteractionSession mRunningVoice;
451
452 /**
453 * The last resumed activity. This is identical to the current resumed activity most
454 * of the time but could be different when we're pausing one activity before we resume
455 * another activity.
456 */
457 ActivityRecord mLastResumedActivity;
458
459 /**
460 * The activity that is currently being traced as the active resumed activity.
461 *
462 * @see #updateResumedAppTrace
463 */
464 private @Nullable ActivityRecord mTracedResumedActivity;
465
466 /** If non-null, we are tracking the time the user spends in the currently focused app. */
467 AppTimeTracker mCurAppTimeTracker;
468
469 private FontScaleSettingObserver mFontScaleSettingObserver;
470
471 private final class FontScaleSettingObserver extends ContentObserver {
472 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
473 private final Uri mHideErrorDialogsUri = Settings.Global.getUriFor(HIDE_ERROR_DIALOGS);
474
475 public FontScaleSettingObserver() {
476 super(mH);
477 final ContentResolver resolver = mContext.getContentResolver();
478 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
479 resolver.registerContentObserver(mHideErrorDialogsUri, false, this,
480 UserHandle.USER_ALL);
481 }
482
483 @Override
484 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
485 if (mFontScaleUri.equals(uri)) {
486 updateFontScaleIfNeeded(userId);
487 } else if (mHideErrorDialogsUri.equals(uri)) {
488 synchronized (mGlobalLock) {
489 updateShouldShowDialogsLocked(getGlobalConfiguration());
490 }
491 }
492 }
493 }
494
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700495 ActivityTaskManagerService(Context context) {
496 mContext = context;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700497 mUiContext = ActivityThread.currentActivityThread().getSystemUiContext();
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700498 mLifecycleManager = new ClientLifecycleManager();
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700499 }
500
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700501 void onSystemReady() {
502 mAssistUtils = new AssistUtils(mContext);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700503 mVrController.onSystemReady();
504 mRecentTasks.onSystemReadyLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700505 }
506
Wale Ogunwalef6733932018-06-27 05:14:34 -0700507 void onInitPowerManagement() {
508 mStackSupervisor.initPowerManagement();
509 final PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
510 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
511 mVoiceWakeLock.setReferenceCounted(false);
512 }
513
514 void installSystemProviders() {
515 mFontScaleSettingObserver = new FontScaleSettingObserver();
516 }
517
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700518 void retrieveSettings(ContentResolver resolver) {
519 final boolean freeformWindowManagement =
520 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
521 || Settings.Global.getInt(
522 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
523
524 final boolean supportsMultiWindow = ActivityTaskManager.supportsMultiWindow(mContext);
525 final boolean supportsPictureInPicture = supportsMultiWindow &&
526 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
527 final boolean supportsSplitScreenMultiWindow =
528 ActivityTaskManager.supportsSplitScreenMultiWindow(mContext);
529 final boolean supportsMultiDisplay = mContext.getPackageManager()
530 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
531 final boolean alwaysFinishActivities =
532 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
533 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
534 final boolean forceResizable = Settings.Global.getInt(
535 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
536
537 // Transfer any global setting for forcing RTL layout, into a System Property
538 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
539
540 final Configuration configuration = new Configuration();
541 Settings.System.getConfiguration(resolver, configuration);
542 if (forceRtl) {
543 // This will take care of setting the correct layout direction flags
544 configuration.setLayoutDirection(configuration.locale);
545 }
546
547 synchronized (mGlobalLock) {
548 mForceResizableActivities = forceResizable;
549 final boolean multiWindowFormEnabled = freeformWindowManagement
550 || supportsSplitScreenMultiWindow
551 || supportsPictureInPicture
552 || supportsMultiDisplay;
553 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
554 mSupportsMultiWindow = true;
555 mSupportsFreeformWindowManagement = freeformWindowManagement;
556 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
557 mSupportsPictureInPicture = supportsPictureInPicture;
558 mSupportsMultiDisplay = supportsMultiDisplay;
559 } else {
560 mSupportsMultiWindow = false;
561 mSupportsFreeformWindowManagement = false;
562 mSupportsSplitScreenMultiWindow = false;
563 mSupportsPictureInPicture = false;
564 mSupportsMultiDisplay = false;
565 }
566 mWindowManager.setForceResizableTasks(mForceResizableActivities);
567 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
568 // This happens before any activities are started, so we can change global configuration
569 // in-place.
570 updateConfigurationLocked(configuration, null, true);
571 final Configuration globalConfig = getGlobalConfiguration();
572 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
573
574 // Load resources only after the current configuration has been set.
575 final Resources res = mContext.getResources();
576 mThumbnailWidth = res.getDimensionPixelSize(
577 com.android.internal.R.dimen.thumbnail_width);
578 mThumbnailHeight = res.getDimensionPixelSize(
579 com.android.internal.R.dimen.thumbnail_height);
580
581 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
582 mFullscreenThumbnailScale = (float) res
583 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
584 (float) globalConfig.screenWidthDp;
585 } else {
586 mFullscreenThumbnailScale = res.getFraction(
587 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
588 }
589 }
590 }
591
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700592 // TODO: Will be converted to WM lock once transition is complete.
593 void setActivityManagerService(ActivityManagerService am) {
594 mAm = am;
595 mGlobalLock = mAm;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700596 mH = new H(mAm.mHandlerThread.getLooper());
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700597 mUiHandler = new UiHandler();
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700598
599 mTempConfig.setToDefaults();
600 mTempConfig.setLocales(LocaleList.getDefault());
601 mConfigurationSeq = mTempConfig.seq = 1;
602 mStackSupervisor = createStackSupervisor();
603 mStackSupervisor.onConfigurationChanged(mTempConfig);
604
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700605 mTaskChangeNotificationController =
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700606 new TaskChangeNotificationController(mGlobalLock, mStackSupervisor, mH);
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700607 mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mH);
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700608 mActivityStartController = new ActivityStartController(this);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700609 mRecentTasks = createRecentTasks();
610 mStackSupervisor.setRecentTasks(mRecentTasks);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700611 mVrController = new VrController(mGlobalLock);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700612 mKeyguardController = mStackSupervisor.getKeyguardController();
613 }
614
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700615 void onActivityManagerInternalAdded() {
616 mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700617 mUgmInternal = LocalServices.getService(UriGrantsManagerInternal.class);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700618 }
619
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700620 protected ActivityStackSupervisor createStackSupervisor() {
621 final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mH.getLooper());
622 supervisor.initialize();
623 return supervisor;
624 }
625
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700626 void setWindowManager(WindowManagerService wm) {
627 mWindowManager = wm;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700628 mLockTaskController.setWindowManager(wm);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700629 }
630
Wale Ogunwalef6733932018-06-27 05:14:34 -0700631 UserManagerService getUserManager() {
632 if (mUserManager == null) {
633 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
634 mUserManager = (UserManagerService) IUserManager.Stub.asInterface(b);
635 }
636 return mUserManager;
637 }
638
639 AppOpsService getAppOpsService() {
640 if (mAppOpsService == null) {
641 IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
642 mAppOpsService = (AppOpsService) IAppOpsService.Stub.asInterface(b);
643 }
644 return mAppOpsService;
645 }
646
647 boolean hasUserRestriction(String restriction, int userId) {
648 return getUserManager().hasUserRestriction(restriction, userId);
649 }
650
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700651 protected RecentTasks createRecentTasks() {
652 return new RecentTasks(this, mStackSupervisor);
653 }
654
655 RecentTasks getRecentTasks() {
656 return mRecentTasks;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700657 }
658
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700659 ClientLifecycleManager getLifecycleManager() {
660 return mLifecycleManager;
661 }
662
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700663 ActivityStartController getActivityStartController() {
664 return mActivityStartController;
665 }
666
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700667 TaskChangeNotificationController getTaskChangeNotificationController() {
668 return mTaskChangeNotificationController;
669 }
670
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700671 LockTaskController getLockTaskController() {
672 return mLockTaskController;
673 }
674
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700675 private void start() {
676 LocalServices.addService(ActivityTaskManagerInternal.class, new LocalService());
677 }
678
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700679 public static final class Lifecycle extends SystemService {
680 private final ActivityTaskManagerService mService;
681
682 public Lifecycle(Context context) {
683 super(context);
684 mService = new ActivityTaskManagerService(context);
685 }
686
687 @Override
688 public void onStart() {
689 publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700690 mService.start();
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700691 }
692
693 public ActivityTaskManagerService getService() {
694 return mService;
695 }
696 }
697
698 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700699 public final int startActivity(IApplicationThread caller, String callingPackage,
700 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
701 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
702 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
703 resultWho, requestCode, startFlags, profilerInfo, bOptions,
704 UserHandle.getCallingUserId());
705 }
706
707 @Override
708 public final int startActivities(IApplicationThread caller, String callingPackage,
709 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
710 int userId) {
711 final String reason = "startActivities";
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700712 enforceNotIsolatedCaller(reason);
713 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, reason);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700714 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700715 return getActivityStartController().startActivities(caller, -1, callingPackage, intents,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700716 resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId, reason);
717 }
718
719 @Override
720 public int startActivityAsUser(IApplicationThread caller, String callingPackage,
721 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
722 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
723 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
724 resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
725 true /*validateIncomingUser*/);
726 }
727
728 int startActivityAsUser(IApplicationThread caller, String callingPackage,
729 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
730 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
731 boolean validateIncomingUser) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700732 enforceNotIsolatedCaller("startActivityAsUser");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700733
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700734 userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700735 Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
736
737 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700738 return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700739 .setCaller(caller)
740 .setCallingPackage(callingPackage)
741 .setResolvedType(resolvedType)
742 .setResultTo(resultTo)
743 .setResultWho(resultWho)
744 .setRequestCode(requestCode)
745 .setStartFlags(startFlags)
746 .setProfilerInfo(profilerInfo)
747 .setActivityOptions(bOptions)
748 .setMayWait(userId)
749 .execute();
750
751 }
752
753 @Override
754 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
755 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700756 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions) {
757 enforceNotIsolatedCaller("startActivityIntentSender");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700758 // Refuse possible leaked file descriptors
759 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
760 throw new IllegalArgumentException("File descriptors passed in Intent");
761 }
762
763 if (!(target instanceof PendingIntentRecord)) {
764 throw new IllegalArgumentException("Bad PendingIntent object");
765 }
766
767 PendingIntentRecord pir = (PendingIntentRecord)target;
768
769 synchronized (mGlobalLock) {
770 // If this is coming from the currently resumed activity, it is
771 // effectively saying that app switches are allowed at this point.
Andrii Kulian5f750bc2018-07-17 08:57:23 -0700772 final ActivityStack stack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700773 if (stack.mResumedActivity != null &&
774 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700775 mAppSwitchesAllowedTime = 0;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700776 }
777 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700778 return pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700779 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700780 }
781
782 @Override
783 public boolean startNextMatchingActivity(IBinder callingActivity, Intent intent,
784 Bundle bOptions) {
785 // Refuse possible leaked file descriptors
786 if (intent != null && intent.hasFileDescriptors()) {
787 throw new IllegalArgumentException("File descriptors passed in Intent");
788 }
789 SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
790
791 synchronized (mGlobalLock) {
792 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
793 if (r == null) {
794 SafeActivityOptions.abort(options);
795 return false;
796 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700797 if (!r.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700798 // The caller is not running... d'oh!
799 SafeActivityOptions.abort(options);
800 return false;
801 }
802 intent = new Intent(intent);
803 // The caller is not allowed to change the data.
804 intent.setDataAndType(r.intent.getData(), r.intent.getType());
805 // And we are resetting to find the next component...
806 intent.setComponent(null);
807
808 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
809
810 ActivityInfo aInfo = null;
811 try {
812 List<ResolveInfo> resolves =
813 AppGlobals.getPackageManager().queryIntentActivities(
814 intent, r.resolvedType,
815 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
816 UserHandle.getCallingUserId()).getList();
817
818 // Look for the original activity in the list...
819 final int N = resolves != null ? resolves.size() : 0;
820 for (int i=0; i<N; i++) {
821 ResolveInfo rInfo = resolves.get(i);
822 if (rInfo.activityInfo.packageName.equals(r.packageName)
823 && rInfo.activityInfo.name.equals(r.info.name)) {
824 // We found the current one... the next matching is
825 // after it.
826 i++;
827 if (i<N) {
828 aInfo = resolves.get(i).activityInfo;
829 }
830 if (debug) {
831 Slog.v(TAG, "Next matching activity: found current " + r.packageName
832 + "/" + r.info.name);
833 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
834 ? "null" : aInfo.packageName + "/" + aInfo.name));
835 }
836 break;
837 }
838 }
839 } catch (RemoteException e) {
840 }
841
842 if (aInfo == null) {
843 // Nobody who is next!
844 SafeActivityOptions.abort(options);
845 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
846 return false;
847 }
848
849 intent.setComponent(new ComponentName(
850 aInfo.applicationInfo.packageName, aInfo.name));
851 intent.setFlags(intent.getFlags()&~(
852 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
853 Intent.FLAG_ACTIVITY_CLEAR_TOP|
854 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
855 FLAG_ACTIVITY_NEW_TASK));
856
857 // Okay now we need to start the new activity, replacing the currently running activity.
858 // This is a little tricky because we want to start the new one as if the current one is
859 // finished, but not finish the current one first so that there is no flicker.
860 // And thus...
861 final boolean wasFinishing = r.finishing;
862 r.finishing = true;
863
864 // Propagate reply information over to the new activity.
865 final ActivityRecord resultTo = r.resultTo;
866 final String resultWho = r.resultWho;
867 final int requestCode = r.requestCode;
868 r.resultTo = null;
869 if (resultTo != null) {
870 resultTo.removeResultsLocked(r, resultWho, requestCode);
871 }
872
873 final long origId = Binder.clearCallingIdentity();
874 // TODO(b/64750076): Check if calling pid should really be -1.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700875 final int res = getActivityStartController()
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700876 .obtainStarter(intent, "startNextMatchingActivity")
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700877 .setCaller(r.app.getThread())
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700878 .setResolvedType(r.resolvedType)
879 .setActivityInfo(aInfo)
880 .setResultTo(resultTo != null ? resultTo.appToken : null)
881 .setResultWho(resultWho)
882 .setRequestCode(requestCode)
883 .setCallingPid(-1)
884 .setCallingUid(r.launchedFromUid)
885 .setCallingPackage(r.launchedFromPackage)
886 .setRealCallingPid(-1)
887 .setRealCallingUid(r.launchedFromUid)
888 .setActivityOptions(options)
889 .execute();
890 Binder.restoreCallingIdentity(origId);
891
892 r.finishing = wasFinishing;
893 if (res != ActivityManager.START_SUCCESS) {
894 return false;
895 }
896 return true;
897 }
898 }
899
900 @Override
901 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
902 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
903 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
904 final WaitResult res = new WaitResult();
905 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700906 enforceNotIsolatedCaller("startActivityAndWait");
907 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
908 userId, "startActivityAndWait");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700909 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700910 getActivityStartController().obtainStarter(intent, "startActivityAndWait")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700911 .setCaller(caller)
912 .setCallingPackage(callingPackage)
913 .setResolvedType(resolvedType)
914 .setResultTo(resultTo)
915 .setResultWho(resultWho)
916 .setRequestCode(requestCode)
917 .setStartFlags(startFlags)
918 .setActivityOptions(bOptions)
919 .setMayWait(userId)
920 .setProfilerInfo(profilerInfo)
921 .setWaitResult(res)
922 .execute();
923 }
924 return res;
925 }
926
927 @Override
928 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
929 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
930 int startFlags, Configuration config, Bundle bOptions, int userId) {
931 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700932 enforceNotIsolatedCaller("startActivityWithConfig");
933 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
934 "startActivityWithConfig");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700935 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700936 return getActivityStartController().obtainStarter(intent, "startActivityWithConfig")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700937 .setCaller(caller)
938 .setCallingPackage(callingPackage)
939 .setResolvedType(resolvedType)
940 .setResultTo(resultTo)
941 .setResultWho(resultWho)
942 .setRequestCode(requestCode)
943 .setStartFlags(startFlags)
944 .setGlobalConfiguration(config)
945 .setActivityOptions(bOptions)
946 .setMayWait(userId)
947 .execute();
948 }
949 }
950
951 @Override
952 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
953 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
954 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
955 int userId) {
956
957 // This is very dangerous -- it allows you to perform a start activity (including
958 // permission grants) as any app that may launch one of your own activities. So
959 // we will only allow this to be done from activities that are part of the core framework,
960 // and then only when they are running as the system.
961 final ActivityRecord sourceRecord;
962 final int targetUid;
963 final String targetPackage;
964 final boolean isResolver;
965 synchronized (mGlobalLock) {
966 if (resultTo == null) {
967 throw new SecurityException("Must be called from an activity");
968 }
969 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
970 if (sourceRecord == null) {
971 throw new SecurityException("Called with bad activity token: " + resultTo);
972 }
973 if (!sourceRecord.info.packageName.equals("android")) {
974 throw new SecurityException(
975 "Must be called from an activity that is declared in the android package");
976 }
977 if (sourceRecord.app == null) {
978 throw new SecurityException("Called without a process attached to activity");
979 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700980 if (UserHandle.getAppId(sourceRecord.app.mUid) != SYSTEM_UID) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700981 // This is still okay, as long as this activity is running under the
982 // uid of the original calling activity.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700983 if (sourceRecord.app.mUid != sourceRecord.launchedFromUid) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700984 throw new SecurityException(
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700985 "Calling activity in uid " + sourceRecord.app.mUid
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700986 + " must be system uid or original calling uid "
987 + sourceRecord.launchedFromUid);
988 }
989 }
990 if (ignoreTargetSecurity) {
991 if (intent.getComponent() == null) {
992 throw new SecurityException(
993 "Component must be specified with ignoreTargetSecurity");
994 }
995 if (intent.getSelector() != null) {
996 throw new SecurityException(
997 "Selector not allowed with ignoreTargetSecurity");
998 }
999 }
1000 targetUid = sourceRecord.launchedFromUid;
1001 targetPackage = sourceRecord.launchedFromPackage;
1002 isResolver = sourceRecord.isResolverOrChildActivity();
1003 }
1004
1005 if (userId == UserHandle.USER_NULL) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001006 userId = UserHandle.getUserId(sourceRecord.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001007 }
1008
1009 // TODO: Switch to user app stacks here.
1010 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001011 return getActivityStartController().obtainStarter(intent, "startActivityAsCaller")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001012 .setCallingUid(targetUid)
1013 .setCallingPackage(targetPackage)
1014 .setResolvedType(resolvedType)
1015 .setResultTo(resultTo)
1016 .setResultWho(resultWho)
1017 .setRequestCode(requestCode)
1018 .setStartFlags(startFlags)
1019 .setActivityOptions(bOptions)
1020 .setMayWait(userId)
1021 .setIgnoreTargetSecurity(ignoreTargetSecurity)
1022 .setFilterCallingUid(isResolver ? 0 /* system */ : targetUid)
1023 .execute();
1024 } catch (SecurityException e) {
1025 // XXX need to figure out how to propagate to original app.
1026 // A SecurityException here is generally actually a fault of the original
1027 // calling activity (such as a fairly granting permissions), so propagate it
1028 // back to them.
1029 /*
1030 StringBuilder msg = new StringBuilder();
1031 msg.append("While launching");
1032 msg.append(intent.toString());
1033 msg.append(": ");
1034 msg.append(e.getMessage());
1035 */
1036 throw e;
1037 }
1038 }
1039
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001040 int handleIncomingUser(int callingPid, int callingUid, int userId, String name) {
1041 return mAmInternal.handleIncomingUser(callingPid, callingUid, userId, false /* allowAll */,
1042 ALLOW_FULL_ONLY, name, null /* callerPackage */);
1043 }
1044
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001045 @Override
1046 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
1047 Intent intent, String resolvedType, IVoiceInteractionSession session,
1048 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
1049 Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001050 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001051 if (session == null || interactor == null) {
1052 throw new NullPointerException("null session or interactor");
1053 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001054 userId = handleIncomingUser(callingPid, callingUid, userId, "startVoiceActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001055 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001056 return getActivityStartController().obtainStarter(intent, "startVoiceActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001057 .setCallingUid(callingUid)
1058 .setCallingPackage(callingPackage)
1059 .setResolvedType(resolvedType)
1060 .setVoiceSession(session)
1061 .setVoiceInteractor(interactor)
1062 .setStartFlags(startFlags)
1063 .setProfilerInfo(profilerInfo)
1064 .setActivityOptions(bOptions)
1065 .setMayWait(userId)
1066 .execute();
1067 }
1068
1069 @Override
1070 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
1071 Intent intent, String resolvedType, Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001072 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
1073 userId = handleIncomingUser(callingPid, callingUid, userId, "startAssistantActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001074
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001075 return getActivityStartController().obtainStarter(intent, "startAssistantActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001076 .setCallingUid(callingUid)
1077 .setCallingPackage(callingPackage)
1078 .setResolvedType(resolvedType)
1079 .setActivityOptions(bOptions)
1080 .setMayWait(userId)
1081 .execute();
1082 }
1083
1084 @Override
1085 public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
1086 IRecentsAnimationRunner recentsAnimationRunner) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001087 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001088 final int callingPid = Binder.getCallingPid();
1089 final long origId = Binder.clearCallingIdentity();
1090 try {
1091 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07001092 final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
1093 final int recentsUid = mRecentTasks.getRecentsComponentUid();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001094
1095 // Start a new recents animation
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001096 final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
1097 getActivityStartController(), mWindowManager, callingPid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001098 anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
1099 recentsUid, assistDataReceiver);
1100 }
1101 } finally {
1102 Binder.restoreCallingIdentity(origId);
1103 }
1104 }
1105
1106 @Override
1107 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001108 enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001109 "startActivityFromRecents()");
1110
1111 final int callingPid = Binder.getCallingPid();
1112 final int callingUid = Binder.getCallingUid();
1113 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(bOptions);
1114 final long origId = Binder.clearCallingIdentity();
1115 try {
1116 synchronized (mGlobalLock) {
1117 return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
1118 safeOptions);
1119 }
1120 } finally {
1121 Binder.restoreCallingIdentity(origId);
1122 }
1123 }
1124
1125 /**
1126 * This is the internal entry point for handling Activity.finish().
1127 *
1128 * @param token The Binder token referencing the Activity we want to finish.
1129 * @param resultCode Result code, if any, from this Activity.
1130 * @param resultData Result data (Intent), if any, from this Activity.
1131 * @param finishTask Whether to finish the task associated with this Activity.
1132 *
1133 * @return Returns true if the activity successfully finished, or false if it is still running.
1134 */
1135 @Override
1136 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
1137 int finishTask) {
1138 // Refuse possible leaked file descriptors
1139 if (resultData != null && resultData.hasFileDescriptors()) {
1140 throw new IllegalArgumentException("File descriptors passed in Intent");
1141 }
1142
1143 synchronized (mGlobalLock) {
1144 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1145 if (r == null) {
1146 return true;
1147 }
1148 // Keep track of the root activity of the task before we finish it
1149 TaskRecord tr = r.getTask();
1150 ActivityRecord rootR = tr.getRootActivity();
1151 if (rootR == null) {
1152 Slog.w(TAG, "Finishing task with all activities already finished");
1153 }
1154 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
1155 // finish.
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001156 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001157 return false;
1158 }
1159
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001160 // TODO: There is a dup. of this block of code in ActivityStack.navigateUpToLocked
1161 // We should consolidate.
1162 if (mController != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001163 // Find the first activity that is not finishing.
1164 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
1165 if (next != null) {
1166 // ask watcher if this is allowed
1167 boolean resumeOK = true;
1168 try {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001169 resumeOK = mController.activityResuming(next.packageName);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001170 } catch (RemoteException e) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001171 mController = null;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001172 Watchdog.getInstance().setActivityController(null);
1173 }
1174
1175 if (!resumeOK) {
1176 Slog.i(TAG, "Not finishing activity because controller resumed");
1177 return false;
1178 }
1179 }
1180 }
1181 final long origId = Binder.clearCallingIdentity();
1182 try {
1183 boolean res;
1184 final boolean finishWithRootActivity =
1185 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
1186 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
1187 || (finishWithRootActivity && r == rootR)) {
1188 // If requested, remove the task that is associated to this activity only if it
1189 // was the root activity in the task. The result code and data is ignored
1190 // because we don't support returning them across task boundaries. Also, to
1191 // keep backwards compatibility we remove the task from recents when finishing
1192 // task with root activity.
1193 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
1194 finishWithRootActivity, "finish-activity");
1195 if (!res) {
1196 Slog.i(TAG, "Removing task failed to finish activity");
1197 }
Garfield Tan2746ab52018-07-25 12:33:01 -07001198 // Explicitly dismissing the activity so reset its relaunch flag.
1199 r.mRelaunchReason = ActivityRecord.RELAUNCH_REASON_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001200 } else {
1201 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
1202 resultData, "app-request", true);
1203 if (!res) {
1204 Slog.i(TAG, "Failed to finish by app-request");
1205 }
1206 }
1207 return res;
1208 } finally {
1209 Binder.restoreCallingIdentity(origId);
1210 }
1211 }
1212 }
1213
1214 @Override
1215 public boolean finishActivityAffinity(IBinder token) {
1216 synchronized (mGlobalLock) {
1217 final long origId = Binder.clearCallingIdentity();
1218 try {
1219 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1220 if (r == null) {
1221 return false;
1222 }
1223
1224 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
1225 // can finish.
1226 final TaskRecord task = r.getTask();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001227 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001228 return false;
1229 }
1230 return task.getStack().finishActivityAffinityLocked(r);
1231 } finally {
1232 Binder.restoreCallingIdentity(origId);
1233 }
1234 }
1235 }
1236
1237 @Override
1238 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
1239 final long origId = Binder.clearCallingIdentity();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001240 try {
1241 WindowProcessController proc = null;
1242 synchronized (mGlobalLock) {
1243 ActivityStack stack = ActivityRecord.getStackLocked(token);
1244 if (stack == null) {
1245 return;
1246 }
1247 final ActivityRecord r = mStackSupervisor.activityIdleInternalLocked(token,
1248 false /* fromTimeout */, false /* processPausingActivities */, config);
1249 if (r != null) {
1250 proc = r.app;
1251 }
1252 if (stopProfiling && proc != null) {
1253 proc.clearProfilerIfNeeded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001254 }
1255 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001256 } finally {
1257 Binder.restoreCallingIdentity(origId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001258 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001259 }
1260
1261 @Override
1262 public final void activityResumed(IBinder token) {
1263 final long origId = Binder.clearCallingIdentity();
1264 synchronized (mGlobalLock) {
1265 ActivityRecord.activityResumedLocked(token);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001266 mWindowManager.notifyAppResumedFinished(token);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001267 }
1268 Binder.restoreCallingIdentity(origId);
1269 }
1270
1271 @Override
1272 public final void activityPaused(IBinder token) {
1273 final long origId = Binder.clearCallingIdentity();
1274 synchronized (mGlobalLock) {
1275 ActivityStack stack = ActivityRecord.getStackLocked(token);
1276 if (stack != null) {
1277 stack.activityPausedLocked(token, false);
1278 }
1279 }
1280 Binder.restoreCallingIdentity(origId);
1281 }
1282
1283 @Override
1284 public final void activityStopped(IBinder token, Bundle icicle,
1285 PersistableBundle persistentState, CharSequence description) {
1286 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
1287
1288 // Refuse possible leaked file descriptors
1289 if (icicle != null && icicle.hasFileDescriptors()) {
1290 throw new IllegalArgumentException("File descriptors passed in Bundle");
1291 }
1292
1293 final long origId = Binder.clearCallingIdentity();
1294
1295 synchronized (mGlobalLock) {
1296 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1297 if (r != null) {
1298 r.activityStoppedLocked(icicle, persistentState, description);
1299 }
1300 }
1301
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001302 mAmInternal.trimApplications();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001303
1304 Binder.restoreCallingIdentity(origId);
1305 }
1306
1307 @Override
1308 public final void activityDestroyed(IBinder token) {
1309 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
1310 synchronized (mGlobalLock) {
1311 ActivityStack stack = ActivityRecord.getStackLocked(token);
1312 if (stack != null) {
1313 stack.activityDestroyedLocked(token, "activityDestroyed");
1314 }
1315 }
1316 }
1317
1318 @Override
1319 public final void activityRelaunched(IBinder token) {
1320 final long origId = Binder.clearCallingIdentity();
1321 synchronized (mGlobalLock) {
1322 mStackSupervisor.activityRelaunchedLocked(token);
1323 }
1324 Binder.restoreCallingIdentity(origId);
1325 }
1326
1327 public final void activitySlept(IBinder token) {
1328 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
1329
1330 final long origId = Binder.clearCallingIdentity();
1331
1332 synchronized (mGlobalLock) {
1333 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1334 if (r != null) {
1335 mStackSupervisor.activitySleptLocked(r);
1336 }
1337 }
1338
1339 Binder.restoreCallingIdentity(origId);
1340 }
1341
1342 @Override
1343 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
1344 synchronized (mGlobalLock) {
1345 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1346 if (r == null) {
1347 return;
1348 }
1349 final long origId = Binder.clearCallingIdentity();
1350 try {
1351 r.setRequestedOrientation(requestedOrientation);
1352 } finally {
1353 Binder.restoreCallingIdentity(origId);
1354 }
1355 }
1356 }
1357
1358 @Override
1359 public int getRequestedOrientation(IBinder token) {
1360 synchronized (mGlobalLock) {
1361 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1362 if (r == null) {
1363 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
1364 }
1365 return r.getRequestedOrientation();
1366 }
1367 }
1368
1369 @Override
1370 public void setImmersive(IBinder token, boolean immersive) {
1371 synchronized (mGlobalLock) {
1372 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1373 if (r == null) {
1374 throw new IllegalArgumentException();
1375 }
1376 r.immersive = immersive;
1377
1378 // update associated state if we're frontmost
Andrii Kulian52d255c2018-07-13 11:32:19 -07001379 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001380 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001381 applyUpdateLockStateLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001382 }
1383 }
1384 }
1385
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001386 void applyUpdateLockStateLocked(ActivityRecord r) {
1387 // Modifications to the UpdateLock state are done on our handler, outside
1388 // the activity manager's locks. The new state is determined based on the
1389 // state *now* of the relevant activity record. The object is passed to
1390 // the handler solely for logging detail, not to be consulted/modified.
1391 final boolean nextState = r != null && r.immersive;
1392 mH.post(() -> {
1393 if (mUpdateLock.isHeld() != nextState) {
1394 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1395 "Applying new update lock state '" + nextState + "' for " + r);
1396 if (nextState) {
1397 mUpdateLock.acquire();
1398 } else {
1399 mUpdateLock.release();
1400 }
1401 }
1402 });
1403 }
1404
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001405 @Override
1406 public boolean isImmersive(IBinder token) {
1407 synchronized (mGlobalLock) {
1408 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1409 if (r == null) {
1410 throw new IllegalArgumentException();
1411 }
1412 return r.immersive;
1413 }
1414 }
1415
1416 @Override
1417 public boolean isTopActivityImmersive() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001418 enforceNotIsolatedCaller("isTopActivityImmersive");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001419 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001420 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001421 return (r != null) ? r.immersive : false;
1422 }
1423 }
1424
1425 @Override
1426 public void overridePendingTransition(IBinder token, String packageName,
1427 int enterAnim, int exitAnim) {
1428 synchronized (mGlobalLock) {
1429 ActivityRecord self = ActivityRecord.isInStackLocked(token);
1430 if (self == null) {
1431 return;
1432 }
1433
1434 final long origId = Binder.clearCallingIdentity();
1435
1436 if (self.isState(
1437 ActivityStack.ActivityState.RESUMED, ActivityStack.ActivityState.PAUSING)) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001438 mWindowManager.overridePendingAppTransition(packageName,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001439 enterAnim, exitAnim, null);
1440 }
1441
1442 Binder.restoreCallingIdentity(origId);
1443 }
1444 }
1445
1446 @Override
1447 public int getFrontActivityScreenCompatMode() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001448 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
1449 ApplicationInfo ai;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001450 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001451 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001452 if (r == null) {
1453 return ActivityManager.COMPAT_MODE_UNKNOWN;
1454 }
1455 ai = r.info.applicationInfo;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001456 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001457
1458 return mAmInternal.getPackageScreenCompatMode(ai);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001459 }
1460
1461 @Override
1462 public void setFrontActivityScreenCompatMode(int mode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001463 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001464 "setFrontActivityScreenCompatMode");
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001465 ApplicationInfo ai;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001466 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001467 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001468 if (r == null) {
1469 Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity");
1470 return;
1471 }
1472 ai = r.info.applicationInfo;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001473 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001474
1475 mAmInternal.setPackageScreenCompatMode(ai, mode);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001476 }
1477
1478 @Override
1479 public int getLaunchedFromUid(IBinder activityToken) {
1480 ActivityRecord srec;
1481 synchronized (mGlobalLock) {
1482 srec = ActivityRecord.forTokenLocked(activityToken);
1483 }
1484 if (srec == null) {
1485 return -1;
1486 }
1487 return srec.launchedFromUid;
1488 }
1489
1490 @Override
1491 public String getLaunchedFromPackage(IBinder activityToken) {
1492 ActivityRecord srec;
1493 synchronized (mGlobalLock) {
1494 srec = ActivityRecord.forTokenLocked(activityToken);
1495 }
1496 if (srec == null) {
1497 return null;
1498 }
1499 return srec.launchedFromPackage;
1500 }
1501
1502 @Override
1503 public boolean convertFromTranslucent(IBinder token) {
1504 final long origId = Binder.clearCallingIdentity();
1505 try {
1506 synchronized (mGlobalLock) {
1507 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1508 if (r == null) {
1509 return false;
1510 }
1511 final boolean translucentChanged = r.changeWindowTranslucency(true);
1512 if (translucentChanged) {
1513 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
1514 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001515 mWindowManager.setAppFullscreen(token, true);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001516 return translucentChanged;
1517 }
1518 } finally {
1519 Binder.restoreCallingIdentity(origId);
1520 }
1521 }
1522
1523 @Override
1524 public boolean convertToTranslucent(IBinder token, Bundle options) {
1525 SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
1526 final long origId = Binder.clearCallingIdentity();
1527 try {
1528 synchronized (mGlobalLock) {
1529 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1530 if (r == null) {
1531 return false;
1532 }
1533 final TaskRecord task = r.getTask();
1534 int index = task.mActivities.lastIndexOf(r);
1535 if (index > 0) {
1536 ActivityRecord under = task.mActivities.get(index - 1);
1537 under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
1538 }
1539 final boolean translucentChanged = r.changeWindowTranslucency(false);
1540 if (translucentChanged) {
1541 r.getStack().convertActivityToTranslucent(r);
1542 }
1543 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001544 mWindowManager.setAppFullscreen(token, false);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001545 return translucentChanged;
1546 }
1547 } finally {
1548 Binder.restoreCallingIdentity(origId);
1549 }
1550 }
1551
1552 @Override
1553 public void notifyActivityDrawn(IBinder token) {
1554 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
1555 synchronized (mGlobalLock) {
1556 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
1557 if (r != null) {
1558 r.getStack().notifyActivityDrawnLocked(r);
1559 }
1560 }
1561 }
1562
1563 @Override
1564 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
1565 synchronized (mGlobalLock) {
1566 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1567 if (r == null) {
1568 return;
1569 }
1570 r.reportFullyDrawnLocked(restoredFromBundle);
1571 }
1572 }
1573
1574 @Override
1575 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
1576 synchronized (mGlobalLock) {
1577 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
1578 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
1579 return stack.mDisplayId;
1580 }
1581 return DEFAULT_DISPLAY;
1582 }
1583 }
1584
1585 @Override
1586 public ActivityManager.StackInfo getFocusedStackInfo() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001587 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001588 long ident = Binder.clearCallingIdentity();
1589 try {
1590 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001591 ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001592 if (focusedStack != null) {
1593 return mStackSupervisor.getStackInfo(focusedStack.mStackId);
1594 }
1595 return null;
1596 }
1597 } finally {
1598 Binder.restoreCallingIdentity(ident);
1599 }
1600 }
1601
1602 @Override
1603 public void setFocusedStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001604 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001605 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
1606 final long callingId = Binder.clearCallingIdentity();
1607 try {
1608 synchronized (mGlobalLock) {
1609 final ActivityStack stack = mStackSupervisor.getStack(stackId);
1610 if (stack == null) {
1611 Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
1612 return;
1613 }
1614 final ActivityRecord r = stack.topRunningActivityLocked();
1615 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
1616 r, "setFocusedStack")) {
1617 mStackSupervisor.resumeFocusedStackTopActivityLocked();
1618 }
1619 }
1620 } finally {
1621 Binder.restoreCallingIdentity(callingId);
1622 }
1623 }
1624
1625 @Override
1626 public void setFocusedTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001627 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001628 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
1629 final long callingId = Binder.clearCallingIdentity();
1630 try {
1631 synchronized (mGlobalLock) {
1632 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1633 if (task == null) {
1634 return;
1635 }
1636 final ActivityRecord r = task.topRunningActivityLocked();
1637 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
1638 mStackSupervisor.resumeFocusedStackTopActivityLocked();
1639 }
1640 }
1641 } finally {
1642 Binder.restoreCallingIdentity(callingId);
1643 }
1644 }
1645
1646 @Override
1647 public boolean removeTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001648 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001649 synchronized (mGlobalLock) {
1650 final long ident = Binder.clearCallingIdentity();
1651 try {
1652 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
1653 "remove-task");
1654 } finally {
1655 Binder.restoreCallingIdentity(ident);
1656 }
1657 }
1658 }
1659
1660 @Override
1661 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
1662 synchronized (mGlobalLock) {
1663 final ActivityRecord srec = ActivityRecord.forTokenLocked(token);
1664 if (srec != null) {
1665 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
1666 }
1667 }
1668 return false;
1669 }
1670
1671 @Override
1672 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
1673 Intent resultData) {
1674
1675 synchronized (mGlobalLock) {
1676 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
1677 if (r != null) {
1678 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
1679 }
1680 return false;
1681 }
1682 }
1683
1684 /**
1685 * Attempts to move a task backwards in z-order (the order of activities within the task is
1686 * unchanged).
1687 *
1688 * There are several possible results of this call:
1689 * - if the task is locked, then we will show the lock toast
1690 * - if there is a task behind the provided task, then that task is made visible and resumed as
1691 * this task is moved to the back
1692 * - otherwise, if there are no other tasks in the stack:
1693 * - if this task is in the pinned stack, then we remove the stack completely, which will
1694 * have the effect of moving the task to the top or bottom of the fullscreen stack
1695 * (depending on whether it is visible)
1696 * - otherwise, we simply return home and hide this task
1697 *
1698 * @param token A reference to the activity we wish to move
1699 * @param nonRoot If false then this only works if the activity is the root
1700 * of a task; if true it will work for any activity in a task.
1701 * @return Returns true if the move completed, false if not.
1702 */
1703 @Override
1704 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001705 enforceNotIsolatedCaller("moveActivityTaskToBack");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001706 synchronized (mGlobalLock) {
1707 final long origId = Binder.clearCallingIdentity();
1708 try {
1709 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
1710 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1711 if (task != null) {
1712 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
1713 }
1714 } finally {
1715 Binder.restoreCallingIdentity(origId);
1716 }
1717 }
1718 return false;
1719 }
1720
1721 @Override
1722 public Rect getTaskBounds(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001723 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001724 long ident = Binder.clearCallingIdentity();
1725 Rect rect = new Rect();
1726 try {
1727 synchronized (mGlobalLock) {
1728 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
1729 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1730 if (task == null) {
1731 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
1732 return rect;
1733 }
1734 if (task.getStack() != null) {
1735 // Return the bounds from window manager since it will be adjusted for various
1736 // things like the presense of a docked stack for tasks that aren't resizeable.
1737 task.getWindowContainerBounds(rect);
1738 } else {
1739 // Task isn't in window manager yet since it isn't associated with a stack.
1740 // Return the persist value from activity manager
1741 if (!task.matchParentBounds()) {
1742 rect.set(task.getBounds());
1743 } else if (task.mLastNonFullscreenBounds != null) {
1744 rect.set(task.mLastNonFullscreenBounds);
1745 }
1746 }
1747 }
1748 } finally {
1749 Binder.restoreCallingIdentity(ident);
1750 }
1751 return rect;
1752 }
1753
1754 @Override
1755 public ActivityManager.TaskDescription getTaskDescription(int id) {
1756 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001757 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001758 MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
1759 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
1760 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1761 if (tr != null) {
1762 return tr.lastTaskDescription;
1763 }
1764 }
1765 return null;
1766 }
1767
1768 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001769 public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
1770 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
1771 setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
1772 toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
1773 return;
1774 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001775 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001776 synchronized (mGlobalLock) {
1777 final long ident = Binder.clearCallingIdentity();
1778 try {
1779 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1780 if (task == null) {
1781 Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
1782 return;
1783 }
1784
1785 if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
1786 + " to windowingMode=" + windowingMode + " toTop=" + toTop);
1787
1788 if (!task.isActivityTypeStandardOrUndefined()) {
1789 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
1790 + " non-standard task " + taskId + " to windowing mode="
1791 + windowingMode);
1792 }
1793
1794 final ActivityStack stack = task.getStack();
1795 if (toTop) {
1796 stack.moveToFront("setTaskWindowingMode", task);
1797 }
1798 stack.setWindowingMode(windowingMode);
1799 } finally {
1800 Binder.restoreCallingIdentity(ident);
1801 }
1802 }
1803 }
1804
1805 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001806 public String getCallingPackage(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001807 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001808 ActivityRecord r = getCallingRecordLocked(token);
1809 return r != null ? r.info.packageName : null;
1810 }
1811 }
1812
1813 @Override
1814 public ComponentName getCallingActivity(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001815 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001816 ActivityRecord r = getCallingRecordLocked(token);
1817 return r != null ? r.intent.getComponent() : null;
1818 }
1819 }
1820
1821 private ActivityRecord getCallingRecordLocked(IBinder token) {
1822 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1823 if (r == null) {
1824 return null;
1825 }
1826 return r.resultTo;
1827 }
1828
1829 @Override
1830 public void unhandledBack() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001831 mAmInternal.enforceCallingPermission(android.Manifest.permission.FORCE_BACK, "unhandledBack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001832
1833 synchronized (mGlobalLock) {
1834 final long origId = Binder.clearCallingIdentity();
1835 try {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001836 getTopDisplayFocusedStack().unhandledBackLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001837 } finally {
1838 Binder.restoreCallingIdentity(origId);
1839 }
1840 }
1841 }
1842
1843 /**
1844 * TODO: Add mController hook
1845 */
1846 @Override
1847 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001848 mAmInternal.enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001849
1850 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
1851 synchronized (mGlobalLock) {
1852 moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
1853 false /* fromRecents */);
1854 }
1855 }
1856
1857 void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
1858 boolean fromRecents) {
1859
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001860 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001861 Binder.getCallingUid(), -1, -1, "Task to front")) {
1862 SafeActivityOptions.abort(options);
1863 return;
1864 }
1865 final long origId = Binder.clearCallingIdentity();
1866 try {
1867 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1868 if (task == null) {
1869 Slog.d(TAG, "Could not find task for id: "+ taskId);
1870 return;
1871 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001872 if (getLockTaskController().isLockTaskModeViolation(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001873 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
1874 return;
1875 }
1876 ActivityOptions realOptions = options != null
1877 ? options.getOptions(mStackSupervisor)
1878 : null;
1879 mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
1880 false /* forceNonResizable */);
1881
1882 final ActivityRecord topActivity = task.getTopActivity();
1883 if (topActivity != null) {
1884
1885 // We are reshowing a task, use a starting window to hide the initial draw delay
1886 // so the transition can start earlier.
1887 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
1888 true /* taskSwitch */, fromRecents);
1889 }
1890 } finally {
1891 Binder.restoreCallingIdentity(origId);
1892 }
1893 SafeActivityOptions.abort(options);
1894 }
1895
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001896 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
1897 int callingPid, int callingUid, String name) {
1898 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
1899 return true;
1900 }
1901
1902 if (getRecentTasks().isCallerRecents(sourceUid)) {
1903 return true;
1904 }
1905
1906 int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
1907 if (perm == PackageManager.PERMISSION_GRANTED) {
1908 return true;
1909 }
1910 if (checkAllowAppSwitchUid(sourceUid)) {
1911 return true;
1912 }
1913
1914 // If the actual IPC caller is different from the logical source, then
1915 // also see if they are allowed to control app switches.
1916 if (callingUid != -1 && callingUid != sourceUid) {
1917 perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
1918 if (perm == PackageManager.PERMISSION_GRANTED) {
1919 return true;
1920 }
1921 if (checkAllowAppSwitchUid(callingUid)) {
1922 return true;
1923 }
1924 }
1925
1926 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
1927 return false;
1928 }
1929
1930 private boolean checkAllowAppSwitchUid(int uid) {
1931 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
1932 if (types != null) {
1933 for (int i = types.size() - 1; i >= 0; i--) {
1934 if (types.valueAt(i).intValue() == uid) {
1935 return true;
1936 }
1937 }
1938 }
1939 return false;
1940 }
1941
1942 @Override
1943 public void setActivityController(IActivityController controller, boolean imAMonkey) {
1944 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
1945 "setActivityController()");
1946 synchronized (mGlobalLock) {
1947 mController = controller;
1948 mControllerIsAMonkey = imAMonkey;
1949 Watchdog.getInstance().setActivityController(controller);
1950 }
1951 }
1952
1953 boolean isControllerAMonkey() {
1954 synchronized (mGlobalLock) {
1955 return mController != null && mControllerIsAMonkey;
1956 }
1957 }
1958
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001959 @Override
1960 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
1961 synchronized (mGlobalLock) {
1962 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
1963 }
1964 }
1965
1966 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001967 public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum) {
1968 return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
1969 }
1970
1971 @Override
1972 public List<ActivityManager.RunningTaskInfo> getFilteredTasks(int maxNum,
1973 @WindowConfiguration.ActivityType int ignoreActivityType,
1974 @WindowConfiguration.WindowingMode int ignoreWindowingMode) {
1975 final int callingUid = Binder.getCallingUid();
1976 ArrayList<ActivityManager.RunningTaskInfo> list = new ArrayList<>();
1977
1978 synchronized (mGlobalLock) {
1979 if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
1980
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001981 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001982 callingUid);
1983 mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
1984 ignoreWindowingMode, callingUid, allowed);
1985 }
1986
1987 return list;
1988 }
1989
1990 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001991 public final void finishSubActivity(IBinder token, String resultWho, int requestCode) {
1992 synchronized (mGlobalLock) {
1993 final long origId = Binder.clearCallingIdentity();
1994 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1995 if (r != null) {
1996 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
1997 }
1998 Binder.restoreCallingIdentity(origId);
1999 }
2000 }
2001
2002 @Override
2003 public boolean willActivityBeVisible(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002004 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002005 ActivityStack stack = ActivityRecord.getStackLocked(token);
2006 if (stack != null) {
2007 return stack.willActivityBeVisibleLocked(token);
2008 }
2009 return false;
2010 }
2011 }
2012
2013 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002014 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002015 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002016 synchronized (mGlobalLock) {
2017 final long ident = Binder.clearCallingIdentity();
2018 try {
2019 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2020 if (task == null) {
2021 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
2022 return;
2023 }
2024
2025 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
2026 + " to stackId=" + stackId + " toTop=" + toTop);
2027
2028 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2029 if (stack == null) {
2030 throw new IllegalStateException(
2031 "moveTaskToStack: No stack for stackId=" + stackId);
2032 }
2033 if (!stack.isActivityTypeStandardOrUndefined()) {
2034 throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
2035 + taskId + " to stack " + stackId);
2036 }
2037 if (stack.inSplitScreenPrimaryWindowingMode()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002038 mWindowManager.setDockedStackCreateState(
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002039 SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
2040 }
2041 task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
2042 "moveTaskToStack");
2043 } finally {
2044 Binder.restoreCallingIdentity(ident);
2045 }
2046 }
2047 }
2048
2049 @Override
2050 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
2051 boolean preserveWindows, boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002052 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002053
2054 final long ident = Binder.clearCallingIdentity();
2055 try {
2056 synchronized (mGlobalLock) {
2057 if (animate) {
2058 final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
2059 if (stack == null) {
2060 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2061 return;
2062 }
2063 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
2064 throw new IllegalArgumentException("Stack: " + stackId
2065 + " doesn't support animated resize.");
2066 }
2067 stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
2068 animationDuration, false /* fromFullscreen */);
2069 } else {
2070 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2071 if (stack == null) {
2072 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2073 return;
2074 }
2075 mStackSupervisor.resizeStackLocked(stack, destBounds,
2076 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
2077 preserveWindows, allowResizeInDockedMode, !DEFER_RESUME);
2078 }
2079 }
2080 } finally {
2081 Binder.restoreCallingIdentity(ident);
2082 }
2083 }
2084
2085 /**
2086 * Moves the specified task to the primary-split-screen stack.
2087 *
2088 * @param taskId Id of task to move.
2089 * @param createMode The mode the primary split screen stack should be created in if it doesn't
2090 * exist already. See
2091 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
2092 * and
2093 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
2094 * @param toTop If the task and stack should be moved to the top.
2095 * @param animate Whether we should play an animation for the moving the task.
2096 * @param initialBounds If the primary stack gets created, it will use these bounds for the
2097 * stack. Pass {@code null} to use default bounds.
2098 * @param showRecents If the recents activity should be shown on the other side of the task
2099 * going into split-screen mode.
2100 */
2101 @Override
2102 public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode,
2103 boolean toTop, boolean animate, Rect initialBounds, boolean showRecents) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002104 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002105 "setTaskWindowingModeSplitScreenPrimary()");
2106 synchronized (mGlobalLock) {
2107 final long ident = Binder.clearCallingIdentity();
2108 try {
2109 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2110 if (task == null) {
2111 Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
2112 return false;
2113 }
2114 if (DEBUG_STACK) Slog.d(TAG_STACK,
2115 "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
2116 + " to createMode=" + createMode + " toTop=" + toTop);
2117 if (!task.isActivityTypeStandardOrUndefined()) {
2118 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
2119 + " non-standard task " + taskId + " to split-screen windowing mode");
2120 }
2121
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002122 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002123 final int windowingMode = task.getWindowingMode();
2124 final ActivityStack stack = task.getStack();
2125 if (toTop) {
2126 stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
2127 }
2128 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
2129 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */);
2130 return windowingMode != task.getWindowingMode();
2131 } finally {
2132 Binder.restoreCallingIdentity(ident);
2133 }
2134 }
2135 }
2136
2137 /**
2138 * Removes stacks in the input windowing modes from the system if they are of activity type
2139 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
2140 */
2141 @Override
2142 public void removeStacksInWindowingModes(int[] windowingModes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002143 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002144 "removeStacksInWindowingModes()");
2145
2146 synchronized (mGlobalLock) {
2147 final long ident = Binder.clearCallingIdentity();
2148 try {
2149 mStackSupervisor.removeStacksInWindowingModes(windowingModes);
2150 } finally {
2151 Binder.restoreCallingIdentity(ident);
2152 }
2153 }
2154 }
2155
2156 @Override
2157 public void removeStacksWithActivityTypes(int[] activityTypes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002158 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002159 "removeStacksWithActivityTypes()");
2160
2161 synchronized (mGlobalLock) {
2162 final long ident = Binder.clearCallingIdentity();
2163 try {
2164 mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
2165 } finally {
2166 Binder.restoreCallingIdentity(ident);
2167 }
2168 }
2169 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002170
2171 @Override
2172 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
2173 int userId) {
2174 final int callingUid = Binder.getCallingUid();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002175 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, "getRecentTasks");
2176 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002177 callingUid);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002178 final boolean detailed = checkGetTasksPermission(
2179 android.Manifest.permission.GET_DETAILED_TASKS, Binder.getCallingPid(),
2180 UserHandle.getAppId(callingUid))
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002181 == PackageManager.PERMISSION_GRANTED;
2182
2183 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002184 return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002185 callingUid);
2186 }
2187 }
2188
2189 @Override
2190 public List<ActivityManager.StackInfo> getAllStackInfos() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002191 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002192 long ident = Binder.clearCallingIdentity();
2193 try {
2194 synchronized (mGlobalLock) {
2195 return mStackSupervisor.getAllStackInfosLocked();
2196 }
2197 } finally {
2198 Binder.restoreCallingIdentity(ident);
2199 }
2200 }
2201
2202 @Override
2203 public ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002204 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002205 long ident = Binder.clearCallingIdentity();
2206 try {
2207 synchronized (mGlobalLock) {
2208 return mStackSupervisor.getStackInfo(windowingMode, activityType);
2209 }
2210 } finally {
2211 Binder.restoreCallingIdentity(ident);
2212 }
2213 }
2214
2215 @Override
2216 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002217 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002218 final long callingUid = Binder.getCallingUid();
2219 final long origId = Binder.clearCallingIdentity();
2220 try {
2221 synchronized (mGlobalLock) {
2222 // Cancel the recents animation synchronously (do not hold the WM lock)
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002223 mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002224 ? REORDER_MOVE_TO_ORIGINAL_POSITION
2225 : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
2226 }
2227 } finally {
2228 Binder.restoreCallingIdentity(origId);
2229 }
2230 }
2231
2232 @Override
2233 public void startLockTaskModeByToken(IBinder token) {
2234 synchronized (mGlobalLock) {
2235 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2236 if (r == null) {
2237 return;
2238 }
2239 startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
2240 }
2241 }
2242
2243 @Override
2244 public void startSystemLockTaskMode(int taskId) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002245 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002246 // This makes inner call to look as if it was initiated by system.
2247 long ident = Binder.clearCallingIdentity();
2248 try {
2249 synchronized (mGlobalLock) {
2250 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2251
2252 // When starting lock task mode the stack must be in front and focused
2253 task.getStack().moveToFront("startSystemLockTaskMode");
2254 startLockTaskModeLocked(task, true /* isSystemCaller */);
2255 }
2256 } finally {
2257 Binder.restoreCallingIdentity(ident);
2258 }
2259 }
2260
2261 @Override
2262 public void stopLockTaskModeByToken(IBinder token) {
2263 synchronized (mGlobalLock) {
2264 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2265 if (r == null) {
2266 return;
2267 }
2268 stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
2269 }
2270 }
2271
2272 /**
2273 * This API should be called by SystemUI only when user perform certain action to dismiss
2274 * lock task mode. We should only dismiss pinned lock task mode in this case.
2275 */
2276 @Override
2277 public void stopSystemLockTaskMode() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002278 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002279 stopLockTaskModeInternal(null, true /* isSystemCaller */);
2280 }
2281
2282 private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
2283 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
2284 if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
2285 return;
2286 }
2287
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002288 final ActivityStack stack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002289 if (stack == null || task != stack.topTask()) {
2290 throw new IllegalArgumentException("Invalid task, not in foreground");
2291 }
2292
2293 // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
2294 // system or a specific app.
2295 // * System-initiated requests will only start the pinned mode (screen pinning)
2296 // * App-initiated requests
2297 // - will put the device in fully locked mode (LockTask), if the app is whitelisted
2298 // - will start the pinned mode, otherwise
2299 final int callingUid = Binder.getCallingUid();
2300 long ident = Binder.clearCallingIdentity();
2301 try {
2302 // When a task is locked, dismiss the pinned stack if it exists
2303 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2304
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002305 getLockTaskController().startLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002306 } finally {
2307 Binder.restoreCallingIdentity(ident);
2308 }
2309 }
2310
2311 private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
2312 final int callingUid = Binder.getCallingUid();
2313 long ident = Binder.clearCallingIdentity();
2314 try {
2315 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002316 getLockTaskController().stopLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002317 }
2318 // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
2319 // task and jumping straight into a call in the case of emergency call back.
2320 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
2321 if (tm != null) {
2322 tm.showInCallScreen(false);
2323 }
2324 } finally {
2325 Binder.restoreCallingIdentity(ident);
2326 }
2327 }
2328
2329 @Override
2330 public boolean isInLockTaskMode() {
2331 return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
2332 }
2333
2334 @Override
2335 public int getLockTaskModeState() {
2336 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002337 return getLockTaskController().getLockTaskModeState();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002338 }
2339 }
2340
2341 @Override
2342 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
2343 synchronized (mGlobalLock) {
2344 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2345 if (r != null) {
2346 r.setTaskDescription(td);
2347 final TaskRecord task = r.getTask();
2348 task.updateTaskDescription();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002349 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002350 }
2351 }
2352 }
2353
2354 @Override
2355 public Bundle getActivityOptions(IBinder token) {
2356 final long origId = Binder.clearCallingIdentity();
2357 try {
2358 synchronized (mGlobalLock) {
2359 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
2360 if (r != null) {
2361 final ActivityOptions activityOptions = r.takeOptionsLocked();
2362 return activityOptions == null ? null : activityOptions.toBundle();
2363 }
2364 return null;
2365 }
2366 } finally {
2367 Binder.restoreCallingIdentity(origId);
2368 }
2369 }
2370
2371 @Override
2372 public List<IBinder> getAppTasks(String callingPackage) {
2373 int callingUid = Binder.getCallingUid();
2374 long ident = Binder.clearCallingIdentity();
2375 try {
2376 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002377 return mRecentTasks.getAppTasksList(callingUid, callingPackage);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002378 }
2379 } finally {
2380 Binder.restoreCallingIdentity(ident);
2381 }
2382 }
2383
2384 @Override
2385 public void finishVoiceTask(IVoiceInteractionSession session) {
2386 synchronized (mGlobalLock) {
2387 final long origId = Binder.clearCallingIdentity();
2388 try {
2389 // TODO: VI Consider treating local voice interactions and voice tasks
2390 // differently here
2391 mStackSupervisor.finishVoiceTask(session);
2392 } finally {
2393 Binder.restoreCallingIdentity(origId);
2394 }
2395 }
2396
2397 }
2398
2399 @Override
2400 public boolean isTopOfTask(IBinder token) {
2401 synchronized (mGlobalLock) {
2402 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2403 if (r == null) {
2404 throw new IllegalArgumentException();
2405 }
2406 return r.getTask().getTopActivity() == r;
2407 }
2408 }
2409
2410 @Override
2411 public void notifyLaunchTaskBehindComplete(IBinder token) {
2412 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
2413 }
2414
2415 @Override
2416 public void notifyEnterAnimationComplete(IBinder token) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002417 mH.post(() -> {
2418 synchronized (mGlobalLock) {
2419 ActivityRecord r = ActivityRecord.forTokenLocked(token);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002420 if (r != null && r.attachedToProcess()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002421 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002422 r.app.getThread().scheduleEnterAnimationComplete(r.appToken);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002423 } catch (RemoteException e) {
2424 }
2425 }
2426 }
2427
2428 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002429 }
2430
2431 /** Called from an app when assist data is ready. */
2432 @Override
2433 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
2434 AssistContent content, Uri referrer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002435 PendingAssistExtras pae = (PendingAssistExtras) token;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002436 synchronized (pae) {
2437 pae.result = extras;
2438 pae.structure = structure;
2439 pae.content = content;
2440 if (referrer != null) {
2441 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
2442 }
2443 if (structure != null) {
2444 structure.setHomeActivity(pae.isHome);
2445 }
2446 pae.haveResult = true;
2447 pae.notifyAll();
2448 if (pae.intent == null && pae.receiver == null) {
2449 // Caller is just waiting for the result.
2450 return;
2451 }
2452 }
2453 // We are now ready to launch the assist activity.
2454 IAssistDataReceiver sendReceiver = null;
2455 Bundle sendBundle = null;
2456 synchronized (mGlobalLock) {
2457 buildAssistBundleLocked(pae, extras);
2458 boolean exists = mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002459 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002460 if (!exists) {
2461 // Timed out.
2462 return;
2463 }
2464
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002465 if ((sendReceiver = pae.receiver) != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002466 // Caller wants result sent back to them.
2467 sendBundle = new Bundle();
2468 sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
2469 sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
2470 sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
2471 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
2472 }
2473 }
2474 if (sendReceiver != null) {
2475 try {
2476 sendReceiver.onHandleAssistData(sendBundle);
2477 } catch (RemoteException e) {
2478 }
2479 return;
2480 }
2481
2482 final long ident = Binder.clearCallingIdentity();
2483 try {
2484 if (TextUtils.equals(pae.intent.getAction(),
2485 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
2486 pae.intent.putExtras(pae.extras);
2487 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
2488 } else {
2489 pae.intent.replaceExtras(pae.extras);
2490 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
2491 | Intent.FLAG_ACTIVITY_SINGLE_TOP
2492 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002493 mAmInternal.closeSystemDialogs("assist");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002494
2495 try {
2496 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
2497 } catch (ActivityNotFoundException e) {
2498 Slog.w(TAG, "No activity to handle assist action.", e);
2499 }
2500 }
2501 } finally {
2502 Binder.restoreCallingIdentity(ident);
2503 }
2504 }
2505
2506 @Override
2507 public int addAppTask(IBinder activityToken, Intent intent,
2508 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
2509 final int callingUid = Binder.getCallingUid();
2510 final long callingIdent = Binder.clearCallingIdentity();
2511
2512 try {
2513 synchronized (mGlobalLock) {
2514 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
2515 if (r == null) {
2516 throw new IllegalArgumentException("Activity does not exist; token="
2517 + activityToken);
2518 }
2519 ComponentName comp = intent.getComponent();
2520 if (comp == null) {
2521 throw new IllegalArgumentException("Intent " + intent
2522 + " must specify explicit component");
2523 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002524 if (thumbnail.getWidth() != mThumbnailWidth
2525 || thumbnail.getHeight() != mThumbnailHeight) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002526 throw new IllegalArgumentException("Bad thumbnail size: got "
2527 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002528 + mThumbnailWidth + "x" + mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002529 }
2530 if (intent.getSelector() != null) {
2531 intent.setSelector(null);
2532 }
2533 if (intent.getSourceBounds() != null) {
2534 intent.setSourceBounds(null);
2535 }
2536 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
2537 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
2538 // The caller has added this as an auto-remove task... that makes no
2539 // sense, so turn off auto-remove.
2540 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
2541 }
2542 }
2543 final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
2544 STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
2545 if (ainfo.applicationInfo.uid != callingUid) {
2546 throw new SecurityException(
2547 "Can't add task for another application: target uid="
2548 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
2549 }
2550
2551 final ActivityStack stack = r.getStack();
2552 final TaskRecord task = stack.createTaskRecord(
2553 mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent,
2554 null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002555 if (!mRecentTasks.addToBottom(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002556 // The app has too many tasks already and we can't add any more
2557 stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
2558 return INVALID_TASK_ID;
2559 }
2560 task.lastTaskDescription.copyFrom(description);
2561
2562 // TODO: Send the thumbnail to WM to store it.
2563
2564 return task.taskId;
2565 }
2566 } finally {
2567 Binder.restoreCallingIdentity(callingIdent);
2568 }
2569 }
2570
2571 @Override
2572 public Point getAppTaskThumbnailSize() {
2573 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002574 return new Point(mThumbnailWidth, mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002575 }
2576 }
2577
2578 @Override
2579 public void setTaskResizeable(int taskId, int resizeableMode) {
2580 synchronized (mGlobalLock) {
2581 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
2582 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
2583 if (task == null) {
2584 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
2585 return;
2586 }
2587 task.setResizeMode(resizeableMode);
2588 }
2589 }
2590
2591 @Override
2592 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002593 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002594 long ident = Binder.clearCallingIdentity();
2595 try {
2596 synchronized (mGlobalLock) {
2597 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2598 if (task == null) {
2599 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
2600 return;
2601 }
2602 // Place the task in the right stack if it isn't there already based on
2603 // the requested bounds.
2604 // The stack transition logic is:
2605 // - a null bounds on a freeform task moves that task to fullscreen
2606 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
2607 // that task to freeform
2608 // - otherwise the task is not moved
2609 ActivityStack stack = task.getStack();
2610 if (!task.getWindowConfiguration().canResizeTask()) {
2611 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
2612 }
2613 if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
2614 stack = stack.getDisplay().getOrCreateStack(
2615 WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
2616 } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
2617 stack = stack.getDisplay().getOrCreateStack(
2618 WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
2619 }
2620
2621 // Reparent the task to the right stack if necessary
2622 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
2623 if (stack != task.getStack()) {
2624 // Defer resume until the task is resized below
2625 task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
2626 DEFER_RESUME, "resizeTask");
2627 preserveWindow = false;
2628 }
2629
2630 // After reparenting (which only resizes the task to the stack bounds), resize the
2631 // task to the actual bounds provided
2632 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
2633 }
2634 } finally {
2635 Binder.restoreCallingIdentity(ident);
2636 }
2637 }
2638
2639 @Override
2640 public boolean releaseActivityInstance(IBinder token) {
2641 synchronized (mGlobalLock) {
2642 final long origId = Binder.clearCallingIdentity();
2643 try {
2644 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2645 if (r == null) {
2646 return false;
2647 }
2648 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
2649 } finally {
2650 Binder.restoreCallingIdentity(origId);
2651 }
2652 }
2653 }
2654
2655 @Override
2656 public void releaseSomeActivities(IApplicationThread appInt) {
2657 synchronized (mGlobalLock) {
2658 final long origId = Binder.clearCallingIdentity();
2659 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002660 WindowProcessController app =
2661 mAm.getRecordForAppLocked(appInt).getWindowProcessController();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002662 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
2663 } finally {
2664 Binder.restoreCallingIdentity(origId);
2665 }
2666 }
2667 }
2668
2669 @Override
2670 public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
2671 int secondaryDisplayShowing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002672 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002673 != PackageManager.PERMISSION_GRANTED) {
2674 throw new SecurityException("Requires permission "
2675 + android.Manifest.permission.DEVICE_POWER);
2676 }
2677
2678 synchronized (mGlobalLock) {
2679 long ident = Binder.clearCallingIdentity();
2680 if (mKeyguardShown != keyguardShowing) {
2681 mKeyguardShown = keyguardShowing;
2682 reportCurKeyguardUsageEventLocked(keyguardShowing);
2683 }
2684 try {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002685 mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002686 secondaryDisplayShowing);
2687 } finally {
2688 Binder.restoreCallingIdentity(ident);
2689 }
2690 }
2691
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002692 mH.post(() -> {
2693 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2694 mScreenObservers.get(i).onKeyguardStateChanged(keyguardShowing);
2695 }
2696 });
2697 }
2698
2699 void onScreenAwakeChanged(boolean isAwake) {
2700 mH.post(() -> {
2701 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2702 mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2703 }
2704 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002705 }
2706
2707 @Override
2708 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002709 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
2710 userId, "getTaskDescriptionIcon");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002711
2712 final File passedIconFile = new File(filePath);
2713 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
2714 passedIconFile.getName());
2715 if (!legitIconFile.getPath().equals(filePath)
2716 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
2717 throw new IllegalArgumentException("Bad file path: " + filePath
2718 + " passed for userId " + userId);
2719 }
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002720 return mRecentTasks.getTaskDescriptionIcon(filePath);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002721 }
2722
2723 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002724 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002725 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
2726 final ActivityOptions activityOptions = safeOptions != null
2727 ? safeOptions.getOptions(mStackSupervisor)
2728 : null;
2729 if (activityOptions == null
2730 || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
2731 || activityOptions.getCustomInPlaceResId() == 0) {
2732 throw new IllegalArgumentException("Expected in-place ActivityOption " +
2733 "with valid animation");
2734 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002735 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
2736 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002737 activityOptions.getCustomInPlaceResId());
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002738 mWindowManager.executeAppTransition();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002739 }
2740
2741 @Override
2742 public void removeStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002743 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002744 synchronized (mGlobalLock) {
2745 final long ident = Binder.clearCallingIdentity();
2746 try {
2747 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2748 if (stack == null) {
2749 Slog.w(TAG, "removeStack: No stack with id=" + stackId);
2750 return;
2751 }
2752 if (!stack.isActivityTypeStandardOrUndefined()) {
2753 throw new IllegalArgumentException(
2754 "Removing non-standard stack is not allowed.");
2755 }
2756 mStackSupervisor.removeStack(stack);
2757 } finally {
2758 Binder.restoreCallingIdentity(ident);
2759 }
2760 }
2761 }
2762
2763 @Override
2764 public void moveStackToDisplay(int stackId, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002765 mAmInternal.enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002766
2767 synchronized (mGlobalLock) {
2768 final long ident = Binder.clearCallingIdentity();
2769 try {
2770 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
2771 + " to displayId=" + displayId);
2772 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
2773 } finally {
2774 Binder.restoreCallingIdentity(ident);
2775 }
2776 }
2777 }
2778
2779 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002780 public void exitFreeformMode(IBinder token) {
2781 synchronized (mGlobalLock) {
2782 long ident = Binder.clearCallingIdentity();
2783 try {
2784 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2785 if (r == null) {
2786 throw new IllegalArgumentException(
2787 "exitFreeformMode: No activity record matching token=" + token);
2788 }
2789
2790 final ActivityStack stack = r.getStack();
2791 if (stack == null || !stack.inFreeformWindowingMode()) {
2792 throw new IllegalStateException(
2793 "exitFreeformMode: You can only go fullscreen from freeform.");
2794 }
2795
2796 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
2797 } finally {
2798 Binder.restoreCallingIdentity(ident);
2799 }
2800 }
2801 }
2802
2803 /** Sets the task stack listener that gets callbacks when a task stack changes. */
2804 @Override
2805 public void registerTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002806 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002807 "registerTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002808 mTaskChangeNotificationController.registerTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002809 }
2810
2811 /** Unregister a task stack listener so that it stops receiving callbacks. */
2812 @Override
2813 public void unregisterTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002814 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002815 "unregisterTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002816 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002817 }
2818
2819 private void reportCurKeyguardUsageEventLocked(boolean keyguardShowing) {
2820 mAm.reportGlobalUsageEventLocked(keyguardShowing
2821 ? UsageEvents.Event.KEYGUARD_SHOWN
2822 : UsageEvents.Event.KEYGUARD_HIDDEN);
2823 }
2824
2825 @Override
2826 public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
2827 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
2828 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
2829 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
2830 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
2831 }
2832
2833 @Override
2834 public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
2835 IBinder activityToken, int flags) {
2836 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
2837 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
2838 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
2839 }
2840
2841 @Override
2842 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
2843 Bundle args) {
2844 return enqueueAssistContext(requestType, intent, hint, null, null, null,
2845 true /* focused */, true /* newSessionId */, userHandle, args,
2846 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
2847 }
2848
2849 @Override
2850 public Bundle getAssistContextExtras(int requestType) {
2851 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
2852 null, null, true /* focused */, true /* newSessionId */,
2853 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
2854 if (pae == null) {
2855 return null;
2856 }
2857 synchronized (pae) {
2858 while (!pae.haveResult) {
2859 try {
2860 pae.wait();
2861 } catch (InterruptedException e) {
2862 }
2863 }
2864 }
2865 synchronized (mGlobalLock) {
2866 buildAssistBundleLocked(pae, pae.result);
2867 mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002868 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002869 }
2870 return pae.extras;
2871 }
2872
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002873 /**
2874 * Binder IPC calls go through the public entry point.
2875 * This can be called with or without the global lock held.
2876 */
2877 private static int checkCallingPermission(String permission) {
2878 return checkPermission(
2879 permission, Binder.getCallingPid(), UserHandle.getAppId(Binder.getCallingUid()));
2880 }
2881
2882 /** This can be called with or without the global lock held. */
2883 void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
2884 if (!getRecentTasks().isCallerRecents(Binder.getCallingUid())) {
2885 mAmInternal.enforceCallingPermission(permission, func);
2886 }
2887 }
2888
2889 @VisibleForTesting
2890 int checkGetTasksPermission(String permission, int pid, int uid) {
2891 return checkPermission(permission, pid, uid);
2892 }
2893
2894 static int checkPermission(String permission, int pid, int uid) {
2895 if (permission == null) {
2896 return PackageManager.PERMISSION_DENIED;
2897 }
2898 return checkComponentPermission(permission, pid, uid, -1, true);
2899 }
2900
2901 boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
2902 if (getRecentTasks().isCallerRecents(callingUid)) {
2903 // Always allow the recents component to get tasks
2904 return true;
2905 }
2906
2907 boolean allowed = checkGetTasksPermission(android.Manifest.permission.REAL_GET_TASKS,
2908 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
2909 if (!allowed) {
2910 if (checkGetTasksPermission(android.Manifest.permission.GET_TASKS,
2911 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
2912 // Temporary compatibility: some existing apps on the system image may
2913 // still be requesting the old permission and not switched to the new
2914 // one; if so, we'll still allow them full access. This means we need
2915 // to see if they are holding the old permission and are a system app.
2916 try {
2917 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
2918 allowed = true;
2919 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
2920 + " is using old GET_TASKS but privileged; allowing");
2921 }
2922 } catch (RemoteException e) {
2923 }
2924 }
2925 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
2926 + " does not hold REAL_GET_TASKS; limiting output");
2927 }
2928 return allowed;
2929 }
2930
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002931 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
2932 IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
2933 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
2934 int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002935 mAmInternal.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002936 "enqueueAssistContext()");
2937
2938 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002939 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002940 if (activity == null) {
2941 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
2942 return null;
2943 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002944 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002945 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
2946 return null;
2947 }
2948 if (focused) {
2949 if (activityToken != null) {
2950 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
2951 if (activity != caller) {
2952 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
2953 + " is not current top " + activity);
2954 return null;
2955 }
2956 }
2957 } else {
2958 activity = ActivityRecord.forTokenLocked(activityToken);
2959 if (activity == null) {
2960 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
2961 + " couldn't be found");
2962 return null;
2963 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002964 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002965 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
2966 return null;
2967 }
2968 }
2969
2970 PendingAssistExtras pae;
2971 Bundle extras = new Bundle();
2972 if (args != null) {
2973 extras.putAll(args);
2974 }
2975 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002976 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002977
2978 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
2979 userHandle);
2980 pae.isHome = activity.isActivityTypeHome();
2981
2982 // Increment the sessionId if necessary
2983 if (newSessionId) {
2984 mViSessionId++;
2985 }
2986 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002987 activity.app.getThread().requestAssistContextExtras(activity.appToken, pae,
2988 requestType, mViSessionId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002989 mPendingAssistExtras.add(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002990 mUiHandler.postDelayed(pae, timeout);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002991 } catch (RemoteException e) {
2992 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
2993 return null;
2994 }
2995 return pae;
2996 }
2997 }
2998
2999 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
3000 if (result != null) {
3001 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
3002 }
3003 if (pae.hint != null) {
3004 pae.extras.putBoolean(pae.hint, true);
3005 }
3006 }
3007
3008 private void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
3009 IAssistDataReceiver receiver;
3010 synchronized (mGlobalLock) {
3011 mPendingAssistExtras.remove(pae);
3012 receiver = pae.receiver;
3013 }
3014 if (receiver != null) {
3015 // Caller wants result sent back to them.
3016 Bundle sendBundle = new Bundle();
3017 // At least return the receiver extras
3018 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
3019 try {
3020 pae.receiver.onHandleAssistData(sendBundle);
3021 } catch (RemoteException e) {
3022 }
3023 }
3024 }
3025
3026 public class PendingAssistExtras extends Binder implements Runnable {
3027 public final ActivityRecord activity;
3028 public boolean isHome;
3029 public final Bundle extras;
3030 public final Intent intent;
3031 public final String hint;
3032 public final IAssistDataReceiver receiver;
3033 public final int userHandle;
3034 public boolean haveResult = false;
3035 public Bundle result = null;
3036 public AssistStructure structure = null;
3037 public AssistContent content = null;
3038 public Bundle receiverExtras;
3039
3040 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
3041 String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
3042 int _userHandle) {
3043 activity = _activity;
3044 extras = _extras;
3045 intent = _intent;
3046 hint = _hint;
3047 receiver = _receiver;
3048 receiverExtras = _receiverExtras;
3049 userHandle = _userHandle;
3050 }
3051
3052 @Override
3053 public void run() {
3054 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
3055 synchronized (this) {
3056 haveResult = true;
3057 notifyAll();
3058 }
3059 pendingAssistExtrasTimedOut(this);
3060 }
3061 }
3062
3063 @Override
3064 public boolean isAssistDataAllowedOnCurrentActivity() {
3065 int userId;
3066 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003067 final ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003068 if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
3069 return false;
3070 }
3071
3072 final ActivityRecord activity = focusedStack.getTopActivity();
3073 if (activity == null) {
3074 return false;
3075 }
3076 userId = activity.userId;
3077 }
3078 return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
3079 }
3080
3081 @Override
3082 public boolean showAssistFromActivity(IBinder token, Bundle args) {
3083 long ident = Binder.clearCallingIdentity();
3084 try {
3085 synchronized (mGlobalLock) {
3086 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003087 ActivityRecord top = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003088 if (top != caller) {
3089 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3090 + " is not current top " + top);
3091 return false;
3092 }
3093 if (!top.nowVisible) {
3094 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3095 + " is not visible");
3096 return false;
3097 }
3098 }
3099 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
3100 token);
3101 } finally {
3102 Binder.restoreCallingIdentity(ident);
3103 }
3104 }
3105
3106 @Override
3107 public boolean isRootVoiceInteraction(IBinder token) {
3108 synchronized (mGlobalLock) {
3109 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3110 if (r == null) {
3111 return false;
3112 }
3113 return r.rootVoiceInteraction;
3114 }
3115 }
3116
Wale Ogunwalef6733932018-06-27 05:14:34 -07003117 private void onLocalVoiceInteractionStartedLocked(IBinder activity,
3118 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
3119 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
3120 if (activityToCallback == null) return;
3121 activityToCallback.setVoiceSessionLocked(voiceSession);
3122
3123 // Inform the activity
3124 try {
3125 activityToCallback.app.getThread().scheduleLocalVoiceInteractionStarted(activity,
3126 voiceInteractor);
3127 long token = Binder.clearCallingIdentity();
3128 try {
3129 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
3130 } finally {
3131 Binder.restoreCallingIdentity(token);
3132 }
3133 // TODO: VI Should we cache the activity so that it's easier to find later
3134 // rather than scan through all the stacks and activities?
3135 } catch (RemoteException re) {
3136 activityToCallback.clearVoiceSessionLocked();
3137 // TODO: VI Should this terminate the voice session?
3138 }
3139 }
3140
3141 private void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
3142 Slog.d(TAG, "<<< startRunningVoiceLocked()");
3143 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
3144 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
3145 boolean wasRunningVoice = mRunningVoice != null;
3146 mRunningVoice = session;
3147 if (!wasRunningVoice) {
3148 mVoiceWakeLock.acquire();
3149 updateSleepIfNeededLocked();
3150 }
3151 }
3152 }
3153
3154 void finishRunningVoiceLocked() {
3155 if (mRunningVoice != null) {
3156 mRunningVoice = null;
3157 mVoiceWakeLock.release();
3158 updateSleepIfNeededLocked();
3159 }
3160 }
3161
3162 @Override
3163 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3164 synchronized (mGlobalLock) {
3165 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3166 if (keepAwake) {
3167 mVoiceWakeLock.acquire();
3168 } else {
3169 mVoiceWakeLock.release();
3170 }
3171 }
3172 }
3173 }
3174
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003175 @Override
3176 public ComponentName getActivityClassForToken(IBinder token) {
3177 synchronized (mGlobalLock) {
3178 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3179 if (r == null) {
3180 return null;
3181 }
3182 return r.intent.getComponent();
3183 }
3184 }
3185
3186 @Override
3187 public String getPackageForToken(IBinder token) {
3188 synchronized (mGlobalLock) {
3189 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3190 if (r == null) {
3191 return null;
3192 }
3193 return r.packageName;
3194 }
3195 }
3196
3197 @Override
3198 public void showLockTaskEscapeMessage(IBinder token) {
3199 synchronized (mGlobalLock) {
3200 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3201 if (r == null) {
3202 return;
3203 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003204 getLockTaskController().showLockTaskToast();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003205 }
3206 }
3207
3208 @Override
3209 public void keyguardGoingAway(int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003210 enforceNotIsolatedCaller("keyguardGoingAway");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003211 final long token = Binder.clearCallingIdentity();
3212 try {
3213 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003214 mKeyguardController.keyguardGoingAway(flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003215 }
3216 } finally {
3217 Binder.restoreCallingIdentity(token);
3218 }
3219 }
3220
3221 /**
3222 * Try to place task to provided position. The final position might be different depending on
3223 * current user and stacks state. The task will be moved to target stack if it's currently in
3224 * different stack.
3225 */
3226 @Override
3227 public void positionTaskInStack(int taskId, int stackId, int position) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003228 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003229 synchronized (mGlobalLock) {
3230 long ident = Binder.clearCallingIdentity();
3231 try {
3232 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
3233 + taskId + " in stackId=" + stackId + " at position=" + position);
3234 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3235 if (task == null) {
3236 throw new IllegalArgumentException("positionTaskInStack: no task for id="
3237 + taskId);
3238 }
3239
3240 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3241
3242 if (stack == null) {
3243 throw new IllegalArgumentException("positionTaskInStack: no stack for id="
3244 + stackId);
3245 }
3246 if (!stack.isActivityTypeStandardOrUndefined()) {
3247 throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
3248 + " the position of task " + taskId + " in/to non-standard stack");
3249 }
3250
3251 // TODO: Have the callers of this API call a separate reparent method if that is
3252 // what they intended to do vs. having this method also do reparenting.
3253 if (task.getStack() == stack) {
3254 // Change position in current stack.
3255 stack.positionChildAt(task, position);
3256 } else {
3257 // Reparent to new stack.
3258 task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
3259 !DEFER_RESUME, "positionTaskInStack");
3260 }
3261 } finally {
3262 Binder.restoreCallingIdentity(ident);
3263 }
3264 }
3265 }
3266
3267 @Override
3268 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
3269 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
3270 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
3271 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
3272 synchronized (mGlobalLock) {
3273 ActivityRecord record = ActivityRecord.isInStackLocked(token);
3274 if (record == null) {
3275 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
3276 + "found for: " + token);
3277 }
3278 record.setSizeConfigurations(horizontalSizeConfiguration,
3279 verticalSizeConfigurations, smallestSizeConfigurations);
3280 }
3281 }
3282
3283 /**
3284 * Dismisses split-screen multi-window mode.
3285 * @param toTop If true the current primary split-screen stack will be placed or left on top.
3286 */
3287 @Override
3288 public void dismissSplitScreenMode(boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003289 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003290 MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
3291 final long ident = Binder.clearCallingIdentity();
3292 try {
3293 synchronized (mGlobalLock) {
3294 final ActivityStack stack =
3295 mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
3296 if (stack == null) {
3297 Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
3298 return;
3299 }
3300
3301 if (toTop) {
3302 // Caller wants the current split-screen primary stack to be the top stack after
3303 // it goes fullscreen, so move it to the front.
3304 stack.moveToFront("dismissSplitScreenMode");
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003305 } else if (mStackSupervisor.isTopDisplayFocusedStack(stack)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003306 // In this case the current split-screen primary stack shouldn't be the top
3307 // stack after it goes fullscreen, but it current has focus, so we move the
3308 // focus to the top-most split-screen secondary stack next to it.
3309 final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
3310 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
3311 if (otherStack != null) {
3312 otherStack.moveToFront("dismissSplitScreenMode_other");
3313 }
3314 }
3315
3316 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
3317 }
3318 } finally {
3319 Binder.restoreCallingIdentity(ident);
3320 }
3321 }
3322
3323 /**
3324 * Dismisses Pip
3325 * @param animate True if the dismissal should be animated.
3326 * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
3327 * default animation duration should be used.
3328 */
3329 @Override
3330 public void dismissPip(boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003331 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003332 final long ident = Binder.clearCallingIdentity();
3333 try {
3334 synchronized (mGlobalLock) {
3335 final PinnedActivityStack stack =
3336 mStackSupervisor.getDefaultDisplay().getPinnedStack();
3337 if (stack == null) {
3338 Slog.w(TAG, "dismissPip: pinned stack not found.");
3339 return;
3340 }
3341 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
3342 throw new IllegalArgumentException("Stack: " + stack
3343 + " doesn't support animated resize.");
3344 }
3345 if (animate) {
3346 stack.animateResizePinnedStack(null /* sourceHintBounds */,
3347 null /* destBounds */, animationDuration, false /* fromFullscreen */);
3348 } else {
3349 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
3350 }
3351 }
3352 } finally {
3353 Binder.restoreCallingIdentity(ident);
3354 }
3355 }
3356
3357 @Override
3358 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003359 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003360 synchronized (mGlobalLock) {
3361 mSuppressResizeConfigChanges = suppress;
3362 }
3363 }
3364
3365 /**
3366 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
3367 * animated the stack to the fullscreen, but can also be called if we are relaunching an
3368 * activity and clearing the task at the same time.
3369 */
3370 @Override
3371 // TODO: API should just be about changing windowing modes...
3372 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003373 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003374 "moveTasksToFullscreenStack()");
3375 synchronized (mGlobalLock) {
3376 final long origId = Binder.clearCallingIdentity();
3377 try {
3378 final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
3379 if (stack != null){
3380 if (!stack.isActivityTypeStandardOrUndefined()) {
3381 throw new IllegalArgumentException(
3382 "You can't move tasks from non-standard stacks.");
3383 }
3384 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
3385 }
3386 } finally {
3387 Binder.restoreCallingIdentity(origId);
3388 }
3389 }
3390 }
3391
3392 /**
3393 * Moves the top activity in the input stackId to the pinned stack.
3394 *
3395 * @param stackId Id of stack to move the top activity to pinned stack.
3396 * @param bounds Bounds to use for pinned stack.
3397 *
3398 * @return True if the top activity of the input stack was successfully moved to the pinned
3399 * stack.
3400 */
3401 @Override
3402 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003403 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003404 "moveTopActivityToPinnedStack()");
3405 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003406 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003407 throw new IllegalStateException("moveTopActivityToPinnedStack:"
3408 + "Device doesn't support picture-in-picture mode");
3409 }
3410
3411 long ident = Binder.clearCallingIdentity();
3412 try {
3413 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
3414 } finally {
3415 Binder.restoreCallingIdentity(ident);
3416 }
3417 }
3418 }
3419
3420 @Override
3421 public boolean isInMultiWindowMode(IBinder token) {
3422 final long origId = Binder.clearCallingIdentity();
3423 try {
3424 synchronized (mGlobalLock) {
3425 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3426 if (r == null) {
3427 return false;
3428 }
3429 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
3430 return r.inMultiWindowMode();
3431 }
3432 } finally {
3433 Binder.restoreCallingIdentity(origId);
3434 }
3435 }
3436
3437 @Override
3438 public boolean isInPictureInPictureMode(IBinder token) {
3439 final long origId = Binder.clearCallingIdentity();
3440 try {
3441 synchronized (mGlobalLock) {
3442 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
3443 }
3444 } finally {
3445 Binder.restoreCallingIdentity(origId);
3446 }
3447 }
3448
3449 private boolean isInPictureInPictureMode(ActivityRecord r) {
3450 if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
3451 || r.getStack().isInStackLocked(r) == null) {
3452 return false;
3453 }
3454
3455 // If we are animating to fullscreen then we have already dispatched the PIP mode
3456 // changed, so we should reflect that check here as well.
3457 final PinnedActivityStack stack = r.getStack();
3458 final PinnedStackWindowController windowController = stack.getWindowContainerController();
3459 return !windowController.isAnimatingBoundsToFullscreen();
3460 }
3461
3462 @Override
3463 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
3464 final long origId = Binder.clearCallingIdentity();
3465 try {
3466 synchronized (mGlobalLock) {
3467 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3468 "enterPictureInPictureMode", token, params);
3469
3470 // If the activity is already in picture in picture mode, then just return early
3471 if (isInPictureInPictureMode(r)) {
3472 return true;
3473 }
3474
3475 // Activity supports picture-in-picture, now check that we can enter PiP at this
3476 // point, if it is
3477 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
3478 false /* beforeStopping */)) {
3479 return false;
3480 }
3481
3482 final Runnable enterPipRunnable = () -> {
Wale Ogunwalef276a6f2018-06-15 08:26:07 -07003483 synchronized (mGlobalLock) {
3484 // Only update the saved args from the args that are set
3485 r.pictureInPictureArgs.copyOnlySet(params);
3486 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
3487 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
3488 // Adjust the source bounds by the insets for the transition down
3489 final Rect sourceBounds = new Rect(
3490 r.pictureInPictureArgs.getSourceRectHint());
3491 mStackSupervisor.moveActivityToPinnedStackLocked(
3492 r, sourceBounds, aspectRatio, "enterPictureInPictureMode");
3493 final PinnedActivityStack stack = r.getStack();
3494 stack.setPictureInPictureAspectRatio(aspectRatio);
3495 stack.setPictureInPictureActions(actions);
3496 MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
3497 r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
3498 logPictureInPictureArgs(params);
3499 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003500 };
3501
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003502 if (isKeyguardLocked()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003503 // If the keyguard is showing or occluded, then try and dismiss it before
3504 // entering picture-in-picture (this will prompt the user to authenticate if the
3505 // device is currently locked).
3506 dismissKeyguard(token, new KeyguardDismissCallback() {
3507 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003508 public void onDismissSucceeded() {
3509 mH.post(enterPipRunnable);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003510 }
3511 }, null /* message */);
3512 } else {
3513 // Enter picture in picture immediately otherwise
3514 enterPipRunnable.run();
3515 }
3516 return true;
3517 }
3518 } finally {
3519 Binder.restoreCallingIdentity(origId);
3520 }
3521 }
3522
3523 @Override
3524 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
3525 final long origId = Binder.clearCallingIdentity();
3526 try {
3527 synchronized (mGlobalLock) {
3528 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3529 "setPictureInPictureParams", token, params);
3530
3531 // Only update the saved args from the args that are set
3532 r.pictureInPictureArgs.copyOnlySet(params);
3533 if (r.inPinnedWindowingMode()) {
3534 // If the activity is already in picture-in-picture, update the pinned stack now
3535 // if it is not already expanding to fullscreen. Otherwise, the arguments will
3536 // be used the next time the activity enters PiP
3537 final PinnedActivityStack stack = r.getStack();
3538 if (!stack.isAnimatingBoundsToFullscreen()) {
3539 stack.setPictureInPictureAspectRatio(
3540 r.pictureInPictureArgs.getAspectRatio());
3541 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
3542 }
3543 }
3544 logPictureInPictureArgs(params);
3545 }
3546 } finally {
3547 Binder.restoreCallingIdentity(origId);
3548 }
3549 }
3550
3551 @Override
3552 public int getMaxNumPictureInPictureActions(IBinder token) {
3553 // Currently, this is a static constant, but later, we may change this to be dependent on
3554 // the context of the activity
3555 return 3;
3556 }
3557
3558 private void logPictureInPictureArgs(PictureInPictureParams params) {
3559 if (params.hasSetActions()) {
3560 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
3561 params.getActions().size());
3562 }
3563 if (params.hasSetAspectRatio()) {
3564 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
3565 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
3566 MetricsLogger.action(lm);
3567 }
3568 }
3569
3570 /**
3571 * Checks the state of the system and the activity associated with the given {@param token} to
3572 * verify that picture-in-picture is supported for that activity.
3573 *
3574 * @return the activity record for the given {@param token} if all the checks pass.
3575 */
3576 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
3577 IBinder token, PictureInPictureParams params) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003578 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003579 throw new IllegalStateException(caller
3580 + ": Device doesn't support picture-in-picture mode.");
3581 }
3582
3583 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3584 if (r == null) {
3585 throw new IllegalStateException(caller
3586 + ": Can't find activity for token=" + token);
3587 }
3588
3589 if (!r.supportsPictureInPicture()) {
3590 throw new IllegalStateException(caller
3591 + ": Current activity does not support picture-in-picture.");
3592 }
3593
3594 if (params.hasSetAspectRatio()
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003595 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003596 params.getAspectRatio())) {
3597 final float minAspectRatio = mContext.getResources().getFloat(
3598 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
3599 final float maxAspectRatio = mContext.getResources().getFloat(
3600 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
3601 throw new IllegalArgumentException(String.format(caller
3602 + ": Aspect ratio is too extreme (must be between %f and %f).",
3603 minAspectRatio, maxAspectRatio));
3604 }
3605
3606 // Truncate the number of actions if necessary
3607 params.truncateActions(getMaxNumPictureInPictureActions(token));
3608
3609 return r;
3610 }
3611
3612 @Override
3613 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003614 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003615 synchronized (mGlobalLock) {
3616 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
3617 if (r == null) {
3618 throw new IllegalArgumentException("Activity does not exist; token="
3619 + activityToken);
3620 }
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07003621 return r.getUriPermissionsLocked().getExternalToken();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003622 }
3623 }
3624
3625 @Override
3626 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
3627 Rect tempDockedTaskInsetBounds,
3628 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003629 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003630 long ident = Binder.clearCallingIdentity();
3631 try {
3632 synchronized (mGlobalLock) {
3633 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
3634 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
3635 PRESERVE_WINDOWS);
3636 }
3637 } finally {
3638 Binder.restoreCallingIdentity(ident);
3639 }
3640 }
3641
3642 @Override
3643 public void setSplitScreenResizing(boolean resizing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003644 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003645 final long ident = Binder.clearCallingIdentity();
3646 try {
3647 synchronized (mGlobalLock) {
3648 mStackSupervisor.setSplitScreenResizing(resizing);
3649 }
3650 } finally {
3651 Binder.restoreCallingIdentity(ident);
3652 }
3653 }
3654
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003655 /**
3656 * Check that we have the features required for VR-related API calls, and throw an exception if
3657 * not.
3658 */
3659 void enforceSystemHasVrFeature() {
3660 if (!mContext.getPackageManager().hasSystemFeature(
3661 PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
3662 throw new UnsupportedOperationException("VR mode not supported on this device!");
3663 }
3664 }
3665
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003666 @Override
3667 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003668 enforceSystemHasVrFeature();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003669
3670 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3671
3672 ActivityRecord r;
3673 synchronized (mGlobalLock) {
3674 r = ActivityRecord.isInStackLocked(token);
3675 }
3676
3677 if (r == null) {
3678 throw new IllegalArgumentException();
3679 }
3680
3681 int err;
3682 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
3683 VrManagerInternal.NO_ERROR) {
3684 return err;
3685 }
3686
3687 // Clear the binder calling uid since this path may call moveToTask().
3688 final long callingId = Binder.clearCallingIdentity();
3689 try {
3690 synchronized (mGlobalLock) {
3691 r.requestedVrComponent = (enabled) ? packageName : null;
3692
3693 // Update associated state if this activity is currently focused
Andrii Kulian52d255c2018-07-13 11:32:19 -07003694 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003695 applyUpdateVrModeLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003696 }
3697 return 0;
3698 }
3699 } finally {
3700 Binder.restoreCallingIdentity(callingId);
3701 }
3702 }
3703
3704 @Override
3705 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
3706 Slog.i(TAG, "Activity tried to startLocalVoiceInteraction");
3707 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003708 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003709 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
3710 throw new SecurityException("Only focused activity can call startVoiceInteraction");
3711 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07003712 if (mRunningVoice != null || activity.getTask().voiceSession != null
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003713 || activity.voiceSession != null) {
3714 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
3715 return;
3716 }
3717 if (activity.pendingVoiceInteractionStart) {
3718 Slog.w(TAG, "Pending start of voice interaction already.");
3719 return;
3720 }
3721 activity.pendingVoiceInteractionStart = true;
3722 }
3723 LocalServices.getService(VoiceInteractionManagerInternal.class)
3724 .startLocalVoiceInteraction(callingActivity, options);
3725 }
3726
3727 @Override
3728 public void stopLocalVoiceInteraction(IBinder callingActivity) {
3729 LocalServices.getService(VoiceInteractionManagerInternal.class)
3730 .stopLocalVoiceInteraction(callingActivity);
3731 }
3732
3733 @Override
3734 public boolean supportsLocalVoiceInteraction() {
3735 return LocalServices.getService(VoiceInteractionManagerInternal.class)
3736 .supportsLocalVoiceInteraction();
3737 }
3738
3739 /** Notifies all listeners when the pinned stack animation starts. */
3740 @Override
3741 public void notifyPinnedStackAnimationStarted() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003742 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003743 }
3744
3745 /** Notifies all listeners when the pinned stack animation ends. */
3746 @Override
3747 public void notifyPinnedStackAnimationEnded() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003748 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003749 }
3750
3751 @Override
3752 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003753 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003754 final long ident = Binder.clearCallingIdentity();
3755 try {
3756 synchronized (mGlobalLock) {
3757 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
3758 }
3759 } finally {
3760 Binder.restoreCallingIdentity(ident);
3761 }
3762 }
3763
3764 @Override
3765 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003766 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003767
3768 synchronized (mGlobalLock) {
3769 // Check if display is initialized in AM.
3770 if (!mStackSupervisor.isDisplayAdded(displayId)) {
3771 // Call might come when display is not yet added or has already been removed.
3772 if (DEBUG_CONFIGURATION) {
3773 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
3774 + displayId);
3775 }
3776 return false;
3777 }
3778
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003779 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003780 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003781 values = mWindowManager.computeNewConfiguration(displayId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003782 }
3783
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003784 if (mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003785 // Update OOM levels based on display size.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003786 mAm.mProcessList.applyDisplaySize(mWindowManager);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003787 }
3788
3789 final long origId = Binder.clearCallingIdentity();
3790 try {
3791 if (values != null) {
3792 Settings.System.clearConfiguration(values);
3793 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003794 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003795 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
3796 return mTmpUpdateConfigurationResult.changes != 0;
3797 } finally {
3798 Binder.restoreCallingIdentity(origId);
3799 }
3800 }
3801 }
3802
3803 @Override
3804 public boolean updateConfiguration(Configuration values) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003805 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003806
3807 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003808 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003809 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003810 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003811 }
3812
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003813 if (mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003814 // Update OOM levels based on display size.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003815 mAm.mProcessList.applyDisplaySize(mWindowManager);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003816 }
3817
3818 final long origId = Binder.clearCallingIdentity();
3819 try {
3820 if (values != null) {
3821 Settings.System.clearConfiguration(values);
3822 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003823 updateConfigurationLocked(values, null, false, false /* persistent */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003824 UserHandle.USER_NULL, false /* deferResume */,
3825 mTmpUpdateConfigurationResult);
3826 return mTmpUpdateConfigurationResult.changes != 0;
3827 } finally {
3828 Binder.restoreCallingIdentity(origId);
3829 }
3830 }
3831 }
3832
3833 @Override
3834 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
3835 CharSequence message) {
3836 if (message != null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003837 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003838 Manifest.permission.SHOW_KEYGUARD_MESSAGE, "dismissKeyguard()");
3839 }
3840 final long callingId = Binder.clearCallingIdentity();
3841 try {
3842 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003843 mKeyguardController.dismissKeyguard(token, callback, message);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003844 }
3845 } finally {
3846 Binder.restoreCallingIdentity(callingId);
3847 }
3848 }
3849
3850 @Override
3851 public void cancelTaskWindowTransition(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003852 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003853 "cancelTaskWindowTransition()");
3854 final long ident = Binder.clearCallingIdentity();
3855 try {
3856 synchronized (mGlobalLock) {
3857 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
3858 MATCH_TASK_IN_STACKS_ONLY);
3859 if (task == null) {
3860 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
3861 return;
3862 }
3863 task.cancelWindowTransition();
3864 }
3865 } finally {
3866 Binder.restoreCallingIdentity(ident);
3867 }
3868 }
3869
3870 @Override
3871 public ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003872 enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003873 final long ident = Binder.clearCallingIdentity();
3874 try {
3875 final TaskRecord task;
3876 synchronized (mGlobalLock) {
3877 task = mStackSupervisor.anyTaskForIdLocked(taskId,
3878 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
3879 if (task == null) {
3880 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
3881 return null;
3882 }
3883 }
3884 // Don't call this while holding the lock as this operation might hit the disk.
3885 return task.getSnapshot(reducedResolution);
3886 } finally {
3887 Binder.restoreCallingIdentity(ident);
3888 }
3889 }
3890
3891 @Override
3892 public void setDisablePreviewScreenshots(IBinder token, boolean disable) {
3893 synchronized (mGlobalLock) {
3894 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3895 if (r == null) {
3896 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
3897 + token);
3898 return;
3899 }
3900 final long origId = Binder.clearCallingIdentity();
3901 try {
3902 r.setDisablePreviewScreenshots(disable);
3903 } finally {
3904 Binder.restoreCallingIdentity(origId);
3905 }
3906 }
3907 }
3908
3909 /** Return the user id of the last resumed activity. */
3910 @Override
3911 public @UserIdInt
3912 int getLastResumedActivityUserId() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003913 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003914 Manifest.permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
3915 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07003916 if (mLastResumedActivity == null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003917 return getCurrentUserId();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003918 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07003919 return mLastResumedActivity.userId;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003920 }
3921 }
3922
3923 @Override
3924 public void updateLockTaskFeatures(int userId, int flags) {
3925 final int callingUid = Binder.getCallingUid();
3926 if (callingUid != 0 && callingUid != SYSTEM_UID) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003927 mAmInternal.enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003928 "updateLockTaskFeatures()");
3929 }
3930 synchronized (mGlobalLock) {
3931 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
3932 Integer.toHexString(flags));
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003933 getLockTaskController().updateLockTaskFeatures(userId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003934 }
3935 }
3936
3937 @Override
3938 public void setShowWhenLocked(IBinder token, boolean showWhenLocked) {
3939 synchronized (mGlobalLock) {
3940 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3941 if (r == null) {
3942 return;
3943 }
3944 final long origId = Binder.clearCallingIdentity();
3945 try {
3946 r.setShowWhenLocked(showWhenLocked);
3947 } finally {
3948 Binder.restoreCallingIdentity(origId);
3949 }
3950 }
3951 }
3952
3953 @Override
3954 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) {
3955 synchronized (mGlobalLock) {
3956 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3957 if (r == null) {
3958 return;
3959 }
3960 final long origId = Binder.clearCallingIdentity();
3961 try {
3962 r.setTurnScreenOn(turnScreenOn);
3963 } finally {
3964 Binder.restoreCallingIdentity(origId);
3965 }
3966 }
3967 }
3968
3969 @Override
3970 public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003971 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003972 "registerRemoteAnimations");
3973 definition.setCallingPid(Binder.getCallingPid());
3974 synchronized (mGlobalLock) {
3975 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3976 if (r == null) {
3977 return;
3978 }
3979 final long origId = Binder.clearCallingIdentity();
3980 try {
3981 r.registerRemoteAnimations(definition);
3982 } finally {
3983 Binder.restoreCallingIdentity(origId);
3984 }
3985 }
3986 }
3987
3988 @Override
3989 public void registerRemoteAnimationForNextActivityStart(String packageName,
3990 RemoteAnimationAdapter adapter) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003991 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003992 "registerRemoteAnimationForNextActivityStart");
3993 adapter.setCallingPid(Binder.getCallingPid());
3994 synchronized (mGlobalLock) {
3995 final long origId = Binder.clearCallingIdentity();
3996 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07003997 getActivityStartController().registerRemoteAnimationForNextActivityStart(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003998 packageName, adapter);
3999 } finally {
4000 Binder.restoreCallingIdentity(origId);
4001 }
4002 }
4003 }
4004
4005 /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
4006 @Override
4007 public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
4008 synchronized (mGlobalLock) {
4009 final long origId = Binder.clearCallingIdentity();
4010 try {
4011 mAm.mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
4012 } finally {
4013 Binder.restoreCallingIdentity(origId);
4014 }
4015 }
4016 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004017
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004018 @Override
4019 public void setVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004020 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004021 synchronized (mGlobalLock) {
4022 synchronized (mAm.mPidsSelfLocked) {
4023 final int pid = Binder.getCallingPid();
4024 final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004025 mVrController.setVrThreadLocked(tid, pid, proc.getWindowProcessController());
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004026 }
4027 }
4028 }
4029
4030 @Override
4031 public void setPersistentVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004032 if (checkCallingPermission(Manifest.permission.RESTRICTED_VR_ACCESS)
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004033 != PERMISSION_GRANTED) {
4034 final String msg = "Permission Denial: setPersistentVrThread() from pid="
4035 + Binder.getCallingPid()
4036 + ", uid=" + Binder.getCallingUid()
4037 + " requires " + Manifest.permission.RESTRICTED_VR_ACCESS;
4038 Slog.w(TAG, msg);
4039 throw new SecurityException(msg);
4040 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004041 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004042 synchronized (mGlobalLock) {
4043 synchronized (mAm.mPidsSelfLocked) {
4044 final int pid = Binder.getCallingPid();
4045 final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
4046 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
4047 }
4048 }
4049 }
4050
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004051 @Override
4052 public void stopAppSwitches() {
4053 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
4054 synchronized (mGlobalLock) {
4055 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME;
4056 mDidAppSwitch = false;
4057 getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
4058 }
4059 }
4060
4061 @Override
4062 public void resumeAppSwitches() {
4063 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
4064 synchronized (mGlobalLock) {
4065 // Note that we don't execute any pending app switches... we will
4066 // let those wait until either the timeout, or the next start
4067 // activity request.
4068 mAppSwitchesAllowedTime = 0;
4069 }
4070 }
4071
4072 void onStartActivitySetDidAppSwitch() {
4073 if (mDidAppSwitch) {
4074 // This is the second allowed switch since we stopped switches, so now just generally
4075 // allow switches. Use case:
4076 // - user presses home (switches disabled, switch to home, mDidAppSwitch now true);
4077 // - user taps a home icon (coming from home so allowed, we hit here and now allow
4078 // anyone to switch again).
4079 mAppSwitchesAllowedTime = 0;
4080 } else {
4081 mDidAppSwitch = true;
4082 }
4083 }
4084
4085 /** @return whether the system should disable UI modes incompatible with VR mode. */
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004086 boolean shouldDisableNonVrUiLocked() {
4087 return mVrController.shouldDisableNonVrUiLocked();
4088 }
4089
4090 void applyUpdateVrModeLocked(ActivityRecord r) {
4091 // VR apps are expected to run in a main display. If an app is turning on VR for
4092 // itself, but lives in a dynamic stack, then make sure that it is moved to the main
4093 // fullscreen stack before enabling VR Mode.
4094 // TODO: The goal of this code is to keep the VR app on the main display. When the
4095 // stack implementation changes in the future, keep in mind that the use of the fullscreen
4096 // stack is a means to move the activity to the main display and a moveActivityToDisplay()
4097 // option would be a better choice here.
4098 if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
4099 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
4100 + " to main stack for VR");
4101 final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
4102 WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
4103 moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
4104 }
4105 mH.post(() -> {
4106 if (!mVrController.onVrModeChanged(r)) {
4107 return;
4108 }
4109 synchronized (mGlobalLock) {
4110 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
4111 mWindowManager.disableNonVrUi(disableNonVrUi);
4112 if (disableNonVrUi) {
4113 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
4114 // then remove the pinned stack.
4115 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
4116 }
4117 }
4118 });
4119 }
4120
Andrii Kulian5f750bc2018-07-17 08:57:23 -07004121 ActivityStack getTopDisplayFocusedStack() {
4122 return mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004123 }
4124
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004125 /** Pokes the task persister. */
4126 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
4127 mRecentTasks.notifyTaskPersisterLocked(task, flush);
4128 }
4129
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004130 void onTopProcChangedLocked(WindowProcessController proc) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004131 mVrController.onTopProcChangedLocked(proc);
4132 }
4133
4134 boolean isKeyguardLocked() {
4135 return mKeyguardController.isKeyguardLocked();
4136 }
4137
4138 boolean isNextTransitionForward() {
4139 int transit = mWindowManager.getPendingAppTransition();
4140 return transit == TRANSIT_ACTIVITY_OPEN
4141 || transit == TRANSIT_TASK_OPEN
4142 || transit == TRANSIT_TASK_TO_FRONT;
4143 }
4144
Wale Ogunwalef6733932018-06-27 05:14:34 -07004145 void dumpSleepStates(PrintWriter pw, boolean testPssMode) {
4146 synchronized (mGlobalLock) {
4147 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
4148 if (mRunningVoice != null) {
4149 pw.println(" mRunningVoice=" + mRunningVoice);
4150 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
4151 }
4152 pw.println(" mSleeping=" + mSleeping);
4153 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + testPssMode);
4154 pw.println(" mVrController=" + mVrController);
4155 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004156 }
4157
Wale Ogunwalef6733932018-06-27 05:14:34 -07004158 void writeSleepStateToProto(ProtoOutputStream proto) {
4159 for (ActivityTaskManagerInternal.SleepToken st : mStackSupervisor.mSleepTokens) {
4160 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS,
4161 st.toString());
4162 }
4163
4164 if (mRunningVoice != null) {
4165 final long vrToken = proto.start(
4166 ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
4167 proto.write(ActivityManagerServiceDumpProcessesProto.Voice.SESSION,
4168 mRunningVoice.toString());
4169 mVoiceWakeLock.writeToProto(
4170 proto, ActivityManagerServiceDumpProcessesProto.Voice.WAKELOCK);
4171 proto.end(vrToken);
4172 }
4173
4174 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
4175 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN,
4176 mShuttingDown);
4177 mVrController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004178 }
4179
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004180 int getCurrentUserId() {
4181 return mAmInternal.getCurrentUserId();
4182 }
4183
4184 private void enforceNotIsolatedCaller(String caller) {
4185 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4186 throw new SecurityException("Isolated process not allowed to call " + caller);
4187 }
4188 }
4189
Wale Ogunwalef6733932018-06-27 05:14:34 -07004190 public Configuration getConfiguration() {
4191 Configuration ci;
4192 synchronized(mGlobalLock) {
4193 ci = new Configuration(getGlobalConfiguration());
4194 ci.userSetLocale = false;
4195 }
4196 return ci;
4197 }
4198
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004199 /**
4200 * Current global configuration information. Contains general settings for the entire system,
4201 * also corresponds to the merged configuration of the default display.
4202 */
4203 Configuration getGlobalConfiguration() {
4204 return mStackSupervisor.getConfiguration();
4205 }
4206
4207 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4208 boolean initLocale) {
4209 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
4210 }
4211
4212 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4213 boolean initLocale, boolean deferResume) {
4214 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
4215 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
4216 UserHandle.USER_NULL, deferResume);
4217 }
4218
4219 void updatePersistentConfiguration(Configuration values, @UserIdInt int userId) {
4220 final long origId = Binder.clearCallingIdentity();
4221 try {
4222 synchronized (mGlobalLock) {
4223 updateConfigurationLocked(values, null, false, true, userId,
4224 false /* deferResume */);
4225 }
4226 } finally {
4227 Binder.restoreCallingIdentity(origId);
4228 }
4229 }
4230
4231 void updateUserConfiguration() {
4232 synchronized (mGlobalLock) {
4233 final Configuration configuration = new Configuration(getGlobalConfiguration());
4234 final int currentUserId = mAmInternal.getCurrentUserId();
4235 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
4236 currentUserId, Settings.System.canWrite(mContext));
4237 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
4238 false /* persistent */, currentUserId, false /* deferResume */);
4239 }
4240 }
4241
4242 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4243 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
4244 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
4245 deferResume, null /* result */);
4246 }
4247
4248 /**
4249 * Do either or both things: (1) change the current configuration, and (2)
4250 * make sure the given activity is running with the (now) current
4251 * configuration. Returns true if the activity has been left running, or
4252 * false if <var>starting</var> is being destroyed to match the new
4253 * configuration.
4254 *
4255 * @param userId is only used when persistent parameter is set to true to persist configuration
4256 * for that particular user
4257 */
4258 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4259 boolean initLocale, boolean persistent, int userId, boolean deferResume,
4260 ActivityTaskManagerService.UpdateConfigurationResult result) {
4261 int changes = 0;
4262 boolean kept = true;
4263
4264 if (mWindowManager != null) {
4265 mWindowManager.deferSurfaceLayout();
4266 }
4267 try {
4268 if (values != null) {
4269 changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
4270 deferResume);
4271 }
4272
4273 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4274 } finally {
4275 if (mWindowManager != null) {
4276 mWindowManager.continueSurfaceLayout();
4277 }
4278 }
4279
4280 if (result != null) {
4281 result.changes = changes;
4282 result.activityRelaunched = !kept;
4283 }
4284 return kept;
4285 }
4286
4287 /**
4288 * Returns true if this configuration change is interesting enough to send an
4289 * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
4290 */
4291 private static boolean isSplitConfigurationChange(int configDiff) {
4292 return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
4293 }
4294
4295 /** Update default (global) configuration and notify listeners about changes. */
4296 private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
4297 boolean persistent, int userId, boolean deferResume) {
4298 mTempConfig.setTo(getGlobalConfiguration());
4299 final int changes = mTempConfig.updateFrom(values);
4300 if (changes == 0) {
4301 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
4302 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
4303 // performDisplayOverrideConfigUpdate in order to send the new display configuration
4304 // (even if there are no actual changes) to unfreeze the window.
4305 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
4306 return 0;
4307 }
4308
4309 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
4310 "Updating global configuration to: " + values);
4311
4312 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
4313 StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
4314 values.colorMode,
4315 values.densityDpi,
4316 values.fontScale,
4317 values.hardKeyboardHidden,
4318 values.keyboard,
4319 values.keyboardHidden,
4320 values.mcc,
4321 values.mnc,
4322 values.navigation,
4323 values.navigationHidden,
4324 values.orientation,
4325 values.screenHeightDp,
4326 values.screenLayout,
4327 values.screenWidthDp,
4328 values.smallestScreenWidthDp,
4329 values.touchscreen,
4330 values.uiMode);
4331
4332
4333 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
4334 final LocaleList locales = values.getLocales();
4335 int bestLocaleIndex = 0;
4336 if (locales.size() > 1) {
4337 if (mSupportedSystemLocales == null) {
4338 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
4339 }
4340 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
4341 }
4342 SystemProperties.set("persist.sys.locale",
4343 locales.get(bestLocaleIndex).toLanguageTag());
4344 LocaleList.setDefault(locales, bestLocaleIndex);
4345 mAm.mHandler.sendMessage(mAm.mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
4346 locales.get(bestLocaleIndex)));
4347 }
4348
4349 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
4350 mTempConfig.seq = mConfigurationSeq;
4351
4352 // Update stored global config and notify everyone about the change.
4353 mStackSupervisor.onConfigurationChanged(mTempConfig);
4354
4355 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
4356 // TODO(multi-display): Update UsageEvents#Event to include displayId.
4357 mAm.mUsageStatsService.reportConfigurationChange(
4358 mTempConfig, mAmInternal.getCurrentUserId());
4359
4360 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
Wale Ogunwalef6733932018-06-27 05:14:34 -07004361 updateShouldShowDialogsLocked(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004362
4363 AttributeCache ac = AttributeCache.instance();
4364 if (ac != null) {
4365 ac.updateConfiguration(mTempConfig);
4366 }
4367
4368 // Make sure all resources in our process are updated right now, so that anyone who is going
4369 // to retrieve resource values after we return will be sure to get the new ones. This is
4370 // especially important during boot, where the first config change needs to guarantee all
4371 // resources have that config before following boot code is executed.
4372 mAm.mSystemThread.applyConfigurationToResources(mTempConfig);
4373
4374 // We need another copy of global config because we're scheduling some calls instead of
4375 // running them in place. We need to be sure that object we send will be handled unchanged.
4376 final Configuration configCopy = new Configuration(mTempConfig);
4377 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
4378 Message msg = mAm.mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
4379 msg.obj = configCopy;
4380 msg.arg1 = userId;
4381 mAm.mHandler.sendMessage(msg);
4382 }
4383
4384 for (int i = mAm.mLruProcesses.size() - 1; i >= 0; i--) {
4385 ProcessRecord app = mAm.mLruProcesses.get(i);
4386 try {
4387 if (app.thread != null) {
4388 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
4389 + app.processName + " new config " + configCopy);
4390 getLifecycleManager().scheduleTransaction(app.thread,
4391 ConfigurationChangeItem.obtain(configCopy));
4392 }
4393 } catch (Exception e) {
4394 Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
4395 }
4396 }
4397
4398 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
4399 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
4400 | Intent.FLAG_RECEIVER_FOREGROUND
4401 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4402 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4403 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4404 UserHandle.USER_ALL);
4405 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
4406 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
4407 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
4408 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
4409 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4410 if (initLocale || !mAm.mProcessesReady) {
4411 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
4412 }
4413 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4414 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4415 UserHandle.USER_ALL);
4416 }
4417
4418 // Send a broadcast to PackageInstallers if the configuration change is interesting
4419 // for the purposes of installing additional splits.
4420 if (!initLocale && isSplitConfigurationChange(changes)) {
4421 intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
4422 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
4423 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
4424
4425 // Typically only app stores will have this permission.
4426 String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES };
4427 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions,
4428 OP_NONE, null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
4429 }
4430
4431 // Override configuration of the default display duplicates global config, so we need to
4432 // update it also. This will also notify WindowManager about changes.
4433 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
4434 DEFAULT_DISPLAY);
4435
4436 return changes;
4437 }
4438
4439 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
4440 boolean deferResume, int displayId) {
4441 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
4442 displayId, null /* result */);
4443 }
4444
4445 /**
4446 * Updates override configuration specific for the selected display. If no config is provided,
4447 * new one will be computed in WM based on current display info.
4448 */
4449 boolean updateDisplayOverrideConfigurationLocked(Configuration values,
4450 ActivityRecord starting, boolean deferResume, int displayId,
4451 ActivityTaskManagerService.UpdateConfigurationResult result) {
4452 int changes = 0;
4453 boolean kept = true;
4454
4455 if (mWindowManager != null) {
4456 mWindowManager.deferSurfaceLayout();
4457 }
4458 try {
4459 if (values != null) {
4460 if (displayId == DEFAULT_DISPLAY) {
4461 // Override configuration of the default display duplicates global config, so
4462 // we're calling global config update instead for default display. It will also
4463 // apply the correct override config.
4464 changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
4465 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
4466 } else {
4467 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
4468 }
4469 }
4470
4471 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4472 } finally {
4473 if (mWindowManager != null) {
4474 mWindowManager.continueSurfaceLayout();
4475 }
4476 }
4477
4478 if (result != null) {
4479 result.changes = changes;
4480 result.activityRelaunched = !kept;
4481 }
4482 return kept;
4483 }
4484
4485 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
4486 int displayId) {
4487 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
4488 final int changes = mTempConfig.updateFrom(values);
4489 if (changes != 0) {
4490 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
4491 + mTempConfig + " for displayId=" + displayId);
4492 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
4493
4494 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
4495 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
4496 mAm.mAppWarnings.onDensityChanged();
4497
4498 mAm.killAllBackgroundProcessesExcept(N,
4499 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
4500 }
4501 }
4502
4503 // Update the configuration with WM first and check if any of the stacks need to be resized
4504 // due to the configuration change. If so, resize the stacks now and do any relaunches if
4505 // necessary. This way we don't need to relaunch again afterwards in
4506 // ensureActivityConfiguration().
4507 if (mWindowManager != null) {
4508 final int[] resizedStacks =
4509 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
4510 if (resizedStacks != null) {
4511 for (int stackId : resizedStacks) {
4512 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
4513 }
4514 }
4515 }
4516
4517 return changes;
4518 }
4519
Wale Ogunwalef6733932018-06-27 05:14:34 -07004520 private void updateEventDispatchingLocked(boolean booted) {
4521 mWindowManager.setEventDispatching(booted && !mShuttingDown);
4522 }
4523
4524 void enableScreenAfterBoot(boolean booted) {
4525 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4526 SystemClock.uptimeMillis());
4527 mWindowManager.enableScreenAfterBoot();
4528
4529 synchronized (mGlobalLock) {
4530 updateEventDispatchingLocked(booted);
4531 }
4532 }
4533
4534 boolean canShowErrorDialogs() {
4535 return mShowDialogs && !mSleeping && !mShuttingDown
4536 && !mKeyguardController.isKeyguardOrAodShowing(DEFAULT_DISPLAY)
4537 && !hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
Wale Ogunwale86b74462018-07-02 08:42:43 -07004538 mAmInternal.getCurrentUserId())
Wale Ogunwalef6733932018-06-27 05:14:34 -07004539 && !(UserManager.isDeviceInDemoMode(mContext)
Wale Ogunwale86b74462018-07-02 08:42:43 -07004540 && mAmInternal.getCurrentUser().isDemo());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004541 }
4542
4543 /**
4544 * Decide based on the configuration whether we should show the ANR,
4545 * crash, etc dialogs. The idea is that if there is no affordance to
4546 * press the on-screen buttons, or the user experience would be more
4547 * greatly impacted than the crash itself, we shouldn't show the dialog.
4548 *
4549 * A thought: SystemUI might also want to get told about this, the Power
4550 * dialog / global actions also might want different behaviors.
4551 */
4552 private void updateShouldShowDialogsLocked(Configuration config) {
4553 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
4554 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
4555 && config.navigation == Configuration.NAVIGATION_NONAV);
4556 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
4557 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
4558 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
4559 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
4560 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
4561 final boolean hideDialogsSet = Settings.Global.getInt(mContext.getContentResolver(),
4562 HIDE_ERROR_DIALOGS, 0) != 0;
4563 mShowDialogs = inputMethodExists && uiModeSupportsDialogs && !hideDialogsSet;
4564 }
4565
4566 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
4567 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
4568 FONT_SCALE, 1.0f, userId);
4569
4570 synchronized (this) {
4571 if (getGlobalConfiguration().fontScale == scaleFactor) {
4572 return;
4573 }
4574
4575 final Configuration configuration
4576 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
4577 configuration.fontScale = scaleFactor;
4578 updatePersistentConfiguration(configuration, userId);
4579 }
4580 }
4581
4582 // Actually is sleeping or shutting down or whatever else in the future
4583 // is an inactive state.
4584 boolean isSleepingOrShuttingDownLocked() {
4585 return isSleepingLocked() || mShuttingDown;
4586 }
4587
4588 boolean isSleepingLocked() {
4589 return mSleeping;
4590 }
4591
4592 /**
4593 * Update AMS states when an activity is resumed. This should only be called by
4594 * {@link ActivityStack#onActivityStateChanged(
4595 * ActivityRecord, ActivityStack.ActivityState, String)} when an activity is resumed.
4596 */
4597 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
4598 final TaskRecord task = r.getTask();
4599 if (task.isActivityTypeStandard()) {
4600 if (mCurAppTimeTracker != r.appTimeTracker) {
4601 // We are switching app tracking. Complete the current one.
4602 if (mCurAppTimeTracker != null) {
4603 mCurAppTimeTracker.stop();
4604 mH.obtainMessage(
4605 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
4606 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
4607 mCurAppTimeTracker = null;
4608 }
4609 if (r.appTimeTracker != null) {
4610 mCurAppTimeTracker = r.appTimeTracker;
4611 startTimeTrackingFocusedActivityLocked();
4612 }
4613 } else {
4614 startTimeTrackingFocusedActivityLocked();
4615 }
4616 } else {
4617 r.appTimeTracker = null;
4618 }
4619 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
4620 // TODO: Probably not, because we don't want to resume voice on switching
4621 // back to this activity
4622 if (task.voiceInteractor != null) {
4623 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
4624 } else {
4625 finishRunningVoiceLocked();
4626
4627 if (mLastResumedActivity != null) {
4628 final IVoiceInteractionSession session;
4629
4630 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
4631 if (lastResumedActivityTask != null
4632 && lastResumedActivityTask.voiceSession != null) {
4633 session = lastResumedActivityTask.voiceSession;
4634 } else {
4635 session = mLastResumedActivity.voiceSession;
4636 }
4637
4638 if (session != null) {
4639 // We had been in a voice interaction session, but now focused has
4640 // move to something different. Just finish the session, we can't
4641 // return to it and retain the proper state and synchronization with
4642 // the voice interaction service.
4643 finishVoiceTask(session);
4644 }
4645 }
4646 }
4647
4648 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
4649 mAmInternal.sendForegroundProfileChanged(r.userId);
4650 }
4651 updateResumedAppTrace(r);
4652 mLastResumedActivity = r;
4653
4654 mWindowManager.setFocusedApp(r.appToken, true);
4655
4656 applyUpdateLockStateLocked(r);
4657 applyUpdateVrModeLocked(r);
4658
4659 EventLogTags.writeAmSetResumedActivity(
4660 r == null ? -1 : r.userId,
4661 r == null ? "NULL" : r.shortComponentName,
4662 reason);
4663 }
4664
4665 ActivityTaskManagerInternal.SleepToken acquireSleepToken(String tag, int displayId) {
4666 synchronized (mGlobalLock) {
4667 final ActivityTaskManagerInternal.SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
4668 updateSleepIfNeededLocked();
4669 return token;
4670 }
4671 }
4672
4673 void updateSleepIfNeededLocked() {
4674 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
4675 final boolean wasSleeping = mSleeping;
4676 boolean updateOomAdj = false;
4677
4678 if (!shouldSleep) {
4679 // If wasSleeping is true, we need to wake up activity manager state from when
4680 // we started sleeping. In either case, we need to apply the sleep tokens, which
4681 // will wake up stacks or put them to sleep as appropriate.
4682 if (wasSleeping) {
4683 mSleeping = false;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07004684 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
4685 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__AWAKE);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004686 startTimeTrackingFocusedActivityLocked();
4687 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
4688 mStackSupervisor.comeOutOfSleepIfNeededLocked();
4689 }
4690 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
4691 if (wasSleeping) {
4692 updateOomAdj = true;
4693 }
4694 } else if (!mSleeping && shouldSleep) {
4695 mSleeping = true;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07004696 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
4697 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__ASLEEP);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004698 if (mCurAppTimeTracker != null) {
4699 mCurAppTimeTracker.stop();
4700 }
4701 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
4702 mStackSupervisor.goingToSleepLocked();
4703 updateResumedAppTrace(null /* resumed */);
4704 updateOomAdj = true;
4705 }
4706 if (updateOomAdj) {
4707 mH.post(mAmInternal::updateOomAdj);
4708 }
4709 }
4710
4711 void updateOomAdj() {
4712 mH.post(mAmInternal::updateOomAdj);
4713 }
4714
Andrii Kulian52d255c2018-07-13 11:32:19 -07004715 // TODO(b/111541062): Update app time tracking to make it aware of multiple resumed activities
Wale Ogunwalef6733932018-06-27 05:14:34 -07004716 private void startTimeTrackingFocusedActivityLocked() {
Andrii Kulian52d255c2018-07-13 11:32:19 -07004717 final ActivityRecord resumedActivity = mStackSupervisor.getTopResumedActivity();
Wale Ogunwalef6733932018-06-27 05:14:34 -07004718 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
4719 mCurAppTimeTracker.start(resumedActivity.packageName);
4720 }
4721 }
4722
4723 private void updateResumedAppTrace(@Nullable ActivityRecord resumed) {
4724 if (mTracedResumedActivity != null) {
4725 Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER,
4726 constructResumedTraceName(mTracedResumedActivity.packageName), 0);
4727 }
4728 if (resumed != null) {
4729 Trace.asyncTraceBegin(TRACE_TAG_ACTIVITY_MANAGER,
4730 constructResumedTraceName(resumed.packageName), 0);
4731 }
4732 mTracedResumedActivity = resumed;
4733 }
4734
4735 private String constructResumedTraceName(String packageName) {
4736 return "focused app: " + packageName;
4737 }
4738
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004739 /** Helper method that requests bounds from WM and applies them to stack. */
4740 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
4741 final Rect newStackBounds = new Rect();
4742 final ActivityStack stack = mStackSupervisor.getStack(stackId);
4743
4744 // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
4745 if (stack == null) {
4746 final StringWriter writer = new StringWriter();
4747 final PrintWriter printWriter = new PrintWriter(writer);
4748 mStackSupervisor.dumpDisplays(printWriter);
4749 printWriter.flush();
4750
4751 Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
4752 }
4753
4754 stack.getBoundsForNewConfiguration(newStackBounds);
4755 mStackSupervisor.resizeStackLocked(
4756 stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
4757 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
4758 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
4759 }
4760
4761 /** Applies latest configuration and/or visibility updates if needed. */
4762 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
4763 boolean kept = true;
Andrii Kulian5f750bc2018-07-17 08:57:23 -07004764 final ActivityStack mainStack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004765 // mainStack is null during startup.
4766 if (mainStack != null) {
4767 if (changes != 0 && starting == null) {
4768 // If the configuration changed, and the caller is not already
4769 // in the process of starting an activity, then find the top
4770 // activity to check if its configuration needs to change.
4771 starting = mainStack.topRunningActivityLocked();
4772 }
4773
4774 if (starting != null) {
4775 kept = starting.ensureActivityConfiguration(changes,
4776 false /* preserveWindow */);
4777 // And we need to make sure at this point that all other activities
4778 // are made visible with the correct configuration.
4779 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
4780 !PRESERVE_WINDOWS);
4781 }
4782 }
4783
4784 return kept;
4785 }
4786
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004787 void logAppTooSlow(WindowProcessController app, long startTime, String msg) {
4788 if (true || Build.IS_USER) {
4789 return;
4790 }
4791
4792 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4793 StrictMode.allowThreadDiskWrites();
4794 try {
4795 File tracesDir = new File("/data/anr");
4796 File tracesFile = null;
4797 try {
4798 tracesFile = File.createTempFile("app_slow", null, tracesDir);
4799
4800 StringBuilder sb = new StringBuilder();
4801 Time tobj = new Time();
4802 tobj.set(System.currentTimeMillis());
4803 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4804 sb.append(": ");
4805 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4806 sb.append(" since ");
4807 sb.append(msg);
4808 FileOutputStream fos = new FileOutputStream(tracesFile);
4809 fos.write(sb.toString().getBytes());
4810 if (app == null) {
4811 fos.write("\n*** No application process!".getBytes());
4812 }
4813 fos.close();
4814 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4815 } catch (IOException e) {
4816 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesFile, e);
4817 return;
4818 }
4819
4820 if (app != null && app.getPid() > 0) {
4821 ArrayList<Integer> firstPids = new ArrayList<Integer>();
4822 firstPids.add(app.getPid());
4823 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, null, null);
4824 }
4825
4826 File lastTracesFile = null;
4827 File curTracesFile = null;
4828 for (int i=9; i>=0; i--) {
4829 String name = String.format(Locale.US, "slow%02d.txt", i);
4830 curTracesFile = new File(tracesDir, name);
4831 if (curTracesFile.exists()) {
4832 if (lastTracesFile != null) {
4833 curTracesFile.renameTo(lastTracesFile);
4834 } else {
4835 curTracesFile.delete();
4836 }
4837 }
4838 lastTracesFile = curTracesFile;
4839 }
4840 tracesFile.renameTo(curTracesFile);
4841 } finally {
4842 StrictMode.setThreadPolicy(oldPolicy);
4843 }
4844 }
4845
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004846 final class H extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07004847 static final int REPORT_TIME_TRACKER_MSG = 1;
4848
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004849 public H(Looper looper) {
4850 super(looper, null, true);
4851 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004852
4853 @Override
4854 public void handleMessage(Message msg) {
4855 switch (msg.what) {
4856 case REPORT_TIME_TRACKER_MSG: {
4857 AppTimeTracker tracker = (AppTimeTracker) msg.obj;
4858 tracker.deliverResult(mContext);
4859 } break;
4860 }
4861 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004862 }
4863
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004864 final class UiHandler extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07004865 static final int DISMISS_DIALOG_UI_MSG = 1;
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004866
4867 public UiHandler() {
4868 super(com.android.server.UiThread.get().getLooper(), null, true);
4869 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004870
4871 @Override
4872 public void handleMessage(Message msg) {
4873 switch (msg.what) {
4874 case DISMISS_DIALOG_UI_MSG: {
4875 final Dialog d = (Dialog) msg.obj;
4876 d.dismiss();
4877 break;
4878 }
4879 }
4880 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004881 }
4882
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004883 final class LocalService extends ActivityTaskManagerInternal {
4884 @Override
4885 public SleepToken acquireSleepToken(String tag, int displayId) {
4886 Preconditions.checkNotNull(tag);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004887 return ActivityTaskManagerService.this.acquireSleepToken(tag, displayId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004888 }
4889
4890 @Override
4891 public ComponentName getHomeActivityForUser(int userId) {
4892 synchronized (mGlobalLock) {
4893 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
4894 return homeActivity == null ? null : homeActivity.realActivity;
4895 }
4896 }
4897
4898 @Override
4899 public void onLocalVoiceInteractionStarted(IBinder activity,
4900 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4901 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07004902 onLocalVoiceInteractionStartedLocked(activity, voiceSession, voiceInteractor);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004903 }
4904 }
4905
4906 @Override
4907 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
4908 synchronized (mGlobalLock) {
4909 mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
4910 reasons, timestamp);
4911 }
4912 }
4913
4914 @Override
4915 public void notifyAppTransitionFinished() {
4916 synchronized (mGlobalLock) {
4917 mStackSupervisor.notifyAppTransitionDone();
4918 }
4919 }
4920
4921 @Override
4922 public void notifyAppTransitionCancelled() {
4923 synchronized (mGlobalLock) {
4924 mStackSupervisor.notifyAppTransitionDone();
4925 }
4926 }
4927
4928 @Override
4929 public List<IBinder> getTopVisibleActivities() {
4930 synchronized (mGlobalLock) {
4931 return mStackSupervisor.getTopVisibleActivities();
4932 }
4933 }
4934
4935 @Override
4936 public void notifyDockedStackMinimizedChanged(boolean minimized) {
4937 synchronized (mGlobalLock) {
4938 mStackSupervisor.setDockedStackMinimized(minimized);
4939 }
4940 }
4941
4942 @Override
4943 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
4944 Bundle bOptions) {
4945 Preconditions.checkNotNull(intents, "intents");
4946 final String[] resolvedTypes = new String[intents.length];
4947
4948 // UID of the package on user userId.
4949 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
4950 // packageUid may not be initialized.
4951 int packageUid = 0;
4952 final long ident = Binder.clearCallingIdentity();
4953
4954 try {
4955 for (int i = 0; i < intents.length; i++) {
4956 resolvedTypes[i] =
4957 intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
4958 }
4959
4960 packageUid = AppGlobals.getPackageManager().getPackageUid(
4961 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
4962 } catch (RemoteException e) {
4963 // Shouldn't happen.
4964 } finally {
4965 Binder.restoreCallingIdentity(ident);
4966 }
4967
4968 synchronized (mGlobalLock) {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07004969 return getActivityStartController().startActivitiesInPackage(
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004970 packageUid, packageName,
4971 intents, resolvedTypes, null /* resultTo */,
4972 SafeActivityOptions.fromBundle(bOptions), userId,
4973 false /* validateIncomingUser */);
4974 }
4975 }
4976
4977 @Override
4978 public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
4979 Intent intent, Bundle options, int userId) {
4980 return ActivityTaskManagerService.this.startActivityAsUser(
4981 caller, callerPacakge, intent,
4982 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4983 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
4984 false /*validateIncomingUser*/);
4985 }
4986
4987 @Override
4988 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
4989 synchronized (mGlobalLock) {
4990
4991 // We might change the visibilities here, so prepare an empty app transition which
4992 // might be overridden later if we actually change visibilities.
4993 final boolean wasTransitionSet =
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004994 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004995 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004996 mWindowManager.prepareAppTransition(TRANSIT_NONE,
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004997 false /* alwaysKeepCurrent */);
4998 }
4999 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5000
5001 // If there was a transition set already we don't want to interfere with it as we
5002 // might be starting it too early.
5003 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005004 mWindowManager.executeAppTransition();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005005 }
5006 }
5007 if (callback != null) {
5008 callback.run();
5009 }
5010 }
5011
5012 @Override
5013 public void notifyKeyguardTrustedChanged() {
5014 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005015 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005016 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5017 }
5018 }
5019 }
5020
5021 /**
5022 * Called after virtual display Id is updated by
5023 * {@link com.android.server.vr.Vr2dDisplay} with a specific
5024 * {@param vrVr2dDisplayId}.
5025 */
5026 @Override
5027 public void setVr2dDisplayId(int vr2dDisplayId) {
5028 if (DEBUG_STACK) Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
5029 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005030 mVr2dDisplayId = vr2dDisplayId;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005031 }
5032 }
5033
5034 @Override
5035 public void setFocusedActivity(IBinder token) {
5036 synchronized (mGlobalLock) {
5037 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
5038 if (r == null) {
5039 throw new IllegalArgumentException(
5040 "setFocusedActivity: No activity record matching token=" + token);
5041 }
5042 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
5043 r, "setFocusedActivity")) {
5044 mStackSupervisor.resumeFocusedStackTopActivityLocked();
5045 }
5046 }
5047 }
5048
5049 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005050 public void registerScreenObserver(ScreenObserver observer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005051 mScreenObservers.add(observer);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005052 }
5053
5054 @Override
5055 public boolean isCallerRecents(int callingUid) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005056 return getRecentTasks().isCallerRecents(callingUid);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005057 }
5058
5059 @Override
5060 public boolean isRecentsComponentHomeActivity(int userId) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005061 return getRecentTasks().isRecentsComponentHomeActivity(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005062 }
5063
5064 @Override
5065 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
5066 ActivityTaskManagerService.this.cancelRecentsAnimation(restoreHomeStackPosition);
5067 }
5068
5069 @Override
5070 public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005071 ActivityTaskManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005072 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005073
5074 @Override
5075 public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
5076 synchronized (mGlobalLock) {
5077 mActiveVoiceInteractionServiceComponent = component;
5078 }
5079 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005080
5081 @Override
5082 public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
5083 if (!mAmInternal.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
5084 return;
5085 }
5086 synchronized (mGlobalLock) {
5087 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
5088 if (types == null) {
5089 if (uid < 0) {
5090 return;
5091 }
5092 types = new ArrayMap<>();
5093 mAllowAppSwitchUids.put(userId, types);
5094 }
5095 if (uid < 0) {
5096 types.remove(type);
5097 } else {
5098 types.put(type, uid);
5099 }
5100 }
5101 }
5102
5103 @Override
5104 public void onUserStopped(int userId) {
5105 synchronized (mGlobalLock) {
5106 getRecentTasks().unloadUserDataFromMemoryLocked(userId);
5107 mAllowAppSwitchUids.remove(userId);
5108 }
5109 }
5110
5111 @Override
5112 public boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
5113 synchronized (mGlobalLock) {
5114 return ActivityTaskManagerService.this.isGetTasksAllowed(
5115 caller, callingPid, callingUid);
5116 }
5117 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005118
5119 @Override
5120 public void onProcessAdded(WindowProcessController proc) {
5121 synchronized (mGlobalLock) {
5122 mProcessNames.put(proc.mName, proc.mUid, proc);
5123 }
5124 }
5125
5126 @Override
5127 public void onProcessRemoved(String name, int uid) {
5128 synchronized (mGlobalLock) {
5129 mProcessNames.remove(name, uid);
5130 }
5131 }
5132
5133 @Override
5134 public void onCleanUpApplicationRecord(WindowProcessController proc) {
5135 synchronized (mGlobalLock) {
5136 if (proc == mHomeProcess) {
5137 mHomeProcess = null;
5138 }
5139 if (proc == mPreviousProcess) {
5140 mPreviousProcess = null;
5141 }
5142 }
5143 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005144
5145 @Override
5146 public int getTopProcessState() {
5147 synchronized (mGlobalLock) {
5148 return mTopProcessState;
5149 }
5150 }
5151
5152 @Override
5153 public boolean isSleeping() {
5154 synchronized (mGlobalLock) {
5155 return isSleepingLocked();
5156 }
5157 }
5158
5159 @Override
5160 public boolean isShuttingDown() {
5161 synchronized (mGlobalLock) {
5162 return mShuttingDown;
5163 }
5164 }
5165
5166 @Override
5167 public boolean shuttingDown(boolean booted, int timeout) {
5168 synchronized (mGlobalLock) {
5169 mShuttingDown = true;
5170 mStackSupervisor.prepareForShutdownLocked();
5171 updateEventDispatchingLocked(booted);
5172 return mStackSupervisor.shutdownLocked(timeout);
5173 }
5174 }
5175
5176 @Override
5177 public void enableScreenAfterBoot(boolean booted) {
5178 synchronized (mGlobalLock) {
5179 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5180 SystemClock.uptimeMillis());
5181 mWindowManager.enableScreenAfterBoot();
5182 updateEventDispatchingLocked(booted);
5183 }
5184 }
5185
5186 @Override
5187 public boolean showStrictModeViolationDialog() {
5188 synchronized (mGlobalLock) {
5189 return mShowDialogs && !mSleeping && !mShuttingDown;
5190 }
5191 }
5192
5193 @Override
5194 public void showSystemReadyErrorDialogsIfNeeded() {
5195 synchronized (mGlobalLock) {
5196 try {
5197 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
5198 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
5199 + " data partition or your device will be unstable.");
5200 mUiHandler.post(() -> {
5201 if (mShowDialogs) {
5202 AlertDialog d = new BaseErrorDialog(mUiContext);
5203 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5204 d.setCancelable(false);
5205 d.setTitle(mUiContext.getText(R.string.android_system_label));
5206 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
5207 d.setButton(DialogInterface.BUTTON_POSITIVE,
5208 mUiContext.getText(R.string.ok),
5209 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5210 d.show();
5211 }
5212 });
5213 }
5214 } catch (RemoteException e) {
5215 }
5216
5217 if (!Build.isBuildConsistent()) {
5218 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
5219 mUiHandler.post(() -> {
5220 if (mShowDialogs) {
5221 AlertDialog d = new BaseErrorDialog(mUiContext);
5222 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5223 d.setCancelable(false);
5224 d.setTitle(mUiContext.getText(R.string.android_system_label));
5225 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
5226 d.setButton(DialogInterface.BUTTON_POSITIVE,
5227 mUiContext.getText(R.string.ok),
5228 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5229 d.show();
5230 }
5231 });
5232 }
5233 }
5234 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005235 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07005236}