blob: 77269054c4b1ea70530b9a4acf693add23e09fa1 [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
Wale Ogunwale59507092018-10-29 09:00:30 -070017package com.android.server.wm;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070018
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 Ogunwalebff2df42018-10-18 17:09:19 -070029import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
Evan Rosky4505b352018-09-06 11:20:40 -070030import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
Yunfan Chen79b96062018-10-17 12:45:23 -070031import static android.app.ActivityTaskManager.INVALID_TASK_ID;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070032import static android.app.ActivityTaskManager.RESIZE_MODE_PRESERVE_WINDOW;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070033import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
34import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070035import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
36import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070037import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
38import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070039import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070040import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Wale Ogunwale31913b52018-10-13 08:29:31 -070041import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070042import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
Wale Ogunwale31913b52018-10-13 08:29:31 -070043import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
Wale Ogunwale214f3482018-10-04 11:00:47 -070044import static android.content.pm.ApplicationInfo.FLAG_FACTORY_TEST;
Wale Ogunwale342fbe92018-10-09 08:44:10 -070045import static android.content.pm.ConfigurationInfo.GL_ES_VERSION_UNDEFINED;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070046import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
47import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
Evan Rosky4505b352018-09-06 11:20:40 -070048import static android.content.pm.PackageManager.FEATURE_PC;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070049import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070050import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070051import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
52import static android.os.Build.VERSION_CODES.N;
Wale Ogunwale214f3482018-10-04 11:00:47 -070053import static android.os.FactoryTest.FACTORY_TEST_HIGH_LEVEL;
54import static android.os.FactoryTest.FACTORY_TEST_LOW_LEVEL;
55import static android.os.FactoryTest.FACTORY_TEST_OFF;
Wale Ogunwale31913b52018-10-13 08:29:31 -070056import static android.os.Process.FIRST_APPLICATION_UID;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070057import static android.os.Process.SYSTEM_UID;
Evan Rosky4505b352018-09-06 11:20:40 -070058import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070059import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
60import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
61import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
62import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
Evan Rosky4505b352018-09-06 11:20:40 -070063import static android.provider.Settings.Global.HIDE_ERROR_DIALOGS;
64import static android.provider.Settings.System.FONT_SCALE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070065import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
66import static android.view.Display.DEFAULT_DISPLAY;
67import static android.view.Display.INVALID_DISPLAY;
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;
Evan Rosky4505b352018-09-06 11:20:40 -070070
Yunfan Chen79b96062018-10-17 12:45:23 -070071import static com.android.server.am.ActivityManagerService.ANR_TRACE_DIR;
72import static com.android.server.am.ActivityManagerService.MY_PID;
73import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS;
74import static com.android.server.am.ActivityManagerService.dumpStackTraces;
Wale Ogunwale31913b52018-10-13 08:29:31 -070075import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.CONFIG_WILL_CHANGE;
76import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.CONTROLLER;
77import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.CURRENT_TRACKER;
78import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.Controller.IS_A_MONKEY;
79import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.GLOBAL_CONFIGURATION;
80import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.GOING_TO_SLEEP;
81import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.HEAVY_WEIGHT_PROC;
82import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.HOME_PROC;
83import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.LAUNCHING_ACTIVITY;
84import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC;
Wale Ogunwale59507092018-10-29 09:00:30 -070085import static com.android.server.am.ActivityManagerServiceDumpProcessesProto
86 .PREVIOUS_PROC_VISIBLE_TIME_MS;
Wale Ogunwale31913b52018-10-13 08:29:31 -070087import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.SCREEN_COMPAT_PACKAGES;
Wale Ogunwale59507092018-10-29 09:00:30 -070088import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage
89 .MODE;
90import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage
91 .PACKAGE;
92import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
93import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME;
94import static com.android.server.wm.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
95import static com.android.server.wm.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
96import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
97import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
98import static com.android.server.wm.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
99import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ALL;
100import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
101import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_FOCUS;
102import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_IMMERSIVE;
103import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_LOCKTASK;
104import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STACK;
105import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
106import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
107import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_VISIBILITY;
108import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
109import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS;
110import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_IMMERSIVE;
111import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_LOCKTASK;
112import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STACK;
113import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH;
114import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_VISIBILITY;
115import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
116import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
Evan Rosky4505b352018-09-06 11:20:40 -0700117import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT;
118import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_DATA;
119import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
120import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;
wilsonshihe7903ea2018-09-26 16:17:59 +0800121import static com.android.server.wm.ActivityTaskManagerService.H.REPORT_TIME_TRACKER_MSG;
122import static com.android.server.wm.ActivityTaskManagerService.UiHandler.DISMISS_DIALOG_UI_MSG;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700123import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
124import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
wilsonshihe7903ea2018-09-26 16:17:59 +0800125import static com.android.server.wm.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
126import static com.android.server.wm.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
127import static com.android.server.wm.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700128
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700129import android.Manifest;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700130import android.annotation.NonNull;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700131import android.annotation.Nullable;
132import android.annotation.UserIdInt;
133import android.app.Activity;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700134import android.app.ActivityManager;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700135import android.app.ActivityManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700136import android.app.ActivityOptions;
137import android.app.ActivityTaskManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700138import android.app.ActivityThread;
139import android.app.AlertDialog;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700140import android.app.AppGlobals;
Evan Rosky4505b352018-09-06 11:20:40 -0700141import android.app.Dialog;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700142import android.app.IActivityController;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700143import android.app.IActivityTaskManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700144import android.app.IApplicationThread;
145import android.app.IAssistDataReceiver;
Wale Ogunwale53783742018-09-16 10:21:51 -0700146import android.app.INotificationManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700147import android.app.ITaskStackListener;
Wale Ogunwale53783742018-09-16 10:21:51 -0700148import android.app.Notification;
149import android.app.NotificationManager;
150import android.app.PendingIntent;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700151import android.app.PictureInPictureParams;
152import android.app.ProfilerInfo;
153import android.app.RemoteAction;
154import android.app.WaitResult;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700155import android.app.WindowConfiguration;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700156import android.app.admin.DevicePolicyCache;
157import android.app.assist.AssistContent;
158import android.app.assist.AssistStructure;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700159import android.app.usage.UsageStatsManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700160import android.content.ActivityNotFoundException;
161import android.content.ComponentName;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700162import android.content.ContentResolver;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700163import android.content.Context;
Evan Rosky4505b352018-09-06 11:20:40 -0700164import android.content.DialogInterface;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700165import android.content.IIntentSender;
166import android.content.Intent;
167import android.content.pm.ActivityInfo;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700168import android.content.pm.ApplicationInfo;
Yunfan Chen75157d72018-07-27 14:47:21 +0900169import android.content.pm.ConfigurationInfo;
Evan Rosky4505b352018-09-06 11:20:40 -0700170import android.content.pm.IPackageManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700171import android.content.pm.PackageManager;
Evan Rosky4505b352018-09-06 11:20:40 -0700172import android.content.pm.PackageManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700173import android.content.pm.ParceledListSlice;
174import android.content.pm.ResolveInfo;
Wale Ogunwale53783742018-09-16 10:21:51 -0700175import android.content.res.CompatibilityInfo;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700176import android.content.res.Configuration;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700177import android.content.res.Resources;
Evan Rosky4505b352018-09-06 11:20:40 -0700178import android.database.ContentObserver;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700179import android.graphics.Bitmap;
180import android.graphics.Point;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700181import android.graphics.Rect;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700182import android.metrics.LogMaker;
183import android.net.Uri;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700184import android.os.Binder;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700185import android.os.Build;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700186import android.os.Bundle;
Wale Ogunwale214f3482018-10-04 11:00:47 -0700187import android.os.FactoryTest;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700188import android.os.FileUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700189import android.os.Handler;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700190import android.os.IBinder;
Evan Rosky4505b352018-09-06 11:20:40 -0700191import android.os.IUserManager;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700192import android.os.LocaleList;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700193import android.os.Looper;
194import android.os.Message;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700195import android.os.PersistableBundle;
Evan Rosky4505b352018-09-06 11:20:40 -0700196import android.os.PowerManager;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700197import android.os.PowerManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700198import android.os.RemoteException;
Evan Rosky4505b352018-09-06 11:20:40 -0700199import android.os.ServiceManager;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700200import android.os.StrictMode;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700201import android.os.SystemClock;
202import android.os.SystemProperties;
Evan Rosky4505b352018-09-06 11:20:40 -0700203import android.os.Trace;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700204import android.os.UpdateLock;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700205import android.os.UserHandle;
Evan Rosky4505b352018-09-06 11:20:40 -0700206import android.os.UserManager;
207import android.os.WorkSource;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700208import android.os.storage.IStorageManager;
209import android.os.storage.StorageManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700210import android.provider.Settings;
211import android.service.voice.IVoiceInteractionSession;
212import android.service.voice.VoiceInteractionManagerInternal;
213import android.telecom.TelecomManager;
214import android.text.TextUtils;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700215import android.text.format.Time;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700216import android.util.ArrayMap;
217import android.util.EventLog;
218import android.util.Log;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700219import android.util.Slog;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700220import android.util.SparseArray;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700221import android.util.SparseIntArray;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700222import android.util.StatsLog;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700223import android.util.TimeUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700224import android.util.proto.ProtoOutputStream;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700225import android.view.IRecentsAnimationRunner;
226import android.view.RemoteAnimationAdapter;
227import android.view.RemoteAnimationDefinition;
Evan Rosky4505b352018-09-06 11:20:40 -0700228import android.view.WindowManager;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700229
Evan Rosky4505b352018-09-06 11:20:40 -0700230import com.android.internal.R;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700231import com.android.internal.annotations.VisibleForTesting;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700232import com.android.internal.app.AssistUtils;
Evan Rosky4505b352018-09-06 11:20:40 -0700233import com.android.internal.app.IAppOpsService;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700234import com.android.internal.app.IVoiceInteractor;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700235import com.android.internal.app.ProcessMap;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700236import com.android.internal.logging.MetricsLogger;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700237import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Wale Ogunwale53783742018-09-16 10:21:51 -0700238import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
239import com.android.internal.notification.SystemNotificationChannels;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700240import com.android.internal.os.TransferPipe;
Evan Rosky4505b352018-09-06 11:20:40 -0700241import com.android.internal.os.logging.MetricsLoggerWrapper;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700242import com.android.internal.policy.IKeyguardDismissCallback;
243import com.android.internal.policy.KeyguardDismissCallback;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700244import com.android.internal.util.ArrayUtils;
245import com.android.internal.util.FastPrintWriter;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700246import com.android.internal.util.Preconditions;
Wale Ogunwale53783742018-09-16 10:21:51 -0700247import com.android.internal.util.function.pooled.PooledLambda;
Evan Rosky4505b352018-09-06 11:20:40 -0700248import com.android.server.AppOpsService;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700249import com.android.server.AttributeCache;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700250import com.android.server.LocalServices;
251import com.android.server.SystemService;
Evan Rosky4505b352018-09-06 11:20:40 -0700252import com.android.server.SystemServiceManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700253import com.android.server.Watchdog;
Wale Ogunwale59507092018-10-29 09:00:30 -0700254import com.android.server.am.ActivityManagerService;
255import com.android.server.am.ActivityManagerServiceDumpActivitiesProto;
256import com.android.server.am.ActivityManagerServiceDumpProcessesProto;
257import com.android.server.am.AppTimeTracker;
258import com.android.server.am.BaseErrorDialog;
259import com.android.server.am.EventLogTags;
260import com.android.server.am.PendingIntentController;
261import com.android.server.am.PendingIntentRecord;
262import com.android.server.am.UserState;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700263import com.android.server.firewall.IntentFirewall;
Evan Rosky4505b352018-09-06 11:20:40 -0700264import com.android.server.pm.UserManagerService;
265import com.android.server.uri.UriGrantsManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700266import com.android.server.vr.VrManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700267
Wale Ogunwale31913b52018-10-13 08:29:31 -0700268import java.io.BufferedReader;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700269import java.io.File;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700270import java.io.FileDescriptor;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700271import java.io.FileOutputStream;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700272import java.io.FileReader;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700273import java.io.IOException;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700274import java.io.PrintWriter;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700275import java.io.StringWriter;
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700276import java.lang.ref.WeakReference;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700277import java.text.DateFormat;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700278import java.util.ArrayList;
Wale Ogunwale27c48ae2018-10-25 19:01:01 -0700279import java.util.Arrays;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700280import java.util.Date;
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700281import java.util.HashSet;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700282import java.util.List;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700283import java.util.Locale;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700284import java.util.Map;
285import java.util.Set;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700286
287/**
288 * System service for managing activities and their containers (task, stacks, displays,... ).
289 *
290 * {@hide}
291 */
292public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
Wale Ogunwale98875612018-10-12 07:53:02 -0700293 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityTaskManagerService" : TAG_ATM;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700294 private static final String TAG_STACK = TAG + POSTFIX_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700295 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
296 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
297 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
298 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
299 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700300 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700301
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700302 // How long we wait until we timeout on key dispatching.
Wale Ogunwale51cc98a2018-10-15 10:41:05 -0700303 public static final int KEY_DISPATCHING_TIMEOUT_MS = 5 * 1000;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700304 // How long we wait until we timeout on key dispatching during instrumentation.
Wale Ogunwale51cc98a2018-10-15 10:41:05 -0700305 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS = 60 * 1000;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700306
Wale Ogunwale98875612018-10-12 07:53:02 -0700307 /** Used to indicate that an app transition should be animated. */
308 static final boolean ANIMATE = true;
309
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700310 /** Hardware-reported OpenGLES version. */
311 final int GL_ES_VERSION;
312
Wale Ogunwale31913b52018-10-13 08:29:31 -0700313 public static final String DUMP_ACTIVITIES_CMD = "activities" ;
314 public static final String DUMP_ACTIVITIES_SHORT_CMD = "a" ;
315 public static final String DUMP_LASTANR_CMD = "lastanr" ;
316 public static final String DUMP_LASTANR_TRACES_CMD = "lastanr-traces" ;
317 public static final String DUMP_STARTER_CMD = "starter" ;
318 public static final String DUMP_CONTAINERS_CMD = "containers" ;
319 public static final String DUMP_RECENTS_CMD = "recents" ;
320 public static final String DUMP_RECENTS_SHORT_CMD = "r" ;
321
Wale Ogunwale64258362018-10-16 15:13:37 -0700322 /** This activity is not being relaunched, or being relaunched for a non-resize reason. */
323 public static final int RELAUNCH_REASON_NONE = 0;
324 /** This activity is being relaunched due to windowing mode change. */
325 public static final int RELAUNCH_REASON_WINDOWING_MODE_RESIZE = 1;
326 /** This activity is being relaunched due to a free-resize operation. */
327 public static final int RELAUNCH_REASON_FREE_RESIZE = 2;
328
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700329 Context mContext;
Wale Ogunwale64258362018-10-16 15:13:37 -0700330
Wale Ogunwalef6733932018-06-27 05:14:34 -0700331 /**
332 * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
333 * change at runtime. Use mContext for non-UI purposes.
334 */
335 final Context mUiContext;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700336 final ActivityThread mSystemThread;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700337 H mH;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700338 UiHandler mUiHandler;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700339 ActivityManagerInternal mAmInternal;
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700340 UriGrantsManagerInternal mUgmInternal;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700341 private PackageManagerInternal mPmInternal;
Wale Ogunwale53783742018-09-16 10:21:51 -0700342 private ActivityTaskManagerInternal mInternal;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700343 PowerManagerInternal mPowerManagerInternal;
344 private UsageStatsManagerInternal mUsageStatsInternal;
345
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700346 PendingIntentController mPendingIntentController;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700347 IntentFirewall mIntentFirewall;
348
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700349 /* Global service lock used by the package the owns this service. */
350 Object mGlobalLock;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700351 ActivityStackSupervisor mStackSupervisor;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700352 WindowManagerService mWindowManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700353 private UserManagerService mUserManager;
354 private AppOpsService mAppOpsService;
Wale Ogunwalebff2df42018-10-18 17:09:19 -0700355 /** All active uids in the system. */
Wale Ogunwale9de19442018-10-18 19:05:03 -0700356 private final SparseArray<Integer> mActiveUids = new SparseArray<>();
357 private final SparseArray<String> mPendingTempWhitelist = new SparseArray<>();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700358 /** All processes currently running that might have a window organized by name. */
359 final ProcessMap<WindowProcessController> mProcessNames = new ProcessMap<>();
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700360 /** All processes we currently have running mapped by pid */
361 final SparseArray<WindowProcessController> mPidMap = new SparseArray<>();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700362 /** This is the process holding what we currently consider to be the "home" activity. */
363 WindowProcessController mHomeProcess;
Wale Ogunwale53783742018-09-16 10:21:51 -0700364 /** The currently running heavy-weight process, if any. */
365 WindowProcessController mHeavyWeightProcess = null;
Wale Ogunwale214f3482018-10-04 11:00:47 -0700366 boolean mHasHeavyWeightFeature;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700367 /**
368 * This is the process holding the activity the user last visited that is in a different process
369 * from the one they are currently in.
370 */
371 WindowProcessController mPreviousProcess;
372 /** The time at which the previous process was last visible. */
373 long mPreviousProcessVisibleTime;
374
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700375 /** List of intents that were used to start the most recent tasks. */
376 private RecentTasks mRecentTasks;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700377 /** State of external calls telling us if the device is awake or asleep. */
378 private boolean mKeyguardShown = false;
379
380 // Wrapper around VoiceInteractionServiceManager
381 private AssistUtils mAssistUtils;
382
383 // VoiceInteraction session ID that changes for each new request except when
384 // being called for multi-window assist in a single session.
385 private int mViSessionId = 1000;
386
387 // How long to wait in getAssistContextExtras for the activity and foreground services
388 // to respond with the result.
389 private static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
390
391 // How long top wait when going through the modern assist (which doesn't need to block
392 // on getting this result before starting to launch its UI).
393 private static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
394
395 // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
396 private static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
397
398 private final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
399
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700400 // Keeps track of the active voice interaction service component, notified from
401 // VoiceInteractionManagerService
402 ComponentName mActiveVoiceInteractionServiceComponent;
403
Wale Ogunwalee2172292018-10-25 10:11:10 -0700404 VrController mVrController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700405 KeyguardController mKeyguardController;
406 private final ClientLifecycleManager mLifecycleManager;
407 private TaskChangeNotificationController mTaskChangeNotificationController;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700408 /** The controller for all operations related to locktask. */
409 private LockTaskController mLockTaskController;
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700410 private ActivityStartController mActivityStartController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700411
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700412 boolean mSuppressResizeConfigChanges;
413
414 private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
415 new UpdateConfigurationResult();
416
417 static final class UpdateConfigurationResult {
418 // Configuration changes that were updated.
419 int changes;
420 // If the activity was relaunched to match the new configuration.
421 boolean activityRelaunched;
422
423 void reset() {
424 changes = 0;
425 activityRelaunched = false;
426 }
427 }
428
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700429 /** Current sequencing integer of the configuration, for skipping old configurations. */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700430 private int mConfigurationSeq;
431 // To cache the list of supported system locales
432 private String[] mSupportedSystemLocales = null;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700433
434 /**
435 * Temp object used when global and/or display override configuration is updated. It is also
436 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
437 * anyone...
438 */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700439 private Configuration mTempConfig = new Configuration();
440
Wale Ogunwalef6733932018-06-27 05:14:34 -0700441 /** Temporary to avoid allocations. */
442 final StringBuilder mStringBuilder = new StringBuilder(256);
443
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700444 // Amount of time after a call to stopAppSwitches() during which we will
445 // prevent further untrusted switches from happening.
446 private static final long APP_SWITCH_DELAY_TIME = 5 * 1000;
447
448 /**
449 * The time at which we will allow normal application switches again,
450 * after a call to {@link #stopAppSwitches()}.
451 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700452 private long mAppSwitchesAllowedTime;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700453 /**
454 * This is set to true after the first switch after mAppSwitchesAllowedTime
455 * is set; any switches after that will clear the time.
456 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700457 private boolean mDidAppSwitch;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700458
459 IActivityController mController = null;
460 boolean mControllerIsAMonkey = false;
461
Wale Ogunwale214f3482018-10-04 11:00:47 -0700462 final int mFactoryTest;
463
464 /** Used to control how we initialize the service. */
465 ComponentName mTopComponent;
466 String mTopAction = Intent.ACTION_MAIN;
467 String mTopData;
468
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700469 /**
Wale Ogunwale31913b52018-10-13 08:29:31 -0700470 * Dump of the activity state at the time of the last ANR. Cleared after
471 * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
472 */
473 String mLastANRState;
474
475 /**
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700476 * Used to retain an update lock when the foreground activity is in
477 * immersive mode.
478 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700479 private final UpdateLock mUpdateLock = new UpdateLock("immersive");
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700480
481 /**
482 * Packages that are being allowed to perform unrestricted app switches. Mapping is
483 * User -> Type -> uid.
484 */
485 final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
486
487 /** The dimensions of the thumbnails in the Recents UI. */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700488 private int mThumbnailWidth;
489 private int mThumbnailHeight;
490 private float mFullscreenThumbnailScale;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700491
492 /**
493 * Flag that indicates if multi-window is enabled.
494 *
495 * For any particular form of multi-window to be enabled, generic multi-window must be enabled
496 * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
497 * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
498 * At least one of the forms of multi-window must be enabled in order for this flag to be
499 * initialized to 'true'.
500 *
501 * @see #mSupportsSplitScreenMultiWindow
502 * @see #mSupportsFreeformWindowManagement
503 * @see #mSupportsPictureInPicture
504 * @see #mSupportsMultiDisplay
505 */
506 boolean mSupportsMultiWindow;
507 boolean mSupportsSplitScreenMultiWindow;
508 boolean mSupportsFreeformWindowManagement;
509 boolean mSupportsPictureInPicture;
510 boolean mSupportsMultiDisplay;
511 boolean mForceResizableActivities;
512
513 final List<ActivityTaskManagerInternal.ScreenObserver> mScreenObservers = new ArrayList<>();
514
515 // VR Vr2d Display Id.
516 int mVr2dDisplayId = INVALID_DISPLAY;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700517
Wale Ogunwalef6733932018-06-27 05:14:34 -0700518 /**
519 * Set while we are wanting to sleep, to prevent any
520 * activities from being started/resumed.
521 *
522 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
523 *
524 * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
525 * while in the sleep state until there is a pending transition out of sleep, in which case
526 * mSleeping is set to false, and remains false while awake.
527 *
528 * Whether mSleeping can quickly toggled between true/false without the device actually
529 * display changing states is undefined.
530 */
531 private boolean mSleeping = false;
532
533 /**
534 * The process state used for processes that are running the top activities.
535 * This changes between TOP and TOP_SLEEPING to following mSleeping.
536 */
537 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
538
539 // Whether we should show our dialogs (ANR, crash, etc) or just perform their default action
540 // automatically. Important for devices without direct input devices.
541 private boolean mShowDialogs = true;
542
543 /** Set if we are shutting down the system, similar to sleeping. */
544 boolean mShuttingDown = false;
545
546 /**
547 * We want to hold a wake lock while running a voice interaction session, since
548 * this may happen with the screen off and we need to keep the CPU running to
549 * be able to continue to interact with the user.
550 */
551 PowerManager.WakeLock mVoiceWakeLock;
552
553 /**
554 * Set while we are running a voice interaction. This overrides sleeping while it is active.
555 */
556 IVoiceInteractionSession mRunningVoice;
557
558 /**
559 * The last resumed activity. This is identical to the current resumed activity most
560 * of the time but could be different when we're pausing one activity before we resume
561 * another activity.
562 */
563 ActivityRecord mLastResumedActivity;
564
565 /**
566 * The activity that is currently being traced as the active resumed activity.
567 *
568 * @see #updateResumedAppTrace
569 */
570 private @Nullable ActivityRecord mTracedResumedActivity;
571
572 /** If non-null, we are tracking the time the user spends in the currently focused app. */
573 AppTimeTracker mCurAppTimeTracker;
574
Wale Ogunwale008163e2018-07-23 23:11:08 -0700575 private AppWarnings mAppWarnings;
576
Wale Ogunwale53783742018-09-16 10:21:51 -0700577 /**
578 * Packages that the user has asked to have run in screen size
579 * compatibility mode instead of filling the screen.
580 */
581 CompatModePackages mCompatModePackages;
582
Wale Ogunwalef6733932018-06-27 05:14:34 -0700583 private FontScaleSettingObserver mFontScaleSettingObserver;
584
585 private final class FontScaleSettingObserver extends ContentObserver {
586 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
587 private final Uri mHideErrorDialogsUri = Settings.Global.getUriFor(HIDE_ERROR_DIALOGS);
588
589 public FontScaleSettingObserver() {
590 super(mH);
591 final ContentResolver resolver = mContext.getContentResolver();
592 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
593 resolver.registerContentObserver(mHideErrorDialogsUri, false, this,
594 UserHandle.USER_ALL);
595 }
596
597 @Override
598 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
599 if (mFontScaleUri.equals(uri)) {
600 updateFontScaleIfNeeded(userId);
601 } else if (mHideErrorDialogsUri.equals(uri)) {
602 synchronized (mGlobalLock) {
603 updateShouldShowDialogsLocked(getGlobalConfiguration());
604 }
605 }
606 }
607 }
608
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700609 ActivityTaskManagerService(Context context) {
610 mContext = context;
Wale Ogunwale214f3482018-10-04 11:00:47 -0700611 mFactoryTest = FactoryTest.getMode();
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700612 mSystemThread = ActivityThread.currentActivityThread();
613 mUiContext = mSystemThread.getSystemUiContext();
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700614 mLifecycleManager = new ClientLifecycleManager();
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700615 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", GL_ES_VERSION_UNDEFINED);
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700616 }
617
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700618 public void onSystemReady() {
619 synchronized (mGlobalLock) {
620 mHasHeavyWeightFeature = mContext.getPackageManager().hasSystemFeature(
621 PackageManager.FEATURE_CANT_SAVE_STATE);
622 mAssistUtils = new AssistUtils(mContext);
623 mVrController.onSystemReady();
624 mRecentTasks.onSystemReadyLocked();
625 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700626 }
627
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700628 public void onInitPowerManagement() {
629 synchronized (mGlobalLock) {
630 mStackSupervisor.initPowerManagement();
631 final PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
632 mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
633 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
634 mVoiceWakeLock.setReferenceCounted(false);
635 }
Wale Ogunwalef6733932018-06-27 05:14:34 -0700636 }
637
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700638 public void installSystemProviders() {
Wale Ogunwalef6733932018-06-27 05:14:34 -0700639 mFontScaleSettingObserver = new FontScaleSettingObserver();
640 }
641
Wale Ogunwale59507092018-10-29 09:00:30 -0700642 public void retrieveSettings(ContentResolver resolver) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700643 final boolean freeformWindowManagement =
644 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
645 || Settings.Global.getInt(
646 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
647
648 final boolean supportsMultiWindow = ActivityTaskManager.supportsMultiWindow(mContext);
649 final boolean supportsPictureInPicture = supportsMultiWindow &&
650 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
651 final boolean supportsSplitScreenMultiWindow =
652 ActivityTaskManager.supportsSplitScreenMultiWindow(mContext);
653 final boolean supportsMultiDisplay = mContext.getPackageManager()
654 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
655 final boolean alwaysFinishActivities =
656 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
657 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
658 final boolean forceResizable = Settings.Global.getInt(
659 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
Garfield Tane0846042018-07-26 13:42:04 -0700660 final boolean isPc = mContext.getPackageManager().hasSystemFeature(FEATURE_PC);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700661
662 // Transfer any global setting for forcing RTL layout, into a System Property
663 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
664
665 final Configuration configuration = new Configuration();
666 Settings.System.getConfiguration(resolver, configuration);
667 if (forceRtl) {
668 // This will take care of setting the correct layout direction flags
669 configuration.setLayoutDirection(configuration.locale);
670 }
671
672 synchronized (mGlobalLock) {
673 mForceResizableActivities = forceResizable;
674 final boolean multiWindowFormEnabled = freeformWindowManagement
675 || supportsSplitScreenMultiWindow
676 || supportsPictureInPicture
677 || supportsMultiDisplay;
678 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
679 mSupportsMultiWindow = true;
680 mSupportsFreeformWindowManagement = freeformWindowManagement;
681 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
682 mSupportsPictureInPicture = supportsPictureInPicture;
683 mSupportsMultiDisplay = supportsMultiDisplay;
684 } else {
685 mSupportsMultiWindow = false;
686 mSupportsFreeformWindowManagement = false;
687 mSupportsSplitScreenMultiWindow = false;
688 mSupportsPictureInPicture = false;
689 mSupportsMultiDisplay = false;
690 }
691 mWindowManager.setForceResizableTasks(mForceResizableActivities);
692 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
Garfield Tane0846042018-07-26 13:42:04 -0700693 mWindowManager.setSupportsFreeformWindowManagement(mSupportsFreeformWindowManagement);
694 mWindowManager.setIsPc(isPc);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700695 // This happens before any activities are started, so we can change global configuration
696 // in-place.
697 updateConfigurationLocked(configuration, null, true);
698 final Configuration globalConfig = getGlobalConfiguration();
699 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
700
701 // Load resources only after the current configuration has been set.
702 final Resources res = mContext.getResources();
703 mThumbnailWidth = res.getDimensionPixelSize(
704 com.android.internal.R.dimen.thumbnail_width);
705 mThumbnailHeight = res.getDimensionPixelSize(
706 com.android.internal.R.dimen.thumbnail_height);
707
708 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
709 mFullscreenThumbnailScale = (float) res
710 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
711 (float) globalConfig.screenWidthDp;
712 } else {
713 mFullscreenThumbnailScale = res.getFraction(
714 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
715 }
716 }
717 }
718
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700719 // TODO: Will be converted to WM lock once transition is complete.
Wale Ogunwale59507092018-10-29 09:00:30 -0700720 public void setActivityManagerService(Object globalLock, Looper looper,
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700721 IntentFirewall intentFirewall, PendingIntentController intentController) {
Wale Ogunwale9de19442018-10-18 19:05:03 -0700722 mGlobalLock = globalLock;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700723 mH = new H(looper);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700724 mUiHandler = new UiHandler();
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700725 mIntentFirewall = intentFirewall;
Wale Ogunwale53783742018-09-16 10:21:51 -0700726 final File systemDir = SystemServiceManager.ensureSystemDir();
727 mAppWarnings = new AppWarnings(this, mUiContext, mH, mUiHandler, systemDir);
728 mCompatModePackages = new CompatModePackages(this, systemDir, mH);
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700729 mPendingIntentController = intentController;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700730
731 mTempConfig.setToDefaults();
732 mTempConfig.setLocales(LocaleList.getDefault());
733 mConfigurationSeq = mTempConfig.seq = 1;
734 mStackSupervisor = createStackSupervisor();
735 mStackSupervisor.onConfigurationChanged(mTempConfig);
736
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700737 mTaskChangeNotificationController =
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700738 new TaskChangeNotificationController(mGlobalLock, mStackSupervisor, mH);
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700739 mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mH);
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700740 mActivityStartController = new ActivityStartController(this);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700741 mRecentTasks = createRecentTasks();
742 mStackSupervisor.setRecentTasks(mRecentTasks);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700743 mVrController = new VrController(mGlobalLock);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700744 mKeyguardController = mStackSupervisor.getKeyguardController();
745 }
746
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700747 public void onActivityManagerInternalAdded() {
748 synchronized (mGlobalLock) {
749 mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
750 mUgmInternal = LocalServices.getService(UriGrantsManagerInternal.class);
751 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700752 }
753
Yunfan Chen75157d72018-07-27 14:47:21 +0900754 int increaseConfigurationSeqLocked() {
755 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
756 return mConfigurationSeq;
757 }
758
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700759 protected ActivityStackSupervisor createStackSupervisor() {
760 final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mH.getLooper());
761 supervisor.initialize();
762 return supervisor;
763 }
764
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700765 public void setWindowManager(WindowManagerService wm) {
766 synchronized (mGlobalLock) {
767 mWindowManager = wm;
768 mLockTaskController.setWindowManager(wm);
769 mStackSupervisor.setWindowManager(wm);
770 }
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700771 }
772
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700773 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
774 synchronized (mGlobalLock) {
775 mUsageStatsInternal = usageStatsManager;
776 }
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700777 }
778
Wale Ogunwalef6733932018-06-27 05:14:34 -0700779 UserManagerService getUserManager() {
780 if (mUserManager == null) {
781 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
782 mUserManager = (UserManagerService) IUserManager.Stub.asInterface(b);
783 }
784 return mUserManager;
785 }
786
787 AppOpsService getAppOpsService() {
788 if (mAppOpsService == null) {
789 IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
790 mAppOpsService = (AppOpsService) IAppOpsService.Stub.asInterface(b);
791 }
792 return mAppOpsService;
793 }
794
795 boolean hasUserRestriction(String restriction, int userId) {
796 return getUserManager().hasUserRestriction(restriction, userId);
797 }
798
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700799 protected RecentTasks createRecentTasks() {
800 return new RecentTasks(this, mStackSupervisor);
801 }
802
803 RecentTasks getRecentTasks() {
804 return mRecentTasks;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700805 }
806
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700807 ClientLifecycleManager getLifecycleManager() {
808 return mLifecycleManager;
809 }
810
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700811 ActivityStartController getActivityStartController() {
812 return mActivityStartController;
813 }
814
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700815 TaskChangeNotificationController getTaskChangeNotificationController() {
816 return mTaskChangeNotificationController;
817 }
818
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700819 LockTaskController getLockTaskController() {
820 return mLockTaskController;
821 }
822
Yunfan Chen75157d72018-07-27 14:47:21 +0900823 /**
824 * Return the global configuration used by the process corresponding to the input pid. This is
825 * usually the global configuration with some overrides specific to that process.
826 */
827 Configuration getGlobalConfigurationForCallingPid() {
828 final int pid = Binder.getCallingPid();
829 if (pid == MY_PID || pid < 0) {
830 return getGlobalConfiguration();
831 }
832 synchronized (mGlobalLock) {
833 final WindowProcessController app = mPidMap.get(pid);
834 return app != null ? app.getConfiguration() : getGlobalConfiguration();
835 }
836 }
837
838 /**
839 * Return the device configuration info used by the process corresponding to the input pid.
840 * The value is consistent with the global configuration for the process.
841 */
842 @Override
843 public ConfigurationInfo getDeviceConfigurationInfo() {
844 ConfigurationInfo config = new ConfigurationInfo();
845 synchronized (mGlobalLock) {
846 final Configuration globalConfig = getGlobalConfigurationForCallingPid();
847 config.reqTouchScreen = globalConfig.touchscreen;
848 config.reqKeyboardType = globalConfig.keyboard;
849 config.reqNavigation = globalConfig.navigation;
850 if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
851 || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
852 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
853 }
854 if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
855 && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
856 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
857 }
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700858 config.reqGlEsVersion = GL_ES_VERSION;
Yunfan Chen75157d72018-07-27 14:47:21 +0900859 }
860 return config;
861 }
862
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700863 private void start() {
Wale Ogunwale53783742018-09-16 10:21:51 -0700864 mInternal = new LocalService();
865 LocalServices.addService(ActivityTaskManagerInternal.class, mInternal);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700866 }
867
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700868 public static final class Lifecycle extends SystemService {
869 private final ActivityTaskManagerService mService;
870
871 public Lifecycle(Context context) {
872 super(context);
873 mService = new ActivityTaskManagerService(context);
874 }
875
876 @Override
877 public void onStart() {
878 publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700879 mService.start();
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700880 }
881
882 public ActivityTaskManagerService getService() {
883 return mService;
884 }
885 }
886
887 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700888 public final int startActivity(IApplicationThread caller, String callingPackage,
889 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
890 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
891 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
892 resultWho, requestCode, startFlags, profilerInfo, bOptions,
893 UserHandle.getCallingUserId());
894 }
895
896 @Override
897 public final int startActivities(IApplicationThread caller, String callingPackage,
898 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
899 int userId) {
900 final String reason = "startActivities";
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700901 enforceNotIsolatedCaller(reason);
902 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, reason);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700903 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700904 return getActivityStartController().startActivities(caller, -1, callingPackage, intents,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100905 resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId, reason,
906 null /* originatingPendingIntent */);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700907 }
908
909 @Override
910 public int startActivityAsUser(IApplicationThread caller, String callingPackage,
911 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
912 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
913 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
914 resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
915 true /*validateIncomingUser*/);
916 }
917
918 int startActivityAsUser(IApplicationThread caller, String callingPackage,
919 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
920 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
921 boolean validateIncomingUser) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700922 enforceNotIsolatedCaller("startActivityAsUser");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700923
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700924 userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700925 Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
926
927 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700928 return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700929 .setCaller(caller)
930 .setCallingPackage(callingPackage)
931 .setResolvedType(resolvedType)
932 .setResultTo(resultTo)
933 .setResultWho(resultWho)
934 .setRequestCode(requestCode)
935 .setStartFlags(startFlags)
936 .setProfilerInfo(profilerInfo)
937 .setActivityOptions(bOptions)
938 .setMayWait(userId)
939 .execute();
940
941 }
942
943 @Override
944 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
945 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700946 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions) {
947 enforceNotIsolatedCaller("startActivityIntentSender");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700948 // Refuse possible leaked file descriptors
949 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
950 throw new IllegalArgumentException("File descriptors passed in Intent");
951 }
952
953 if (!(target instanceof PendingIntentRecord)) {
954 throw new IllegalArgumentException("Bad PendingIntent object");
955 }
956
957 PendingIntentRecord pir = (PendingIntentRecord)target;
958
959 synchronized (mGlobalLock) {
960 // If this is coming from the currently resumed activity, it is
961 // effectively saying that app switches are allowed at this point.
Andrii Kulian5f750bc2018-07-17 08:57:23 -0700962 final ActivityStack stack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700963 if (stack.mResumedActivity != null &&
964 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700965 mAppSwitchesAllowedTime = 0;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700966 }
967 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700968 return pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700969 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700970 }
971
972 @Override
973 public boolean startNextMatchingActivity(IBinder callingActivity, Intent intent,
974 Bundle bOptions) {
975 // Refuse possible leaked file descriptors
976 if (intent != null && intent.hasFileDescriptors()) {
977 throw new IllegalArgumentException("File descriptors passed in Intent");
978 }
979 SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
980
981 synchronized (mGlobalLock) {
982 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
983 if (r == null) {
984 SafeActivityOptions.abort(options);
985 return false;
986 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700987 if (!r.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700988 // The caller is not running... d'oh!
989 SafeActivityOptions.abort(options);
990 return false;
991 }
992 intent = new Intent(intent);
993 // The caller is not allowed to change the data.
994 intent.setDataAndType(r.intent.getData(), r.intent.getType());
995 // And we are resetting to find the next component...
996 intent.setComponent(null);
997
998 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
999
1000 ActivityInfo aInfo = null;
1001 try {
1002 List<ResolveInfo> resolves =
1003 AppGlobals.getPackageManager().queryIntentActivities(
1004 intent, r.resolvedType,
1005 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
1006 UserHandle.getCallingUserId()).getList();
1007
1008 // Look for the original activity in the list...
1009 final int N = resolves != null ? resolves.size() : 0;
1010 for (int i=0; i<N; i++) {
1011 ResolveInfo rInfo = resolves.get(i);
1012 if (rInfo.activityInfo.packageName.equals(r.packageName)
1013 && rInfo.activityInfo.name.equals(r.info.name)) {
1014 // We found the current one... the next matching is
1015 // after it.
1016 i++;
1017 if (i<N) {
1018 aInfo = resolves.get(i).activityInfo;
1019 }
1020 if (debug) {
1021 Slog.v(TAG, "Next matching activity: found current " + r.packageName
1022 + "/" + r.info.name);
1023 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
1024 ? "null" : aInfo.packageName + "/" + aInfo.name));
1025 }
1026 break;
1027 }
1028 }
1029 } catch (RemoteException e) {
1030 }
1031
1032 if (aInfo == null) {
1033 // Nobody who is next!
1034 SafeActivityOptions.abort(options);
1035 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
1036 return false;
1037 }
1038
1039 intent.setComponent(new ComponentName(
1040 aInfo.applicationInfo.packageName, aInfo.name));
1041 intent.setFlags(intent.getFlags()&~(
1042 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
1043 Intent.FLAG_ACTIVITY_CLEAR_TOP|
1044 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
1045 FLAG_ACTIVITY_NEW_TASK));
1046
1047 // Okay now we need to start the new activity, replacing the currently running activity.
1048 // This is a little tricky because we want to start the new one as if the current one is
1049 // finished, but not finish the current one first so that there is no flicker.
1050 // And thus...
1051 final boolean wasFinishing = r.finishing;
1052 r.finishing = true;
1053
1054 // Propagate reply information over to the new activity.
1055 final ActivityRecord resultTo = r.resultTo;
1056 final String resultWho = r.resultWho;
1057 final int requestCode = r.requestCode;
1058 r.resultTo = null;
1059 if (resultTo != null) {
1060 resultTo.removeResultsLocked(r, resultWho, requestCode);
1061 }
1062
1063 final long origId = Binder.clearCallingIdentity();
1064 // TODO(b/64750076): Check if calling pid should really be -1.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001065 final int res = getActivityStartController()
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001066 .obtainStarter(intent, "startNextMatchingActivity")
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001067 .setCaller(r.app.getThread())
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001068 .setResolvedType(r.resolvedType)
1069 .setActivityInfo(aInfo)
1070 .setResultTo(resultTo != null ? resultTo.appToken : null)
1071 .setResultWho(resultWho)
1072 .setRequestCode(requestCode)
1073 .setCallingPid(-1)
1074 .setCallingUid(r.launchedFromUid)
1075 .setCallingPackage(r.launchedFromPackage)
1076 .setRealCallingPid(-1)
1077 .setRealCallingUid(r.launchedFromUid)
1078 .setActivityOptions(options)
1079 .execute();
1080 Binder.restoreCallingIdentity(origId);
1081
1082 r.finishing = wasFinishing;
1083 if (res != ActivityManager.START_SUCCESS) {
1084 return false;
1085 }
1086 return true;
1087 }
1088 }
1089
1090 @Override
1091 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
1092 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1093 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
1094 final WaitResult res = new WaitResult();
1095 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001096 enforceNotIsolatedCaller("startActivityAndWait");
1097 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
1098 userId, "startActivityAndWait");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001099 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001100 getActivityStartController().obtainStarter(intent, "startActivityAndWait")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001101 .setCaller(caller)
1102 .setCallingPackage(callingPackage)
1103 .setResolvedType(resolvedType)
1104 .setResultTo(resultTo)
1105 .setResultWho(resultWho)
1106 .setRequestCode(requestCode)
1107 .setStartFlags(startFlags)
1108 .setActivityOptions(bOptions)
1109 .setMayWait(userId)
1110 .setProfilerInfo(profilerInfo)
1111 .setWaitResult(res)
1112 .execute();
1113 }
1114 return res;
1115 }
1116
1117 @Override
1118 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
1119 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1120 int startFlags, Configuration config, Bundle bOptions, int userId) {
1121 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001122 enforceNotIsolatedCaller("startActivityWithConfig");
1123 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
1124 "startActivityWithConfig");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001125 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001126 return getActivityStartController().obtainStarter(intent, "startActivityWithConfig")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001127 .setCaller(caller)
1128 .setCallingPackage(callingPackage)
1129 .setResolvedType(resolvedType)
1130 .setResultTo(resultTo)
1131 .setResultWho(resultWho)
1132 .setRequestCode(requestCode)
1133 .setStartFlags(startFlags)
1134 .setGlobalConfiguration(config)
1135 .setActivityOptions(bOptions)
1136 .setMayWait(userId)
1137 .execute();
1138 }
1139 }
1140
1141 @Override
1142 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
1143 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1144 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
1145 int userId) {
1146
1147 // This is very dangerous -- it allows you to perform a start activity (including
1148 // permission grants) as any app that may launch one of your own activities. So
1149 // we will only allow this to be done from activities that are part of the core framework,
1150 // and then only when they are running as the system.
1151 final ActivityRecord sourceRecord;
1152 final int targetUid;
1153 final String targetPackage;
1154 final boolean isResolver;
1155 synchronized (mGlobalLock) {
1156 if (resultTo == null) {
1157 throw new SecurityException("Must be called from an activity");
1158 }
1159 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
1160 if (sourceRecord == null) {
1161 throw new SecurityException("Called with bad activity token: " + resultTo);
1162 }
1163 if (!sourceRecord.info.packageName.equals("android")) {
1164 throw new SecurityException(
1165 "Must be called from an activity that is declared in the android package");
1166 }
1167 if (sourceRecord.app == null) {
1168 throw new SecurityException("Called without a process attached to activity");
1169 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001170 if (UserHandle.getAppId(sourceRecord.app.mUid) != SYSTEM_UID) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001171 // This is still okay, as long as this activity is running under the
1172 // uid of the original calling activity.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001173 if (sourceRecord.app.mUid != sourceRecord.launchedFromUid) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001174 throw new SecurityException(
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001175 "Calling activity in uid " + sourceRecord.app.mUid
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001176 + " must be system uid or original calling uid "
1177 + sourceRecord.launchedFromUid);
1178 }
1179 }
1180 if (ignoreTargetSecurity) {
1181 if (intent.getComponent() == null) {
1182 throw new SecurityException(
1183 "Component must be specified with ignoreTargetSecurity");
1184 }
1185 if (intent.getSelector() != null) {
1186 throw new SecurityException(
1187 "Selector not allowed with ignoreTargetSecurity");
1188 }
1189 }
1190 targetUid = sourceRecord.launchedFromUid;
1191 targetPackage = sourceRecord.launchedFromPackage;
1192 isResolver = sourceRecord.isResolverOrChildActivity();
1193 }
1194
1195 if (userId == UserHandle.USER_NULL) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001196 userId = UserHandle.getUserId(sourceRecord.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001197 }
1198
1199 // TODO: Switch to user app stacks here.
1200 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001201 return getActivityStartController().obtainStarter(intent, "startActivityAsCaller")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001202 .setCallingUid(targetUid)
1203 .setCallingPackage(targetPackage)
1204 .setResolvedType(resolvedType)
1205 .setResultTo(resultTo)
1206 .setResultWho(resultWho)
1207 .setRequestCode(requestCode)
1208 .setStartFlags(startFlags)
1209 .setActivityOptions(bOptions)
1210 .setMayWait(userId)
1211 .setIgnoreTargetSecurity(ignoreTargetSecurity)
1212 .setFilterCallingUid(isResolver ? 0 /* system */ : targetUid)
1213 .execute();
1214 } catch (SecurityException e) {
1215 // XXX need to figure out how to propagate to original app.
1216 // A SecurityException here is generally actually a fault of the original
1217 // calling activity (such as a fairly granting permissions), so propagate it
1218 // back to them.
1219 /*
1220 StringBuilder msg = new StringBuilder();
1221 msg.append("While launching");
1222 msg.append(intent.toString());
1223 msg.append(": ");
1224 msg.append(e.getMessage());
1225 */
1226 throw e;
1227 }
1228 }
1229
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001230 int handleIncomingUser(int callingPid, int callingUid, int userId, String name) {
1231 return mAmInternal.handleIncomingUser(callingPid, callingUid, userId, false /* allowAll */,
1232 ALLOW_FULL_ONLY, name, null /* callerPackage */);
1233 }
1234
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001235 @Override
1236 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
1237 Intent intent, String resolvedType, IVoiceInteractionSession session,
1238 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
1239 Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001240 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001241 if (session == null || interactor == null) {
1242 throw new NullPointerException("null session or interactor");
1243 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001244 userId = handleIncomingUser(callingPid, callingUid, userId, "startVoiceActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001245 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001246 return getActivityStartController().obtainStarter(intent, "startVoiceActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001247 .setCallingUid(callingUid)
1248 .setCallingPackage(callingPackage)
1249 .setResolvedType(resolvedType)
1250 .setVoiceSession(session)
1251 .setVoiceInteractor(interactor)
1252 .setStartFlags(startFlags)
1253 .setProfilerInfo(profilerInfo)
1254 .setActivityOptions(bOptions)
1255 .setMayWait(userId)
1256 .execute();
1257 }
1258
1259 @Override
1260 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
1261 Intent intent, String resolvedType, Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001262 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
1263 userId = handleIncomingUser(callingPid, callingUid, userId, "startAssistantActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001264
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001265 return getActivityStartController().obtainStarter(intent, "startAssistantActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001266 .setCallingUid(callingUid)
1267 .setCallingPackage(callingPackage)
1268 .setResolvedType(resolvedType)
1269 .setActivityOptions(bOptions)
1270 .setMayWait(userId)
1271 .execute();
1272 }
1273
1274 @Override
1275 public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
1276 IRecentsAnimationRunner recentsAnimationRunner) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001277 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001278 final int callingPid = Binder.getCallingPid();
1279 final long origId = Binder.clearCallingIdentity();
1280 try {
1281 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07001282 final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
1283 final int recentsUid = mRecentTasks.getRecentsComponentUid();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001284
1285 // Start a new recents animation
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001286 final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
1287 getActivityStartController(), mWindowManager, callingPid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001288 anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
1289 recentsUid, assistDataReceiver);
1290 }
1291 } finally {
1292 Binder.restoreCallingIdentity(origId);
1293 }
1294 }
1295
1296 @Override
1297 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001298 enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001299 "startActivityFromRecents()");
1300
1301 final int callingPid = Binder.getCallingPid();
1302 final int callingUid = Binder.getCallingUid();
1303 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(bOptions);
1304 final long origId = Binder.clearCallingIdentity();
1305 try {
1306 synchronized (mGlobalLock) {
1307 return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
1308 safeOptions);
1309 }
1310 } finally {
1311 Binder.restoreCallingIdentity(origId);
1312 }
1313 }
1314
1315 /**
1316 * This is the internal entry point for handling Activity.finish().
1317 *
1318 * @param token The Binder token referencing the Activity we want to finish.
1319 * @param resultCode Result code, if any, from this Activity.
1320 * @param resultData Result data (Intent), if any, from this Activity.
1321 * @param finishTask Whether to finish the task associated with this Activity.
1322 *
1323 * @return Returns true if the activity successfully finished, or false if it is still running.
1324 */
1325 @Override
1326 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
1327 int finishTask) {
1328 // Refuse possible leaked file descriptors
1329 if (resultData != null && resultData.hasFileDescriptors()) {
1330 throw new IllegalArgumentException("File descriptors passed in Intent");
1331 }
1332
1333 synchronized (mGlobalLock) {
1334 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1335 if (r == null) {
1336 return true;
1337 }
1338 // Keep track of the root activity of the task before we finish it
1339 TaskRecord tr = r.getTask();
1340 ActivityRecord rootR = tr.getRootActivity();
1341 if (rootR == null) {
1342 Slog.w(TAG, "Finishing task with all activities already finished");
1343 }
1344 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
1345 // finish.
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001346 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001347 return false;
1348 }
1349
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001350 // TODO: There is a dup. of this block of code in ActivityStack.navigateUpToLocked
1351 // We should consolidate.
1352 if (mController != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001353 // Find the first activity that is not finishing.
1354 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
1355 if (next != null) {
1356 // ask watcher if this is allowed
1357 boolean resumeOK = true;
1358 try {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001359 resumeOK = mController.activityResuming(next.packageName);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001360 } catch (RemoteException e) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001361 mController = null;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001362 Watchdog.getInstance().setActivityController(null);
1363 }
1364
1365 if (!resumeOK) {
1366 Slog.i(TAG, "Not finishing activity because controller resumed");
1367 return false;
1368 }
1369 }
1370 }
1371 final long origId = Binder.clearCallingIdentity();
1372 try {
1373 boolean res;
1374 final boolean finishWithRootActivity =
1375 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
1376 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
1377 || (finishWithRootActivity && r == rootR)) {
1378 // If requested, remove the task that is associated to this activity only if it
1379 // was the root activity in the task. The result code and data is ignored
1380 // because we don't support returning them across task boundaries. Also, to
1381 // keep backwards compatibility we remove the task from recents when finishing
1382 // task with root activity.
1383 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
1384 finishWithRootActivity, "finish-activity");
1385 if (!res) {
1386 Slog.i(TAG, "Removing task failed to finish activity");
1387 }
Garfield Tan2746ab52018-07-25 12:33:01 -07001388 // Explicitly dismissing the activity so reset its relaunch flag.
Wale Ogunwale64258362018-10-16 15:13:37 -07001389 r.mRelaunchReason = RELAUNCH_REASON_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001390 } else {
1391 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
1392 resultData, "app-request", true);
1393 if (!res) {
1394 Slog.i(TAG, "Failed to finish by app-request");
1395 }
1396 }
1397 return res;
1398 } finally {
1399 Binder.restoreCallingIdentity(origId);
1400 }
1401 }
1402 }
1403
1404 @Override
1405 public boolean finishActivityAffinity(IBinder token) {
1406 synchronized (mGlobalLock) {
1407 final long origId = Binder.clearCallingIdentity();
1408 try {
1409 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1410 if (r == null) {
1411 return false;
1412 }
1413
1414 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
1415 // can finish.
1416 final TaskRecord task = r.getTask();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001417 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001418 return false;
1419 }
1420 return task.getStack().finishActivityAffinityLocked(r);
1421 } finally {
1422 Binder.restoreCallingIdentity(origId);
1423 }
1424 }
1425 }
1426
1427 @Override
1428 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
1429 final long origId = Binder.clearCallingIdentity();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001430 try {
1431 WindowProcessController proc = null;
1432 synchronized (mGlobalLock) {
1433 ActivityStack stack = ActivityRecord.getStackLocked(token);
1434 if (stack == null) {
1435 return;
1436 }
1437 final ActivityRecord r = mStackSupervisor.activityIdleInternalLocked(token,
1438 false /* fromTimeout */, false /* processPausingActivities */, config);
1439 if (r != null) {
1440 proc = r.app;
1441 }
1442 if (stopProfiling && proc != null) {
1443 proc.clearProfilerIfNeeded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001444 }
1445 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001446 } finally {
1447 Binder.restoreCallingIdentity(origId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001448 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001449 }
1450
1451 @Override
1452 public final void activityResumed(IBinder token) {
1453 final long origId = Binder.clearCallingIdentity();
1454 synchronized (mGlobalLock) {
1455 ActivityRecord.activityResumedLocked(token);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001456 mWindowManager.notifyAppResumedFinished(token);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001457 }
1458 Binder.restoreCallingIdentity(origId);
1459 }
1460
1461 @Override
1462 public final void activityPaused(IBinder token) {
1463 final long origId = Binder.clearCallingIdentity();
1464 synchronized (mGlobalLock) {
1465 ActivityStack stack = ActivityRecord.getStackLocked(token);
1466 if (stack != null) {
1467 stack.activityPausedLocked(token, false);
1468 }
1469 }
1470 Binder.restoreCallingIdentity(origId);
1471 }
1472
1473 @Override
1474 public final void activityStopped(IBinder token, Bundle icicle,
1475 PersistableBundle persistentState, CharSequence description) {
1476 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
1477
1478 // Refuse possible leaked file descriptors
1479 if (icicle != null && icicle.hasFileDescriptors()) {
1480 throw new IllegalArgumentException("File descriptors passed in Bundle");
1481 }
1482
1483 final long origId = Binder.clearCallingIdentity();
1484
1485 synchronized (mGlobalLock) {
1486 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1487 if (r != null) {
1488 r.activityStoppedLocked(icicle, persistentState, description);
1489 }
1490 }
1491
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001492 mAmInternal.trimApplications();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001493
1494 Binder.restoreCallingIdentity(origId);
1495 }
1496
1497 @Override
1498 public final void activityDestroyed(IBinder token) {
1499 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
1500 synchronized (mGlobalLock) {
1501 ActivityStack stack = ActivityRecord.getStackLocked(token);
1502 if (stack != null) {
1503 stack.activityDestroyedLocked(token, "activityDestroyed");
1504 }
1505 }
1506 }
1507
1508 @Override
1509 public final void activityRelaunched(IBinder token) {
1510 final long origId = Binder.clearCallingIdentity();
1511 synchronized (mGlobalLock) {
1512 mStackSupervisor.activityRelaunchedLocked(token);
1513 }
1514 Binder.restoreCallingIdentity(origId);
1515 }
1516
1517 public final void activitySlept(IBinder token) {
1518 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
1519
1520 final long origId = Binder.clearCallingIdentity();
1521
1522 synchronized (mGlobalLock) {
1523 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1524 if (r != null) {
1525 mStackSupervisor.activitySleptLocked(r);
1526 }
1527 }
1528
1529 Binder.restoreCallingIdentity(origId);
1530 }
1531
1532 @Override
1533 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
1534 synchronized (mGlobalLock) {
1535 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1536 if (r == null) {
1537 return;
1538 }
1539 final long origId = Binder.clearCallingIdentity();
1540 try {
1541 r.setRequestedOrientation(requestedOrientation);
1542 } finally {
1543 Binder.restoreCallingIdentity(origId);
1544 }
1545 }
1546 }
1547
1548 @Override
1549 public int getRequestedOrientation(IBinder token) {
1550 synchronized (mGlobalLock) {
1551 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1552 if (r == null) {
1553 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
1554 }
1555 return r.getRequestedOrientation();
1556 }
1557 }
1558
1559 @Override
1560 public void setImmersive(IBinder token, boolean immersive) {
1561 synchronized (mGlobalLock) {
1562 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1563 if (r == null) {
1564 throw new IllegalArgumentException();
1565 }
1566 r.immersive = immersive;
1567
1568 // update associated state if we're frontmost
Andrii Kulian52d255c2018-07-13 11:32:19 -07001569 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001570 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001571 applyUpdateLockStateLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001572 }
1573 }
1574 }
1575
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001576 void applyUpdateLockStateLocked(ActivityRecord r) {
1577 // Modifications to the UpdateLock state are done on our handler, outside
1578 // the activity manager's locks. The new state is determined based on the
1579 // state *now* of the relevant activity record. The object is passed to
1580 // the handler solely for logging detail, not to be consulted/modified.
1581 final boolean nextState = r != null && r.immersive;
1582 mH.post(() -> {
1583 if (mUpdateLock.isHeld() != nextState) {
1584 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1585 "Applying new update lock state '" + nextState + "' for " + r);
1586 if (nextState) {
1587 mUpdateLock.acquire();
1588 } else {
1589 mUpdateLock.release();
1590 }
1591 }
1592 });
1593 }
1594
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001595 @Override
1596 public boolean isImmersive(IBinder token) {
1597 synchronized (mGlobalLock) {
1598 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1599 if (r == null) {
1600 throw new IllegalArgumentException();
1601 }
1602 return r.immersive;
1603 }
1604 }
1605
1606 @Override
1607 public boolean isTopActivityImmersive() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001608 enforceNotIsolatedCaller("isTopActivityImmersive");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001609 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001610 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001611 return (r != null) ? r.immersive : false;
1612 }
1613 }
1614
1615 @Override
1616 public void overridePendingTransition(IBinder token, String packageName,
1617 int enterAnim, int exitAnim) {
1618 synchronized (mGlobalLock) {
1619 ActivityRecord self = ActivityRecord.isInStackLocked(token);
1620 if (self == null) {
1621 return;
1622 }
1623
1624 final long origId = Binder.clearCallingIdentity();
1625
1626 if (self.isState(
1627 ActivityStack.ActivityState.RESUMED, ActivityStack.ActivityState.PAUSING)) {
lumark588a3e82018-07-20 18:53:54 +08001628 self.getDisplay().getWindowContainerController().overridePendingAppTransition(
1629 packageName, enterAnim, exitAnim, null);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001630 }
1631
1632 Binder.restoreCallingIdentity(origId);
1633 }
1634 }
1635
1636 @Override
1637 public int getFrontActivityScreenCompatMode() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001638 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001639 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001640 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001641 if (r == null) {
1642 return ActivityManager.COMPAT_MODE_UNKNOWN;
1643 }
Wale Ogunwale53783742018-09-16 10:21:51 -07001644 return mCompatModePackages.computeCompatModeLocked(r.info.applicationInfo);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001645 }
1646 }
1647
1648 @Override
1649 public void setFrontActivityScreenCompatMode(int mode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001650 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001651 "setFrontActivityScreenCompatMode");
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001652 ApplicationInfo ai;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001653 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001654 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001655 if (r == null) {
1656 Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity");
1657 return;
1658 }
1659 ai = r.info.applicationInfo;
Wale Ogunwale53783742018-09-16 10:21:51 -07001660 mCompatModePackages.setPackageScreenCompatModeLocked(ai, mode);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001661 }
1662 }
1663
1664 @Override
1665 public int getLaunchedFromUid(IBinder activityToken) {
1666 ActivityRecord srec;
1667 synchronized (mGlobalLock) {
1668 srec = ActivityRecord.forTokenLocked(activityToken);
1669 }
1670 if (srec == null) {
1671 return -1;
1672 }
1673 return srec.launchedFromUid;
1674 }
1675
1676 @Override
1677 public String getLaunchedFromPackage(IBinder activityToken) {
1678 ActivityRecord srec;
1679 synchronized (mGlobalLock) {
1680 srec = ActivityRecord.forTokenLocked(activityToken);
1681 }
1682 if (srec == null) {
1683 return null;
1684 }
1685 return srec.launchedFromPackage;
1686 }
1687
1688 @Override
1689 public boolean convertFromTranslucent(IBinder token) {
1690 final long origId = Binder.clearCallingIdentity();
1691 try {
1692 synchronized (mGlobalLock) {
1693 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1694 if (r == null) {
1695 return false;
1696 }
1697 final boolean translucentChanged = r.changeWindowTranslucency(true);
1698 if (translucentChanged) {
1699 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
1700 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001701 mWindowManager.setAppFullscreen(token, true);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001702 return translucentChanged;
1703 }
1704 } finally {
1705 Binder.restoreCallingIdentity(origId);
1706 }
1707 }
1708
1709 @Override
1710 public boolean convertToTranslucent(IBinder token, Bundle options) {
1711 SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
1712 final long origId = Binder.clearCallingIdentity();
1713 try {
1714 synchronized (mGlobalLock) {
1715 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1716 if (r == null) {
1717 return false;
1718 }
1719 final TaskRecord task = r.getTask();
1720 int index = task.mActivities.lastIndexOf(r);
1721 if (index > 0) {
1722 ActivityRecord under = task.mActivities.get(index - 1);
1723 under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
1724 }
1725 final boolean translucentChanged = r.changeWindowTranslucency(false);
1726 if (translucentChanged) {
1727 r.getStack().convertActivityToTranslucent(r);
1728 }
1729 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001730 mWindowManager.setAppFullscreen(token, false);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001731 return translucentChanged;
1732 }
1733 } finally {
1734 Binder.restoreCallingIdentity(origId);
1735 }
1736 }
1737
1738 @Override
1739 public void notifyActivityDrawn(IBinder token) {
1740 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
1741 synchronized (mGlobalLock) {
1742 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
1743 if (r != null) {
1744 r.getStack().notifyActivityDrawnLocked(r);
1745 }
1746 }
1747 }
1748
1749 @Override
1750 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
1751 synchronized (mGlobalLock) {
1752 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1753 if (r == null) {
1754 return;
1755 }
1756 r.reportFullyDrawnLocked(restoredFromBundle);
1757 }
1758 }
1759
1760 @Override
1761 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
1762 synchronized (mGlobalLock) {
1763 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
1764 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
1765 return stack.mDisplayId;
1766 }
1767 return DEFAULT_DISPLAY;
1768 }
1769 }
1770
1771 @Override
1772 public ActivityManager.StackInfo getFocusedStackInfo() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001773 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001774 long ident = Binder.clearCallingIdentity();
1775 try {
1776 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001777 ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001778 if (focusedStack != null) {
1779 return mStackSupervisor.getStackInfo(focusedStack.mStackId);
1780 }
1781 return null;
1782 }
1783 } finally {
1784 Binder.restoreCallingIdentity(ident);
1785 }
1786 }
1787
1788 @Override
1789 public void setFocusedStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001790 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001791 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
1792 final long callingId = Binder.clearCallingIdentity();
1793 try {
1794 synchronized (mGlobalLock) {
1795 final ActivityStack stack = mStackSupervisor.getStack(stackId);
1796 if (stack == null) {
1797 Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
1798 return;
1799 }
1800 final ActivityRecord r = stack.topRunningActivityLocked();
Louis Chang19443452018-10-09 12:10:21 +08001801 if (r != null && r.moveFocusableActivityToTop("setFocusedStack")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08001802 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001803 }
1804 }
1805 } finally {
1806 Binder.restoreCallingIdentity(callingId);
1807 }
1808 }
1809
1810 @Override
1811 public void setFocusedTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001812 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001813 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
1814 final long callingId = Binder.clearCallingIdentity();
1815 try {
1816 synchronized (mGlobalLock) {
Riddle Hsu090ac6f2018-10-31 12:55:29 +08001817 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
1818 MATCH_TASK_IN_STACKS_ONLY);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001819 if (task == null) {
1820 return;
1821 }
1822 final ActivityRecord r = task.topRunningActivityLocked();
Louis Chang19443452018-10-09 12:10:21 +08001823 if (r != null && r.moveFocusableActivityToTop("setFocusedTask")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08001824 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001825 }
1826 }
1827 } finally {
1828 Binder.restoreCallingIdentity(callingId);
1829 }
1830 }
1831
1832 @Override
1833 public boolean removeTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001834 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001835 synchronized (mGlobalLock) {
1836 final long ident = Binder.clearCallingIdentity();
1837 try {
1838 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
1839 "remove-task");
1840 } finally {
1841 Binder.restoreCallingIdentity(ident);
1842 }
1843 }
1844 }
1845
1846 @Override
Winson Chunge6439102018-07-30 15:48:01 -07001847 public void removeAllVisibleRecentTasks() {
1848 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeAllVisibleRecentTasks()");
1849 synchronized (mGlobalLock) {
1850 final long ident = Binder.clearCallingIdentity();
1851 try {
1852 getRecentTasks().removeAllVisibleTasks();
1853 } finally {
1854 Binder.restoreCallingIdentity(ident);
1855 }
1856 }
1857 }
1858
1859 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001860 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
1861 synchronized (mGlobalLock) {
1862 final ActivityRecord srec = ActivityRecord.forTokenLocked(token);
1863 if (srec != null) {
1864 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
1865 }
1866 }
1867 return false;
1868 }
1869
1870 @Override
1871 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
1872 Intent resultData) {
1873
1874 synchronized (mGlobalLock) {
1875 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
1876 if (r != null) {
1877 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
1878 }
1879 return false;
1880 }
1881 }
1882
1883 /**
1884 * Attempts to move a task backwards in z-order (the order of activities within the task is
1885 * unchanged).
1886 *
1887 * There are several possible results of this call:
1888 * - if the task is locked, then we will show the lock toast
1889 * - if there is a task behind the provided task, then that task is made visible and resumed as
1890 * this task is moved to the back
1891 * - otherwise, if there are no other tasks in the stack:
1892 * - if this task is in the pinned stack, then we remove the stack completely, which will
1893 * have the effect of moving the task to the top or bottom of the fullscreen stack
1894 * (depending on whether it is visible)
1895 * - otherwise, we simply return home and hide this task
1896 *
1897 * @param token A reference to the activity we wish to move
1898 * @param nonRoot If false then this only works if the activity is the root
1899 * of a task; if true it will work for any activity in a task.
1900 * @return Returns true if the move completed, false if not.
1901 */
1902 @Override
1903 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001904 enforceNotIsolatedCaller("moveActivityTaskToBack");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001905 synchronized (mGlobalLock) {
1906 final long origId = Binder.clearCallingIdentity();
1907 try {
1908 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
1909 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1910 if (task != null) {
1911 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
1912 }
1913 } finally {
1914 Binder.restoreCallingIdentity(origId);
1915 }
1916 }
1917 return false;
1918 }
1919
1920 @Override
1921 public Rect getTaskBounds(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001922 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001923 long ident = Binder.clearCallingIdentity();
1924 Rect rect = new Rect();
1925 try {
1926 synchronized (mGlobalLock) {
1927 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
1928 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1929 if (task == null) {
1930 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
1931 return rect;
1932 }
1933 if (task.getStack() != null) {
1934 // Return the bounds from window manager since it will be adjusted for various
1935 // things like the presense of a docked stack for tasks that aren't resizeable.
1936 task.getWindowContainerBounds(rect);
1937 } else {
1938 // Task isn't in window manager yet since it isn't associated with a stack.
1939 // Return the persist value from activity manager
1940 if (!task.matchParentBounds()) {
1941 rect.set(task.getBounds());
1942 } else if (task.mLastNonFullscreenBounds != null) {
1943 rect.set(task.mLastNonFullscreenBounds);
1944 }
1945 }
1946 }
1947 } finally {
1948 Binder.restoreCallingIdentity(ident);
1949 }
1950 return rect;
1951 }
1952
1953 @Override
1954 public ActivityManager.TaskDescription getTaskDescription(int id) {
1955 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001956 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001957 MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
1958 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
1959 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1960 if (tr != null) {
1961 return tr.lastTaskDescription;
1962 }
1963 }
1964 return null;
1965 }
1966
1967 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001968 public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
1969 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
1970 setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
1971 toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
1972 return;
1973 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001974 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001975 synchronized (mGlobalLock) {
1976 final long ident = Binder.clearCallingIdentity();
1977 try {
Riddle Hsu090ac6f2018-10-31 12:55:29 +08001978 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
1979 MATCH_TASK_IN_STACKS_ONLY);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001980 if (task == null) {
1981 Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
1982 return;
1983 }
1984
1985 if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
1986 + " to windowingMode=" + windowingMode + " toTop=" + toTop);
1987
1988 if (!task.isActivityTypeStandardOrUndefined()) {
1989 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
1990 + " non-standard task " + taskId + " to windowing mode="
1991 + windowingMode);
1992 }
1993
1994 final ActivityStack stack = task.getStack();
1995 if (toTop) {
1996 stack.moveToFront("setTaskWindowingMode", task);
1997 }
1998 stack.setWindowingMode(windowingMode);
1999 } finally {
2000 Binder.restoreCallingIdentity(ident);
2001 }
2002 }
2003 }
2004
2005 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002006 public String getCallingPackage(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002007 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002008 ActivityRecord r = getCallingRecordLocked(token);
2009 return r != null ? r.info.packageName : null;
2010 }
2011 }
2012
2013 @Override
2014 public ComponentName getCallingActivity(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002015 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002016 ActivityRecord r = getCallingRecordLocked(token);
2017 return r != null ? r.intent.getComponent() : null;
2018 }
2019 }
2020
2021 private ActivityRecord getCallingRecordLocked(IBinder token) {
2022 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2023 if (r == null) {
2024 return null;
2025 }
2026 return r.resultTo;
2027 }
2028
2029 @Override
2030 public void unhandledBack() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002031 mAmInternal.enforceCallingPermission(android.Manifest.permission.FORCE_BACK, "unhandledBack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002032
2033 synchronized (mGlobalLock) {
2034 final long origId = Binder.clearCallingIdentity();
2035 try {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002036 getTopDisplayFocusedStack().unhandledBackLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002037 } finally {
2038 Binder.restoreCallingIdentity(origId);
2039 }
2040 }
2041 }
2042
2043 /**
2044 * TODO: Add mController hook
2045 */
2046 @Override
2047 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002048 mAmInternal.enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002049
2050 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
2051 synchronized (mGlobalLock) {
2052 moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
2053 false /* fromRecents */);
2054 }
2055 }
2056
2057 void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
2058 boolean fromRecents) {
2059
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002060 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002061 Binder.getCallingUid(), -1, -1, "Task to front")) {
2062 SafeActivityOptions.abort(options);
2063 return;
2064 }
2065 final long origId = Binder.clearCallingIdentity();
2066 try {
2067 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2068 if (task == null) {
2069 Slog.d(TAG, "Could not find task for id: "+ taskId);
Winson Chungd0243682018-09-25 18:11:54 -07002070 SafeActivityOptions.abort(options);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002071 return;
2072 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002073 if (getLockTaskController().isLockTaskModeViolation(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002074 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
Winson Chungd0243682018-09-25 18:11:54 -07002075 SafeActivityOptions.abort(options);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002076 return;
2077 }
2078 ActivityOptions realOptions = options != null
2079 ? options.getOptions(mStackSupervisor)
2080 : null;
2081 mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
2082 false /* forceNonResizable */);
2083
2084 final ActivityRecord topActivity = task.getTopActivity();
2085 if (topActivity != null) {
2086
2087 // We are reshowing a task, use a starting window to hide the initial draw delay
2088 // so the transition can start earlier.
2089 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
2090 true /* taskSwitch */, fromRecents);
2091 }
2092 } finally {
2093 Binder.restoreCallingIdentity(origId);
2094 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002095 }
2096
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002097 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
2098 int callingPid, int callingUid, String name) {
2099 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
2100 return true;
2101 }
2102
2103 if (getRecentTasks().isCallerRecents(sourceUid)) {
2104 return true;
2105 }
2106
2107 int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
2108 if (perm == PackageManager.PERMISSION_GRANTED) {
2109 return true;
2110 }
2111 if (checkAllowAppSwitchUid(sourceUid)) {
2112 return true;
2113 }
2114
2115 // If the actual IPC caller is different from the logical source, then
2116 // also see if they are allowed to control app switches.
2117 if (callingUid != -1 && callingUid != sourceUid) {
2118 perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
2119 if (perm == PackageManager.PERMISSION_GRANTED) {
2120 return true;
2121 }
2122 if (checkAllowAppSwitchUid(callingUid)) {
2123 return true;
2124 }
2125 }
2126
2127 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
2128 return false;
2129 }
2130
2131 private boolean checkAllowAppSwitchUid(int uid) {
2132 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
2133 if (types != null) {
2134 for (int i = types.size() - 1; i >= 0; i--) {
2135 if (types.valueAt(i).intValue() == uid) {
2136 return true;
2137 }
2138 }
2139 }
2140 return false;
2141 }
2142
2143 @Override
2144 public void setActivityController(IActivityController controller, boolean imAMonkey) {
2145 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
2146 "setActivityController()");
2147 synchronized (mGlobalLock) {
2148 mController = controller;
2149 mControllerIsAMonkey = imAMonkey;
2150 Watchdog.getInstance().setActivityController(controller);
2151 }
2152 }
2153
Wale Ogunwale387b34c2018-10-25 19:59:40 -07002154 public boolean isControllerAMonkey() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002155 synchronized (mGlobalLock) {
2156 return mController != null && mControllerIsAMonkey;
2157 }
2158 }
2159
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002160 @Override
2161 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
2162 synchronized (mGlobalLock) {
2163 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
2164 }
2165 }
2166
2167 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002168 public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum) {
2169 return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
2170 }
2171
2172 @Override
2173 public List<ActivityManager.RunningTaskInfo> getFilteredTasks(int maxNum,
2174 @WindowConfiguration.ActivityType int ignoreActivityType,
2175 @WindowConfiguration.WindowingMode int ignoreWindowingMode) {
2176 final int callingUid = Binder.getCallingUid();
2177 ArrayList<ActivityManager.RunningTaskInfo> list = new ArrayList<>();
2178
2179 synchronized (mGlobalLock) {
2180 if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
2181
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002182 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002183 callingUid);
2184 mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
2185 ignoreWindowingMode, callingUid, allowed);
2186 }
2187
2188 return list;
2189 }
2190
2191 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002192 public final void finishSubActivity(IBinder token, String resultWho, int requestCode) {
2193 synchronized (mGlobalLock) {
2194 final long origId = Binder.clearCallingIdentity();
2195 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2196 if (r != null) {
2197 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
2198 }
2199 Binder.restoreCallingIdentity(origId);
2200 }
2201 }
2202
2203 @Override
2204 public boolean willActivityBeVisible(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002205 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002206 ActivityStack stack = ActivityRecord.getStackLocked(token);
2207 if (stack != null) {
2208 return stack.willActivityBeVisibleLocked(token);
2209 }
2210 return false;
2211 }
2212 }
2213
2214 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002215 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002216 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002217 synchronized (mGlobalLock) {
2218 final long ident = Binder.clearCallingIdentity();
2219 try {
2220 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2221 if (task == null) {
2222 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
2223 return;
2224 }
2225
2226 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
2227 + " to stackId=" + stackId + " toTop=" + toTop);
2228
2229 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2230 if (stack == null) {
2231 throw new IllegalStateException(
2232 "moveTaskToStack: No stack for stackId=" + stackId);
2233 }
2234 if (!stack.isActivityTypeStandardOrUndefined()) {
2235 throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
2236 + taskId + " to stack " + stackId);
2237 }
2238 if (stack.inSplitScreenPrimaryWindowingMode()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002239 mWindowManager.setDockedStackCreateState(
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002240 SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
2241 }
2242 task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
2243 "moveTaskToStack");
2244 } finally {
2245 Binder.restoreCallingIdentity(ident);
2246 }
2247 }
2248 }
2249
2250 @Override
2251 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
2252 boolean preserveWindows, boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002253 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002254
2255 final long ident = Binder.clearCallingIdentity();
2256 try {
2257 synchronized (mGlobalLock) {
2258 if (animate) {
2259 final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
2260 if (stack == null) {
2261 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2262 return;
2263 }
2264 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
2265 throw new IllegalArgumentException("Stack: " + stackId
2266 + " doesn't support animated resize.");
2267 }
2268 stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
2269 animationDuration, false /* fromFullscreen */);
2270 } else {
2271 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2272 if (stack == null) {
2273 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2274 return;
2275 }
2276 mStackSupervisor.resizeStackLocked(stack, destBounds,
2277 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
2278 preserveWindows, allowResizeInDockedMode, !DEFER_RESUME);
2279 }
2280 }
2281 } finally {
2282 Binder.restoreCallingIdentity(ident);
2283 }
2284 }
2285
2286 /**
2287 * Moves the specified task to the primary-split-screen stack.
2288 *
2289 * @param taskId Id of task to move.
2290 * @param createMode The mode the primary split screen stack should be created in if it doesn't
2291 * exist already. See
2292 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
2293 * and
2294 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
2295 * @param toTop If the task and stack should be moved to the top.
2296 * @param animate Whether we should play an animation for the moving the task.
2297 * @param initialBounds If the primary stack gets created, it will use these bounds for the
2298 * stack. Pass {@code null} to use default bounds.
2299 * @param showRecents If the recents activity should be shown on the other side of the task
2300 * going into split-screen mode.
2301 */
2302 @Override
2303 public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode,
2304 boolean toTop, boolean animate, Rect initialBounds, boolean showRecents) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002305 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002306 "setTaskWindowingModeSplitScreenPrimary()");
2307 synchronized (mGlobalLock) {
2308 final long ident = Binder.clearCallingIdentity();
2309 try {
Riddle Hsu090ac6f2018-10-31 12:55:29 +08002310 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
2311 MATCH_TASK_IN_STACKS_ONLY);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002312 if (task == null) {
2313 Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
2314 return false;
2315 }
2316 if (DEBUG_STACK) Slog.d(TAG_STACK,
2317 "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
2318 + " to createMode=" + createMode + " toTop=" + toTop);
2319 if (!task.isActivityTypeStandardOrUndefined()) {
2320 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
2321 + " non-standard task " + taskId + " to split-screen windowing mode");
2322 }
2323
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002324 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002325 final int windowingMode = task.getWindowingMode();
2326 final ActivityStack stack = task.getStack();
2327 if (toTop) {
2328 stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
2329 }
2330 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
2331 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */);
2332 return windowingMode != task.getWindowingMode();
2333 } finally {
2334 Binder.restoreCallingIdentity(ident);
2335 }
2336 }
2337 }
2338
2339 /**
2340 * Removes stacks in the input windowing modes from the system if they are of activity type
2341 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
2342 */
2343 @Override
2344 public void removeStacksInWindowingModes(int[] windowingModes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002345 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002346 "removeStacksInWindowingModes()");
2347
2348 synchronized (mGlobalLock) {
2349 final long ident = Binder.clearCallingIdentity();
2350 try {
2351 mStackSupervisor.removeStacksInWindowingModes(windowingModes);
2352 } finally {
2353 Binder.restoreCallingIdentity(ident);
2354 }
2355 }
2356 }
2357
2358 @Override
2359 public void removeStacksWithActivityTypes(int[] activityTypes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002360 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002361 "removeStacksWithActivityTypes()");
2362
2363 synchronized (mGlobalLock) {
2364 final long ident = Binder.clearCallingIdentity();
2365 try {
2366 mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
2367 } finally {
2368 Binder.restoreCallingIdentity(ident);
2369 }
2370 }
2371 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002372
2373 @Override
2374 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
2375 int userId) {
2376 final int callingUid = Binder.getCallingUid();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002377 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, "getRecentTasks");
2378 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002379 callingUid);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002380 final boolean detailed = checkGetTasksPermission(
2381 android.Manifest.permission.GET_DETAILED_TASKS, Binder.getCallingPid(),
2382 UserHandle.getAppId(callingUid))
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002383 == PackageManager.PERMISSION_GRANTED;
2384
2385 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002386 return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002387 callingUid);
2388 }
2389 }
2390
2391 @Override
2392 public List<ActivityManager.StackInfo> getAllStackInfos() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002393 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002394 long ident = Binder.clearCallingIdentity();
2395 try {
2396 synchronized (mGlobalLock) {
2397 return mStackSupervisor.getAllStackInfosLocked();
2398 }
2399 } finally {
2400 Binder.restoreCallingIdentity(ident);
2401 }
2402 }
2403
2404 @Override
2405 public ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002406 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002407 long ident = Binder.clearCallingIdentity();
2408 try {
2409 synchronized (mGlobalLock) {
2410 return mStackSupervisor.getStackInfo(windowingMode, activityType);
2411 }
2412 } finally {
2413 Binder.restoreCallingIdentity(ident);
2414 }
2415 }
2416
2417 @Override
2418 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002419 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002420 final long callingUid = Binder.getCallingUid();
2421 final long origId = Binder.clearCallingIdentity();
2422 try {
2423 synchronized (mGlobalLock) {
2424 // Cancel the recents animation synchronously (do not hold the WM lock)
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002425 mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002426 ? REORDER_MOVE_TO_ORIGINAL_POSITION
2427 : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
2428 }
2429 } finally {
2430 Binder.restoreCallingIdentity(origId);
2431 }
2432 }
2433
2434 @Override
2435 public void startLockTaskModeByToken(IBinder token) {
2436 synchronized (mGlobalLock) {
2437 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2438 if (r == null) {
2439 return;
2440 }
2441 startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
2442 }
2443 }
2444
2445 @Override
Riddle Hsu090ac6f2018-10-31 12:55:29 +08002446 public void startSystemLockTaskMode(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002447 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002448 // This makes inner call to look as if it was initiated by system.
2449 long ident = Binder.clearCallingIdentity();
2450 try {
2451 synchronized (mGlobalLock) {
Riddle Hsu090ac6f2018-10-31 12:55:29 +08002452 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
2453 MATCH_TASK_IN_STACKS_ONLY);
2454 if (task == null) {
2455 return;
2456 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002457
2458 // When starting lock task mode the stack must be in front and focused
2459 task.getStack().moveToFront("startSystemLockTaskMode");
2460 startLockTaskModeLocked(task, true /* isSystemCaller */);
2461 }
2462 } finally {
2463 Binder.restoreCallingIdentity(ident);
2464 }
2465 }
2466
2467 @Override
2468 public void stopLockTaskModeByToken(IBinder token) {
2469 synchronized (mGlobalLock) {
2470 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2471 if (r == null) {
2472 return;
2473 }
2474 stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
2475 }
2476 }
2477
2478 /**
2479 * This API should be called by SystemUI only when user perform certain action to dismiss
2480 * lock task mode. We should only dismiss pinned lock task mode in this case.
2481 */
2482 @Override
2483 public void stopSystemLockTaskMode() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002484 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002485 stopLockTaskModeInternal(null, true /* isSystemCaller */);
2486 }
2487
2488 private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
2489 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
2490 if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
2491 return;
2492 }
2493
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002494 final ActivityStack stack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002495 if (stack == null || task != stack.topTask()) {
2496 throw new IllegalArgumentException("Invalid task, not in foreground");
2497 }
2498
2499 // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
2500 // system or a specific app.
2501 // * System-initiated requests will only start the pinned mode (screen pinning)
2502 // * App-initiated requests
2503 // - will put the device in fully locked mode (LockTask), if the app is whitelisted
2504 // - will start the pinned mode, otherwise
2505 final int callingUid = Binder.getCallingUid();
2506 long ident = Binder.clearCallingIdentity();
2507 try {
2508 // When a task is locked, dismiss the pinned stack if it exists
2509 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2510
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002511 getLockTaskController().startLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002512 } finally {
2513 Binder.restoreCallingIdentity(ident);
2514 }
2515 }
2516
2517 private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
2518 final int callingUid = Binder.getCallingUid();
2519 long ident = Binder.clearCallingIdentity();
2520 try {
2521 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002522 getLockTaskController().stopLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002523 }
2524 // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
2525 // task and jumping straight into a call in the case of emergency call back.
2526 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
2527 if (tm != null) {
2528 tm.showInCallScreen(false);
2529 }
2530 } finally {
2531 Binder.restoreCallingIdentity(ident);
2532 }
2533 }
2534
2535 @Override
Wale Ogunwale27c48ae2018-10-25 19:01:01 -07002536 public void updateLockTaskPackages(int userId, String[] packages) {
2537 final int callingUid = Binder.getCallingUid();
2538 if (callingUid != 0 && callingUid != SYSTEM_UID) {
2539 mAmInternal.enforceCallingPermission(Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
2540 "updateLockTaskPackages()");
2541 }
2542 synchronized (this) {
2543 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":"
2544 + Arrays.toString(packages));
2545 getLockTaskController().updateLockTaskPackages(userId, packages);
2546 }
2547 }
2548
2549 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002550 public boolean isInLockTaskMode() {
2551 return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
2552 }
2553
2554 @Override
2555 public int getLockTaskModeState() {
2556 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002557 return getLockTaskController().getLockTaskModeState();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002558 }
2559 }
2560
2561 @Override
2562 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
2563 synchronized (mGlobalLock) {
2564 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2565 if (r != null) {
2566 r.setTaskDescription(td);
2567 final TaskRecord task = r.getTask();
2568 task.updateTaskDescription();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002569 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002570 }
2571 }
2572 }
2573
2574 @Override
2575 public Bundle getActivityOptions(IBinder token) {
2576 final long origId = Binder.clearCallingIdentity();
2577 try {
2578 synchronized (mGlobalLock) {
2579 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
2580 if (r != null) {
2581 final ActivityOptions activityOptions = r.takeOptionsLocked();
2582 return activityOptions == null ? null : activityOptions.toBundle();
2583 }
2584 return null;
2585 }
2586 } finally {
2587 Binder.restoreCallingIdentity(origId);
2588 }
2589 }
2590
2591 @Override
2592 public List<IBinder> getAppTasks(String callingPackage) {
2593 int callingUid = Binder.getCallingUid();
2594 long ident = Binder.clearCallingIdentity();
2595 try {
2596 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002597 return mRecentTasks.getAppTasksList(callingUid, callingPackage);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002598 }
2599 } finally {
2600 Binder.restoreCallingIdentity(ident);
2601 }
2602 }
2603
2604 @Override
2605 public void finishVoiceTask(IVoiceInteractionSession session) {
2606 synchronized (mGlobalLock) {
2607 final long origId = Binder.clearCallingIdentity();
2608 try {
2609 // TODO: VI Consider treating local voice interactions and voice tasks
2610 // differently here
2611 mStackSupervisor.finishVoiceTask(session);
2612 } finally {
2613 Binder.restoreCallingIdentity(origId);
2614 }
2615 }
2616
2617 }
2618
2619 @Override
2620 public boolean isTopOfTask(IBinder token) {
2621 synchronized (mGlobalLock) {
2622 ActivityRecord r = ActivityRecord.isInStackLocked(token);
Riddle Hsu66b74a82018-07-26 00:20:12 +08002623 return r != null && r.getTask().getTopActivity() == r;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002624 }
2625 }
2626
2627 @Override
2628 public void notifyLaunchTaskBehindComplete(IBinder token) {
2629 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
2630 }
2631
2632 @Override
2633 public void notifyEnterAnimationComplete(IBinder token) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002634 mH.post(() -> {
2635 synchronized (mGlobalLock) {
2636 ActivityRecord r = ActivityRecord.forTokenLocked(token);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002637 if (r != null && r.attachedToProcess()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002638 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002639 r.app.getThread().scheduleEnterAnimationComplete(r.appToken);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002640 } catch (RemoteException e) {
2641 }
2642 }
2643 }
2644
2645 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002646 }
2647
2648 /** Called from an app when assist data is ready. */
2649 @Override
2650 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
2651 AssistContent content, Uri referrer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002652 PendingAssistExtras pae = (PendingAssistExtras) token;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002653 synchronized (pae) {
2654 pae.result = extras;
2655 pae.structure = structure;
2656 pae.content = content;
2657 if (referrer != null) {
2658 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
2659 }
2660 if (structure != null) {
Winson Chung48b25652018-10-22 14:04:30 -07002661 // Pre-fill the task/activity component for all assist data receivers
2662 structure.setTaskId(pae.activity.getTask().taskId);
2663 structure.setActivityComponent(pae.activity.realActivity);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002664 structure.setHomeActivity(pae.isHome);
2665 }
2666 pae.haveResult = true;
2667 pae.notifyAll();
2668 if (pae.intent == null && pae.receiver == null) {
2669 // Caller is just waiting for the result.
2670 return;
2671 }
2672 }
2673 // We are now ready to launch the assist activity.
2674 IAssistDataReceiver sendReceiver = null;
2675 Bundle sendBundle = null;
2676 synchronized (mGlobalLock) {
2677 buildAssistBundleLocked(pae, extras);
2678 boolean exists = mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002679 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002680 if (!exists) {
2681 // Timed out.
2682 return;
2683 }
2684
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002685 if ((sendReceiver = pae.receiver) != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002686 // Caller wants result sent back to them.
2687 sendBundle = new Bundle();
2688 sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
2689 sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
2690 sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
2691 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
2692 }
2693 }
2694 if (sendReceiver != null) {
2695 try {
2696 sendReceiver.onHandleAssistData(sendBundle);
2697 } catch (RemoteException e) {
2698 }
2699 return;
2700 }
2701
2702 final long ident = Binder.clearCallingIdentity();
2703 try {
2704 if (TextUtils.equals(pae.intent.getAction(),
2705 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
2706 pae.intent.putExtras(pae.extras);
2707 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
2708 } else {
2709 pae.intent.replaceExtras(pae.extras);
2710 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
2711 | Intent.FLAG_ACTIVITY_SINGLE_TOP
2712 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Wale Ogunwale31913b52018-10-13 08:29:31 -07002713 mInternal.closeSystemDialogs("assist");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002714
2715 try {
2716 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
2717 } catch (ActivityNotFoundException e) {
2718 Slog.w(TAG, "No activity to handle assist action.", e);
2719 }
2720 }
2721 } finally {
2722 Binder.restoreCallingIdentity(ident);
2723 }
2724 }
2725
2726 @Override
2727 public int addAppTask(IBinder activityToken, Intent intent,
2728 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
2729 final int callingUid = Binder.getCallingUid();
2730 final long callingIdent = Binder.clearCallingIdentity();
2731
2732 try {
2733 synchronized (mGlobalLock) {
2734 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
2735 if (r == null) {
2736 throw new IllegalArgumentException("Activity does not exist; token="
2737 + activityToken);
2738 }
2739 ComponentName comp = intent.getComponent();
2740 if (comp == null) {
2741 throw new IllegalArgumentException("Intent " + intent
2742 + " must specify explicit component");
2743 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002744 if (thumbnail.getWidth() != mThumbnailWidth
2745 || thumbnail.getHeight() != mThumbnailHeight) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002746 throw new IllegalArgumentException("Bad thumbnail size: got "
2747 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002748 + mThumbnailWidth + "x" + mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002749 }
2750 if (intent.getSelector() != null) {
2751 intent.setSelector(null);
2752 }
2753 if (intent.getSourceBounds() != null) {
2754 intent.setSourceBounds(null);
2755 }
2756 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
2757 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
2758 // The caller has added this as an auto-remove task... that makes no
2759 // sense, so turn off auto-remove.
2760 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
2761 }
2762 }
2763 final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
2764 STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
2765 if (ainfo.applicationInfo.uid != callingUid) {
2766 throw new SecurityException(
2767 "Can't add task for another application: target uid="
2768 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
2769 }
2770
2771 final ActivityStack stack = r.getStack();
2772 final TaskRecord task = stack.createTaskRecord(
2773 mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent,
2774 null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002775 if (!mRecentTasks.addToBottom(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002776 // The app has too many tasks already and we can't add any more
2777 stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
2778 return INVALID_TASK_ID;
2779 }
2780 task.lastTaskDescription.copyFrom(description);
2781
2782 // TODO: Send the thumbnail to WM to store it.
2783
2784 return task.taskId;
2785 }
2786 } finally {
2787 Binder.restoreCallingIdentity(callingIdent);
2788 }
2789 }
2790
2791 @Override
2792 public Point getAppTaskThumbnailSize() {
2793 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002794 return new Point(mThumbnailWidth, mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002795 }
2796 }
2797
2798 @Override
2799 public void setTaskResizeable(int taskId, int resizeableMode) {
2800 synchronized (mGlobalLock) {
2801 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
2802 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
2803 if (task == null) {
2804 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
2805 return;
2806 }
2807 task.setResizeMode(resizeableMode);
2808 }
2809 }
2810
2811 @Override
2812 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002813 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002814 long ident = Binder.clearCallingIdentity();
2815 try {
2816 synchronized (mGlobalLock) {
Riddle Hsu090ac6f2018-10-31 12:55:29 +08002817 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
2818 MATCH_TASK_IN_STACKS_ONLY);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002819 if (task == null) {
2820 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
2821 return;
2822 }
2823 // Place the task in the right stack if it isn't there already based on
2824 // the requested bounds.
2825 // The stack transition logic is:
2826 // - a null bounds on a freeform task moves that task to fullscreen
2827 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
2828 // that task to freeform
2829 // - otherwise the task is not moved
2830 ActivityStack stack = task.getStack();
2831 if (!task.getWindowConfiguration().canResizeTask()) {
2832 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
2833 }
2834 if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
2835 stack = stack.getDisplay().getOrCreateStack(
2836 WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
2837 } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
2838 stack = stack.getDisplay().getOrCreateStack(
2839 WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
2840 }
2841
2842 // Reparent the task to the right stack if necessary
2843 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
2844 if (stack != task.getStack()) {
2845 // Defer resume until the task is resized below
2846 task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
2847 DEFER_RESUME, "resizeTask");
2848 preserveWindow = false;
2849 }
2850
2851 // After reparenting (which only resizes the task to the stack bounds), resize the
2852 // task to the actual bounds provided
2853 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
2854 }
2855 } finally {
2856 Binder.restoreCallingIdentity(ident);
2857 }
2858 }
2859
2860 @Override
2861 public boolean releaseActivityInstance(IBinder token) {
2862 synchronized (mGlobalLock) {
2863 final long origId = Binder.clearCallingIdentity();
2864 try {
2865 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2866 if (r == null) {
2867 return false;
2868 }
2869 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
2870 } finally {
2871 Binder.restoreCallingIdentity(origId);
2872 }
2873 }
2874 }
2875
2876 @Override
2877 public void releaseSomeActivities(IApplicationThread appInt) {
2878 synchronized (mGlobalLock) {
2879 final long origId = Binder.clearCallingIdentity();
2880 try {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07002881 final WindowProcessController app = getProcessController(appInt);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002882 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
2883 } finally {
2884 Binder.restoreCallingIdentity(origId);
2885 }
2886 }
2887 }
2888
2889 @Override
2890 public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
wilsonshihe7903ea2018-09-26 16:17:59 +08002891 int[] secondaryDisplaysShowing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002892 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002893 != PackageManager.PERMISSION_GRANTED) {
2894 throw new SecurityException("Requires permission "
2895 + android.Manifest.permission.DEVICE_POWER);
2896 }
2897
2898 synchronized (mGlobalLock) {
2899 long ident = Binder.clearCallingIdentity();
2900 if (mKeyguardShown != keyguardShowing) {
2901 mKeyguardShown = keyguardShowing;
Wale Ogunwale342fbe92018-10-09 08:44:10 -07002902 final Message msg = PooledLambda.obtainMessage(
2903 ActivityManagerInternal::reportCurKeyguardUsageEvent, mAmInternal,
2904 keyguardShowing);
2905 mH.sendMessage(msg);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002906 }
2907 try {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002908 mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
wilsonshihe7903ea2018-09-26 16:17:59 +08002909 secondaryDisplaysShowing);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002910 } finally {
2911 Binder.restoreCallingIdentity(ident);
2912 }
2913 }
2914
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002915 mH.post(() -> {
2916 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2917 mScreenObservers.get(i).onKeyguardStateChanged(keyguardShowing);
2918 }
2919 });
2920 }
2921
Wale Ogunwale387b34c2018-10-25 19:59:40 -07002922 public void onScreenAwakeChanged(boolean isAwake) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002923 mH.post(() -> {
2924 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2925 mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2926 }
2927 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002928 }
2929
2930 @Override
2931 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002932 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
2933 userId, "getTaskDescriptionIcon");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002934
2935 final File passedIconFile = new File(filePath);
2936 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
2937 passedIconFile.getName());
2938 if (!legitIconFile.getPath().equals(filePath)
2939 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
2940 throw new IllegalArgumentException("Bad file path: " + filePath
2941 + " passed for userId " + userId);
2942 }
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002943 return mRecentTasks.getTaskDescriptionIcon(filePath);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002944 }
2945
2946 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002947 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002948 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
2949 final ActivityOptions activityOptions = safeOptions != null
2950 ? safeOptions.getOptions(mStackSupervisor)
2951 : null;
2952 if (activityOptions == null
2953 || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
2954 || activityOptions.getCustomInPlaceResId() == 0) {
2955 throw new IllegalArgumentException("Expected in-place ActivityOption " +
2956 "with valid animation");
2957 }
lumark588a3e82018-07-20 18:53:54 +08002958 // Get top display of front most application.
2959 final ActivityStack focusedStack = getTopDisplayFocusedStack();
2960 if (focusedStack != null) {
2961 final DisplayWindowController dwc =
2962 focusedStack.getDisplay().getWindowContainerController();
2963 dwc.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
2964 dwc.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
2965 activityOptions.getCustomInPlaceResId());
2966 dwc.executeAppTransition();
2967 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002968 }
2969
2970 @Override
2971 public void removeStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002972 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002973 synchronized (mGlobalLock) {
2974 final long ident = Binder.clearCallingIdentity();
2975 try {
2976 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2977 if (stack == null) {
2978 Slog.w(TAG, "removeStack: No stack with id=" + stackId);
2979 return;
2980 }
2981 if (!stack.isActivityTypeStandardOrUndefined()) {
2982 throw new IllegalArgumentException(
2983 "Removing non-standard stack is not allowed.");
2984 }
2985 mStackSupervisor.removeStack(stack);
2986 } finally {
2987 Binder.restoreCallingIdentity(ident);
2988 }
2989 }
2990 }
2991
2992 @Override
2993 public void moveStackToDisplay(int stackId, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002994 mAmInternal.enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002995
2996 synchronized (mGlobalLock) {
2997 final long ident = Binder.clearCallingIdentity();
2998 try {
2999 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
3000 + " to displayId=" + displayId);
3001 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
3002 } finally {
3003 Binder.restoreCallingIdentity(ident);
3004 }
3005 }
3006 }
3007
3008 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003009 public void exitFreeformMode(IBinder token) {
3010 synchronized (mGlobalLock) {
3011 long ident = Binder.clearCallingIdentity();
3012 try {
3013 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3014 if (r == null) {
3015 throw new IllegalArgumentException(
3016 "exitFreeformMode: No activity record matching token=" + token);
3017 }
3018
3019 final ActivityStack stack = r.getStack();
3020 if (stack == null || !stack.inFreeformWindowingMode()) {
3021 throw new IllegalStateException(
3022 "exitFreeformMode: You can only go fullscreen from freeform.");
3023 }
3024
3025 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
3026 } finally {
3027 Binder.restoreCallingIdentity(ident);
3028 }
3029 }
3030 }
3031
3032 /** Sets the task stack listener that gets callbacks when a task stack changes. */
3033 @Override
3034 public void registerTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003035 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003036 "registerTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003037 mTaskChangeNotificationController.registerTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003038 }
3039
3040 /** Unregister a task stack listener so that it stops receiving callbacks. */
3041 @Override
3042 public void unregisterTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003043 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003044 "unregisterTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003045 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003046 }
3047
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003048 @Override
3049 public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
3050 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
3051 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
3052 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
3053 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
3054 }
3055
3056 @Override
3057 public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
3058 IBinder activityToken, int flags) {
3059 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
3060 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
3061 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
3062 }
3063
3064 @Override
3065 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
3066 Bundle args) {
3067 return enqueueAssistContext(requestType, intent, hint, null, null, null,
3068 true /* focused */, true /* newSessionId */, userHandle, args,
3069 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
3070 }
3071
3072 @Override
3073 public Bundle getAssistContextExtras(int requestType) {
3074 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
3075 null, null, true /* focused */, true /* newSessionId */,
3076 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
3077 if (pae == null) {
3078 return null;
3079 }
3080 synchronized (pae) {
3081 while (!pae.haveResult) {
3082 try {
3083 pae.wait();
3084 } catch (InterruptedException e) {
3085 }
3086 }
3087 }
3088 synchronized (mGlobalLock) {
3089 buildAssistBundleLocked(pae, pae.result);
3090 mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003091 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003092 }
3093 return pae.extras;
3094 }
3095
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003096 /**
3097 * Binder IPC calls go through the public entry point.
3098 * This can be called with or without the global lock held.
3099 */
3100 private static int checkCallingPermission(String permission) {
3101 return checkPermission(
3102 permission, Binder.getCallingPid(), UserHandle.getAppId(Binder.getCallingUid()));
3103 }
3104
3105 /** This can be called with or without the global lock held. */
Wale Ogunwale214f3482018-10-04 11:00:47 -07003106 private void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003107 if (!getRecentTasks().isCallerRecents(Binder.getCallingUid())) {
3108 mAmInternal.enforceCallingPermission(permission, func);
3109 }
3110 }
3111
3112 @VisibleForTesting
3113 int checkGetTasksPermission(String permission, int pid, int uid) {
3114 return checkPermission(permission, pid, uid);
3115 }
3116
3117 static int checkPermission(String permission, int pid, int uid) {
3118 if (permission == null) {
3119 return PackageManager.PERMISSION_DENIED;
3120 }
3121 return checkComponentPermission(permission, pid, uid, -1, true);
3122 }
3123
Wale Ogunwale214f3482018-10-04 11:00:47 -07003124 public static int checkComponentPermission(String permission, int pid, int uid,
3125 int owningUid, boolean exported) {
3126 return ActivityManagerService.checkComponentPermission(
3127 permission, pid, uid, owningUid, exported);
3128 }
3129
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003130 boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
3131 if (getRecentTasks().isCallerRecents(callingUid)) {
3132 // Always allow the recents component to get tasks
3133 return true;
3134 }
3135
3136 boolean allowed = checkGetTasksPermission(android.Manifest.permission.REAL_GET_TASKS,
3137 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
3138 if (!allowed) {
3139 if (checkGetTasksPermission(android.Manifest.permission.GET_TASKS,
3140 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
3141 // Temporary compatibility: some existing apps on the system image may
3142 // still be requesting the old permission and not switched to the new
3143 // one; if so, we'll still allow them full access. This means we need
3144 // to see if they are holding the old permission and are a system app.
3145 try {
3146 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
3147 allowed = true;
3148 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
3149 + " is using old GET_TASKS but privileged; allowing");
3150 }
3151 } catch (RemoteException e) {
3152 }
3153 }
3154 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
3155 + " does not hold REAL_GET_TASKS; limiting output");
3156 }
3157 return allowed;
3158 }
3159
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003160 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
3161 IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
3162 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
3163 int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003164 mAmInternal.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003165 "enqueueAssistContext()");
3166
3167 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003168 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003169 if (activity == null) {
3170 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
3171 return null;
3172 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003173 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003174 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
3175 return null;
3176 }
3177 if (focused) {
3178 if (activityToken != null) {
3179 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
3180 if (activity != caller) {
3181 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
3182 + " is not current top " + activity);
3183 return null;
3184 }
3185 }
3186 } else {
3187 activity = ActivityRecord.forTokenLocked(activityToken);
3188 if (activity == null) {
3189 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
3190 + " couldn't be found");
3191 return null;
3192 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003193 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003194 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
3195 return null;
3196 }
3197 }
3198
3199 PendingAssistExtras pae;
3200 Bundle extras = new Bundle();
3201 if (args != null) {
3202 extras.putAll(args);
3203 }
3204 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003205 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003206
3207 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
3208 userHandle);
3209 pae.isHome = activity.isActivityTypeHome();
3210
3211 // Increment the sessionId if necessary
3212 if (newSessionId) {
3213 mViSessionId++;
3214 }
3215 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003216 activity.app.getThread().requestAssistContextExtras(activity.appToken, pae,
3217 requestType, mViSessionId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003218 mPendingAssistExtras.add(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003219 mUiHandler.postDelayed(pae, timeout);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003220 } catch (RemoteException e) {
3221 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
3222 return null;
3223 }
3224 return pae;
3225 }
3226 }
3227
3228 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
3229 if (result != null) {
3230 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
3231 }
3232 if (pae.hint != null) {
3233 pae.extras.putBoolean(pae.hint, true);
3234 }
3235 }
3236
3237 private void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
3238 IAssistDataReceiver receiver;
3239 synchronized (mGlobalLock) {
3240 mPendingAssistExtras.remove(pae);
3241 receiver = pae.receiver;
3242 }
3243 if (receiver != null) {
3244 // Caller wants result sent back to them.
3245 Bundle sendBundle = new Bundle();
3246 // At least return the receiver extras
3247 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
3248 try {
3249 pae.receiver.onHandleAssistData(sendBundle);
3250 } catch (RemoteException e) {
3251 }
3252 }
3253 }
3254
3255 public class PendingAssistExtras extends Binder implements Runnable {
3256 public final ActivityRecord activity;
3257 public boolean isHome;
3258 public final Bundle extras;
3259 public final Intent intent;
3260 public final String hint;
3261 public final IAssistDataReceiver receiver;
3262 public final int userHandle;
3263 public boolean haveResult = false;
3264 public Bundle result = null;
3265 public AssistStructure structure = null;
3266 public AssistContent content = null;
3267 public Bundle receiverExtras;
3268
3269 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
3270 String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
3271 int _userHandle) {
3272 activity = _activity;
3273 extras = _extras;
3274 intent = _intent;
3275 hint = _hint;
3276 receiver = _receiver;
3277 receiverExtras = _receiverExtras;
3278 userHandle = _userHandle;
3279 }
3280
3281 @Override
3282 public void run() {
3283 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
3284 synchronized (this) {
3285 haveResult = true;
3286 notifyAll();
3287 }
3288 pendingAssistExtrasTimedOut(this);
3289 }
3290 }
3291
3292 @Override
3293 public boolean isAssistDataAllowedOnCurrentActivity() {
3294 int userId;
3295 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003296 final ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003297 if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
3298 return false;
3299 }
3300
3301 final ActivityRecord activity = focusedStack.getTopActivity();
3302 if (activity == null) {
3303 return false;
3304 }
3305 userId = activity.userId;
3306 }
3307 return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
3308 }
3309
3310 @Override
3311 public boolean showAssistFromActivity(IBinder token, Bundle args) {
3312 long ident = Binder.clearCallingIdentity();
3313 try {
3314 synchronized (mGlobalLock) {
3315 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003316 ActivityRecord top = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003317 if (top != caller) {
3318 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3319 + " is not current top " + top);
3320 return false;
3321 }
3322 if (!top.nowVisible) {
3323 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3324 + " is not visible");
3325 return false;
3326 }
3327 }
3328 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
3329 token);
3330 } finally {
3331 Binder.restoreCallingIdentity(ident);
3332 }
3333 }
3334
3335 @Override
3336 public boolean isRootVoiceInteraction(IBinder token) {
3337 synchronized (mGlobalLock) {
3338 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3339 if (r == null) {
3340 return false;
3341 }
3342 return r.rootVoiceInteraction;
3343 }
3344 }
3345
Wale Ogunwalef6733932018-06-27 05:14:34 -07003346 private void onLocalVoiceInteractionStartedLocked(IBinder activity,
3347 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
3348 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
3349 if (activityToCallback == null) return;
3350 activityToCallback.setVoiceSessionLocked(voiceSession);
3351
3352 // Inform the activity
3353 try {
3354 activityToCallback.app.getThread().scheduleLocalVoiceInteractionStarted(activity,
3355 voiceInteractor);
3356 long token = Binder.clearCallingIdentity();
3357 try {
3358 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
3359 } finally {
3360 Binder.restoreCallingIdentity(token);
3361 }
3362 // TODO: VI Should we cache the activity so that it's easier to find later
3363 // rather than scan through all the stacks and activities?
3364 } catch (RemoteException re) {
3365 activityToCallback.clearVoiceSessionLocked();
3366 // TODO: VI Should this terminate the voice session?
3367 }
3368 }
3369
3370 private void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
3371 Slog.d(TAG, "<<< startRunningVoiceLocked()");
3372 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
3373 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
3374 boolean wasRunningVoice = mRunningVoice != null;
3375 mRunningVoice = session;
3376 if (!wasRunningVoice) {
3377 mVoiceWakeLock.acquire();
3378 updateSleepIfNeededLocked();
3379 }
3380 }
3381 }
3382
3383 void finishRunningVoiceLocked() {
3384 if (mRunningVoice != null) {
3385 mRunningVoice = null;
3386 mVoiceWakeLock.release();
3387 updateSleepIfNeededLocked();
3388 }
3389 }
3390
3391 @Override
3392 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3393 synchronized (mGlobalLock) {
3394 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3395 if (keepAwake) {
3396 mVoiceWakeLock.acquire();
3397 } else {
3398 mVoiceWakeLock.release();
3399 }
3400 }
3401 }
3402 }
3403
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003404 @Override
3405 public ComponentName getActivityClassForToken(IBinder token) {
3406 synchronized (mGlobalLock) {
3407 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3408 if (r == null) {
3409 return null;
3410 }
3411 return r.intent.getComponent();
3412 }
3413 }
3414
3415 @Override
3416 public String getPackageForToken(IBinder token) {
3417 synchronized (mGlobalLock) {
3418 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3419 if (r == null) {
3420 return null;
3421 }
3422 return r.packageName;
3423 }
3424 }
3425
3426 @Override
3427 public void showLockTaskEscapeMessage(IBinder token) {
3428 synchronized (mGlobalLock) {
3429 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3430 if (r == null) {
3431 return;
3432 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003433 getLockTaskController().showLockTaskToast();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003434 }
3435 }
3436
3437 @Override
3438 public void keyguardGoingAway(int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003439 enforceNotIsolatedCaller("keyguardGoingAway");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003440 final long token = Binder.clearCallingIdentity();
3441 try {
3442 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003443 mKeyguardController.keyguardGoingAway(flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003444 }
3445 } finally {
3446 Binder.restoreCallingIdentity(token);
3447 }
3448 }
3449
3450 /**
3451 * Try to place task to provided position. The final position might be different depending on
3452 * current user and stacks state. The task will be moved to target stack if it's currently in
3453 * different stack.
3454 */
3455 @Override
3456 public void positionTaskInStack(int taskId, int stackId, int position) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003457 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003458 synchronized (mGlobalLock) {
3459 long ident = Binder.clearCallingIdentity();
3460 try {
3461 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
3462 + taskId + " in stackId=" + stackId + " at position=" + position);
3463 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3464 if (task == null) {
3465 throw new IllegalArgumentException("positionTaskInStack: no task for id="
3466 + taskId);
3467 }
3468
3469 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3470
3471 if (stack == null) {
3472 throw new IllegalArgumentException("positionTaskInStack: no stack for id="
3473 + stackId);
3474 }
3475 if (!stack.isActivityTypeStandardOrUndefined()) {
3476 throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
3477 + " the position of task " + taskId + " in/to non-standard stack");
3478 }
3479
3480 // TODO: Have the callers of this API call a separate reparent method if that is
3481 // what they intended to do vs. having this method also do reparenting.
3482 if (task.getStack() == stack) {
3483 // Change position in current stack.
3484 stack.positionChildAt(task, position);
3485 } else {
3486 // Reparent to new stack.
3487 task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
3488 !DEFER_RESUME, "positionTaskInStack");
3489 }
3490 } finally {
3491 Binder.restoreCallingIdentity(ident);
3492 }
3493 }
3494 }
3495
3496 @Override
3497 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
3498 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
3499 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
3500 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
3501 synchronized (mGlobalLock) {
3502 ActivityRecord record = ActivityRecord.isInStackLocked(token);
3503 if (record == null) {
3504 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
3505 + "found for: " + token);
3506 }
3507 record.setSizeConfigurations(horizontalSizeConfiguration,
3508 verticalSizeConfigurations, smallestSizeConfigurations);
3509 }
3510 }
3511
3512 /**
3513 * Dismisses split-screen multi-window mode.
3514 * @param toTop If true the current primary split-screen stack will be placed or left on top.
3515 */
3516 @Override
3517 public void dismissSplitScreenMode(boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003518 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003519 MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
3520 final long ident = Binder.clearCallingIdentity();
3521 try {
3522 synchronized (mGlobalLock) {
3523 final ActivityStack stack =
3524 mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
3525 if (stack == null) {
3526 Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
3527 return;
3528 }
3529
3530 if (toTop) {
3531 // Caller wants the current split-screen primary stack to be the top stack after
3532 // it goes fullscreen, so move it to the front.
3533 stack.moveToFront("dismissSplitScreenMode");
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003534 } else if (mStackSupervisor.isTopDisplayFocusedStack(stack)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003535 // In this case the current split-screen primary stack shouldn't be the top
3536 // stack after it goes fullscreen, but it current has focus, so we move the
3537 // focus to the top-most split-screen secondary stack next to it.
3538 final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
3539 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
3540 if (otherStack != null) {
3541 otherStack.moveToFront("dismissSplitScreenMode_other");
3542 }
3543 }
3544
Evan Rosky10475742018-09-05 19:02:48 -07003545 stack.setWindowingMode(WINDOWING_MODE_UNDEFINED);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003546 }
3547 } finally {
3548 Binder.restoreCallingIdentity(ident);
3549 }
3550 }
3551
3552 /**
3553 * Dismisses Pip
3554 * @param animate True if the dismissal should be animated.
3555 * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
3556 * default animation duration should be used.
3557 */
3558 @Override
3559 public void dismissPip(boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003560 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003561 final long ident = Binder.clearCallingIdentity();
3562 try {
3563 synchronized (mGlobalLock) {
3564 final PinnedActivityStack stack =
3565 mStackSupervisor.getDefaultDisplay().getPinnedStack();
3566 if (stack == null) {
3567 Slog.w(TAG, "dismissPip: pinned stack not found.");
3568 return;
3569 }
3570 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
3571 throw new IllegalArgumentException("Stack: " + stack
3572 + " doesn't support animated resize.");
3573 }
3574 if (animate) {
3575 stack.animateResizePinnedStack(null /* sourceHintBounds */,
3576 null /* destBounds */, animationDuration, false /* fromFullscreen */);
3577 } else {
3578 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
3579 }
3580 }
3581 } finally {
3582 Binder.restoreCallingIdentity(ident);
3583 }
3584 }
3585
3586 @Override
3587 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003588 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003589 synchronized (mGlobalLock) {
3590 mSuppressResizeConfigChanges = suppress;
3591 }
3592 }
3593
3594 /**
3595 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
3596 * animated the stack to the fullscreen, but can also be called if we are relaunching an
3597 * activity and clearing the task at the same time.
3598 */
3599 @Override
3600 // TODO: API should just be about changing windowing modes...
3601 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003602 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003603 "moveTasksToFullscreenStack()");
3604 synchronized (mGlobalLock) {
3605 final long origId = Binder.clearCallingIdentity();
3606 try {
3607 final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
3608 if (stack != null){
3609 if (!stack.isActivityTypeStandardOrUndefined()) {
3610 throw new IllegalArgumentException(
3611 "You can't move tasks from non-standard stacks.");
3612 }
3613 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
3614 }
3615 } finally {
3616 Binder.restoreCallingIdentity(origId);
3617 }
3618 }
3619 }
3620
3621 /**
3622 * Moves the top activity in the input stackId to the pinned stack.
3623 *
3624 * @param stackId Id of stack to move the top activity to pinned stack.
3625 * @param bounds Bounds to use for pinned stack.
3626 *
3627 * @return True if the top activity of the input stack was successfully moved to the pinned
3628 * stack.
3629 */
3630 @Override
3631 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003632 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003633 "moveTopActivityToPinnedStack()");
3634 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003635 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003636 throw new IllegalStateException("moveTopActivityToPinnedStack:"
3637 + "Device doesn't support picture-in-picture mode");
3638 }
3639
3640 long ident = Binder.clearCallingIdentity();
3641 try {
3642 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
3643 } finally {
3644 Binder.restoreCallingIdentity(ident);
3645 }
3646 }
3647 }
3648
3649 @Override
3650 public boolean isInMultiWindowMode(IBinder token) {
3651 final long origId = Binder.clearCallingIdentity();
3652 try {
3653 synchronized (mGlobalLock) {
3654 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3655 if (r == null) {
3656 return false;
3657 }
3658 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
3659 return r.inMultiWindowMode();
3660 }
3661 } finally {
3662 Binder.restoreCallingIdentity(origId);
3663 }
3664 }
3665
3666 @Override
3667 public boolean isInPictureInPictureMode(IBinder token) {
3668 final long origId = Binder.clearCallingIdentity();
3669 try {
3670 synchronized (mGlobalLock) {
3671 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
3672 }
3673 } finally {
3674 Binder.restoreCallingIdentity(origId);
3675 }
3676 }
3677
3678 private boolean isInPictureInPictureMode(ActivityRecord r) {
3679 if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
3680 || r.getStack().isInStackLocked(r) == null) {
3681 return false;
3682 }
3683
3684 // If we are animating to fullscreen then we have already dispatched the PIP mode
3685 // changed, so we should reflect that check here as well.
3686 final PinnedActivityStack stack = r.getStack();
3687 final PinnedStackWindowController windowController = stack.getWindowContainerController();
3688 return !windowController.isAnimatingBoundsToFullscreen();
3689 }
3690
3691 @Override
3692 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
3693 final long origId = Binder.clearCallingIdentity();
3694 try {
3695 synchronized (mGlobalLock) {
3696 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3697 "enterPictureInPictureMode", token, params);
3698
3699 // If the activity is already in picture in picture mode, then just return early
3700 if (isInPictureInPictureMode(r)) {
3701 return true;
3702 }
3703
3704 // Activity supports picture-in-picture, now check that we can enter PiP at this
3705 // point, if it is
3706 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
3707 false /* beforeStopping */)) {
3708 return false;
3709 }
3710
3711 final Runnable enterPipRunnable = () -> {
Wale Ogunwalef276a6f2018-06-15 08:26:07 -07003712 synchronized (mGlobalLock) {
3713 // Only update the saved args from the args that are set
3714 r.pictureInPictureArgs.copyOnlySet(params);
3715 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
3716 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
3717 // Adjust the source bounds by the insets for the transition down
3718 final Rect sourceBounds = new Rect(
3719 r.pictureInPictureArgs.getSourceRectHint());
3720 mStackSupervisor.moveActivityToPinnedStackLocked(
3721 r, sourceBounds, aspectRatio, "enterPictureInPictureMode");
3722 final PinnedActivityStack stack = r.getStack();
3723 stack.setPictureInPictureAspectRatio(aspectRatio);
3724 stack.setPictureInPictureActions(actions);
3725 MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
3726 r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
3727 logPictureInPictureArgs(params);
3728 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003729 };
3730
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003731 if (isKeyguardLocked()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003732 // If the keyguard is showing or occluded, then try and dismiss it before
3733 // entering picture-in-picture (this will prompt the user to authenticate if the
3734 // device is currently locked).
3735 dismissKeyguard(token, new KeyguardDismissCallback() {
3736 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003737 public void onDismissSucceeded() {
3738 mH.post(enterPipRunnable);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003739 }
3740 }, null /* message */);
3741 } else {
3742 // Enter picture in picture immediately otherwise
3743 enterPipRunnable.run();
3744 }
3745 return true;
3746 }
3747 } finally {
3748 Binder.restoreCallingIdentity(origId);
3749 }
3750 }
3751
3752 @Override
3753 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
3754 final long origId = Binder.clearCallingIdentity();
3755 try {
3756 synchronized (mGlobalLock) {
3757 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3758 "setPictureInPictureParams", token, params);
3759
3760 // Only update the saved args from the args that are set
3761 r.pictureInPictureArgs.copyOnlySet(params);
3762 if (r.inPinnedWindowingMode()) {
3763 // If the activity is already in picture-in-picture, update the pinned stack now
3764 // if it is not already expanding to fullscreen. Otherwise, the arguments will
3765 // be used the next time the activity enters PiP
3766 final PinnedActivityStack stack = r.getStack();
3767 if (!stack.isAnimatingBoundsToFullscreen()) {
3768 stack.setPictureInPictureAspectRatio(
3769 r.pictureInPictureArgs.getAspectRatio());
3770 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
3771 }
3772 }
3773 logPictureInPictureArgs(params);
3774 }
3775 } finally {
3776 Binder.restoreCallingIdentity(origId);
3777 }
3778 }
3779
3780 @Override
3781 public int getMaxNumPictureInPictureActions(IBinder token) {
3782 // Currently, this is a static constant, but later, we may change this to be dependent on
3783 // the context of the activity
3784 return 3;
3785 }
3786
3787 private void logPictureInPictureArgs(PictureInPictureParams params) {
3788 if (params.hasSetActions()) {
3789 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
3790 params.getActions().size());
3791 }
3792 if (params.hasSetAspectRatio()) {
3793 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
3794 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
3795 MetricsLogger.action(lm);
3796 }
3797 }
3798
3799 /**
3800 * Checks the state of the system and the activity associated with the given {@param token} to
3801 * verify that picture-in-picture is supported for that activity.
3802 *
3803 * @return the activity record for the given {@param token} if all the checks pass.
3804 */
3805 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
3806 IBinder token, PictureInPictureParams params) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003807 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003808 throw new IllegalStateException(caller
3809 + ": Device doesn't support picture-in-picture mode.");
3810 }
3811
3812 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3813 if (r == null) {
3814 throw new IllegalStateException(caller
3815 + ": Can't find activity for token=" + token);
3816 }
3817
3818 if (!r.supportsPictureInPicture()) {
3819 throw new IllegalStateException(caller
3820 + ": Current activity does not support picture-in-picture.");
3821 }
3822
3823 if (params.hasSetAspectRatio()
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003824 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003825 params.getAspectRatio())) {
3826 final float minAspectRatio = mContext.getResources().getFloat(
3827 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
3828 final float maxAspectRatio = mContext.getResources().getFloat(
3829 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
3830 throw new IllegalArgumentException(String.format(caller
3831 + ": Aspect ratio is too extreme (must be between %f and %f).",
3832 minAspectRatio, maxAspectRatio));
3833 }
3834
3835 // Truncate the number of actions if necessary
3836 params.truncateActions(getMaxNumPictureInPictureActions(token));
3837
3838 return r;
3839 }
3840
3841 @Override
3842 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003843 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003844 synchronized (mGlobalLock) {
3845 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
3846 if (r == null) {
3847 throw new IllegalArgumentException("Activity does not exist; token="
3848 + activityToken);
3849 }
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07003850 return r.getUriPermissionsLocked().getExternalToken();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003851 }
3852 }
3853
3854 @Override
3855 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
3856 Rect tempDockedTaskInsetBounds,
3857 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003858 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003859 long ident = Binder.clearCallingIdentity();
3860 try {
3861 synchronized (mGlobalLock) {
3862 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
3863 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
3864 PRESERVE_WINDOWS);
3865 }
3866 } finally {
3867 Binder.restoreCallingIdentity(ident);
3868 }
3869 }
3870
3871 @Override
3872 public void setSplitScreenResizing(boolean resizing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003873 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003874 final long ident = Binder.clearCallingIdentity();
3875 try {
3876 synchronized (mGlobalLock) {
3877 mStackSupervisor.setSplitScreenResizing(resizing);
3878 }
3879 } finally {
3880 Binder.restoreCallingIdentity(ident);
3881 }
3882 }
3883
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003884 /**
3885 * Check that we have the features required for VR-related API calls, and throw an exception if
3886 * not.
3887 */
Wale Ogunwale59507092018-10-29 09:00:30 -07003888 public void enforceSystemHasVrFeature() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003889 if (!mContext.getPackageManager().hasSystemFeature(
3890 PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
3891 throw new UnsupportedOperationException("VR mode not supported on this device!");
3892 }
3893 }
3894
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003895 @Override
3896 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003897 enforceSystemHasVrFeature();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003898
3899 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3900
3901 ActivityRecord r;
3902 synchronized (mGlobalLock) {
3903 r = ActivityRecord.isInStackLocked(token);
3904 }
3905
3906 if (r == null) {
3907 throw new IllegalArgumentException();
3908 }
3909
3910 int err;
3911 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
3912 VrManagerInternal.NO_ERROR) {
3913 return err;
3914 }
3915
3916 // Clear the binder calling uid since this path may call moveToTask().
3917 final long callingId = Binder.clearCallingIdentity();
3918 try {
3919 synchronized (mGlobalLock) {
3920 r.requestedVrComponent = (enabled) ? packageName : null;
3921
3922 // Update associated state if this activity is currently focused
Andrii Kulian52d255c2018-07-13 11:32:19 -07003923 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003924 applyUpdateVrModeLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003925 }
3926 return 0;
3927 }
3928 } finally {
3929 Binder.restoreCallingIdentity(callingId);
3930 }
3931 }
3932
3933 @Override
3934 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
3935 Slog.i(TAG, "Activity tried to startLocalVoiceInteraction");
3936 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003937 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003938 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
3939 throw new SecurityException("Only focused activity can call startVoiceInteraction");
3940 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07003941 if (mRunningVoice != null || activity.getTask().voiceSession != null
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003942 || activity.voiceSession != null) {
3943 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
3944 return;
3945 }
3946 if (activity.pendingVoiceInteractionStart) {
3947 Slog.w(TAG, "Pending start of voice interaction already.");
3948 return;
3949 }
3950 activity.pendingVoiceInteractionStart = true;
3951 }
3952 LocalServices.getService(VoiceInteractionManagerInternal.class)
3953 .startLocalVoiceInteraction(callingActivity, options);
3954 }
3955
3956 @Override
3957 public void stopLocalVoiceInteraction(IBinder callingActivity) {
3958 LocalServices.getService(VoiceInteractionManagerInternal.class)
3959 .stopLocalVoiceInteraction(callingActivity);
3960 }
3961
3962 @Override
3963 public boolean supportsLocalVoiceInteraction() {
3964 return LocalServices.getService(VoiceInteractionManagerInternal.class)
3965 .supportsLocalVoiceInteraction();
3966 }
3967
3968 /** Notifies all listeners when the pinned stack animation starts. */
3969 @Override
3970 public void notifyPinnedStackAnimationStarted() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003971 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003972 }
3973
3974 /** Notifies all listeners when the pinned stack animation ends. */
3975 @Override
3976 public void notifyPinnedStackAnimationEnded() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003977 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003978 }
3979
3980 @Override
3981 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003982 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003983 final long ident = Binder.clearCallingIdentity();
3984 try {
3985 synchronized (mGlobalLock) {
3986 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
3987 }
3988 } finally {
3989 Binder.restoreCallingIdentity(ident);
3990 }
3991 }
3992
3993 @Override
3994 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003995 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003996
3997 synchronized (mGlobalLock) {
3998 // Check if display is initialized in AM.
3999 if (!mStackSupervisor.isDisplayAdded(displayId)) {
4000 // Call might come when display is not yet added or has already been removed.
4001 if (DEBUG_CONFIGURATION) {
4002 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
4003 + displayId);
4004 }
4005 return false;
4006 }
4007
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004008 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004009 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004010 values = mWindowManager.computeNewConfiguration(displayId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004011 }
4012
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004013 if (mWindowManager != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004014 final Message msg = PooledLambda.obtainMessage(
4015 ActivityManagerInternal::updateOomLevelsForDisplay, mAmInternal, displayId);
4016 mH.sendMessage(msg);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004017 }
4018
4019 final long origId = Binder.clearCallingIdentity();
4020 try {
4021 if (values != null) {
4022 Settings.System.clearConfiguration(values);
4023 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004024 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004025 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
4026 return mTmpUpdateConfigurationResult.changes != 0;
4027 } finally {
4028 Binder.restoreCallingIdentity(origId);
4029 }
4030 }
4031 }
4032
4033 @Override
4034 public boolean updateConfiguration(Configuration values) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004035 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004036
4037 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004038 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004039 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004040 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004041 }
4042
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004043 if (mWindowManager != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004044 final Message msg = PooledLambda.obtainMessage(
4045 ActivityManagerInternal::updateOomLevelsForDisplay, mAmInternal,
4046 DEFAULT_DISPLAY);
4047 mH.sendMessage(msg);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004048 }
4049
4050 final long origId = Binder.clearCallingIdentity();
4051 try {
4052 if (values != null) {
4053 Settings.System.clearConfiguration(values);
4054 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004055 updateConfigurationLocked(values, null, false, false /* persistent */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004056 UserHandle.USER_NULL, false /* deferResume */,
4057 mTmpUpdateConfigurationResult);
4058 return mTmpUpdateConfigurationResult.changes != 0;
4059 } finally {
4060 Binder.restoreCallingIdentity(origId);
4061 }
4062 }
4063 }
4064
4065 @Override
4066 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
4067 CharSequence message) {
4068 if (message != null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004069 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004070 Manifest.permission.SHOW_KEYGUARD_MESSAGE, "dismissKeyguard()");
4071 }
4072 final long callingId = Binder.clearCallingIdentity();
4073 try {
4074 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004075 mKeyguardController.dismissKeyguard(token, callback, message);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004076 }
4077 } finally {
4078 Binder.restoreCallingIdentity(callingId);
4079 }
4080 }
4081
4082 @Override
4083 public void cancelTaskWindowTransition(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004084 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004085 "cancelTaskWindowTransition()");
4086 final long ident = Binder.clearCallingIdentity();
4087 try {
4088 synchronized (mGlobalLock) {
4089 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
4090 MATCH_TASK_IN_STACKS_ONLY);
4091 if (task == null) {
4092 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
4093 return;
4094 }
4095 task.cancelWindowTransition();
4096 }
4097 } finally {
4098 Binder.restoreCallingIdentity(ident);
4099 }
4100 }
4101
4102 @Override
4103 public ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004104 enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004105 final long ident = Binder.clearCallingIdentity();
4106 try {
4107 final TaskRecord task;
4108 synchronized (mGlobalLock) {
4109 task = mStackSupervisor.anyTaskForIdLocked(taskId,
4110 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
4111 if (task == null) {
4112 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
4113 return null;
4114 }
4115 }
4116 // Don't call this while holding the lock as this operation might hit the disk.
4117 return task.getSnapshot(reducedResolution);
4118 } finally {
4119 Binder.restoreCallingIdentity(ident);
4120 }
4121 }
4122
4123 @Override
4124 public void setDisablePreviewScreenshots(IBinder token, boolean disable) {
4125 synchronized (mGlobalLock) {
4126 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4127 if (r == null) {
4128 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
4129 + token);
4130 return;
4131 }
4132 final long origId = Binder.clearCallingIdentity();
4133 try {
4134 r.setDisablePreviewScreenshots(disable);
4135 } finally {
4136 Binder.restoreCallingIdentity(origId);
4137 }
4138 }
4139 }
4140
4141 /** Return the user id of the last resumed activity. */
4142 @Override
4143 public @UserIdInt
4144 int getLastResumedActivityUserId() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004145 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004146 Manifest.permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
4147 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07004148 if (mLastResumedActivity == null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004149 return getCurrentUserId();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004150 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004151 return mLastResumedActivity.userId;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004152 }
4153 }
4154
4155 @Override
4156 public void updateLockTaskFeatures(int userId, int flags) {
4157 final int callingUid = Binder.getCallingUid();
4158 if (callingUid != 0 && callingUid != SYSTEM_UID) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004159 mAmInternal.enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004160 "updateLockTaskFeatures()");
4161 }
4162 synchronized (mGlobalLock) {
4163 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
4164 Integer.toHexString(flags));
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07004165 getLockTaskController().updateLockTaskFeatures(userId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004166 }
4167 }
4168
4169 @Override
4170 public void setShowWhenLocked(IBinder token, boolean showWhenLocked) {
4171 synchronized (mGlobalLock) {
4172 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4173 if (r == null) {
4174 return;
4175 }
4176 final long origId = Binder.clearCallingIdentity();
4177 try {
4178 r.setShowWhenLocked(showWhenLocked);
4179 } finally {
4180 Binder.restoreCallingIdentity(origId);
4181 }
4182 }
4183 }
4184
4185 @Override
4186 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) {
4187 synchronized (mGlobalLock) {
4188 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4189 if (r == null) {
4190 return;
4191 }
4192 final long origId = Binder.clearCallingIdentity();
4193 try {
4194 r.setTurnScreenOn(turnScreenOn);
4195 } finally {
4196 Binder.restoreCallingIdentity(origId);
4197 }
4198 }
4199 }
4200
4201 @Override
4202 public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004203 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004204 "registerRemoteAnimations");
4205 definition.setCallingPid(Binder.getCallingPid());
4206 synchronized (mGlobalLock) {
4207 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4208 if (r == null) {
4209 return;
4210 }
4211 final long origId = Binder.clearCallingIdentity();
4212 try {
4213 r.registerRemoteAnimations(definition);
4214 } finally {
4215 Binder.restoreCallingIdentity(origId);
4216 }
4217 }
4218 }
4219
4220 @Override
4221 public void registerRemoteAnimationForNextActivityStart(String packageName,
4222 RemoteAnimationAdapter adapter) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004223 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004224 "registerRemoteAnimationForNextActivityStart");
4225 adapter.setCallingPid(Binder.getCallingPid());
4226 synchronized (mGlobalLock) {
4227 final long origId = Binder.clearCallingIdentity();
4228 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07004229 getActivityStartController().registerRemoteAnimationForNextActivityStart(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004230 packageName, adapter);
4231 } finally {
4232 Binder.restoreCallingIdentity(origId);
4233 }
4234 }
4235 }
4236
4237 /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
4238 @Override
4239 public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
4240 synchronized (mGlobalLock) {
4241 final long origId = Binder.clearCallingIdentity();
4242 try {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004243 mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004244 } finally {
4245 Binder.restoreCallingIdentity(origId);
4246 }
4247 }
4248 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004249
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004250 @Override
4251 public void setVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004252 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004253 synchronized (mGlobalLock) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004254 final int pid = Binder.getCallingPid();
4255 final WindowProcessController wpc = mPidMap.get(pid);
4256 mVrController.setVrThreadLocked(tid, pid, wpc);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004257 }
4258 }
4259
4260 @Override
4261 public void setPersistentVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004262 if (checkCallingPermission(Manifest.permission.RESTRICTED_VR_ACCESS)
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004263 != PERMISSION_GRANTED) {
4264 final String msg = "Permission Denial: setPersistentVrThread() from pid="
4265 + Binder.getCallingPid()
4266 + ", uid=" + Binder.getCallingUid()
4267 + " requires " + Manifest.permission.RESTRICTED_VR_ACCESS;
4268 Slog.w(TAG, msg);
4269 throw new SecurityException(msg);
4270 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004271 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004272 synchronized (mGlobalLock) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004273 final int pid = Binder.getCallingPid();
4274 final WindowProcessController proc = mPidMap.get(pid);
4275 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004276 }
4277 }
4278
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004279 @Override
4280 public void stopAppSwitches() {
4281 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
4282 synchronized (mGlobalLock) {
4283 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME;
4284 mDidAppSwitch = false;
4285 getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
4286 }
4287 }
4288
4289 @Override
4290 public void resumeAppSwitches() {
4291 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
4292 synchronized (mGlobalLock) {
4293 // Note that we don't execute any pending app switches... we will
4294 // let those wait until either the timeout, or the next start
4295 // activity request.
4296 mAppSwitchesAllowedTime = 0;
4297 }
4298 }
4299
4300 void onStartActivitySetDidAppSwitch() {
4301 if (mDidAppSwitch) {
4302 // This is the second allowed switch since we stopped switches, so now just generally
4303 // allow switches. Use case:
4304 // - user presses home (switches disabled, switch to home, mDidAppSwitch now true);
4305 // - user taps a home icon (coming from home so allowed, we hit here and now allow
4306 // anyone to switch again).
4307 mAppSwitchesAllowedTime = 0;
4308 } else {
4309 mDidAppSwitch = true;
4310 }
4311 }
4312
4313 /** @return whether the system should disable UI modes incompatible with VR mode. */
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004314 boolean shouldDisableNonVrUiLocked() {
4315 return mVrController.shouldDisableNonVrUiLocked();
4316 }
4317
Wale Ogunwale53783742018-09-16 10:21:51 -07004318 private void applyUpdateVrModeLocked(ActivityRecord r) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004319 // VR apps are expected to run in a main display. If an app is turning on VR for
4320 // itself, but lives in a dynamic stack, then make sure that it is moved to the main
4321 // fullscreen stack before enabling VR Mode.
4322 // TODO: The goal of this code is to keep the VR app on the main display. When the
4323 // stack implementation changes in the future, keep in mind that the use of the fullscreen
4324 // stack is a means to move the activity to the main display and a moveActivityToDisplay()
4325 // option would be a better choice here.
4326 if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
4327 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
4328 + " to main stack for VR");
4329 final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
4330 WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
4331 moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
4332 }
4333 mH.post(() -> {
4334 if (!mVrController.onVrModeChanged(r)) {
4335 return;
4336 }
4337 synchronized (mGlobalLock) {
4338 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
4339 mWindowManager.disableNonVrUi(disableNonVrUi);
4340 if (disableNonVrUi) {
4341 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
4342 // then remove the pinned stack.
4343 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
4344 }
4345 }
4346 });
4347 }
4348
Wale Ogunwale53783742018-09-16 10:21:51 -07004349 @Override
4350 public int getPackageScreenCompatMode(String packageName) {
4351 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4352 synchronized (mGlobalLock) {
4353 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4354 }
4355 }
4356
4357 @Override
4358 public void setPackageScreenCompatMode(String packageName, int mode) {
4359 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4360 "setPackageScreenCompatMode");
4361 synchronized (mGlobalLock) {
4362 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4363 }
4364 }
4365
4366 @Override
4367 public boolean getPackageAskScreenCompat(String packageName) {
4368 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4369 synchronized (mGlobalLock) {
4370 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4371 }
4372 }
4373
4374 @Override
4375 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4376 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4377 "setPackageAskScreenCompat");
4378 synchronized (mGlobalLock) {
4379 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4380 }
4381 }
4382
Wale Ogunwale64258362018-10-16 15:13:37 -07004383 public static String relaunchReasonToString(int relaunchReason) {
4384 switch (relaunchReason) {
4385 case RELAUNCH_REASON_WINDOWING_MODE_RESIZE:
4386 return "window_resize";
4387 case RELAUNCH_REASON_FREE_RESIZE:
4388 return "free_resize";
4389 default:
4390 return null;
4391 }
4392 }
4393
Andrii Kulian5f750bc2018-07-17 08:57:23 -07004394 ActivityStack getTopDisplayFocusedStack() {
4395 return mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004396 }
4397
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004398 /** Pokes the task persister. */
4399 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
4400 mRecentTasks.notifyTaskPersisterLocked(task, flush);
4401 }
4402
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004403 boolean isKeyguardLocked() {
4404 return mKeyguardController.isKeyguardLocked();
4405 }
4406
Wale Ogunwale31913b52018-10-13 08:29:31 -07004407 void dumpLastANRLocked(PrintWriter pw) {
4408 pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
4409 if (mLastANRState == null) {
4410 pw.println(" <no ANR has occurred since boot>");
4411 } else {
4412 pw.println(mLastANRState);
4413 }
4414 }
4415
4416 void dumpLastANRTracesLocked(PrintWriter pw) {
4417 pw.println("ACTIVITY MANAGER LAST ANR TRACES (dumpsys activity lastanr-traces)");
4418
4419 final File[] files = new File(ANR_TRACE_DIR).listFiles();
4420 if (ArrayUtils.isEmpty(files)) {
4421 pw.println(" <no ANR has occurred since boot>");
4422 return;
4423 }
4424 // Find the latest file.
4425 File latest = null;
4426 for (File f : files) {
4427 if ((latest == null) || (latest.lastModified() < f.lastModified())) {
4428 latest = f;
Wale Ogunwalef6733932018-06-27 05:14:34 -07004429 }
Wale Ogunwale31913b52018-10-13 08:29:31 -07004430 }
4431 pw.print("File: ");
4432 pw.print(latest.getName());
4433 pw.println();
4434 try (BufferedReader in = new BufferedReader(new FileReader(latest))) {
4435 String line;
4436 while ((line = in.readLine()) != null) {
4437 pw.println(line);
4438 }
4439 } catch (IOException e) {
4440 pw.print("Unable to read: ");
4441 pw.print(e);
4442 pw.println();
4443 }
4444 }
4445
4446 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
4447 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
4448 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
4449 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
4450 }
4451
4452 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
4453 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
4454 pw.println(header);
4455
4456 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
4457 dumpPackage);
4458 boolean needSep = printedAnything;
4459
4460 boolean printed = ActivityStackSupervisor.printThisActivity(pw,
4461 mStackSupervisor.getTopResumedActivity(), dumpPackage, needSep,
4462 " ResumedActivity: ");
4463 if (printed) {
4464 printedAnything = true;
4465 needSep = false;
4466 }
4467
4468 if (dumpPackage == null) {
4469 if (needSep) {
4470 pw.println();
4471 }
4472 printedAnything = true;
4473 mStackSupervisor.dump(pw, " ");
4474 }
4475
4476 if (!printedAnything) {
4477 pw.println(" (nothing)");
4478 }
4479 }
4480
4481 void dumpActivityContainersLocked(PrintWriter pw) {
4482 pw.println("ACTIVITY MANAGER STARTER (dumpsys activity containers)");
4483 mStackSupervisor.dumpChildrenNames(pw, " ");
4484 pw.println(" ");
4485 }
4486
4487 void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
4488 pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
4489 getActivityStartController().dump(pw, "", dumpPackage);
4490 }
4491
4492 /**
4493 * There are three things that cmd can be:
4494 * - a flattened component name that matches an existing activity
4495 * - the cmd arg isn't the flattened component name of an existing activity:
4496 * dump all activity whose component contains the cmd as a substring
4497 * - A hex number of the ActivityRecord object instance.
4498 *
4499 * @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
4500 * @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
4501 */
4502 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
4503 int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
4504 ArrayList<ActivityRecord> activities;
4505
4506 synchronized (mGlobalLock) {
4507 activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
4508 dumpFocusedStackOnly);
4509 }
4510
4511 if (activities.size() <= 0) {
4512 return false;
4513 }
4514
4515 String[] newArgs = new String[args.length - opti];
4516 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
4517
4518 TaskRecord lastTask = null;
4519 boolean needSep = false;
4520 for (int i = activities.size() - 1; i >= 0; i--) {
4521 ActivityRecord r = activities.get(i);
4522 if (needSep) {
4523 pw.println();
4524 }
4525 needSep = true;
4526 synchronized (mGlobalLock) {
4527 final TaskRecord task = r.getTask();
4528 if (lastTask != task) {
4529 lastTask = task;
4530 pw.print("TASK "); pw.print(lastTask.affinity);
4531 pw.print(" id="); pw.print(lastTask.taskId);
4532 pw.print(" userId="); pw.println(lastTask.userId);
4533 if (dumpAll) {
4534 lastTask.dump(pw, " ");
4535 }
4536 }
4537 }
4538 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
4539 }
4540 return true;
4541 }
4542
4543 /**
4544 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
4545 * there is a thread associated with the activity.
4546 */
4547 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
4548 final ActivityRecord r, String[] args, boolean dumpAll) {
4549 String innerPrefix = prefix + " ";
4550 synchronized (mGlobalLock) {
4551 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
4552 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
4553 pw.print(" pid=");
4554 if (r.hasProcess()) pw.println(r.app.getPid());
4555 else pw.println("(not running)");
4556 if (dumpAll) {
4557 r.dump(pw, innerPrefix);
4558 }
4559 }
4560 if (r.attachedToProcess()) {
4561 // flush anything that is already in the PrintWriter since the thread is going
4562 // to write to the file descriptor directly
4563 pw.flush();
4564 try {
4565 TransferPipe tp = new TransferPipe();
4566 try {
4567 r.app.getThread().dumpActivity(tp.getWriteFd(),
4568 r.appToken, innerPrefix, args);
4569 tp.go(fd);
4570 } finally {
4571 tp.kill();
4572 }
4573 } catch (IOException e) {
4574 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
4575 } catch (RemoteException e) {
4576 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
4577 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004578 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004579 }
4580
Wale Ogunwalef6733932018-06-27 05:14:34 -07004581 void writeSleepStateToProto(ProtoOutputStream proto) {
4582 for (ActivityTaskManagerInternal.SleepToken st : mStackSupervisor.mSleepTokens) {
4583 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS,
4584 st.toString());
4585 }
4586
4587 if (mRunningVoice != null) {
4588 final long vrToken = proto.start(
4589 ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
4590 proto.write(ActivityManagerServiceDumpProcessesProto.Voice.SESSION,
4591 mRunningVoice.toString());
4592 mVoiceWakeLock.writeToProto(
4593 proto, ActivityManagerServiceDumpProcessesProto.Voice.WAKELOCK);
4594 proto.end(vrToken);
4595 }
4596
4597 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
4598 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN,
4599 mShuttingDown);
4600 mVrController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004601 }
4602
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004603 int getCurrentUserId() {
4604 return mAmInternal.getCurrentUserId();
4605 }
4606
4607 private void enforceNotIsolatedCaller(String caller) {
4608 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4609 throw new SecurityException("Isolated process not allowed to call " + caller);
4610 }
4611 }
4612
Wale Ogunwalef6733932018-06-27 05:14:34 -07004613 public Configuration getConfiguration() {
4614 Configuration ci;
4615 synchronized(mGlobalLock) {
Yunfan Chen75157d72018-07-27 14:47:21 +09004616 ci = new Configuration(getGlobalConfigurationForCallingPid());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004617 ci.userSetLocale = false;
4618 }
4619 return ci;
4620 }
4621
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004622 /**
4623 * Current global configuration information. Contains general settings for the entire system,
4624 * also corresponds to the merged configuration of the default display.
4625 */
4626 Configuration getGlobalConfiguration() {
4627 return mStackSupervisor.getConfiguration();
4628 }
4629
4630 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4631 boolean initLocale) {
4632 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
4633 }
4634
4635 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4636 boolean initLocale, boolean deferResume) {
4637 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
4638 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
4639 UserHandle.USER_NULL, deferResume);
4640 }
4641
Wale Ogunwale59507092018-10-29 09:00:30 -07004642 public void updatePersistentConfiguration(Configuration values, @UserIdInt int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004643 final long origId = Binder.clearCallingIdentity();
4644 try {
4645 synchronized (mGlobalLock) {
4646 updateConfigurationLocked(values, null, false, true, userId,
4647 false /* deferResume */);
4648 }
4649 } finally {
4650 Binder.restoreCallingIdentity(origId);
4651 }
4652 }
4653
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004654 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4655 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
4656 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
4657 deferResume, null /* result */);
4658 }
4659
4660 /**
4661 * Do either or both things: (1) change the current configuration, and (2)
4662 * make sure the given activity is running with the (now) current
4663 * configuration. Returns true if the activity has been left running, or
4664 * false if <var>starting</var> is being destroyed to match the new
4665 * configuration.
4666 *
4667 * @param userId is only used when persistent parameter is set to true to persist configuration
4668 * for that particular user
4669 */
4670 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4671 boolean initLocale, boolean persistent, int userId, boolean deferResume,
4672 ActivityTaskManagerService.UpdateConfigurationResult result) {
4673 int changes = 0;
4674 boolean kept = true;
4675
4676 if (mWindowManager != null) {
4677 mWindowManager.deferSurfaceLayout();
4678 }
4679 try {
4680 if (values != null) {
4681 changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
4682 deferResume);
4683 }
4684
4685 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4686 } finally {
4687 if (mWindowManager != null) {
4688 mWindowManager.continueSurfaceLayout();
4689 }
4690 }
4691
4692 if (result != null) {
4693 result.changes = changes;
4694 result.activityRelaunched = !kept;
4695 }
4696 return kept;
4697 }
4698
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004699 /** Update default (global) configuration and notify listeners about changes. */
4700 private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
4701 boolean persistent, int userId, boolean deferResume) {
4702 mTempConfig.setTo(getGlobalConfiguration());
4703 final int changes = mTempConfig.updateFrom(values);
4704 if (changes == 0) {
4705 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
4706 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
4707 // performDisplayOverrideConfigUpdate in order to send the new display configuration
4708 // (even if there are no actual changes) to unfreeze the window.
4709 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
4710 return 0;
4711 }
4712
4713 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
4714 "Updating global configuration to: " + values);
4715
4716 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
4717 StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
4718 values.colorMode,
4719 values.densityDpi,
4720 values.fontScale,
4721 values.hardKeyboardHidden,
4722 values.keyboard,
4723 values.keyboardHidden,
4724 values.mcc,
4725 values.mnc,
4726 values.navigation,
4727 values.navigationHidden,
4728 values.orientation,
4729 values.screenHeightDp,
4730 values.screenLayout,
4731 values.screenWidthDp,
4732 values.smallestScreenWidthDp,
4733 values.touchscreen,
4734 values.uiMode);
4735
4736
4737 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
4738 final LocaleList locales = values.getLocales();
4739 int bestLocaleIndex = 0;
4740 if (locales.size() > 1) {
4741 if (mSupportedSystemLocales == null) {
4742 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
4743 }
4744 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
4745 }
4746 SystemProperties.set("persist.sys.locale",
4747 locales.get(bestLocaleIndex).toLanguageTag());
4748 LocaleList.setDefault(locales, bestLocaleIndex);
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004749
4750 final Message m = PooledLambda.obtainMessage(
4751 ActivityTaskManagerService::sendLocaleToMountDaemonMsg, this,
4752 locales.get(bestLocaleIndex));
4753 mH.sendMessage(m);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004754 }
4755
Yunfan Chen75157d72018-07-27 14:47:21 +09004756 mTempConfig.seq = increaseConfigurationSeqLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004757
4758 // Update stored global config and notify everyone about the change.
4759 mStackSupervisor.onConfigurationChanged(mTempConfig);
4760
4761 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
4762 // TODO(multi-display): Update UsageEvents#Event to include displayId.
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004763 mUsageStatsInternal.reportConfigurationChange(mTempConfig, mAmInternal.getCurrentUserId());
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004764
4765 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
Wale Ogunwalef6733932018-06-27 05:14:34 -07004766 updateShouldShowDialogsLocked(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004767
4768 AttributeCache ac = AttributeCache.instance();
4769 if (ac != null) {
4770 ac.updateConfiguration(mTempConfig);
4771 }
4772
4773 // Make sure all resources in our process are updated right now, so that anyone who is going
4774 // to retrieve resource values after we return will be sure to get the new ones. This is
4775 // especially important during boot, where the first config change needs to guarantee all
4776 // resources have that config before following boot code is executed.
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004777 mSystemThread.applyConfigurationToResources(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004778
4779 // We need another copy of global config because we're scheduling some calls instead of
4780 // running them in place. We need to be sure that object we send will be handled unchanged.
4781 final Configuration configCopy = new Configuration(mTempConfig);
4782 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004783 final Message msg = PooledLambda.obtainMessage(
4784 ActivityTaskManagerService::sendPutConfigurationForUserMsg,
4785 this, userId, configCopy);
4786 mH.sendMessage(msg);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004787 }
4788
Yunfan Chen34fcc7a2018-10-11 16:26:09 -07004789 for (int i = mPidMap.size() - 1; i >= 0; i--) {
Yunfan Chen79b96062018-10-17 12:45:23 -07004790 final int pid = mPidMap.keyAt(i);
4791 final WindowProcessController app = mPidMap.get(pid);
Yunfan Chen34fcc7a2018-10-11 16:26:09 -07004792 if (DEBUG_CONFIGURATION) {
4793 Slog.v(TAG_CONFIGURATION, "Update process config of "
4794 + app.mName + " to new config " + configCopy);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004795 }
Yunfan Chen34fcc7a2018-10-11 16:26:09 -07004796 app.onConfigurationChanged(configCopy);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004797 }
4798
Wale Ogunwale2ea36d42018-10-18 10:27:31 -07004799 final Message msg = PooledLambda.obtainMessage(
4800 ActivityManagerInternal::broadcastGlobalConfigurationChanged,
4801 mAmInternal, changes, initLocale);
4802 mH.sendMessage(msg);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004803
4804 // Override configuration of the default display duplicates global config, so we need to
4805 // update it also. This will also notify WindowManager about changes.
4806 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
4807 DEFAULT_DISPLAY);
4808
4809 return changes;
4810 }
4811
4812 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
4813 boolean deferResume, int displayId) {
4814 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
4815 displayId, null /* result */);
4816 }
4817
4818 /**
4819 * Updates override configuration specific for the selected display. If no config is provided,
4820 * new one will be computed in WM based on current display info.
4821 */
4822 boolean updateDisplayOverrideConfigurationLocked(Configuration values,
4823 ActivityRecord starting, boolean deferResume, int displayId,
4824 ActivityTaskManagerService.UpdateConfigurationResult result) {
4825 int changes = 0;
4826 boolean kept = true;
4827
4828 if (mWindowManager != null) {
4829 mWindowManager.deferSurfaceLayout();
4830 }
4831 try {
4832 if (values != null) {
4833 if (displayId == DEFAULT_DISPLAY) {
4834 // Override configuration of the default display duplicates global config, so
4835 // we're calling global config update instead for default display. It will also
4836 // apply the correct override config.
4837 changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
4838 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
4839 } else {
4840 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
4841 }
4842 }
4843
4844 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4845 } finally {
4846 if (mWindowManager != null) {
4847 mWindowManager.continueSurfaceLayout();
4848 }
4849 }
4850
4851 if (result != null) {
4852 result.changes = changes;
4853 result.activityRelaunched = !kept;
4854 }
4855 return kept;
4856 }
4857
4858 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
4859 int displayId) {
4860 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
4861 final int changes = mTempConfig.updateFrom(values);
4862 if (changes != 0) {
4863 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
4864 + mTempConfig + " for displayId=" + displayId);
4865 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
4866
4867 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
4868 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004869 mAppWarnings.onDensityChanged();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004870
Wale Ogunwale5c918702018-10-18 11:06:33 -07004871 // Post message to start process to avoid possible deadlock of calling into AMS with
4872 // the ATMS lock held.
4873 final Message msg = PooledLambda.obtainMessage(
4874 ActivityManagerInternal::killAllBackgroundProcessesExcept, mAmInternal,
4875 N, ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
4876 mH.sendMessage(msg);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004877 }
4878 }
4879
4880 // Update the configuration with WM first and check if any of the stacks need to be resized
4881 // due to the configuration change. If so, resize the stacks now and do any relaunches if
4882 // necessary. This way we don't need to relaunch again afterwards in
4883 // ensureActivityConfiguration().
4884 if (mWindowManager != null) {
4885 final int[] resizedStacks =
4886 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
4887 if (resizedStacks != null) {
4888 for (int stackId : resizedStacks) {
4889 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
4890 }
4891 }
4892 }
4893
4894 return changes;
4895 }
4896
Wale Ogunwalef6733932018-06-27 05:14:34 -07004897 private void updateEventDispatchingLocked(boolean booted) {
4898 mWindowManager.setEventDispatching(booted && !mShuttingDown);
4899 }
4900
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004901 private void sendPutConfigurationForUserMsg(int userId, Configuration config) {
4902 final ContentResolver resolver = mContext.getContentResolver();
4903 Settings.System.putConfigurationForUser(resolver, config, userId);
4904 }
4905
4906 private void sendLocaleToMountDaemonMsg(Locale l) {
4907 try {
4908 IBinder service = ServiceManager.getService("mount");
4909 IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
4910 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
4911 storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
4912 } catch (RemoteException e) {
4913 Log.e(TAG, "Error storing locale for decryption UI", e);
4914 }
4915 }
4916
4917 boolean isActivityStartsLoggingEnabled() {
4918 return mAmInternal.isActivityStartsLoggingEnabled();
4919 }
4920
Wale Ogunwalef6733932018-06-27 05:14:34 -07004921 void enableScreenAfterBoot(boolean booted) {
4922 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4923 SystemClock.uptimeMillis());
4924 mWindowManager.enableScreenAfterBoot();
4925
4926 synchronized (mGlobalLock) {
4927 updateEventDispatchingLocked(booted);
4928 }
4929 }
4930
Wale Ogunwale906f9c62018-07-23 11:23:44 -07004931 static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
4932 if (r == null || !r.hasProcess()) {
4933 return KEY_DISPATCHING_TIMEOUT_MS;
4934 }
4935 return getInputDispatchingTimeoutLocked(r.app);
4936 }
4937
4938 private static long getInputDispatchingTimeoutLocked(WindowProcessController r) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07004939 return r != null ? r.getInputDispatchingTimeout() : KEY_DISPATCHING_TIMEOUT_MS;
Wale Ogunwale906f9c62018-07-23 11:23:44 -07004940 }
4941
Wale Ogunwalef6733932018-06-27 05:14:34 -07004942 /**
4943 * Decide based on the configuration whether we should show the ANR,
4944 * crash, etc dialogs. The idea is that if there is no affordance to
4945 * press the on-screen buttons, or the user experience would be more
4946 * greatly impacted than the crash itself, we shouldn't show the dialog.
4947 *
4948 * A thought: SystemUI might also want to get told about this, the Power
4949 * dialog / global actions also might want different behaviors.
4950 */
4951 private void updateShouldShowDialogsLocked(Configuration config) {
4952 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
4953 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
4954 && config.navigation == Configuration.NAVIGATION_NONAV);
4955 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
4956 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
4957 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
4958 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
4959 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
4960 final boolean hideDialogsSet = Settings.Global.getInt(mContext.getContentResolver(),
4961 HIDE_ERROR_DIALOGS, 0) != 0;
4962 mShowDialogs = inputMethodExists && uiModeSupportsDialogs && !hideDialogsSet;
4963 }
4964
4965 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
4966 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
4967 FONT_SCALE, 1.0f, userId);
4968
4969 synchronized (this) {
4970 if (getGlobalConfiguration().fontScale == scaleFactor) {
4971 return;
4972 }
4973
4974 final Configuration configuration
4975 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
4976 configuration.fontScale = scaleFactor;
4977 updatePersistentConfiguration(configuration, userId);
4978 }
4979 }
4980
4981 // Actually is sleeping or shutting down or whatever else in the future
4982 // is an inactive state.
4983 boolean isSleepingOrShuttingDownLocked() {
4984 return isSleepingLocked() || mShuttingDown;
4985 }
4986
4987 boolean isSleepingLocked() {
4988 return mSleeping;
4989 }
4990
Riddle Hsu16567132018-08-16 21:37:47 +08004991 /** Update AMS states when an activity is resumed. */
Wale Ogunwalef6733932018-06-27 05:14:34 -07004992 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
4993 final TaskRecord task = r.getTask();
4994 if (task.isActivityTypeStandard()) {
4995 if (mCurAppTimeTracker != r.appTimeTracker) {
4996 // We are switching app tracking. Complete the current one.
4997 if (mCurAppTimeTracker != null) {
4998 mCurAppTimeTracker.stop();
4999 mH.obtainMessage(
5000 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
5001 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
5002 mCurAppTimeTracker = null;
5003 }
5004 if (r.appTimeTracker != null) {
5005 mCurAppTimeTracker = r.appTimeTracker;
5006 startTimeTrackingFocusedActivityLocked();
5007 }
5008 } else {
5009 startTimeTrackingFocusedActivityLocked();
5010 }
5011 } else {
5012 r.appTimeTracker = null;
5013 }
5014 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
5015 // TODO: Probably not, because we don't want to resume voice on switching
5016 // back to this activity
5017 if (task.voiceInteractor != null) {
5018 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
5019 } else {
5020 finishRunningVoiceLocked();
5021
5022 if (mLastResumedActivity != null) {
5023 final IVoiceInteractionSession session;
5024
5025 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
5026 if (lastResumedActivityTask != null
5027 && lastResumedActivityTask.voiceSession != null) {
5028 session = lastResumedActivityTask.voiceSession;
5029 } else {
5030 session = mLastResumedActivity.voiceSession;
5031 }
5032
5033 if (session != null) {
5034 // We had been in a voice interaction session, but now focused has
5035 // move to something different. Just finish the session, we can't
5036 // return to it and retain the proper state and synchronization with
5037 // the voice interaction service.
5038 finishVoiceTask(session);
5039 }
5040 }
5041 }
5042
5043 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
5044 mAmInternal.sendForegroundProfileChanged(r.userId);
5045 }
5046 updateResumedAppTrace(r);
5047 mLastResumedActivity = r;
5048
Tiger Huang1e5b10a2018-07-30 20:19:51 +08005049 r.getDisplay().setFocusedApp(r, true);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005050
5051 applyUpdateLockStateLocked(r);
5052 applyUpdateVrModeLocked(r);
5053
5054 EventLogTags.writeAmSetResumedActivity(
5055 r == null ? -1 : r.userId,
5056 r == null ? "NULL" : r.shortComponentName,
5057 reason);
5058 }
5059
5060 ActivityTaskManagerInternal.SleepToken acquireSleepToken(String tag, int displayId) {
5061 synchronized (mGlobalLock) {
5062 final ActivityTaskManagerInternal.SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
5063 updateSleepIfNeededLocked();
5064 return token;
5065 }
5066 }
5067
5068 void updateSleepIfNeededLocked() {
5069 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
5070 final boolean wasSleeping = mSleeping;
5071 boolean updateOomAdj = false;
5072
5073 if (!shouldSleep) {
5074 // If wasSleeping is true, we need to wake up activity manager state from when
5075 // we started sleeping. In either case, we need to apply the sleep tokens, which
5076 // will wake up stacks or put them to sleep as appropriate.
5077 if (wasSleeping) {
5078 mSleeping = false;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07005079 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
5080 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__AWAKE);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005081 startTimeTrackingFocusedActivityLocked();
5082 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
5083 mStackSupervisor.comeOutOfSleepIfNeededLocked();
5084 }
5085 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
5086 if (wasSleeping) {
5087 updateOomAdj = true;
5088 }
5089 } else if (!mSleeping && shouldSleep) {
5090 mSleeping = true;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07005091 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
5092 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__ASLEEP);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005093 if (mCurAppTimeTracker != null) {
5094 mCurAppTimeTracker.stop();
5095 }
5096 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
5097 mStackSupervisor.goingToSleepLocked();
5098 updateResumedAppTrace(null /* resumed */);
5099 updateOomAdj = true;
5100 }
5101 if (updateOomAdj) {
5102 mH.post(mAmInternal::updateOomAdj);
5103 }
5104 }
5105
5106 void updateOomAdj() {
5107 mH.post(mAmInternal::updateOomAdj);
5108 }
5109
Wale Ogunwale53783742018-09-16 10:21:51 -07005110 void updateCpuStats() {
5111 mH.post(mAmInternal::updateCpuStats);
5112 }
5113
5114 void updateUsageStats(ActivityRecord component, boolean resumed) {
5115 final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::updateUsageStats,
5116 mAmInternal, component.realActivity, component.app.mUid, component.userId, resumed);
5117 mH.sendMessage(m);
5118 }
5119
5120 void setBooting(boolean booting) {
5121 mAmInternal.setBooting(booting);
5122 }
5123
5124 boolean isBooting() {
5125 return mAmInternal.isBooting();
5126 }
5127
5128 void setBooted(boolean booted) {
5129 mAmInternal.setBooted(booted);
5130 }
5131
5132 boolean isBooted() {
5133 return mAmInternal.isBooted();
5134 }
5135
5136 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
5137 mH.post(() -> {
5138 if (finishBooting) {
5139 mAmInternal.finishBooting();
5140 }
5141 if (enableScreen) {
5142 mInternal.enableScreenAfterBoot(isBooted());
5143 }
5144 });
5145 }
5146
5147 void setHeavyWeightProcess(ActivityRecord root) {
5148 mHeavyWeightProcess = root.app;
5149 final Message m = PooledLambda.obtainMessage(
5150 ActivityTaskManagerService::postHeavyWeightProcessNotification, this,
5151 root.app, root.intent, root.userId);
5152 mH.sendMessage(m);
5153 }
5154
5155 void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
5156 if (mHeavyWeightProcess == null || mHeavyWeightProcess != proc) {
5157 return;
5158 }
5159
5160 mHeavyWeightProcess = null;
5161 final Message m = PooledLambda.obtainMessage(
5162 ActivityTaskManagerService::cancelHeavyWeightProcessNotification, this,
5163 proc.mUserId);
5164 mH.sendMessage(m);
5165 }
5166
5167 private void cancelHeavyWeightProcessNotification(int userId) {
5168 final INotificationManager inm = NotificationManager.getService();
5169 if (inm == null) {
5170 return;
5171 }
5172 try {
5173 inm.cancelNotificationWithTag("android", null,
5174 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, userId);
5175 } catch (RuntimeException e) {
5176 Slog.w(TAG, "Error canceling notification for service", e);
5177 } catch (RemoteException e) {
5178 }
5179
5180 }
5181
5182 private void postHeavyWeightProcessNotification(
5183 WindowProcessController proc, Intent intent, int userId) {
5184 if (proc == null) {
5185 return;
5186 }
5187
5188 final INotificationManager inm = NotificationManager.getService();
5189 if (inm == null) {
5190 return;
5191 }
5192
5193 try {
5194 Context context = mContext.createPackageContext(proc.mInfo.packageName, 0);
5195 String text = mContext.getString(R.string.heavy_weight_notification,
5196 context.getApplicationInfo().loadLabel(context.getPackageManager()));
5197 Notification notification =
5198 new Notification.Builder(context,
5199 SystemNotificationChannels.HEAVY_WEIGHT_APP)
5200 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
5201 .setWhen(0)
5202 .setOngoing(true)
5203 .setTicker(text)
5204 .setColor(mContext.getColor(
5205 com.android.internal.R.color.system_notification_accent_color))
5206 .setContentTitle(text)
5207 .setContentText(
5208 mContext.getText(R.string.heavy_weight_notification_detail))
5209 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
5210 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
5211 new UserHandle(userId)))
5212 .build();
5213 try {
5214 inm.enqueueNotificationWithTag("android", "android", null,
5215 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, notification, userId);
5216 } catch (RuntimeException e) {
5217 Slog.w(TAG, "Error showing notification for heavy-weight app", e);
5218 } catch (RemoteException e) {
5219 }
5220 } catch (PackageManager.NameNotFoundException e) {
5221 Slog.w(TAG, "Unable to create context for heavy notification", e);
5222 }
5223
5224 }
5225
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07005226 IIntentSender getIntentSenderLocked(int type, String packageName, int callingUid, int userId,
5227 IBinder token, String resultWho, int requestCode, Intent[] intents,
5228 String[] resolvedTypes, int flags, Bundle bOptions) {
5229
5230 ActivityRecord activity = null;
5231 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5232 activity = ActivityRecord.isInStackLocked(token);
5233 if (activity == null) {
5234 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
5235 return null;
5236 }
5237 if (activity.finishing) {
5238 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
5239 return null;
5240 }
5241 }
5242
5243 final PendingIntentRecord rec = mPendingIntentController.getIntentSender(type, packageName,
5244 callingUid, userId, token, resultWho, requestCode, intents, resolvedTypes, flags,
5245 bOptions);
5246 final boolean noCreate = (flags & PendingIntent.FLAG_NO_CREATE) != 0;
5247 if (noCreate) {
5248 return rec;
5249 }
5250 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5251 if (activity.pendingResults == null) {
5252 activity.pendingResults = new HashSet<>();
5253 }
5254 activity.pendingResults.add(rec.ref);
5255 }
5256 return rec;
5257 }
5258
Andrii Kulian52d255c2018-07-13 11:32:19 -07005259 // TODO(b/111541062): Update app time tracking to make it aware of multiple resumed activities
Wale Ogunwalef6733932018-06-27 05:14:34 -07005260 private void startTimeTrackingFocusedActivityLocked() {
Andrii Kulian52d255c2018-07-13 11:32:19 -07005261 final ActivityRecord resumedActivity = mStackSupervisor.getTopResumedActivity();
Wale Ogunwalef6733932018-06-27 05:14:34 -07005262 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
5263 mCurAppTimeTracker.start(resumedActivity.packageName);
5264 }
5265 }
5266
5267 private void updateResumedAppTrace(@Nullable ActivityRecord resumed) {
5268 if (mTracedResumedActivity != null) {
5269 Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER,
5270 constructResumedTraceName(mTracedResumedActivity.packageName), 0);
5271 }
5272 if (resumed != null) {
5273 Trace.asyncTraceBegin(TRACE_TAG_ACTIVITY_MANAGER,
5274 constructResumedTraceName(resumed.packageName), 0);
5275 }
5276 mTracedResumedActivity = resumed;
5277 }
5278
5279 private String constructResumedTraceName(String packageName) {
5280 return "focused app: " + packageName;
5281 }
5282
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005283 /** Helper method that requests bounds from WM and applies them to stack. */
5284 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
5285 final Rect newStackBounds = new Rect();
5286 final ActivityStack stack = mStackSupervisor.getStack(stackId);
5287
5288 // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
5289 if (stack == null) {
5290 final StringWriter writer = new StringWriter();
5291 final PrintWriter printWriter = new PrintWriter(writer);
5292 mStackSupervisor.dumpDisplays(printWriter);
5293 printWriter.flush();
5294
5295 Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
5296 }
5297
5298 stack.getBoundsForNewConfiguration(newStackBounds);
5299 mStackSupervisor.resizeStackLocked(
5300 stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
5301 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
5302 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
5303 }
5304
5305 /** Applies latest configuration and/or visibility updates if needed. */
5306 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
5307 boolean kept = true;
Andrii Kulian5f750bc2018-07-17 08:57:23 -07005308 final ActivityStack mainStack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005309 // mainStack is null during startup.
5310 if (mainStack != null) {
5311 if (changes != 0 && starting == null) {
5312 // If the configuration changed, and the caller is not already
5313 // in the process of starting an activity, then find the top
5314 // activity to check if its configuration needs to change.
5315 starting = mainStack.topRunningActivityLocked();
5316 }
5317
5318 if (starting != null) {
5319 kept = starting.ensureActivityConfiguration(changes,
5320 false /* preserveWindow */);
5321 // And we need to make sure at this point that all other activities
5322 // are made visible with the correct configuration.
5323 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
5324 !PRESERVE_WINDOWS);
5325 }
5326 }
5327
5328 return kept;
5329 }
5330
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005331 void scheduleAppGcsLocked() {
5332 mH.post(() -> mAmInternal.scheduleAppGcs());
5333 }
5334
Wale Ogunwale53783742018-09-16 10:21:51 -07005335 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
5336 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
5337 }
5338
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005339 /**
5340 * Returns the PackageManager. Used by classes hosted by {@link ActivityTaskManagerService}. The
5341 * PackageManager could be unavailable at construction time and therefore needs to be accessed
5342 * on demand.
5343 */
5344 IPackageManager getPackageManager() {
5345 return AppGlobals.getPackageManager();
5346 }
5347
5348 PackageManagerInternal getPackageManagerInternalLocked() {
5349 if (mPmInternal == null) {
5350 mPmInternal = LocalServices.getService(PackageManagerInternal.class);
5351 }
5352 return mPmInternal;
5353 }
5354
Wale Ogunwale008163e2018-07-23 23:11:08 -07005355 AppWarnings getAppWarningsLocked() {
5356 return mAppWarnings;
5357 }
5358
Wale Ogunwale214f3482018-10-04 11:00:47 -07005359 Intent getHomeIntent() {
5360 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
5361 intent.setComponent(mTopComponent);
5362 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
5363 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5364 intent.addCategory(Intent.CATEGORY_HOME);
5365 }
5366 return intent;
5367 }
5368
Wale Ogunwale214f3482018-10-04 11:00:47 -07005369 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
5370 if (info == null) return null;
5371 ApplicationInfo newInfo = new ApplicationInfo(info);
5372 newInfo.initForUser(userId);
5373 return newInfo;
5374 }
5375
Wale Ogunwale9c103022018-10-18 07:44:54 -07005376 WindowProcessController getProcessController(String processName, int uid) {
Wale Ogunwale214f3482018-10-04 11:00:47 -07005377 if (uid == SYSTEM_UID) {
5378 // The system gets to run in any process. If there are multiple processes with the same
5379 // uid, just pick the first (this should never happen).
5380 final SparseArray<WindowProcessController> procs =
5381 mProcessNames.getMap().get(processName);
5382 if (procs == null) return null;
5383 final int procCount = procs.size();
5384 for (int i = 0; i < procCount; i++) {
5385 final int procUid = procs.keyAt(i);
5386 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
5387 // Don't use an app process or different user process for system component.
5388 continue;
5389 }
5390 return procs.valueAt(i);
5391 }
5392 }
5393
5394 return mProcessNames.get(processName, uid);
5395 }
5396
Wale Ogunwale342fbe92018-10-09 08:44:10 -07005397 WindowProcessController getProcessController(IApplicationThread thread) {
5398 if (thread == null) {
5399 return null;
5400 }
5401
5402 final IBinder threadBinder = thread.asBinder();
5403 final ArrayMap<String, SparseArray<WindowProcessController>> pmap = mProcessNames.getMap();
5404 for (int i = pmap.size()-1; i >= 0; i--) {
5405 final SparseArray<WindowProcessController> procs = pmap.valueAt(i);
5406 for (int j = procs.size() - 1; j >= 0; j--) {
5407 final WindowProcessController proc = procs.valueAt(j);
5408 if (proc.hasThread() && proc.getThread().asBinder() == threadBinder) {
5409 return proc;
5410 }
5411 }
5412 }
5413
5414 return null;
5415 }
5416
Wale Ogunwalebff2df42018-10-18 17:09:19 -07005417 int getUidStateLocked(int uid) {
5418 return mActiveUids.get(uid, PROCESS_STATE_NONEXISTENT);
5419 }
5420
Wale Ogunwale9de19442018-10-18 19:05:03 -07005421 /**
5422 * @return whitelist tag for a uid from mPendingTempWhitelist, null if not currently on
5423 * the whitelist
5424 */
5425 String getPendingTempWhitelistTagForUidLocked(int uid) {
5426 return mPendingTempWhitelist.get(uid);
5427 }
5428
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005429 void logAppTooSlow(WindowProcessController app, long startTime, String msg) {
5430 if (true || Build.IS_USER) {
5431 return;
5432 }
5433
5434 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5435 StrictMode.allowThreadDiskWrites();
5436 try {
5437 File tracesDir = new File("/data/anr");
5438 File tracesFile = null;
5439 try {
5440 tracesFile = File.createTempFile("app_slow", null, tracesDir);
5441
5442 StringBuilder sb = new StringBuilder();
5443 Time tobj = new Time();
5444 tobj.set(System.currentTimeMillis());
5445 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5446 sb.append(": ");
5447 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5448 sb.append(" since ");
5449 sb.append(msg);
5450 FileOutputStream fos = new FileOutputStream(tracesFile);
5451 fos.write(sb.toString().getBytes());
5452 if (app == null) {
5453 fos.write("\n*** No application process!".getBytes());
5454 }
5455 fos.close();
5456 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5457 } catch (IOException e) {
5458 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesFile, e);
5459 return;
5460 }
5461
5462 if (app != null && app.getPid() > 0) {
5463 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5464 firstPids.add(app.getPid());
5465 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, null, null);
5466 }
5467
5468 File lastTracesFile = null;
5469 File curTracesFile = null;
5470 for (int i=9; i>=0; i--) {
5471 String name = String.format(Locale.US, "slow%02d.txt", i);
5472 curTracesFile = new File(tracesDir, name);
5473 if (curTracesFile.exists()) {
5474 if (lastTracesFile != null) {
5475 curTracesFile.renameTo(lastTracesFile);
5476 } else {
5477 curTracesFile.delete();
5478 }
5479 }
5480 lastTracesFile = curTracesFile;
5481 }
5482 tracesFile.renameTo(curTracesFile);
5483 } finally {
5484 StrictMode.setThreadPolicy(oldPolicy);
5485 }
5486 }
5487
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005488 final class H extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005489 static final int REPORT_TIME_TRACKER_MSG = 1;
Wale Ogunwale98875612018-10-12 07:53:02 -07005490 static final int FIRST_ACTIVITY_STACK_MSG = 100;
5491 static final int FIRST_SUPERVISOR_STACK_MSG = 200;
Wale Ogunwalef6733932018-06-27 05:14:34 -07005492
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005493 public H(Looper looper) {
5494 super(looper, null, true);
5495 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005496
5497 @Override
5498 public void handleMessage(Message msg) {
5499 switch (msg.what) {
5500 case REPORT_TIME_TRACKER_MSG: {
5501 AppTimeTracker tracker = (AppTimeTracker) msg.obj;
5502 tracker.deliverResult(mContext);
5503 } break;
5504 }
5505 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005506 }
5507
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005508 final class UiHandler extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005509 static final int DISMISS_DIALOG_UI_MSG = 1;
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005510
5511 public UiHandler() {
5512 super(com.android.server.UiThread.get().getLooper(), null, true);
5513 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005514
5515 @Override
5516 public void handleMessage(Message msg) {
5517 switch (msg.what) {
5518 case DISMISS_DIALOG_UI_MSG: {
5519 final Dialog d = (Dialog) msg.obj;
5520 d.dismiss();
5521 break;
5522 }
5523 }
5524 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005525 }
5526
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005527 final class LocalService extends ActivityTaskManagerInternal {
5528 @Override
5529 public SleepToken acquireSleepToken(String tag, int displayId) {
5530 Preconditions.checkNotNull(tag);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005531 return ActivityTaskManagerService.this.acquireSleepToken(tag, displayId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005532 }
5533
5534 @Override
5535 public ComponentName getHomeActivityForUser(int userId) {
5536 synchronized (mGlobalLock) {
Louis Changbd48dca2018-08-29 17:44:34 +08005537 ActivityRecord homeActivity =
5538 mStackSupervisor.getDefaultDisplayHomeActivityForUser(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005539 return homeActivity == null ? null : homeActivity.realActivity;
5540 }
5541 }
5542
5543 @Override
5544 public void onLocalVoiceInteractionStarted(IBinder activity,
5545 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
5546 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005547 onLocalVoiceInteractionStartedLocked(activity, voiceSession, voiceInteractor);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005548 }
5549 }
5550
5551 @Override
5552 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
5553 synchronized (mGlobalLock) {
5554 mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
5555 reasons, timestamp);
5556 }
5557 }
5558
5559 @Override
5560 public void notifyAppTransitionFinished() {
5561 synchronized (mGlobalLock) {
5562 mStackSupervisor.notifyAppTransitionDone();
5563 }
5564 }
5565
5566 @Override
5567 public void notifyAppTransitionCancelled() {
5568 synchronized (mGlobalLock) {
5569 mStackSupervisor.notifyAppTransitionDone();
5570 }
5571 }
5572
5573 @Override
5574 public List<IBinder> getTopVisibleActivities() {
5575 synchronized (mGlobalLock) {
5576 return mStackSupervisor.getTopVisibleActivities();
5577 }
5578 }
5579
5580 @Override
5581 public void notifyDockedStackMinimizedChanged(boolean minimized) {
5582 synchronized (mGlobalLock) {
5583 mStackSupervisor.setDockedStackMinimized(minimized);
5584 }
5585 }
5586
5587 @Override
5588 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
5589 Bundle bOptions) {
5590 Preconditions.checkNotNull(intents, "intents");
5591 final String[] resolvedTypes = new String[intents.length];
5592
5593 // UID of the package on user userId.
5594 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
5595 // packageUid may not be initialized.
5596 int packageUid = 0;
5597 final long ident = Binder.clearCallingIdentity();
5598
5599 try {
5600 for (int i = 0; i < intents.length; i++) {
5601 resolvedTypes[i] =
5602 intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
5603 }
5604
5605 packageUid = AppGlobals.getPackageManager().getPackageUid(
5606 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
5607 } catch (RemoteException e) {
5608 // Shouldn't happen.
5609 } finally {
5610 Binder.restoreCallingIdentity(ident);
5611 }
5612
5613 synchronized (mGlobalLock) {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07005614 return getActivityStartController().startActivitiesInPackage(
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005615 packageUid, packageName,
5616 intents, resolvedTypes, null /* resultTo */,
5617 SafeActivityOptions.fromBundle(bOptions), userId,
Michal Karpinski201bc0c2018-07-20 15:32:00 +01005618 false /* validateIncomingUser */, null /* originatingPendingIntent */);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005619 }
5620 }
5621
5622 @Override
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07005623 public int startActivitiesInPackage(int uid, String callingPackage, Intent[] intents,
5624 String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, int userId,
5625 boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent) {
5626 synchronized (mGlobalLock) {
5627 return getActivityStartController().startActivitiesInPackage(uid, callingPackage,
5628 intents, resolvedTypes, resultTo, options, userId, validateIncomingUser,
5629 originatingPendingIntent);
5630 }
5631 }
5632
5633 @Override
5634 public int startActivityInPackage(int uid, int realCallingPid, int realCallingUid,
5635 String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
5636 String resultWho, int requestCode, int startFlags, SafeActivityOptions options,
5637 int userId, TaskRecord inTask, String reason, boolean validateIncomingUser,
5638 PendingIntentRecord originatingPendingIntent) {
5639 synchronized (mGlobalLock) {
5640 return getActivityStartController().startActivityInPackage(uid, realCallingPid,
5641 realCallingUid, callingPackage, intent, resolvedType, resultTo, resultWho,
5642 requestCode, startFlags, options, userId, inTask, reason,
5643 validateIncomingUser, originatingPendingIntent);
5644 }
5645 }
5646
5647 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005648 public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
5649 Intent intent, Bundle options, int userId) {
5650 return ActivityTaskManagerService.this.startActivityAsUser(
5651 caller, callerPacakge, intent,
5652 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
5653 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
5654 false /*validateIncomingUser*/);
5655 }
5656
5657 @Override
lumark588a3e82018-07-20 18:53:54 +08005658 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback, int displayId) {
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005659 synchronized (mGlobalLock) {
5660
5661 // We might change the visibilities here, so prepare an empty app transition which
5662 // might be overridden later if we actually change visibilities.
lumark588a3e82018-07-20 18:53:54 +08005663 final DisplayWindowController dwc = mStackSupervisor.getActivityDisplay(displayId)
5664 .getWindowContainerController();
5665 final boolean wasTransitionSet = dwc.getPendingAppTransition() != TRANSIT_NONE;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005666 if (!wasTransitionSet) {
lumark588a3e82018-07-20 18:53:54 +08005667 dwc.prepareAppTransition(TRANSIT_NONE, false /* alwaysKeepCurrent */);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005668 }
5669 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5670
5671 // If there was a transition set already we don't want to interfere with it as we
5672 // might be starting it too early.
5673 if (!wasTransitionSet) {
lumark588a3e82018-07-20 18:53:54 +08005674 dwc.executeAppTransition();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005675 }
5676 }
5677 if (callback != null) {
5678 callback.run();
5679 }
5680 }
5681
5682 @Override
5683 public void notifyKeyguardTrustedChanged() {
5684 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005685 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005686 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5687 }
5688 }
5689 }
5690
5691 /**
5692 * Called after virtual display Id is updated by
5693 * {@link com.android.server.vr.Vr2dDisplay} with a specific
5694 * {@param vrVr2dDisplayId}.
5695 */
5696 @Override
5697 public void setVr2dDisplayId(int vr2dDisplayId) {
5698 if (DEBUG_STACK) Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
5699 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005700 mVr2dDisplayId = vr2dDisplayId;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005701 }
5702 }
5703
5704 @Override
5705 public void setFocusedActivity(IBinder token) {
5706 synchronized (mGlobalLock) {
5707 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
5708 if (r == null) {
5709 throw new IllegalArgumentException(
5710 "setFocusedActivity: No activity record matching token=" + token);
5711 }
Louis Chang19443452018-10-09 12:10:21 +08005712 if (r.moveFocusableActivityToTop("setFocusedActivity")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08005713 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005714 }
5715 }
5716 }
5717
5718 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005719 public void registerScreenObserver(ScreenObserver observer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005720 mScreenObservers.add(observer);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005721 }
5722
5723 @Override
5724 public boolean isCallerRecents(int callingUid) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005725 return getRecentTasks().isCallerRecents(callingUid);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005726 }
5727
5728 @Override
5729 public boolean isRecentsComponentHomeActivity(int userId) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005730 return getRecentTasks().isRecentsComponentHomeActivity(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005731 }
5732
5733 @Override
5734 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
5735 ActivityTaskManagerService.this.cancelRecentsAnimation(restoreHomeStackPosition);
5736 }
5737
5738 @Override
5739 public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005740 ActivityTaskManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005741 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005742
5743 @Override
5744 public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
5745 synchronized (mGlobalLock) {
5746 mActiveVoiceInteractionServiceComponent = component;
5747 }
5748 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005749
5750 @Override
5751 public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
5752 if (!mAmInternal.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
5753 return;
5754 }
5755 synchronized (mGlobalLock) {
5756 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
5757 if (types == null) {
5758 if (uid < 0) {
5759 return;
5760 }
5761 types = new ArrayMap<>();
5762 mAllowAppSwitchUids.put(userId, types);
5763 }
5764 if (uid < 0) {
5765 types.remove(type);
5766 } else {
5767 types.put(type, uid);
5768 }
5769 }
5770 }
5771
5772 @Override
5773 public void onUserStopped(int userId) {
5774 synchronized (mGlobalLock) {
5775 getRecentTasks().unloadUserDataFromMemoryLocked(userId);
5776 mAllowAppSwitchUids.remove(userId);
5777 }
5778 }
5779
5780 @Override
5781 public boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
5782 synchronized (mGlobalLock) {
5783 return ActivityTaskManagerService.this.isGetTasksAllowed(
5784 caller, callingPid, callingUid);
5785 }
5786 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005787
5788 @Override
5789 public void onProcessAdded(WindowProcessController proc) {
5790 synchronized (mGlobalLock) {
5791 mProcessNames.put(proc.mName, proc.mUid, proc);
5792 }
5793 }
5794
5795 @Override
5796 public void onProcessRemoved(String name, int uid) {
5797 synchronized (mGlobalLock) {
5798 mProcessNames.remove(name, uid);
5799 }
5800 }
5801
5802 @Override
5803 public void onCleanUpApplicationRecord(WindowProcessController proc) {
5804 synchronized (mGlobalLock) {
5805 if (proc == mHomeProcess) {
5806 mHomeProcess = null;
5807 }
5808 if (proc == mPreviousProcess) {
5809 mPreviousProcess = null;
5810 }
5811 }
5812 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005813
5814 @Override
5815 public int getTopProcessState() {
5816 synchronized (mGlobalLock) {
5817 return mTopProcessState;
5818 }
5819 }
5820
5821 @Override
Wale Ogunwale53783742018-09-16 10:21:51 -07005822 public boolean isHeavyWeightProcess(WindowProcessController proc) {
5823 synchronized (mGlobalLock) {
5824 return proc == mHeavyWeightProcess;
5825 }
5826 }
5827
5828 @Override
5829 public void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
5830 synchronized (mGlobalLock) {
5831 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(proc);
5832 }
5833 }
5834
5835 @Override
5836 public void finishHeavyWeightApp() {
5837 synchronized (mGlobalLock) {
Sudheer Shankaee1da272018-10-20 20:11:44 -07005838 if (mHeavyWeightProcess != null) {
5839 mHeavyWeightProcess.finishActivities();
5840 }
Wale Ogunwale53783742018-09-16 10:21:51 -07005841 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(
5842 mHeavyWeightProcess);
5843 }
5844 }
5845
5846 @Override
Wale Ogunwalef6733932018-06-27 05:14:34 -07005847 public boolean isSleeping() {
5848 synchronized (mGlobalLock) {
5849 return isSleepingLocked();
5850 }
5851 }
5852
5853 @Override
5854 public boolean isShuttingDown() {
5855 synchronized (mGlobalLock) {
5856 return mShuttingDown;
5857 }
5858 }
5859
5860 @Override
5861 public boolean shuttingDown(boolean booted, int timeout) {
5862 synchronized (mGlobalLock) {
5863 mShuttingDown = true;
5864 mStackSupervisor.prepareForShutdownLocked();
5865 updateEventDispatchingLocked(booted);
Wale Ogunwaled4d67d02018-10-25 18:09:39 -07005866 notifyTaskPersisterLocked(null, true);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005867 return mStackSupervisor.shutdownLocked(timeout);
5868 }
5869 }
5870
5871 @Override
5872 public void enableScreenAfterBoot(boolean booted) {
5873 synchronized (mGlobalLock) {
5874 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5875 SystemClock.uptimeMillis());
5876 mWindowManager.enableScreenAfterBoot();
5877 updateEventDispatchingLocked(booted);
5878 }
5879 }
5880
5881 @Override
5882 public boolean showStrictModeViolationDialog() {
5883 synchronized (mGlobalLock) {
5884 return mShowDialogs && !mSleeping && !mShuttingDown;
5885 }
5886 }
5887
5888 @Override
5889 public void showSystemReadyErrorDialogsIfNeeded() {
5890 synchronized (mGlobalLock) {
5891 try {
5892 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
5893 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
5894 + " data partition or your device will be unstable.");
5895 mUiHandler.post(() -> {
5896 if (mShowDialogs) {
5897 AlertDialog d = new BaseErrorDialog(mUiContext);
5898 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5899 d.setCancelable(false);
5900 d.setTitle(mUiContext.getText(R.string.android_system_label));
5901 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
5902 d.setButton(DialogInterface.BUTTON_POSITIVE,
5903 mUiContext.getText(R.string.ok),
5904 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5905 d.show();
5906 }
5907 });
5908 }
5909 } catch (RemoteException e) {
5910 }
5911
5912 if (!Build.isBuildConsistent()) {
5913 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
5914 mUiHandler.post(() -> {
5915 if (mShowDialogs) {
5916 AlertDialog d = new BaseErrorDialog(mUiContext);
5917 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5918 d.setCancelable(false);
5919 d.setTitle(mUiContext.getText(R.string.android_system_label));
5920 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
5921 d.setButton(DialogInterface.BUTTON_POSITIVE,
5922 mUiContext.getText(R.string.ok),
5923 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5924 d.show();
5925 }
5926 });
5927 }
5928 }
5929 }
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005930
5931 @Override
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005932 public void onProcessMapped(int pid, WindowProcessController proc) {
5933 synchronized (mGlobalLock) {
5934 mPidMap.put(pid, proc);
5935 }
5936 }
5937
5938 @Override
5939 public void onProcessUnMapped(int pid) {
5940 synchronized (mGlobalLock) {
5941 mPidMap.remove(pid);
5942 }
5943 }
Wale Ogunwale008163e2018-07-23 23:11:08 -07005944
5945 @Override
5946 public void onPackageDataCleared(String name) {
5947 synchronized (mGlobalLock) {
Wale Ogunwale53783742018-09-16 10:21:51 -07005948 mCompatModePackages.handlePackageDataClearedLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07005949 mAppWarnings.onPackageDataCleared(name);
5950 }
5951 }
5952
5953 @Override
5954 public void onPackageUninstalled(String name) {
5955 synchronized (mGlobalLock) {
5956 mAppWarnings.onPackageUninstalled(name);
Wale Ogunwale53783742018-09-16 10:21:51 -07005957 mCompatModePackages.handlePackageUninstalledLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07005958 }
5959 }
Wale Ogunwale53783742018-09-16 10:21:51 -07005960
5961 @Override
5962 public void onPackageAdded(String name, boolean replacing) {
5963 synchronized (mGlobalLock) {
5964 mCompatModePackages.handlePackageAddedLocked(name, replacing);
5965 }
5966 }
5967
5968 @Override
Wale Ogunwale31913b52018-10-13 08:29:31 -07005969 public void onPackageReplaced(ApplicationInfo aInfo) {
5970 synchronized (mGlobalLock) {
5971 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
5972 }
5973 }
5974
5975 @Override
Wale Ogunwale53783742018-09-16 10:21:51 -07005976 public CompatibilityInfo compatibilityInfoForPackage(ApplicationInfo ai) {
5977 synchronized (mGlobalLock) {
5978 return compatibilityInfoForPackageLocked(ai);
5979 }
5980 }
5981
Yunfan Chen75157d72018-07-27 14:47:21 +09005982 /**
5983 * Set the corresponding display information for the process global configuration. To be
5984 * called when we need to show IME on a different display.
5985 *
5986 * @param pid The process id associated with the IME window.
5987 * @param displayId The ID of the display showing the IME.
5988 */
5989 @Override
Yunfan Chen79b96062018-10-17 12:45:23 -07005990 public void onImeWindowSetOnDisplay(final int pid, final int displayId) {
Yunfan Chen75157d72018-07-27 14:47:21 +09005991 if (pid == MY_PID || pid < 0) {
5992 if (DEBUG_CONFIGURATION) {
5993 Slog.w(TAG,
5994 "Trying to update display configuration for system/invalid process.");
5995 }
5996 return;
5997 }
5998 mH.post(() -> {
5999 synchronized (mGlobalLock) {
Yunfan Chen79b96062018-10-17 12:45:23 -07006000 final ActivityDisplay activityDisplay =
6001 mStackSupervisor.getActivityDisplay(displayId);
6002 if (activityDisplay == null) {
6003 // Call might come when display is not yet added or has been removed.
Yunfan Chen75157d72018-07-27 14:47:21 +09006004 if (DEBUG_CONFIGURATION) {
6005 Slog.w(TAG, "Trying to update display configuration for non-existing "
Yunfan Chen79b96062018-10-17 12:45:23 -07006006 + "displayId=" + displayId);
Yunfan Chen75157d72018-07-27 14:47:21 +09006007 }
6008 return;
6009 }
Yunfan Chen79b96062018-10-17 12:45:23 -07006010 final WindowProcessController process = mPidMap.get(pid);
6011 if (process == null) {
Yunfan Chen75157d72018-07-27 14:47:21 +09006012 if (DEBUG_CONFIGURATION) {
Yunfan Chen79b96062018-10-17 12:45:23 -07006013 Slog.w(TAG, "Trying to update display configuration for invalid "
6014 + "process, pid=" + pid);
Yunfan Chen75157d72018-07-27 14:47:21 +09006015 }
6016 return;
6017 }
Yunfan Chen79b96062018-10-17 12:45:23 -07006018 process.registerDisplayConfigurationListenerLocked(activityDisplay);
Yunfan Chen75157d72018-07-27 14:47:21 +09006019 }
6020 });
Yunfan Chen79b96062018-10-17 12:45:23 -07006021
Yunfan Chen75157d72018-07-27 14:47:21 +09006022 }
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07006023
6024 @Override
6025 public void sendActivityResult(int callingUid, IBinder activityToken, String resultWho,
6026 int requestCode, int resultCode, Intent data) {
6027 synchronized (mGlobalLock) {
6028 final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
6029 if (r != null && r.getStack() != null) {
6030 r.getStack().sendActivityResultLocked(callingUid, r, resultWho, requestCode,
6031 resultCode, data);
6032 }
6033 }
6034 }
6035
6036 @Override
6037 public void clearPendingResultForActivity(IBinder activityToken,
6038 WeakReference<PendingIntentRecord> pir) {
6039 synchronized (mGlobalLock) {
6040 final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
6041 if (r != null && r.pendingResults != null) {
6042 r.pendingResults.remove(pir);
6043 }
6044 }
6045 }
6046
6047 @Override
6048 public IIntentSender getIntentSender(int type, String packageName,
6049 int callingUid, int userId, IBinder token, String resultWho,
6050 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6051 Bundle bOptions) {
6052 synchronized (mGlobalLock) {
6053 return getIntentSenderLocked(type, packageName, callingUid, userId, token,
6054 resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6055 }
6056 }
Wale Ogunwalec4e63a42018-10-02 13:19:54 -07006057
6058 @Override
6059 public ActivityServiceConnectionsHolder getServiceConnectionsHolder(IBinder token) {
6060 synchronized (mGlobalLock) {
6061 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
6062 if (r == null) {
6063 return null;
6064 }
6065 if (r.mServiceConnectionsHolder == null) {
6066 r.mServiceConnectionsHolder = new ActivityServiceConnectionsHolder(
6067 ActivityTaskManagerService.this, r);
6068 }
6069
6070 return r.mServiceConnectionsHolder;
6071 }
6072 }
Wale Ogunwale214f3482018-10-04 11:00:47 -07006073
6074 @Override
6075 public Intent getHomeIntent() {
6076 synchronized (mGlobalLock) {
6077 return ActivityTaskManagerService.this.getHomeIntent();
6078 }
6079 }
6080
6081 @Override
6082 public boolean startHomeActivity(int userId, String reason) {
6083 synchronized (mGlobalLock) {
Louis Chang89f43fc2018-10-05 10:59:14 +08006084 return mStackSupervisor.startHomeOnDisplay(userId, reason, DEFAULT_DISPLAY);
6085 }
6086 }
6087
6088 @Override
6089 public boolean startHomeOnAllDisplays(int userId, String reason) {
6090 synchronized (mGlobalLock) {
6091 return mStackSupervisor.startHomeOnAllDisplays(userId, reason);
Wale Ogunwale214f3482018-10-04 11:00:47 -07006092 }
6093 }
6094
6095 @Override
6096 public boolean isFactoryTestProcess(WindowProcessController wpc) {
6097 synchronized (mGlobalLock) {
6098 if (mFactoryTest == FACTORY_TEST_OFF) {
6099 return false;
6100 }
6101 if (mFactoryTest == FACTORY_TEST_LOW_LEVEL && mTopComponent != null
6102 && wpc.mName.equals(mTopComponent.getPackageName())) {
6103 return true;
6104 }
6105 return mFactoryTest == FACTORY_TEST_HIGH_LEVEL
6106 && (wpc.mInfo.flags & FLAG_FACTORY_TEST) != 0;
6107 }
6108 }
6109
6110 @Override
6111 public void updateTopComponentForFactoryTest() {
6112 synchronized (mGlobalLock) {
6113 if (mFactoryTest != FACTORY_TEST_LOW_LEVEL) {
6114 return;
6115 }
6116 final ResolveInfo ri = mContext.getPackageManager()
6117 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), STOCK_PM_FLAGS);
6118 final CharSequence errorMsg;
6119 if (ri != null) {
6120 final ActivityInfo ai = ri.activityInfo;
6121 final ApplicationInfo app = ai.applicationInfo;
6122 if ((app.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
6123 mTopAction = Intent.ACTION_FACTORY_TEST;
6124 mTopData = null;
6125 mTopComponent = new ComponentName(app.packageName, ai.name);
6126 errorMsg = null;
6127 } else {
6128 errorMsg = mContext.getResources().getText(
6129 com.android.internal.R.string.factorytest_not_system);
6130 }
6131 } else {
6132 errorMsg = mContext.getResources().getText(
6133 com.android.internal.R.string.factorytest_no_action);
6134 }
6135 if (errorMsg == null) {
6136 return;
6137 }
6138
6139 mTopAction = null;
6140 mTopData = null;
6141 mTopComponent = null;
6142 mUiHandler.post(() -> {
6143 Dialog d = new FactoryErrorDialog(mUiContext, errorMsg);
6144 d.show();
Wale Ogunwale342fbe92018-10-09 08:44:10 -07006145 mAmInternal.ensureBootCompleted();
Wale Ogunwale214f3482018-10-04 11:00:47 -07006146 });
6147 }
6148 }
Wale Ogunwale31913b52018-10-13 08:29:31 -07006149
6150 @Override
6151 public void handleAppDied(WindowProcessController wpc, boolean restarting,
6152 Runnable finishInstrumentationCallback) {
6153 synchronized (mGlobalLock) {
6154 // Remove this application's activities from active lists.
6155 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(wpc);
6156
6157 wpc.clearRecentTasks();
6158 wpc.clearActivities();
6159
6160 if (wpc.isInstrumenting()) {
6161 finishInstrumentationCallback.run();
6162 }
6163
6164 mWindowManager.deferSurfaceLayout();
6165 try {
6166 if (!restarting && hasVisibleActivities
6167 && !mStackSupervisor.resumeFocusedStacksTopActivitiesLocked()) {
6168 // If there was nothing to resume, and we are not already restarting this
6169 // process, but there is a visible activity that is hosted by the process...
6170 // then make sure all visible activities are running, taking care of
6171 // restarting this process.
6172 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6173 }
6174 } finally {
6175 mWindowManager.continueSurfaceLayout();
6176 }
6177 }
6178 }
6179
6180 @Override
6181 public void closeSystemDialogs(String reason) {
6182 enforceNotIsolatedCaller("closeSystemDialogs");
6183
6184 final int pid = Binder.getCallingPid();
6185 final int uid = Binder.getCallingUid();
6186 final long origId = Binder.clearCallingIdentity();
6187 try {
6188 synchronized (mGlobalLock) {
6189 // Only allow this from foreground processes, so that background
6190 // applications can't abuse it to prevent system UI from being shown.
6191 if (uid >= FIRST_APPLICATION_UID) {
6192 final WindowProcessController proc = mPidMap.get(pid);
6193 if (!proc.isPerceptible()) {
6194 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6195 + " from background process " + proc);
6196 return;
6197 }
6198 }
Wale Ogunwale31913b52018-10-13 08:29:31 -07006199 mWindowManager.closeSystemDialogs(reason);
6200
6201 mStackSupervisor.closeSystemDialogsLocked();
Wale Ogunwale31913b52018-10-13 08:29:31 -07006202 }
Wale Ogunwale2ea36d42018-10-18 10:27:31 -07006203 // Call into AM outside the synchronized block.
6204 mAmInternal.broadcastCloseSystemDialogs(reason);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006205 } finally {
6206 Binder.restoreCallingIdentity(origId);
6207 }
6208 }
6209
6210 @Override
6211 public void cleanupDisabledPackageComponents(
6212 String packageName, Set<String> disabledClasses, int userId, boolean booted) {
6213 synchronized (mGlobalLock) {
6214 // Clean-up disabled activities.
6215 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6216 packageName, disabledClasses, true, false, userId) && booted) {
6217 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
6218 mStackSupervisor.scheduleIdleLocked();
6219 }
6220
6221 // Clean-up disabled tasks
6222 getRecentTasks().cleanupDisabledPackageTasksLocked(
6223 packageName, disabledClasses, userId);
6224 }
6225 }
6226
6227 @Override
6228 public boolean onForceStopPackage(String packageName, boolean doit, boolean evenPersistent,
6229 int userId) {
6230 synchronized (mGlobalLock) {
6231
6232 boolean didSomething =
6233 getActivityStartController().clearPendingActivityLaunches(packageName);
6234 didSomething |= mStackSupervisor.finishDisabledPackageActivitiesLocked(packageName,
6235 null, doit, evenPersistent, userId);
6236 return didSomething;
6237 }
6238 }
6239
6240 @Override
6241 public void resumeTopActivities(boolean scheduleIdle) {
6242 synchronized (mGlobalLock) {
6243 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
6244 if (scheduleIdle) {
6245 mStackSupervisor.scheduleIdleLocked();
6246 }
6247 }
6248 }
6249
6250 @Override
6251 public void preBindApplication(WindowProcessController wpc) {
6252 synchronized (mGlobalLock) {
6253 mStackSupervisor.getActivityMetricsLogger().notifyBindApplication(wpc.mInfo);
6254 }
6255 }
6256
6257 @Override
6258 public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
6259 synchronized (mGlobalLock) {
6260 return mStackSupervisor.attachApplicationLocked(wpc);
6261 }
6262 }
6263
6264 @Override
6265 public void notifyLockedProfile(@UserIdInt int userId, int currentUserId) {
6266 try {
6267 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
6268 throw new SecurityException("Only privileged app can call notifyLockedProfile");
6269 }
6270 } catch (RemoteException ex) {
6271 throw new SecurityException("Fail to check is caller a privileged app", ex);
6272 }
6273
6274 synchronized (mGlobalLock) {
6275 final long ident = Binder.clearCallingIdentity();
6276 try {
6277 if (mAmInternal.shouldConfirmCredentials(userId)) {
6278 if (mKeyguardController.isKeyguardLocked()) {
6279 // Showing launcher to avoid user entering credential twice.
6280 startHomeActivity(currentUserId, "notifyLockedProfile");
6281 }
6282 mStackSupervisor.lockAllProfileTasks(userId);
6283 }
6284 } finally {
6285 Binder.restoreCallingIdentity(ident);
6286 }
6287 }
6288 }
6289
6290 @Override
6291 public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
6292 mAmInternal.enforceCallingPermission(
6293 MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
6294
6295 synchronized (mGlobalLock) {
6296 final long ident = Binder.clearCallingIdentity();
6297 try {
6298 intent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
6299 FLAG_ACTIVITY_TASK_ON_HOME);
6300 ActivityOptions activityOptions = options != null
6301 ? new ActivityOptions(options) : ActivityOptions.makeBasic();
6302 activityOptions.setLaunchTaskId(
6303 mStackSupervisor.getDefaultDisplayHomeActivity().getTask().taskId);
6304 mContext.startActivityAsUser(intent, activityOptions.toBundle(),
6305 UserHandle.CURRENT);
6306 } finally {
6307 Binder.restoreCallingIdentity(ident);
6308 }
6309 }
6310 }
6311
6312 @Override
6313 public void writeActivitiesToProto(ProtoOutputStream proto) {
6314 synchronized (mGlobalLock) {
6315 // The output proto of "activity --proto activities"
6316 // is ActivityManagerServiceDumpActivitiesProto
6317 mStackSupervisor.writeToProto(proto,
6318 ActivityManagerServiceDumpActivitiesProto.ACTIVITY_STACK_SUPERVISOR);
6319 }
6320 }
6321
6322 @Override
6323 public void saveANRState(String reason) {
6324 synchronized (mGlobalLock) {
6325 final StringWriter sw = new StringWriter();
6326 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
6327 pw.println(" ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
6328 if (reason != null) {
6329 pw.println(" Reason: " + reason);
6330 }
6331 pw.println();
6332 getActivityStartController().dump(pw, " ", null);
6333 pw.println();
6334 pw.println("-------------------------------------------------------------------------------");
6335 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
6336 true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
6337 "" /* header */);
6338 pw.println();
6339 pw.close();
6340
6341 mLastANRState = sw.toString();
6342 }
6343 }
6344
6345 @Override
6346 public void clearSavedANRState() {
6347 synchronized (mGlobalLock) {
6348 mLastANRState = null;
6349 }
6350 }
6351
6352 @Override
6353 public void dump(String cmd, FileDescriptor fd, PrintWriter pw, String[] args, int opti,
6354 boolean dumpAll, boolean dumpClient, String dumpPackage) {
6355 synchronized (mGlobalLock) {
6356 if (DUMP_ACTIVITIES_CMD.equals(cmd) || DUMP_ACTIVITIES_SHORT_CMD.equals(cmd)) {
6357 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
6358 } else if (DUMP_LASTANR_CMD.equals(cmd)) {
6359 dumpLastANRLocked(pw);
6360 } else if (DUMP_LASTANR_TRACES_CMD.equals(cmd)) {
6361 dumpLastANRTracesLocked(pw);
6362 } else if (DUMP_STARTER_CMD.equals(cmd)) {
6363 dumpActivityStarterLocked(pw, dumpPackage);
6364 } else if (DUMP_CONTAINERS_CMD.equals(cmd)) {
6365 dumpActivityContainersLocked(pw);
6366 } else if (DUMP_RECENTS_CMD.equals(cmd) || DUMP_RECENTS_SHORT_CMD.equals(cmd)) {
6367 if (getRecentTasks() != null) {
6368 getRecentTasks().dump(pw, dumpAll, dumpPackage);
6369 }
6370 }
6371 }
6372 }
6373
6374 @Override
6375 public boolean dumpForProcesses(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
6376 String dumpPackage, int dumpAppId, boolean needSep, boolean testPssMode,
6377 int wakefulness) {
6378 synchronized (mGlobalLock) {
6379 if (mHomeProcess != null && (dumpPackage == null
6380 || mHomeProcess.mPkgList.contains(dumpPackage))) {
6381 if (needSep) {
6382 pw.println();
6383 needSep = false;
6384 }
6385 pw.println(" mHomeProcess: " + mHomeProcess);
6386 }
6387 if (mPreviousProcess != null && (dumpPackage == null
6388 || mPreviousProcess.mPkgList.contains(dumpPackage))) {
6389 if (needSep) {
6390 pw.println();
6391 needSep = false;
6392 }
6393 pw.println(" mPreviousProcess: " + mPreviousProcess);
6394 }
6395 if (dumpAll && (mPreviousProcess == null || dumpPackage == null
6396 || mPreviousProcess.mPkgList.contains(dumpPackage))) {
6397 StringBuilder sb = new StringBuilder(128);
6398 sb.append(" mPreviousProcessVisibleTime: ");
6399 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
6400 pw.println(sb);
6401 }
6402 if (mHeavyWeightProcess != null && (dumpPackage == null
6403 || mHeavyWeightProcess.mPkgList.contains(dumpPackage))) {
6404 if (needSep) {
6405 pw.println();
6406 needSep = false;
6407 }
6408 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
6409 }
6410 if (dumpPackage == null) {
6411 pw.println(" mGlobalConfiguration: " + getGlobalConfiguration());
6412 mStackSupervisor.dumpDisplayConfigs(pw, " ");
6413 }
6414 if (dumpAll) {
6415 if (dumpPackage == null) {
6416 pw.println(" mConfigWillChange: "
6417 + getTopDisplayFocusedStack().mConfigWillChange);
6418 }
6419 if (mCompatModePackages.getPackages().size() > 0) {
6420 boolean printed = false;
6421 for (Map.Entry<String, Integer> entry
6422 : mCompatModePackages.getPackages().entrySet()) {
6423 String pkg = entry.getKey();
6424 int mode = entry.getValue();
6425 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
6426 continue;
6427 }
6428 if (!printed) {
6429 pw.println(" mScreenCompatPackages:");
6430 printed = true;
6431 }
6432 pw.println(" " + pkg + ": " + mode);
6433 }
6434 }
6435 }
6436
6437 if (dumpPackage == null) {
6438 pw.println(" mWakefulness="
6439 + PowerManagerInternal.wakefulnessToString(wakefulness));
6440 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
6441 if (mRunningVoice != null) {
6442 pw.println(" mRunningVoice=" + mRunningVoice);
6443 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
6444 }
6445 pw.println(" mSleeping=" + mSleeping);
6446 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + testPssMode);
6447 pw.println(" mVrController=" + mVrController);
6448 }
6449 if (mCurAppTimeTracker != null) {
6450 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
6451 }
6452 if (mAllowAppSwitchUids.size() > 0) {
6453 boolean printed = false;
6454 for (int i = 0; i < mAllowAppSwitchUids.size(); i++) {
6455 ArrayMap<String, Integer> types = mAllowAppSwitchUids.valueAt(i);
6456 for (int j = 0; j < types.size(); j++) {
6457 if (dumpPackage == null ||
6458 UserHandle.getAppId(types.valueAt(j).intValue()) == dumpAppId) {
6459 if (needSep) {
6460 pw.println();
6461 needSep = false;
6462 }
6463 if (!printed) {
6464 pw.println(" mAllowAppSwitchUids:");
6465 printed = true;
6466 }
6467 pw.print(" User ");
6468 pw.print(mAllowAppSwitchUids.keyAt(i));
6469 pw.print(": Type ");
6470 pw.print(types.keyAt(j));
6471 pw.print(" = ");
6472 UserHandle.formatUid(pw, types.valueAt(j).intValue());
6473 pw.println();
6474 }
6475 }
6476 }
6477 }
6478 if (dumpPackage == null) {
6479 if (mController != null) {
6480 pw.println(" mController=" + mController
6481 + " mControllerIsAMonkey=" + mControllerIsAMonkey);
6482 }
6483 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
6484 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
6485 }
6486
6487 return needSep;
6488 }
6489 }
6490
6491 @Override
6492 public void writeProcessesToProto(ProtoOutputStream proto, String dumpPackage) {
6493 synchronized (mGlobalLock) {
6494 if (dumpPackage == null) {
6495 getGlobalConfiguration().writeToProto(proto, GLOBAL_CONFIGURATION);
6496 proto.write(CONFIG_WILL_CHANGE, getTopDisplayFocusedStack().mConfigWillChange);
6497 writeSleepStateToProto(proto);
6498 if (mController != null) {
6499 final long token = proto.start(CONTROLLER);
6500 proto.write(CONTROLLER, mController.toString());
6501 proto.write(IS_A_MONKEY, mControllerIsAMonkey);
6502 proto.end(token);
6503 }
6504 mStackSupervisor.mGoingToSleep.writeToProto(proto, GOING_TO_SLEEP);
6505 mStackSupervisor.mLaunchingActivity.writeToProto(proto, LAUNCHING_ACTIVITY);
6506 }
6507
6508 if (mHomeProcess != null && (dumpPackage == null
6509 || mHomeProcess.mPkgList.contains(dumpPackage))) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07006510 mHomeProcess.writeToProto(proto, HOME_PROC);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006511 }
6512
6513 if (mPreviousProcess != null && (dumpPackage == null
6514 || mPreviousProcess.mPkgList.contains(dumpPackage))) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07006515 mPreviousProcess.writeToProto(proto, PREVIOUS_PROC);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006516 proto.write(PREVIOUS_PROC_VISIBLE_TIME_MS, mPreviousProcessVisibleTime);
6517 }
6518
6519 if (mHeavyWeightProcess != null && (dumpPackage == null
6520 || mHeavyWeightProcess.mPkgList.contains(dumpPackage))) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07006521 mHeavyWeightProcess.writeToProto(proto, HEAVY_WEIGHT_PROC);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006522 }
6523
6524 for (Map.Entry<String, Integer> entry
6525 : mCompatModePackages.getPackages().entrySet()) {
6526 String pkg = entry.getKey();
6527 int mode = entry.getValue();
6528 if (dumpPackage == null || dumpPackage.equals(pkg)) {
6529 long compatToken = proto.start(SCREEN_COMPAT_PACKAGES);
6530 proto.write(PACKAGE, pkg);
6531 proto.write(MODE, mode);
6532 proto.end(compatToken);
6533 }
6534 }
6535
6536 if (mCurAppTimeTracker != null) {
6537 mCurAppTimeTracker.writeToProto(proto, CURRENT_TRACKER, true);
6538 }
6539
6540 }
6541 }
6542
6543 @Override
6544 public boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name,
6545 String[] args, int opti, boolean dumpAll, boolean dumpVisibleStacksOnly,
6546 boolean dumpFocusedStackOnly) {
6547 synchronized (mGlobalLock) {
6548 return ActivityTaskManagerService.this.dumpActivity(fd, pw, name, args, opti,
6549 dumpAll, dumpVisibleStacksOnly, dumpFocusedStackOnly);
6550 }
6551 }
6552
6553 @Override
Wale Ogunwaled4d67d02018-10-25 18:09:39 -07006554 public void dumpForOom(PrintWriter pw) {
6555 synchronized (mGlobalLock) {
6556 pw.println(" mHomeProcess: " + mHomeProcess);
6557 pw.println(" mPreviousProcess: " + mPreviousProcess);
6558 if (mHeavyWeightProcess != null) {
6559 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
6560 }
6561 }
6562 }
6563
6564 @Override
Wale Ogunwale31913b52018-10-13 08:29:31 -07006565 public boolean canGcNow() {
6566 synchronized (mGlobalLock) {
6567 return isSleeping() || mStackSupervisor.allResumedActivitiesIdle();
6568 }
6569 }
6570
6571 @Override
6572 public WindowProcessController getTopApp() {
6573 synchronized (mGlobalLock) {
6574 final ActivityRecord top = mStackSupervisor.getTopResumedActivity();
6575 return top != null ? top.app : null;
6576 }
6577 }
6578
6579 @Override
6580 public void rankTaskLayersIfNeeded() {
6581 synchronized (mGlobalLock) {
6582 if (mStackSupervisor != null) {
6583 mStackSupervisor.rankTaskLayersIfNeeded();
6584 }
6585 }
6586 }
6587
6588 @Override
6589 public void scheduleDestroyAllActivities(String reason) {
6590 synchronized (mGlobalLock) {
6591 mStackSupervisor.scheduleDestroyAllActivities(null, reason);
6592 }
6593 }
6594
6595 @Override
6596 public void removeUser(int userId) {
6597 synchronized (mGlobalLock) {
6598 mStackSupervisor.removeUserLocked(userId);
6599 }
6600 }
6601
6602 @Override
6603 public boolean switchUser(int userId, UserState userState) {
6604 synchronized (mGlobalLock) {
6605 return mStackSupervisor.switchUserLocked(userId, userState);
6606 }
6607 }
6608
6609 @Override
6610 public void onHandleAppCrash(WindowProcessController wpc) {
6611 synchronized (mGlobalLock) {
6612 mStackSupervisor.handleAppCrashLocked(wpc);
6613 }
6614 }
Wale Ogunwale64258362018-10-16 15:13:37 -07006615
6616 @Override
6617 public int finishTopCrashedActivities(WindowProcessController crashedApp, String reason) {
6618 synchronized (mGlobalLock) {
6619 return mStackSupervisor.finishTopCrashedActivitiesLocked(crashedApp, reason);
6620 }
6621 }
Wale Ogunwalebff2df42018-10-18 17:09:19 -07006622
6623 @Override
6624 public void onUidActive(int uid, int procState) {
6625 synchronized (mGlobalLock) {
6626 mActiveUids.put(uid, procState);
6627 }
6628 }
6629
6630 @Override
6631 public void onUidInactive(int uid) {
6632 synchronized (mGlobalLock) {
6633 mActiveUids.remove(uid);
6634 }
6635 }
6636
6637 @Override
6638 public void onActiveUidsCleared() {
6639 synchronized (mGlobalLock) {
6640 mActiveUids.clear();
6641 }
6642 }
6643
6644 @Override
6645 public void onUidProcStateChanged(int uid, int procState) {
6646 synchronized (mGlobalLock) {
6647 if (mActiveUids.get(uid) != null) {
6648 mActiveUids.put(uid, procState);
6649 }
6650 }
6651 }
Wale Ogunwale9de19442018-10-18 19:05:03 -07006652
6653 @Override
6654 public void onUidAddedToPendingTempWhitelist(int uid, String tag) {
6655 synchronized (mGlobalLock) {
6656 mPendingTempWhitelist.put(uid, tag);
6657 }
6658 }
6659
6660 @Override
6661 public void onUidRemovedFromPendingTempWhitelist(int uid) {
6662 synchronized (mGlobalLock) {
6663 mPendingTempWhitelist.remove(uid);
6664 }
6665 }
Wale Ogunwalee2172292018-10-25 10:11:10 -07006666
6667 @Override
6668 public boolean handleAppCrashInActivityController(String processName, int pid,
6669 String shortMsg, String longMsg, long timeMillis, String stackTrace,
6670 Runnable killCrashingAppCallback) {
6671 synchronized (mGlobalLock) {
6672 if (mController == null) {
6673 return false;
6674 }
6675
6676 try {
6677 if (!mController.appCrashed(processName, pid, shortMsg, longMsg, timeMillis,
6678 stackTrace)) {
6679 killCrashingAppCallback.run();
6680 return true;
6681 }
6682 } catch (RemoteException e) {
6683 mController = null;
6684 Watchdog.getInstance().setActivityController(null);
6685 }
6686 return false;
6687 }
6688 }
Wale Ogunwaled7889f52018-10-25 11:03:20 -07006689
6690 @Override
6691 public void removeRecentTasksByPackageName(String packageName, int userId) {
6692 synchronized (mGlobalLock) {
6693 mRecentTasks.removeTasksByPackageName(packageName, userId);
6694 }
6695 }
6696
6697 @Override
6698 public void cleanupRecentTasksForUser(int userId) {
6699 synchronized (mGlobalLock) {
6700 mRecentTasks.cleanupLocked(userId);
6701 }
6702 }
6703
6704 @Override
6705 public void loadRecentTasksForUser(int userId) {
6706 synchronized (mGlobalLock) {
6707 mRecentTasks.loadUserRecentsLocked(userId);
6708 }
6709 }
6710
6711 @Override
6712 public void onPackagesSuspendedChanged(String[] packages, boolean suspended, int userId) {
6713 synchronized (mGlobalLock) {
6714 mRecentTasks.onPackagesSuspendedChanged(packages, suspended, userId);
6715 }
6716 }
6717
6718 @Override
6719 public void flushRecentTasks() {
6720 mRecentTasks.flush();
6721 }
Wale Ogunwaled4d67d02018-10-25 18:09:39 -07006722
6723 @Override
6724 public WindowProcessController getHomeProcess() {
6725 synchronized (mGlobalLock) {
6726 return mHomeProcess;
6727 }
6728 }
6729
6730 @Override
6731 public WindowProcessController getPreviousProcess() {
6732 synchronized (mGlobalLock) {
6733 return mPreviousProcess;
6734 }
6735 }
Wale Ogunwale27c48ae2018-10-25 19:01:01 -07006736
6737 @Override
6738 public void clearLockedTasks(String reason) {
6739 synchronized (mGlobalLock) {
6740 getLockTaskController().clearLockedTasks(reason);
6741 }
6742 }
6743
6744 @Override
6745 public void updateUserConfiguration() {
6746 synchronized (mGlobalLock) {
6747 final Configuration configuration = new Configuration(getGlobalConfiguration());
6748 final int currentUserId = mAmInternal.getCurrentUserId();
6749 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(),
6750 configuration, currentUserId, Settings.System.canWrite(mContext));
6751 updateConfigurationLocked(configuration, null /* starting */,
6752 false /* initLocale */, false /* persistent */, currentUserId,
6753 false /* deferResume */);
6754 }
6755 }
Wale Ogunwale387b34c2018-10-25 19:59:40 -07006756
6757 @Override
6758 public boolean canShowErrorDialogs() {
6759 synchronized (mGlobalLock) {
6760 return mShowDialogs && !mSleeping && !mShuttingDown
6761 && !mKeyguardController.isKeyguardOrAodShowing(DEFAULT_DISPLAY)
6762 && !hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
6763 mAmInternal.getCurrentUserId())
6764 && !(UserManager.isDeviceInDemoMode(mContext)
6765 && mAmInternal.getCurrentUser().isDemo());
6766 }
6767 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07006768 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07006769}