blob: 77ad04c4e0e510d93df88173012920d76bbb663e [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 }
1198 } else {
1199 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
1200 resultData, "app-request", true);
1201 if (!res) {
1202 Slog.i(TAG, "Failed to finish by app-request");
1203 }
1204 }
1205 return res;
1206 } finally {
1207 Binder.restoreCallingIdentity(origId);
1208 }
1209 }
1210 }
1211
1212 @Override
1213 public boolean finishActivityAffinity(IBinder token) {
1214 synchronized (mGlobalLock) {
1215 final long origId = Binder.clearCallingIdentity();
1216 try {
1217 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1218 if (r == null) {
1219 return false;
1220 }
1221
1222 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
1223 // can finish.
1224 final TaskRecord task = r.getTask();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001225 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001226 return false;
1227 }
1228 return task.getStack().finishActivityAffinityLocked(r);
1229 } finally {
1230 Binder.restoreCallingIdentity(origId);
1231 }
1232 }
1233 }
1234
1235 @Override
1236 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
1237 final long origId = Binder.clearCallingIdentity();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001238 try {
1239 WindowProcessController proc = null;
1240 synchronized (mGlobalLock) {
1241 ActivityStack stack = ActivityRecord.getStackLocked(token);
1242 if (stack == null) {
1243 return;
1244 }
1245 final ActivityRecord r = mStackSupervisor.activityIdleInternalLocked(token,
1246 false /* fromTimeout */, false /* processPausingActivities */, config);
1247 if (r != null) {
1248 proc = r.app;
1249 }
1250 if (stopProfiling && proc != null) {
1251 proc.clearProfilerIfNeeded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001252 }
1253 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001254 } finally {
1255 Binder.restoreCallingIdentity(origId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001256 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001257 }
1258
1259 @Override
1260 public final void activityResumed(IBinder token) {
1261 final long origId = Binder.clearCallingIdentity();
1262 synchronized (mGlobalLock) {
1263 ActivityRecord.activityResumedLocked(token);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001264 mWindowManager.notifyAppResumedFinished(token);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001265 }
1266 Binder.restoreCallingIdentity(origId);
1267 }
1268
1269 @Override
1270 public final void activityPaused(IBinder token) {
1271 final long origId = Binder.clearCallingIdentity();
1272 synchronized (mGlobalLock) {
1273 ActivityStack stack = ActivityRecord.getStackLocked(token);
1274 if (stack != null) {
1275 stack.activityPausedLocked(token, false);
1276 }
1277 }
1278 Binder.restoreCallingIdentity(origId);
1279 }
1280
1281 @Override
1282 public final void activityStopped(IBinder token, Bundle icicle,
1283 PersistableBundle persistentState, CharSequence description) {
1284 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
1285
1286 // Refuse possible leaked file descriptors
1287 if (icicle != null && icicle.hasFileDescriptors()) {
1288 throw new IllegalArgumentException("File descriptors passed in Bundle");
1289 }
1290
1291 final long origId = Binder.clearCallingIdentity();
1292
1293 synchronized (mGlobalLock) {
1294 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1295 if (r != null) {
1296 r.activityStoppedLocked(icicle, persistentState, description);
1297 }
1298 }
1299
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001300 mAmInternal.trimApplications();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001301
1302 Binder.restoreCallingIdentity(origId);
1303 }
1304
1305 @Override
1306 public final void activityDestroyed(IBinder token) {
1307 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
1308 synchronized (mGlobalLock) {
1309 ActivityStack stack = ActivityRecord.getStackLocked(token);
1310 if (stack != null) {
1311 stack.activityDestroyedLocked(token, "activityDestroyed");
1312 }
1313 }
1314 }
1315
1316 @Override
1317 public final void activityRelaunched(IBinder token) {
1318 final long origId = Binder.clearCallingIdentity();
1319 synchronized (mGlobalLock) {
1320 mStackSupervisor.activityRelaunchedLocked(token);
1321 }
1322 Binder.restoreCallingIdentity(origId);
1323 }
1324
1325 public final void activitySlept(IBinder token) {
1326 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
1327
1328 final long origId = Binder.clearCallingIdentity();
1329
1330 synchronized (mGlobalLock) {
1331 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1332 if (r != null) {
1333 mStackSupervisor.activitySleptLocked(r);
1334 }
1335 }
1336
1337 Binder.restoreCallingIdentity(origId);
1338 }
1339
1340 @Override
1341 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
1342 synchronized (mGlobalLock) {
1343 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1344 if (r == null) {
1345 return;
1346 }
1347 final long origId = Binder.clearCallingIdentity();
1348 try {
1349 r.setRequestedOrientation(requestedOrientation);
1350 } finally {
1351 Binder.restoreCallingIdentity(origId);
1352 }
1353 }
1354 }
1355
1356 @Override
1357 public int getRequestedOrientation(IBinder token) {
1358 synchronized (mGlobalLock) {
1359 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1360 if (r == null) {
1361 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
1362 }
1363 return r.getRequestedOrientation();
1364 }
1365 }
1366
1367 @Override
1368 public void setImmersive(IBinder token, boolean immersive) {
1369 synchronized (mGlobalLock) {
1370 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1371 if (r == null) {
1372 throw new IllegalArgumentException();
1373 }
1374 r.immersive = immersive;
1375
1376 // update associated state if we're frontmost
Andrii Kulian52d255c2018-07-13 11:32:19 -07001377 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001378 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001379 applyUpdateLockStateLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001380 }
1381 }
1382 }
1383
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001384 void applyUpdateLockStateLocked(ActivityRecord r) {
1385 // Modifications to the UpdateLock state are done on our handler, outside
1386 // the activity manager's locks. The new state is determined based on the
1387 // state *now* of the relevant activity record. The object is passed to
1388 // the handler solely for logging detail, not to be consulted/modified.
1389 final boolean nextState = r != null && r.immersive;
1390 mH.post(() -> {
1391 if (mUpdateLock.isHeld() != nextState) {
1392 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1393 "Applying new update lock state '" + nextState + "' for " + r);
1394 if (nextState) {
1395 mUpdateLock.acquire();
1396 } else {
1397 mUpdateLock.release();
1398 }
1399 }
1400 });
1401 }
1402
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001403 @Override
1404 public boolean isImmersive(IBinder token) {
1405 synchronized (mGlobalLock) {
1406 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1407 if (r == null) {
1408 throw new IllegalArgumentException();
1409 }
1410 return r.immersive;
1411 }
1412 }
1413
1414 @Override
1415 public boolean isTopActivityImmersive() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001416 enforceNotIsolatedCaller("isTopActivityImmersive");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001417 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001418 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001419 return (r != null) ? r.immersive : false;
1420 }
1421 }
1422
1423 @Override
1424 public void overridePendingTransition(IBinder token, String packageName,
1425 int enterAnim, int exitAnim) {
1426 synchronized (mGlobalLock) {
1427 ActivityRecord self = ActivityRecord.isInStackLocked(token);
1428 if (self == null) {
1429 return;
1430 }
1431
1432 final long origId = Binder.clearCallingIdentity();
1433
1434 if (self.isState(
1435 ActivityStack.ActivityState.RESUMED, ActivityStack.ActivityState.PAUSING)) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001436 mWindowManager.overridePendingAppTransition(packageName,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001437 enterAnim, exitAnim, null);
1438 }
1439
1440 Binder.restoreCallingIdentity(origId);
1441 }
1442 }
1443
1444 @Override
1445 public int getFrontActivityScreenCompatMode() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001446 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
1447 ApplicationInfo ai;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001448 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001449 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001450 if (r == null) {
1451 return ActivityManager.COMPAT_MODE_UNKNOWN;
1452 }
1453 ai = r.info.applicationInfo;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001454 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001455
1456 return mAmInternal.getPackageScreenCompatMode(ai);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001457 }
1458
1459 @Override
1460 public void setFrontActivityScreenCompatMode(int mode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001461 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001462 "setFrontActivityScreenCompatMode");
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001463 ApplicationInfo ai;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001464 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001465 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001466 if (r == null) {
1467 Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity");
1468 return;
1469 }
1470 ai = r.info.applicationInfo;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001471 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001472
1473 mAmInternal.setPackageScreenCompatMode(ai, mode);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001474 }
1475
1476 @Override
1477 public int getLaunchedFromUid(IBinder activityToken) {
1478 ActivityRecord srec;
1479 synchronized (mGlobalLock) {
1480 srec = ActivityRecord.forTokenLocked(activityToken);
1481 }
1482 if (srec == null) {
1483 return -1;
1484 }
1485 return srec.launchedFromUid;
1486 }
1487
1488 @Override
1489 public String getLaunchedFromPackage(IBinder activityToken) {
1490 ActivityRecord srec;
1491 synchronized (mGlobalLock) {
1492 srec = ActivityRecord.forTokenLocked(activityToken);
1493 }
1494 if (srec == null) {
1495 return null;
1496 }
1497 return srec.launchedFromPackage;
1498 }
1499
1500 @Override
1501 public boolean convertFromTranslucent(IBinder token) {
1502 final long origId = Binder.clearCallingIdentity();
1503 try {
1504 synchronized (mGlobalLock) {
1505 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1506 if (r == null) {
1507 return false;
1508 }
1509 final boolean translucentChanged = r.changeWindowTranslucency(true);
1510 if (translucentChanged) {
1511 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
1512 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001513 mWindowManager.setAppFullscreen(token, true);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001514 return translucentChanged;
1515 }
1516 } finally {
1517 Binder.restoreCallingIdentity(origId);
1518 }
1519 }
1520
1521 @Override
1522 public boolean convertToTranslucent(IBinder token, Bundle options) {
1523 SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
1524 final long origId = Binder.clearCallingIdentity();
1525 try {
1526 synchronized (mGlobalLock) {
1527 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1528 if (r == null) {
1529 return false;
1530 }
1531 final TaskRecord task = r.getTask();
1532 int index = task.mActivities.lastIndexOf(r);
1533 if (index > 0) {
1534 ActivityRecord under = task.mActivities.get(index - 1);
1535 under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
1536 }
1537 final boolean translucentChanged = r.changeWindowTranslucency(false);
1538 if (translucentChanged) {
1539 r.getStack().convertActivityToTranslucent(r);
1540 }
1541 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001542 mWindowManager.setAppFullscreen(token, false);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001543 return translucentChanged;
1544 }
1545 } finally {
1546 Binder.restoreCallingIdentity(origId);
1547 }
1548 }
1549
1550 @Override
1551 public void notifyActivityDrawn(IBinder token) {
1552 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
1553 synchronized (mGlobalLock) {
1554 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
1555 if (r != null) {
1556 r.getStack().notifyActivityDrawnLocked(r);
1557 }
1558 }
1559 }
1560
1561 @Override
1562 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
1563 synchronized (mGlobalLock) {
1564 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1565 if (r == null) {
1566 return;
1567 }
1568 r.reportFullyDrawnLocked(restoredFromBundle);
1569 }
1570 }
1571
1572 @Override
1573 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
1574 synchronized (mGlobalLock) {
1575 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
1576 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
1577 return stack.mDisplayId;
1578 }
1579 return DEFAULT_DISPLAY;
1580 }
1581 }
1582
1583 @Override
1584 public ActivityManager.StackInfo getFocusedStackInfo() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001585 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001586 long ident = Binder.clearCallingIdentity();
1587 try {
1588 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001589 ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001590 if (focusedStack != null) {
1591 return mStackSupervisor.getStackInfo(focusedStack.mStackId);
1592 }
1593 return null;
1594 }
1595 } finally {
1596 Binder.restoreCallingIdentity(ident);
1597 }
1598 }
1599
1600 @Override
1601 public void setFocusedStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001602 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001603 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
1604 final long callingId = Binder.clearCallingIdentity();
1605 try {
1606 synchronized (mGlobalLock) {
1607 final ActivityStack stack = mStackSupervisor.getStack(stackId);
1608 if (stack == null) {
1609 Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
1610 return;
1611 }
1612 final ActivityRecord r = stack.topRunningActivityLocked();
1613 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
1614 r, "setFocusedStack")) {
1615 mStackSupervisor.resumeFocusedStackTopActivityLocked();
1616 }
1617 }
1618 } finally {
1619 Binder.restoreCallingIdentity(callingId);
1620 }
1621 }
1622
1623 @Override
1624 public void setFocusedTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001625 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001626 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
1627 final long callingId = Binder.clearCallingIdentity();
1628 try {
1629 synchronized (mGlobalLock) {
1630 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1631 if (task == null) {
1632 return;
1633 }
1634 final ActivityRecord r = task.topRunningActivityLocked();
1635 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
1636 mStackSupervisor.resumeFocusedStackTopActivityLocked();
1637 }
1638 }
1639 } finally {
1640 Binder.restoreCallingIdentity(callingId);
1641 }
1642 }
1643
1644 @Override
1645 public boolean removeTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001646 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001647 synchronized (mGlobalLock) {
1648 final long ident = Binder.clearCallingIdentity();
1649 try {
1650 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
1651 "remove-task");
1652 } finally {
1653 Binder.restoreCallingIdentity(ident);
1654 }
1655 }
1656 }
1657
1658 @Override
1659 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
1660 synchronized (mGlobalLock) {
1661 final ActivityRecord srec = ActivityRecord.forTokenLocked(token);
1662 if (srec != null) {
1663 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
1664 }
1665 }
1666 return false;
1667 }
1668
1669 @Override
1670 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
1671 Intent resultData) {
1672
1673 synchronized (mGlobalLock) {
1674 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
1675 if (r != null) {
1676 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
1677 }
1678 return false;
1679 }
1680 }
1681
1682 /**
1683 * Attempts to move a task backwards in z-order (the order of activities within the task is
1684 * unchanged).
1685 *
1686 * There are several possible results of this call:
1687 * - if the task is locked, then we will show the lock toast
1688 * - if there is a task behind the provided task, then that task is made visible and resumed as
1689 * this task is moved to the back
1690 * - otherwise, if there are no other tasks in the stack:
1691 * - if this task is in the pinned stack, then we remove the stack completely, which will
1692 * have the effect of moving the task to the top or bottom of the fullscreen stack
1693 * (depending on whether it is visible)
1694 * - otherwise, we simply return home and hide this task
1695 *
1696 * @param token A reference to the activity we wish to move
1697 * @param nonRoot If false then this only works if the activity is the root
1698 * of a task; if true it will work for any activity in a task.
1699 * @return Returns true if the move completed, false if not.
1700 */
1701 @Override
1702 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001703 enforceNotIsolatedCaller("moveActivityTaskToBack");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001704 synchronized (mGlobalLock) {
1705 final long origId = Binder.clearCallingIdentity();
1706 try {
1707 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
1708 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1709 if (task != null) {
1710 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
1711 }
1712 } finally {
1713 Binder.restoreCallingIdentity(origId);
1714 }
1715 }
1716 return false;
1717 }
1718
1719 @Override
1720 public Rect getTaskBounds(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001721 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001722 long ident = Binder.clearCallingIdentity();
1723 Rect rect = new Rect();
1724 try {
1725 synchronized (mGlobalLock) {
1726 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
1727 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1728 if (task == null) {
1729 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
1730 return rect;
1731 }
1732 if (task.getStack() != null) {
1733 // Return the bounds from window manager since it will be adjusted for various
1734 // things like the presense of a docked stack for tasks that aren't resizeable.
1735 task.getWindowContainerBounds(rect);
1736 } else {
1737 // Task isn't in window manager yet since it isn't associated with a stack.
1738 // Return the persist value from activity manager
1739 if (!task.matchParentBounds()) {
1740 rect.set(task.getBounds());
1741 } else if (task.mLastNonFullscreenBounds != null) {
1742 rect.set(task.mLastNonFullscreenBounds);
1743 }
1744 }
1745 }
1746 } finally {
1747 Binder.restoreCallingIdentity(ident);
1748 }
1749 return rect;
1750 }
1751
1752 @Override
1753 public ActivityManager.TaskDescription getTaskDescription(int id) {
1754 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001755 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001756 MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
1757 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
1758 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1759 if (tr != null) {
1760 return tr.lastTaskDescription;
1761 }
1762 }
1763 return null;
1764 }
1765
1766 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001767 public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
1768 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
1769 setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
1770 toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
1771 return;
1772 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001773 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001774 synchronized (mGlobalLock) {
1775 final long ident = Binder.clearCallingIdentity();
1776 try {
1777 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1778 if (task == null) {
1779 Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
1780 return;
1781 }
1782
1783 if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
1784 + " to windowingMode=" + windowingMode + " toTop=" + toTop);
1785
1786 if (!task.isActivityTypeStandardOrUndefined()) {
1787 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
1788 + " non-standard task " + taskId + " to windowing mode="
1789 + windowingMode);
1790 }
1791
1792 final ActivityStack stack = task.getStack();
1793 if (toTop) {
1794 stack.moveToFront("setTaskWindowingMode", task);
1795 }
1796 stack.setWindowingMode(windowingMode);
1797 } finally {
1798 Binder.restoreCallingIdentity(ident);
1799 }
1800 }
1801 }
1802
1803 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001804 public String getCallingPackage(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001805 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001806 ActivityRecord r = getCallingRecordLocked(token);
1807 return r != null ? r.info.packageName : null;
1808 }
1809 }
1810
1811 @Override
1812 public ComponentName getCallingActivity(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001813 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001814 ActivityRecord r = getCallingRecordLocked(token);
1815 return r != null ? r.intent.getComponent() : null;
1816 }
1817 }
1818
1819 private ActivityRecord getCallingRecordLocked(IBinder token) {
1820 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1821 if (r == null) {
1822 return null;
1823 }
1824 return r.resultTo;
1825 }
1826
1827 @Override
1828 public void unhandledBack() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001829 mAmInternal.enforceCallingPermission(android.Manifest.permission.FORCE_BACK, "unhandledBack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001830
1831 synchronized (mGlobalLock) {
1832 final long origId = Binder.clearCallingIdentity();
1833 try {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001834 getTopDisplayFocusedStack().unhandledBackLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001835 } finally {
1836 Binder.restoreCallingIdentity(origId);
1837 }
1838 }
1839 }
1840
1841 /**
1842 * TODO: Add mController hook
1843 */
1844 @Override
1845 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001846 mAmInternal.enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001847
1848 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
1849 synchronized (mGlobalLock) {
1850 moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
1851 false /* fromRecents */);
1852 }
1853 }
1854
1855 void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
1856 boolean fromRecents) {
1857
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001858 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001859 Binder.getCallingUid(), -1, -1, "Task to front")) {
1860 SafeActivityOptions.abort(options);
1861 return;
1862 }
1863 final long origId = Binder.clearCallingIdentity();
1864 try {
1865 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1866 if (task == null) {
1867 Slog.d(TAG, "Could not find task for id: "+ taskId);
1868 return;
1869 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001870 if (getLockTaskController().isLockTaskModeViolation(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001871 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
1872 return;
1873 }
1874 ActivityOptions realOptions = options != null
1875 ? options.getOptions(mStackSupervisor)
1876 : null;
1877 mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
1878 false /* forceNonResizable */);
1879
1880 final ActivityRecord topActivity = task.getTopActivity();
1881 if (topActivity != null) {
1882
1883 // We are reshowing a task, use a starting window to hide the initial draw delay
1884 // so the transition can start earlier.
1885 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
1886 true /* taskSwitch */, fromRecents);
1887 }
1888 } finally {
1889 Binder.restoreCallingIdentity(origId);
1890 }
1891 SafeActivityOptions.abort(options);
1892 }
1893
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001894 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
1895 int callingPid, int callingUid, String name) {
1896 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
1897 return true;
1898 }
1899
1900 if (getRecentTasks().isCallerRecents(sourceUid)) {
1901 return true;
1902 }
1903
1904 int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
1905 if (perm == PackageManager.PERMISSION_GRANTED) {
1906 return true;
1907 }
1908 if (checkAllowAppSwitchUid(sourceUid)) {
1909 return true;
1910 }
1911
1912 // If the actual IPC caller is different from the logical source, then
1913 // also see if they are allowed to control app switches.
1914 if (callingUid != -1 && callingUid != sourceUid) {
1915 perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
1916 if (perm == PackageManager.PERMISSION_GRANTED) {
1917 return true;
1918 }
1919 if (checkAllowAppSwitchUid(callingUid)) {
1920 return true;
1921 }
1922 }
1923
1924 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
1925 return false;
1926 }
1927
1928 private boolean checkAllowAppSwitchUid(int uid) {
1929 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
1930 if (types != null) {
1931 for (int i = types.size() - 1; i >= 0; i--) {
1932 if (types.valueAt(i).intValue() == uid) {
1933 return true;
1934 }
1935 }
1936 }
1937 return false;
1938 }
1939
1940 @Override
1941 public void setActivityController(IActivityController controller, boolean imAMonkey) {
1942 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
1943 "setActivityController()");
1944 synchronized (mGlobalLock) {
1945 mController = controller;
1946 mControllerIsAMonkey = imAMonkey;
1947 Watchdog.getInstance().setActivityController(controller);
1948 }
1949 }
1950
1951 boolean isControllerAMonkey() {
1952 synchronized (mGlobalLock) {
1953 return mController != null && mControllerIsAMonkey;
1954 }
1955 }
1956
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001957 @Override
1958 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
1959 synchronized (mGlobalLock) {
1960 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
1961 }
1962 }
1963
1964 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001965 public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum) {
1966 return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
1967 }
1968
1969 @Override
1970 public List<ActivityManager.RunningTaskInfo> getFilteredTasks(int maxNum,
1971 @WindowConfiguration.ActivityType int ignoreActivityType,
1972 @WindowConfiguration.WindowingMode int ignoreWindowingMode) {
1973 final int callingUid = Binder.getCallingUid();
1974 ArrayList<ActivityManager.RunningTaskInfo> list = new ArrayList<>();
1975
1976 synchronized (mGlobalLock) {
1977 if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
1978
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001979 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001980 callingUid);
1981 mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
1982 ignoreWindowingMode, callingUid, allowed);
1983 }
1984
1985 return list;
1986 }
1987
1988 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001989 public final void finishSubActivity(IBinder token, String resultWho, int requestCode) {
1990 synchronized (mGlobalLock) {
1991 final long origId = Binder.clearCallingIdentity();
1992 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1993 if (r != null) {
1994 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
1995 }
1996 Binder.restoreCallingIdentity(origId);
1997 }
1998 }
1999
2000 @Override
2001 public boolean willActivityBeVisible(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002002 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002003 ActivityStack stack = ActivityRecord.getStackLocked(token);
2004 if (stack != null) {
2005 return stack.willActivityBeVisibleLocked(token);
2006 }
2007 return false;
2008 }
2009 }
2010
2011 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002012 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002013 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002014 synchronized (mGlobalLock) {
2015 final long ident = Binder.clearCallingIdentity();
2016 try {
2017 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2018 if (task == null) {
2019 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
2020 return;
2021 }
2022
2023 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
2024 + " to stackId=" + stackId + " toTop=" + toTop);
2025
2026 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2027 if (stack == null) {
2028 throw new IllegalStateException(
2029 "moveTaskToStack: No stack for stackId=" + stackId);
2030 }
2031 if (!stack.isActivityTypeStandardOrUndefined()) {
2032 throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
2033 + taskId + " to stack " + stackId);
2034 }
2035 if (stack.inSplitScreenPrimaryWindowingMode()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002036 mWindowManager.setDockedStackCreateState(
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002037 SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
2038 }
2039 task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
2040 "moveTaskToStack");
2041 } finally {
2042 Binder.restoreCallingIdentity(ident);
2043 }
2044 }
2045 }
2046
2047 @Override
2048 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
2049 boolean preserveWindows, boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002050 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002051
2052 final long ident = Binder.clearCallingIdentity();
2053 try {
2054 synchronized (mGlobalLock) {
2055 if (animate) {
2056 final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
2057 if (stack == null) {
2058 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2059 return;
2060 }
2061 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
2062 throw new IllegalArgumentException("Stack: " + stackId
2063 + " doesn't support animated resize.");
2064 }
2065 stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
2066 animationDuration, false /* fromFullscreen */);
2067 } else {
2068 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2069 if (stack == null) {
2070 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2071 return;
2072 }
2073 mStackSupervisor.resizeStackLocked(stack, destBounds,
2074 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
2075 preserveWindows, allowResizeInDockedMode, !DEFER_RESUME);
2076 }
2077 }
2078 } finally {
2079 Binder.restoreCallingIdentity(ident);
2080 }
2081 }
2082
2083 /**
2084 * Moves the specified task to the primary-split-screen stack.
2085 *
2086 * @param taskId Id of task to move.
2087 * @param createMode The mode the primary split screen stack should be created in if it doesn't
2088 * exist already. See
2089 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
2090 * and
2091 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
2092 * @param toTop If the task and stack should be moved to the top.
2093 * @param animate Whether we should play an animation for the moving the task.
2094 * @param initialBounds If the primary stack gets created, it will use these bounds for the
2095 * stack. Pass {@code null} to use default bounds.
2096 * @param showRecents If the recents activity should be shown on the other side of the task
2097 * going into split-screen mode.
2098 */
2099 @Override
2100 public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode,
2101 boolean toTop, boolean animate, Rect initialBounds, boolean showRecents) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002102 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002103 "setTaskWindowingModeSplitScreenPrimary()");
2104 synchronized (mGlobalLock) {
2105 final long ident = Binder.clearCallingIdentity();
2106 try {
2107 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2108 if (task == null) {
2109 Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
2110 return false;
2111 }
2112 if (DEBUG_STACK) Slog.d(TAG_STACK,
2113 "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
2114 + " to createMode=" + createMode + " toTop=" + toTop);
2115 if (!task.isActivityTypeStandardOrUndefined()) {
2116 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
2117 + " non-standard task " + taskId + " to split-screen windowing mode");
2118 }
2119
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002120 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002121 final int windowingMode = task.getWindowingMode();
2122 final ActivityStack stack = task.getStack();
2123 if (toTop) {
2124 stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
2125 }
2126 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
2127 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */);
2128 return windowingMode != task.getWindowingMode();
2129 } finally {
2130 Binder.restoreCallingIdentity(ident);
2131 }
2132 }
2133 }
2134
2135 /**
2136 * Removes stacks in the input windowing modes from the system if they are of activity type
2137 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
2138 */
2139 @Override
2140 public void removeStacksInWindowingModes(int[] windowingModes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002141 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002142 "removeStacksInWindowingModes()");
2143
2144 synchronized (mGlobalLock) {
2145 final long ident = Binder.clearCallingIdentity();
2146 try {
2147 mStackSupervisor.removeStacksInWindowingModes(windowingModes);
2148 } finally {
2149 Binder.restoreCallingIdentity(ident);
2150 }
2151 }
2152 }
2153
2154 @Override
2155 public void removeStacksWithActivityTypes(int[] activityTypes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002156 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002157 "removeStacksWithActivityTypes()");
2158
2159 synchronized (mGlobalLock) {
2160 final long ident = Binder.clearCallingIdentity();
2161 try {
2162 mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
2163 } finally {
2164 Binder.restoreCallingIdentity(ident);
2165 }
2166 }
2167 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002168
2169 @Override
2170 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
2171 int userId) {
2172 final int callingUid = Binder.getCallingUid();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002173 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, "getRecentTasks");
2174 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002175 callingUid);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002176 final boolean detailed = checkGetTasksPermission(
2177 android.Manifest.permission.GET_DETAILED_TASKS, Binder.getCallingPid(),
2178 UserHandle.getAppId(callingUid))
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002179 == PackageManager.PERMISSION_GRANTED;
2180
2181 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002182 return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002183 callingUid);
2184 }
2185 }
2186
2187 @Override
2188 public List<ActivityManager.StackInfo> getAllStackInfos() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002189 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002190 long ident = Binder.clearCallingIdentity();
2191 try {
2192 synchronized (mGlobalLock) {
2193 return mStackSupervisor.getAllStackInfosLocked();
2194 }
2195 } finally {
2196 Binder.restoreCallingIdentity(ident);
2197 }
2198 }
2199
2200 @Override
2201 public ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002202 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002203 long ident = Binder.clearCallingIdentity();
2204 try {
2205 synchronized (mGlobalLock) {
2206 return mStackSupervisor.getStackInfo(windowingMode, activityType);
2207 }
2208 } finally {
2209 Binder.restoreCallingIdentity(ident);
2210 }
2211 }
2212
2213 @Override
2214 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002215 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002216 final long callingUid = Binder.getCallingUid();
2217 final long origId = Binder.clearCallingIdentity();
2218 try {
2219 synchronized (mGlobalLock) {
2220 // Cancel the recents animation synchronously (do not hold the WM lock)
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002221 mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002222 ? REORDER_MOVE_TO_ORIGINAL_POSITION
2223 : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
2224 }
2225 } finally {
2226 Binder.restoreCallingIdentity(origId);
2227 }
2228 }
2229
2230 @Override
2231 public void startLockTaskModeByToken(IBinder token) {
2232 synchronized (mGlobalLock) {
2233 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2234 if (r == null) {
2235 return;
2236 }
2237 startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
2238 }
2239 }
2240
2241 @Override
2242 public void startSystemLockTaskMode(int taskId) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002243 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002244 // This makes inner call to look as if it was initiated by system.
2245 long ident = Binder.clearCallingIdentity();
2246 try {
2247 synchronized (mGlobalLock) {
2248 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2249
2250 // When starting lock task mode the stack must be in front and focused
2251 task.getStack().moveToFront("startSystemLockTaskMode");
2252 startLockTaskModeLocked(task, true /* isSystemCaller */);
2253 }
2254 } finally {
2255 Binder.restoreCallingIdentity(ident);
2256 }
2257 }
2258
2259 @Override
2260 public void stopLockTaskModeByToken(IBinder token) {
2261 synchronized (mGlobalLock) {
2262 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2263 if (r == null) {
2264 return;
2265 }
2266 stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
2267 }
2268 }
2269
2270 /**
2271 * This API should be called by SystemUI only when user perform certain action to dismiss
2272 * lock task mode. We should only dismiss pinned lock task mode in this case.
2273 */
2274 @Override
2275 public void stopSystemLockTaskMode() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002276 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002277 stopLockTaskModeInternal(null, true /* isSystemCaller */);
2278 }
2279
2280 private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
2281 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
2282 if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
2283 return;
2284 }
2285
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002286 final ActivityStack stack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002287 if (stack == null || task != stack.topTask()) {
2288 throw new IllegalArgumentException("Invalid task, not in foreground");
2289 }
2290
2291 // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
2292 // system or a specific app.
2293 // * System-initiated requests will only start the pinned mode (screen pinning)
2294 // * App-initiated requests
2295 // - will put the device in fully locked mode (LockTask), if the app is whitelisted
2296 // - will start the pinned mode, otherwise
2297 final int callingUid = Binder.getCallingUid();
2298 long ident = Binder.clearCallingIdentity();
2299 try {
2300 // When a task is locked, dismiss the pinned stack if it exists
2301 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2302
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002303 getLockTaskController().startLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002304 } finally {
2305 Binder.restoreCallingIdentity(ident);
2306 }
2307 }
2308
2309 private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
2310 final int callingUid = Binder.getCallingUid();
2311 long ident = Binder.clearCallingIdentity();
2312 try {
2313 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002314 getLockTaskController().stopLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002315 }
2316 // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
2317 // task and jumping straight into a call in the case of emergency call back.
2318 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
2319 if (tm != null) {
2320 tm.showInCallScreen(false);
2321 }
2322 } finally {
2323 Binder.restoreCallingIdentity(ident);
2324 }
2325 }
2326
2327 @Override
2328 public boolean isInLockTaskMode() {
2329 return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
2330 }
2331
2332 @Override
2333 public int getLockTaskModeState() {
2334 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002335 return getLockTaskController().getLockTaskModeState();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002336 }
2337 }
2338
2339 @Override
2340 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
2341 synchronized (mGlobalLock) {
2342 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2343 if (r != null) {
2344 r.setTaskDescription(td);
2345 final TaskRecord task = r.getTask();
2346 task.updateTaskDescription();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002347 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002348 }
2349 }
2350 }
2351
2352 @Override
2353 public Bundle getActivityOptions(IBinder token) {
2354 final long origId = Binder.clearCallingIdentity();
2355 try {
2356 synchronized (mGlobalLock) {
2357 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
2358 if (r != null) {
2359 final ActivityOptions activityOptions = r.takeOptionsLocked();
2360 return activityOptions == null ? null : activityOptions.toBundle();
2361 }
2362 return null;
2363 }
2364 } finally {
2365 Binder.restoreCallingIdentity(origId);
2366 }
2367 }
2368
2369 @Override
2370 public List<IBinder> getAppTasks(String callingPackage) {
2371 int callingUid = Binder.getCallingUid();
2372 long ident = Binder.clearCallingIdentity();
2373 try {
2374 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002375 return mRecentTasks.getAppTasksList(callingUid, callingPackage);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002376 }
2377 } finally {
2378 Binder.restoreCallingIdentity(ident);
2379 }
2380 }
2381
2382 @Override
2383 public void finishVoiceTask(IVoiceInteractionSession session) {
2384 synchronized (mGlobalLock) {
2385 final long origId = Binder.clearCallingIdentity();
2386 try {
2387 // TODO: VI Consider treating local voice interactions and voice tasks
2388 // differently here
2389 mStackSupervisor.finishVoiceTask(session);
2390 } finally {
2391 Binder.restoreCallingIdentity(origId);
2392 }
2393 }
2394
2395 }
2396
2397 @Override
2398 public boolean isTopOfTask(IBinder token) {
2399 synchronized (mGlobalLock) {
2400 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2401 if (r == null) {
2402 throw new IllegalArgumentException();
2403 }
2404 return r.getTask().getTopActivity() == r;
2405 }
2406 }
2407
2408 @Override
2409 public void notifyLaunchTaskBehindComplete(IBinder token) {
2410 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
2411 }
2412
2413 @Override
2414 public void notifyEnterAnimationComplete(IBinder token) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002415 mH.post(() -> {
2416 synchronized (mGlobalLock) {
2417 ActivityRecord r = ActivityRecord.forTokenLocked(token);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002418 if (r != null && r.attachedToProcess()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002419 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002420 r.app.getThread().scheduleEnterAnimationComplete(r.appToken);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002421 } catch (RemoteException e) {
2422 }
2423 }
2424 }
2425
2426 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002427 }
2428
2429 /** Called from an app when assist data is ready. */
2430 @Override
2431 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
2432 AssistContent content, Uri referrer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002433 PendingAssistExtras pae = (PendingAssistExtras) token;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002434 synchronized (pae) {
2435 pae.result = extras;
2436 pae.structure = structure;
2437 pae.content = content;
2438 if (referrer != null) {
2439 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
2440 }
2441 if (structure != null) {
2442 structure.setHomeActivity(pae.isHome);
2443 }
2444 pae.haveResult = true;
2445 pae.notifyAll();
2446 if (pae.intent == null && pae.receiver == null) {
2447 // Caller is just waiting for the result.
2448 return;
2449 }
2450 }
2451 // We are now ready to launch the assist activity.
2452 IAssistDataReceiver sendReceiver = null;
2453 Bundle sendBundle = null;
2454 synchronized (mGlobalLock) {
2455 buildAssistBundleLocked(pae, extras);
2456 boolean exists = mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002457 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002458 if (!exists) {
2459 // Timed out.
2460 return;
2461 }
2462
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002463 if ((sendReceiver = pae.receiver) != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002464 // Caller wants result sent back to them.
2465 sendBundle = new Bundle();
2466 sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
2467 sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
2468 sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
2469 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
2470 }
2471 }
2472 if (sendReceiver != null) {
2473 try {
2474 sendReceiver.onHandleAssistData(sendBundle);
2475 } catch (RemoteException e) {
2476 }
2477 return;
2478 }
2479
2480 final long ident = Binder.clearCallingIdentity();
2481 try {
2482 if (TextUtils.equals(pae.intent.getAction(),
2483 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
2484 pae.intent.putExtras(pae.extras);
2485 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
2486 } else {
2487 pae.intent.replaceExtras(pae.extras);
2488 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
2489 | Intent.FLAG_ACTIVITY_SINGLE_TOP
2490 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002491 mAmInternal.closeSystemDialogs("assist");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002492
2493 try {
2494 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
2495 } catch (ActivityNotFoundException e) {
2496 Slog.w(TAG, "No activity to handle assist action.", e);
2497 }
2498 }
2499 } finally {
2500 Binder.restoreCallingIdentity(ident);
2501 }
2502 }
2503
2504 @Override
2505 public int addAppTask(IBinder activityToken, Intent intent,
2506 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
2507 final int callingUid = Binder.getCallingUid();
2508 final long callingIdent = Binder.clearCallingIdentity();
2509
2510 try {
2511 synchronized (mGlobalLock) {
2512 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
2513 if (r == null) {
2514 throw new IllegalArgumentException("Activity does not exist; token="
2515 + activityToken);
2516 }
2517 ComponentName comp = intent.getComponent();
2518 if (comp == null) {
2519 throw new IllegalArgumentException("Intent " + intent
2520 + " must specify explicit component");
2521 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002522 if (thumbnail.getWidth() != mThumbnailWidth
2523 || thumbnail.getHeight() != mThumbnailHeight) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002524 throw new IllegalArgumentException("Bad thumbnail size: got "
2525 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002526 + mThumbnailWidth + "x" + mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002527 }
2528 if (intent.getSelector() != null) {
2529 intent.setSelector(null);
2530 }
2531 if (intent.getSourceBounds() != null) {
2532 intent.setSourceBounds(null);
2533 }
2534 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
2535 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
2536 // The caller has added this as an auto-remove task... that makes no
2537 // sense, so turn off auto-remove.
2538 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
2539 }
2540 }
2541 final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
2542 STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
2543 if (ainfo.applicationInfo.uid != callingUid) {
2544 throw new SecurityException(
2545 "Can't add task for another application: target uid="
2546 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
2547 }
2548
2549 final ActivityStack stack = r.getStack();
2550 final TaskRecord task = stack.createTaskRecord(
2551 mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent,
2552 null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002553 if (!mRecentTasks.addToBottom(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002554 // The app has too many tasks already and we can't add any more
2555 stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
2556 return INVALID_TASK_ID;
2557 }
2558 task.lastTaskDescription.copyFrom(description);
2559
2560 // TODO: Send the thumbnail to WM to store it.
2561
2562 return task.taskId;
2563 }
2564 } finally {
2565 Binder.restoreCallingIdentity(callingIdent);
2566 }
2567 }
2568
2569 @Override
2570 public Point getAppTaskThumbnailSize() {
2571 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002572 return new Point(mThumbnailWidth, mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002573 }
2574 }
2575
2576 @Override
2577 public void setTaskResizeable(int taskId, int resizeableMode) {
2578 synchronized (mGlobalLock) {
2579 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
2580 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
2581 if (task == null) {
2582 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
2583 return;
2584 }
2585 task.setResizeMode(resizeableMode);
2586 }
2587 }
2588
2589 @Override
2590 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002591 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002592 long ident = Binder.clearCallingIdentity();
2593 try {
2594 synchronized (mGlobalLock) {
2595 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2596 if (task == null) {
2597 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
2598 return;
2599 }
2600 // Place the task in the right stack if it isn't there already based on
2601 // the requested bounds.
2602 // The stack transition logic is:
2603 // - a null bounds on a freeform task moves that task to fullscreen
2604 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
2605 // that task to freeform
2606 // - otherwise the task is not moved
2607 ActivityStack stack = task.getStack();
2608 if (!task.getWindowConfiguration().canResizeTask()) {
2609 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
2610 }
2611 if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
2612 stack = stack.getDisplay().getOrCreateStack(
2613 WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
2614 } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
2615 stack = stack.getDisplay().getOrCreateStack(
2616 WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
2617 }
2618
2619 // Reparent the task to the right stack if necessary
2620 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
2621 if (stack != task.getStack()) {
2622 // Defer resume until the task is resized below
2623 task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
2624 DEFER_RESUME, "resizeTask");
2625 preserveWindow = false;
2626 }
2627
2628 // After reparenting (which only resizes the task to the stack bounds), resize the
2629 // task to the actual bounds provided
2630 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
2631 }
2632 } finally {
2633 Binder.restoreCallingIdentity(ident);
2634 }
2635 }
2636
2637 @Override
2638 public boolean releaseActivityInstance(IBinder token) {
2639 synchronized (mGlobalLock) {
2640 final long origId = Binder.clearCallingIdentity();
2641 try {
2642 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2643 if (r == null) {
2644 return false;
2645 }
2646 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
2647 } finally {
2648 Binder.restoreCallingIdentity(origId);
2649 }
2650 }
2651 }
2652
2653 @Override
2654 public void releaseSomeActivities(IApplicationThread appInt) {
2655 synchronized (mGlobalLock) {
2656 final long origId = Binder.clearCallingIdentity();
2657 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002658 WindowProcessController app =
2659 mAm.getRecordForAppLocked(appInt).getWindowProcessController();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002660 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
2661 } finally {
2662 Binder.restoreCallingIdentity(origId);
2663 }
2664 }
2665 }
2666
2667 @Override
2668 public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
2669 int secondaryDisplayShowing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002670 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002671 != PackageManager.PERMISSION_GRANTED) {
2672 throw new SecurityException("Requires permission "
2673 + android.Manifest.permission.DEVICE_POWER);
2674 }
2675
2676 synchronized (mGlobalLock) {
2677 long ident = Binder.clearCallingIdentity();
2678 if (mKeyguardShown != keyguardShowing) {
2679 mKeyguardShown = keyguardShowing;
2680 reportCurKeyguardUsageEventLocked(keyguardShowing);
2681 }
2682 try {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002683 mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002684 secondaryDisplayShowing);
2685 } finally {
2686 Binder.restoreCallingIdentity(ident);
2687 }
2688 }
2689
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002690 mH.post(() -> {
2691 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2692 mScreenObservers.get(i).onKeyguardStateChanged(keyguardShowing);
2693 }
2694 });
2695 }
2696
2697 void onScreenAwakeChanged(boolean isAwake) {
2698 mH.post(() -> {
2699 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2700 mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2701 }
2702 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002703 }
2704
2705 @Override
2706 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002707 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
2708 userId, "getTaskDescriptionIcon");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002709
2710 final File passedIconFile = new File(filePath);
2711 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
2712 passedIconFile.getName());
2713 if (!legitIconFile.getPath().equals(filePath)
2714 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
2715 throw new IllegalArgumentException("Bad file path: " + filePath
2716 + " passed for userId " + userId);
2717 }
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002718 return mRecentTasks.getTaskDescriptionIcon(filePath);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002719 }
2720
2721 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002722 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002723 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
2724 final ActivityOptions activityOptions = safeOptions != null
2725 ? safeOptions.getOptions(mStackSupervisor)
2726 : null;
2727 if (activityOptions == null
2728 || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
2729 || activityOptions.getCustomInPlaceResId() == 0) {
2730 throw new IllegalArgumentException("Expected in-place ActivityOption " +
2731 "with valid animation");
2732 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002733 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
2734 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002735 activityOptions.getCustomInPlaceResId());
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002736 mWindowManager.executeAppTransition();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002737 }
2738
2739 @Override
2740 public void removeStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002741 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002742 synchronized (mGlobalLock) {
2743 final long ident = Binder.clearCallingIdentity();
2744 try {
2745 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2746 if (stack == null) {
2747 Slog.w(TAG, "removeStack: No stack with id=" + stackId);
2748 return;
2749 }
2750 if (!stack.isActivityTypeStandardOrUndefined()) {
2751 throw new IllegalArgumentException(
2752 "Removing non-standard stack is not allowed.");
2753 }
2754 mStackSupervisor.removeStack(stack);
2755 } finally {
2756 Binder.restoreCallingIdentity(ident);
2757 }
2758 }
2759 }
2760
2761 @Override
2762 public void moveStackToDisplay(int stackId, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002763 mAmInternal.enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002764
2765 synchronized (mGlobalLock) {
2766 final long ident = Binder.clearCallingIdentity();
2767 try {
2768 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
2769 + " to displayId=" + displayId);
2770 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
2771 } finally {
2772 Binder.restoreCallingIdentity(ident);
2773 }
2774 }
2775 }
2776
2777 @Override
2778 public int createStackOnDisplay(int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002779 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002780 synchronized (mGlobalLock) {
2781 final ActivityDisplay display =
2782 mStackSupervisor.getActivityDisplayOrCreateLocked(displayId);
2783 if (display == null) {
2784 return INVALID_STACK_ID;
2785 }
2786 // TODO(multi-display): Have the caller pass in the windowing mode and activity type.
2787 final ActivityStack stack = display.createStack(
2788 WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
2789 ON_TOP);
2790 return (stack != null) ? stack.mStackId : INVALID_STACK_ID;
2791 }
2792 }
2793
2794 @Override
2795 public void exitFreeformMode(IBinder token) {
2796 synchronized (mGlobalLock) {
2797 long ident = Binder.clearCallingIdentity();
2798 try {
2799 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2800 if (r == null) {
2801 throw new IllegalArgumentException(
2802 "exitFreeformMode: No activity record matching token=" + token);
2803 }
2804
2805 final ActivityStack stack = r.getStack();
2806 if (stack == null || !stack.inFreeformWindowingMode()) {
2807 throw new IllegalStateException(
2808 "exitFreeformMode: You can only go fullscreen from freeform.");
2809 }
2810
2811 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
2812 } finally {
2813 Binder.restoreCallingIdentity(ident);
2814 }
2815 }
2816 }
2817
2818 /** Sets the task stack listener that gets callbacks when a task stack changes. */
2819 @Override
2820 public void registerTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002821 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002822 "registerTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002823 mTaskChangeNotificationController.registerTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002824 }
2825
2826 /** Unregister a task stack listener so that it stops receiving callbacks. */
2827 @Override
2828 public void unregisterTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002829 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002830 "unregisterTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002831 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002832 }
2833
2834 private void reportCurKeyguardUsageEventLocked(boolean keyguardShowing) {
2835 mAm.reportGlobalUsageEventLocked(keyguardShowing
2836 ? UsageEvents.Event.KEYGUARD_SHOWN
2837 : UsageEvents.Event.KEYGUARD_HIDDEN);
2838 }
2839
2840 @Override
2841 public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
2842 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
2843 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
2844 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
2845 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
2846 }
2847
2848 @Override
2849 public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
2850 IBinder activityToken, int flags) {
2851 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
2852 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
2853 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
2854 }
2855
2856 @Override
2857 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
2858 Bundle args) {
2859 return enqueueAssistContext(requestType, intent, hint, null, null, null,
2860 true /* focused */, true /* newSessionId */, userHandle, args,
2861 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
2862 }
2863
2864 @Override
2865 public Bundle getAssistContextExtras(int requestType) {
2866 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
2867 null, null, true /* focused */, true /* newSessionId */,
2868 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
2869 if (pae == null) {
2870 return null;
2871 }
2872 synchronized (pae) {
2873 while (!pae.haveResult) {
2874 try {
2875 pae.wait();
2876 } catch (InterruptedException e) {
2877 }
2878 }
2879 }
2880 synchronized (mGlobalLock) {
2881 buildAssistBundleLocked(pae, pae.result);
2882 mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002883 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002884 }
2885 return pae.extras;
2886 }
2887
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002888 /**
2889 * Binder IPC calls go through the public entry point.
2890 * This can be called with or without the global lock held.
2891 */
2892 private static int checkCallingPermission(String permission) {
2893 return checkPermission(
2894 permission, Binder.getCallingPid(), UserHandle.getAppId(Binder.getCallingUid()));
2895 }
2896
2897 /** This can be called with or without the global lock held. */
2898 void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
2899 if (!getRecentTasks().isCallerRecents(Binder.getCallingUid())) {
2900 mAmInternal.enforceCallingPermission(permission, func);
2901 }
2902 }
2903
2904 @VisibleForTesting
2905 int checkGetTasksPermission(String permission, int pid, int uid) {
2906 return checkPermission(permission, pid, uid);
2907 }
2908
2909 static int checkPermission(String permission, int pid, int uid) {
2910 if (permission == null) {
2911 return PackageManager.PERMISSION_DENIED;
2912 }
2913 return checkComponentPermission(permission, pid, uid, -1, true);
2914 }
2915
2916 boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
2917 if (getRecentTasks().isCallerRecents(callingUid)) {
2918 // Always allow the recents component to get tasks
2919 return true;
2920 }
2921
2922 boolean allowed = checkGetTasksPermission(android.Manifest.permission.REAL_GET_TASKS,
2923 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
2924 if (!allowed) {
2925 if (checkGetTasksPermission(android.Manifest.permission.GET_TASKS,
2926 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
2927 // Temporary compatibility: some existing apps on the system image may
2928 // still be requesting the old permission and not switched to the new
2929 // one; if so, we'll still allow them full access. This means we need
2930 // to see if they are holding the old permission and are a system app.
2931 try {
2932 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
2933 allowed = true;
2934 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
2935 + " is using old GET_TASKS but privileged; allowing");
2936 }
2937 } catch (RemoteException e) {
2938 }
2939 }
2940 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
2941 + " does not hold REAL_GET_TASKS; limiting output");
2942 }
2943 return allowed;
2944 }
2945
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002946 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
2947 IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
2948 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
2949 int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002950 mAmInternal.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002951 "enqueueAssistContext()");
2952
2953 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002954 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002955 if (activity == null) {
2956 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
2957 return null;
2958 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002959 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002960 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
2961 return null;
2962 }
2963 if (focused) {
2964 if (activityToken != null) {
2965 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
2966 if (activity != caller) {
2967 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
2968 + " is not current top " + activity);
2969 return null;
2970 }
2971 }
2972 } else {
2973 activity = ActivityRecord.forTokenLocked(activityToken);
2974 if (activity == null) {
2975 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
2976 + " couldn't be found");
2977 return null;
2978 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002979 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002980 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
2981 return null;
2982 }
2983 }
2984
2985 PendingAssistExtras pae;
2986 Bundle extras = new Bundle();
2987 if (args != null) {
2988 extras.putAll(args);
2989 }
2990 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002991 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002992
2993 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
2994 userHandle);
2995 pae.isHome = activity.isActivityTypeHome();
2996
2997 // Increment the sessionId if necessary
2998 if (newSessionId) {
2999 mViSessionId++;
3000 }
3001 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003002 activity.app.getThread().requestAssistContextExtras(activity.appToken, pae,
3003 requestType, mViSessionId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003004 mPendingAssistExtras.add(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003005 mUiHandler.postDelayed(pae, timeout);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003006 } catch (RemoteException e) {
3007 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
3008 return null;
3009 }
3010 return pae;
3011 }
3012 }
3013
3014 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
3015 if (result != null) {
3016 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
3017 }
3018 if (pae.hint != null) {
3019 pae.extras.putBoolean(pae.hint, true);
3020 }
3021 }
3022
3023 private void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
3024 IAssistDataReceiver receiver;
3025 synchronized (mGlobalLock) {
3026 mPendingAssistExtras.remove(pae);
3027 receiver = pae.receiver;
3028 }
3029 if (receiver != null) {
3030 // Caller wants result sent back to them.
3031 Bundle sendBundle = new Bundle();
3032 // At least return the receiver extras
3033 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
3034 try {
3035 pae.receiver.onHandleAssistData(sendBundle);
3036 } catch (RemoteException e) {
3037 }
3038 }
3039 }
3040
3041 public class PendingAssistExtras extends Binder implements Runnable {
3042 public final ActivityRecord activity;
3043 public boolean isHome;
3044 public final Bundle extras;
3045 public final Intent intent;
3046 public final String hint;
3047 public final IAssistDataReceiver receiver;
3048 public final int userHandle;
3049 public boolean haveResult = false;
3050 public Bundle result = null;
3051 public AssistStructure structure = null;
3052 public AssistContent content = null;
3053 public Bundle receiverExtras;
3054
3055 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
3056 String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
3057 int _userHandle) {
3058 activity = _activity;
3059 extras = _extras;
3060 intent = _intent;
3061 hint = _hint;
3062 receiver = _receiver;
3063 receiverExtras = _receiverExtras;
3064 userHandle = _userHandle;
3065 }
3066
3067 @Override
3068 public void run() {
3069 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
3070 synchronized (this) {
3071 haveResult = true;
3072 notifyAll();
3073 }
3074 pendingAssistExtrasTimedOut(this);
3075 }
3076 }
3077
3078 @Override
3079 public boolean isAssistDataAllowedOnCurrentActivity() {
3080 int userId;
3081 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003082 final ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003083 if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
3084 return false;
3085 }
3086
3087 final ActivityRecord activity = focusedStack.getTopActivity();
3088 if (activity == null) {
3089 return false;
3090 }
3091 userId = activity.userId;
3092 }
3093 return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
3094 }
3095
3096 @Override
3097 public boolean showAssistFromActivity(IBinder token, Bundle args) {
3098 long ident = Binder.clearCallingIdentity();
3099 try {
3100 synchronized (mGlobalLock) {
3101 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003102 ActivityRecord top = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003103 if (top != caller) {
3104 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3105 + " is not current top " + top);
3106 return false;
3107 }
3108 if (!top.nowVisible) {
3109 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3110 + " is not visible");
3111 return false;
3112 }
3113 }
3114 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
3115 token);
3116 } finally {
3117 Binder.restoreCallingIdentity(ident);
3118 }
3119 }
3120
3121 @Override
3122 public boolean isRootVoiceInteraction(IBinder token) {
3123 synchronized (mGlobalLock) {
3124 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3125 if (r == null) {
3126 return false;
3127 }
3128 return r.rootVoiceInteraction;
3129 }
3130 }
3131
Wale Ogunwalef6733932018-06-27 05:14:34 -07003132 private void onLocalVoiceInteractionStartedLocked(IBinder activity,
3133 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
3134 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
3135 if (activityToCallback == null) return;
3136 activityToCallback.setVoiceSessionLocked(voiceSession);
3137
3138 // Inform the activity
3139 try {
3140 activityToCallback.app.getThread().scheduleLocalVoiceInteractionStarted(activity,
3141 voiceInteractor);
3142 long token = Binder.clearCallingIdentity();
3143 try {
3144 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
3145 } finally {
3146 Binder.restoreCallingIdentity(token);
3147 }
3148 // TODO: VI Should we cache the activity so that it's easier to find later
3149 // rather than scan through all the stacks and activities?
3150 } catch (RemoteException re) {
3151 activityToCallback.clearVoiceSessionLocked();
3152 // TODO: VI Should this terminate the voice session?
3153 }
3154 }
3155
3156 private void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
3157 Slog.d(TAG, "<<< startRunningVoiceLocked()");
3158 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
3159 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
3160 boolean wasRunningVoice = mRunningVoice != null;
3161 mRunningVoice = session;
3162 if (!wasRunningVoice) {
3163 mVoiceWakeLock.acquire();
3164 updateSleepIfNeededLocked();
3165 }
3166 }
3167 }
3168
3169 void finishRunningVoiceLocked() {
3170 if (mRunningVoice != null) {
3171 mRunningVoice = null;
3172 mVoiceWakeLock.release();
3173 updateSleepIfNeededLocked();
3174 }
3175 }
3176
3177 @Override
3178 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3179 synchronized (mGlobalLock) {
3180 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3181 if (keepAwake) {
3182 mVoiceWakeLock.acquire();
3183 } else {
3184 mVoiceWakeLock.release();
3185 }
3186 }
3187 }
3188 }
3189
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003190 @Override
3191 public ComponentName getActivityClassForToken(IBinder token) {
3192 synchronized (mGlobalLock) {
3193 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3194 if (r == null) {
3195 return null;
3196 }
3197 return r.intent.getComponent();
3198 }
3199 }
3200
3201 @Override
3202 public String getPackageForToken(IBinder token) {
3203 synchronized (mGlobalLock) {
3204 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3205 if (r == null) {
3206 return null;
3207 }
3208 return r.packageName;
3209 }
3210 }
3211
3212 @Override
3213 public void showLockTaskEscapeMessage(IBinder token) {
3214 synchronized (mGlobalLock) {
3215 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3216 if (r == null) {
3217 return;
3218 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003219 getLockTaskController().showLockTaskToast();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003220 }
3221 }
3222
3223 @Override
3224 public void keyguardGoingAway(int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003225 enforceNotIsolatedCaller("keyguardGoingAway");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003226 final long token = Binder.clearCallingIdentity();
3227 try {
3228 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003229 mKeyguardController.keyguardGoingAway(flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003230 }
3231 } finally {
3232 Binder.restoreCallingIdentity(token);
3233 }
3234 }
3235
3236 /**
3237 * Try to place task to provided position. The final position might be different depending on
3238 * current user and stacks state. The task will be moved to target stack if it's currently in
3239 * different stack.
3240 */
3241 @Override
3242 public void positionTaskInStack(int taskId, int stackId, int position) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003243 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003244 synchronized (mGlobalLock) {
3245 long ident = Binder.clearCallingIdentity();
3246 try {
3247 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
3248 + taskId + " in stackId=" + stackId + " at position=" + position);
3249 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3250 if (task == null) {
3251 throw new IllegalArgumentException("positionTaskInStack: no task for id="
3252 + taskId);
3253 }
3254
3255 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3256
3257 if (stack == null) {
3258 throw new IllegalArgumentException("positionTaskInStack: no stack for id="
3259 + stackId);
3260 }
3261 if (!stack.isActivityTypeStandardOrUndefined()) {
3262 throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
3263 + " the position of task " + taskId + " in/to non-standard stack");
3264 }
3265
3266 // TODO: Have the callers of this API call a separate reparent method if that is
3267 // what they intended to do vs. having this method also do reparenting.
3268 if (task.getStack() == stack) {
3269 // Change position in current stack.
3270 stack.positionChildAt(task, position);
3271 } else {
3272 // Reparent to new stack.
3273 task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
3274 !DEFER_RESUME, "positionTaskInStack");
3275 }
3276 } finally {
3277 Binder.restoreCallingIdentity(ident);
3278 }
3279 }
3280 }
3281
3282 @Override
3283 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
3284 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
3285 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
3286 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
3287 synchronized (mGlobalLock) {
3288 ActivityRecord record = ActivityRecord.isInStackLocked(token);
3289 if (record == null) {
3290 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
3291 + "found for: " + token);
3292 }
3293 record.setSizeConfigurations(horizontalSizeConfiguration,
3294 verticalSizeConfigurations, smallestSizeConfigurations);
3295 }
3296 }
3297
3298 /**
3299 * Dismisses split-screen multi-window mode.
3300 * @param toTop If true the current primary split-screen stack will be placed or left on top.
3301 */
3302 @Override
3303 public void dismissSplitScreenMode(boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003304 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003305 MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
3306 final long ident = Binder.clearCallingIdentity();
3307 try {
3308 synchronized (mGlobalLock) {
3309 final ActivityStack stack =
3310 mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
3311 if (stack == null) {
3312 Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
3313 return;
3314 }
3315
3316 if (toTop) {
3317 // Caller wants the current split-screen primary stack to be the top stack after
3318 // it goes fullscreen, so move it to the front.
3319 stack.moveToFront("dismissSplitScreenMode");
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003320 } else if (mStackSupervisor.isTopDisplayFocusedStack(stack)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003321 // In this case the current split-screen primary stack shouldn't be the top
3322 // stack after it goes fullscreen, but it current has focus, so we move the
3323 // focus to the top-most split-screen secondary stack next to it.
3324 final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
3325 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
3326 if (otherStack != null) {
3327 otherStack.moveToFront("dismissSplitScreenMode_other");
3328 }
3329 }
3330
3331 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
3332 }
3333 } finally {
3334 Binder.restoreCallingIdentity(ident);
3335 }
3336 }
3337
3338 /**
3339 * Dismisses Pip
3340 * @param animate True if the dismissal should be animated.
3341 * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
3342 * default animation duration should be used.
3343 */
3344 @Override
3345 public void dismissPip(boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003346 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003347 final long ident = Binder.clearCallingIdentity();
3348 try {
3349 synchronized (mGlobalLock) {
3350 final PinnedActivityStack stack =
3351 mStackSupervisor.getDefaultDisplay().getPinnedStack();
3352 if (stack == null) {
3353 Slog.w(TAG, "dismissPip: pinned stack not found.");
3354 return;
3355 }
3356 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
3357 throw new IllegalArgumentException("Stack: " + stack
3358 + " doesn't support animated resize.");
3359 }
3360 if (animate) {
3361 stack.animateResizePinnedStack(null /* sourceHintBounds */,
3362 null /* destBounds */, animationDuration, false /* fromFullscreen */);
3363 } else {
3364 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
3365 }
3366 }
3367 } finally {
3368 Binder.restoreCallingIdentity(ident);
3369 }
3370 }
3371
3372 @Override
3373 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003374 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003375 synchronized (mGlobalLock) {
3376 mSuppressResizeConfigChanges = suppress;
3377 }
3378 }
3379
3380 /**
3381 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
3382 * animated the stack to the fullscreen, but can also be called if we are relaunching an
3383 * activity and clearing the task at the same time.
3384 */
3385 @Override
3386 // TODO: API should just be about changing windowing modes...
3387 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003388 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003389 "moveTasksToFullscreenStack()");
3390 synchronized (mGlobalLock) {
3391 final long origId = Binder.clearCallingIdentity();
3392 try {
3393 final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
3394 if (stack != null){
3395 if (!stack.isActivityTypeStandardOrUndefined()) {
3396 throw new IllegalArgumentException(
3397 "You can't move tasks from non-standard stacks.");
3398 }
3399 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
3400 }
3401 } finally {
3402 Binder.restoreCallingIdentity(origId);
3403 }
3404 }
3405 }
3406
3407 /**
3408 * Moves the top activity in the input stackId to the pinned stack.
3409 *
3410 * @param stackId Id of stack to move the top activity to pinned stack.
3411 * @param bounds Bounds to use for pinned stack.
3412 *
3413 * @return True if the top activity of the input stack was successfully moved to the pinned
3414 * stack.
3415 */
3416 @Override
3417 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003418 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003419 "moveTopActivityToPinnedStack()");
3420 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003421 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003422 throw new IllegalStateException("moveTopActivityToPinnedStack:"
3423 + "Device doesn't support picture-in-picture mode");
3424 }
3425
3426 long ident = Binder.clearCallingIdentity();
3427 try {
3428 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
3429 } finally {
3430 Binder.restoreCallingIdentity(ident);
3431 }
3432 }
3433 }
3434
3435 @Override
3436 public boolean isInMultiWindowMode(IBinder token) {
3437 final long origId = Binder.clearCallingIdentity();
3438 try {
3439 synchronized (mGlobalLock) {
3440 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3441 if (r == null) {
3442 return false;
3443 }
3444 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
3445 return r.inMultiWindowMode();
3446 }
3447 } finally {
3448 Binder.restoreCallingIdentity(origId);
3449 }
3450 }
3451
3452 @Override
3453 public boolean isInPictureInPictureMode(IBinder token) {
3454 final long origId = Binder.clearCallingIdentity();
3455 try {
3456 synchronized (mGlobalLock) {
3457 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
3458 }
3459 } finally {
3460 Binder.restoreCallingIdentity(origId);
3461 }
3462 }
3463
3464 private boolean isInPictureInPictureMode(ActivityRecord r) {
3465 if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
3466 || r.getStack().isInStackLocked(r) == null) {
3467 return false;
3468 }
3469
3470 // If we are animating to fullscreen then we have already dispatched the PIP mode
3471 // changed, so we should reflect that check here as well.
3472 final PinnedActivityStack stack = r.getStack();
3473 final PinnedStackWindowController windowController = stack.getWindowContainerController();
3474 return !windowController.isAnimatingBoundsToFullscreen();
3475 }
3476
3477 @Override
3478 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
3479 final long origId = Binder.clearCallingIdentity();
3480 try {
3481 synchronized (mGlobalLock) {
3482 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3483 "enterPictureInPictureMode", token, params);
3484
3485 // If the activity is already in picture in picture mode, then just return early
3486 if (isInPictureInPictureMode(r)) {
3487 return true;
3488 }
3489
3490 // Activity supports picture-in-picture, now check that we can enter PiP at this
3491 // point, if it is
3492 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
3493 false /* beforeStopping */)) {
3494 return false;
3495 }
3496
3497 final Runnable enterPipRunnable = () -> {
Wale Ogunwalef276a6f2018-06-15 08:26:07 -07003498 synchronized (mGlobalLock) {
3499 // Only update the saved args from the args that are set
3500 r.pictureInPictureArgs.copyOnlySet(params);
3501 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
3502 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
3503 // Adjust the source bounds by the insets for the transition down
3504 final Rect sourceBounds = new Rect(
3505 r.pictureInPictureArgs.getSourceRectHint());
3506 mStackSupervisor.moveActivityToPinnedStackLocked(
3507 r, sourceBounds, aspectRatio, "enterPictureInPictureMode");
3508 final PinnedActivityStack stack = r.getStack();
3509 stack.setPictureInPictureAspectRatio(aspectRatio);
3510 stack.setPictureInPictureActions(actions);
3511 MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
3512 r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
3513 logPictureInPictureArgs(params);
3514 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003515 };
3516
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003517 if (isKeyguardLocked()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003518 // If the keyguard is showing or occluded, then try and dismiss it before
3519 // entering picture-in-picture (this will prompt the user to authenticate if the
3520 // device is currently locked).
3521 dismissKeyguard(token, new KeyguardDismissCallback() {
3522 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003523 public void onDismissSucceeded() {
3524 mH.post(enterPipRunnable);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003525 }
3526 }, null /* message */);
3527 } else {
3528 // Enter picture in picture immediately otherwise
3529 enterPipRunnable.run();
3530 }
3531 return true;
3532 }
3533 } finally {
3534 Binder.restoreCallingIdentity(origId);
3535 }
3536 }
3537
3538 @Override
3539 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
3540 final long origId = Binder.clearCallingIdentity();
3541 try {
3542 synchronized (mGlobalLock) {
3543 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3544 "setPictureInPictureParams", token, params);
3545
3546 // Only update the saved args from the args that are set
3547 r.pictureInPictureArgs.copyOnlySet(params);
3548 if (r.inPinnedWindowingMode()) {
3549 // If the activity is already in picture-in-picture, update the pinned stack now
3550 // if it is not already expanding to fullscreen. Otherwise, the arguments will
3551 // be used the next time the activity enters PiP
3552 final PinnedActivityStack stack = r.getStack();
3553 if (!stack.isAnimatingBoundsToFullscreen()) {
3554 stack.setPictureInPictureAspectRatio(
3555 r.pictureInPictureArgs.getAspectRatio());
3556 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
3557 }
3558 }
3559 logPictureInPictureArgs(params);
3560 }
3561 } finally {
3562 Binder.restoreCallingIdentity(origId);
3563 }
3564 }
3565
3566 @Override
3567 public int getMaxNumPictureInPictureActions(IBinder token) {
3568 // Currently, this is a static constant, but later, we may change this to be dependent on
3569 // the context of the activity
3570 return 3;
3571 }
3572
3573 private void logPictureInPictureArgs(PictureInPictureParams params) {
3574 if (params.hasSetActions()) {
3575 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
3576 params.getActions().size());
3577 }
3578 if (params.hasSetAspectRatio()) {
3579 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
3580 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
3581 MetricsLogger.action(lm);
3582 }
3583 }
3584
3585 /**
3586 * Checks the state of the system and the activity associated with the given {@param token} to
3587 * verify that picture-in-picture is supported for that activity.
3588 *
3589 * @return the activity record for the given {@param token} if all the checks pass.
3590 */
3591 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
3592 IBinder token, PictureInPictureParams params) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003593 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003594 throw new IllegalStateException(caller
3595 + ": Device doesn't support picture-in-picture mode.");
3596 }
3597
3598 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3599 if (r == null) {
3600 throw new IllegalStateException(caller
3601 + ": Can't find activity for token=" + token);
3602 }
3603
3604 if (!r.supportsPictureInPicture()) {
3605 throw new IllegalStateException(caller
3606 + ": Current activity does not support picture-in-picture.");
3607 }
3608
3609 if (params.hasSetAspectRatio()
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003610 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003611 params.getAspectRatio())) {
3612 final float minAspectRatio = mContext.getResources().getFloat(
3613 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
3614 final float maxAspectRatio = mContext.getResources().getFloat(
3615 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
3616 throw new IllegalArgumentException(String.format(caller
3617 + ": Aspect ratio is too extreme (must be between %f and %f).",
3618 minAspectRatio, maxAspectRatio));
3619 }
3620
3621 // Truncate the number of actions if necessary
3622 params.truncateActions(getMaxNumPictureInPictureActions(token));
3623
3624 return r;
3625 }
3626
3627 @Override
3628 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003629 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003630 synchronized (mGlobalLock) {
3631 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
3632 if (r == null) {
3633 throw new IllegalArgumentException("Activity does not exist; token="
3634 + activityToken);
3635 }
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07003636 return r.getUriPermissionsLocked().getExternalToken();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003637 }
3638 }
3639
3640 @Override
3641 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
3642 Rect tempDockedTaskInsetBounds,
3643 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003644 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003645 long ident = Binder.clearCallingIdentity();
3646 try {
3647 synchronized (mGlobalLock) {
3648 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
3649 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
3650 PRESERVE_WINDOWS);
3651 }
3652 } finally {
3653 Binder.restoreCallingIdentity(ident);
3654 }
3655 }
3656
3657 @Override
3658 public void setSplitScreenResizing(boolean resizing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003659 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003660 final long ident = Binder.clearCallingIdentity();
3661 try {
3662 synchronized (mGlobalLock) {
3663 mStackSupervisor.setSplitScreenResizing(resizing);
3664 }
3665 } finally {
3666 Binder.restoreCallingIdentity(ident);
3667 }
3668 }
3669
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003670 /**
3671 * Check that we have the features required for VR-related API calls, and throw an exception if
3672 * not.
3673 */
3674 void enforceSystemHasVrFeature() {
3675 if (!mContext.getPackageManager().hasSystemFeature(
3676 PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
3677 throw new UnsupportedOperationException("VR mode not supported on this device!");
3678 }
3679 }
3680
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003681 @Override
3682 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003683 enforceSystemHasVrFeature();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003684
3685 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3686
3687 ActivityRecord r;
3688 synchronized (mGlobalLock) {
3689 r = ActivityRecord.isInStackLocked(token);
3690 }
3691
3692 if (r == null) {
3693 throw new IllegalArgumentException();
3694 }
3695
3696 int err;
3697 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
3698 VrManagerInternal.NO_ERROR) {
3699 return err;
3700 }
3701
3702 // Clear the binder calling uid since this path may call moveToTask().
3703 final long callingId = Binder.clearCallingIdentity();
3704 try {
3705 synchronized (mGlobalLock) {
3706 r.requestedVrComponent = (enabled) ? packageName : null;
3707
3708 // Update associated state if this activity is currently focused
Andrii Kulian52d255c2018-07-13 11:32:19 -07003709 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003710 applyUpdateVrModeLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003711 }
3712 return 0;
3713 }
3714 } finally {
3715 Binder.restoreCallingIdentity(callingId);
3716 }
3717 }
3718
3719 @Override
3720 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
3721 Slog.i(TAG, "Activity tried to startLocalVoiceInteraction");
3722 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003723 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003724 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
3725 throw new SecurityException("Only focused activity can call startVoiceInteraction");
3726 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07003727 if (mRunningVoice != null || activity.getTask().voiceSession != null
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003728 || activity.voiceSession != null) {
3729 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
3730 return;
3731 }
3732 if (activity.pendingVoiceInteractionStart) {
3733 Slog.w(TAG, "Pending start of voice interaction already.");
3734 return;
3735 }
3736 activity.pendingVoiceInteractionStart = true;
3737 }
3738 LocalServices.getService(VoiceInteractionManagerInternal.class)
3739 .startLocalVoiceInteraction(callingActivity, options);
3740 }
3741
3742 @Override
3743 public void stopLocalVoiceInteraction(IBinder callingActivity) {
3744 LocalServices.getService(VoiceInteractionManagerInternal.class)
3745 .stopLocalVoiceInteraction(callingActivity);
3746 }
3747
3748 @Override
3749 public boolean supportsLocalVoiceInteraction() {
3750 return LocalServices.getService(VoiceInteractionManagerInternal.class)
3751 .supportsLocalVoiceInteraction();
3752 }
3753
3754 /** Notifies all listeners when the pinned stack animation starts. */
3755 @Override
3756 public void notifyPinnedStackAnimationStarted() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003757 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003758 }
3759
3760 /** Notifies all listeners when the pinned stack animation ends. */
3761 @Override
3762 public void notifyPinnedStackAnimationEnded() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003763 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003764 }
3765
3766 @Override
3767 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003768 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003769 final long ident = Binder.clearCallingIdentity();
3770 try {
3771 synchronized (mGlobalLock) {
3772 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
3773 }
3774 } finally {
3775 Binder.restoreCallingIdentity(ident);
3776 }
3777 }
3778
3779 @Override
3780 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003781 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003782
3783 synchronized (mGlobalLock) {
3784 // Check if display is initialized in AM.
3785 if (!mStackSupervisor.isDisplayAdded(displayId)) {
3786 // Call might come when display is not yet added or has already been removed.
3787 if (DEBUG_CONFIGURATION) {
3788 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
3789 + displayId);
3790 }
3791 return false;
3792 }
3793
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003794 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003795 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003796 values = mWindowManager.computeNewConfiguration(displayId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003797 }
3798
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003799 if (mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003800 // Update OOM levels based on display size.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003801 mAm.mProcessList.applyDisplaySize(mWindowManager);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003802 }
3803
3804 final long origId = Binder.clearCallingIdentity();
3805 try {
3806 if (values != null) {
3807 Settings.System.clearConfiguration(values);
3808 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003809 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003810 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
3811 return mTmpUpdateConfigurationResult.changes != 0;
3812 } finally {
3813 Binder.restoreCallingIdentity(origId);
3814 }
3815 }
3816 }
3817
3818 @Override
3819 public boolean updateConfiguration(Configuration values) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003820 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003821
3822 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003823 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003824 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003825 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003826 }
3827
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003828 if (mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003829 // Update OOM levels based on display size.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003830 mAm.mProcessList.applyDisplaySize(mWindowManager);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003831 }
3832
3833 final long origId = Binder.clearCallingIdentity();
3834 try {
3835 if (values != null) {
3836 Settings.System.clearConfiguration(values);
3837 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003838 updateConfigurationLocked(values, null, false, false /* persistent */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003839 UserHandle.USER_NULL, false /* deferResume */,
3840 mTmpUpdateConfigurationResult);
3841 return mTmpUpdateConfigurationResult.changes != 0;
3842 } finally {
3843 Binder.restoreCallingIdentity(origId);
3844 }
3845 }
3846 }
3847
3848 @Override
3849 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
3850 CharSequence message) {
3851 if (message != null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003852 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003853 Manifest.permission.SHOW_KEYGUARD_MESSAGE, "dismissKeyguard()");
3854 }
3855 final long callingId = Binder.clearCallingIdentity();
3856 try {
3857 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003858 mKeyguardController.dismissKeyguard(token, callback, message);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003859 }
3860 } finally {
3861 Binder.restoreCallingIdentity(callingId);
3862 }
3863 }
3864
3865 @Override
3866 public void cancelTaskWindowTransition(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003867 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003868 "cancelTaskWindowTransition()");
3869 final long ident = Binder.clearCallingIdentity();
3870 try {
3871 synchronized (mGlobalLock) {
3872 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
3873 MATCH_TASK_IN_STACKS_ONLY);
3874 if (task == null) {
3875 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
3876 return;
3877 }
3878 task.cancelWindowTransition();
3879 }
3880 } finally {
3881 Binder.restoreCallingIdentity(ident);
3882 }
3883 }
3884
3885 @Override
3886 public ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003887 enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003888 final long ident = Binder.clearCallingIdentity();
3889 try {
3890 final TaskRecord task;
3891 synchronized (mGlobalLock) {
3892 task = mStackSupervisor.anyTaskForIdLocked(taskId,
3893 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
3894 if (task == null) {
3895 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
3896 return null;
3897 }
3898 }
3899 // Don't call this while holding the lock as this operation might hit the disk.
3900 return task.getSnapshot(reducedResolution);
3901 } finally {
3902 Binder.restoreCallingIdentity(ident);
3903 }
3904 }
3905
3906 @Override
3907 public void setDisablePreviewScreenshots(IBinder token, boolean disable) {
3908 synchronized (mGlobalLock) {
3909 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3910 if (r == null) {
3911 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
3912 + token);
3913 return;
3914 }
3915 final long origId = Binder.clearCallingIdentity();
3916 try {
3917 r.setDisablePreviewScreenshots(disable);
3918 } finally {
3919 Binder.restoreCallingIdentity(origId);
3920 }
3921 }
3922 }
3923
3924 /** Return the user id of the last resumed activity. */
3925 @Override
3926 public @UserIdInt
3927 int getLastResumedActivityUserId() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003928 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003929 Manifest.permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
3930 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07003931 if (mLastResumedActivity == null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003932 return getCurrentUserId();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003933 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07003934 return mLastResumedActivity.userId;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003935 }
3936 }
3937
3938 @Override
3939 public void updateLockTaskFeatures(int userId, int flags) {
3940 final int callingUid = Binder.getCallingUid();
3941 if (callingUid != 0 && callingUid != SYSTEM_UID) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003942 mAmInternal.enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003943 "updateLockTaskFeatures()");
3944 }
3945 synchronized (mGlobalLock) {
3946 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
3947 Integer.toHexString(flags));
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003948 getLockTaskController().updateLockTaskFeatures(userId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003949 }
3950 }
3951
3952 @Override
3953 public void setShowWhenLocked(IBinder token, boolean showWhenLocked) {
3954 synchronized (mGlobalLock) {
3955 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3956 if (r == null) {
3957 return;
3958 }
3959 final long origId = Binder.clearCallingIdentity();
3960 try {
3961 r.setShowWhenLocked(showWhenLocked);
3962 } finally {
3963 Binder.restoreCallingIdentity(origId);
3964 }
3965 }
3966 }
3967
3968 @Override
3969 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) {
3970 synchronized (mGlobalLock) {
3971 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3972 if (r == null) {
3973 return;
3974 }
3975 final long origId = Binder.clearCallingIdentity();
3976 try {
3977 r.setTurnScreenOn(turnScreenOn);
3978 } finally {
3979 Binder.restoreCallingIdentity(origId);
3980 }
3981 }
3982 }
3983
3984 @Override
3985 public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003986 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003987 "registerRemoteAnimations");
3988 definition.setCallingPid(Binder.getCallingPid());
3989 synchronized (mGlobalLock) {
3990 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3991 if (r == null) {
3992 return;
3993 }
3994 final long origId = Binder.clearCallingIdentity();
3995 try {
3996 r.registerRemoteAnimations(definition);
3997 } finally {
3998 Binder.restoreCallingIdentity(origId);
3999 }
4000 }
4001 }
4002
4003 @Override
4004 public void registerRemoteAnimationForNextActivityStart(String packageName,
4005 RemoteAnimationAdapter adapter) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004006 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004007 "registerRemoteAnimationForNextActivityStart");
4008 adapter.setCallingPid(Binder.getCallingPid());
4009 synchronized (mGlobalLock) {
4010 final long origId = Binder.clearCallingIdentity();
4011 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07004012 getActivityStartController().registerRemoteAnimationForNextActivityStart(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004013 packageName, adapter);
4014 } finally {
4015 Binder.restoreCallingIdentity(origId);
4016 }
4017 }
4018 }
4019
4020 /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
4021 @Override
4022 public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
4023 synchronized (mGlobalLock) {
4024 final long origId = Binder.clearCallingIdentity();
4025 try {
4026 mAm.mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
4027 } finally {
4028 Binder.restoreCallingIdentity(origId);
4029 }
4030 }
4031 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004032
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004033 @Override
4034 public void setVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004035 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004036 synchronized (mGlobalLock) {
4037 synchronized (mAm.mPidsSelfLocked) {
4038 final int pid = Binder.getCallingPid();
4039 final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004040 mVrController.setVrThreadLocked(tid, pid, proc.getWindowProcessController());
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004041 }
4042 }
4043 }
4044
4045 @Override
4046 public void setPersistentVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004047 if (checkCallingPermission(Manifest.permission.RESTRICTED_VR_ACCESS)
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004048 != PERMISSION_GRANTED) {
4049 final String msg = "Permission Denial: setPersistentVrThread() from pid="
4050 + Binder.getCallingPid()
4051 + ", uid=" + Binder.getCallingUid()
4052 + " requires " + Manifest.permission.RESTRICTED_VR_ACCESS;
4053 Slog.w(TAG, msg);
4054 throw new SecurityException(msg);
4055 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004056 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004057 synchronized (mGlobalLock) {
4058 synchronized (mAm.mPidsSelfLocked) {
4059 final int pid = Binder.getCallingPid();
4060 final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
4061 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
4062 }
4063 }
4064 }
4065
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004066 @Override
4067 public void stopAppSwitches() {
4068 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
4069 synchronized (mGlobalLock) {
4070 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME;
4071 mDidAppSwitch = false;
4072 getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
4073 }
4074 }
4075
4076 @Override
4077 public void resumeAppSwitches() {
4078 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
4079 synchronized (mGlobalLock) {
4080 // Note that we don't execute any pending app switches... we will
4081 // let those wait until either the timeout, or the next start
4082 // activity request.
4083 mAppSwitchesAllowedTime = 0;
4084 }
4085 }
4086
4087 void onStartActivitySetDidAppSwitch() {
4088 if (mDidAppSwitch) {
4089 // This is the second allowed switch since we stopped switches, so now just generally
4090 // allow switches. Use case:
4091 // - user presses home (switches disabled, switch to home, mDidAppSwitch now true);
4092 // - user taps a home icon (coming from home so allowed, we hit here and now allow
4093 // anyone to switch again).
4094 mAppSwitchesAllowedTime = 0;
4095 } else {
4096 mDidAppSwitch = true;
4097 }
4098 }
4099
4100 /** @return whether the system should disable UI modes incompatible with VR mode. */
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004101 boolean shouldDisableNonVrUiLocked() {
4102 return mVrController.shouldDisableNonVrUiLocked();
4103 }
4104
4105 void applyUpdateVrModeLocked(ActivityRecord r) {
4106 // VR apps are expected to run in a main display. If an app is turning on VR for
4107 // itself, but lives in a dynamic stack, then make sure that it is moved to the main
4108 // fullscreen stack before enabling VR Mode.
4109 // TODO: The goal of this code is to keep the VR app on the main display. When the
4110 // stack implementation changes in the future, keep in mind that the use of the fullscreen
4111 // stack is a means to move the activity to the main display and a moveActivityToDisplay()
4112 // option would be a better choice here.
4113 if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
4114 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
4115 + " to main stack for VR");
4116 final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
4117 WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
4118 moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
4119 }
4120 mH.post(() -> {
4121 if (!mVrController.onVrModeChanged(r)) {
4122 return;
4123 }
4124 synchronized (mGlobalLock) {
4125 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
4126 mWindowManager.disableNonVrUi(disableNonVrUi);
4127 if (disableNonVrUi) {
4128 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
4129 // then remove the pinned stack.
4130 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
4131 }
4132 }
4133 });
4134 }
4135
Andrii Kulian5f750bc2018-07-17 08:57:23 -07004136 ActivityStack getTopDisplayFocusedStack() {
4137 return mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004138 }
4139
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004140 /** Pokes the task persister. */
4141 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
4142 mRecentTasks.notifyTaskPersisterLocked(task, flush);
4143 }
4144
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004145 void onTopProcChangedLocked(WindowProcessController proc) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004146 mVrController.onTopProcChangedLocked(proc);
4147 }
4148
4149 boolean isKeyguardLocked() {
4150 return mKeyguardController.isKeyguardLocked();
4151 }
4152
4153 boolean isNextTransitionForward() {
4154 int transit = mWindowManager.getPendingAppTransition();
4155 return transit == TRANSIT_ACTIVITY_OPEN
4156 || transit == TRANSIT_TASK_OPEN
4157 || transit == TRANSIT_TASK_TO_FRONT;
4158 }
4159
Wale Ogunwalef6733932018-06-27 05:14:34 -07004160 void dumpSleepStates(PrintWriter pw, boolean testPssMode) {
4161 synchronized (mGlobalLock) {
4162 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
4163 if (mRunningVoice != null) {
4164 pw.println(" mRunningVoice=" + mRunningVoice);
4165 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
4166 }
4167 pw.println(" mSleeping=" + mSleeping);
4168 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + testPssMode);
4169 pw.println(" mVrController=" + mVrController);
4170 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004171 }
4172
Wale Ogunwalef6733932018-06-27 05:14:34 -07004173 void writeSleepStateToProto(ProtoOutputStream proto) {
4174 for (ActivityTaskManagerInternal.SleepToken st : mStackSupervisor.mSleepTokens) {
4175 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS,
4176 st.toString());
4177 }
4178
4179 if (mRunningVoice != null) {
4180 final long vrToken = proto.start(
4181 ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
4182 proto.write(ActivityManagerServiceDumpProcessesProto.Voice.SESSION,
4183 mRunningVoice.toString());
4184 mVoiceWakeLock.writeToProto(
4185 proto, ActivityManagerServiceDumpProcessesProto.Voice.WAKELOCK);
4186 proto.end(vrToken);
4187 }
4188
4189 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
4190 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN,
4191 mShuttingDown);
4192 mVrController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004193 }
4194
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004195 int getCurrentUserId() {
4196 return mAmInternal.getCurrentUserId();
4197 }
4198
4199 private void enforceNotIsolatedCaller(String caller) {
4200 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4201 throw new SecurityException("Isolated process not allowed to call " + caller);
4202 }
4203 }
4204
Wale Ogunwalef6733932018-06-27 05:14:34 -07004205 public Configuration getConfiguration() {
4206 Configuration ci;
4207 synchronized(mGlobalLock) {
4208 ci = new Configuration(getGlobalConfiguration());
4209 ci.userSetLocale = false;
4210 }
4211 return ci;
4212 }
4213
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004214 /**
4215 * Current global configuration information. Contains general settings for the entire system,
4216 * also corresponds to the merged configuration of the default display.
4217 */
4218 Configuration getGlobalConfiguration() {
4219 return mStackSupervisor.getConfiguration();
4220 }
4221
4222 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4223 boolean initLocale) {
4224 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
4225 }
4226
4227 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4228 boolean initLocale, boolean deferResume) {
4229 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
4230 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
4231 UserHandle.USER_NULL, deferResume);
4232 }
4233
4234 void updatePersistentConfiguration(Configuration values, @UserIdInt int userId) {
4235 final long origId = Binder.clearCallingIdentity();
4236 try {
4237 synchronized (mGlobalLock) {
4238 updateConfigurationLocked(values, null, false, true, userId,
4239 false /* deferResume */);
4240 }
4241 } finally {
4242 Binder.restoreCallingIdentity(origId);
4243 }
4244 }
4245
4246 void updateUserConfiguration() {
4247 synchronized (mGlobalLock) {
4248 final Configuration configuration = new Configuration(getGlobalConfiguration());
4249 final int currentUserId = mAmInternal.getCurrentUserId();
4250 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
4251 currentUserId, Settings.System.canWrite(mContext));
4252 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
4253 false /* persistent */, currentUserId, false /* deferResume */);
4254 }
4255 }
4256
4257 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4258 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
4259 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
4260 deferResume, null /* result */);
4261 }
4262
4263 /**
4264 * Do either or both things: (1) change the current configuration, and (2)
4265 * make sure the given activity is running with the (now) current
4266 * configuration. Returns true if the activity has been left running, or
4267 * false if <var>starting</var> is being destroyed to match the new
4268 * configuration.
4269 *
4270 * @param userId is only used when persistent parameter is set to true to persist configuration
4271 * for that particular user
4272 */
4273 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4274 boolean initLocale, boolean persistent, int userId, boolean deferResume,
4275 ActivityTaskManagerService.UpdateConfigurationResult result) {
4276 int changes = 0;
4277 boolean kept = true;
4278
4279 if (mWindowManager != null) {
4280 mWindowManager.deferSurfaceLayout();
4281 }
4282 try {
4283 if (values != null) {
4284 changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
4285 deferResume);
4286 }
4287
4288 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4289 } finally {
4290 if (mWindowManager != null) {
4291 mWindowManager.continueSurfaceLayout();
4292 }
4293 }
4294
4295 if (result != null) {
4296 result.changes = changes;
4297 result.activityRelaunched = !kept;
4298 }
4299 return kept;
4300 }
4301
4302 /**
4303 * Returns true if this configuration change is interesting enough to send an
4304 * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
4305 */
4306 private static boolean isSplitConfigurationChange(int configDiff) {
4307 return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
4308 }
4309
4310 /** Update default (global) configuration and notify listeners about changes. */
4311 private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
4312 boolean persistent, int userId, boolean deferResume) {
4313 mTempConfig.setTo(getGlobalConfiguration());
4314 final int changes = mTempConfig.updateFrom(values);
4315 if (changes == 0) {
4316 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
4317 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
4318 // performDisplayOverrideConfigUpdate in order to send the new display configuration
4319 // (even if there are no actual changes) to unfreeze the window.
4320 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
4321 return 0;
4322 }
4323
4324 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
4325 "Updating global configuration to: " + values);
4326
4327 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
4328 StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
4329 values.colorMode,
4330 values.densityDpi,
4331 values.fontScale,
4332 values.hardKeyboardHidden,
4333 values.keyboard,
4334 values.keyboardHidden,
4335 values.mcc,
4336 values.mnc,
4337 values.navigation,
4338 values.navigationHidden,
4339 values.orientation,
4340 values.screenHeightDp,
4341 values.screenLayout,
4342 values.screenWidthDp,
4343 values.smallestScreenWidthDp,
4344 values.touchscreen,
4345 values.uiMode);
4346
4347
4348 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
4349 final LocaleList locales = values.getLocales();
4350 int bestLocaleIndex = 0;
4351 if (locales.size() > 1) {
4352 if (mSupportedSystemLocales == null) {
4353 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
4354 }
4355 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
4356 }
4357 SystemProperties.set("persist.sys.locale",
4358 locales.get(bestLocaleIndex).toLanguageTag());
4359 LocaleList.setDefault(locales, bestLocaleIndex);
4360 mAm.mHandler.sendMessage(mAm.mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
4361 locales.get(bestLocaleIndex)));
4362 }
4363
4364 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
4365 mTempConfig.seq = mConfigurationSeq;
4366
4367 // Update stored global config and notify everyone about the change.
4368 mStackSupervisor.onConfigurationChanged(mTempConfig);
4369
4370 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
4371 // TODO(multi-display): Update UsageEvents#Event to include displayId.
4372 mAm.mUsageStatsService.reportConfigurationChange(
4373 mTempConfig, mAmInternal.getCurrentUserId());
4374
4375 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
Wale Ogunwalef6733932018-06-27 05:14:34 -07004376 updateShouldShowDialogsLocked(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004377
4378 AttributeCache ac = AttributeCache.instance();
4379 if (ac != null) {
4380 ac.updateConfiguration(mTempConfig);
4381 }
4382
4383 // Make sure all resources in our process are updated right now, so that anyone who is going
4384 // to retrieve resource values after we return will be sure to get the new ones. This is
4385 // especially important during boot, where the first config change needs to guarantee all
4386 // resources have that config before following boot code is executed.
4387 mAm.mSystemThread.applyConfigurationToResources(mTempConfig);
4388
4389 // We need another copy of global config because we're scheduling some calls instead of
4390 // running them in place. We need to be sure that object we send will be handled unchanged.
4391 final Configuration configCopy = new Configuration(mTempConfig);
4392 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
4393 Message msg = mAm.mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
4394 msg.obj = configCopy;
4395 msg.arg1 = userId;
4396 mAm.mHandler.sendMessage(msg);
4397 }
4398
4399 for (int i = mAm.mLruProcesses.size() - 1; i >= 0; i--) {
4400 ProcessRecord app = mAm.mLruProcesses.get(i);
4401 try {
4402 if (app.thread != null) {
4403 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
4404 + app.processName + " new config " + configCopy);
4405 getLifecycleManager().scheduleTransaction(app.thread,
4406 ConfigurationChangeItem.obtain(configCopy));
4407 }
4408 } catch (Exception e) {
4409 Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
4410 }
4411 }
4412
4413 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
4414 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
4415 | Intent.FLAG_RECEIVER_FOREGROUND
4416 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4417 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4418 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4419 UserHandle.USER_ALL);
4420 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
4421 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
4422 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
4423 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
4424 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4425 if (initLocale || !mAm.mProcessesReady) {
4426 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
4427 }
4428 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4429 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4430 UserHandle.USER_ALL);
4431 }
4432
4433 // Send a broadcast to PackageInstallers if the configuration change is interesting
4434 // for the purposes of installing additional splits.
4435 if (!initLocale && isSplitConfigurationChange(changes)) {
4436 intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
4437 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
4438 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
4439
4440 // Typically only app stores will have this permission.
4441 String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES };
4442 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions,
4443 OP_NONE, null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
4444 }
4445
4446 // Override configuration of the default display duplicates global config, so we need to
4447 // update it also. This will also notify WindowManager about changes.
4448 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
4449 DEFAULT_DISPLAY);
4450
4451 return changes;
4452 }
4453
4454 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
4455 boolean deferResume, int displayId) {
4456 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
4457 displayId, null /* result */);
4458 }
4459
4460 /**
4461 * Updates override configuration specific for the selected display. If no config is provided,
4462 * new one will be computed in WM based on current display info.
4463 */
4464 boolean updateDisplayOverrideConfigurationLocked(Configuration values,
4465 ActivityRecord starting, boolean deferResume, int displayId,
4466 ActivityTaskManagerService.UpdateConfigurationResult result) {
4467 int changes = 0;
4468 boolean kept = true;
4469
4470 if (mWindowManager != null) {
4471 mWindowManager.deferSurfaceLayout();
4472 }
4473 try {
4474 if (values != null) {
4475 if (displayId == DEFAULT_DISPLAY) {
4476 // Override configuration of the default display duplicates global config, so
4477 // we're calling global config update instead for default display. It will also
4478 // apply the correct override config.
4479 changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
4480 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
4481 } else {
4482 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
4483 }
4484 }
4485
4486 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4487 } finally {
4488 if (mWindowManager != null) {
4489 mWindowManager.continueSurfaceLayout();
4490 }
4491 }
4492
4493 if (result != null) {
4494 result.changes = changes;
4495 result.activityRelaunched = !kept;
4496 }
4497 return kept;
4498 }
4499
4500 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
4501 int displayId) {
4502 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
4503 final int changes = mTempConfig.updateFrom(values);
4504 if (changes != 0) {
4505 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
4506 + mTempConfig + " for displayId=" + displayId);
4507 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
4508
4509 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
4510 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
4511 mAm.mAppWarnings.onDensityChanged();
4512
4513 mAm.killAllBackgroundProcessesExcept(N,
4514 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
4515 }
4516 }
4517
4518 // Update the configuration with WM first and check if any of the stacks need to be resized
4519 // due to the configuration change. If so, resize the stacks now and do any relaunches if
4520 // necessary. This way we don't need to relaunch again afterwards in
4521 // ensureActivityConfiguration().
4522 if (mWindowManager != null) {
4523 final int[] resizedStacks =
4524 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
4525 if (resizedStacks != null) {
4526 for (int stackId : resizedStacks) {
4527 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
4528 }
4529 }
4530 }
4531
4532 return changes;
4533 }
4534
Wale Ogunwalef6733932018-06-27 05:14:34 -07004535 private void updateEventDispatchingLocked(boolean booted) {
4536 mWindowManager.setEventDispatching(booted && !mShuttingDown);
4537 }
4538
4539 void enableScreenAfterBoot(boolean booted) {
4540 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4541 SystemClock.uptimeMillis());
4542 mWindowManager.enableScreenAfterBoot();
4543
4544 synchronized (mGlobalLock) {
4545 updateEventDispatchingLocked(booted);
4546 }
4547 }
4548
4549 boolean canShowErrorDialogs() {
4550 return mShowDialogs && !mSleeping && !mShuttingDown
4551 && !mKeyguardController.isKeyguardOrAodShowing(DEFAULT_DISPLAY)
4552 && !hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
Wale Ogunwale86b74462018-07-02 08:42:43 -07004553 mAmInternal.getCurrentUserId())
Wale Ogunwalef6733932018-06-27 05:14:34 -07004554 && !(UserManager.isDeviceInDemoMode(mContext)
Wale Ogunwale86b74462018-07-02 08:42:43 -07004555 && mAmInternal.getCurrentUser().isDemo());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004556 }
4557
4558 /**
4559 * Decide based on the configuration whether we should show the ANR,
4560 * crash, etc dialogs. The idea is that if there is no affordance to
4561 * press the on-screen buttons, or the user experience would be more
4562 * greatly impacted than the crash itself, we shouldn't show the dialog.
4563 *
4564 * A thought: SystemUI might also want to get told about this, the Power
4565 * dialog / global actions also might want different behaviors.
4566 */
4567 private void updateShouldShowDialogsLocked(Configuration config) {
4568 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
4569 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
4570 && config.navigation == Configuration.NAVIGATION_NONAV);
4571 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
4572 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
4573 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
4574 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
4575 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
4576 final boolean hideDialogsSet = Settings.Global.getInt(mContext.getContentResolver(),
4577 HIDE_ERROR_DIALOGS, 0) != 0;
4578 mShowDialogs = inputMethodExists && uiModeSupportsDialogs && !hideDialogsSet;
4579 }
4580
4581 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
4582 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
4583 FONT_SCALE, 1.0f, userId);
4584
4585 synchronized (this) {
4586 if (getGlobalConfiguration().fontScale == scaleFactor) {
4587 return;
4588 }
4589
4590 final Configuration configuration
4591 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
4592 configuration.fontScale = scaleFactor;
4593 updatePersistentConfiguration(configuration, userId);
4594 }
4595 }
4596
4597 // Actually is sleeping or shutting down or whatever else in the future
4598 // is an inactive state.
4599 boolean isSleepingOrShuttingDownLocked() {
4600 return isSleepingLocked() || mShuttingDown;
4601 }
4602
4603 boolean isSleepingLocked() {
4604 return mSleeping;
4605 }
4606
4607 /**
4608 * Update AMS states when an activity is resumed. This should only be called by
4609 * {@link ActivityStack#onActivityStateChanged(
4610 * ActivityRecord, ActivityStack.ActivityState, String)} when an activity is resumed.
4611 */
4612 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
4613 final TaskRecord task = r.getTask();
4614 if (task.isActivityTypeStandard()) {
4615 if (mCurAppTimeTracker != r.appTimeTracker) {
4616 // We are switching app tracking. Complete the current one.
4617 if (mCurAppTimeTracker != null) {
4618 mCurAppTimeTracker.stop();
4619 mH.obtainMessage(
4620 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
4621 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
4622 mCurAppTimeTracker = null;
4623 }
4624 if (r.appTimeTracker != null) {
4625 mCurAppTimeTracker = r.appTimeTracker;
4626 startTimeTrackingFocusedActivityLocked();
4627 }
4628 } else {
4629 startTimeTrackingFocusedActivityLocked();
4630 }
4631 } else {
4632 r.appTimeTracker = null;
4633 }
4634 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
4635 // TODO: Probably not, because we don't want to resume voice on switching
4636 // back to this activity
4637 if (task.voiceInteractor != null) {
4638 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
4639 } else {
4640 finishRunningVoiceLocked();
4641
4642 if (mLastResumedActivity != null) {
4643 final IVoiceInteractionSession session;
4644
4645 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
4646 if (lastResumedActivityTask != null
4647 && lastResumedActivityTask.voiceSession != null) {
4648 session = lastResumedActivityTask.voiceSession;
4649 } else {
4650 session = mLastResumedActivity.voiceSession;
4651 }
4652
4653 if (session != null) {
4654 // We had been in a voice interaction session, but now focused has
4655 // move to something different. Just finish the session, we can't
4656 // return to it and retain the proper state and synchronization with
4657 // the voice interaction service.
4658 finishVoiceTask(session);
4659 }
4660 }
4661 }
4662
4663 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
4664 mAmInternal.sendForegroundProfileChanged(r.userId);
4665 }
4666 updateResumedAppTrace(r);
4667 mLastResumedActivity = r;
4668
4669 mWindowManager.setFocusedApp(r.appToken, true);
4670
4671 applyUpdateLockStateLocked(r);
4672 applyUpdateVrModeLocked(r);
4673
4674 EventLogTags.writeAmSetResumedActivity(
4675 r == null ? -1 : r.userId,
4676 r == null ? "NULL" : r.shortComponentName,
4677 reason);
4678 }
4679
4680 ActivityTaskManagerInternal.SleepToken acquireSleepToken(String tag, int displayId) {
4681 synchronized (mGlobalLock) {
4682 final ActivityTaskManagerInternal.SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
4683 updateSleepIfNeededLocked();
4684 return token;
4685 }
4686 }
4687
4688 void updateSleepIfNeededLocked() {
4689 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
4690 final boolean wasSleeping = mSleeping;
4691 boolean updateOomAdj = false;
4692
4693 if (!shouldSleep) {
4694 // If wasSleeping is true, we need to wake up activity manager state from when
4695 // we started sleeping. In either case, we need to apply the sleep tokens, which
4696 // will wake up stacks or put them to sleep as appropriate.
4697 if (wasSleeping) {
4698 mSleeping = false;
4699 startTimeTrackingFocusedActivityLocked();
4700 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
4701 mStackSupervisor.comeOutOfSleepIfNeededLocked();
4702 }
4703 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
4704 if (wasSleeping) {
4705 updateOomAdj = true;
4706 }
4707 } else if (!mSleeping && shouldSleep) {
4708 mSleeping = true;
4709 if (mCurAppTimeTracker != null) {
4710 mCurAppTimeTracker.stop();
4711 }
4712 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
4713 mStackSupervisor.goingToSleepLocked();
4714 updateResumedAppTrace(null /* resumed */);
4715 updateOomAdj = true;
4716 }
4717 if (updateOomAdj) {
4718 mH.post(mAmInternal::updateOomAdj);
4719 }
4720 }
4721
4722 void updateOomAdj() {
4723 mH.post(mAmInternal::updateOomAdj);
4724 }
4725
Andrii Kulian52d255c2018-07-13 11:32:19 -07004726 // TODO(b/111541062): Update app time tracking to make it aware of multiple resumed activities
Wale Ogunwalef6733932018-06-27 05:14:34 -07004727 private void startTimeTrackingFocusedActivityLocked() {
Andrii Kulian52d255c2018-07-13 11:32:19 -07004728 final ActivityRecord resumedActivity = mStackSupervisor.getTopResumedActivity();
Wale Ogunwalef6733932018-06-27 05:14:34 -07004729 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
4730 mCurAppTimeTracker.start(resumedActivity.packageName);
4731 }
4732 }
4733
4734 private void updateResumedAppTrace(@Nullable ActivityRecord resumed) {
4735 if (mTracedResumedActivity != null) {
4736 Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER,
4737 constructResumedTraceName(mTracedResumedActivity.packageName), 0);
4738 }
4739 if (resumed != null) {
4740 Trace.asyncTraceBegin(TRACE_TAG_ACTIVITY_MANAGER,
4741 constructResumedTraceName(resumed.packageName), 0);
4742 }
4743 mTracedResumedActivity = resumed;
4744 }
4745
4746 private String constructResumedTraceName(String packageName) {
4747 return "focused app: " + packageName;
4748 }
4749
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004750 /** Helper method that requests bounds from WM and applies them to stack. */
4751 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
4752 final Rect newStackBounds = new Rect();
4753 final ActivityStack stack = mStackSupervisor.getStack(stackId);
4754
4755 // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
4756 if (stack == null) {
4757 final StringWriter writer = new StringWriter();
4758 final PrintWriter printWriter = new PrintWriter(writer);
4759 mStackSupervisor.dumpDisplays(printWriter);
4760 printWriter.flush();
4761
4762 Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
4763 }
4764
4765 stack.getBoundsForNewConfiguration(newStackBounds);
4766 mStackSupervisor.resizeStackLocked(
4767 stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
4768 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
4769 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
4770 }
4771
4772 /** Applies latest configuration and/or visibility updates if needed. */
4773 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
4774 boolean kept = true;
Andrii Kulian5f750bc2018-07-17 08:57:23 -07004775 final ActivityStack mainStack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004776 // mainStack is null during startup.
4777 if (mainStack != null) {
4778 if (changes != 0 && starting == null) {
4779 // If the configuration changed, and the caller is not already
4780 // in the process of starting an activity, then find the top
4781 // activity to check if its configuration needs to change.
4782 starting = mainStack.topRunningActivityLocked();
4783 }
4784
4785 if (starting != null) {
4786 kept = starting.ensureActivityConfiguration(changes,
4787 false /* preserveWindow */);
4788 // And we need to make sure at this point that all other activities
4789 // are made visible with the correct configuration.
4790 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
4791 !PRESERVE_WINDOWS);
4792 }
4793 }
4794
4795 return kept;
4796 }
4797
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004798 void logAppTooSlow(WindowProcessController app, long startTime, String msg) {
4799 if (true || Build.IS_USER) {
4800 return;
4801 }
4802
4803 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4804 StrictMode.allowThreadDiskWrites();
4805 try {
4806 File tracesDir = new File("/data/anr");
4807 File tracesFile = null;
4808 try {
4809 tracesFile = File.createTempFile("app_slow", null, tracesDir);
4810
4811 StringBuilder sb = new StringBuilder();
4812 Time tobj = new Time();
4813 tobj.set(System.currentTimeMillis());
4814 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4815 sb.append(": ");
4816 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4817 sb.append(" since ");
4818 sb.append(msg);
4819 FileOutputStream fos = new FileOutputStream(tracesFile);
4820 fos.write(sb.toString().getBytes());
4821 if (app == null) {
4822 fos.write("\n*** No application process!".getBytes());
4823 }
4824 fos.close();
4825 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4826 } catch (IOException e) {
4827 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesFile, e);
4828 return;
4829 }
4830
4831 if (app != null && app.getPid() > 0) {
4832 ArrayList<Integer> firstPids = new ArrayList<Integer>();
4833 firstPids.add(app.getPid());
4834 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, null, null);
4835 }
4836
4837 File lastTracesFile = null;
4838 File curTracesFile = null;
4839 for (int i=9; i>=0; i--) {
4840 String name = String.format(Locale.US, "slow%02d.txt", i);
4841 curTracesFile = new File(tracesDir, name);
4842 if (curTracesFile.exists()) {
4843 if (lastTracesFile != null) {
4844 curTracesFile.renameTo(lastTracesFile);
4845 } else {
4846 curTracesFile.delete();
4847 }
4848 }
4849 lastTracesFile = curTracesFile;
4850 }
4851 tracesFile.renameTo(curTracesFile);
4852 } finally {
4853 StrictMode.setThreadPolicy(oldPolicy);
4854 }
4855 }
4856
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004857 final class H extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07004858 static final int REPORT_TIME_TRACKER_MSG = 1;
4859
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004860 public H(Looper looper) {
4861 super(looper, null, true);
4862 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004863
4864 @Override
4865 public void handleMessage(Message msg) {
4866 switch (msg.what) {
4867 case REPORT_TIME_TRACKER_MSG: {
4868 AppTimeTracker tracker = (AppTimeTracker) msg.obj;
4869 tracker.deliverResult(mContext);
4870 } break;
4871 }
4872 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004873 }
4874
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004875 final class UiHandler extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07004876 static final int DISMISS_DIALOG_UI_MSG = 1;
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004877
4878 public UiHandler() {
4879 super(com.android.server.UiThread.get().getLooper(), null, true);
4880 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004881
4882 @Override
4883 public void handleMessage(Message msg) {
4884 switch (msg.what) {
4885 case DISMISS_DIALOG_UI_MSG: {
4886 final Dialog d = (Dialog) msg.obj;
4887 d.dismiss();
4888 break;
4889 }
4890 }
4891 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004892 }
4893
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004894 final class LocalService extends ActivityTaskManagerInternal {
4895 @Override
4896 public SleepToken acquireSleepToken(String tag, int displayId) {
4897 Preconditions.checkNotNull(tag);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004898 return ActivityTaskManagerService.this.acquireSleepToken(tag, displayId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004899 }
4900
4901 @Override
4902 public ComponentName getHomeActivityForUser(int userId) {
4903 synchronized (mGlobalLock) {
4904 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
4905 return homeActivity == null ? null : homeActivity.realActivity;
4906 }
4907 }
4908
4909 @Override
4910 public void onLocalVoiceInteractionStarted(IBinder activity,
4911 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4912 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07004913 onLocalVoiceInteractionStartedLocked(activity, voiceSession, voiceInteractor);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004914 }
4915 }
4916
4917 @Override
4918 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
4919 synchronized (mGlobalLock) {
4920 mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
4921 reasons, timestamp);
4922 }
4923 }
4924
4925 @Override
4926 public void notifyAppTransitionFinished() {
4927 synchronized (mGlobalLock) {
4928 mStackSupervisor.notifyAppTransitionDone();
4929 }
4930 }
4931
4932 @Override
4933 public void notifyAppTransitionCancelled() {
4934 synchronized (mGlobalLock) {
4935 mStackSupervisor.notifyAppTransitionDone();
4936 }
4937 }
4938
4939 @Override
4940 public List<IBinder> getTopVisibleActivities() {
4941 synchronized (mGlobalLock) {
4942 return mStackSupervisor.getTopVisibleActivities();
4943 }
4944 }
4945
4946 @Override
4947 public void notifyDockedStackMinimizedChanged(boolean minimized) {
4948 synchronized (mGlobalLock) {
4949 mStackSupervisor.setDockedStackMinimized(minimized);
4950 }
4951 }
4952
4953 @Override
4954 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
4955 Bundle bOptions) {
4956 Preconditions.checkNotNull(intents, "intents");
4957 final String[] resolvedTypes = new String[intents.length];
4958
4959 // UID of the package on user userId.
4960 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
4961 // packageUid may not be initialized.
4962 int packageUid = 0;
4963 final long ident = Binder.clearCallingIdentity();
4964
4965 try {
4966 for (int i = 0; i < intents.length; i++) {
4967 resolvedTypes[i] =
4968 intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
4969 }
4970
4971 packageUid = AppGlobals.getPackageManager().getPackageUid(
4972 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
4973 } catch (RemoteException e) {
4974 // Shouldn't happen.
4975 } finally {
4976 Binder.restoreCallingIdentity(ident);
4977 }
4978
4979 synchronized (mGlobalLock) {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07004980 return getActivityStartController().startActivitiesInPackage(
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004981 packageUid, packageName,
4982 intents, resolvedTypes, null /* resultTo */,
4983 SafeActivityOptions.fromBundle(bOptions), userId,
4984 false /* validateIncomingUser */);
4985 }
4986 }
4987
4988 @Override
4989 public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
4990 Intent intent, Bundle options, int userId) {
4991 return ActivityTaskManagerService.this.startActivityAsUser(
4992 caller, callerPacakge, intent,
4993 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4994 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
4995 false /*validateIncomingUser*/);
4996 }
4997
4998 @Override
4999 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
5000 synchronized (mGlobalLock) {
5001
5002 // We might change the visibilities here, so prepare an empty app transition which
5003 // might be overridden later if we actually change visibilities.
5004 final boolean wasTransitionSet =
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005005 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005006 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005007 mWindowManager.prepareAppTransition(TRANSIT_NONE,
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005008 false /* alwaysKeepCurrent */);
5009 }
5010 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5011
5012 // If there was a transition set already we don't want to interfere with it as we
5013 // might be starting it too early.
5014 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005015 mWindowManager.executeAppTransition();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005016 }
5017 }
5018 if (callback != null) {
5019 callback.run();
5020 }
5021 }
5022
5023 @Override
5024 public void notifyKeyguardTrustedChanged() {
5025 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005026 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005027 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5028 }
5029 }
5030 }
5031
5032 /**
5033 * Called after virtual display Id is updated by
5034 * {@link com.android.server.vr.Vr2dDisplay} with a specific
5035 * {@param vrVr2dDisplayId}.
5036 */
5037 @Override
5038 public void setVr2dDisplayId(int vr2dDisplayId) {
5039 if (DEBUG_STACK) Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
5040 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005041 mVr2dDisplayId = vr2dDisplayId;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005042 }
5043 }
5044
5045 @Override
5046 public void setFocusedActivity(IBinder token) {
5047 synchronized (mGlobalLock) {
5048 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
5049 if (r == null) {
5050 throw new IllegalArgumentException(
5051 "setFocusedActivity: No activity record matching token=" + token);
5052 }
5053 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
5054 r, "setFocusedActivity")) {
5055 mStackSupervisor.resumeFocusedStackTopActivityLocked();
5056 }
5057 }
5058 }
5059
5060 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005061 public void registerScreenObserver(ScreenObserver observer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005062 mScreenObservers.add(observer);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005063 }
5064
5065 @Override
5066 public boolean isCallerRecents(int callingUid) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005067 return getRecentTasks().isCallerRecents(callingUid);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005068 }
5069
5070 @Override
5071 public boolean isRecentsComponentHomeActivity(int userId) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005072 return getRecentTasks().isRecentsComponentHomeActivity(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005073 }
5074
5075 @Override
5076 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
5077 ActivityTaskManagerService.this.cancelRecentsAnimation(restoreHomeStackPosition);
5078 }
5079
5080 @Override
5081 public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005082 ActivityTaskManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005083 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005084
5085 @Override
5086 public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
5087 synchronized (mGlobalLock) {
5088 mActiveVoiceInteractionServiceComponent = component;
5089 }
5090 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005091
5092 @Override
5093 public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
5094 if (!mAmInternal.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
5095 return;
5096 }
5097 synchronized (mGlobalLock) {
5098 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
5099 if (types == null) {
5100 if (uid < 0) {
5101 return;
5102 }
5103 types = new ArrayMap<>();
5104 mAllowAppSwitchUids.put(userId, types);
5105 }
5106 if (uid < 0) {
5107 types.remove(type);
5108 } else {
5109 types.put(type, uid);
5110 }
5111 }
5112 }
5113
5114 @Override
5115 public void onUserStopped(int userId) {
5116 synchronized (mGlobalLock) {
5117 getRecentTasks().unloadUserDataFromMemoryLocked(userId);
5118 mAllowAppSwitchUids.remove(userId);
5119 }
5120 }
5121
5122 @Override
5123 public boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
5124 synchronized (mGlobalLock) {
5125 return ActivityTaskManagerService.this.isGetTasksAllowed(
5126 caller, callingPid, callingUid);
5127 }
5128 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005129
5130 @Override
5131 public void onProcessAdded(WindowProcessController proc) {
5132 synchronized (mGlobalLock) {
5133 mProcessNames.put(proc.mName, proc.mUid, proc);
5134 }
5135 }
5136
5137 @Override
5138 public void onProcessRemoved(String name, int uid) {
5139 synchronized (mGlobalLock) {
5140 mProcessNames.remove(name, uid);
5141 }
5142 }
5143
5144 @Override
5145 public void onCleanUpApplicationRecord(WindowProcessController proc) {
5146 synchronized (mGlobalLock) {
5147 if (proc == mHomeProcess) {
5148 mHomeProcess = null;
5149 }
5150 if (proc == mPreviousProcess) {
5151 mPreviousProcess = null;
5152 }
5153 }
5154 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005155
5156 @Override
5157 public int getTopProcessState() {
5158 synchronized (mGlobalLock) {
5159 return mTopProcessState;
5160 }
5161 }
5162
5163 @Override
5164 public boolean isSleeping() {
5165 synchronized (mGlobalLock) {
5166 return isSleepingLocked();
5167 }
5168 }
5169
5170 @Override
5171 public boolean isShuttingDown() {
5172 synchronized (mGlobalLock) {
5173 return mShuttingDown;
5174 }
5175 }
5176
5177 @Override
5178 public boolean shuttingDown(boolean booted, int timeout) {
5179 synchronized (mGlobalLock) {
5180 mShuttingDown = true;
5181 mStackSupervisor.prepareForShutdownLocked();
5182 updateEventDispatchingLocked(booted);
5183 return mStackSupervisor.shutdownLocked(timeout);
5184 }
5185 }
5186
5187 @Override
5188 public void enableScreenAfterBoot(boolean booted) {
5189 synchronized (mGlobalLock) {
5190 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5191 SystemClock.uptimeMillis());
5192 mWindowManager.enableScreenAfterBoot();
5193 updateEventDispatchingLocked(booted);
5194 }
5195 }
5196
5197 @Override
5198 public boolean showStrictModeViolationDialog() {
5199 synchronized (mGlobalLock) {
5200 return mShowDialogs && !mSleeping && !mShuttingDown;
5201 }
5202 }
5203
5204 @Override
5205 public void showSystemReadyErrorDialogsIfNeeded() {
5206 synchronized (mGlobalLock) {
5207 try {
5208 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
5209 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
5210 + " data partition or your device will be unstable.");
5211 mUiHandler.post(() -> {
5212 if (mShowDialogs) {
5213 AlertDialog d = new BaseErrorDialog(mUiContext);
5214 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5215 d.setCancelable(false);
5216 d.setTitle(mUiContext.getText(R.string.android_system_label));
5217 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
5218 d.setButton(DialogInterface.BUTTON_POSITIVE,
5219 mUiContext.getText(R.string.ok),
5220 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5221 d.show();
5222 }
5223 });
5224 }
5225 } catch (RemoteException e) {
5226 }
5227
5228 if (!Build.isBuildConsistent()) {
5229 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
5230 mUiHandler.post(() -> {
5231 if (mShowDialogs) {
5232 AlertDialog d = new BaseErrorDialog(mUiContext);
5233 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5234 d.setCancelable(false);
5235 d.setTitle(mUiContext.getText(R.string.android_system_label));
5236 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
5237 d.setButton(DialogInterface.BUTTON_POSITIVE,
5238 mUiContext.getText(R.string.ok),
5239 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5240 d.show();
5241 }
5242 });
5243 }
5244 }
5245 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005246 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07005247}