blob: 078ed0ed509caa7f3bffe9c06fdf3717697f08c3 [file] [log] [blame]
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.server.am;
18
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070019import static android.Manifest.permission.BIND_VOICE_INTERACTION;
20import static android.Manifest.permission.CHANGE_CONFIGURATION;
21import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
22import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070023import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070024import static android.Manifest.permission.READ_FRAME_BUFFER;
25import static android.Manifest.permission.REMOVE_TASKS;
26import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070027import static android.Manifest.permission.STOP_APP_SWITCHES;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070028import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
Wale 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;
Yunfan Chen79b96062018-10-17 12:45:23 -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;
Yunfan Chen79b96062018-10-17 12:45:23 -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.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
93import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
94import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
95import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
96import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
97import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
98import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
Wale Ogunwale98875612018-10-12 07:53:02 -070099import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_ALL;
100import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
101import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_FOCUS;
102import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_IMMERSIVE;
103import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_LOCKTASK;
104import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_STACK;
105import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
106import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
107import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_VISIBILITY;
108import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
109import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS;
110import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_IMMERSIVE;
111import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_LOCKTASK;
112import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_STACK;
113import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH;
114import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_VISIBILITY;
115import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_ATM;
116import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
Evan Rosky4505b352018-09-06 11:20:40 -0700117import static com.android.server.am.ActivityTaskManagerService.H.REPORT_TIME_TRACKER_MSG;
118import static com.android.server.am.ActivityTaskManagerService.UiHandler.DISMISS_DIALOG_UI_MSG;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700119import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700120import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700121import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
Evan Rosky4505b352018-09-06 11:20:40 -0700122import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT;
123import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_DATA;
124import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
125import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700126import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
127import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
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 Ogunwale342fbe92018-10-09 08:44:10 -0700254import com.android.server.firewall.IntentFirewall;
Evan Rosky4505b352018-09-06 11:20:40 -0700255import com.android.server.pm.UserManagerService;
256import com.android.server.uri.UriGrantsManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700257import com.android.server.vr.VrManagerInternal;
Evan Rosky4505b352018-09-06 11:20:40 -0700258import com.android.server.wm.ActivityTaskManagerInternal;
lumark588a3e82018-07-20 18:53:54 +0800259import com.android.server.wm.DisplayWindowController;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700260import com.android.server.wm.PinnedStackWindowController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700261import com.android.server.wm.WindowManagerService;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700262
Wale Ogunwale31913b52018-10-13 08:29:31 -0700263import java.io.BufferedReader;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700264import java.io.File;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700265import java.io.FileDescriptor;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700266import java.io.FileOutputStream;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700267import java.io.FileReader;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700268import java.io.IOException;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700269import java.io.PrintWriter;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700270import java.io.StringWriter;
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700271import java.lang.ref.WeakReference;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700272import java.text.DateFormat;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700273import java.util.ArrayList;
Wale Ogunwale27c48ae2018-10-25 19:01:01 -0700274import java.util.Arrays;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700275import java.util.Date;
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700276import java.util.HashSet;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700277import java.util.List;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700278import java.util.Locale;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700279import java.util.Map;
280import java.util.Set;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700281
282/**
283 * System service for managing activities and their containers (task, stacks, displays,... ).
284 *
285 * {@hide}
286 */
287public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
Wale Ogunwale98875612018-10-12 07:53:02 -0700288 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityTaskManagerService" : TAG_ATM;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700289 private static final String TAG_STACK = TAG + POSTFIX_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700290 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
291 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
292 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
293 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
294 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700295 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700296
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700297 // How long we wait until we timeout on key dispatching.
Wale Ogunwale51cc98a2018-10-15 10:41:05 -0700298 public static final int KEY_DISPATCHING_TIMEOUT_MS = 5 * 1000;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700299 // How long we wait until we timeout on key dispatching during instrumentation.
Wale Ogunwale51cc98a2018-10-15 10:41:05 -0700300 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS = 60 * 1000;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700301
Wale Ogunwale98875612018-10-12 07:53:02 -0700302 /** Used to indicate that an app transition should be animated. */
303 static final boolean ANIMATE = true;
304
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700305 /** Hardware-reported OpenGLES version. */
306 final int GL_ES_VERSION;
307
Wale Ogunwale31913b52018-10-13 08:29:31 -0700308 public static final String DUMP_ACTIVITIES_CMD = "activities" ;
309 public static final String DUMP_ACTIVITIES_SHORT_CMD = "a" ;
310 public static final String DUMP_LASTANR_CMD = "lastanr" ;
311 public static final String DUMP_LASTANR_TRACES_CMD = "lastanr-traces" ;
312 public static final String DUMP_STARTER_CMD = "starter" ;
313 public static final String DUMP_CONTAINERS_CMD = "containers" ;
314 public static final String DUMP_RECENTS_CMD = "recents" ;
315 public static final String DUMP_RECENTS_SHORT_CMD = "r" ;
316
Wale Ogunwale64258362018-10-16 15:13:37 -0700317 /** This activity is not being relaunched, or being relaunched for a non-resize reason. */
318 public static final int RELAUNCH_REASON_NONE = 0;
319 /** This activity is being relaunched due to windowing mode change. */
320 public static final int RELAUNCH_REASON_WINDOWING_MODE_RESIZE = 1;
321 /** This activity is being relaunched due to a free-resize operation. */
322 public static final int RELAUNCH_REASON_FREE_RESIZE = 2;
323
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700324 Context mContext;
Wale Ogunwale64258362018-10-16 15:13:37 -0700325
Wale Ogunwalef6733932018-06-27 05:14:34 -0700326 /**
327 * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
328 * change at runtime. Use mContext for non-UI purposes.
329 */
330 final Context mUiContext;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700331 final ActivityThread mSystemThread;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700332 H mH;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700333 UiHandler mUiHandler;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700334 ActivityManagerInternal mAmInternal;
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700335 UriGrantsManagerInternal mUgmInternal;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700336 private PackageManagerInternal mPmInternal;
Wale Ogunwale53783742018-09-16 10:21:51 -0700337 private ActivityTaskManagerInternal mInternal;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700338 PowerManagerInternal mPowerManagerInternal;
339 private UsageStatsManagerInternal mUsageStatsInternal;
340
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700341 PendingIntentController mPendingIntentController;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700342 IntentFirewall mIntentFirewall;
343
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700344 /* Global service lock used by the package the owns this service. */
345 Object mGlobalLock;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700346 ActivityStackSupervisor mStackSupervisor;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700347 WindowManagerService mWindowManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700348 private UserManagerService mUserManager;
349 private AppOpsService mAppOpsService;
Wale Ogunwalebff2df42018-10-18 17:09:19 -0700350 /** All active uids in the system. */
Wale Ogunwale9de19442018-10-18 19:05:03 -0700351 private final SparseArray<Integer> mActiveUids = new SparseArray<>();
352 private final SparseArray<String> mPendingTempWhitelist = new SparseArray<>();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700353 /** All processes currently running that might have a window organized by name. */
354 final ProcessMap<WindowProcessController> mProcessNames = new ProcessMap<>();
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700355 /** All processes we currently have running mapped by pid */
356 final SparseArray<WindowProcessController> mPidMap = new SparseArray<>();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700357 /** This is the process holding what we currently consider to be the "home" activity. */
358 WindowProcessController mHomeProcess;
Wale Ogunwale53783742018-09-16 10:21:51 -0700359 /** The currently running heavy-weight process, if any. */
360 WindowProcessController mHeavyWeightProcess = null;
Wale Ogunwale214f3482018-10-04 11:00:47 -0700361 boolean mHasHeavyWeightFeature;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700362 /**
363 * This is the process holding the activity the user last visited that is in a different process
364 * from the one they are currently in.
365 */
366 WindowProcessController mPreviousProcess;
367 /** The time at which the previous process was last visible. */
368 long mPreviousProcessVisibleTime;
369
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700370 /** List of intents that were used to start the most recent tasks. */
371 private RecentTasks mRecentTasks;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700372 /** State of external calls telling us if the device is awake or asleep. */
373 private boolean mKeyguardShown = false;
374
375 // Wrapper around VoiceInteractionServiceManager
376 private AssistUtils mAssistUtils;
377
378 // VoiceInteraction session ID that changes for each new request except when
379 // being called for multi-window assist in a single session.
380 private int mViSessionId = 1000;
381
382 // How long to wait in getAssistContextExtras for the activity and foreground services
383 // to respond with the result.
384 private static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
385
386 // How long top wait when going through the modern assist (which doesn't need to block
387 // on getting this result before starting to launch its UI).
388 private static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
389
390 // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
391 private static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
392
393 private final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
394
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700395 // Keeps track of the active voice interaction service component, notified from
396 // VoiceInteractionManagerService
397 ComponentName mActiveVoiceInteractionServiceComponent;
398
Wale Ogunwalee2172292018-10-25 10:11:10 -0700399 VrController mVrController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700400 KeyguardController mKeyguardController;
401 private final ClientLifecycleManager mLifecycleManager;
402 private TaskChangeNotificationController mTaskChangeNotificationController;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700403 /** The controller for all operations related to locktask. */
404 private LockTaskController mLockTaskController;
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700405 private ActivityStartController mActivityStartController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700406
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700407 boolean mSuppressResizeConfigChanges;
408
409 private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
410 new UpdateConfigurationResult();
411
412 static final class UpdateConfigurationResult {
413 // Configuration changes that were updated.
414 int changes;
415 // If the activity was relaunched to match the new configuration.
416 boolean activityRelaunched;
417
418 void reset() {
419 changes = 0;
420 activityRelaunched = false;
421 }
422 }
423
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700424 /** Current sequencing integer of the configuration, for skipping old configurations. */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700425 private int mConfigurationSeq;
426 // To cache the list of supported system locales
427 private String[] mSupportedSystemLocales = null;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700428
429 /**
430 * Temp object used when global and/or display override configuration is updated. It is also
431 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
432 * anyone...
433 */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700434 private Configuration mTempConfig = new Configuration();
435
Wale Ogunwalef6733932018-06-27 05:14:34 -0700436 /** Temporary to avoid allocations. */
437 final StringBuilder mStringBuilder = new StringBuilder(256);
438
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700439 // Amount of time after a call to stopAppSwitches() during which we will
440 // prevent further untrusted switches from happening.
441 private static final long APP_SWITCH_DELAY_TIME = 5 * 1000;
442
443 /**
444 * The time at which we will allow normal application switches again,
445 * after a call to {@link #stopAppSwitches()}.
446 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700447 private long mAppSwitchesAllowedTime;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700448 /**
449 * This is set to true after the first switch after mAppSwitchesAllowedTime
450 * is set; any switches after that will clear the time.
451 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700452 private boolean mDidAppSwitch;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700453
454 IActivityController mController = null;
455 boolean mControllerIsAMonkey = false;
456
Wale Ogunwale214f3482018-10-04 11:00:47 -0700457 final int mFactoryTest;
458
459 /** Used to control how we initialize the service. */
460 ComponentName mTopComponent;
461 String mTopAction = Intent.ACTION_MAIN;
462 String mTopData;
463
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700464 /**
Wale Ogunwale31913b52018-10-13 08:29:31 -0700465 * Dump of the activity state at the time of the last ANR. Cleared after
466 * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
467 */
468 String mLastANRState;
469
470 /**
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700471 * Used to retain an update lock when the foreground activity is in
472 * immersive mode.
473 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700474 private final UpdateLock mUpdateLock = new UpdateLock("immersive");
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700475
476 /**
477 * Packages that are being allowed to perform unrestricted app switches. Mapping is
478 * User -> Type -> uid.
479 */
480 final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
481
482 /** The dimensions of the thumbnails in the Recents UI. */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700483 private int mThumbnailWidth;
484 private int mThumbnailHeight;
485 private float mFullscreenThumbnailScale;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700486
487 /**
488 * Flag that indicates if multi-window is enabled.
489 *
490 * For any particular form of multi-window to be enabled, generic multi-window must be enabled
491 * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
492 * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
493 * At least one of the forms of multi-window must be enabled in order for this flag to be
494 * initialized to 'true'.
495 *
496 * @see #mSupportsSplitScreenMultiWindow
497 * @see #mSupportsFreeformWindowManagement
498 * @see #mSupportsPictureInPicture
499 * @see #mSupportsMultiDisplay
500 */
501 boolean mSupportsMultiWindow;
502 boolean mSupportsSplitScreenMultiWindow;
503 boolean mSupportsFreeformWindowManagement;
504 boolean mSupportsPictureInPicture;
505 boolean mSupportsMultiDisplay;
506 boolean mForceResizableActivities;
507
508 final List<ActivityTaskManagerInternal.ScreenObserver> mScreenObservers = new ArrayList<>();
509
510 // VR Vr2d Display Id.
511 int mVr2dDisplayId = INVALID_DISPLAY;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700512
Wale Ogunwalef6733932018-06-27 05:14:34 -0700513 /**
514 * Set while we are wanting to sleep, to prevent any
515 * activities from being started/resumed.
516 *
517 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
518 *
519 * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
520 * while in the sleep state until there is a pending transition out of sleep, in which case
521 * mSleeping is set to false, and remains false while awake.
522 *
523 * Whether mSleeping can quickly toggled between true/false without the device actually
524 * display changing states is undefined.
525 */
526 private boolean mSleeping = false;
527
528 /**
529 * The process state used for processes that are running the top activities.
530 * This changes between TOP and TOP_SLEEPING to following mSleeping.
531 */
532 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
533
534 // Whether we should show our dialogs (ANR, crash, etc) or just perform their default action
535 // automatically. Important for devices without direct input devices.
536 private boolean mShowDialogs = true;
537
538 /** Set if we are shutting down the system, similar to sleeping. */
539 boolean mShuttingDown = false;
540
541 /**
542 * We want to hold a wake lock while running a voice interaction session, since
543 * this may happen with the screen off and we need to keep the CPU running to
544 * be able to continue to interact with the user.
545 */
546 PowerManager.WakeLock mVoiceWakeLock;
547
548 /**
549 * Set while we are running a voice interaction. This overrides sleeping while it is active.
550 */
551 IVoiceInteractionSession mRunningVoice;
552
553 /**
554 * The last resumed activity. This is identical to the current resumed activity most
555 * of the time but could be different when we're pausing one activity before we resume
556 * another activity.
557 */
558 ActivityRecord mLastResumedActivity;
559
560 /**
561 * The activity that is currently being traced as the active resumed activity.
562 *
563 * @see #updateResumedAppTrace
564 */
565 private @Nullable ActivityRecord mTracedResumedActivity;
566
567 /** If non-null, we are tracking the time the user spends in the currently focused app. */
568 AppTimeTracker mCurAppTimeTracker;
569
Wale Ogunwale008163e2018-07-23 23:11:08 -0700570 private AppWarnings mAppWarnings;
571
Wale Ogunwale53783742018-09-16 10:21:51 -0700572 /**
573 * Packages that the user has asked to have run in screen size
574 * compatibility mode instead of filling the screen.
575 */
576 CompatModePackages mCompatModePackages;
577
Wale Ogunwalef6733932018-06-27 05:14:34 -0700578 private FontScaleSettingObserver mFontScaleSettingObserver;
579
580 private final class FontScaleSettingObserver extends ContentObserver {
581 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
582 private final Uri mHideErrorDialogsUri = Settings.Global.getUriFor(HIDE_ERROR_DIALOGS);
583
584 public FontScaleSettingObserver() {
585 super(mH);
586 final ContentResolver resolver = mContext.getContentResolver();
587 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
588 resolver.registerContentObserver(mHideErrorDialogsUri, false, this,
589 UserHandle.USER_ALL);
590 }
591
592 @Override
593 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
594 if (mFontScaleUri.equals(uri)) {
595 updateFontScaleIfNeeded(userId);
596 } else if (mHideErrorDialogsUri.equals(uri)) {
597 synchronized (mGlobalLock) {
598 updateShouldShowDialogsLocked(getGlobalConfiguration());
599 }
600 }
601 }
602 }
603
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700604 ActivityTaskManagerService(Context context) {
605 mContext = context;
Wale Ogunwale214f3482018-10-04 11:00:47 -0700606 mFactoryTest = FactoryTest.getMode();
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700607 mSystemThread = ActivityThread.currentActivityThread();
608 mUiContext = mSystemThread.getSystemUiContext();
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700609 mLifecycleManager = new ClientLifecycleManager();
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700610 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", GL_ES_VERSION_UNDEFINED);
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700611 }
612
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700613 public void onSystemReady() {
614 synchronized (mGlobalLock) {
615 mHasHeavyWeightFeature = mContext.getPackageManager().hasSystemFeature(
616 PackageManager.FEATURE_CANT_SAVE_STATE);
617 mAssistUtils = new AssistUtils(mContext);
618 mVrController.onSystemReady();
619 mRecentTasks.onSystemReadyLocked();
620 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700621 }
622
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700623 public void onInitPowerManagement() {
624 synchronized (mGlobalLock) {
625 mStackSupervisor.initPowerManagement();
626 final PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
627 mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
628 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
629 mVoiceWakeLock.setReferenceCounted(false);
630 }
Wale Ogunwalef6733932018-06-27 05:14:34 -0700631 }
632
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700633 public void installSystemProviders() {
Wale Ogunwalef6733932018-06-27 05:14:34 -0700634 mFontScaleSettingObserver = new FontScaleSettingObserver();
635 }
636
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700637 void retrieveSettings(ContentResolver resolver) {
638 final boolean freeformWindowManagement =
639 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
640 || Settings.Global.getInt(
641 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
642
643 final boolean supportsMultiWindow = ActivityTaskManager.supportsMultiWindow(mContext);
644 final boolean supportsPictureInPicture = supportsMultiWindow &&
645 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
646 final boolean supportsSplitScreenMultiWindow =
647 ActivityTaskManager.supportsSplitScreenMultiWindow(mContext);
648 final boolean supportsMultiDisplay = mContext.getPackageManager()
649 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
650 final boolean alwaysFinishActivities =
651 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
652 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
653 final boolean forceResizable = Settings.Global.getInt(
654 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
Garfield Tane0846042018-07-26 13:42:04 -0700655 final boolean isPc = mContext.getPackageManager().hasSystemFeature(FEATURE_PC);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700656
657 // Transfer any global setting for forcing RTL layout, into a System Property
658 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
659
660 final Configuration configuration = new Configuration();
661 Settings.System.getConfiguration(resolver, configuration);
662 if (forceRtl) {
663 // This will take care of setting the correct layout direction flags
664 configuration.setLayoutDirection(configuration.locale);
665 }
666
667 synchronized (mGlobalLock) {
668 mForceResizableActivities = forceResizable;
669 final boolean multiWindowFormEnabled = freeformWindowManagement
670 || supportsSplitScreenMultiWindow
671 || supportsPictureInPicture
672 || supportsMultiDisplay;
673 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
674 mSupportsMultiWindow = true;
675 mSupportsFreeformWindowManagement = freeformWindowManagement;
676 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
677 mSupportsPictureInPicture = supportsPictureInPicture;
678 mSupportsMultiDisplay = supportsMultiDisplay;
679 } else {
680 mSupportsMultiWindow = false;
681 mSupportsFreeformWindowManagement = false;
682 mSupportsSplitScreenMultiWindow = false;
683 mSupportsPictureInPicture = false;
684 mSupportsMultiDisplay = false;
685 }
686 mWindowManager.setForceResizableTasks(mForceResizableActivities);
687 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
Garfield Tane0846042018-07-26 13:42:04 -0700688 mWindowManager.setSupportsFreeformWindowManagement(mSupportsFreeformWindowManagement);
689 mWindowManager.setIsPc(isPc);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700690 // This happens before any activities are started, so we can change global configuration
691 // in-place.
692 updateConfigurationLocked(configuration, null, true);
693 final Configuration globalConfig = getGlobalConfiguration();
694 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
695
696 // Load resources only after the current configuration has been set.
697 final Resources res = mContext.getResources();
698 mThumbnailWidth = res.getDimensionPixelSize(
699 com.android.internal.R.dimen.thumbnail_width);
700 mThumbnailHeight = res.getDimensionPixelSize(
701 com.android.internal.R.dimen.thumbnail_height);
702
703 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
704 mFullscreenThumbnailScale = (float) res
705 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
706 (float) globalConfig.screenWidthDp;
707 } else {
708 mFullscreenThumbnailScale = res.getFraction(
709 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
710 }
711 }
712 }
713
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700714 // TODO: Will be converted to WM lock once transition is complete.
Wale Ogunwale9de19442018-10-18 19:05:03 -0700715 void setActivityManagerService(Object globalLock, Looper looper,
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700716 IntentFirewall intentFirewall, PendingIntentController intentController) {
Wale Ogunwale9de19442018-10-18 19:05:03 -0700717 mGlobalLock = globalLock;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700718 mH = new H(looper);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700719 mUiHandler = new UiHandler();
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700720 mIntentFirewall = intentFirewall;
Wale Ogunwale53783742018-09-16 10:21:51 -0700721 final File systemDir = SystemServiceManager.ensureSystemDir();
722 mAppWarnings = new AppWarnings(this, mUiContext, mH, mUiHandler, systemDir);
723 mCompatModePackages = new CompatModePackages(this, systemDir, mH);
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700724 mPendingIntentController = intentController;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700725
726 mTempConfig.setToDefaults();
727 mTempConfig.setLocales(LocaleList.getDefault());
728 mConfigurationSeq = mTempConfig.seq = 1;
729 mStackSupervisor = createStackSupervisor();
730 mStackSupervisor.onConfigurationChanged(mTempConfig);
731
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700732 mTaskChangeNotificationController =
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700733 new TaskChangeNotificationController(mGlobalLock, mStackSupervisor, mH);
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700734 mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mH);
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700735 mActivityStartController = new ActivityStartController(this);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700736 mRecentTasks = createRecentTasks();
737 mStackSupervisor.setRecentTasks(mRecentTasks);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700738 mVrController = new VrController(mGlobalLock);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700739 mKeyguardController = mStackSupervisor.getKeyguardController();
740 }
741
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700742 public void onActivityManagerInternalAdded() {
743 synchronized (mGlobalLock) {
744 mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
745 mUgmInternal = LocalServices.getService(UriGrantsManagerInternal.class);
746 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700747 }
748
Yunfan Chen75157d72018-07-27 14:47:21 +0900749 int increaseConfigurationSeqLocked() {
750 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
751 return mConfigurationSeq;
752 }
753
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700754 protected ActivityStackSupervisor createStackSupervisor() {
755 final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mH.getLooper());
756 supervisor.initialize();
757 return supervisor;
758 }
759
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700760 public void setWindowManager(WindowManagerService wm) {
761 synchronized (mGlobalLock) {
762 mWindowManager = wm;
763 mLockTaskController.setWindowManager(wm);
764 mStackSupervisor.setWindowManager(wm);
765 }
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700766 }
767
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700768 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
769 synchronized (mGlobalLock) {
770 mUsageStatsInternal = usageStatsManager;
771 }
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700772 }
773
Wale Ogunwalef6733932018-06-27 05:14:34 -0700774 UserManagerService getUserManager() {
775 if (mUserManager == null) {
776 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
777 mUserManager = (UserManagerService) IUserManager.Stub.asInterface(b);
778 }
779 return mUserManager;
780 }
781
782 AppOpsService getAppOpsService() {
783 if (mAppOpsService == null) {
784 IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
785 mAppOpsService = (AppOpsService) IAppOpsService.Stub.asInterface(b);
786 }
787 return mAppOpsService;
788 }
789
790 boolean hasUserRestriction(String restriction, int userId) {
791 return getUserManager().hasUserRestriction(restriction, userId);
792 }
793
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700794 protected RecentTasks createRecentTasks() {
795 return new RecentTasks(this, mStackSupervisor);
796 }
797
798 RecentTasks getRecentTasks() {
799 return mRecentTasks;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700800 }
801
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700802 ClientLifecycleManager getLifecycleManager() {
803 return mLifecycleManager;
804 }
805
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700806 ActivityStartController getActivityStartController() {
807 return mActivityStartController;
808 }
809
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700810 TaskChangeNotificationController getTaskChangeNotificationController() {
811 return mTaskChangeNotificationController;
812 }
813
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700814 LockTaskController getLockTaskController() {
815 return mLockTaskController;
816 }
817
Yunfan Chen75157d72018-07-27 14:47:21 +0900818 /**
819 * Return the global configuration used by the process corresponding to the input pid. This is
820 * usually the global configuration with some overrides specific to that process.
821 */
822 Configuration getGlobalConfigurationForCallingPid() {
823 final int pid = Binder.getCallingPid();
824 if (pid == MY_PID || pid < 0) {
825 return getGlobalConfiguration();
826 }
827 synchronized (mGlobalLock) {
828 final WindowProcessController app = mPidMap.get(pid);
829 return app != null ? app.getConfiguration() : getGlobalConfiguration();
830 }
831 }
832
833 /**
834 * Return the device configuration info used by the process corresponding to the input pid.
835 * The value is consistent with the global configuration for the process.
836 */
837 @Override
838 public ConfigurationInfo getDeviceConfigurationInfo() {
839 ConfigurationInfo config = new ConfigurationInfo();
840 synchronized (mGlobalLock) {
841 final Configuration globalConfig = getGlobalConfigurationForCallingPid();
842 config.reqTouchScreen = globalConfig.touchscreen;
843 config.reqKeyboardType = globalConfig.keyboard;
844 config.reqNavigation = globalConfig.navigation;
845 if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
846 || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
847 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
848 }
849 if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
850 && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
851 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
852 }
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700853 config.reqGlEsVersion = GL_ES_VERSION;
Yunfan Chen75157d72018-07-27 14:47:21 +0900854 }
855 return config;
856 }
857
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700858 private void start() {
Wale Ogunwale53783742018-09-16 10:21:51 -0700859 mInternal = new LocalService();
860 LocalServices.addService(ActivityTaskManagerInternal.class, mInternal);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700861 }
862
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700863 public static final class Lifecycle extends SystemService {
864 private final ActivityTaskManagerService mService;
865
866 public Lifecycle(Context context) {
867 super(context);
868 mService = new ActivityTaskManagerService(context);
869 }
870
871 @Override
872 public void onStart() {
873 publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700874 mService.start();
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700875 }
876
877 public ActivityTaskManagerService getService() {
878 return mService;
879 }
880 }
881
882 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700883 public final int startActivity(IApplicationThread caller, String callingPackage,
884 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
885 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
886 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
887 resultWho, requestCode, startFlags, profilerInfo, bOptions,
888 UserHandle.getCallingUserId());
889 }
890
891 @Override
892 public final int startActivities(IApplicationThread caller, String callingPackage,
893 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
894 int userId) {
895 final String reason = "startActivities";
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700896 enforceNotIsolatedCaller(reason);
897 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, reason);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700898 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700899 return getActivityStartController().startActivities(caller, -1, callingPackage, intents,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100900 resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId, reason,
901 null /* originatingPendingIntent */);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700902 }
903
904 @Override
905 public int startActivityAsUser(IApplicationThread caller, String callingPackage,
906 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
907 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
908 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
909 resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
910 true /*validateIncomingUser*/);
911 }
912
913 int startActivityAsUser(IApplicationThread caller, String callingPackage,
914 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
915 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
916 boolean validateIncomingUser) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700917 enforceNotIsolatedCaller("startActivityAsUser");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700918
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700919 userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700920 Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
921
922 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700923 return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700924 .setCaller(caller)
925 .setCallingPackage(callingPackage)
926 .setResolvedType(resolvedType)
927 .setResultTo(resultTo)
928 .setResultWho(resultWho)
929 .setRequestCode(requestCode)
930 .setStartFlags(startFlags)
931 .setProfilerInfo(profilerInfo)
932 .setActivityOptions(bOptions)
933 .setMayWait(userId)
934 .execute();
935
936 }
937
938 @Override
939 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
940 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700941 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions) {
942 enforceNotIsolatedCaller("startActivityIntentSender");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700943 // Refuse possible leaked file descriptors
944 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
945 throw new IllegalArgumentException("File descriptors passed in Intent");
946 }
947
948 if (!(target instanceof PendingIntentRecord)) {
949 throw new IllegalArgumentException("Bad PendingIntent object");
950 }
951
952 PendingIntentRecord pir = (PendingIntentRecord)target;
953
954 synchronized (mGlobalLock) {
955 // If this is coming from the currently resumed activity, it is
956 // effectively saying that app switches are allowed at this point.
Andrii Kulian5f750bc2018-07-17 08:57:23 -0700957 final ActivityStack stack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700958 if (stack.mResumedActivity != null &&
959 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700960 mAppSwitchesAllowedTime = 0;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700961 }
962 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700963 return pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700964 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700965 }
966
967 @Override
968 public boolean startNextMatchingActivity(IBinder callingActivity, Intent intent,
969 Bundle bOptions) {
970 // Refuse possible leaked file descriptors
971 if (intent != null && intent.hasFileDescriptors()) {
972 throw new IllegalArgumentException("File descriptors passed in Intent");
973 }
974 SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
975
976 synchronized (mGlobalLock) {
977 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
978 if (r == null) {
979 SafeActivityOptions.abort(options);
980 return false;
981 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700982 if (!r.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700983 // The caller is not running... d'oh!
984 SafeActivityOptions.abort(options);
985 return false;
986 }
987 intent = new Intent(intent);
988 // The caller is not allowed to change the data.
989 intent.setDataAndType(r.intent.getData(), r.intent.getType());
990 // And we are resetting to find the next component...
991 intent.setComponent(null);
992
993 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
994
995 ActivityInfo aInfo = null;
996 try {
997 List<ResolveInfo> resolves =
998 AppGlobals.getPackageManager().queryIntentActivities(
999 intent, r.resolvedType,
1000 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
1001 UserHandle.getCallingUserId()).getList();
1002
1003 // Look for the original activity in the list...
1004 final int N = resolves != null ? resolves.size() : 0;
1005 for (int i=0; i<N; i++) {
1006 ResolveInfo rInfo = resolves.get(i);
1007 if (rInfo.activityInfo.packageName.equals(r.packageName)
1008 && rInfo.activityInfo.name.equals(r.info.name)) {
1009 // We found the current one... the next matching is
1010 // after it.
1011 i++;
1012 if (i<N) {
1013 aInfo = resolves.get(i).activityInfo;
1014 }
1015 if (debug) {
1016 Slog.v(TAG, "Next matching activity: found current " + r.packageName
1017 + "/" + r.info.name);
1018 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
1019 ? "null" : aInfo.packageName + "/" + aInfo.name));
1020 }
1021 break;
1022 }
1023 }
1024 } catch (RemoteException e) {
1025 }
1026
1027 if (aInfo == null) {
1028 // Nobody who is next!
1029 SafeActivityOptions.abort(options);
1030 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
1031 return false;
1032 }
1033
1034 intent.setComponent(new ComponentName(
1035 aInfo.applicationInfo.packageName, aInfo.name));
1036 intent.setFlags(intent.getFlags()&~(
1037 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
1038 Intent.FLAG_ACTIVITY_CLEAR_TOP|
1039 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
1040 FLAG_ACTIVITY_NEW_TASK));
1041
1042 // Okay now we need to start the new activity, replacing the currently running activity.
1043 // This is a little tricky because we want to start the new one as if the current one is
1044 // finished, but not finish the current one first so that there is no flicker.
1045 // And thus...
1046 final boolean wasFinishing = r.finishing;
1047 r.finishing = true;
1048
1049 // Propagate reply information over to the new activity.
1050 final ActivityRecord resultTo = r.resultTo;
1051 final String resultWho = r.resultWho;
1052 final int requestCode = r.requestCode;
1053 r.resultTo = null;
1054 if (resultTo != null) {
1055 resultTo.removeResultsLocked(r, resultWho, requestCode);
1056 }
1057
1058 final long origId = Binder.clearCallingIdentity();
1059 // TODO(b/64750076): Check if calling pid should really be -1.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001060 final int res = getActivityStartController()
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001061 .obtainStarter(intent, "startNextMatchingActivity")
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001062 .setCaller(r.app.getThread())
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001063 .setResolvedType(r.resolvedType)
1064 .setActivityInfo(aInfo)
1065 .setResultTo(resultTo != null ? resultTo.appToken : null)
1066 .setResultWho(resultWho)
1067 .setRequestCode(requestCode)
1068 .setCallingPid(-1)
1069 .setCallingUid(r.launchedFromUid)
1070 .setCallingPackage(r.launchedFromPackage)
1071 .setRealCallingPid(-1)
1072 .setRealCallingUid(r.launchedFromUid)
1073 .setActivityOptions(options)
1074 .execute();
1075 Binder.restoreCallingIdentity(origId);
1076
1077 r.finishing = wasFinishing;
1078 if (res != ActivityManager.START_SUCCESS) {
1079 return false;
1080 }
1081 return true;
1082 }
1083 }
1084
1085 @Override
1086 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
1087 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1088 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
1089 final WaitResult res = new WaitResult();
1090 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001091 enforceNotIsolatedCaller("startActivityAndWait");
1092 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
1093 userId, "startActivityAndWait");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001094 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001095 getActivityStartController().obtainStarter(intent, "startActivityAndWait")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001096 .setCaller(caller)
1097 .setCallingPackage(callingPackage)
1098 .setResolvedType(resolvedType)
1099 .setResultTo(resultTo)
1100 .setResultWho(resultWho)
1101 .setRequestCode(requestCode)
1102 .setStartFlags(startFlags)
1103 .setActivityOptions(bOptions)
1104 .setMayWait(userId)
1105 .setProfilerInfo(profilerInfo)
1106 .setWaitResult(res)
1107 .execute();
1108 }
1109 return res;
1110 }
1111
1112 @Override
1113 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
1114 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1115 int startFlags, Configuration config, Bundle bOptions, int userId) {
1116 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001117 enforceNotIsolatedCaller("startActivityWithConfig");
1118 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
1119 "startActivityWithConfig");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001120 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001121 return getActivityStartController().obtainStarter(intent, "startActivityWithConfig")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001122 .setCaller(caller)
1123 .setCallingPackage(callingPackage)
1124 .setResolvedType(resolvedType)
1125 .setResultTo(resultTo)
1126 .setResultWho(resultWho)
1127 .setRequestCode(requestCode)
1128 .setStartFlags(startFlags)
1129 .setGlobalConfiguration(config)
1130 .setActivityOptions(bOptions)
1131 .setMayWait(userId)
1132 .execute();
1133 }
1134 }
1135
1136 @Override
1137 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
1138 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1139 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
1140 int userId) {
1141
1142 // This is very dangerous -- it allows you to perform a start activity (including
1143 // permission grants) as any app that may launch one of your own activities. So
1144 // we will only allow this to be done from activities that are part of the core framework,
1145 // and then only when they are running as the system.
1146 final ActivityRecord sourceRecord;
1147 final int targetUid;
1148 final String targetPackage;
1149 final boolean isResolver;
1150 synchronized (mGlobalLock) {
1151 if (resultTo == null) {
1152 throw new SecurityException("Must be called from an activity");
1153 }
1154 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
1155 if (sourceRecord == null) {
1156 throw new SecurityException("Called with bad activity token: " + resultTo);
1157 }
1158 if (!sourceRecord.info.packageName.equals("android")) {
1159 throw new SecurityException(
1160 "Must be called from an activity that is declared in the android package");
1161 }
1162 if (sourceRecord.app == null) {
1163 throw new SecurityException("Called without a process attached to activity");
1164 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001165 if (UserHandle.getAppId(sourceRecord.app.mUid) != SYSTEM_UID) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001166 // This is still okay, as long as this activity is running under the
1167 // uid of the original calling activity.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001168 if (sourceRecord.app.mUid != sourceRecord.launchedFromUid) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001169 throw new SecurityException(
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001170 "Calling activity in uid " + sourceRecord.app.mUid
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001171 + " must be system uid or original calling uid "
1172 + sourceRecord.launchedFromUid);
1173 }
1174 }
1175 if (ignoreTargetSecurity) {
1176 if (intent.getComponent() == null) {
1177 throw new SecurityException(
1178 "Component must be specified with ignoreTargetSecurity");
1179 }
1180 if (intent.getSelector() != null) {
1181 throw new SecurityException(
1182 "Selector not allowed with ignoreTargetSecurity");
1183 }
1184 }
1185 targetUid = sourceRecord.launchedFromUid;
1186 targetPackage = sourceRecord.launchedFromPackage;
1187 isResolver = sourceRecord.isResolverOrChildActivity();
1188 }
1189
1190 if (userId == UserHandle.USER_NULL) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001191 userId = UserHandle.getUserId(sourceRecord.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001192 }
1193
1194 // TODO: Switch to user app stacks here.
1195 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001196 return getActivityStartController().obtainStarter(intent, "startActivityAsCaller")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001197 .setCallingUid(targetUid)
1198 .setCallingPackage(targetPackage)
1199 .setResolvedType(resolvedType)
1200 .setResultTo(resultTo)
1201 .setResultWho(resultWho)
1202 .setRequestCode(requestCode)
1203 .setStartFlags(startFlags)
1204 .setActivityOptions(bOptions)
1205 .setMayWait(userId)
1206 .setIgnoreTargetSecurity(ignoreTargetSecurity)
1207 .setFilterCallingUid(isResolver ? 0 /* system */ : targetUid)
1208 .execute();
1209 } catch (SecurityException e) {
1210 // XXX need to figure out how to propagate to original app.
1211 // A SecurityException here is generally actually a fault of the original
1212 // calling activity (such as a fairly granting permissions), so propagate it
1213 // back to them.
1214 /*
1215 StringBuilder msg = new StringBuilder();
1216 msg.append("While launching");
1217 msg.append(intent.toString());
1218 msg.append(": ");
1219 msg.append(e.getMessage());
1220 */
1221 throw e;
1222 }
1223 }
1224
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001225 int handleIncomingUser(int callingPid, int callingUid, int userId, String name) {
1226 return mAmInternal.handleIncomingUser(callingPid, callingUid, userId, false /* allowAll */,
1227 ALLOW_FULL_ONLY, name, null /* callerPackage */);
1228 }
1229
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001230 @Override
1231 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
1232 Intent intent, String resolvedType, IVoiceInteractionSession session,
1233 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
1234 Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001235 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001236 if (session == null || interactor == null) {
1237 throw new NullPointerException("null session or interactor");
1238 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001239 userId = handleIncomingUser(callingPid, callingUid, userId, "startVoiceActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001240 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001241 return getActivityStartController().obtainStarter(intent, "startVoiceActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001242 .setCallingUid(callingUid)
1243 .setCallingPackage(callingPackage)
1244 .setResolvedType(resolvedType)
1245 .setVoiceSession(session)
1246 .setVoiceInteractor(interactor)
1247 .setStartFlags(startFlags)
1248 .setProfilerInfo(profilerInfo)
1249 .setActivityOptions(bOptions)
1250 .setMayWait(userId)
1251 .execute();
1252 }
1253
1254 @Override
1255 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
1256 Intent intent, String resolvedType, Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001257 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
1258 userId = handleIncomingUser(callingPid, callingUid, userId, "startAssistantActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001259
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001260 return getActivityStartController().obtainStarter(intent, "startAssistantActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001261 .setCallingUid(callingUid)
1262 .setCallingPackage(callingPackage)
1263 .setResolvedType(resolvedType)
1264 .setActivityOptions(bOptions)
1265 .setMayWait(userId)
1266 .execute();
1267 }
1268
1269 @Override
1270 public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
1271 IRecentsAnimationRunner recentsAnimationRunner) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001272 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001273 final int callingPid = Binder.getCallingPid();
1274 final long origId = Binder.clearCallingIdentity();
1275 try {
1276 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07001277 final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
1278 final int recentsUid = mRecentTasks.getRecentsComponentUid();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001279
1280 // Start a new recents animation
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001281 final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
1282 getActivityStartController(), mWindowManager, callingPid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001283 anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
1284 recentsUid, assistDataReceiver);
1285 }
1286 } finally {
1287 Binder.restoreCallingIdentity(origId);
1288 }
1289 }
1290
1291 @Override
1292 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001293 enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001294 "startActivityFromRecents()");
1295
1296 final int callingPid = Binder.getCallingPid();
1297 final int callingUid = Binder.getCallingUid();
1298 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(bOptions);
1299 final long origId = Binder.clearCallingIdentity();
1300 try {
1301 synchronized (mGlobalLock) {
1302 return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
1303 safeOptions);
1304 }
1305 } finally {
1306 Binder.restoreCallingIdentity(origId);
1307 }
1308 }
1309
1310 /**
1311 * This is the internal entry point for handling Activity.finish().
1312 *
1313 * @param token The Binder token referencing the Activity we want to finish.
1314 * @param resultCode Result code, if any, from this Activity.
1315 * @param resultData Result data (Intent), if any, from this Activity.
1316 * @param finishTask Whether to finish the task associated with this Activity.
1317 *
1318 * @return Returns true if the activity successfully finished, or false if it is still running.
1319 */
1320 @Override
1321 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
1322 int finishTask) {
1323 // Refuse possible leaked file descriptors
1324 if (resultData != null && resultData.hasFileDescriptors()) {
1325 throw new IllegalArgumentException("File descriptors passed in Intent");
1326 }
1327
1328 synchronized (mGlobalLock) {
1329 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1330 if (r == null) {
1331 return true;
1332 }
1333 // Keep track of the root activity of the task before we finish it
1334 TaskRecord tr = r.getTask();
1335 ActivityRecord rootR = tr.getRootActivity();
1336 if (rootR == null) {
1337 Slog.w(TAG, "Finishing task with all activities already finished");
1338 }
1339 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
1340 // finish.
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001341 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001342 return false;
1343 }
1344
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001345 // TODO: There is a dup. of this block of code in ActivityStack.navigateUpToLocked
1346 // We should consolidate.
1347 if (mController != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001348 // Find the first activity that is not finishing.
1349 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
1350 if (next != null) {
1351 // ask watcher if this is allowed
1352 boolean resumeOK = true;
1353 try {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001354 resumeOK = mController.activityResuming(next.packageName);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001355 } catch (RemoteException e) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001356 mController = null;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001357 Watchdog.getInstance().setActivityController(null);
1358 }
1359
1360 if (!resumeOK) {
1361 Slog.i(TAG, "Not finishing activity because controller resumed");
1362 return false;
1363 }
1364 }
1365 }
1366 final long origId = Binder.clearCallingIdentity();
1367 try {
1368 boolean res;
1369 final boolean finishWithRootActivity =
1370 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
1371 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
1372 || (finishWithRootActivity && r == rootR)) {
1373 // If requested, remove the task that is associated to this activity only if it
1374 // was the root activity in the task. The result code and data is ignored
1375 // because we don't support returning them across task boundaries. Also, to
1376 // keep backwards compatibility we remove the task from recents when finishing
1377 // task with root activity.
1378 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
1379 finishWithRootActivity, "finish-activity");
1380 if (!res) {
1381 Slog.i(TAG, "Removing task failed to finish activity");
1382 }
Garfield Tan2746ab52018-07-25 12:33:01 -07001383 // Explicitly dismissing the activity so reset its relaunch flag.
Wale Ogunwale64258362018-10-16 15:13:37 -07001384 r.mRelaunchReason = RELAUNCH_REASON_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001385 } else {
1386 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
1387 resultData, "app-request", true);
1388 if (!res) {
1389 Slog.i(TAG, "Failed to finish by app-request");
1390 }
1391 }
1392 return res;
1393 } finally {
1394 Binder.restoreCallingIdentity(origId);
1395 }
1396 }
1397 }
1398
1399 @Override
1400 public boolean finishActivityAffinity(IBinder token) {
1401 synchronized (mGlobalLock) {
1402 final long origId = Binder.clearCallingIdentity();
1403 try {
1404 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1405 if (r == null) {
1406 return false;
1407 }
1408
1409 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
1410 // can finish.
1411 final TaskRecord task = r.getTask();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001412 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001413 return false;
1414 }
1415 return task.getStack().finishActivityAffinityLocked(r);
1416 } finally {
1417 Binder.restoreCallingIdentity(origId);
1418 }
1419 }
1420 }
1421
1422 @Override
1423 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
1424 final long origId = Binder.clearCallingIdentity();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001425 try {
1426 WindowProcessController proc = null;
1427 synchronized (mGlobalLock) {
1428 ActivityStack stack = ActivityRecord.getStackLocked(token);
1429 if (stack == null) {
1430 return;
1431 }
1432 final ActivityRecord r = mStackSupervisor.activityIdleInternalLocked(token,
1433 false /* fromTimeout */, false /* processPausingActivities */, config);
1434 if (r != null) {
1435 proc = r.app;
1436 }
1437 if (stopProfiling && proc != null) {
1438 proc.clearProfilerIfNeeded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001439 }
1440 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001441 } finally {
1442 Binder.restoreCallingIdentity(origId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001443 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001444 }
1445
1446 @Override
1447 public final void activityResumed(IBinder token) {
1448 final long origId = Binder.clearCallingIdentity();
1449 synchronized (mGlobalLock) {
1450 ActivityRecord.activityResumedLocked(token);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001451 mWindowManager.notifyAppResumedFinished(token);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001452 }
1453 Binder.restoreCallingIdentity(origId);
1454 }
1455
1456 @Override
1457 public final void activityPaused(IBinder token) {
1458 final long origId = Binder.clearCallingIdentity();
1459 synchronized (mGlobalLock) {
1460 ActivityStack stack = ActivityRecord.getStackLocked(token);
1461 if (stack != null) {
1462 stack.activityPausedLocked(token, false);
1463 }
1464 }
1465 Binder.restoreCallingIdentity(origId);
1466 }
1467
1468 @Override
1469 public final void activityStopped(IBinder token, Bundle icicle,
1470 PersistableBundle persistentState, CharSequence description) {
1471 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
1472
1473 // Refuse possible leaked file descriptors
1474 if (icicle != null && icicle.hasFileDescriptors()) {
1475 throw new IllegalArgumentException("File descriptors passed in Bundle");
1476 }
1477
1478 final long origId = Binder.clearCallingIdentity();
1479
1480 synchronized (mGlobalLock) {
1481 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1482 if (r != null) {
1483 r.activityStoppedLocked(icicle, persistentState, description);
1484 }
1485 }
1486
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001487 mAmInternal.trimApplications();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001488
1489 Binder.restoreCallingIdentity(origId);
1490 }
1491
1492 @Override
1493 public final void activityDestroyed(IBinder token) {
1494 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
1495 synchronized (mGlobalLock) {
1496 ActivityStack stack = ActivityRecord.getStackLocked(token);
1497 if (stack != null) {
1498 stack.activityDestroyedLocked(token, "activityDestroyed");
1499 }
1500 }
1501 }
1502
1503 @Override
1504 public final void activityRelaunched(IBinder token) {
1505 final long origId = Binder.clearCallingIdentity();
1506 synchronized (mGlobalLock) {
1507 mStackSupervisor.activityRelaunchedLocked(token);
1508 }
1509 Binder.restoreCallingIdentity(origId);
1510 }
1511
1512 public final void activitySlept(IBinder token) {
1513 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
1514
1515 final long origId = Binder.clearCallingIdentity();
1516
1517 synchronized (mGlobalLock) {
1518 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1519 if (r != null) {
1520 mStackSupervisor.activitySleptLocked(r);
1521 }
1522 }
1523
1524 Binder.restoreCallingIdentity(origId);
1525 }
1526
1527 @Override
1528 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
1529 synchronized (mGlobalLock) {
1530 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1531 if (r == null) {
1532 return;
1533 }
1534 final long origId = Binder.clearCallingIdentity();
1535 try {
1536 r.setRequestedOrientation(requestedOrientation);
1537 } finally {
1538 Binder.restoreCallingIdentity(origId);
1539 }
1540 }
1541 }
1542
1543 @Override
1544 public int getRequestedOrientation(IBinder token) {
1545 synchronized (mGlobalLock) {
1546 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1547 if (r == null) {
1548 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
1549 }
1550 return r.getRequestedOrientation();
1551 }
1552 }
1553
1554 @Override
1555 public void setImmersive(IBinder token, boolean immersive) {
1556 synchronized (mGlobalLock) {
1557 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1558 if (r == null) {
1559 throw new IllegalArgumentException();
1560 }
1561 r.immersive = immersive;
1562
1563 // update associated state if we're frontmost
Andrii Kulian52d255c2018-07-13 11:32:19 -07001564 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001565 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001566 applyUpdateLockStateLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001567 }
1568 }
1569 }
1570
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001571 void applyUpdateLockStateLocked(ActivityRecord r) {
1572 // Modifications to the UpdateLock state are done on our handler, outside
1573 // the activity manager's locks. The new state is determined based on the
1574 // state *now* of the relevant activity record. The object is passed to
1575 // the handler solely for logging detail, not to be consulted/modified.
1576 final boolean nextState = r != null && r.immersive;
1577 mH.post(() -> {
1578 if (mUpdateLock.isHeld() != nextState) {
1579 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1580 "Applying new update lock state '" + nextState + "' for " + r);
1581 if (nextState) {
1582 mUpdateLock.acquire();
1583 } else {
1584 mUpdateLock.release();
1585 }
1586 }
1587 });
1588 }
1589
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001590 @Override
1591 public boolean isImmersive(IBinder token) {
1592 synchronized (mGlobalLock) {
1593 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1594 if (r == null) {
1595 throw new IllegalArgumentException();
1596 }
1597 return r.immersive;
1598 }
1599 }
1600
1601 @Override
1602 public boolean isTopActivityImmersive() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001603 enforceNotIsolatedCaller("isTopActivityImmersive");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001604 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001605 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001606 return (r != null) ? r.immersive : false;
1607 }
1608 }
1609
1610 @Override
1611 public void overridePendingTransition(IBinder token, String packageName,
1612 int enterAnim, int exitAnim) {
1613 synchronized (mGlobalLock) {
1614 ActivityRecord self = ActivityRecord.isInStackLocked(token);
1615 if (self == null) {
1616 return;
1617 }
1618
1619 final long origId = Binder.clearCallingIdentity();
1620
1621 if (self.isState(
1622 ActivityStack.ActivityState.RESUMED, ActivityStack.ActivityState.PAUSING)) {
lumark588a3e82018-07-20 18:53:54 +08001623 self.getDisplay().getWindowContainerController().overridePendingAppTransition(
1624 packageName, enterAnim, exitAnim, null);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001625 }
1626
1627 Binder.restoreCallingIdentity(origId);
1628 }
1629 }
1630
1631 @Override
1632 public int getFrontActivityScreenCompatMode() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001633 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001634 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001635 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001636 if (r == null) {
1637 return ActivityManager.COMPAT_MODE_UNKNOWN;
1638 }
Wale Ogunwale53783742018-09-16 10:21:51 -07001639 return mCompatModePackages.computeCompatModeLocked(r.info.applicationInfo);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001640 }
1641 }
1642
1643 @Override
1644 public void setFrontActivityScreenCompatMode(int mode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001645 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001646 "setFrontActivityScreenCompatMode");
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001647 ApplicationInfo ai;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001648 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001649 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001650 if (r == null) {
1651 Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity");
1652 return;
1653 }
1654 ai = r.info.applicationInfo;
Wale Ogunwale53783742018-09-16 10:21:51 -07001655 mCompatModePackages.setPackageScreenCompatModeLocked(ai, mode);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001656 }
1657 }
1658
1659 @Override
1660 public int getLaunchedFromUid(IBinder activityToken) {
1661 ActivityRecord srec;
1662 synchronized (mGlobalLock) {
1663 srec = ActivityRecord.forTokenLocked(activityToken);
1664 }
1665 if (srec == null) {
1666 return -1;
1667 }
1668 return srec.launchedFromUid;
1669 }
1670
1671 @Override
1672 public String getLaunchedFromPackage(IBinder activityToken) {
1673 ActivityRecord srec;
1674 synchronized (mGlobalLock) {
1675 srec = ActivityRecord.forTokenLocked(activityToken);
1676 }
1677 if (srec == null) {
1678 return null;
1679 }
1680 return srec.launchedFromPackage;
1681 }
1682
1683 @Override
1684 public boolean convertFromTranslucent(IBinder token) {
1685 final long origId = Binder.clearCallingIdentity();
1686 try {
1687 synchronized (mGlobalLock) {
1688 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1689 if (r == null) {
1690 return false;
1691 }
1692 final boolean translucentChanged = r.changeWindowTranslucency(true);
1693 if (translucentChanged) {
1694 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
1695 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001696 mWindowManager.setAppFullscreen(token, true);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001697 return translucentChanged;
1698 }
1699 } finally {
1700 Binder.restoreCallingIdentity(origId);
1701 }
1702 }
1703
1704 @Override
1705 public boolean convertToTranslucent(IBinder token, Bundle options) {
1706 SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
1707 final long origId = Binder.clearCallingIdentity();
1708 try {
1709 synchronized (mGlobalLock) {
1710 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1711 if (r == null) {
1712 return false;
1713 }
1714 final TaskRecord task = r.getTask();
1715 int index = task.mActivities.lastIndexOf(r);
1716 if (index > 0) {
1717 ActivityRecord under = task.mActivities.get(index - 1);
1718 under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
1719 }
1720 final boolean translucentChanged = r.changeWindowTranslucency(false);
1721 if (translucentChanged) {
1722 r.getStack().convertActivityToTranslucent(r);
1723 }
1724 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001725 mWindowManager.setAppFullscreen(token, false);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001726 return translucentChanged;
1727 }
1728 } finally {
1729 Binder.restoreCallingIdentity(origId);
1730 }
1731 }
1732
1733 @Override
1734 public void notifyActivityDrawn(IBinder token) {
1735 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
1736 synchronized (mGlobalLock) {
1737 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
1738 if (r != null) {
1739 r.getStack().notifyActivityDrawnLocked(r);
1740 }
1741 }
1742 }
1743
1744 @Override
1745 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
1746 synchronized (mGlobalLock) {
1747 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1748 if (r == null) {
1749 return;
1750 }
1751 r.reportFullyDrawnLocked(restoredFromBundle);
1752 }
1753 }
1754
1755 @Override
1756 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
1757 synchronized (mGlobalLock) {
1758 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
1759 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
1760 return stack.mDisplayId;
1761 }
1762 return DEFAULT_DISPLAY;
1763 }
1764 }
1765
1766 @Override
1767 public ActivityManager.StackInfo getFocusedStackInfo() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001768 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001769 long ident = Binder.clearCallingIdentity();
1770 try {
1771 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001772 ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001773 if (focusedStack != null) {
1774 return mStackSupervisor.getStackInfo(focusedStack.mStackId);
1775 }
1776 return null;
1777 }
1778 } finally {
1779 Binder.restoreCallingIdentity(ident);
1780 }
1781 }
1782
1783 @Override
1784 public void setFocusedStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001785 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001786 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
1787 final long callingId = Binder.clearCallingIdentity();
1788 try {
1789 synchronized (mGlobalLock) {
1790 final ActivityStack stack = mStackSupervisor.getStack(stackId);
1791 if (stack == null) {
1792 Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
1793 return;
1794 }
1795 final ActivityRecord r = stack.topRunningActivityLocked();
Louis Chang19443452018-10-09 12:10:21 +08001796 if (r != null && r.moveFocusableActivityToTop("setFocusedStack")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08001797 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001798 }
1799 }
1800 } finally {
1801 Binder.restoreCallingIdentity(callingId);
1802 }
1803 }
1804
1805 @Override
1806 public void setFocusedTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001807 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001808 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
1809 final long callingId = Binder.clearCallingIdentity();
1810 try {
1811 synchronized (mGlobalLock) {
1812 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1813 if (task == null) {
1814 return;
1815 }
1816 final ActivityRecord r = task.topRunningActivityLocked();
Louis Chang19443452018-10-09 12:10:21 +08001817 if (r != null && r.moveFocusableActivityToTop("setFocusedTask")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08001818 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001819 }
1820 }
1821 } finally {
1822 Binder.restoreCallingIdentity(callingId);
1823 }
1824 }
1825
1826 @Override
1827 public boolean removeTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001828 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001829 synchronized (mGlobalLock) {
1830 final long ident = Binder.clearCallingIdentity();
1831 try {
1832 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
1833 "remove-task");
1834 } finally {
1835 Binder.restoreCallingIdentity(ident);
1836 }
1837 }
1838 }
1839
1840 @Override
Winson Chunge6439102018-07-30 15:48:01 -07001841 public void removeAllVisibleRecentTasks() {
1842 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeAllVisibleRecentTasks()");
1843 synchronized (mGlobalLock) {
1844 final long ident = Binder.clearCallingIdentity();
1845 try {
1846 getRecentTasks().removeAllVisibleTasks();
1847 } finally {
1848 Binder.restoreCallingIdentity(ident);
1849 }
1850 }
1851 }
1852
1853 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001854 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
1855 synchronized (mGlobalLock) {
1856 final ActivityRecord srec = ActivityRecord.forTokenLocked(token);
1857 if (srec != null) {
1858 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
1859 }
1860 }
1861 return false;
1862 }
1863
1864 @Override
1865 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
1866 Intent resultData) {
1867
1868 synchronized (mGlobalLock) {
1869 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
1870 if (r != null) {
1871 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
1872 }
1873 return false;
1874 }
1875 }
1876
1877 /**
1878 * Attempts to move a task backwards in z-order (the order of activities within the task is
1879 * unchanged).
1880 *
1881 * There are several possible results of this call:
1882 * - if the task is locked, then we will show the lock toast
1883 * - if there is a task behind the provided task, then that task is made visible and resumed as
1884 * this task is moved to the back
1885 * - otherwise, if there are no other tasks in the stack:
1886 * - if this task is in the pinned stack, then we remove the stack completely, which will
1887 * have the effect of moving the task to the top or bottom of the fullscreen stack
1888 * (depending on whether it is visible)
1889 * - otherwise, we simply return home and hide this task
1890 *
1891 * @param token A reference to the activity we wish to move
1892 * @param nonRoot If false then this only works if the activity is the root
1893 * of a task; if true it will work for any activity in a task.
1894 * @return Returns true if the move completed, false if not.
1895 */
1896 @Override
1897 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001898 enforceNotIsolatedCaller("moveActivityTaskToBack");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001899 synchronized (mGlobalLock) {
1900 final long origId = Binder.clearCallingIdentity();
1901 try {
1902 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
1903 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1904 if (task != null) {
1905 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
1906 }
1907 } finally {
1908 Binder.restoreCallingIdentity(origId);
1909 }
1910 }
1911 return false;
1912 }
1913
1914 @Override
1915 public Rect getTaskBounds(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001916 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001917 long ident = Binder.clearCallingIdentity();
1918 Rect rect = new Rect();
1919 try {
1920 synchronized (mGlobalLock) {
1921 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
1922 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1923 if (task == null) {
1924 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
1925 return rect;
1926 }
1927 if (task.getStack() != null) {
1928 // Return the bounds from window manager since it will be adjusted for various
1929 // things like the presense of a docked stack for tasks that aren't resizeable.
1930 task.getWindowContainerBounds(rect);
1931 } else {
1932 // Task isn't in window manager yet since it isn't associated with a stack.
1933 // Return the persist value from activity manager
1934 if (!task.matchParentBounds()) {
1935 rect.set(task.getBounds());
1936 } else if (task.mLastNonFullscreenBounds != null) {
1937 rect.set(task.mLastNonFullscreenBounds);
1938 }
1939 }
1940 }
1941 } finally {
1942 Binder.restoreCallingIdentity(ident);
1943 }
1944 return rect;
1945 }
1946
1947 @Override
1948 public ActivityManager.TaskDescription getTaskDescription(int id) {
1949 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001950 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001951 MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
1952 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
1953 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1954 if (tr != null) {
1955 return tr.lastTaskDescription;
1956 }
1957 }
1958 return null;
1959 }
1960
1961 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001962 public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
1963 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
1964 setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
1965 toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
1966 return;
1967 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001968 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001969 synchronized (mGlobalLock) {
1970 final long ident = Binder.clearCallingIdentity();
1971 try {
1972 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1973 if (task == null) {
1974 Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
1975 return;
1976 }
1977
1978 if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
1979 + " to windowingMode=" + windowingMode + " toTop=" + toTop);
1980
1981 if (!task.isActivityTypeStandardOrUndefined()) {
1982 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
1983 + " non-standard task " + taskId + " to windowing mode="
1984 + windowingMode);
1985 }
1986
1987 final ActivityStack stack = task.getStack();
1988 if (toTop) {
1989 stack.moveToFront("setTaskWindowingMode", task);
1990 }
1991 stack.setWindowingMode(windowingMode);
1992 } finally {
1993 Binder.restoreCallingIdentity(ident);
1994 }
1995 }
1996 }
1997
1998 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001999 public String getCallingPackage(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002000 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002001 ActivityRecord r = getCallingRecordLocked(token);
2002 return r != null ? r.info.packageName : null;
2003 }
2004 }
2005
2006 @Override
2007 public ComponentName getCallingActivity(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002008 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002009 ActivityRecord r = getCallingRecordLocked(token);
2010 return r != null ? r.intent.getComponent() : null;
2011 }
2012 }
2013
2014 private ActivityRecord getCallingRecordLocked(IBinder token) {
2015 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2016 if (r == null) {
2017 return null;
2018 }
2019 return r.resultTo;
2020 }
2021
2022 @Override
2023 public void unhandledBack() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002024 mAmInternal.enforceCallingPermission(android.Manifest.permission.FORCE_BACK, "unhandledBack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002025
2026 synchronized (mGlobalLock) {
2027 final long origId = Binder.clearCallingIdentity();
2028 try {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002029 getTopDisplayFocusedStack().unhandledBackLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002030 } finally {
2031 Binder.restoreCallingIdentity(origId);
2032 }
2033 }
2034 }
2035
2036 /**
2037 * TODO: Add mController hook
2038 */
2039 @Override
2040 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002041 mAmInternal.enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002042
2043 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
2044 synchronized (mGlobalLock) {
2045 moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
2046 false /* fromRecents */);
2047 }
2048 }
2049
2050 void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
2051 boolean fromRecents) {
2052
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002053 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002054 Binder.getCallingUid(), -1, -1, "Task to front")) {
2055 SafeActivityOptions.abort(options);
2056 return;
2057 }
2058 final long origId = Binder.clearCallingIdentity();
2059 try {
2060 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2061 if (task == null) {
2062 Slog.d(TAG, "Could not find task for id: "+ taskId);
Winson Chungd0243682018-09-25 18:11:54 -07002063 SafeActivityOptions.abort(options);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002064 return;
2065 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002066 if (getLockTaskController().isLockTaskModeViolation(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002067 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
Winson Chungd0243682018-09-25 18:11:54 -07002068 SafeActivityOptions.abort(options);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002069 return;
2070 }
2071 ActivityOptions realOptions = options != null
2072 ? options.getOptions(mStackSupervisor)
2073 : null;
2074 mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
2075 false /* forceNonResizable */);
2076
2077 final ActivityRecord topActivity = task.getTopActivity();
2078 if (topActivity != null) {
2079
2080 // We are reshowing a task, use a starting window to hide the initial draw delay
2081 // so the transition can start earlier.
2082 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
2083 true /* taskSwitch */, fromRecents);
2084 }
2085 } finally {
2086 Binder.restoreCallingIdentity(origId);
2087 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002088 }
2089
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002090 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
2091 int callingPid, int callingUid, String name) {
2092 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
2093 return true;
2094 }
2095
2096 if (getRecentTasks().isCallerRecents(sourceUid)) {
2097 return true;
2098 }
2099
2100 int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
2101 if (perm == PackageManager.PERMISSION_GRANTED) {
2102 return true;
2103 }
2104 if (checkAllowAppSwitchUid(sourceUid)) {
2105 return true;
2106 }
2107
2108 // If the actual IPC caller is different from the logical source, then
2109 // also see if they are allowed to control app switches.
2110 if (callingUid != -1 && callingUid != sourceUid) {
2111 perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
2112 if (perm == PackageManager.PERMISSION_GRANTED) {
2113 return true;
2114 }
2115 if (checkAllowAppSwitchUid(callingUid)) {
2116 return true;
2117 }
2118 }
2119
2120 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
2121 return false;
2122 }
2123
2124 private boolean checkAllowAppSwitchUid(int uid) {
2125 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
2126 if (types != null) {
2127 for (int i = types.size() - 1; i >= 0; i--) {
2128 if (types.valueAt(i).intValue() == uid) {
2129 return true;
2130 }
2131 }
2132 }
2133 return false;
2134 }
2135
2136 @Override
2137 public void setActivityController(IActivityController controller, boolean imAMonkey) {
2138 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
2139 "setActivityController()");
2140 synchronized (mGlobalLock) {
2141 mController = controller;
2142 mControllerIsAMonkey = imAMonkey;
2143 Watchdog.getInstance().setActivityController(controller);
2144 }
2145 }
2146
Wale Ogunwale387b34c2018-10-25 19:59:40 -07002147 public boolean isControllerAMonkey() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002148 synchronized (mGlobalLock) {
2149 return mController != null && mControllerIsAMonkey;
2150 }
2151 }
2152
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002153 @Override
2154 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
2155 synchronized (mGlobalLock) {
2156 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
2157 }
2158 }
2159
2160 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002161 public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum) {
2162 return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
2163 }
2164
2165 @Override
2166 public List<ActivityManager.RunningTaskInfo> getFilteredTasks(int maxNum,
2167 @WindowConfiguration.ActivityType int ignoreActivityType,
2168 @WindowConfiguration.WindowingMode int ignoreWindowingMode) {
2169 final int callingUid = Binder.getCallingUid();
2170 ArrayList<ActivityManager.RunningTaskInfo> list = new ArrayList<>();
2171
2172 synchronized (mGlobalLock) {
2173 if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
2174
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002175 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002176 callingUid);
2177 mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
2178 ignoreWindowingMode, callingUid, allowed);
2179 }
2180
2181 return list;
2182 }
2183
2184 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002185 public final void finishSubActivity(IBinder token, String resultWho, int requestCode) {
2186 synchronized (mGlobalLock) {
2187 final long origId = Binder.clearCallingIdentity();
2188 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2189 if (r != null) {
2190 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
2191 }
2192 Binder.restoreCallingIdentity(origId);
2193 }
2194 }
2195
2196 @Override
2197 public boolean willActivityBeVisible(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002198 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002199 ActivityStack stack = ActivityRecord.getStackLocked(token);
2200 if (stack != null) {
2201 return stack.willActivityBeVisibleLocked(token);
2202 }
2203 return false;
2204 }
2205 }
2206
2207 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002208 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002209 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002210 synchronized (mGlobalLock) {
2211 final long ident = Binder.clearCallingIdentity();
2212 try {
2213 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2214 if (task == null) {
2215 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
2216 return;
2217 }
2218
2219 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
2220 + " to stackId=" + stackId + " toTop=" + toTop);
2221
2222 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2223 if (stack == null) {
2224 throw new IllegalStateException(
2225 "moveTaskToStack: No stack for stackId=" + stackId);
2226 }
2227 if (!stack.isActivityTypeStandardOrUndefined()) {
2228 throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
2229 + taskId + " to stack " + stackId);
2230 }
2231 if (stack.inSplitScreenPrimaryWindowingMode()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002232 mWindowManager.setDockedStackCreateState(
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002233 SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
2234 }
2235 task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
2236 "moveTaskToStack");
2237 } finally {
2238 Binder.restoreCallingIdentity(ident);
2239 }
2240 }
2241 }
2242
2243 @Override
2244 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
2245 boolean preserveWindows, boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002246 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002247
2248 final long ident = Binder.clearCallingIdentity();
2249 try {
2250 synchronized (mGlobalLock) {
2251 if (animate) {
2252 final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
2253 if (stack == null) {
2254 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2255 return;
2256 }
2257 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
2258 throw new IllegalArgumentException("Stack: " + stackId
2259 + " doesn't support animated resize.");
2260 }
2261 stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
2262 animationDuration, false /* fromFullscreen */);
2263 } else {
2264 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2265 if (stack == null) {
2266 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2267 return;
2268 }
2269 mStackSupervisor.resizeStackLocked(stack, destBounds,
2270 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
2271 preserveWindows, allowResizeInDockedMode, !DEFER_RESUME);
2272 }
2273 }
2274 } finally {
2275 Binder.restoreCallingIdentity(ident);
2276 }
2277 }
2278
2279 /**
2280 * Moves the specified task to the primary-split-screen stack.
2281 *
2282 * @param taskId Id of task to move.
2283 * @param createMode The mode the primary split screen stack should be created in if it doesn't
2284 * exist already. See
2285 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
2286 * and
2287 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
2288 * @param toTop If the task and stack should be moved to the top.
2289 * @param animate Whether we should play an animation for the moving the task.
2290 * @param initialBounds If the primary stack gets created, it will use these bounds for the
2291 * stack. Pass {@code null} to use default bounds.
2292 * @param showRecents If the recents activity should be shown on the other side of the task
2293 * going into split-screen mode.
2294 */
2295 @Override
2296 public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode,
2297 boolean toTop, boolean animate, Rect initialBounds, boolean showRecents) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002298 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002299 "setTaskWindowingModeSplitScreenPrimary()");
2300 synchronized (mGlobalLock) {
2301 final long ident = Binder.clearCallingIdentity();
2302 try {
2303 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2304 if (task == null) {
2305 Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
2306 return false;
2307 }
2308 if (DEBUG_STACK) Slog.d(TAG_STACK,
2309 "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
2310 + " to createMode=" + createMode + " toTop=" + toTop);
2311 if (!task.isActivityTypeStandardOrUndefined()) {
2312 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
2313 + " non-standard task " + taskId + " to split-screen windowing mode");
2314 }
2315
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002316 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002317 final int windowingMode = task.getWindowingMode();
2318 final ActivityStack stack = task.getStack();
2319 if (toTop) {
2320 stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
2321 }
2322 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
2323 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */);
2324 return windowingMode != task.getWindowingMode();
2325 } finally {
2326 Binder.restoreCallingIdentity(ident);
2327 }
2328 }
2329 }
2330
2331 /**
2332 * Removes stacks in the input windowing modes from the system if they are of activity type
2333 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
2334 */
2335 @Override
2336 public void removeStacksInWindowingModes(int[] windowingModes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002337 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002338 "removeStacksInWindowingModes()");
2339
2340 synchronized (mGlobalLock) {
2341 final long ident = Binder.clearCallingIdentity();
2342 try {
2343 mStackSupervisor.removeStacksInWindowingModes(windowingModes);
2344 } finally {
2345 Binder.restoreCallingIdentity(ident);
2346 }
2347 }
2348 }
2349
2350 @Override
2351 public void removeStacksWithActivityTypes(int[] activityTypes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002352 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002353 "removeStacksWithActivityTypes()");
2354
2355 synchronized (mGlobalLock) {
2356 final long ident = Binder.clearCallingIdentity();
2357 try {
2358 mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
2359 } finally {
2360 Binder.restoreCallingIdentity(ident);
2361 }
2362 }
2363 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002364
2365 @Override
2366 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
2367 int userId) {
2368 final int callingUid = Binder.getCallingUid();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002369 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, "getRecentTasks");
2370 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002371 callingUid);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002372 final boolean detailed = checkGetTasksPermission(
2373 android.Manifest.permission.GET_DETAILED_TASKS, Binder.getCallingPid(),
2374 UserHandle.getAppId(callingUid))
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002375 == PackageManager.PERMISSION_GRANTED;
2376
2377 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002378 return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002379 callingUid);
2380 }
2381 }
2382
2383 @Override
2384 public List<ActivityManager.StackInfo> getAllStackInfos() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002385 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002386 long ident = Binder.clearCallingIdentity();
2387 try {
2388 synchronized (mGlobalLock) {
2389 return mStackSupervisor.getAllStackInfosLocked();
2390 }
2391 } finally {
2392 Binder.restoreCallingIdentity(ident);
2393 }
2394 }
2395
2396 @Override
2397 public ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002398 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002399 long ident = Binder.clearCallingIdentity();
2400 try {
2401 synchronized (mGlobalLock) {
2402 return mStackSupervisor.getStackInfo(windowingMode, activityType);
2403 }
2404 } finally {
2405 Binder.restoreCallingIdentity(ident);
2406 }
2407 }
2408
2409 @Override
2410 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002411 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002412 final long callingUid = Binder.getCallingUid();
2413 final long origId = Binder.clearCallingIdentity();
2414 try {
2415 synchronized (mGlobalLock) {
2416 // Cancel the recents animation synchronously (do not hold the WM lock)
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002417 mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002418 ? REORDER_MOVE_TO_ORIGINAL_POSITION
2419 : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
2420 }
2421 } finally {
2422 Binder.restoreCallingIdentity(origId);
2423 }
2424 }
2425
2426 @Override
2427 public void startLockTaskModeByToken(IBinder token) {
2428 synchronized (mGlobalLock) {
2429 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2430 if (r == null) {
2431 return;
2432 }
2433 startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
2434 }
2435 }
2436
2437 @Override
2438 public void startSystemLockTaskMode(int taskId) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002439 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002440 // This makes inner call to look as if it was initiated by system.
2441 long ident = Binder.clearCallingIdentity();
2442 try {
2443 synchronized (mGlobalLock) {
2444 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2445
2446 // When starting lock task mode the stack must be in front and focused
2447 task.getStack().moveToFront("startSystemLockTaskMode");
2448 startLockTaskModeLocked(task, true /* isSystemCaller */);
2449 }
2450 } finally {
2451 Binder.restoreCallingIdentity(ident);
2452 }
2453 }
2454
2455 @Override
2456 public void stopLockTaskModeByToken(IBinder token) {
2457 synchronized (mGlobalLock) {
2458 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2459 if (r == null) {
2460 return;
2461 }
2462 stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
2463 }
2464 }
2465
2466 /**
2467 * This API should be called by SystemUI only when user perform certain action to dismiss
2468 * lock task mode. We should only dismiss pinned lock task mode in this case.
2469 */
2470 @Override
2471 public void stopSystemLockTaskMode() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002472 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002473 stopLockTaskModeInternal(null, true /* isSystemCaller */);
2474 }
2475
2476 private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
2477 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
2478 if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
2479 return;
2480 }
2481
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002482 final ActivityStack stack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002483 if (stack == null || task != stack.topTask()) {
2484 throw new IllegalArgumentException("Invalid task, not in foreground");
2485 }
2486
2487 // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
2488 // system or a specific app.
2489 // * System-initiated requests will only start the pinned mode (screen pinning)
2490 // * App-initiated requests
2491 // - will put the device in fully locked mode (LockTask), if the app is whitelisted
2492 // - will start the pinned mode, otherwise
2493 final int callingUid = Binder.getCallingUid();
2494 long ident = Binder.clearCallingIdentity();
2495 try {
2496 // When a task is locked, dismiss the pinned stack if it exists
2497 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2498
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002499 getLockTaskController().startLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002500 } finally {
2501 Binder.restoreCallingIdentity(ident);
2502 }
2503 }
2504
2505 private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
2506 final int callingUid = Binder.getCallingUid();
2507 long ident = Binder.clearCallingIdentity();
2508 try {
2509 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002510 getLockTaskController().stopLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002511 }
2512 // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
2513 // task and jumping straight into a call in the case of emergency call back.
2514 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
2515 if (tm != null) {
2516 tm.showInCallScreen(false);
2517 }
2518 } finally {
2519 Binder.restoreCallingIdentity(ident);
2520 }
2521 }
2522
2523 @Override
Wale Ogunwale27c48ae2018-10-25 19:01:01 -07002524 public void updateLockTaskPackages(int userId, String[] packages) {
2525 final int callingUid = Binder.getCallingUid();
2526 if (callingUid != 0 && callingUid != SYSTEM_UID) {
2527 mAmInternal.enforceCallingPermission(Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
2528 "updateLockTaskPackages()");
2529 }
2530 synchronized (this) {
2531 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":"
2532 + Arrays.toString(packages));
2533 getLockTaskController().updateLockTaskPackages(userId, packages);
2534 }
2535 }
2536
2537 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002538 public boolean isInLockTaskMode() {
2539 return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
2540 }
2541
2542 @Override
2543 public int getLockTaskModeState() {
2544 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002545 return getLockTaskController().getLockTaskModeState();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002546 }
2547 }
2548
2549 @Override
2550 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
2551 synchronized (mGlobalLock) {
2552 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2553 if (r != null) {
2554 r.setTaskDescription(td);
2555 final TaskRecord task = r.getTask();
2556 task.updateTaskDescription();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002557 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002558 }
2559 }
2560 }
2561
2562 @Override
2563 public Bundle getActivityOptions(IBinder token) {
2564 final long origId = Binder.clearCallingIdentity();
2565 try {
2566 synchronized (mGlobalLock) {
2567 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
2568 if (r != null) {
2569 final ActivityOptions activityOptions = r.takeOptionsLocked();
2570 return activityOptions == null ? null : activityOptions.toBundle();
2571 }
2572 return null;
2573 }
2574 } finally {
2575 Binder.restoreCallingIdentity(origId);
2576 }
2577 }
2578
2579 @Override
2580 public List<IBinder> getAppTasks(String callingPackage) {
2581 int callingUid = Binder.getCallingUid();
2582 long ident = Binder.clearCallingIdentity();
2583 try {
2584 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002585 return mRecentTasks.getAppTasksList(callingUid, callingPackage);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002586 }
2587 } finally {
2588 Binder.restoreCallingIdentity(ident);
2589 }
2590 }
2591
2592 @Override
2593 public void finishVoiceTask(IVoiceInteractionSession session) {
2594 synchronized (mGlobalLock) {
2595 final long origId = Binder.clearCallingIdentity();
2596 try {
2597 // TODO: VI Consider treating local voice interactions and voice tasks
2598 // differently here
2599 mStackSupervisor.finishVoiceTask(session);
2600 } finally {
2601 Binder.restoreCallingIdentity(origId);
2602 }
2603 }
2604
2605 }
2606
2607 @Override
2608 public boolean isTopOfTask(IBinder token) {
2609 synchronized (mGlobalLock) {
2610 ActivityRecord r = ActivityRecord.isInStackLocked(token);
Riddle Hsu66b74a82018-07-26 00:20:12 +08002611 return r != null && r.getTask().getTopActivity() == r;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002612 }
2613 }
2614
2615 @Override
2616 public void notifyLaunchTaskBehindComplete(IBinder token) {
2617 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
2618 }
2619
2620 @Override
2621 public void notifyEnterAnimationComplete(IBinder token) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002622 mH.post(() -> {
2623 synchronized (mGlobalLock) {
2624 ActivityRecord r = ActivityRecord.forTokenLocked(token);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002625 if (r != null && r.attachedToProcess()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002626 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002627 r.app.getThread().scheduleEnterAnimationComplete(r.appToken);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002628 } catch (RemoteException e) {
2629 }
2630 }
2631 }
2632
2633 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002634 }
2635
2636 /** Called from an app when assist data is ready. */
2637 @Override
2638 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
2639 AssistContent content, Uri referrer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002640 PendingAssistExtras pae = (PendingAssistExtras) token;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002641 synchronized (pae) {
2642 pae.result = extras;
2643 pae.structure = structure;
2644 pae.content = content;
2645 if (referrer != null) {
2646 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
2647 }
2648 if (structure != null) {
2649 structure.setHomeActivity(pae.isHome);
2650 }
2651 pae.haveResult = true;
2652 pae.notifyAll();
2653 if (pae.intent == null && pae.receiver == null) {
2654 // Caller is just waiting for the result.
2655 return;
2656 }
2657 }
2658 // We are now ready to launch the assist activity.
2659 IAssistDataReceiver sendReceiver = null;
2660 Bundle sendBundle = null;
2661 synchronized (mGlobalLock) {
2662 buildAssistBundleLocked(pae, extras);
2663 boolean exists = mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002664 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002665 if (!exists) {
2666 // Timed out.
2667 return;
2668 }
2669
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002670 if ((sendReceiver = pae.receiver) != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002671 // Caller wants result sent back to them.
2672 sendBundle = new Bundle();
2673 sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
2674 sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
2675 sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
2676 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
2677 }
2678 }
2679 if (sendReceiver != null) {
2680 try {
2681 sendReceiver.onHandleAssistData(sendBundle);
2682 } catch (RemoteException e) {
2683 }
2684 return;
2685 }
2686
2687 final long ident = Binder.clearCallingIdentity();
2688 try {
2689 if (TextUtils.equals(pae.intent.getAction(),
2690 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
2691 pae.intent.putExtras(pae.extras);
2692 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
2693 } else {
2694 pae.intent.replaceExtras(pae.extras);
2695 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
2696 | Intent.FLAG_ACTIVITY_SINGLE_TOP
2697 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Wale Ogunwale31913b52018-10-13 08:29:31 -07002698 mInternal.closeSystemDialogs("assist");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002699
2700 try {
2701 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
2702 } catch (ActivityNotFoundException e) {
2703 Slog.w(TAG, "No activity to handle assist action.", e);
2704 }
2705 }
2706 } finally {
2707 Binder.restoreCallingIdentity(ident);
2708 }
2709 }
2710
2711 @Override
2712 public int addAppTask(IBinder activityToken, Intent intent,
2713 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
2714 final int callingUid = Binder.getCallingUid();
2715 final long callingIdent = Binder.clearCallingIdentity();
2716
2717 try {
2718 synchronized (mGlobalLock) {
2719 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
2720 if (r == null) {
2721 throw new IllegalArgumentException("Activity does not exist; token="
2722 + activityToken);
2723 }
2724 ComponentName comp = intent.getComponent();
2725 if (comp == null) {
2726 throw new IllegalArgumentException("Intent " + intent
2727 + " must specify explicit component");
2728 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002729 if (thumbnail.getWidth() != mThumbnailWidth
2730 || thumbnail.getHeight() != mThumbnailHeight) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002731 throw new IllegalArgumentException("Bad thumbnail size: got "
2732 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002733 + mThumbnailWidth + "x" + mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002734 }
2735 if (intent.getSelector() != null) {
2736 intent.setSelector(null);
2737 }
2738 if (intent.getSourceBounds() != null) {
2739 intent.setSourceBounds(null);
2740 }
2741 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
2742 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
2743 // The caller has added this as an auto-remove task... that makes no
2744 // sense, so turn off auto-remove.
2745 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
2746 }
2747 }
2748 final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
2749 STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
2750 if (ainfo.applicationInfo.uid != callingUid) {
2751 throw new SecurityException(
2752 "Can't add task for another application: target uid="
2753 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
2754 }
2755
2756 final ActivityStack stack = r.getStack();
2757 final TaskRecord task = stack.createTaskRecord(
2758 mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent,
2759 null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002760 if (!mRecentTasks.addToBottom(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002761 // The app has too many tasks already and we can't add any more
2762 stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
2763 return INVALID_TASK_ID;
2764 }
2765 task.lastTaskDescription.copyFrom(description);
2766
2767 // TODO: Send the thumbnail to WM to store it.
2768
2769 return task.taskId;
2770 }
2771 } finally {
2772 Binder.restoreCallingIdentity(callingIdent);
2773 }
2774 }
2775
2776 @Override
2777 public Point getAppTaskThumbnailSize() {
2778 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002779 return new Point(mThumbnailWidth, mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002780 }
2781 }
2782
2783 @Override
2784 public void setTaskResizeable(int taskId, int resizeableMode) {
2785 synchronized (mGlobalLock) {
2786 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
2787 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
2788 if (task == null) {
2789 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
2790 return;
2791 }
2792 task.setResizeMode(resizeableMode);
2793 }
2794 }
2795
2796 @Override
2797 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002798 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002799 long ident = Binder.clearCallingIdentity();
2800 try {
2801 synchronized (mGlobalLock) {
2802 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2803 if (task == null) {
2804 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
2805 return;
2806 }
2807 // Place the task in the right stack if it isn't there already based on
2808 // the requested bounds.
2809 // The stack transition logic is:
2810 // - a null bounds on a freeform task moves that task to fullscreen
2811 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
2812 // that task to freeform
2813 // - otherwise the task is not moved
2814 ActivityStack stack = task.getStack();
2815 if (!task.getWindowConfiguration().canResizeTask()) {
2816 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
2817 }
2818 if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
2819 stack = stack.getDisplay().getOrCreateStack(
2820 WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
2821 } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
2822 stack = stack.getDisplay().getOrCreateStack(
2823 WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
2824 }
2825
2826 // Reparent the task to the right stack if necessary
2827 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
2828 if (stack != task.getStack()) {
2829 // Defer resume until the task is resized below
2830 task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
2831 DEFER_RESUME, "resizeTask");
2832 preserveWindow = false;
2833 }
2834
2835 // After reparenting (which only resizes the task to the stack bounds), resize the
2836 // task to the actual bounds provided
2837 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
2838 }
2839 } finally {
2840 Binder.restoreCallingIdentity(ident);
2841 }
2842 }
2843
2844 @Override
2845 public boolean releaseActivityInstance(IBinder token) {
2846 synchronized (mGlobalLock) {
2847 final long origId = Binder.clearCallingIdentity();
2848 try {
2849 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2850 if (r == null) {
2851 return false;
2852 }
2853 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
2854 } finally {
2855 Binder.restoreCallingIdentity(origId);
2856 }
2857 }
2858 }
2859
2860 @Override
2861 public void releaseSomeActivities(IApplicationThread appInt) {
2862 synchronized (mGlobalLock) {
2863 final long origId = Binder.clearCallingIdentity();
2864 try {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07002865 final WindowProcessController app = getProcessController(appInt);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002866 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
2867 } finally {
2868 Binder.restoreCallingIdentity(origId);
2869 }
2870 }
2871 }
2872
2873 @Override
2874 public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
2875 int secondaryDisplayShowing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002876 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002877 != PackageManager.PERMISSION_GRANTED) {
2878 throw new SecurityException("Requires permission "
2879 + android.Manifest.permission.DEVICE_POWER);
2880 }
2881
2882 synchronized (mGlobalLock) {
2883 long ident = Binder.clearCallingIdentity();
2884 if (mKeyguardShown != keyguardShowing) {
2885 mKeyguardShown = keyguardShowing;
Wale Ogunwale342fbe92018-10-09 08:44:10 -07002886 final Message msg = PooledLambda.obtainMessage(
2887 ActivityManagerInternal::reportCurKeyguardUsageEvent, mAmInternal,
2888 keyguardShowing);
2889 mH.sendMessage(msg);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002890 }
2891 try {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002892 mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002893 secondaryDisplayShowing);
2894 } finally {
2895 Binder.restoreCallingIdentity(ident);
2896 }
2897 }
2898
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002899 mH.post(() -> {
2900 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2901 mScreenObservers.get(i).onKeyguardStateChanged(keyguardShowing);
2902 }
2903 });
2904 }
2905
Wale Ogunwale387b34c2018-10-25 19:59:40 -07002906 public void onScreenAwakeChanged(boolean isAwake) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002907 mH.post(() -> {
2908 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2909 mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2910 }
2911 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002912 }
2913
2914 @Override
2915 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002916 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
2917 userId, "getTaskDescriptionIcon");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002918
2919 final File passedIconFile = new File(filePath);
2920 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
2921 passedIconFile.getName());
2922 if (!legitIconFile.getPath().equals(filePath)
2923 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
2924 throw new IllegalArgumentException("Bad file path: " + filePath
2925 + " passed for userId " + userId);
2926 }
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002927 return mRecentTasks.getTaskDescriptionIcon(filePath);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002928 }
2929
2930 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002931 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002932 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
2933 final ActivityOptions activityOptions = safeOptions != null
2934 ? safeOptions.getOptions(mStackSupervisor)
2935 : null;
2936 if (activityOptions == null
2937 || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
2938 || activityOptions.getCustomInPlaceResId() == 0) {
2939 throw new IllegalArgumentException("Expected in-place ActivityOption " +
2940 "with valid animation");
2941 }
lumark588a3e82018-07-20 18:53:54 +08002942 // Get top display of front most application.
2943 final ActivityStack focusedStack = getTopDisplayFocusedStack();
2944 if (focusedStack != null) {
2945 final DisplayWindowController dwc =
2946 focusedStack.getDisplay().getWindowContainerController();
2947 dwc.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
2948 dwc.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
2949 activityOptions.getCustomInPlaceResId());
2950 dwc.executeAppTransition();
2951 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002952 }
2953
2954 @Override
2955 public void removeStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002956 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002957 synchronized (mGlobalLock) {
2958 final long ident = Binder.clearCallingIdentity();
2959 try {
2960 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2961 if (stack == null) {
2962 Slog.w(TAG, "removeStack: No stack with id=" + stackId);
2963 return;
2964 }
2965 if (!stack.isActivityTypeStandardOrUndefined()) {
2966 throw new IllegalArgumentException(
2967 "Removing non-standard stack is not allowed.");
2968 }
2969 mStackSupervisor.removeStack(stack);
2970 } finally {
2971 Binder.restoreCallingIdentity(ident);
2972 }
2973 }
2974 }
2975
2976 @Override
2977 public void moveStackToDisplay(int stackId, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002978 mAmInternal.enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002979
2980 synchronized (mGlobalLock) {
2981 final long ident = Binder.clearCallingIdentity();
2982 try {
2983 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
2984 + " to displayId=" + displayId);
2985 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
2986 } finally {
2987 Binder.restoreCallingIdentity(ident);
2988 }
2989 }
2990 }
2991
2992 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002993 public void exitFreeformMode(IBinder token) {
2994 synchronized (mGlobalLock) {
2995 long ident = Binder.clearCallingIdentity();
2996 try {
2997 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2998 if (r == null) {
2999 throw new IllegalArgumentException(
3000 "exitFreeformMode: No activity record matching token=" + token);
3001 }
3002
3003 final ActivityStack stack = r.getStack();
3004 if (stack == null || !stack.inFreeformWindowingMode()) {
3005 throw new IllegalStateException(
3006 "exitFreeformMode: You can only go fullscreen from freeform.");
3007 }
3008
3009 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
3010 } finally {
3011 Binder.restoreCallingIdentity(ident);
3012 }
3013 }
3014 }
3015
3016 /** Sets the task stack listener that gets callbacks when a task stack changes. */
3017 @Override
3018 public void registerTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003019 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003020 "registerTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003021 mTaskChangeNotificationController.registerTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003022 }
3023
3024 /** Unregister a task stack listener so that it stops receiving callbacks. */
3025 @Override
3026 public void unregisterTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003027 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003028 "unregisterTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003029 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003030 }
3031
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003032 @Override
3033 public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
3034 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
3035 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
3036 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
3037 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
3038 }
3039
3040 @Override
3041 public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
3042 IBinder activityToken, int flags) {
3043 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
3044 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
3045 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
3046 }
3047
3048 @Override
3049 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
3050 Bundle args) {
3051 return enqueueAssistContext(requestType, intent, hint, null, null, null,
3052 true /* focused */, true /* newSessionId */, userHandle, args,
3053 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
3054 }
3055
3056 @Override
3057 public Bundle getAssistContextExtras(int requestType) {
3058 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
3059 null, null, true /* focused */, true /* newSessionId */,
3060 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
3061 if (pae == null) {
3062 return null;
3063 }
3064 synchronized (pae) {
3065 while (!pae.haveResult) {
3066 try {
3067 pae.wait();
3068 } catch (InterruptedException e) {
3069 }
3070 }
3071 }
3072 synchronized (mGlobalLock) {
3073 buildAssistBundleLocked(pae, pae.result);
3074 mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003075 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003076 }
3077 return pae.extras;
3078 }
3079
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003080 /**
3081 * Binder IPC calls go through the public entry point.
3082 * This can be called with or without the global lock held.
3083 */
3084 private static int checkCallingPermission(String permission) {
3085 return checkPermission(
3086 permission, Binder.getCallingPid(), UserHandle.getAppId(Binder.getCallingUid()));
3087 }
3088
3089 /** This can be called with or without the global lock held. */
Wale Ogunwale214f3482018-10-04 11:00:47 -07003090 private void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003091 if (!getRecentTasks().isCallerRecents(Binder.getCallingUid())) {
3092 mAmInternal.enforceCallingPermission(permission, func);
3093 }
3094 }
3095
3096 @VisibleForTesting
3097 int checkGetTasksPermission(String permission, int pid, int uid) {
3098 return checkPermission(permission, pid, uid);
3099 }
3100
3101 static int checkPermission(String permission, int pid, int uid) {
3102 if (permission == null) {
3103 return PackageManager.PERMISSION_DENIED;
3104 }
3105 return checkComponentPermission(permission, pid, uid, -1, true);
3106 }
3107
Wale Ogunwale214f3482018-10-04 11:00:47 -07003108 public static int checkComponentPermission(String permission, int pid, int uid,
3109 int owningUid, boolean exported) {
3110 return ActivityManagerService.checkComponentPermission(
3111 permission, pid, uid, owningUid, exported);
3112 }
3113
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003114 boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
3115 if (getRecentTasks().isCallerRecents(callingUid)) {
3116 // Always allow the recents component to get tasks
3117 return true;
3118 }
3119
3120 boolean allowed = checkGetTasksPermission(android.Manifest.permission.REAL_GET_TASKS,
3121 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
3122 if (!allowed) {
3123 if (checkGetTasksPermission(android.Manifest.permission.GET_TASKS,
3124 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
3125 // Temporary compatibility: some existing apps on the system image may
3126 // still be requesting the old permission and not switched to the new
3127 // one; if so, we'll still allow them full access. This means we need
3128 // to see if they are holding the old permission and are a system app.
3129 try {
3130 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
3131 allowed = true;
3132 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
3133 + " is using old GET_TASKS but privileged; allowing");
3134 }
3135 } catch (RemoteException e) {
3136 }
3137 }
3138 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
3139 + " does not hold REAL_GET_TASKS; limiting output");
3140 }
3141 return allowed;
3142 }
3143
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003144 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
3145 IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
3146 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
3147 int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003148 mAmInternal.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003149 "enqueueAssistContext()");
3150
3151 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003152 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003153 if (activity == null) {
3154 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
3155 return null;
3156 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003157 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003158 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
3159 return null;
3160 }
3161 if (focused) {
3162 if (activityToken != null) {
3163 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
3164 if (activity != caller) {
3165 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
3166 + " is not current top " + activity);
3167 return null;
3168 }
3169 }
3170 } else {
3171 activity = ActivityRecord.forTokenLocked(activityToken);
3172 if (activity == null) {
3173 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
3174 + " couldn't be found");
3175 return null;
3176 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003177 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003178 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
3179 return null;
3180 }
3181 }
3182
3183 PendingAssistExtras pae;
3184 Bundle extras = new Bundle();
3185 if (args != null) {
3186 extras.putAll(args);
3187 }
3188 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003189 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003190
3191 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
3192 userHandle);
3193 pae.isHome = activity.isActivityTypeHome();
3194
3195 // Increment the sessionId if necessary
3196 if (newSessionId) {
3197 mViSessionId++;
3198 }
3199 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003200 activity.app.getThread().requestAssistContextExtras(activity.appToken, pae,
3201 requestType, mViSessionId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003202 mPendingAssistExtras.add(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003203 mUiHandler.postDelayed(pae, timeout);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003204 } catch (RemoteException e) {
3205 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
3206 return null;
3207 }
3208 return pae;
3209 }
3210 }
3211
3212 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
3213 if (result != null) {
3214 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
3215 }
3216 if (pae.hint != null) {
3217 pae.extras.putBoolean(pae.hint, true);
3218 }
3219 }
3220
3221 private void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
3222 IAssistDataReceiver receiver;
3223 synchronized (mGlobalLock) {
3224 mPendingAssistExtras.remove(pae);
3225 receiver = pae.receiver;
3226 }
3227 if (receiver != null) {
3228 // Caller wants result sent back to them.
3229 Bundle sendBundle = new Bundle();
3230 // At least return the receiver extras
3231 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
3232 try {
3233 pae.receiver.onHandleAssistData(sendBundle);
3234 } catch (RemoteException e) {
3235 }
3236 }
3237 }
3238
3239 public class PendingAssistExtras extends Binder implements Runnable {
3240 public final ActivityRecord activity;
3241 public boolean isHome;
3242 public final Bundle extras;
3243 public final Intent intent;
3244 public final String hint;
3245 public final IAssistDataReceiver receiver;
3246 public final int userHandle;
3247 public boolean haveResult = false;
3248 public Bundle result = null;
3249 public AssistStructure structure = null;
3250 public AssistContent content = null;
3251 public Bundle receiverExtras;
3252
3253 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
3254 String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
3255 int _userHandle) {
3256 activity = _activity;
3257 extras = _extras;
3258 intent = _intent;
3259 hint = _hint;
3260 receiver = _receiver;
3261 receiverExtras = _receiverExtras;
3262 userHandle = _userHandle;
3263 }
3264
3265 @Override
3266 public void run() {
3267 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
3268 synchronized (this) {
3269 haveResult = true;
3270 notifyAll();
3271 }
3272 pendingAssistExtrasTimedOut(this);
3273 }
3274 }
3275
3276 @Override
3277 public boolean isAssistDataAllowedOnCurrentActivity() {
3278 int userId;
3279 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003280 final ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003281 if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
3282 return false;
3283 }
3284
3285 final ActivityRecord activity = focusedStack.getTopActivity();
3286 if (activity == null) {
3287 return false;
3288 }
3289 userId = activity.userId;
3290 }
3291 return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
3292 }
3293
3294 @Override
3295 public boolean showAssistFromActivity(IBinder token, Bundle args) {
3296 long ident = Binder.clearCallingIdentity();
3297 try {
3298 synchronized (mGlobalLock) {
3299 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003300 ActivityRecord top = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003301 if (top != caller) {
3302 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3303 + " is not current top " + top);
3304 return false;
3305 }
3306 if (!top.nowVisible) {
3307 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3308 + " is not visible");
3309 return false;
3310 }
3311 }
3312 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
3313 token);
3314 } finally {
3315 Binder.restoreCallingIdentity(ident);
3316 }
3317 }
3318
3319 @Override
3320 public boolean isRootVoiceInteraction(IBinder token) {
3321 synchronized (mGlobalLock) {
3322 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3323 if (r == null) {
3324 return false;
3325 }
3326 return r.rootVoiceInteraction;
3327 }
3328 }
3329
Wale Ogunwalef6733932018-06-27 05:14:34 -07003330 private void onLocalVoiceInteractionStartedLocked(IBinder activity,
3331 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
3332 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
3333 if (activityToCallback == null) return;
3334 activityToCallback.setVoiceSessionLocked(voiceSession);
3335
3336 // Inform the activity
3337 try {
3338 activityToCallback.app.getThread().scheduleLocalVoiceInteractionStarted(activity,
3339 voiceInteractor);
3340 long token = Binder.clearCallingIdentity();
3341 try {
3342 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
3343 } finally {
3344 Binder.restoreCallingIdentity(token);
3345 }
3346 // TODO: VI Should we cache the activity so that it's easier to find later
3347 // rather than scan through all the stacks and activities?
3348 } catch (RemoteException re) {
3349 activityToCallback.clearVoiceSessionLocked();
3350 // TODO: VI Should this terminate the voice session?
3351 }
3352 }
3353
3354 private void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
3355 Slog.d(TAG, "<<< startRunningVoiceLocked()");
3356 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
3357 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
3358 boolean wasRunningVoice = mRunningVoice != null;
3359 mRunningVoice = session;
3360 if (!wasRunningVoice) {
3361 mVoiceWakeLock.acquire();
3362 updateSleepIfNeededLocked();
3363 }
3364 }
3365 }
3366
3367 void finishRunningVoiceLocked() {
3368 if (mRunningVoice != null) {
3369 mRunningVoice = null;
3370 mVoiceWakeLock.release();
3371 updateSleepIfNeededLocked();
3372 }
3373 }
3374
3375 @Override
3376 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3377 synchronized (mGlobalLock) {
3378 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3379 if (keepAwake) {
3380 mVoiceWakeLock.acquire();
3381 } else {
3382 mVoiceWakeLock.release();
3383 }
3384 }
3385 }
3386 }
3387
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003388 @Override
3389 public ComponentName getActivityClassForToken(IBinder token) {
3390 synchronized (mGlobalLock) {
3391 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3392 if (r == null) {
3393 return null;
3394 }
3395 return r.intent.getComponent();
3396 }
3397 }
3398
3399 @Override
3400 public String getPackageForToken(IBinder token) {
3401 synchronized (mGlobalLock) {
3402 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3403 if (r == null) {
3404 return null;
3405 }
3406 return r.packageName;
3407 }
3408 }
3409
3410 @Override
3411 public void showLockTaskEscapeMessage(IBinder token) {
3412 synchronized (mGlobalLock) {
3413 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3414 if (r == null) {
3415 return;
3416 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003417 getLockTaskController().showLockTaskToast();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003418 }
3419 }
3420
3421 @Override
3422 public void keyguardGoingAway(int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003423 enforceNotIsolatedCaller("keyguardGoingAway");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003424 final long token = Binder.clearCallingIdentity();
3425 try {
3426 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003427 mKeyguardController.keyguardGoingAway(flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003428 }
3429 } finally {
3430 Binder.restoreCallingIdentity(token);
3431 }
3432 }
3433
3434 /**
3435 * Try to place task to provided position. The final position might be different depending on
3436 * current user and stacks state. The task will be moved to target stack if it's currently in
3437 * different stack.
3438 */
3439 @Override
3440 public void positionTaskInStack(int taskId, int stackId, int position) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003441 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003442 synchronized (mGlobalLock) {
3443 long ident = Binder.clearCallingIdentity();
3444 try {
3445 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
3446 + taskId + " in stackId=" + stackId + " at position=" + position);
3447 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3448 if (task == null) {
3449 throw new IllegalArgumentException("positionTaskInStack: no task for id="
3450 + taskId);
3451 }
3452
3453 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3454
3455 if (stack == null) {
3456 throw new IllegalArgumentException("positionTaskInStack: no stack for id="
3457 + stackId);
3458 }
3459 if (!stack.isActivityTypeStandardOrUndefined()) {
3460 throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
3461 + " the position of task " + taskId + " in/to non-standard stack");
3462 }
3463
3464 // TODO: Have the callers of this API call a separate reparent method if that is
3465 // what they intended to do vs. having this method also do reparenting.
3466 if (task.getStack() == stack) {
3467 // Change position in current stack.
3468 stack.positionChildAt(task, position);
3469 } else {
3470 // Reparent to new stack.
3471 task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
3472 !DEFER_RESUME, "positionTaskInStack");
3473 }
3474 } finally {
3475 Binder.restoreCallingIdentity(ident);
3476 }
3477 }
3478 }
3479
3480 @Override
3481 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
3482 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
3483 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
3484 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
3485 synchronized (mGlobalLock) {
3486 ActivityRecord record = ActivityRecord.isInStackLocked(token);
3487 if (record == null) {
3488 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
3489 + "found for: " + token);
3490 }
3491 record.setSizeConfigurations(horizontalSizeConfiguration,
3492 verticalSizeConfigurations, smallestSizeConfigurations);
3493 }
3494 }
3495
3496 /**
3497 * Dismisses split-screen multi-window mode.
3498 * @param toTop If true the current primary split-screen stack will be placed or left on top.
3499 */
3500 @Override
3501 public void dismissSplitScreenMode(boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003502 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003503 MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
3504 final long ident = Binder.clearCallingIdentity();
3505 try {
3506 synchronized (mGlobalLock) {
3507 final ActivityStack stack =
3508 mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
3509 if (stack == null) {
3510 Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
3511 return;
3512 }
3513
3514 if (toTop) {
3515 // Caller wants the current split-screen primary stack to be the top stack after
3516 // it goes fullscreen, so move it to the front.
3517 stack.moveToFront("dismissSplitScreenMode");
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003518 } else if (mStackSupervisor.isTopDisplayFocusedStack(stack)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003519 // In this case the current split-screen primary stack shouldn't be the top
3520 // stack after it goes fullscreen, but it current has focus, so we move the
3521 // focus to the top-most split-screen secondary stack next to it.
3522 final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
3523 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
3524 if (otherStack != null) {
3525 otherStack.moveToFront("dismissSplitScreenMode_other");
3526 }
3527 }
3528
Evan Rosky10475742018-09-05 19:02:48 -07003529 stack.setWindowingMode(WINDOWING_MODE_UNDEFINED);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003530 }
3531 } finally {
3532 Binder.restoreCallingIdentity(ident);
3533 }
3534 }
3535
3536 /**
3537 * Dismisses Pip
3538 * @param animate True if the dismissal should be animated.
3539 * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
3540 * default animation duration should be used.
3541 */
3542 @Override
3543 public void dismissPip(boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003544 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003545 final long ident = Binder.clearCallingIdentity();
3546 try {
3547 synchronized (mGlobalLock) {
3548 final PinnedActivityStack stack =
3549 mStackSupervisor.getDefaultDisplay().getPinnedStack();
3550 if (stack == null) {
3551 Slog.w(TAG, "dismissPip: pinned stack not found.");
3552 return;
3553 }
3554 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
3555 throw new IllegalArgumentException("Stack: " + stack
3556 + " doesn't support animated resize.");
3557 }
3558 if (animate) {
3559 stack.animateResizePinnedStack(null /* sourceHintBounds */,
3560 null /* destBounds */, animationDuration, false /* fromFullscreen */);
3561 } else {
3562 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
3563 }
3564 }
3565 } finally {
3566 Binder.restoreCallingIdentity(ident);
3567 }
3568 }
3569
3570 @Override
3571 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003572 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003573 synchronized (mGlobalLock) {
3574 mSuppressResizeConfigChanges = suppress;
3575 }
3576 }
3577
3578 /**
3579 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
3580 * animated the stack to the fullscreen, but can also be called if we are relaunching an
3581 * activity and clearing the task at the same time.
3582 */
3583 @Override
3584 // TODO: API should just be about changing windowing modes...
3585 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003586 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003587 "moveTasksToFullscreenStack()");
3588 synchronized (mGlobalLock) {
3589 final long origId = Binder.clearCallingIdentity();
3590 try {
3591 final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
3592 if (stack != null){
3593 if (!stack.isActivityTypeStandardOrUndefined()) {
3594 throw new IllegalArgumentException(
3595 "You can't move tasks from non-standard stacks.");
3596 }
3597 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
3598 }
3599 } finally {
3600 Binder.restoreCallingIdentity(origId);
3601 }
3602 }
3603 }
3604
3605 /**
3606 * Moves the top activity in the input stackId to the pinned stack.
3607 *
3608 * @param stackId Id of stack to move the top activity to pinned stack.
3609 * @param bounds Bounds to use for pinned stack.
3610 *
3611 * @return True if the top activity of the input stack was successfully moved to the pinned
3612 * stack.
3613 */
3614 @Override
3615 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003616 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003617 "moveTopActivityToPinnedStack()");
3618 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003619 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003620 throw new IllegalStateException("moveTopActivityToPinnedStack:"
3621 + "Device doesn't support picture-in-picture mode");
3622 }
3623
3624 long ident = Binder.clearCallingIdentity();
3625 try {
3626 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
3627 } finally {
3628 Binder.restoreCallingIdentity(ident);
3629 }
3630 }
3631 }
3632
3633 @Override
3634 public boolean isInMultiWindowMode(IBinder token) {
3635 final long origId = Binder.clearCallingIdentity();
3636 try {
3637 synchronized (mGlobalLock) {
3638 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3639 if (r == null) {
3640 return false;
3641 }
3642 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
3643 return r.inMultiWindowMode();
3644 }
3645 } finally {
3646 Binder.restoreCallingIdentity(origId);
3647 }
3648 }
3649
3650 @Override
3651 public boolean isInPictureInPictureMode(IBinder token) {
3652 final long origId = Binder.clearCallingIdentity();
3653 try {
3654 synchronized (mGlobalLock) {
3655 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
3656 }
3657 } finally {
3658 Binder.restoreCallingIdentity(origId);
3659 }
3660 }
3661
3662 private boolean isInPictureInPictureMode(ActivityRecord r) {
3663 if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
3664 || r.getStack().isInStackLocked(r) == null) {
3665 return false;
3666 }
3667
3668 // If we are animating to fullscreen then we have already dispatched the PIP mode
3669 // changed, so we should reflect that check here as well.
3670 final PinnedActivityStack stack = r.getStack();
3671 final PinnedStackWindowController windowController = stack.getWindowContainerController();
3672 return !windowController.isAnimatingBoundsToFullscreen();
3673 }
3674
3675 @Override
3676 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
3677 final long origId = Binder.clearCallingIdentity();
3678 try {
3679 synchronized (mGlobalLock) {
3680 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3681 "enterPictureInPictureMode", token, params);
3682
3683 // If the activity is already in picture in picture mode, then just return early
3684 if (isInPictureInPictureMode(r)) {
3685 return true;
3686 }
3687
3688 // Activity supports picture-in-picture, now check that we can enter PiP at this
3689 // point, if it is
3690 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
3691 false /* beforeStopping */)) {
3692 return false;
3693 }
3694
3695 final Runnable enterPipRunnable = () -> {
Wale Ogunwalef276a6f2018-06-15 08:26:07 -07003696 synchronized (mGlobalLock) {
3697 // Only update the saved args from the args that are set
3698 r.pictureInPictureArgs.copyOnlySet(params);
3699 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
3700 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
3701 // Adjust the source bounds by the insets for the transition down
3702 final Rect sourceBounds = new Rect(
3703 r.pictureInPictureArgs.getSourceRectHint());
3704 mStackSupervisor.moveActivityToPinnedStackLocked(
3705 r, sourceBounds, aspectRatio, "enterPictureInPictureMode");
3706 final PinnedActivityStack stack = r.getStack();
3707 stack.setPictureInPictureAspectRatio(aspectRatio);
3708 stack.setPictureInPictureActions(actions);
3709 MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
3710 r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
3711 logPictureInPictureArgs(params);
3712 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003713 };
3714
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003715 if (isKeyguardLocked()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003716 // If the keyguard is showing or occluded, then try and dismiss it before
3717 // entering picture-in-picture (this will prompt the user to authenticate if the
3718 // device is currently locked).
3719 dismissKeyguard(token, new KeyguardDismissCallback() {
3720 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003721 public void onDismissSucceeded() {
3722 mH.post(enterPipRunnable);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003723 }
3724 }, null /* message */);
3725 } else {
3726 // Enter picture in picture immediately otherwise
3727 enterPipRunnable.run();
3728 }
3729 return true;
3730 }
3731 } finally {
3732 Binder.restoreCallingIdentity(origId);
3733 }
3734 }
3735
3736 @Override
3737 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
3738 final long origId = Binder.clearCallingIdentity();
3739 try {
3740 synchronized (mGlobalLock) {
3741 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3742 "setPictureInPictureParams", token, params);
3743
3744 // Only update the saved args from the args that are set
3745 r.pictureInPictureArgs.copyOnlySet(params);
3746 if (r.inPinnedWindowingMode()) {
3747 // If the activity is already in picture-in-picture, update the pinned stack now
3748 // if it is not already expanding to fullscreen. Otherwise, the arguments will
3749 // be used the next time the activity enters PiP
3750 final PinnedActivityStack stack = r.getStack();
3751 if (!stack.isAnimatingBoundsToFullscreen()) {
3752 stack.setPictureInPictureAspectRatio(
3753 r.pictureInPictureArgs.getAspectRatio());
3754 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
3755 }
3756 }
3757 logPictureInPictureArgs(params);
3758 }
3759 } finally {
3760 Binder.restoreCallingIdentity(origId);
3761 }
3762 }
3763
3764 @Override
3765 public int getMaxNumPictureInPictureActions(IBinder token) {
3766 // Currently, this is a static constant, but later, we may change this to be dependent on
3767 // the context of the activity
3768 return 3;
3769 }
3770
3771 private void logPictureInPictureArgs(PictureInPictureParams params) {
3772 if (params.hasSetActions()) {
3773 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
3774 params.getActions().size());
3775 }
3776 if (params.hasSetAspectRatio()) {
3777 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
3778 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
3779 MetricsLogger.action(lm);
3780 }
3781 }
3782
3783 /**
3784 * Checks the state of the system and the activity associated with the given {@param token} to
3785 * verify that picture-in-picture is supported for that activity.
3786 *
3787 * @return the activity record for the given {@param token} if all the checks pass.
3788 */
3789 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
3790 IBinder token, PictureInPictureParams params) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003791 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003792 throw new IllegalStateException(caller
3793 + ": Device doesn't support picture-in-picture mode.");
3794 }
3795
3796 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3797 if (r == null) {
3798 throw new IllegalStateException(caller
3799 + ": Can't find activity for token=" + token);
3800 }
3801
3802 if (!r.supportsPictureInPicture()) {
3803 throw new IllegalStateException(caller
3804 + ": Current activity does not support picture-in-picture.");
3805 }
3806
3807 if (params.hasSetAspectRatio()
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003808 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003809 params.getAspectRatio())) {
3810 final float minAspectRatio = mContext.getResources().getFloat(
3811 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
3812 final float maxAspectRatio = mContext.getResources().getFloat(
3813 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
3814 throw new IllegalArgumentException(String.format(caller
3815 + ": Aspect ratio is too extreme (must be between %f and %f).",
3816 minAspectRatio, maxAspectRatio));
3817 }
3818
3819 // Truncate the number of actions if necessary
3820 params.truncateActions(getMaxNumPictureInPictureActions(token));
3821
3822 return r;
3823 }
3824
3825 @Override
3826 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003827 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003828 synchronized (mGlobalLock) {
3829 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
3830 if (r == null) {
3831 throw new IllegalArgumentException("Activity does not exist; token="
3832 + activityToken);
3833 }
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07003834 return r.getUriPermissionsLocked().getExternalToken();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003835 }
3836 }
3837
3838 @Override
3839 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
3840 Rect tempDockedTaskInsetBounds,
3841 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003842 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003843 long ident = Binder.clearCallingIdentity();
3844 try {
3845 synchronized (mGlobalLock) {
3846 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
3847 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
3848 PRESERVE_WINDOWS);
3849 }
3850 } finally {
3851 Binder.restoreCallingIdentity(ident);
3852 }
3853 }
3854
3855 @Override
3856 public void setSplitScreenResizing(boolean resizing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003857 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003858 final long ident = Binder.clearCallingIdentity();
3859 try {
3860 synchronized (mGlobalLock) {
3861 mStackSupervisor.setSplitScreenResizing(resizing);
3862 }
3863 } finally {
3864 Binder.restoreCallingIdentity(ident);
3865 }
3866 }
3867
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003868 /**
3869 * Check that we have the features required for VR-related API calls, and throw an exception if
3870 * not.
3871 */
3872 void enforceSystemHasVrFeature() {
3873 if (!mContext.getPackageManager().hasSystemFeature(
3874 PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
3875 throw new UnsupportedOperationException("VR mode not supported on this device!");
3876 }
3877 }
3878
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003879 @Override
3880 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003881 enforceSystemHasVrFeature();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003882
3883 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3884
3885 ActivityRecord r;
3886 synchronized (mGlobalLock) {
3887 r = ActivityRecord.isInStackLocked(token);
3888 }
3889
3890 if (r == null) {
3891 throw new IllegalArgumentException();
3892 }
3893
3894 int err;
3895 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
3896 VrManagerInternal.NO_ERROR) {
3897 return err;
3898 }
3899
3900 // Clear the binder calling uid since this path may call moveToTask().
3901 final long callingId = Binder.clearCallingIdentity();
3902 try {
3903 synchronized (mGlobalLock) {
3904 r.requestedVrComponent = (enabled) ? packageName : null;
3905
3906 // Update associated state if this activity is currently focused
Andrii Kulian52d255c2018-07-13 11:32:19 -07003907 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003908 applyUpdateVrModeLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003909 }
3910 return 0;
3911 }
3912 } finally {
3913 Binder.restoreCallingIdentity(callingId);
3914 }
3915 }
3916
3917 @Override
3918 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
3919 Slog.i(TAG, "Activity tried to startLocalVoiceInteraction");
3920 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003921 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003922 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
3923 throw new SecurityException("Only focused activity can call startVoiceInteraction");
3924 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07003925 if (mRunningVoice != null || activity.getTask().voiceSession != null
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003926 || activity.voiceSession != null) {
3927 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
3928 return;
3929 }
3930 if (activity.pendingVoiceInteractionStart) {
3931 Slog.w(TAG, "Pending start of voice interaction already.");
3932 return;
3933 }
3934 activity.pendingVoiceInteractionStart = true;
3935 }
3936 LocalServices.getService(VoiceInteractionManagerInternal.class)
3937 .startLocalVoiceInteraction(callingActivity, options);
3938 }
3939
3940 @Override
3941 public void stopLocalVoiceInteraction(IBinder callingActivity) {
3942 LocalServices.getService(VoiceInteractionManagerInternal.class)
3943 .stopLocalVoiceInteraction(callingActivity);
3944 }
3945
3946 @Override
3947 public boolean supportsLocalVoiceInteraction() {
3948 return LocalServices.getService(VoiceInteractionManagerInternal.class)
3949 .supportsLocalVoiceInteraction();
3950 }
3951
3952 /** Notifies all listeners when the pinned stack animation starts. */
3953 @Override
3954 public void notifyPinnedStackAnimationStarted() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003955 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003956 }
3957
3958 /** Notifies all listeners when the pinned stack animation ends. */
3959 @Override
3960 public void notifyPinnedStackAnimationEnded() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003961 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003962 }
3963
3964 @Override
3965 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003966 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003967 final long ident = Binder.clearCallingIdentity();
3968 try {
3969 synchronized (mGlobalLock) {
3970 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
3971 }
3972 } finally {
3973 Binder.restoreCallingIdentity(ident);
3974 }
3975 }
3976
3977 @Override
3978 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003979 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003980
3981 synchronized (mGlobalLock) {
3982 // Check if display is initialized in AM.
3983 if (!mStackSupervisor.isDisplayAdded(displayId)) {
3984 // Call might come when display is not yet added or has already been removed.
3985 if (DEBUG_CONFIGURATION) {
3986 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
3987 + displayId);
3988 }
3989 return false;
3990 }
3991
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003992 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003993 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003994 values = mWindowManager.computeNewConfiguration(displayId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003995 }
3996
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003997 if (mWindowManager != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07003998 final Message msg = PooledLambda.obtainMessage(
3999 ActivityManagerInternal::updateOomLevelsForDisplay, mAmInternal, displayId);
4000 mH.sendMessage(msg);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004001 }
4002
4003 final long origId = Binder.clearCallingIdentity();
4004 try {
4005 if (values != null) {
4006 Settings.System.clearConfiguration(values);
4007 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004008 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004009 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
4010 return mTmpUpdateConfigurationResult.changes != 0;
4011 } finally {
4012 Binder.restoreCallingIdentity(origId);
4013 }
4014 }
4015 }
4016
4017 @Override
4018 public boolean updateConfiguration(Configuration values) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004019 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004020
4021 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004022 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004023 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004024 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004025 }
4026
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004027 if (mWindowManager != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004028 final Message msg = PooledLambda.obtainMessage(
4029 ActivityManagerInternal::updateOomLevelsForDisplay, mAmInternal,
4030 DEFAULT_DISPLAY);
4031 mH.sendMessage(msg);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004032 }
4033
4034 final long origId = Binder.clearCallingIdentity();
4035 try {
4036 if (values != null) {
4037 Settings.System.clearConfiguration(values);
4038 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004039 updateConfigurationLocked(values, null, false, false /* persistent */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004040 UserHandle.USER_NULL, false /* deferResume */,
4041 mTmpUpdateConfigurationResult);
4042 return mTmpUpdateConfigurationResult.changes != 0;
4043 } finally {
4044 Binder.restoreCallingIdentity(origId);
4045 }
4046 }
4047 }
4048
4049 @Override
4050 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
4051 CharSequence message) {
4052 if (message != null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004053 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004054 Manifest.permission.SHOW_KEYGUARD_MESSAGE, "dismissKeyguard()");
4055 }
4056 final long callingId = Binder.clearCallingIdentity();
4057 try {
4058 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004059 mKeyguardController.dismissKeyguard(token, callback, message);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004060 }
4061 } finally {
4062 Binder.restoreCallingIdentity(callingId);
4063 }
4064 }
4065
4066 @Override
4067 public void cancelTaskWindowTransition(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004068 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004069 "cancelTaskWindowTransition()");
4070 final long ident = Binder.clearCallingIdentity();
4071 try {
4072 synchronized (mGlobalLock) {
4073 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
4074 MATCH_TASK_IN_STACKS_ONLY);
4075 if (task == null) {
4076 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
4077 return;
4078 }
4079 task.cancelWindowTransition();
4080 }
4081 } finally {
4082 Binder.restoreCallingIdentity(ident);
4083 }
4084 }
4085
4086 @Override
4087 public ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004088 enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004089 final long ident = Binder.clearCallingIdentity();
4090 try {
4091 final TaskRecord task;
4092 synchronized (mGlobalLock) {
4093 task = mStackSupervisor.anyTaskForIdLocked(taskId,
4094 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
4095 if (task == null) {
4096 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
4097 return null;
4098 }
4099 }
4100 // Don't call this while holding the lock as this operation might hit the disk.
4101 return task.getSnapshot(reducedResolution);
4102 } finally {
4103 Binder.restoreCallingIdentity(ident);
4104 }
4105 }
4106
4107 @Override
4108 public void setDisablePreviewScreenshots(IBinder token, boolean disable) {
4109 synchronized (mGlobalLock) {
4110 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4111 if (r == null) {
4112 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
4113 + token);
4114 return;
4115 }
4116 final long origId = Binder.clearCallingIdentity();
4117 try {
4118 r.setDisablePreviewScreenshots(disable);
4119 } finally {
4120 Binder.restoreCallingIdentity(origId);
4121 }
4122 }
4123 }
4124
4125 /** Return the user id of the last resumed activity. */
4126 @Override
4127 public @UserIdInt
4128 int getLastResumedActivityUserId() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004129 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004130 Manifest.permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
4131 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07004132 if (mLastResumedActivity == null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004133 return getCurrentUserId();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004134 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004135 return mLastResumedActivity.userId;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004136 }
4137 }
4138
4139 @Override
4140 public void updateLockTaskFeatures(int userId, int flags) {
4141 final int callingUid = Binder.getCallingUid();
4142 if (callingUid != 0 && callingUid != SYSTEM_UID) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004143 mAmInternal.enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004144 "updateLockTaskFeatures()");
4145 }
4146 synchronized (mGlobalLock) {
4147 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
4148 Integer.toHexString(flags));
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07004149 getLockTaskController().updateLockTaskFeatures(userId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004150 }
4151 }
4152
4153 @Override
4154 public void setShowWhenLocked(IBinder token, boolean showWhenLocked) {
4155 synchronized (mGlobalLock) {
4156 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4157 if (r == null) {
4158 return;
4159 }
4160 final long origId = Binder.clearCallingIdentity();
4161 try {
4162 r.setShowWhenLocked(showWhenLocked);
4163 } finally {
4164 Binder.restoreCallingIdentity(origId);
4165 }
4166 }
4167 }
4168
4169 @Override
4170 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) {
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.setTurnScreenOn(turnScreenOn);
4179 } finally {
4180 Binder.restoreCallingIdentity(origId);
4181 }
4182 }
4183 }
4184
4185 @Override
4186 public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004187 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004188 "registerRemoteAnimations");
4189 definition.setCallingPid(Binder.getCallingPid());
4190 synchronized (mGlobalLock) {
4191 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4192 if (r == null) {
4193 return;
4194 }
4195 final long origId = Binder.clearCallingIdentity();
4196 try {
4197 r.registerRemoteAnimations(definition);
4198 } finally {
4199 Binder.restoreCallingIdentity(origId);
4200 }
4201 }
4202 }
4203
4204 @Override
4205 public void registerRemoteAnimationForNextActivityStart(String packageName,
4206 RemoteAnimationAdapter adapter) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004207 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004208 "registerRemoteAnimationForNextActivityStart");
4209 adapter.setCallingPid(Binder.getCallingPid());
4210 synchronized (mGlobalLock) {
4211 final long origId = Binder.clearCallingIdentity();
4212 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07004213 getActivityStartController().registerRemoteAnimationForNextActivityStart(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004214 packageName, adapter);
4215 } finally {
4216 Binder.restoreCallingIdentity(origId);
4217 }
4218 }
4219 }
4220
4221 /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
4222 @Override
4223 public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
4224 synchronized (mGlobalLock) {
4225 final long origId = Binder.clearCallingIdentity();
4226 try {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004227 mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004228 } finally {
4229 Binder.restoreCallingIdentity(origId);
4230 }
4231 }
4232 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004233
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004234 @Override
4235 public void setVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004236 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004237 synchronized (mGlobalLock) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004238 final int pid = Binder.getCallingPid();
4239 final WindowProcessController wpc = mPidMap.get(pid);
4240 mVrController.setVrThreadLocked(tid, pid, wpc);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004241 }
4242 }
4243
4244 @Override
4245 public void setPersistentVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004246 if (checkCallingPermission(Manifest.permission.RESTRICTED_VR_ACCESS)
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004247 != PERMISSION_GRANTED) {
4248 final String msg = "Permission Denial: setPersistentVrThread() from pid="
4249 + Binder.getCallingPid()
4250 + ", uid=" + Binder.getCallingUid()
4251 + " requires " + Manifest.permission.RESTRICTED_VR_ACCESS;
4252 Slog.w(TAG, msg);
4253 throw new SecurityException(msg);
4254 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004255 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004256 synchronized (mGlobalLock) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004257 final int pid = Binder.getCallingPid();
4258 final WindowProcessController proc = mPidMap.get(pid);
4259 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004260 }
4261 }
4262
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004263 @Override
4264 public void stopAppSwitches() {
4265 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
4266 synchronized (mGlobalLock) {
4267 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME;
4268 mDidAppSwitch = false;
4269 getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
4270 }
4271 }
4272
4273 @Override
4274 public void resumeAppSwitches() {
4275 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
4276 synchronized (mGlobalLock) {
4277 // Note that we don't execute any pending app switches... we will
4278 // let those wait until either the timeout, or the next start
4279 // activity request.
4280 mAppSwitchesAllowedTime = 0;
4281 }
4282 }
4283
4284 void onStartActivitySetDidAppSwitch() {
4285 if (mDidAppSwitch) {
4286 // This is the second allowed switch since we stopped switches, so now just generally
4287 // allow switches. Use case:
4288 // - user presses home (switches disabled, switch to home, mDidAppSwitch now true);
4289 // - user taps a home icon (coming from home so allowed, we hit here and now allow
4290 // anyone to switch again).
4291 mAppSwitchesAllowedTime = 0;
4292 } else {
4293 mDidAppSwitch = true;
4294 }
4295 }
4296
4297 /** @return whether the system should disable UI modes incompatible with VR mode. */
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004298 boolean shouldDisableNonVrUiLocked() {
4299 return mVrController.shouldDisableNonVrUiLocked();
4300 }
4301
Wale Ogunwale53783742018-09-16 10:21:51 -07004302 private void applyUpdateVrModeLocked(ActivityRecord r) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004303 // VR apps are expected to run in a main display. If an app is turning on VR for
4304 // itself, but lives in a dynamic stack, then make sure that it is moved to the main
4305 // fullscreen stack before enabling VR Mode.
4306 // TODO: The goal of this code is to keep the VR app on the main display. When the
4307 // stack implementation changes in the future, keep in mind that the use of the fullscreen
4308 // stack is a means to move the activity to the main display and a moveActivityToDisplay()
4309 // option would be a better choice here.
4310 if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
4311 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
4312 + " to main stack for VR");
4313 final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
4314 WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
4315 moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
4316 }
4317 mH.post(() -> {
4318 if (!mVrController.onVrModeChanged(r)) {
4319 return;
4320 }
4321 synchronized (mGlobalLock) {
4322 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
4323 mWindowManager.disableNonVrUi(disableNonVrUi);
4324 if (disableNonVrUi) {
4325 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
4326 // then remove the pinned stack.
4327 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
4328 }
4329 }
4330 });
4331 }
4332
Wale Ogunwale53783742018-09-16 10:21:51 -07004333 @Override
4334 public int getPackageScreenCompatMode(String packageName) {
4335 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4336 synchronized (mGlobalLock) {
4337 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4338 }
4339 }
4340
4341 @Override
4342 public void setPackageScreenCompatMode(String packageName, int mode) {
4343 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4344 "setPackageScreenCompatMode");
4345 synchronized (mGlobalLock) {
4346 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4347 }
4348 }
4349
4350 @Override
4351 public boolean getPackageAskScreenCompat(String packageName) {
4352 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4353 synchronized (mGlobalLock) {
4354 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4355 }
4356 }
4357
4358 @Override
4359 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4360 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4361 "setPackageAskScreenCompat");
4362 synchronized (mGlobalLock) {
4363 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4364 }
4365 }
4366
Wale Ogunwale64258362018-10-16 15:13:37 -07004367 public static String relaunchReasonToString(int relaunchReason) {
4368 switch (relaunchReason) {
4369 case RELAUNCH_REASON_WINDOWING_MODE_RESIZE:
4370 return "window_resize";
4371 case RELAUNCH_REASON_FREE_RESIZE:
4372 return "free_resize";
4373 default:
4374 return null;
4375 }
4376 }
4377
Andrii Kulian5f750bc2018-07-17 08:57:23 -07004378 ActivityStack getTopDisplayFocusedStack() {
4379 return mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004380 }
4381
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004382 /** Pokes the task persister. */
4383 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
4384 mRecentTasks.notifyTaskPersisterLocked(task, flush);
4385 }
4386
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004387 boolean isKeyguardLocked() {
4388 return mKeyguardController.isKeyguardLocked();
4389 }
4390
Wale Ogunwale31913b52018-10-13 08:29:31 -07004391 void dumpLastANRLocked(PrintWriter pw) {
4392 pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
4393 if (mLastANRState == null) {
4394 pw.println(" <no ANR has occurred since boot>");
4395 } else {
4396 pw.println(mLastANRState);
4397 }
4398 }
4399
4400 void dumpLastANRTracesLocked(PrintWriter pw) {
4401 pw.println("ACTIVITY MANAGER LAST ANR TRACES (dumpsys activity lastanr-traces)");
4402
4403 final File[] files = new File(ANR_TRACE_DIR).listFiles();
4404 if (ArrayUtils.isEmpty(files)) {
4405 pw.println(" <no ANR has occurred since boot>");
4406 return;
4407 }
4408 // Find the latest file.
4409 File latest = null;
4410 for (File f : files) {
4411 if ((latest == null) || (latest.lastModified() < f.lastModified())) {
4412 latest = f;
Wale Ogunwalef6733932018-06-27 05:14:34 -07004413 }
Wale Ogunwale31913b52018-10-13 08:29:31 -07004414 }
4415 pw.print("File: ");
4416 pw.print(latest.getName());
4417 pw.println();
4418 try (BufferedReader in = new BufferedReader(new FileReader(latest))) {
4419 String line;
4420 while ((line = in.readLine()) != null) {
4421 pw.println(line);
4422 }
4423 } catch (IOException e) {
4424 pw.print("Unable to read: ");
4425 pw.print(e);
4426 pw.println();
4427 }
4428 }
4429
4430 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
4431 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
4432 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
4433 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
4434 }
4435
4436 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
4437 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
4438 pw.println(header);
4439
4440 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
4441 dumpPackage);
4442 boolean needSep = printedAnything;
4443
4444 boolean printed = ActivityStackSupervisor.printThisActivity(pw,
4445 mStackSupervisor.getTopResumedActivity(), dumpPackage, needSep,
4446 " ResumedActivity: ");
4447 if (printed) {
4448 printedAnything = true;
4449 needSep = false;
4450 }
4451
4452 if (dumpPackage == null) {
4453 if (needSep) {
4454 pw.println();
4455 }
4456 printedAnything = true;
4457 mStackSupervisor.dump(pw, " ");
4458 }
4459
4460 if (!printedAnything) {
4461 pw.println(" (nothing)");
4462 }
4463 }
4464
4465 void dumpActivityContainersLocked(PrintWriter pw) {
4466 pw.println("ACTIVITY MANAGER STARTER (dumpsys activity containers)");
4467 mStackSupervisor.dumpChildrenNames(pw, " ");
4468 pw.println(" ");
4469 }
4470
4471 void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
4472 pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
4473 getActivityStartController().dump(pw, "", dumpPackage);
4474 }
4475
4476 /**
4477 * There are three things that cmd can be:
4478 * - a flattened component name that matches an existing activity
4479 * - the cmd arg isn't the flattened component name of an existing activity:
4480 * dump all activity whose component contains the cmd as a substring
4481 * - A hex number of the ActivityRecord object instance.
4482 *
4483 * @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
4484 * @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
4485 */
4486 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
4487 int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
4488 ArrayList<ActivityRecord> activities;
4489
4490 synchronized (mGlobalLock) {
4491 activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
4492 dumpFocusedStackOnly);
4493 }
4494
4495 if (activities.size() <= 0) {
4496 return false;
4497 }
4498
4499 String[] newArgs = new String[args.length - opti];
4500 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
4501
4502 TaskRecord lastTask = null;
4503 boolean needSep = false;
4504 for (int i = activities.size() - 1; i >= 0; i--) {
4505 ActivityRecord r = activities.get(i);
4506 if (needSep) {
4507 pw.println();
4508 }
4509 needSep = true;
4510 synchronized (mGlobalLock) {
4511 final TaskRecord task = r.getTask();
4512 if (lastTask != task) {
4513 lastTask = task;
4514 pw.print("TASK "); pw.print(lastTask.affinity);
4515 pw.print(" id="); pw.print(lastTask.taskId);
4516 pw.print(" userId="); pw.println(lastTask.userId);
4517 if (dumpAll) {
4518 lastTask.dump(pw, " ");
4519 }
4520 }
4521 }
4522 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
4523 }
4524 return true;
4525 }
4526
4527 /**
4528 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
4529 * there is a thread associated with the activity.
4530 */
4531 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
4532 final ActivityRecord r, String[] args, boolean dumpAll) {
4533 String innerPrefix = prefix + " ";
4534 synchronized (mGlobalLock) {
4535 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
4536 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
4537 pw.print(" pid=");
4538 if (r.hasProcess()) pw.println(r.app.getPid());
4539 else pw.println("(not running)");
4540 if (dumpAll) {
4541 r.dump(pw, innerPrefix);
4542 }
4543 }
4544 if (r.attachedToProcess()) {
4545 // flush anything that is already in the PrintWriter since the thread is going
4546 // to write to the file descriptor directly
4547 pw.flush();
4548 try {
4549 TransferPipe tp = new TransferPipe();
4550 try {
4551 r.app.getThread().dumpActivity(tp.getWriteFd(),
4552 r.appToken, innerPrefix, args);
4553 tp.go(fd);
4554 } finally {
4555 tp.kill();
4556 }
4557 } catch (IOException e) {
4558 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
4559 } catch (RemoteException e) {
4560 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
4561 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004562 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004563 }
4564
Wale Ogunwalef6733932018-06-27 05:14:34 -07004565 void writeSleepStateToProto(ProtoOutputStream proto) {
4566 for (ActivityTaskManagerInternal.SleepToken st : mStackSupervisor.mSleepTokens) {
4567 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS,
4568 st.toString());
4569 }
4570
4571 if (mRunningVoice != null) {
4572 final long vrToken = proto.start(
4573 ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
4574 proto.write(ActivityManagerServiceDumpProcessesProto.Voice.SESSION,
4575 mRunningVoice.toString());
4576 mVoiceWakeLock.writeToProto(
4577 proto, ActivityManagerServiceDumpProcessesProto.Voice.WAKELOCK);
4578 proto.end(vrToken);
4579 }
4580
4581 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
4582 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN,
4583 mShuttingDown);
4584 mVrController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004585 }
4586
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004587 int getCurrentUserId() {
4588 return mAmInternal.getCurrentUserId();
4589 }
4590
4591 private void enforceNotIsolatedCaller(String caller) {
4592 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4593 throw new SecurityException("Isolated process not allowed to call " + caller);
4594 }
4595 }
4596
Wale Ogunwalef6733932018-06-27 05:14:34 -07004597 public Configuration getConfiguration() {
4598 Configuration ci;
4599 synchronized(mGlobalLock) {
Yunfan Chen75157d72018-07-27 14:47:21 +09004600 ci = new Configuration(getGlobalConfigurationForCallingPid());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004601 ci.userSetLocale = false;
4602 }
4603 return ci;
4604 }
4605
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004606 /**
4607 * Current global configuration information. Contains general settings for the entire system,
4608 * also corresponds to the merged configuration of the default display.
4609 */
4610 Configuration getGlobalConfiguration() {
4611 return mStackSupervisor.getConfiguration();
4612 }
4613
4614 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4615 boolean initLocale) {
4616 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
4617 }
4618
4619 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4620 boolean initLocale, boolean deferResume) {
4621 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
4622 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
4623 UserHandle.USER_NULL, deferResume);
4624 }
4625
4626 void updatePersistentConfiguration(Configuration values, @UserIdInt int userId) {
4627 final long origId = Binder.clearCallingIdentity();
4628 try {
4629 synchronized (mGlobalLock) {
4630 updateConfigurationLocked(values, null, false, true, userId,
4631 false /* deferResume */);
4632 }
4633 } finally {
4634 Binder.restoreCallingIdentity(origId);
4635 }
4636 }
4637
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004638 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4639 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
4640 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
4641 deferResume, null /* result */);
4642 }
4643
4644 /**
4645 * Do either or both things: (1) change the current configuration, and (2)
4646 * make sure the given activity is running with the (now) current
4647 * configuration. Returns true if the activity has been left running, or
4648 * false if <var>starting</var> is being destroyed to match the new
4649 * configuration.
4650 *
4651 * @param userId is only used when persistent parameter is set to true to persist configuration
4652 * for that particular user
4653 */
4654 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4655 boolean initLocale, boolean persistent, int userId, boolean deferResume,
4656 ActivityTaskManagerService.UpdateConfigurationResult result) {
4657 int changes = 0;
4658 boolean kept = true;
4659
4660 if (mWindowManager != null) {
4661 mWindowManager.deferSurfaceLayout();
4662 }
4663 try {
4664 if (values != null) {
4665 changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
4666 deferResume);
4667 }
4668
4669 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4670 } finally {
4671 if (mWindowManager != null) {
4672 mWindowManager.continueSurfaceLayout();
4673 }
4674 }
4675
4676 if (result != null) {
4677 result.changes = changes;
4678 result.activityRelaunched = !kept;
4679 }
4680 return kept;
4681 }
4682
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004683 /** Update default (global) configuration and notify listeners about changes. */
4684 private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
4685 boolean persistent, int userId, boolean deferResume) {
4686 mTempConfig.setTo(getGlobalConfiguration());
4687 final int changes = mTempConfig.updateFrom(values);
4688 if (changes == 0) {
4689 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
4690 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
4691 // performDisplayOverrideConfigUpdate in order to send the new display configuration
4692 // (even if there are no actual changes) to unfreeze the window.
4693 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
4694 return 0;
4695 }
4696
4697 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
4698 "Updating global configuration to: " + values);
4699
4700 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
4701 StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
4702 values.colorMode,
4703 values.densityDpi,
4704 values.fontScale,
4705 values.hardKeyboardHidden,
4706 values.keyboard,
4707 values.keyboardHidden,
4708 values.mcc,
4709 values.mnc,
4710 values.navigation,
4711 values.navigationHidden,
4712 values.orientation,
4713 values.screenHeightDp,
4714 values.screenLayout,
4715 values.screenWidthDp,
4716 values.smallestScreenWidthDp,
4717 values.touchscreen,
4718 values.uiMode);
4719
4720
4721 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
4722 final LocaleList locales = values.getLocales();
4723 int bestLocaleIndex = 0;
4724 if (locales.size() > 1) {
4725 if (mSupportedSystemLocales == null) {
4726 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
4727 }
4728 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
4729 }
4730 SystemProperties.set("persist.sys.locale",
4731 locales.get(bestLocaleIndex).toLanguageTag());
4732 LocaleList.setDefault(locales, bestLocaleIndex);
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004733
4734 final Message m = PooledLambda.obtainMessage(
4735 ActivityTaskManagerService::sendLocaleToMountDaemonMsg, this,
4736 locales.get(bestLocaleIndex));
4737 mH.sendMessage(m);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004738 }
4739
Yunfan Chen75157d72018-07-27 14:47:21 +09004740 mTempConfig.seq = increaseConfigurationSeqLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004741
4742 // Update stored global config and notify everyone about the change.
4743 mStackSupervisor.onConfigurationChanged(mTempConfig);
4744
4745 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
4746 // TODO(multi-display): Update UsageEvents#Event to include displayId.
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004747 mUsageStatsInternal.reportConfigurationChange(mTempConfig, mAmInternal.getCurrentUserId());
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004748
4749 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
Wale Ogunwalef6733932018-06-27 05:14:34 -07004750 updateShouldShowDialogsLocked(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004751
4752 AttributeCache ac = AttributeCache.instance();
4753 if (ac != null) {
4754 ac.updateConfiguration(mTempConfig);
4755 }
4756
4757 // Make sure all resources in our process are updated right now, so that anyone who is going
4758 // to retrieve resource values after we return will be sure to get the new ones. This is
4759 // especially important during boot, where the first config change needs to guarantee all
4760 // resources have that config before following boot code is executed.
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004761 mSystemThread.applyConfigurationToResources(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004762
4763 // We need another copy of global config because we're scheduling some calls instead of
4764 // running them in place. We need to be sure that object we send will be handled unchanged.
4765 final Configuration configCopy = new Configuration(mTempConfig);
4766 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004767 final Message msg = PooledLambda.obtainMessage(
4768 ActivityTaskManagerService::sendPutConfigurationForUserMsg,
4769 this, userId, configCopy);
4770 mH.sendMessage(msg);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004771 }
4772
Yunfan Chen34fcc7a2018-10-11 16:26:09 -07004773 for (int i = mPidMap.size() - 1; i >= 0; i--) {
Yunfan Chen79b96062018-10-17 12:45:23 -07004774 final int pid = mPidMap.keyAt(i);
4775 final WindowProcessController app = mPidMap.get(pid);
Yunfan Chen34fcc7a2018-10-11 16:26:09 -07004776 if (DEBUG_CONFIGURATION) {
4777 Slog.v(TAG_CONFIGURATION, "Update process config of "
4778 + app.mName + " to new config " + configCopy);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004779 }
Yunfan Chen34fcc7a2018-10-11 16:26:09 -07004780 app.onConfigurationChanged(configCopy);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004781 }
4782
Wale Ogunwale2ea36d42018-10-18 10:27:31 -07004783 final Message msg = PooledLambda.obtainMessage(
4784 ActivityManagerInternal::broadcastGlobalConfigurationChanged,
4785 mAmInternal, changes, initLocale);
4786 mH.sendMessage(msg);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004787
4788 // Override configuration of the default display duplicates global config, so we need to
4789 // update it also. This will also notify WindowManager about changes.
4790 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
4791 DEFAULT_DISPLAY);
4792
4793 return changes;
4794 }
4795
4796 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
4797 boolean deferResume, int displayId) {
4798 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
4799 displayId, null /* result */);
4800 }
4801
4802 /**
4803 * Updates override configuration specific for the selected display. If no config is provided,
4804 * new one will be computed in WM based on current display info.
4805 */
4806 boolean updateDisplayOverrideConfigurationLocked(Configuration values,
4807 ActivityRecord starting, boolean deferResume, int displayId,
4808 ActivityTaskManagerService.UpdateConfigurationResult result) {
4809 int changes = 0;
4810 boolean kept = true;
4811
4812 if (mWindowManager != null) {
4813 mWindowManager.deferSurfaceLayout();
4814 }
4815 try {
4816 if (values != null) {
4817 if (displayId == DEFAULT_DISPLAY) {
4818 // Override configuration of the default display duplicates global config, so
4819 // we're calling global config update instead for default display. It will also
4820 // apply the correct override config.
4821 changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
4822 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
4823 } else {
4824 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
4825 }
4826 }
4827
4828 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4829 } finally {
4830 if (mWindowManager != null) {
4831 mWindowManager.continueSurfaceLayout();
4832 }
4833 }
4834
4835 if (result != null) {
4836 result.changes = changes;
4837 result.activityRelaunched = !kept;
4838 }
4839 return kept;
4840 }
4841
4842 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
4843 int displayId) {
4844 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
4845 final int changes = mTempConfig.updateFrom(values);
4846 if (changes != 0) {
4847 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
4848 + mTempConfig + " for displayId=" + displayId);
4849 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
4850
4851 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
4852 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004853 mAppWarnings.onDensityChanged();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004854
Wale Ogunwale5c918702018-10-18 11:06:33 -07004855 // Post message to start process to avoid possible deadlock of calling into AMS with
4856 // the ATMS lock held.
4857 final Message msg = PooledLambda.obtainMessage(
4858 ActivityManagerInternal::killAllBackgroundProcessesExcept, mAmInternal,
4859 N, ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
4860 mH.sendMessage(msg);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004861 }
4862 }
4863
4864 // Update the configuration with WM first and check if any of the stacks need to be resized
4865 // due to the configuration change. If so, resize the stacks now and do any relaunches if
4866 // necessary. This way we don't need to relaunch again afterwards in
4867 // ensureActivityConfiguration().
4868 if (mWindowManager != null) {
4869 final int[] resizedStacks =
4870 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
4871 if (resizedStacks != null) {
4872 for (int stackId : resizedStacks) {
4873 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
4874 }
4875 }
4876 }
4877
4878 return changes;
4879 }
4880
Wale Ogunwalef6733932018-06-27 05:14:34 -07004881 private void updateEventDispatchingLocked(boolean booted) {
4882 mWindowManager.setEventDispatching(booted && !mShuttingDown);
4883 }
4884
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004885 private void sendPutConfigurationForUserMsg(int userId, Configuration config) {
4886 final ContentResolver resolver = mContext.getContentResolver();
4887 Settings.System.putConfigurationForUser(resolver, config, userId);
4888 }
4889
4890 private void sendLocaleToMountDaemonMsg(Locale l) {
4891 try {
4892 IBinder service = ServiceManager.getService("mount");
4893 IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
4894 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
4895 storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
4896 } catch (RemoteException e) {
4897 Log.e(TAG, "Error storing locale for decryption UI", e);
4898 }
4899 }
4900
4901 boolean isActivityStartsLoggingEnabled() {
4902 return mAmInternal.isActivityStartsLoggingEnabled();
4903 }
4904
Wale Ogunwalef6733932018-06-27 05:14:34 -07004905 void enableScreenAfterBoot(boolean booted) {
4906 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4907 SystemClock.uptimeMillis());
4908 mWindowManager.enableScreenAfterBoot();
4909
4910 synchronized (mGlobalLock) {
4911 updateEventDispatchingLocked(booted);
4912 }
4913 }
4914
Wale Ogunwale906f9c62018-07-23 11:23:44 -07004915 static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
4916 if (r == null || !r.hasProcess()) {
4917 return KEY_DISPATCHING_TIMEOUT_MS;
4918 }
4919 return getInputDispatchingTimeoutLocked(r.app);
4920 }
4921
4922 private static long getInputDispatchingTimeoutLocked(WindowProcessController r) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07004923 return r != null ? r.getInputDispatchingTimeout() : KEY_DISPATCHING_TIMEOUT_MS;
Wale Ogunwale906f9c62018-07-23 11:23:44 -07004924 }
4925
Wale Ogunwalef6733932018-06-27 05:14:34 -07004926 /**
4927 * Decide based on the configuration whether we should show the ANR,
4928 * crash, etc dialogs. The idea is that if there is no affordance to
4929 * press the on-screen buttons, or the user experience would be more
4930 * greatly impacted than the crash itself, we shouldn't show the dialog.
4931 *
4932 * A thought: SystemUI might also want to get told about this, the Power
4933 * dialog / global actions also might want different behaviors.
4934 */
4935 private void updateShouldShowDialogsLocked(Configuration config) {
4936 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
4937 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
4938 && config.navigation == Configuration.NAVIGATION_NONAV);
4939 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
4940 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
4941 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
4942 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
4943 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
4944 final boolean hideDialogsSet = Settings.Global.getInt(mContext.getContentResolver(),
4945 HIDE_ERROR_DIALOGS, 0) != 0;
4946 mShowDialogs = inputMethodExists && uiModeSupportsDialogs && !hideDialogsSet;
4947 }
4948
4949 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
4950 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
4951 FONT_SCALE, 1.0f, userId);
4952
4953 synchronized (this) {
4954 if (getGlobalConfiguration().fontScale == scaleFactor) {
4955 return;
4956 }
4957
4958 final Configuration configuration
4959 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
4960 configuration.fontScale = scaleFactor;
4961 updatePersistentConfiguration(configuration, userId);
4962 }
4963 }
4964
4965 // Actually is sleeping or shutting down or whatever else in the future
4966 // is an inactive state.
4967 boolean isSleepingOrShuttingDownLocked() {
4968 return isSleepingLocked() || mShuttingDown;
4969 }
4970
4971 boolean isSleepingLocked() {
4972 return mSleeping;
4973 }
4974
Riddle Hsu16567132018-08-16 21:37:47 +08004975 /** Update AMS states when an activity is resumed. */
Wale Ogunwalef6733932018-06-27 05:14:34 -07004976 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
4977 final TaskRecord task = r.getTask();
4978 if (task.isActivityTypeStandard()) {
4979 if (mCurAppTimeTracker != r.appTimeTracker) {
4980 // We are switching app tracking. Complete the current one.
4981 if (mCurAppTimeTracker != null) {
4982 mCurAppTimeTracker.stop();
4983 mH.obtainMessage(
4984 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
4985 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
4986 mCurAppTimeTracker = null;
4987 }
4988 if (r.appTimeTracker != null) {
4989 mCurAppTimeTracker = r.appTimeTracker;
4990 startTimeTrackingFocusedActivityLocked();
4991 }
4992 } else {
4993 startTimeTrackingFocusedActivityLocked();
4994 }
4995 } else {
4996 r.appTimeTracker = null;
4997 }
4998 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
4999 // TODO: Probably not, because we don't want to resume voice on switching
5000 // back to this activity
5001 if (task.voiceInteractor != null) {
5002 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
5003 } else {
5004 finishRunningVoiceLocked();
5005
5006 if (mLastResumedActivity != null) {
5007 final IVoiceInteractionSession session;
5008
5009 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
5010 if (lastResumedActivityTask != null
5011 && lastResumedActivityTask.voiceSession != null) {
5012 session = lastResumedActivityTask.voiceSession;
5013 } else {
5014 session = mLastResumedActivity.voiceSession;
5015 }
5016
5017 if (session != null) {
5018 // We had been in a voice interaction session, but now focused has
5019 // move to something different. Just finish the session, we can't
5020 // return to it and retain the proper state and synchronization with
5021 // the voice interaction service.
5022 finishVoiceTask(session);
5023 }
5024 }
5025 }
5026
5027 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
5028 mAmInternal.sendForegroundProfileChanged(r.userId);
5029 }
5030 updateResumedAppTrace(r);
5031 mLastResumedActivity = r;
5032
Tiger Huang1e5b10a2018-07-30 20:19:51 +08005033 r.getDisplay().setFocusedApp(r, true);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005034
5035 applyUpdateLockStateLocked(r);
5036 applyUpdateVrModeLocked(r);
5037
5038 EventLogTags.writeAmSetResumedActivity(
5039 r == null ? -1 : r.userId,
5040 r == null ? "NULL" : r.shortComponentName,
5041 reason);
5042 }
5043
5044 ActivityTaskManagerInternal.SleepToken acquireSleepToken(String tag, int displayId) {
5045 synchronized (mGlobalLock) {
5046 final ActivityTaskManagerInternal.SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
5047 updateSleepIfNeededLocked();
5048 return token;
5049 }
5050 }
5051
5052 void updateSleepIfNeededLocked() {
5053 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
5054 final boolean wasSleeping = mSleeping;
5055 boolean updateOomAdj = false;
5056
5057 if (!shouldSleep) {
5058 // If wasSleeping is true, we need to wake up activity manager state from when
5059 // we started sleeping. In either case, we need to apply the sleep tokens, which
5060 // will wake up stacks or put them to sleep as appropriate.
5061 if (wasSleeping) {
5062 mSleeping = false;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07005063 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
5064 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__AWAKE);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005065 startTimeTrackingFocusedActivityLocked();
5066 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
5067 mStackSupervisor.comeOutOfSleepIfNeededLocked();
5068 }
5069 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
5070 if (wasSleeping) {
5071 updateOomAdj = true;
5072 }
5073 } else if (!mSleeping && shouldSleep) {
5074 mSleeping = true;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07005075 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
5076 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__ASLEEP);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005077 if (mCurAppTimeTracker != null) {
5078 mCurAppTimeTracker.stop();
5079 }
5080 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
5081 mStackSupervisor.goingToSleepLocked();
5082 updateResumedAppTrace(null /* resumed */);
5083 updateOomAdj = true;
5084 }
5085 if (updateOomAdj) {
5086 mH.post(mAmInternal::updateOomAdj);
5087 }
5088 }
5089
5090 void updateOomAdj() {
5091 mH.post(mAmInternal::updateOomAdj);
5092 }
5093
Wale Ogunwale53783742018-09-16 10:21:51 -07005094 void updateCpuStats() {
5095 mH.post(mAmInternal::updateCpuStats);
5096 }
5097
5098 void updateUsageStats(ActivityRecord component, boolean resumed) {
5099 final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::updateUsageStats,
5100 mAmInternal, component.realActivity, component.app.mUid, component.userId, resumed);
5101 mH.sendMessage(m);
5102 }
5103
5104 void setBooting(boolean booting) {
5105 mAmInternal.setBooting(booting);
5106 }
5107
5108 boolean isBooting() {
5109 return mAmInternal.isBooting();
5110 }
5111
5112 void setBooted(boolean booted) {
5113 mAmInternal.setBooted(booted);
5114 }
5115
5116 boolean isBooted() {
5117 return mAmInternal.isBooted();
5118 }
5119
5120 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
5121 mH.post(() -> {
5122 if (finishBooting) {
5123 mAmInternal.finishBooting();
5124 }
5125 if (enableScreen) {
5126 mInternal.enableScreenAfterBoot(isBooted());
5127 }
5128 });
5129 }
5130
5131 void setHeavyWeightProcess(ActivityRecord root) {
5132 mHeavyWeightProcess = root.app;
5133 final Message m = PooledLambda.obtainMessage(
5134 ActivityTaskManagerService::postHeavyWeightProcessNotification, this,
5135 root.app, root.intent, root.userId);
5136 mH.sendMessage(m);
5137 }
5138
5139 void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
5140 if (mHeavyWeightProcess == null || mHeavyWeightProcess != proc) {
5141 return;
5142 }
5143
5144 mHeavyWeightProcess = null;
5145 final Message m = PooledLambda.obtainMessage(
5146 ActivityTaskManagerService::cancelHeavyWeightProcessNotification, this,
5147 proc.mUserId);
5148 mH.sendMessage(m);
5149 }
5150
5151 private void cancelHeavyWeightProcessNotification(int userId) {
5152 final INotificationManager inm = NotificationManager.getService();
5153 if (inm == null) {
5154 return;
5155 }
5156 try {
5157 inm.cancelNotificationWithTag("android", null,
5158 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, userId);
5159 } catch (RuntimeException e) {
5160 Slog.w(TAG, "Error canceling notification for service", e);
5161 } catch (RemoteException e) {
5162 }
5163
5164 }
5165
5166 private void postHeavyWeightProcessNotification(
5167 WindowProcessController proc, Intent intent, int userId) {
5168 if (proc == null) {
5169 return;
5170 }
5171
5172 final INotificationManager inm = NotificationManager.getService();
5173 if (inm == null) {
5174 return;
5175 }
5176
5177 try {
5178 Context context = mContext.createPackageContext(proc.mInfo.packageName, 0);
5179 String text = mContext.getString(R.string.heavy_weight_notification,
5180 context.getApplicationInfo().loadLabel(context.getPackageManager()));
5181 Notification notification =
5182 new Notification.Builder(context,
5183 SystemNotificationChannels.HEAVY_WEIGHT_APP)
5184 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
5185 .setWhen(0)
5186 .setOngoing(true)
5187 .setTicker(text)
5188 .setColor(mContext.getColor(
5189 com.android.internal.R.color.system_notification_accent_color))
5190 .setContentTitle(text)
5191 .setContentText(
5192 mContext.getText(R.string.heavy_weight_notification_detail))
5193 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
5194 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
5195 new UserHandle(userId)))
5196 .build();
5197 try {
5198 inm.enqueueNotificationWithTag("android", "android", null,
5199 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, notification, userId);
5200 } catch (RuntimeException e) {
5201 Slog.w(TAG, "Error showing notification for heavy-weight app", e);
5202 } catch (RemoteException e) {
5203 }
5204 } catch (PackageManager.NameNotFoundException e) {
5205 Slog.w(TAG, "Unable to create context for heavy notification", e);
5206 }
5207
5208 }
5209
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07005210 IIntentSender getIntentSenderLocked(int type, String packageName, int callingUid, int userId,
5211 IBinder token, String resultWho, int requestCode, Intent[] intents,
5212 String[] resolvedTypes, int flags, Bundle bOptions) {
5213
5214 ActivityRecord activity = null;
5215 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5216 activity = ActivityRecord.isInStackLocked(token);
5217 if (activity == null) {
5218 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
5219 return null;
5220 }
5221 if (activity.finishing) {
5222 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
5223 return null;
5224 }
5225 }
5226
5227 final PendingIntentRecord rec = mPendingIntentController.getIntentSender(type, packageName,
5228 callingUid, userId, token, resultWho, requestCode, intents, resolvedTypes, flags,
5229 bOptions);
5230 final boolean noCreate = (flags & PendingIntent.FLAG_NO_CREATE) != 0;
5231 if (noCreate) {
5232 return rec;
5233 }
5234 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5235 if (activity.pendingResults == null) {
5236 activity.pendingResults = new HashSet<>();
5237 }
5238 activity.pendingResults.add(rec.ref);
5239 }
5240 return rec;
5241 }
5242
Andrii Kulian52d255c2018-07-13 11:32:19 -07005243 // TODO(b/111541062): Update app time tracking to make it aware of multiple resumed activities
Wale Ogunwalef6733932018-06-27 05:14:34 -07005244 private void startTimeTrackingFocusedActivityLocked() {
Andrii Kulian52d255c2018-07-13 11:32:19 -07005245 final ActivityRecord resumedActivity = mStackSupervisor.getTopResumedActivity();
Wale Ogunwalef6733932018-06-27 05:14:34 -07005246 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
5247 mCurAppTimeTracker.start(resumedActivity.packageName);
5248 }
5249 }
5250
5251 private void updateResumedAppTrace(@Nullable ActivityRecord resumed) {
5252 if (mTracedResumedActivity != null) {
5253 Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER,
5254 constructResumedTraceName(mTracedResumedActivity.packageName), 0);
5255 }
5256 if (resumed != null) {
5257 Trace.asyncTraceBegin(TRACE_TAG_ACTIVITY_MANAGER,
5258 constructResumedTraceName(resumed.packageName), 0);
5259 }
5260 mTracedResumedActivity = resumed;
5261 }
5262
5263 private String constructResumedTraceName(String packageName) {
5264 return "focused app: " + packageName;
5265 }
5266
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005267 /** Helper method that requests bounds from WM and applies them to stack. */
5268 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
5269 final Rect newStackBounds = new Rect();
5270 final ActivityStack stack = mStackSupervisor.getStack(stackId);
5271
5272 // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
5273 if (stack == null) {
5274 final StringWriter writer = new StringWriter();
5275 final PrintWriter printWriter = new PrintWriter(writer);
5276 mStackSupervisor.dumpDisplays(printWriter);
5277 printWriter.flush();
5278
5279 Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
5280 }
5281
5282 stack.getBoundsForNewConfiguration(newStackBounds);
5283 mStackSupervisor.resizeStackLocked(
5284 stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
5285 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
5286 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
5287 }
5288
5289 /** Applies latest configuration and/or visibility updates if needed. */
5290 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
5291 boolean kept = true;
Andrii Kulian5f750bc2018-07-17 08:57:23 -07005292 final ActivityStack mainStack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005293 // mainStack is null during startup.
5294 if (mainStack != null) {
5295 if (changes != 0 && starting == null) {
5296 // If the configuration changed, and the caller is not already
5297 // in the process of starting an activity, then find the top
5298 // activity to check if its configuration needs to change.
5299 starting = mainStack.topRunningActivityLocked();
5300 }
5301
5302 if (starting != null) {
5303 kept = starting.ensureActivityConfiguration(changes,
5304 false /* preserveWindow */);
5305 // And we need to make sure at this point that all other activities
5306 // are made visible with the correct configuration.
5307 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
5308 !PRESERVE_WINDOWS);
5309 }
5310 }
5311
5312 return kept;
5313 }
5314
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005315 void scheduleAppGcsLocked() {
5316 mH.post(() -> mAmInternal.scheduleAppGcs());
5317 }
5318
Wale Ogunwale53783742018-09-16 10:21:51 -07005319 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
5320 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
5321 }
5322
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005323 /**
5324 * Returns the PackageManager. Used by classes hosted by {@link ActivityTaskManagerService}. The
5325 * PackageManager could be unavailable at construction time and therefore needs to be accessed
5326 * on demand.
5327 */
5328 IPackageManager getPackageManager() {
5329 return AppGlobals.getPackageManager();
5330 }
5331
5332 PackageManagerInternal getPackageManagerInternalLocked() {
5333 if (mPmInternal == null) {
5334 mPmInternal = LocalServices.getService(PackageManagerInternal.class);
5335 }
5336 return mPmInternal;
5337 }
5338
Wale Ogunwale008163e2018-07-23 23:11:08 -07005339 AppWarnings getAppWarningsLocked() {
5340 return mAppWarnings;
5341 }
5342
Wale Ogunwale214f3482018-10-04 11:00:47 -07005343 Intent getHomeIntent() {
5344 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
5345 intent.setComponent(mTopComponent);
5346 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
5347 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5348 intent.addCategory(Intent.CATEGORY_HOME);
5349 }
5350 return intent;
5351 }
5352
5353 /**
5354 * This starts home activity on displays that can have system decorations and only if the
5355 * home activity can have multiple instances.
5356 */
5357 boolean startHomeActivityLocked(int userId, String reason, int displayId) {
5358 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL && mTopAction == null) {
5359 // We are running in factory test mode, but unable to find the factory test app, so just
5360 // sit around displaying the error message and don't try to start anything.
5361 return false;
5362 }
5363
5364 final Intent intent = getHomeIntent();
5365 ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
5366 if (aInfo != null) {
5367 intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
5368 // Don't do this if the home app is currently being instrumented.
5369 aInfo = new ActivityInfo(aInfo);
5370 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
5371 WindowProcessController app =
5372 getProcessController(aInfo.processName, aInfo.applicationInfo.uid);
5373 if (app == null || !app.isInstrumenting()) {
5374 intent.setFlags(intent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
5375 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
5376 // For ANR debugging to verify if the user activity is the one that actually
5377 // launched.
5378 final String myReason = reason + ":" + userId + ":" + resolvedUserId;
5379 getActivityStartController().startHomeActivity(intent, aInfo, myReason, displayId);
5380 }
5381 } else {
5382 Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
5383 }
5384
5385 return true;
5386 }
5387
5388 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
5389 ActivityInfo ai = null;
5390 final ComponentName comp = intent.getComponent();
5391 try {
5392 if (comp != null) {
5393 // Factory test.
5394 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
5395 } else {
5396 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
5397 intent,
5398 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
5399 flags, userId);
5400
5401 if (info != null) {
5402 ai = info.activityInfo;
5403 }
5404 }
5405 } catch (RemoteException e) {
5406 // ignore
5407 }
5408
5409 return ai;
5410 }
5411
5412 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
5413 if (info == null) return null;
5414 ApplicationInfo newInfo = new ApplicationInfo(info);
5415 newInfo.initForUser(userId);
5416 return newInfo;
5417 }
5418
Wale Ogunwale9c103022018-10-18 07:44:54 -07005419 WindowProcessController getProcessController(String processName, int uid) {
Wale Ogunwale214f3482018-10-04 11:00:47 -07005420 if (uid == SYSTEM_UID) {
5421 // The system gets to run in any process. If there are multiple processes with the same
5422 // uid, just pick the first (this should never happen).
5423 final SparseArray<WindowProcessController> procs =
5424 mProcessNames.getMap().get(processName);
5425 if (procs == null) return null;
5426 final int procCount = procs.size();
5427 for (int i = 0; i < procCount; i++) {
5428 final int procUid = procs.keyAt(i);
5429 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
5430 // Don't use an app process or different user process for system component.
5431 continue;
5432 }
5433 return procs.valueAt(i);
5434 }
5435 }
5436
5437 return mProcessNames.get(processName, uid);
5438 }
5439
Wale Ogunwale342fbe92018-10-09 08:44:10 -07005440 WindowProcessController getProcessController(IApplicationThread thread) {
5441 if (thread == null) {
5442 return null;
5443 }
5444
5445 final IBinder threadBinder = thread.asBinder();
5446 final ArrayMap<String, SparseArray<WindowProcessController>> pmap = mProcessNames.getMap();
5447 for (int i = pmap.size()-1; i >= 0; i--) {
5448 final SparseArray<WindowProcessController> procs = pmap.valueAt(i);
5449 for (int j = procs.size() - 1; j >= 0; j--) {
5450 final WindowProcessController proc = procs.valueAt(j);
5451 if (proc.hasThread() && proc.getThread().asBinder() == threadBinder) {
5452 return proc;
5453 }
5454 }
5455 }
5456
5457 return null;
5458 }
5459
Wale Ogunwalebff2df42018-10-18 17:09:19 -07005460 int getUidStateLocked(int uid) {
5461 return mActiveUids.get(uid, PROCESS_STATE_NONEXISTENT);
5462 }
5463
Wale Ogunwale9de19442018-10-18 19:05:03 -07005464 /**
5465 * @return whitelist tag for a uid from mPendingTempWhitelist, null if not currently on
5466 * the whitelist
5467 */
5468 String getPendingTempWhitelistTagForUidLocked(int uid) {
5469 return mPendingTempWhitelist.get(uid);
5470 }
5471
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005472 void logAppTooSlow(WindowProcessController app, long startTime, String msg) {
5473 if (true || Build.IS_USER) {
5474 return;
5475 }
5476
5477 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5478 StrictMode.allowThreadDiskWrites();
5479 try {
5480 File tracesDir = new File("/data/anr");
5481 File tracesFile = null;
5482 try {
5483 tracesFile = File.createTempFile("app_slow", null, tracesDir);
5484
5485 StringBuilder sb = new StringBuilder();
5486 Time tobj = new Time();
5487 tobj.set(System.currentTimeMillis());
5488 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5489 sb.append(": ");
5490 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5491 sb.append(" since ");
5492 sb.append(msg);
5493 FileOutputStream fos = new FileOutputStream(tracesFile);
5494 fos.write(sb.toString().getBytes());
5495 if (app == null) {
5496 fos.write("\n*** No application process!".getBytes());
5497 }
5498 fos.close();
5499 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5500 } catch (IOException e) {
5501 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesFile, e);
5502 return;
5503 }
5504
5505 if (app != null && app.getPid() > 0) {
5506 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5507 firstPids.add(app.getPid());
5508 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, null, null);
5509 }
5510
5511 File lastTracesFile = null;
5512 File curTracesFile = null;
5513 for (int i=9; i>=0; i--) {
5514 String name = String.format(Locale.US, "slow%02d.txt", i);
5515 curTracesFile = new File(tracesDir, name);
5516 if (curTracesFile.exists()) {
5517 if (lastTracesFile != null) {
5518 curTracesFile.renameTo(lastTracesFile);
5519 } else {
5520 curTracesFile.delete();
5521 }
5522 }
5523 lastTracesFile = curTracesFile;
5524 }
5525 tracesFile.renameTo(curTracesFile);
5526 } finally {
5527 StrictMode.setThreadPolicy(oldPolicy);
5528 }
5529 }
5530
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005531 final class H extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005532 static final int REPORT_TIME_TRACKER_MSG = 1;
Wale Ogunwale98875612018-10-12 07:53:02 -07005533 static final int FIRST_ACTIVITY_STACK_MSG = 100;
5534 static final int FIRST_SUPERVISOR_STACK_MSG = 200;
Wale Ogunwalef6733932018-06-27 05:14:34 -07005535
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005536 public H(Looper looper) {
5537 super(looper, null, true);
5538 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005539
5540 @Override
5541 public void handleMessage(Message msg) {
5542 switch (msg.what) {
5543 case REPORT_TIME_TRACKER_MSG: {
5544 AppTimeTracker tracker = (AppTimeTracker) msg.obj;
5545 tracker.deliverResult(mContext);
5546 } break;
5547 }
5548 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005549 }
5550
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005551 final class UiHandler extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005552 static final int DISMISS_DIALOG_UI_MSG = 1;
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005553
5554 public UiHandler() {
5555 super(com.android.server.UiThread.get().getLooper(), null, true);
5556 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005557
5558 @Override
5559 public void handleMessage(Message msg) {
5560 switch (msg.what) {
5561 case DISMISS_DIALOG_UI_MSG: {
5562 final Dialog d = (Dialog) msg.obj;
5563 d.dismiss();
5564 break;
5565 }
5566 }
5567 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005568 }
5569
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005570 final class LocalService extends ActivityTaskManagerInternal {
5571 @Override
5572 public SleepToken acquireSleepToken(String tag, int displayId) {
5573 Preconditions.checkNotNull(tag);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005574 return ActivityTaskManagerService.this.acquireSleepToken(tag, displayId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005575 }
5576
5577 @Override
5578 public ComponentName getHomeActivityForUser(int userId) {
5579 synchronized (mGlobalLock) {
Louis Changbd48dca2018-08-29 17:44:34 +08005580 ActivityRecord homeActivity =
5581 mStackSupervisor.getDefaultDisplayHomeActivityForUser(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005582 return homeActivity == null ? null : homeActivity.realActivity;
5583 }
5584 }
5585
5586 @Override
5587 public void onLocalVoiceInteractionStarted(IBinder activity,
5588 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
5589 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005590 onLocalVoiceInteractionStartedLocked(activity, voiceSession, voiceInteractor);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005591 }
5592 }
5593
5594 @Override
5595 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
5596 synchronized (mGlobalLock) {
5597 mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
5598 reasons, timestamp);
5599 }
5600 }
5601
5602 @Override
5603 public void notifyAppTransitionFinished() {
5604 synchronized (mGlobalLock) {
5605 mStackSupervisor.notifyAppTransitionDone();
5606 }
5607 }
5608
5609 @Override
5610 public void notifyAppTransitionCancelled() {
5611 synchronized (mGlobalLock) {
5612 mStackSupervisor.notifyAppTransitionDone();
5613 }
5614 }
5615
5616 @Override
5617 public List<IBinder> getTopVisibleActivities() {
5618 synchronized (mGlobalLock) {
5619 return mStackSupervisor.getTopVisibleActivities();
5620 }
5621 }
5622
5623 @Override
5624 public void notifyDockedStackMinimizedChanged(boolean minimized) {
5625 synchronized (mGlobalLock) {
5626 mStackSupervisor.setDockedStackMinimized(minimized);
5627 }
5628 }
5629
5630 @Override
5631 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
5632 Bundle bOptions) {
5633 Preconditions.checkNotNull(intents, "intents");
5634 final String[] resolvedTypes = new String[intents.length];
5635
5636 // UID of the package on user userId.
5637 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
5638 // packageUid may not be initialized.
5639 int packageUid = 0;
5640 final long ident = Binder.clearCallingIdentity();
5641
5642 try {
5643 for (int i = 0; i < intents.length; i++) {
5644 resolvedTypes[i] =
5645 intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
5646 }
5647
5648 packageUid = AppGlobals.getPackageManager().getPackageUid(
5649 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
5650 } catch (RemoteException e) {
5651 // Shouldn't happen.
5652 } finally {
5653 Binder.restoreCallingIdentity(ident);
5654 }
5655
5656 synchronized (mGlobalLock) {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07005657 return getActivityStartController().startActivitiesInPackage(
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005658 packageUid, packageName,
5659 intents, resolvedTypes, null /* resultTo */,
5660 SafeActivityOptions.fromBundle(bOptions), userId,
Michal Karpinski201bc0c2018-07-20 15:32:00 +01005661 false /* validateIncomingUser */, null /* originatingPendingIntent */);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005662 }
5663 }
5664
5665 @Override
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07005666 public int startActivitiesInPackage(int uid, String callingPackage, Intent[] intents,
5667 String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, int userId,
5668 boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent) {
5669 synchronized (mGlobalLock) {
5670 return getActivityStartController().startActivitiesInPackage(uid, callingPackage,
5671 intents, resolvedTypes, resultTo, options, userId, validateIncomingUser,
5672 originatingPendingIntent);
5673 }
5674 }
5675
5676 @Override
5677 public int startActivityInPackage(int uid, int realCallingPid, int realCallingUid,
5678 String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
5679 String resultWho, int requestCode, int startFlags, SafeActivityOptions options,
5680 int userId, TaskRecord inTask, String reason, boolean validateIncomingUser,
5681 PendingIntentRecord originatingPendingIntent) {
5682 synchronized (mGlobalLock) {
5683 return getActivityStartController().startActivityInPackage(uid, realCallingPid,
5684 realCallingUid, callingPackage, intent, resolvedType, resultTo, resultWho,
5685 requestCode, startFlags, options, userId, inTask, reason,
5686 validateIncomingUser, originatingPendingIntent);
5687 }
5688 }
5689
5690 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005691 public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
5692 Intent intent, Bundle options, int userId) {
5693 return ActivityTaskManagerService.this.startActivityAsUser(
5694 caller, callerPacakge, intent,
5695 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
5696 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
5697 false /*validateIncomingUser*/);
5698 }
5699
5700 @Override
lumark588a3e82018-07-20 18:53:54 +08005701 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback, int displayId) {
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005702 synchronized (mGlobalLock) {
5703
5704 // We might change the visibilities here, so prepare an empty app transition which
5705 // might be overridden later if we actually change visibilities.
lumark588a3e82018-07-20 18:53:54 +08005706 final DisplayWindowController dwc = mStackSupervisor.getActivityDisplay(displayId)
5707 .getWindowContainerController();
5708 final boolean wasTransitionSet = dwc.getPendingAppTransition() != TRANSIT_NONE;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005709 if (!wasTransitionSet) {
lumark588a3e82018-07-20 18:53:54 +08005710 dwc.prepareAppTransition(TRANSIT_NONE, false /* alwaysKeepCurrent */);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005711 }
5712 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5713
5714 // If there was a transition set already we don't want to interfere with it as we
5715 // might be starting it too early.
5716 if (!wasTransitionSet) {
lumark588a3e82018-07-20 18:53:54 +08005717 dwc.executeAppTransition();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005718 }
5719 }
5720 if (callback != null) {
5721 callback.run();
5722 }
5723 }
5724
5725 @Override
5726 public void notifyKeyguardTrustedChanged() {
5727 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005728 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005729 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5730 }
5731 }
5732 }
5733
5734 /**
5735 * Called after virtual display Id is updated by
5736 * {@link com.android.server.vr.Vr2dDisplay} with a specific
5737 * {@param vrVr2dDisplayId}.
5738 */
5739 @Override
5740 public void setVr2dDisplayId(int vr2dDisplayId) {
5741 if (DEBUG_STACK) Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
5742 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005743 mVr2dDisplayId = vr2dDisplayId;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005744 }
5745 }
5746
5747 @Override
5748 public void setFocusedActivity(IBinder token) {
5749 synchronized (mGlobalLock) {
5750 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
5751 if (r == null) {
5752 throw new IllegalArgumentException(
5753 "setFocusedActivity: No activity record matching token=" + token);
5754 }
Louis Chang19443452018-10-09 12:10:21 +08005755 if (r.moveFocusableActivityToTop("setFocusedActivity")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08005756 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005757 }
5758 }
5759 }
5760
5761 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005762 public void registerScreenObserver(ScreenObserver observer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005763 mScreenObservers.add(observer);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005764 }
5765
5766 @Override
5767 public boolean isCallerRecents(int callingUid) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005768 return getRecentTasks().isCallerRecents(callingUid);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005769 }
5770
5771 @Override
5772 public boolean isRecentsComponentHomeActivity(int userId) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005773 return getRecentTasks().isRecentsComponentHomeActivity(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005774 }
5775
5776 @Override
5777 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
5778 ActivityTaskManagerService.this.cancelRecentsAnimation(restoreHomeStackPosition);
5779 }
5780
5781 @Override
5782 public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005783 ActivityTaskManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005784 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005785
5786 @Override
5787 public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
5788 synchronized (mGlobalLock) {
5789 mActiveVoiceInteractionServiceComponent = component;
5790 }
5791 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005792
5793 @Override
5794 public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
5795 if (!mAmInternal.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
5796 return;
5797 }
5798 synchronized (mGlobalLock) {
5799 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
5800 if (types == null) {
5801 if (uid < 0) {
5802 return;
5803 }
5804 types = new ArrayMap<>();
5805 mAllowAppSwitchUids.put(userId, types);
5806 }
5807 if (uid < 0) {
5808 types.remove(type);
5809 } else {
5810 types.put(type, uid);
5811 }
5812 }
5813 }
5814
5815 @Override
5816 public void onUserStopped(int userId) {
5817 synchronized (mGlobalLock) {
5818 getRecentTasks().unloadUserDataFromMemoryLocked(userId);
5819 mAllowAppSwitchUids.remove(userId);
5820 }
5821 }
5822
5823 @Override
5824 public boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
5825 synchronized (mGlobalLock) {
5826 return ActivityTaskManagerService.this.isGetTasksAllowed(
5827 caller, callingPid, callingUid);
5828 }
5829 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005830
5831 @Override
5832 public void onProcessAdded(WindowProcessController proc) {
5833 synchronized (mGlobalLock) {
5834 mProcessNames.put(proc.mName, proc.mUid, proc);
5835 }
5836 }
5837
5838 @Override
5839 public void onProcessRemoved(String name, int uid) {
5840 synchronized (mGlobalLock) {
5841 mProcessNames.remove(name, uid);
5842 }
5843 }
5844
5845 @Override
5846 public void onCleanUpApplicationRecord(WindowProcessController proc) {
5847 synchronized (mGlobalLock) {
5848 if (proc == mHomeProcess) {
5849 mHomeProcess = null;
5850 }
5851 if (proc == mPreviousProcess) {
5852 mPreviousProcess = null;
5853 }
5854 }
5855 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005856
5857 @Override
5858 public int getTopProcessState() {
5859 synchronized (mGlobalLock) {
5860 return mTopProcessState;
5861 }
5862 }
5863
5864 @Override
Wale Ogunwale53783742018-09-16 10:21:51 -07005865 public boolean isHeavyWeightProcess(WindowProcessController proc) {
5866 synchronized (mGlobalLock) {
5867 return proc == mHeavyWeightProcess;
5868 }
5869 }
5870
5871 @Override
5872 public void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
5873 synchronized (mGlobalLock) {
5874 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(proc);
5875 }
5876 }
5877
5878 @Override
5879 public void finishHeavyWeightApp() {
5880 synchronized (mGlobalLock) {
Sudheer Shankaee1da272018-10-20 20:11:44 -07005881 if (mHeavyWeightProcess != null) {
5882 mHeavyWeightProcess.finishActivities();
5883 }
Wale Ogunwale53783742018-09-16 10:21:51 -07005884 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(
5885 mHeavyWeightProcess);
5886 }
5887 }
5888
5889 @Override
Wale Ogunwalef6733932018-06-27 05:14:34 -07005890 public boolean isSleeping() {
5891 synchronized (mGlobalLock) {
5892 return isSleepingLocked();
5893 }
5894 }
5895
5896 @Override
5897 public boolean isShuttingDown() {
5898 synchronized (mGlobalLock) {
5899 return mShuttingDown;
5900 }
5901 }
5902
5903 @Override
5904 public boolean shuttingDown(boolean booted, int timeout) {
5905 synchronized (mGlobalLock) {
5906 mShuttingDown = true;
5907 mStackSupervisor.prepareForShutdownLocked();
5908 updateEventDispatchingLocked(booted);
Wale Ogunwaled4d67d02018-10-25 18:09:39 -07005909 notifyTaskPersisterLocked(null, true);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005910 return mStackSupervisor.shutdownLocked(timeout);
5911 }
5912 }
5913
5914 @Override
5915 public void enableScreenAfterBoot(boolean booted) {
5916 synchronized (mGlobalLock) {
5917 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5918 SystemClock.uptimeMillis());
5919 mWindowManager.enableScreenAfterBoot();
5920 updateEventDispatchingLocked(booted);
5921 }
5922 }
5923
5924 @Override
5925 public boolean showStrictModeViolationDialog() {
5926 synchronized (mGlobalLock) {
5927 return mShowDialogs && !mSleeping && !mShuttingDown;
5928 }
5929 }
5930
5931 @Override
5932 public void showSystemReadyErrorDialogsIfNeeded() {
5933 synchronized (mGlobalLock) {
5934 try {
5935 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
5936 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
5937 + " data partition or your device will be unstable.");
5938 mUiHandler.post(() -> {
5939 if (mShowDialogs) {
5940 AlertDialog d = new BaseErrorDialog(mUiContext);
5941 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5942 d.setCancelable(false);
5943 d.setTitle(mUiContext.getText(R.string.android_system_label));
5944 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
5945 d.setButton(DialogInterface.BUTTON_POSITIVE,
5946 mUiContext.getText(R.string.ok),
5947 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5948 d.show();
5949 }
5950 });
5951 }
5952 } catch (RemoteException e) {
5953 }
5954
5955 if (!Build.isBuildConsistent()) {
5956 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
5957 mUiHandler.post(() -> {
5958 if (mShowDialogs) {
5959 AlertDialog d = new BaseErrorDialog(mUiContext);
5960 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5961 d.setCancelable(false);
5962 d.setTitle(mUiContext.getText(R.string.android_system_label));
5963 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
5964 d.setButton(DialogInterface.BUTTON_POSITIVE,
5965 mUiContext.getText(R.string.ok),
5966 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5967 d.show();
5968 }
5969 });
5970 }
5971 }
5972 }
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005973
5974 @Override
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005975 public void onProcessMapped(int pid, WindowProcessController proc) {
5976 synchronized (mGlobalLock) {
5977 mPidMap.put(pid, proc);
5978 }
5979 }
5980
5981 @Override
5982 public void onProcessUnMapped(int pid) {
5983 synchronized (mGlobalLock) {
5984 mPidMap.remove(pid);
5985 }
5986 }
Wale Ogunwale008163e2018-07-23 23:11:08 -07005987
5988 @Override
5989 public void onPackageDataCleared(String name) {
5990 synchronized (mGlobalLock) {
Wale Ogunwale53783742018-09-16 10:21:51 -07005991 mCompatModePackages.handlePackageDataClearedLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07005992 mAppWarnings.onPackageDataCleared(name);
5993 }
5994 }
5995
5996 @Override
5997 public void onPackageUninstalled(String name) {
5998 synchronized (mGlobalLock) {
5999 mAppWarnings.onPackageUninstalled(name);
Wale Ogunwale53783742018-09-16 10:21:51 -07006000 mCompatModePackages.handlePackageUninstalledLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07006001 }
6002 }
Wale Ogunwale53783742018-09-16 10:21:51 -07006003
6004 @Override
6005 public void onPackageAdded(String name, boolean replacing) {
6006 synchronized (mGlobalLock) {
6007 mCompatModePackages.handlePackageAddedLocked(name, replacing);
6008 }
6009 }
6010
6011 @Override
Wale Ogunwale31913b52018-10-13 08:29:31 -07006012 public void onPackageReplaced(ApplicationInfo aInfo) {
6013 synchronized (mGlobalLock) {
6014 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
6015 }
6016 }
6017
6018 @Override
Wale Ogunwale53783742018-09-16 10:21:51 -07006019 public CompatibilityInfo compatibilityInfoForPackage(ApplicationInfo ai) {
6020 synchronized (mGlobalLock) {
6021 return compatibilityInfoForPackageLocked(ai);
6022 }
6023 }
6024
Yunfan Chen75157d72018-07-27 14:47:21 +09006025 /**
6026 * Set the corresponding display information for the process global configuration. To be
6027 * called when we need to show IME on a different display.
6028 *
6029 * @param pid The process id associated with the IME window.
6030 * @param displayId The ID of the display showing the IME.
6031 */
6032 @Override
Yunfan Chen79b96062018-10-17 12:45:23 -07006033 public void onImeWindowSetOnDisplay(final int pid, final int displayId) {
Yunfan Chen75157d72018-07-27 14:47:21 +09006034 if (pid == MY_PID || pid < 0) {
6035 if (DEBUG_CONFIGURATION) {
6036 Slog.w(TAG,
6037 "Trying to update display configuration for system/invalid process.");
6038 }
6039 return;
6040 }
6041 mH.post(() -> {
6042 synchronized (mGlobalLock) {
Yunfan Chen79b96062018-10-17 12:45:23 -07006043 final ActivityDisplay activityDisplay =
6044 mStackSupervisor.getActivityDisplay(displayId);
6045 if (activityDisplay == null) {
6046 // Call might come when display is not yet added or has been removed.
Yunfan Chen75157d72018-07-27 14:47:21 +09006047 if (DEBUG_CONFIGURATION) {
6048 Slog.w(TAG, "Trying to update display configuration for non-existing "
Yunfan Chen79b96062018-10-17 12:45:23 -07006049 + "displayId=" + displayId);
Yunfan Chen75157d72018-07-27 14:47:21 +09006050 }
6051 return;
6052 }
Yunfan Chen79b96062018-10-17 12:45:23 -07006053 final WindowProcessController process = mPidMap.get(pid);
6054 if (process == null) {
Yunfan Chen75157d72018-07-27 14:47:21 +09006055 if (DEBUG_CONFIGURATION) {
Yunfan Chen79b96062018-10-17 12:45:23 -07006056 Slog.w(TAG, "Trying to update display configuration for invalid "
6057 + "process, pid=" + pid);
Yunfan Chen75157d72018-07-27 14:47:21 +09006058 }
6059 return;
6060 }
Yunfan Chen79b96062018-10-17 12:45:23 -07006061 process.registerDisplayConfigurationListenerLocked(activityDisplay);
Yunfan Chen75157d72018-07-27 14:47:21 +09006062 }
6063 });
Yunfan Chen79b96062018-10-17 12:45:23 -07006064
Yunfan Chen75157d72018-07-27 14:47:21 +09006065 }
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07006066
6067 @Override
6068 public void sendActivityResult(int callingUid, IBinder activityToken, String resultWho,
6069 int requestCode, int resultCode, Intent data) {
6070 synchronized (mGlobalLock) {
6071 final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
6072 if (r != null && r.getStack() != null) {
6073 r.getStack().sendActivityResultLocked(callingUid, r, resultWho, requestCode,
6074 resultCode, data);
6075 }
6076 }
6077 }
6078
6079 @Override
6080 public void clearPendingResultForActivity(IBinder activityToken,
6081 WeakReference<PendingIntentRecord> pir) {
6082 synchronized (mGlobalLock) {
6083 final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
6084 if (r != null && r.pendingResults != null) {
6085 r.pendingResults.remove(pir);
6086 }
6087 }
6088 }
6089
6090 @Override
6091 public IIntentSender getIntentSender(int type, String packageName,
6092 int callingUid, int userId, IBinder token, String resultWho,
6093 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6094 Bundle bOptions) {
6095 synchronized (mGlobalLock) {
6096 return getIntentSenderLocked(type, packageName, callingUid, userId, token,
6097 resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6098 }
6099 }
Wale Ogunwalec4e63a42018-10-02 13:19:54 -07006100
6101 @Override
6102 public ActivityServiceConnectionsHolder getServiceConnectionsHolder(IBinder token) {
6103 synchronized (mGlobalLock) {
6104 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
6105 if (r == null) {
6106 return null;
6107 }
6108 if (r.mServiceConnectionsHolder == null) {
6109 r.mServiceConnectionsHolder = new ActivityServiceConnectionsHolder(
6110 ActivityTaskManagerService.this, r);
6111 }
6112
6113 return r.mServiceConnectionsHolder;
6114 }
6115 }
Wale Ogunwale214f3482018-10-04 11:00:47 -07006116
6117 @Override
6118 public Intent getHomeIntent() {
6119 synchronized (mGlobalLock) {
6120 return ActivityTaskManagerService.this.getHomeIntent();
6121 }
6122 }
6123
6124 @Override
6125 public boolean startHomeActivity(int userId, String reason) {
6126 synchronized (mGlobalLock) {
6127 return startHomeActivityLocked(userId, reason, DEFAULT_DISPLAY);
6128 }
6129 }
6130
6131 @Override
6132 public boolean isFactoryTestProcess(WindowProcessController wpc) {
6133 synchronized (mGlobalLock) {
6134 if (mFactoryTest == FACTORY_TEST_OFF) {
6135 return false;
6136 }
6137 if (mFactoryTest == FACTORY_TEST_LOW_LEVEL && mTopComponent != null
6138 && wpc.mName.equals(mTopComponent.getPackageName())) {
6139 return true;
6140 }
6141 return mFactoryTest == FACTORY_TEST_HIGH_LEVEL
6142 && (wpc.mInfo.flags & FLAG_FACTORY_TEST) != 0;
6143 }
6144 }
6145
6146 @Override
6147 public void updateTopComponentForFactoryTest() {
6148 synchronized (mGlobalLock) {
6149 if (mFactoryTest != FACTORY_TEST_LOW_LEVEL) {
6150 return;
6151 }
6152 final ResolveInfo ri = mContext.getPackageManager()
6153 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), STOCK_PM_FLAGS);
6154 final CharSequence errorMsg;
6155 if (ri != null) {
6156 final ActivityInfo ai = ri.activityInfo;
6157 final ApplicationInfo app = ai.applicationInfo;
6158 if ((app.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
6159 mTopAction = Intent.ACTION_FACTORY_TEST;
6160 mTopData = null;
6161 mTopComponent = new ComponentName(app.packageName, ai.name);
6162 errorMsg = null;
6163 } else {
6164 errorMsg = mContext.getResources().getText(
6165 com.android.internal.R.string.factorytest_not_system);
6166 }
6167 } else {
6168 errorMsg = mContext.getResources().getText(
6169 com.android.internal.R.string.factorytest_no_action);
6170 }
6171 if (errorMsg == null) {
6172 return;
6173 }
6174
6175 mTopAction = null;
6176 mTopData = null;
6177 mTopComponent = null;
6178 mUiHandler.post(() -> {
6179 Dialog d = new FactoryErrorDialog(mUiContext, errorMsg);
6180 d.show();
Wale Ogunwale342fbe92018-10-09 08:44:10 -07006181 mAmInternal.ensureBootCompleted();
Wale Ogunwale214f3482018-10-04 11:00:47 -07006182 });
6183 }
6184 }
Wale Ogunwale31913b52018-10-13 08:29:31 -07006185
6186 @Override
6187 public void handleAppDied(WindowProcessController wpc, boolean restarting,
6188 Runnable finishInstrumentationCallback) {
6189 synchronized (mGlobalLock) {
6190 // Remove this application's activities from active lists.
6191 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(wpc);
6192
6193 wpc.clearRecentTasks();
6194 wpc.clearActivities();
6195
6196 if (wpc.isInstrumenting()) {
6197 finishInstrumentationCallback.run();
6198 }
6199
6200 mWindowManager.deferSurfaceLayout();
6201 try {
6202 if (!restarting && hasVisibleActivities
6203 && !mStackSupervisor.resumeFocusedStacksTopActivitiesLocked()) {
6204 // If there was nothing to resume, and we are not already restarting this
6205 // process, but there is a visible activity that is hosted by the process...
6206 // then make sure all visible activities are running, taking care of
6207 // restarting this process.
6208 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6209 }
6210 } finally {
6211 mWindowManager.continueSurfaceLayout();
6212 }
6213 }
6214 }
6215
6216 @Override
6217 public void closeSystemDialogs(String reason) {
6218 enforceNotIsolatedCaller("closeSystemDialogs");
6219
6220 final int pid = Binder.getCallingPid();
6221 final int uid = Binder.getCallingUid();
6222 final long origId = Binder.clearCallingIdentity();
6223 try {
6224 synchronized (mGlobalLock) {
6225 // Only allow this from foreground processes, so that background
6226 // applications can't abuse it to prevent system UI from being shown.
6227 if (uid >= FIRST_APPLICATION_UID) {
6228 final WindowProcessController proc = mPidMap.get(pid);
6229 if (!proc.isPerceptible()) {
6230 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6231 + " from background process " + proc);
6232 return;
6233 }
6234 }
Wale Ogunwale31913b52018-10-13 08:29:31 -07006235 mWindowManager.closeSystemDialogs(reason);
6236
6237 mStackSupervisor.closeSystemDialogsLocked();
Wale Ogunwale31913b52018-10-13 08:29:31 -07006238 }
Wale Ogunwale2ea36d42018-10-18 10:27:31 -07006239 // Call into AM outside the synchronized block.
6240 mAmInternal.broadcastCloseSystemDialogs(reason);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006241 } finally {
6242 Binder.restoreCallingIdentity(origId);
6243 }
6244 }
6245
6246 @Override
6247 public void cleanupDisabledPackageComponents(
6248 String packageName, Set<String> disabledClasses, int userId, boolean booted) {
6249 synchronized (mGlobalLock) {
6250 // Clean-up disabled activities.
6251 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6252 packageName, disabledClasses, true, false, userId) && booted) {
6253 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
6254 mStackSupervisor.scheduleIdleLocked();
6255 }
6256
6257 // Clean-up disabled tasks
6258 getRecentTasks().cleanupDisabledPackageTasksLocked(
6259 packageName, disabledClasses, userId);
6260 }
6261 }
6262
6263 @Override
6264 public boolean onForceStopPackage(String packageName, boolean doit, boolean evenPersistent,
6265 int userId) {
6266 synchronized (mGlobalLock) {
6267
6268 boolean didSomething =
6269 getActivityStartController().clearPendingActivityLaunches(packageName);
6270 didSomething |= mStackSupervisor.finishDisabledPackageActivitiesLocked(packageName,
6271 null, doit, evenPersistent, userId);
6272 return didSomething;
6273 }
6274 }
6275
6276 @Override
6277 public void resumeTopActivities(boolean scheduleIdle) {
6278 synchronized (mGlobalLock) {
6279 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
6280 if (scheduleIdle) {
6281 mStackSupervisor.scheduleIdleLocked();
6282 }
6283 }
6284 }
6285
6286 @Override
6287 public void preBindApplication(WindowProcessController wpc) {
6288 synchronized (mGlobalLock) {
6289 mStackSupervisor.getActivityMetricsLogger().notifyBindApplication(wpc.mInfo);
6290 }
6291 }
6292
6293 @Override
6294 public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
6295 synchronized (mGlobalLock) {
6296 return mStackSupervisor.attachApplicationLocked(wpc);
6297 }
6298 }
6299
6300 @Override
6301 public void notifyLockedProfile(@UserIdInt int userId, int currentUserId) {
6302 try {
6303 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
6304 throw new SecurityException("Only privileged app can call notifyLockedProfile");
6305 }
6306 } catch (RemoteException ex) {
6307 throw new SecurityException("Fail to check is caller a privileged app", ex);
6308 }
6309
6310 synchronized (mGlobalLock) {
6311 final long ident = Binder.clearCallingIdentity();
6312 try {
6313 if (mAmInternal.shouldConfirmCredentials(userId)) {
6314 if (mKeyguardController.isKeyguardLocked()) {
6315 // Showing launcher to avoid user entering credential twice.
6316 startHomeActivity(currentUserId, "notifyLockedProfile");
6317 }
6318 mStackSupervisor.lockAllProfileTasks(userId);
6319 }
6320 } finally {
6321 Binder.restoreCallingIdentity(ident);
6322 }
6323 }
6324 }
6325
6326 @Override
6327 public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
6328 mAmInternal.enforceCallingPermission(
6329 MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
6330
6331 synchronized (mGlobalLock) {
6332 final long ident = Binder.clearCallingIdentity();
6333 try {
6334 intent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
6335 FLAG_ACTIVITY_TASK_ON_HOME);
6336 ActivityOptions activityOptions = options != null
6337 ? new ActivityOptions(options) : ActivityOptions.makeBasic();
6338 activityOptions.setLaunchTaskId(
6339 mStackSupervisor.getDefaultDisplayHomeActivity().getTask().taskId);
6340 mContext.startActivityAsUser(intent, activityOptions.toBundle(),
6341 UserHandle.CURRENT);
6342 } finally {
6343 Binder.restoreCallingIdentity(ident);
6344 }
6345 }
6346 }
6347
6348 @Override
6349 public void writeActivitiesToProto(ProtoOutputStream proto) {
6350 synchronized (mGlobalLock) {
6351 // The output proto of "activity --proto activities"
6352 // is ActivityManagerServiceDumpActivitiesProto
6353 mStackSupervisor.writeToProto(proto,
6354 ActivityManagerServiceDumpActivitiesProto.ACTIVITY_STACK_SUPERVISOR);
6355 }
6356 }
6357
6358 @Override
6359 public void saveANRState(String reason) {
6360 synchronized (mGlobalLock) {
6361 final StringWriter sw = new StringWriter();
6362 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
6363 pw.println(" ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
6364 if (reason != null) {
6365 pw.println(" Reason: " + reason);
6366 }
6367 pw.println();
6368 getActivityStartController().dump(pw, " ", null);
6369 pw.println();
6370 pw.println("-------------------------------------------------------------------------------");
6371 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
6372 true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
6373 "" /* header */);
6374 pw.println();
6375 pw.close();
6376
6377 mLastANRState = sw.toString();
6378 }
6379 }
6380
6381 @Override
6382 public void clearSavedANRState() {
6383 synchronized (mGlobalLock) {
6384 mLastANRState = null;
6385 }
6386 }
6387
6388 @Override
6389 public void dump(String cmd, FileDescriptor fd, PrintWriter pw, String[] args, int opti,
6390 boolean dumpAll, boolean dumpClient, String dumpPackage) {
6391 synchronized (mGlobalLock) {
6392 if (DUMP_ACTIVITIES_CMD.equals(cmd) || DUMP_ACTIVITIES_SHORT_CMD.equals(cmd)) {
6393 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
6394 } else if (DUMP_LASTANR_CMD.equals(cmd)) {
6395 dumpLastANRLocked(pw);
6396 } else if (DUMP_LASTANR_TRACES_CMD.equals(cmd)) {
6397 dumpLastANRTracesLocked(pw);
6398 } else if (DUMP_STARTER_CMD.equals(cmd)) {
6399 dumpActivityStarterLocked(pw, dumpPackage);
6400 } else if (DUMP_CONTAINERS_CMD.equals(cmd)) {
6401 dumpActivityContainersLocked(pw);
6402 } else if (DUMP_RECENTS_CMD.equals(cmd) || DUMP_RECENTS_SHORT_CMD.equals(cmd)) {
6403 if (getRecentTasks() != null) {
6404 getRecentTasks().dump(pw, dumpAll, dumpPackage);
6405 }
6406 }
6407 }
6408 }
6409
6410 @Override
6411 public boolean dumpForProcesses(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
6412 String dumpPackage, int dumpAppId, boolean needSep, boolean testPssMode,
6413 int wakefulness) {
6414 synchronized (mGlobalLock) {
6415 if (mHomeProcess != null && (dumpPackage == null
6416 || mHomeProcess.mPkgList.contains(dumpPackage))) {
6417 if (needSep) {
6418 pw.println();
6419 needSep = false;
6420 }
6421 pw.println(" mHomeProcess: " + mHomeProcess);
6422 }
6423 if (mPreviousProcess != null && (dumpPackage == null
6424 || mPreviousProcess.mPkgList.contains(dumpPackage))) {
6425 if (needSep) {
6426 pw.println();
6427 needSep = false;
6428 }
6429 pw.println(" mPreviousProcess: " + mPreviousProcess);
6430 }
6431 if (dumpAll && (mPreviousProcess == null || dumpPackage == null
6432 || mPreviousProcess.mPkgList.contains(dumpPackage))) {
6433 StringBuilder sb = new StringBuilder(128);
6434 sb.append(" mPreviousProcessVisibleTime: ");
6435 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
6436 pw.println(sb);
6437 }
6438 if (mHeavyWeightProcess != null && (dumpPackage == null
6439 || mHeavyWeightProcess.mPkgList.contains(dumpPackage))) {
6440 if (needSep) {
6441 pw.println();
6442 needSep = false;
6443 }
6444 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
6445 }
6446 if (dumpPackage == null) {
6447 pw.println(" mGlobalConfiguration: " + getGlobalConfiguration());
6448 mStackSupervisor.dumpDisplayConfigs(pw, " ");
6449 }
6450 if (dumpAll) {
6451 if (dumpPackage == null) {
6452 pw.println(" mConfigWillChange: "
6453 + getTopDisplayFocusedStack().mConfigWillChange);
6454 }
6455 if (mCompatModePackages.getPackages().size() > 0) {
6456 boolean printed = false;
6457 for (Map.Entry<String, Integer> entry
6458 : mCompatModePackages.getPackages().entrySet()) {
6459 String pkg = entry.getKey();
6460 int mode = entry.getValue();
6461 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
6462 continue;
6463 }
6464 if (!printed) {
6465 pw.println(" mScreenCompatPackages:");
6466 printed = true;
6467 }
6468 pw.println(" " + pkg + ": " + mode);
6469 }
6470 }
6471 }
6472
6473 if (dumpPackage == null) {
6474 pw.println(" mWakefulness="
6475 + PowerManagerInternal.wakefulnessToString(wakefulness));
6476 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
6477 if (mRunningVoice != null) {
6478 pw.println(" mRunningVoice=" + mRunningVoice);
6479 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
6480 }
6481 pw.println(" mSleeping=" + mSleeping);
6482 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + testPssMode);
6483 pw.println(" mVrController=" + mVrController);
6484 }
6485 if (mCurAppTimeTracker != null) {
6486 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
6487 }
6488 if (mAllowAppSwitchUids.size() > 0) {
6489 boolean printed = false;
6490 for (int i = 0; i < mAllowAppSwitchUids.size(); i++) {
6491 ArrayMap<String, Integer> types = mAllowAppSwitchUids.valueAt(i);
6492 for (int j = 0; j < types.size(); j++) {
6493 if (dumpPackage == null ||
6494 UserHandle.getAppId(types.valueAt(j).intValue()) == dumpAppId) {
6495 if (needSep) {
6496 pw.println();
6497 needSep = false;
6498 }
6499 if (!printed) {
6500 pw.println(" mAllowAppSwitchUids:");
6501 printed = true;
6502 }
6503 pw.print(" User ");
6504 pw.print(mAllowAppSwitchUids.keyAt(i));
6505 pw.print(": Type ");
6506 pw.print(types.keyAt(j));
6507 pw.print(" = ");
6508 UserHandle.formatUid(pw, types.valueAt(j).intValue());
6509 pw.println();
6510 }
6511 }
6512 }
6513 }
6514 if (dumpPackage == null) {
6515 if (mController != null) {
6516 pw.println(" mController=" + mController
6517 + " mControllerIsAMonkey=" + mControllerIsAMonkey);
6518 }
6519 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
6520 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
6521 }
6522
6523 return needSep;
6524 }
6525 }
6526
6527 @Override
6528 public void writeProcessesToProto(ProtoOutputStream proto, String dumpPackage) {
6529 synchronized (mGlobalLock) {
6530 if (dumpPackage == null) {
6531 getGlobalConfiguration().writeToProto(proto, GLOBAL_CONFIGURATION);
6532 proto.write(CONFIG_WILL_CHANGE, getTopDisplayFocusedStack().mConfigWillChange);
6533 writeSleepStateToProto(proto);
6534 if (mController != null) {
6535 final long token = proto.start(CONTROLLER);
6536 proto.write(CONTROLLER, mController.toString());
6537 proto.write(IS_A_MONKEY, mControllerIsAMonkey);
6538 proto.end(token);
6539 }
6540 mStackSupervisor.mGoingToSleep.writeToProto(proto, GOING_TO_SLEEP);
6541 mStackSupervisor.mLaunchingActivity.writeToProto(proto, LAUNCHING_ACTIVITY);
6542 }
6543
6544 if (mHomeProcess != null && (dumpPackage == null
6545 || mHomeProcess.mPkgList.contains(dumpPackage))) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07006546 mHomeProcess.writeToProto(proto, HOME_PROC);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006547 }
6548
6549 if (mPreviousProcess != null && (dumpPackage == null
6550 || mPreviousProcess.mPkgList.contains(dumpPackage))) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07006551 mPreviousProcess.writeToProto(proto, PREVIOUS_PROC);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006552 proto.write(PREVIOUS_PROC_VISIBLE_TIME_MS, mPreviousProcessVisibleTime);
6553 }
6554
6555 if (mHeavyWeightProcess != null && (dumpPackage == null
6556 || mHeavyWeightProcess.mPkgList.contains(dumpPackage))) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07006557 mHeavyWeightProcess.writeToProto(proto, HEAVY_WEIGHT_PROC);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006558 }
6559
6560 for (Map.Entry<String, Integer> entry
6561 : mCompatModePackages.getPackages().entrySet()) {
6562 String pkg = entry.getKey();
6563 int mode = entry.getValue();
6564 if (dumpPackage == null || dumpPackage.equals(pkg)) {
6565 long compatToken = proto.start(SCREEN_COMPAT_PACKAGES);
6566 proto.write(PACKAGE, pkg);
6567 proto.write(MODE, mode);
6568 proto.end(compatToken);
6569 }
6570 }
6571
6572 if (mCurAppTimeTracker != null) {
6573 mCurAppTimeTracker.writeToProto(proto, CURRENT_TRACKER, true);
6574 }
6575
6576 }
6577 }
6578
6579 @Override
6580 public boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name,
6581 String[] args, int opti, boolean dumpAll, boolean dumpVisibleStacksOnly,
6582 boolean dumpFocusedStackOnly) {
6583 synchronized (mGlobalLock) {
6584 return ActivityTaskManagerService.this.dumpActivity(fd, pw, name, args, opti,
6585 dumpAll, dumpVisibleStacksOnly, dumpFocusedStackOnly);
6586 }
6587 }
6588
6589 @Override
Wale Ogunwaled4d67d02018-10-25 18:09:39 -07006590 public void dumpForOom(PrintWriter pw) {
6591 synchronized (mGlobalLock) {
6592 pw.println(" mHomeProcess: " + mHomeProcess);
6593 pw.println(" mPreviousProcess: " + mPreviousProcess);
6594 if (mHeavyWeightProcess != null) {
6595 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
6596 }
6597 }
6598 }
6599
6600 @Override
Wale Ogunwale31913b52018-10-13 08:29:31 -07006601 public boolean canGcNow() {
6602 synchronized (mGlobalLock) {
6603 return isSleeping() || mStackSupervisor.allResumedActivitiesIdle();
6604 }
6605 }
6606
6607 @Override
6608 public WindowProcessController getTopApp() {
6609 synchronized (mGlobalLock) {
6610 final ActivityRecord top = mStackSupervisor.getTopResumedActivity();
6611 return top != null ? top.app : null;
6612 }
6613 }
6614
6615 @Override
6616 public void rankTaskLayersIfNeeded() {
6617 synchronized (mGlobalLock) {
6618 if (mStackSupervisor != null) {
6619 mStackSupervisor.rankTaskLayersIfNeeded();
6620 }
6621 }
6622 }
6623
6624 @Override
6625 public void scheduleDestroyAllActivities(String reason) {
6626 synchronized (mGlobalLock) {
6627 mStackSupervisor.scheduleDestroyAllActivities(null, reason);
6628 }
6629 }
6630
6631 @Override
6632 public void removeUser(int userId) {
6633 synchronized (mGlobalLock) {
6634 mStackSupervisor.removeUserLocked(userId);
6635 }
6636 }
6637
6638 @Override
6639 public boolean switchUser(int userId, UserState userState) {
6640 synchronized (mGlobalLock) {
6641 return mStackSupervisor.switchUserLocked(userId, userState);
6642 }
6643 }
6644
6645 @Override
6646 public void onHandleAppCrash(WindowProcessController wpc) {
6647 synchronized (mGlobalLock) {
6648 mStackSupervisor.handleAppCrashLocked(wpc);
6649 }
6650 }
Wale Ogunwale64258362018-10-16 15:13:37 -07006651
6652 @Override
6653 public int finishTopCrashedActivities(WindowProcessController crashedApp, String reason) {
6654 synchronized (mGlobalLock) {
6655 return mStackSupervisor.finishTopCrashedActivitiesLocked(crashedApp, reason);
6656 }
6657 }
Wale Ogunwalebff2df42018-10-18 17:09:19 -07006658
6659 @Override
6660 public void onUidActive(int uid, int procState) {
6661 synchronized (mGlobalLock) {
6662 mActiveUids.put(uid, procState);
6663 }
6664 }
6665
6666 @Override
6667 public void onUidInactive(int uid) {
6668 synchronized (mGlobalLock) {
6669 mActiveUids.remove(uid);
6670 }
6671 }
6672
6673 @Override
6674 public void onActiveUidsCleared() {
6675 synchronized (mGlobalLock) {
6676 mActiveUids.clear();
6677 }
6678 }
6679
6680 @Override
6681 public void onUidProcStateChanged(int uid, int procState) {
6682 synchronized (mGlobalLock) {
6683 if (mActiveUids.get(uid) != null) {
6684 mActiveUids.put(uid, procState);
6685 }
6686 }
6687 }
Wale Ogunwale9de19442018-10-18 19:05:03 -07006688
6689 @Override
6690 public void onUidAddedToPendingTempWhitelist(int uid, String tag) {
6691 synchronized (mGlobalLock) {
6692 mPendingTempWhitelist.put(uid, tag);
6693 }
6694 }
6695
6696 @Override
6697 public void onUidRemovedFromPendingTempWhitelist(int uid) {
6698 synchronized (mGlobalLock) {
6699 mPendingTempWhitelist.remove(uid);
6700 }
6701 }
Wale Ogunwalee2172292018-10-25 10:11:10 -07006702
6703 @Override
6704 public boolean handleAppCrashInActivityController(String processName, int pid,
6705 String shortMsg, String longMsg, long timeMillis, String stackTrace,
6706 Runnable killCrashingAppCallback) {
6707 synchronized (mGlobalLock) {
6708 if (mController == null) {
6709 return false;
6710 }
6711
6712 try {
6713 if (!mController.appCrashed(processName, pid, shortMsg, longMsg, timeMillis,
6714 stackTrace)) {
6715 killCrashingAppCallback.run();
6716 return true;
6717 }
6718 } catch (RemoteException e) {
6719 mController = null;
6720 Watchdog.getInstance().setActivityController(null);
6721 }
6722 return false;
6723 }
6724 }
Wale Ogunwaled7889f52018-10-25 11:03:20 -07006725
6726 @Override
6727 public void removeRecentTasksByPackageName(String packageName, int userId) {
6728 synchronized (mGlobalLock) {
6729 mRecentTasks.removeTasksByPackageName(packageName, userId);
6730 }
6731 }
6732
6733 @Override
6734 public void cleanupRecentTasksForUser(int userId) {
6735 synchronized (mGlobalLock) {
6736 mRecentTasks.cleanupLocked(userId);
6737 }
6738 }
6739
6740 @Override
6741 public void loadRecentTasksForUser(int userId) {
6742 synchronized (mGlobalLock) {
6743 mRecentTasks.loadUserRecentsLocked(userId);
6744 }
6745 }
6746
6747 @Override
6748 public void onPackagesSuspendedChanged(String[] packages, boolean suspended, int userId) {
6749 synchronized (mGlobalLock) {
6750 mRecentTasks.onPackagesSuspendedChanged(packages, suspended, userId);
6751 }
6752 }
6753
6754 @Override
6755 public void flushRecentTasks() {
6756 mRecentTasks.flush();
6757 }
Wale Ogunwaled4d67d02018-10-25 18:09:39 -07006758
6759 @Override
6760 public WindowProcessController getHomeProcess() {
6761 synchronized (mGlobalLock) {
6762 return mHomeProcess;
6763 }
6764 }
6765
6766 @Override
6767 public WindowProcessController getPreviousProcess() {
6768 synchronized (mGlobalLock) {
6769 return mPreviousProcess;
6770 }
6771 }
Wale Ogunwale27c48ae2018-10-25 19:01:01 -07006772
6773 @Override
6774 public void clearLockedTasks(String reason) {
6775 synchronized (mGlobalLock) {
6776 getLockTaskController().clearLockedTasks(reason);
6777 }
6778 }
6779
6780 @Override
6781 public void updateUserConfiguration() {
6782 synchronized (mGlobalLock) {
6783 final Configuration configuration = new Configuration(getGlobalConfiguration());
6784 final int currentUserId = mAmInternal.getCurrentUserId();
6785 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(),
6786 configuration, currentUserId, Settings.System.canWrite(mContext));
6787 updateConfigurationLocked(configuration, null /* starting */,
6788 false /* initLocale */, false /* persistent */, currentUserId,
6789 false /* deferResume */);
6790 }
6791 }
Wale Ogunwale387b34c2018-10-25 19:59:40 -07006792
6793 @Override
6794 public boolean canShowErrorDialogs() {
6795 synchronized (mGlobalLock) {
6796 return mShowDialogs && !mSleeping && !mShuttingDown
6797 && !mKeyguardController.isKeyguardOrAodShowing(DEFAULT_DISPLAY)
6798 && !hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
6799 mAmInternal.getCurrentUserId())
6800 && !(UserManager.isDeviceInDemoMode(mContext)
6801 && mAmInternal.getCurrentUser().isDemo());
6802 }
6803 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07006804 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07006805}