blob: 4897c05ce7f51d8f0fb175f3d91ff62f7888f09b [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;
Evan Rosky4505b352018-09-06 11:20:40 -070029import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
Yunfan Chen79b96062018-10-17 12:45:23 -070030import static android.app.ActivityTaskManager.INVALID_TASK_ID;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070031import static android.app.ActivityTaskManager.RESIZE_MODE_PRESERVE_WINDOW;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070032import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
33import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070034import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
35import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070036import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
37import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070038import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070039import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Wale Ogunwale31913b52018-10-13 08:29:31 -070040import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070041import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
Wale Ogunwale31913b52018-10-13 08:29:31 -070042import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
Wale Ogunwale214f3482018-10-04 11:00:47 -070043import static android.content.pm.ApplicationInfo.FLAG_FACTORY_TEST;
Wale Ogunwale342fbe92018-10-09 08:44:10 -070044import static android.content.pm.ConfigurationInfo.GL_ES_VERSION_UNDEFINED;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070045import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
46import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
Evan Rosky4505b352018-09-06 11:20:40 -070047import static android.content.pm.PackageManager.FEATURE_PC;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070048import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070049import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070050import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
51import static android.os.Build.VERSION_CODES.N;
Wale Ogunwale214f3482018-10-04 11:00:47 -070052import static android.os.FactoryTest.FACTORY_TEST_HIGH_LEVEL;
53import static android.os.FactoryTest.FACTORY_TEST_LOW_LEVEL;
54import static android.os.FactoryTest.FACTORY_TEST_OFF;
Wale Ogunwale31913b52018-10-13 08:29:31 -070055import static android.os.Process.FIRST_APPLICATION_UID;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070056import static android.os.Process.SYSTEM_UID;
Evan Rosky4505b352018-09-06 11:20:40 -070057import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070058import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
59import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
60import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
61import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
Evan Rosky4505b352018-09-06 11:20:40 -070062import static android.provider.Settings.Global.HIDE_ERROR_DIALOGS;
63import static android.provider.Settings.System.FONT_SCALE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070064import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
65import static android.view.Display.DEFAULT_DISPLAY;
66import static android.view.Display.INVALID_DISPLAY;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070067import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
Wale Ogunwale6767eae2018-05-03 15:52:51 -070068import static android.view.WindowManager.TRANSIT_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070069import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070070import static android.view.WindowManager.TRANSIT_TASK_OPEN;
71import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
Evan Rosky4505b352018-09-06 11:20:40 -070072
Yunfan Chen79b96062018-10-17 12:45:23 -070073import static com.android.server.am.ActivityManagerService.ANR_TRACE_DIR;
74import static com.android.server.am.ActivityManagerService.MY_PID;
75import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS;
76import static com.android.server.am.ActivityManagerService.dumpStackTraces;
Wale Ogunwale31913b52018-10-13 08:29:31 -070077import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.CONFIG_WILL_CHANGE;
78import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.CONTROLLER;
79import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.CURRENT_TRACKER;
80import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.Controller.IS_A_MONKEY;
81import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.GLOBAL_CONFIGURATION;
82import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.GOING_TO_SLEEP;
83import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.HEAVY_WEIGHT_PROC;
84import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.HOME_PROC;
85import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.LAUNCHING_ACTIVITY;
86import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC;
Yunfan Chen79b96062018-10-17 12:45:23 -070087import static com.android.server.am.ActivityManagerServiceDumpProcessesProto
88 .PREVIOUS_PROC_VISIBLE_TIME_MS;
Wale Ogunwale31913b52018-10-13 08:29:31 -070089import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.SCREEN_COMPAT_PACKAGES;
Yunfan Chen79b96062018-10-17 12:45:23 -070090import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage
91 .MODE;
92import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage
93 .PACKAGE;
94import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
95import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
96import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
97import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
98import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
99import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
100import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
Wale Ogunwale98875612018-10-12 07:53:02 -0700101import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_ALL;
102import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
103import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_FOCUS;
104import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_IMMERSIVE;
105import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_LOCKTASK;
106import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_STACK;
107import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
108import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
109import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_VISIBILITY;
110import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
111import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS;
112import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_IMMERSIVE;
113import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_LOCKTASK;
114import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_STACK;
115import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH;
116import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_VISIBILITY;
117import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_ATM;
118import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
Evan Rosky4505b352018-09-06 11:20:40 -0700119import static com.android.server.am.ActivityTaskManagerService.H.REPORT_TIME_TRACKER_MSG;
120import static com.android.server.am.ActivityTaskManagerService.UiHandler.DISMISS_DIALOG_UI_MSG;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700121import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700122import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700123import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
Evan Rosky4505b352018-09-06 11:20:40 -0700124import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT;
125import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_DATA;
126import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
127import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700128import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
129import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700130
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700131import android.Manifest;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700132import android.annotation.NonNull;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700133import android.annotation.Nullable;
134import android.annotation.UserIdInt;
135import android.app.Activity;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700136import android.app.ActivityManager;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700137import android.app.ActivityManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700138import android.app.ActivityOptions;
139import android.app.ActivityTaskManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700140import android.app.ActivityThread;
141import android.app.AlertDialog;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700142import android.app.AppGlobals;
Evan Rosky4505b352018-09-06 11:20:40 -0700143import android.app.Dialog;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700144import android.app.IActivityController;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700145import android.app.IActivityTaskManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700146import android.app.IApplicationThread;
147import android.app.IAssistDataReceiver;
Wale Ogunwale53783742018-09-16 10:21:51 -0700148import android.app.INotificationManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700149import android.app.ITaskStackListener;
Wale Ogunwale53783742018-09-16 10:21:51 -0700150import android.app.Notification;
151import android.app.NotificationManager;
152import android.app.PendingIntent;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700153import android.app.PictureInPictureParams;
154import android.app.ProfilerInfo;
155import android.app.RemoteAction;
156import android.app.WaitResult;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700157import android.app.WindowConfiguration;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700158import android.app.admin.DevicePolicyCache;
159import android.app.assist.AssistContent;
160import android.app.assist.AssistStructure;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700161import android.app.usage.UsageStatsManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700162import android.content.ActivityNotFoundException;
163import android.content.ComponentName;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700164import android.content.ContentResolver;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700165import android.content.Context;
Evan Rosky4505b352018-09-06 11:20:40 -0700166import android.content.DialogInterface;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700167import android.content.IIntentSender;
168import android.content.Intent;
169import android.content.pm.ActivityInfo;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700170import android.content.pm.ApplicationInfo;
Yunfan Chen75157d72018-07-27 14:47:21 +0900171import android.content.pm.ConfigurationInfo;
Evan Rosky4505b352018-09-06 11:20:40 -0700172import android.content.pm.IPackageManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700173import android.content.pm.PackageManager;
Evan Rosky4505b352018-09-06 11:20:40 -0700174import android.content.pm.PackageManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700175import android.content.pm.ParceledListSlice;
176import android.content.pm.ResolveInfo;
Wale Ogunwale53783742018-09-16 10:21:51 -0700177import android.content.res.CompatibilityInfo;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700178import android.content.res.Configuration;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700179import android.content.res.Resources;
Evan Rosky4505b352018-09-06 11:20:40 -0700180import android.database.ContentObserver;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700181import android.graphics.Bitmap;
182import android.graphics.Point;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700183import android.graphics.Rect;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700184import android.metrics.LogMaker;
185import android.net.Uri;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700186import android.os.Binder;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700187import android.os.Build;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700188import android.os.Bundle;
Wale Ogunwale214f3482018-10-04 11:00:47 -0700189import android.os.FactoryTest;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700190import android.os.FileUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700191import android.os.Handler;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700192import android.os.IBinder;
Evan Rosky4505b352018-09-06 11:20:40 -0700193import android.os.IUserManager;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700194import android.os.LocaleList;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700195import android.os.Looper;
196import android.os.Message;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700197import android.os.PersistableBundle;
Evan Rosky4505b352018-09-06 11:20:40 -0700198import android.os.PowerManager;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700199import android.os.PowerManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700200import android.os.RemoteException;
Evan Rosky4505b352018-09-06 11:20:40 -0700201import android.os.ServiceManager;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700202import android.os.StrictMode;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700203import android.os.SystemClock;
204import android.os.SystemProperties;
Evan Rosky4505b352018-09-06 11:20:40 -0700205import android.os.Trace;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700206import android.os.UpdateLock;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700207import android.os.UserHandle;
Evan Rosky4505b352018-09-06 11:20:40 -0700208import android.os.UserManager;
209import android.os.WorkSource;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700210import android.os.storage.IStorageManager;
211import android.os.storage.StorageManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700212import android.provider.Settings;
213import android.service.voice.IVoiceInteractionSession;
214import android.service.voice.VoiceInteractionManagerInternal;
215import android.telecom.TelecomManager;
216import android.text.TextUtils;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700217import android.text.format.Time;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700218import android.util.ArrayMap;
219import android.util.EventLog;
220import android.util.Log;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700221import android.util.Slog;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700222import android.util.SparseArray;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700223import android.util.SparseIntArray;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700224import android.util.StatsLog;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700225import android.util.TimeUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700226import android.util.proto.ProtoOutputStream;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700227import android.view.IRecentsAnimationRunner;
228import android.view.RemoteAnimationAdapter;
229import android.view.RemoteAnimationDefinition;
Evan Rosky4505b352018-09-06 11:20:40 -0700230import android.view.WindowManager;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700231
Evan Rosky4505b352018-09-06 11:20:40 -0700232import com.android.internal.R;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700233import com.android.internal.annotations.VisibleForTesting;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700234import com.android.internal.app.AssistUtils;
Evan Rosky4505b352018-09-06 11:20:40 -0700235import com.android.internal.app.IAppOpsService;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700236import com.android.internal.app.IVoiceInteractor;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700237import com.android.internal.app.ProcessMap;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700238import com.android.internal.logging.MetricsLogger;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700239import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Wale Ogunwale53783742018-09-16 10:21:51 -0700240import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
241import com.android.internal.notification.SystemNotificationChannels;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700242import com.android.internal.os.TransferPipe;
Evan Rosky4505b352018-09-06 11:20:40 -0700243import com.android.internal.os.logging.MetricsLoggerWrapper;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700244import com.android.internal.policy.IKeyguardDismissCallback;
245import com.android.internal.policy.KeyguardDismissCallback;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700246import com.android.internal.util.ArrayUtils;
247import com.android.internal.util.FastPrintWriter;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700248import com.android.internal.util.Preconditions;
Wale Ogunwale53783742018-09-16 10:21:51 -0700249import com.android.internal.util.function.pooled.PooledLambda;
Evan Rosky4505b352018-09-06 11:20:40 -0700250import com.android.server.AppOpsService;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700251import com.android.server.AttributeCache;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700252import com.android.server.LocalServices;
253import com.android.server.SystemService;
Evan Rosky4505b352018-09-06 11:20:40 -0700254import com.android.server.SystemServiceManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700255import com.android.server.Watchdog;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700256import com.android.server.firewall.IntentFirewall;
Evan Rosky4505b352018-09-06 11:20:40 -0700257import com.android.server.pm.UserManagerService;
258import com.android.server.uri.UriGrantsManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700259import com.android.server.vr.VrManagerInternal;
Evan Rosky4505b352018-09-06 11:20:40 -0700260import com.android.server.wm.ActivityTaskManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700261import com.android.server.wm.PinnedStackWindowController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700262import com.android.server.wm.WindowManagerService;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700263
Wale Ogunwale31913b52018-10-13 08:29:31 -0700264import java.io.BufferedReader;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700265import java.io.File;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700266import java.io.FileDescriptor;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700267import java.io.FileOutputStream;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700268import java.io.FileReader;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700269import java.io.IOException;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700270import java.io.PrintWriter;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700271import java.io.StringWriter;
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700272import java.lang.ref.WeakReference;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700273import java.text.DateFormat;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700274import java.util.ArrayList;
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 Ogunwale16e505a2018-05-07 15:00:49 -0700334 ActivityManagerService mAm;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700335 ActivityManagerInternal mAmInternal;
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700336 UriGrantsManagerInternal mUgmInternal;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700337 private PackageManagerInternal mPmInternal;
Wale Ogunwale53783742018-09-16 10:21:51 -0700338 private ActivityTaskManagerInternal mInternal;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700339 PowerManagerInternal mPowerManagerInternal;
340 private UsageStatsManagerInternal mUsageStatsInternal;
341
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700342 PendingIntentController mPendingIntentController;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700343 IntentFirewall mIntentFirewall;
344
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700345 /* Global service lock used by the package the owns this service. */
346 Object mGlobalLock;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700347 ActivityStackSupervisor mStackSupervisor;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700348 WindowManagerService mWindowManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700349 private UserManagerService mUserManager;
350 private AppOpsService mAppOpsService;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700351 /** All processes currently running that might have a window organized by name. */
352 final ProcessMap<WindowProcessController> mProcessNames = new ProcessMap<>();
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700353 /** All processes we currently have running mapped by pid */
354 final SparseArray<WindowProcessController> mPidMap = new SparseArray<>();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700355 /** This is the process holding what we currently consider to be the "home" activity. */
356 WindowProcessController mHomeProcess;
Wale Ogunwale53783742018-09-16 10:21:51 -0700357 /** The currently running heavy-weight process, if any. */
358 WindowProcessController mHeavyWeightProcess = null;
Wale Ogunwale214f3482018-10-04 11:00:47 -0700359 boolean mHasHeavyWeightFeature;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700360 /**
361 * This is the process holding the activity the user last visited that is in a different process
362 * from the one they are currently in.
363 */
364 WindowProcessController mPreviousProcess;
365 /** The time at which the previous process was last visible. */
366 long mPreviousProcessVisibleTime;
367
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700368 /** List of intents that were used to start the most recent tasks. */
369 private RecentTasks mRecentTasks;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700370 /** State of external calls telling us if the device is awake or asleep. */
371 private boolean mKeyguardShown = false;
372
373 // Wrapper around VoiceInteractionServiceManager
374 private AssistUtils mAssistUtils;
375
376 // VoiceInteraction session ID that changes for each new request except when
377 // being called for multi-window assist in a single session.
378 private int mViSessionId = 1000;
379
380 // How long to wait in getAssistContextExtras for the activity and foreground services
381 // to respond with the result.
382 private static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
383
384 // How long top wait when going through the modern assist (which doesn't need to block
385 // on getting this result before starting to launch its UI).
386 private static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
387
388 // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
389 private static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
390
391 private final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
392
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700393 // Keeps track of the active voice interaction service component, notified from
394 // VoiceInteractionManagerService
395 ComponentName mActiveVoiceInteractionServiceComponent;
396
397 private VrController mVrController;
398 KeyguardController mKeyguardController;
399 private final ClientLifecycleManager mLifecycleManager;
400 private TaskChangeNotificationController mTaskChangeNotificationController;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700401 /** The controller for all operations related to locktask. */
402 private LockTaskController mLockTaskController;
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700403 private ActivityStartController mActivityStartController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700404
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700405 boolean mSuppressResizeConfigChanges;
406
407 private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
408 new UpdateConfigurationResult();
409
410 static final class UpdateConfigurationResult {
411 // Configuration changes that were updated.
412 int changes;
413 // If the activity was relaunched to match the new configuration.
414 boolean activityRelaunched;
415
416 void reset() {
417 changes = 0;
418 activityRelaunched = false;
419 }
420 }
421
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700422 /** Current sequencing integer of the configuration, for skipping old configurations. */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700423 private int mConfigurationSeq;
424 // To cache the list of supported system locales
425 private String[] mSupportedSystemLocales = null;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700426
427 /**
428 * Temp object used when global and/or display override configuration is updated. It is also
429 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
430 * anyone...
431 */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700432 private Configuration mTempConfig = new Configuration();
433
Wale Ogunwalef6733932018-06-27 05:14:34 -0700434 /** Temporary to avoid allocations. */
435 final StringBuilder mStringBuilder = new StringBuilder(256);
436
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700437 // Amount of time after a call to stopAppSwitches() during which we will
438 // prevent further untrusted switches from happening.
439 private static final long APP_SWITCH_DELAY_TIME = 5 * 1000;
440
441 /**
442 * The time at which we will allow normal application switches again,
443 * after a call to {@link #stopAppSwitches()}.
444 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700445 private long mAppSwitchesAllowedTime;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700446 /**
447 * This is set to true after the first switch after mAppSwitchesAllowedTime
448 * is set; any switches after that will clear the time.
449 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700450 private boolean mDidAppSwitch;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700451
452 IActivityController mController = null;
453 boolean mControllerIsAMonkey = false;
454
Wale Ogunwale214f3482018-10-04 11:00:47 -0700455 final int mFactoryTest;
456
457 /** Used to control how we initialize the service. */
458 ComponentName mTopComponent;
459 String mTopAction = Intent.ACTION_MAIN;
460 String mTopData;
461
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700462 /**
Wale Ogunwale31913b52018-10-13 08:29:31 -0700463 * Dump of the activity state at the time of the last ANR. Cleared after
464 * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
465 */
466 String mLastANRState;
467
468 /**
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700469 * Used to retain an update lock when the foreground activity is in
470 * immersive mode.
471 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700472 private final UpdateLock mUpdateLock = new UpdateLock("immersive");
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700473
474 /**
475 * Packages that are being allowed to perform unrestricted app switches. Mapping is
476 * User -> Type -> uid.
477 */
478 final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
479
480 /** The dimensions of the thumbnails in the Recents UI. */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700481 private int mThumbnailWidth;
482 private int mThumbnailHeight;
483 private float mFullscreenThumbnailScale;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700484
485 /**
486 * Flag that indicates if multi-window is enabled.
487 *
488 * For any particular form of multi-window to be enabled, generic multi-window must be enabled
489 * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
490 * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
491 * At least one of the forms of multi-window must be enabled in order for this flag to be
492 * initialized to 'true'.
493 *
494 * @see #mSupportsSplitScreenMultiWindow
495 * @see #mSupportsFreeformWindowManagement
496 * @see #mSupportsPictureInPicture
497 * @see #mSupportsMultiDisplay
498 */
499 boolean mSupportsMultiWindow;
500 boolean mSupportsSplitScreenMultiWindow;
501 boolean mSupportsFreeformWindowManagement;
502 boolean mSupportsPictureInPicture;
503 boolean mSupportsMultiDisplay;
504 boolean mForceResizableActivities;
505
506 final List<ActivityTaskManagerInternal.ScreenObserver> mScreenObservers = new ArrayList<>();
507
508 // VR Vr2d Display Id.
509 int mVr2dDisplayId = INVALID_DISPLAY;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700510
Wale Ogunwalef6733932018-06-27 05:14:34 -0700511 /**
512 * Set while we are wanting to sleep, to prevent any
513 * activities from being started/resumed.
514 *
515 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
516 *
517 * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
518 * while in the sleep state until there is a pending transition out of sleep, in which case
519 * mSleeping is set to false, and remains false while awake.
520 *
521 * Whether mSleeping can quickly toggled between true/false without the device actually
522 * display changing states is undefined.
523 */
524 private boolean mSleeping = false;
525
526 /**
527 * The process state used for processes that are running the top activities.
528 * This changes between TOP and TOP_SLEEPING to following mSleeping.
529 */
530 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
531
532 // Whether we should show our dialogs (ANR, crash, etc) or just perform their default action
533 // automatically. Important for devices without direct input devices.
534 private boolean mShowDialogs = true;
535
536 /** Set if we are shutting down the system, similar to sleeping. */
537 boolean mShuttingDown = false;
538
539 /**
540 * We want to hold a wake lock while running a voice interaction session, since
541 * this may happen with the screen off and we need to keep the CPU running to
542 * be able to continue to interact with the user.
543 */
544 PowerManager.WakeLock mVoiceWakeLock;
545
546 /**
547 * Set while we are running a voice interaction. This overrides sleeping while it is active.
548 */
549 IVoiceInteractionSession mRunningVoice;
550
551 /**
552 * The last resumed activity. This is identical to the current resumed activity most
553 * of the time but could be different when we're pausing one activity before we resume
554 * another activity.
555 */
556 ActivityRecord mLastResumedActivity;
557
558 /**
559 * The activity that is currently being traced as the active resumed activity.
560 *
561 * @see #updateResumedAppTrace
562 */
563 private @Nullable ActivityRecord mTracedResumedActivity;
564
565 /** If non-null, we are tracking the time the user spends in the currently focused app. */
566 AppTimeTracker mCurAppTimeTracker;
567
Wale Ogunwale008163e2018-07-23 23:11:08 -0700568 private AppWarnings mAppWarnings;
569
Wale Ogunwale53783742018-09-16 10:21:51 -0700570 /**
571 * Packages that the user has asked to have run in screen size
572 * compatibility mode instead of filling the screen.
573 */
574 CompatModePackages mCompatModePackages;
575
Wale Ogunwalef6733932018-06-27 05:14:34 -0700576 private FontScaleSettingObserver mFontScaleSettingObserver;
577
578 private final class FontScaleSettingObserver extends ContentObserver {
579 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
580 private final Uri mHideErrorDialogsUri = Settings.Global.getUriFor(HIDE_ERROR_DIALOGS);
581
582 public FontScaleSettingObserver() {
583 super(mH);
584 final ContentResolver resolver = mContext.getContentResolver();
585 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
586 resolver.registerContentObserver(mHideErrorDialogsUri, false, this,
587 UserHandle.USER_ALL);
588 }
589
590 @Override
591 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
592 if (mFontScaleUri.equals(uri)) {
593 updateFontScaleIfNeeded(userId);
594 } else if (mHideErrorDialogsUri.equals(uri)) {
595 synchronized (mGlobalLock) {
596 updateShouldShowDialogsLocked(getGlobalConfiguration());
597 }
598 }
599 }
600 }
601
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700602 ActivityTaskManagerService(Context context) {
603 mContext = context;
Wale Ogunwale214f3482018-10-04 11:00:47 -0700604 mFactoryTest = FactoryTest.getMode();
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700605 mSystemThread = ActivityThread.currentActivityThread();
606 mUiContext = mSystemThread.getSystemUiContext();
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700607 mLifecycleManager = new ClientLifecycleManager();
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700608 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", GL_ES_VERSION_UNDEFINED);
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700609 }
610
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700611 void onSystemReady() {
Wale Ogunwale214f3482018-10-04 11:00:47 -0700612 mHasHeavyWeightFeature = mContext.getPackageManager().hasSystemFeature(
613 PackageManager.FEATURE_CANT_SAVE_STATE);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700614 mAssistUtils = new AssistUtils(mContext);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700615 mVrController.onSystemReady();
616 mRecentTasks.onSystemReadyLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700617 }
618
Wale Ogunwalef6733932018-06-27 05:14:34 -0700619 void onInitPowerManagement() {
620 mStackSupervisor.initPowerManagement();
621 final PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700622 mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
Wale Ogunwalef6733932018-06-27 05:14:34 -0700623 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
624 mVoiceWakeLock.setReferenceCounted(false);
625 }
626
627 void installSystemProviders() {
628 mFontScaleSettingObserver = new FontScaleSettingObserver();
629 }
630
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700631 void retrieveSettings(ContentResolver resolver) {
632 final boolean freeformWindowManagement =
633 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
634 || Settings.Global.getInt(
635 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
636
637 final boolean supportsMultiWindow = ActivityTaskManager.supportsMultiWindow(mContext);
638 final boolean supportsPictureInPicture = supportsMultiWindow &&
639 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
640 final boolean supportsSplitScreenMultiWindow =
641 ActivityTaskManager.supportsSplitScreenMultiWindow(mContext);
642 final boolean supportsMultiDisplay = mContext.getPackageManager()
643 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
644 final boolean alwaysFinishActivities =
645 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
646 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
647 final boolean forceResizable = Settings.Global.getInt(
648 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
Garfield Tane0846042018-07-26 13:42:04 -0700649 final boolean isPc = mContext.getPackageManager().hasSystemFeature(FEATURE_PC);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700650
651 // Transfer any global setting for forcing RTL layout, into a System Property
652 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
653
654 final Configuration configuration = new Configuration();
655 Settings.System.getConfiguration(resolver, configuration);
656 if (forceRtl) {
657 // This will take care of setting the correct layout direction flags
658 configuration.setLayoutDirection(configuration.locale);
659 }
660
661 synchronized (mGlobalLock) {
662 mForceResizableActivities = forceResizable;
663 final boolean multiWindowFormEnabled = freeformWindowManagement
664 || supportsSplitScreenMultiWindow
665 || supportsPictureInPicture
666 || supportsMultiDisplay;
667 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
668 mSupportsMultiWindow = true;
669 mSupportsFreeformWindowManagement = freeformWindowManagement;
670 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
671 mSupportsPictureInPicture = supportsPictureInPicture;
672 mSupportsMultiDisplay = supportsMultiDisplay;
673 } else {
674 mSupportsMultiWindow = false;
675 mSupportsFreeformWindowManagement = false;
676 mSupportsSplitScreenMultiWindow = false;
677 mSupportsPictureInPicture = false;
678 mSupportsMultiDisplay = false;
679 }
680 mWindowManager.setForceResizableTasks(mForceResizableActivities);
681 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
Garfield Tane0846042018-07-26 13:42:04 -0700682 mWindowManager.setSupportsFreeformWindowManagement(mSupportsFreeformWindowManagement);
683 mWindowManager.setIsPc(isPc);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700684 // This happens before any activities are started, so we can change global configuration
685 // in-place.
686 updateConfigurationLocked(configuration, null, true);
687 final Configuration globalConfig = getGlobalConfiguration();
688 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
689
690 // Load resources only after the current configuration has been set.
691 final Resources res = mContext.getResources();
692 mThumbnailWidth = res.getDimensionPixelSize(
693 com.android.internal.R.dimen.thumbnail_width);
694 mThumbnailHeight = res.getDimensionPixelSize(
695 com.android.internal.R.dimen.thumbnail_height);
696
697 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
698 mFullscreenThumbnailScale = (float) res
699 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
700 (float) globalConfig.screenWidthDp;
701 } else {
702 mFullscreenThumbnailScale = res.getFraction(
703 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
704 }
705 }
706 }
707
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700708 // TODO: Will be converted to WM lock once transition is complete.
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700709 void setActivityManagerService(ActivityManagerService am, Looper looper,
710 IntentFirewall intentFirewall, PendingIntentController intentController) {
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700711 mAm = am;
712 mGlobalLock = mAm;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700713 mH = new H(looper);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700714 mUiHandler = new UiHandler();
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700715 mIntentFirewall = intentFirewall;
Wale Ogunwale53783742018-09-16 10:21:51 -0700716 final File systemDir = SystemServiceManager.ensureSystemDir();
717 mAppWarnings = new AppWarnings(this, mUiContext, mH, mUiHandler, systemDir);
718 mCompatModePackages = new CompatModePackages(this, systemDir, mH);
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700719 mPendingIntentController = intentController;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700720
721 mTempConfig.setToDefaults();
722 mTempConfig.setLocales(LocaleList.getDefault());
723 mConfigurationSeq = mTempConfig.seq = 1;
724 mStackSupervisor = createStackSupervisor();
725 mStackSupervisor.onConfigurationChanged(mTempConfig);
726
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700727 mTaskChangeNotificationController =
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700728 new TaskChangeNotificationController(mGlobalLock, mStackSupervisor, mH);
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700729 mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mH);
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700730 mActivityStartController = new ActivityStartController(this);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700731 mRecentTasks = createRecentTasks();
732 mStackSupervisor.setRecentTasks(mRecentTasks);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700733 mVrController = new VrController(mGlobalLock);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700734 mKeyguardController = mStackSupervisor.getKeyguardController();
735 }
736
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700737 void onActivityManagerInternalAdded() {
738 mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700739 mUgmInternal = LocalServices.getService(UriGrantsManagerInternal.class);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700740 }
741
Yunfan Chen75157d72018-07-27 14:47:21 +0900742 int increaseConfigurationSeqLocked() {
743 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
744 return mConfigurationSeq;
745 }
746
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700747 protected ActivityStackSupervisor createStackSupervisor() {
748 final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mH.getLooper());
749 supervisor.initialize();
750 return supervisor;
751 }
752
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700753 void setWindowManager(WindowManagerService wm) {
754 mWindowManager = wm;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700755 mLockTaskController.setWindowManager(wm);
Wale Ogunwale31913b52018-10-13 08:29:31 -0700756 mStackSupervisor.setWindowManager(wm);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700757 }
758
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700759 void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
760 mUsageStatsInternal = usageStatsManager;
761 }
762
Wale Ogunwalef6733932018-06-27 05:14:34 -0700763 UserManagerService getUserManager() {
764 if (mUserManager == null) {
765 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
766 mUserManager = (UserManagerService) IUserManager.Stub.asInterface(b);
767 }
768 return mUserManager;
769 }
770
771 AppOpsService getAppOpsService() {
772 if (mAppOpsService == null) {
773 IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
774 mAppOpsService = (AppOpsService) IAppOpsService.Stub.asInterface(b);
775 }
776 return mAppOpsService;
777 }
778
779 boolean hasUserRestriction(String restriction, int userId) {
780 return getUserManager().hasUserRestriction(restriction, userId);
781 }
782
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700783 protected RecentTasks createRecentTasks() {
784 return new RecentTasks(this, mStackSupervisor);
785 }
786
787 RecentTasks getRecentTasks() {
788 return mRecentTasks;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700789 }
790
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700791 ClientLifecycleManager getLifecycleManager() {
792 return mLifecycleManager;
793 }
794
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700795 ActivityStartController getActivityStartController() {
796 return mActivityStartController;
797 }
798
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700799 TaskChangeNotificationController getTaskChangeNotificationController() {
800 return mTaskChangeNotificationController;
801 }
802
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700803 LockTaskController getLockTaskController() {
804 return mLockTaskController;
805 }
806
Yunfan Chen75157d72018-07-27 14:47:21 +0900807 /**
808 * Return the global configuration used by the process corresponding to the input pid. This is
809 * usually the global configuration with some overrides specific to that process.
810 */
811 Configuration getGlobalConfigurationForCallingPid() {
812 final int pid = Binder.getCallingPid();
813 if (pid == MY_PID || pid < 0) {
814 return getGlobalConfiguration();
815 }
816 synchronized (mGlobalLock) {
817 final WindowProcessController app = mPidMap.get(pid);
818 return app != null ? app.getConfiguration() : getGlobalConfiguration();
819 }
820 }
821
822 /**
823 * Return the device configuration info used by the process corresponding to the input pid.
824 * The value is consistent with the global configuration for the process.
825 */
826 @Override
827 public ConfigurationInfo getDeviceConfigurationInfo() {
828 ConfigurationInfo config = new ConfigurationInfo();
829 synchronized (mGlobalLock) {
830 final Configuration globalConfig = getGlobalConfigurationForCallingPid();
831 config.reqTouchScreen = globalConfig.touchscreen;
832 config.reqKeyboardType = globalConfig.keyboard;
833 config.reqNavigation = globalConfig.navigation;
834 if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
835 || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
836 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
837 }
838 if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
839 && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
840 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
841 }
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700842 config.reqGlEsVersion = GL_ES_VERSION;
Yunfan Chen75157d72018-07-27 14:47:21 +0900843 }
844 return config;
845 }
846
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700847 private void start() {
Wale Ogunwale53783742018-09-16 10:21:51 -0700848 mInternal = new LocalService();
849 LocalServices.addService(ActivityTaskManagerInternal.class, mInternal);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700850 }
851
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700852 public static final class Lifecycle extends SystemService {
853 private final ActivityTaskManagerService mService;
854
855 public Lifecycle(Context context) {
856 super(context);
857 mService = new ActivityTaskManagerService(context);
858 }
859
860 @Override
861 public void onStart() {
862 publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700863 mService.start();
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700864 }
865
866 public ActivityTaskManagerService getService() {
867 return mService;
868 }
869 }
870
871 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700872 public final int startActivity(IApplicationThread caller, String callingPackage,
873 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
874 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
875 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
876 resultWho, requestCode, startFlags, profilerInfo, bOptions,
877 UserHandle.getCallingUserId());
878 }
879
880 @Override
881 public final int startActivities(IApplicationThread caller, String callingPackage,
882 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
883 int userId) {
884 final String reason = "startActivities";
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700885 enforceNotIsolatedCaller(reason);
886 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, reason);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700887 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700888 return getActivityStartController().startActivities(caller, -1, callingPackage, intents,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100889 resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId, reason,
890 null /* originatingPendingIntent */);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700891 }
892
893 @Override
894 public int startActivityAsUser(IApplicationThread caller, String callingPackage,
895 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
896 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
897 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
898 resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
899 true /*validateIncomingUser*/);
900 }
901
902 int startActivityAsUser(IApplicationThread caller, String callingPackage,
903 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
904 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
905 boolean validateIncomingUser) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700906 enforceNotIsolatedCaller("startActivityAsUser");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700907
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700908 userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700909 Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
910
911 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700912 return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700913 .setCaller(caller)
914 .setCallingPackage(callingPackage)
915 .setResolvedType(resolvedType)
916 .setResultTo(resultTo)
917 .setResultWho(resultWho)
918 .setRequestCode(requestCode)
919 .setStartFlags(startFlags)
920 .setProfilerInfo(profilerInfo)
921 .setActivityOptions(bOptions)
922 .setMayWait(userId)
923 .execute();
924
925 }
926
927 @Override
928 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
929 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700930 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions) {
931 enforceNotIsolatedCaller("startActivityIntentSender");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700932 // Refuse possible leaked file descriptors
933 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
934 throw new IllegalArgumentException("File descriptors passed in Intent");
935 }
936
937 if (!(target instanceof PendingIntentRecord)) {
938 throw new IllegalArgumentException("Bad PendingIntent object");
939 }
940
941 PendingIntentRecord pir = (PendingIntentRecord)target;
942
943 synchronized (mGlobalLock) {
944 // If this is coming from the currently resumed activity, it is
945 // effectively saying that app switches are allowed at this point.
Andrii Kulian5f750bc2018-07-17 08:57:23 -0700946 final ActivityStack stack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700947 if (stack.mResumedActivity != null &&
948 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700949 mAppSwitchesAllowedTime = 0;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700950 }
951 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700952 return pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700953 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700954 }
955
956 @Override
957 public boolean startNextMatchingActivity(IBinder callingActivity, Intent intent,
958 Bundle bOptions) {
959 // Refuse possible leaked file descriptors
960 if (intent != null && intent.hasFileDescriptors()) {
961 throw new IllegalArgumentException("File descriptors passed in Intent");
962 }
963 SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
964
965 synchronized (mGlobalLock) {
966 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
967 if (r == null) {
968 SafeActivityOptions.abort(options);
969 return false;
970 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700971 if (!r.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700972 // The caller is not running... d'oh!
973 SafeActivityOptions.abort(options);
974 return false;
975 }
976 intent = new Intent(intent);
977 // The caller is not allowed to change the data.
978 intent.setDataAndType(r.intent.getData(), r.intent.getType());
979 // And we are resetting to find the next component...
980 intent.setComponent(null);
981
982 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
983
984 ActivityInfo aInfo = null;
985 try {
986 List<ResolveInfo> resolves =
987 AppGlobals.getPackageManager().queryIntentActivities(
988 intent, r.resolvedType,
989 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
990 UserHandle.getCallingUserId()).getList();
991
992 // Look for the original activity in the list...
993 final int N = resolves != null ? resolves.size() : 0;
994 for (int i=0; i<N; i++) {
995 ResolveInfo rInfo = resolves.get(i);
996 if (rInfo.activityInfo.packageName.equals(r.packageName)
997 && rInfo.activityInfo.name.equals(r.info.name)) {
998 // We found the current one... the next matching is
999 // after it.
1000 i++;
1001 if (i<N) {
1002 aInfo = resolves.get(i).activityInfo;
1003 }
1004 if (debug) {
1005 Slog.v(TAG, "Next matching activity: found current " + r.packageName
1006 + "/" + r.info.name);
1007 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
1008 ? "null" : aInfo.packageName + "/" + aInfo.name));
1009 }
1010 break;
1011 }
1012 }
1013 } catch (RemoteException e) {
1014 }
1015
1016 if (aInfo == null) {
1017 // Nobody who is next!
1018 SafeActivityOptions.abort(options);
1019 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
1020 return false;
1021 }
1022
1023 intent.setComponent(new ComponentName(
1024 aInfo.applicationInfo.packageName, aInfo.name));
1025 intent.setFlags(intent.getFlags()&~(
1026 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
1027 Intent.FLAG_ACTIVITY_CLEAR_TOP|
1028 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
1029 FLAG_ACTIVITY_NEW_TASK));
1030
1031 // Okay now we need to start the new activity, replacing the currently running activity.
1032 // This is a little tricky because we want to start the new one as if the current one is
1033 // finished, but not finish the current one first so that there is no flicker.
1034 // And thus...
1035 final boolean wasFinishing = r.finishing;
1036 r.finishing = true;
1037
1038 // Propagate reply information over to the new activity.
1039 final ActivityRecord resultTo = r.resultTo;
1040 final String resultWho = r.resultWho;
1041 final int requestCode = r.requestCode;
1042 r.resultTo = null;
1043 if (resultTo != null) {
1044 resultTo.removeResultsLocked(r, resultWho, requestCode);
1045 }
1046
1047 final long origId = Binder.clearCallingIdentity();
1048 // TODO(b/64750076): Check if calling pid should really be -1.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001049 final int res = getActivityStartController()
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001050 .obtainStarter(intent, "startNextMatchingActivity")
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001051 .setCaller(r.app.getThread())
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001052 .setResolvedType(r.resolvedType)
1053 .setActivityInfo(aInfo)
1054 .setResultTo(resultTo != null ? resultTo.appToken : null)
1055 .setResultWho(resultWho)
1056 .setRequestCode(requestCode)
1057 .setCallingPid(-1)
1058 .setCallingUid(r.launchedFromUid)
1059 .setCallingPackage(r.launchedFromPackage)
1060 .setRealCallingPid(-1)
1061 .setRealCallingUid(r.launchedFromUid)
1062 .setActivityOptions(options)
1063 .execute();
1064 Binder.restoreCallingIdentity(origId);
1065
1066 r.finishing = wasFinishing;
1067 if (res != ActivityManager.START_SUCCESS) {
1068 return false;
1069 }
1070 return true;
1071 }
1072 }
1073
1074 @Override
1075 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
1076 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1077 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
1078 final WaitResult res = new WaitResult();
1079 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001080 enforceNotIsolatedCaller("startActivityAndWait");
1081 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
1082 userId, "startActivityAndWait");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001083 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001084 getActivityStartController().obtainStarter(intent, "startActivityAndWait")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001085 .setCaller(caller)
1086 .setCallingPackage(callingPackage)
1087 .setResolvedType(resolvedType)
1088 .setResultTo(resultTo)
1089 .setResultWho(resultWho)
1090 .setRequestCode(requestCode)
1091 .setStartFlags(startFlags)
1092 .setActivityOptions(bOptions)
1093 .setMayWait(userId)
1094 .setProfilerInfo(profilerInfo)
1095 .setWaitResult(res)
1096 .execute();
1097 }
1098 return res;
1099 }
1100
1101 @Override
1102 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
1103 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1104 int startFlags, Configuration config, Bundle bOptions, int userId) {
1105 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001106 enforceNotIsolatedCaller("startActivityWithConfig");
1107 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
1108 "startActivityWithConfig");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001109 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001110 return getActivityStartController().obtainStarter(intent, "startActivityWithConfig")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001111 .setCaller(caller)
1112 .setCallingPackage(callingPackage)
1113 .setResolvedType(resolvedType)
1114 .setResultTo(resultTo)
1115 .setResultWho(resultWho)
1116 .setRequestCode(requestCode)
1117 .setStartFlags(startFlags)
1118 .setGlobalConfiguration(config)
1119 .setActivityOptions(bOptions)
1120 .setMayWait(userId)
1121 .execute();
1122 }
1123 }
1124
1125 @Override
1126 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
1127 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1128 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
1129 int userId) {
1130
1131 // This is very dangerous -- it allows you to perform a start activity (including
1132 // permission grants) as any app that may launch one of your own activities. So
1133 // we will only allow this to be done from activities that are part of the core framework,
1134 // and then only when they are running as the system.
1135 final ActivityRecord sourceRecord;
1136 final int targetUid;
1137 final String targetPackage;
1138 final boolean isResolver;
1139 synchronized (mGlobalLock) {
1140 if (resultTo == null) {
1141 throw new SecurityException("Must be called from an activity");
1142 }
1143 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
1144 if (sourceRecord == null) {
1145 throw new SecurityException("Called with bad activity token: " + resultTo);
1146 }
1147 if (!sourceRecord.info.packageName.equals("android")) {
1148 throw new SecurityException(
1149 "Must be called from an activity that is declared in the android package");
1150 }
1151 if (sourceRecord.app == null) {
1152 throw new SecurityException("Called without a process attached to activity");
1153 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001154 if (UserHandle.getAppId(sourceRecord.app.mUid) != SYSTEM_UID) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001155 // This is still okay, as long as this activity is running under the
1156 // uid of the original calling activity.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001157 if (sourceRecord.app.mUid != sourceRecord.launchedFromUid) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001158 throw new SecurityException(
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001159 "Calling activity in uid " + sourceRecord.app.mUid
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001160 + " must be system uid or original calling uid "
1161 + sourceRecord.launchedFromUid);
1162 }
1163 }
1164 if (ignoreTargetSecurity) {
1165 if (intent.getComponent() == null) {
1166 throw new SecurityException(
1167 "Component must be specified with ignoreTargetSecurity");
1168 }
1169 if (intent.getSelector() != null) {
1170 throw new SecurityException(
1171 "Selector not allowed with ignoreTargetSecurity");
1172 }
1173 }
1174 targetUid = sourceRecord.launchedFromUid;
1175 targetPackage = sourceRecord.launchedFromPackage;
1176 isResolver = sourceRecord.isResolverOrChildActivity();
1177 }
1178
1179 if (userId == UserHandle.USER_NULL) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001180 userId = UserHandle.getUserId(sourceRecord.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001181 }
1182
1183 // TODO: Switch to user app stacks here.
1184 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001185 return getActivityStartController().obtainStarter(intent, "startActivityAsCaller")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001186 .setCallingUid(targetUid)
1187 .setCallingPackage(targetPackage)
1188 .setResolvedType(resolvedType)
1189 .setResultTo(resultTo)
1190 .setResultWho(resultWho)
1191 .setRequestCode(requestCode)
1192 .setStartFlags(startFlags)
1193 .setActivityOptions(bOptions)
1194 .setMayWait(userId)
1195 .setIgnoreTargetSecurity(ignoreTargetSecurity)
1196 .setFilterCallingUid(isResolver ? 0 /* system */ : targetUid)
1197 .execute();
1198 } catch (SecurityException e) {
1199 // XXX need to figure out how to propagate to original app.
1200 // A SecurityException here is generally actually a fault of the original
1201 // calling activity (such as a fairly granting permissions), so propagate it
1202 // back to them.
1203 /*
1204 StringBuilder msg = new StringBuilder();
1205 msg.append("While launching");
1206 msg.append(intent.toString());
1207 msg.append(": ");
1208 msg.append(e.getMessage());
1209 */
1210 throw e;
1211 }
1212 }
1213
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001214 int handleIncomingUser(int callingPid, int callingUid, int userId, String name) {
1215 return mAmInternal.handleIncomingUser(callingPid, callingUid, userId, false /* allowAll */,
1216 ALLOW_FULL_ONLY, name, null /* callerPackage */);
1217 }
1218
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001219 @Override
1220 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
1221 Intent intent, String resolvedType, IVoiceInteractionSession session,
1222 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
1223 Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001224 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001225 if (session == null || interactor == null) {
1226 throw new NullPointerException("null session or interactor");
1227 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001228 userId = handleIncomingUser(callingPid, callingUid, userId, "startVoiceActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001229 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001230 return getActivityStartController().obtainStarter(intent, "startVoiceActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001231 .setCallingUid(callingUid)
1232 .setCallingPackage(callingPackage)
1233 .setResolvedType(resolvedType)
1234 .setVoiceSession(session)
1235 .setVoiceInteractor(interactor)
1236 .setStartFlags(startFlags)
1237 .setProfilerInfo(profilerInfo)
1238 .setActivityOptions(bOptions)
1239 .setMayWait(userId)
1240 .execute();
1241 }
1242
1243 @Override
1244 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
1245 Intent intent, String resolvedType, Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001246 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
1247 userId = handleIncomingUser(callingPid, callingUid, userId, "startAssistantActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001248
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001249 return getActivityStartController().obtainStarter(intent, "startAssistantActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001250 .setCallingUid(callingUid)
1251 .setCallingPackage(callingPackage)
1252 .setResolvedType(resolvedType)
1253 .setActivityOptions(bOptions)
1254 .setMayWait(userId)
1255 .execute();
1256 }
1257
1258 @Override
1259 public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
1260 IRecentsAnimationRunner recentsAnimationRunner) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001261 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001262 final int callingPid = Binder.getCallingPid();
1263 final long origId = Binder.clearCallingIdentity();
1264 try {
1265 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07001266 final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
1267 final int recentsUid = mRecentTasks.getRecentsComponentUid();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001268
1269 // Start a new recents animation
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001270 final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
1271 getActivityStartController(), mWindowManager, callingPid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001272 anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
1273 recentsUid, assistDataReceiver);
1274 }
1275 } finally {
1276 Binder.restoreCallingIdentity(origId);
1277 }
1278 }
1279
1280 @Override
1281 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001282 enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001283 "startActivityFromRecents()");
1284
1285 final int callingPid = Binder.getCallingPid();
1286 final int callingUid = Binder.getCallingUid();
1287 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(bOptions);
1288 final long origId = Binder.clearCallingIdentity();
1289 try {
1290 synchronized (mGlobalLock) {
1291 return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
1292 safeOptions);
1293 }
1294 } finally {
1295 Binder.restoreCallingIdentity(origId);
1296 }
1297 }
1298
1299 /**
1300 * This is the internal entry point for handling Activity.finish().
1301 *
1302 * @param token The Binder token referencing the Activity we want to finish.
1303 * @param resultCode Result code, if any, from this Activity.
1304 * @param resultData Result data (Intent), if any, from this Activity.
1305 * @param finishTask Whether to finish the task associated with this Activity.
1306 *
1307 * @return Returns true if the activity successfully finished, or false if it is still running.
1308 */
1309 @Override
1310 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
1311 int finishTask) {
1312 // Refuse possible leaked file descriptors
1313 if (resultData != null && resultData.hasFileDescriptors()) {
1314 throw new IllegalArgumentException("File descriptors passed in Intent");
1315 }
1316
1317 synchronized (mGlobalLock) {
1318 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1319 if (r == null) {
1320 return true;
1321 }
1322 // Keep track of the root activity of the task before we finish it
1323 TaskRecord tr = r.getTask();
1324 ActivityRecord rootR = tr.getRootActivity();
1325 if (rootR == null) {
1326 Slog.w(TAG, "Finishing task with all activities already finished");
1327 }
1328 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
1329 // finish.
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001330 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001331 return false;
1332 }
1333
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001334 // TODO: There is a dup. of this block of code in ActivityStack.navigateUpToLocked
1335 // We should consolidate.
1336 if (mController != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001337 // Find the first activity that is not finishing.
1338 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
1339 if (next != null) {
1340 // ask watcher if this is allowed
1341 boolean resumeOK = true;
1342 try {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001343 resumeOK = mController.activityResuming(next.packageName);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001344 } catch (RemoteException e) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001345 mController = null;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001346 Watchdog.getInstance().setActivityController(null);
1347 }
1348
1349 if (!resumeOK) {
1350 Slog.i(TAG, "Not finishing activity because controller resumed");
1351 return false;
1352 }
1353 }
1354 }
1355 final long origId = Binder.clearCallingIdentity();
1356 try {
1357 boolean res;
1358 final boolean finishWithRootActivity =
1359 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
1360 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
1361 || (finishWithRootActivity && r == rootR)) {
1362 // If requested, remove the task that is associated to this activity only if it
1363 // was the root activity in the task. The result code and data is ignored
1364 // because we don't support returning them across task boundaries. Also, to
1365 // keep backwards compatibility we remove the task from recents when finishing
1366 // task with root activity.
1367 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
1368 finishWithRootActivity, "finish-activity");
1369 if (!res) {
1370 Slog.i(TAG, "Removing task failed to finish activity");
1371 }
Garfield Tan2746ab52018-07-25 12:33:01 -07001372 // Explicitly dismissing the activity so reset its relaunch flag.
Wale Ogunwale64258362018-10-16 15:13:37 -07001373 r.mRelaunchReason = RELAUNCH_REASON_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001374 } else {
1375 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
1376 resultData, "app-request", true);
1377 if (!res) {
1378 Slog.i(TAG, "Failed to finish by app-request");
1379 }
1380 }
1381 return res;
1382 } finally {
1383 Binder.restoreCallingIdentity(origId);
1384 }
1385 }
1386 }
1387
1388 @Override
1389 public boolean finishActivityAffinity(IBinder token) {
1390 synchronized (mGlobalLock) {
1391 final long origId = Binder.clearCallingIdentity();
1392 try {
1393 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1394 if (r == null) {
1395 return false;
1396 }
1397
1398 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
1399 // can finish.
1400 final TaskRecord task = r.getTask();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001401 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001402 return false;
1403 }
1404 return task.getStack().finishActivityAffinityLocked(r);
1405 } finally {
1406 Binder.restoreCallingIdentity(origId);
1407 }
1408 }
1409 }
1410
1411 @Override
1412 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
1413 final long origId = Binder.clearCallingIdentity();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001414 try {
1415 WindowProcessController proc = null;
1416 synchronized (mGlobalLock) {
1417 ActivityStack stack = ActivityRecord.getStackLocked(token);
1418 if (stack == null) {
1419 return;
1420 }
1421 final ActivityRecord r = mStackSupervisor.activityIdleInternalLocked(token,
1422 false /* fromTimeout */, false /* processPausingActivities */, config);
1423 if (r != null) {
1424 proc = r.app;
1425 }
1426 if (stopProfiling && proc != null) {
1427 proc.clearProfilerIfNeeded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001428 }
1429 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001430 } finally {
1431 Binder.restoreCallingIdentity(origId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001432 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001433 }
1434
1435 @Override
1436 public final void activityResumed(IBinder token) {
1437 final long origId = Binder.clearCallingIdentity();
1438 synchronized (mGlobalLock) {
1439 ActivityRecord.activityResumedLocked(token);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001440 mWindowManager.notifyAppResumedFinished(token);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001441 }
1442 Binder.restoreCallingIdentity(origId);
1443 }
1444
1445 @Override
1446 public final void activityPaused(IBinder token) {
1447 final long origId = Binder.clearCallingIdentity();
1448 synchronized (mGlobalLock) {
1449 ActivityStack stack = ActivityRecord.getStackLocked(token);
1450 if (stack != null) {
1451 stack.activityPausedLocked(token, false);
1452 }
1453 }
1454 Binder.restoreCallingIdentity(origId);
1455 }
1456
1457 @Override
1458 public final void activityStopped(IBinder token, Bundle icicle,
1459 PersistableBundle persistentState, CharSequence description) {
1460 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
1461
1462 // Refuse possible leaked file descriptors
1463 if (icicle != null && icicle.hasFileDescriptors()) {
1464 throw new IllegalArgumentException("File descriptors passed in Bundle");
1465 }
1466
1467 final long origId = Binder.clearCallingIdentity();
1468
1469 synchronized (mGlobalLock) {
1470 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1471 if (r != null) {
1472 r.activityStoppedLocked(icicle, persistentState, description);
1473 }
1474 }
1475
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001476 mAmInternal.trimApplications();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001477
1478 Binder.restoreCallingIdentity(origId);
1479 }
1480
1481 @Override
1482 public final void activityDestroyed(IBinder token) {
1483 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
1484 synchronized (mGlobalLock) {
1485 ActivityStack stack = ActivityRecord.getStackLocked(token);
1486 if (stack != null) {
1487 stack.activityDestroyedLocked(token, "activityDestroyed");
1488 }
1489 }
1490 }
1491
1492 @Override
1493 public final void activityRelaunched(IBinder token) {
1494 final long origId = Binder.clearCallingIdentity();
1495 synchronized (mGlobalLock) {
1496 mStackSupervisor.activityRelaunchedLocked(token);
1497 }
1498 Binder.restoreCallingIdentity(origId);
1499 }
1500
1501 public final void activitySlept(IBinder token) {
1502 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
1503
1504 final long origId = Binder.clearCallingIdentity();
1505
1506 synchronized (mGlobalLock) {
1507 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1508 if (r != null) {
1509 mStackSupervisor.activitySleptLocked(r);
1510 }
1511 }
1512
1513 Binder.restoreCallingIdentity(origId);
1514 }
1515
1516 @Override
1517 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
1518 synchronized (mGlobalLock) {
1519 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1520 if (r == null) {
1521 return;
1522 }
1523 final long origId = Binder.clearCallingIdentity();
1524 try {
1525 r.setRequestedOrientation(requestedOrientation);
1526 } finally {
1527 Binder.restoreCallingIdentity(origId);
1528 }
1529 }
1530 }
1531
1532 @Override
1533 public int getRequestedOrientation(IBinder token) {
1534 synchronized (mGlobalLock) {
1535 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1536 if (r == null) {
1537 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
1538 }
1539 return r.getRequestedOrientation();
1540 }
1541 }
1542
1543 @Override
1544 public void setImmersive(IBinder token, boolean immersive) {
1545 synchronized (mGlobalLock) {
1546 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1547 if (r == null) {
1548 throw new IllegalArgumentException();
1549 }
1550 r.immersive = immersive;
1551
1552 // update associated state if we're frontmost
Andrii Kulian52d255c2018-07-13 11:32:19 -07001553 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001554 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001555 applyUpdateLockStateLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001556 }
1557 }
1558 }
1559
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001560 void applyUpdateLockStateLocked(ActivityRecord r) {
1561 // Modifications to the UpdateLock state are done on our handler, outside
1562 // the activity manager's locks. The new state is determined based on the
1563 // state *now* of the relevant activity record. The object is passed to
1564 // the handler solely for logging detail, not to be consulted/modified.
1565 final boolean nextState = r != null && r.immersive;
1566 mH.post(() -> {
1567 if (mUpdateLock.isHeld() != nextState) {
1568 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1569 "Applying new update lock state '" + nextState + "' for " + r);
1570 if (nextState) {
1571 mUpdateLock.acquire();
1572 } else {
1573 mUpdateLock.release();
1574 }
1575 }
1576 });
1577 }
1578
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001579 @Override
1580 public boolean isImmersive(IBinder token) {
1581 synchronized (mGlobalLock) {
1582 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1583 if (r == null) {
1584 throw new IllegalArgumentException();
1585 }
1586 return r.immersive;
1587 }
1588 }
1589
1590 @Override
1591 public boolean isTopActivityImmersive() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001592 enforceNotIsolatedCaller("isTopActivityImmersive");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001593 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001594 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001595 return (r != null) ? r.immersive : false;
1596 }
1597 }
1598
1599 @Override
1600 public void overridePendingTransition(IBinder token, String packageName,
1601 int enterAnim, int exitAnim) {
1602 synchronized (mGlobalLock) {
1603 ActivityRecord self = ActivityRecord.isInStackLocked(token);
1604 if (self == null) {
1605 return;
1606 }
1607
1608 final long origId = Binder.clearCallingIdentity();
1609
1610 if (self.isState(
1611 ActivityStack.ActivityState.RESUMED, ActivityStack.ActivityState.PAUSING)) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001612 mWindowManager.overridePendingAppTransition(packageName,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001613 enterAnim, exitAnim, null);
1614 }
1615
1616 Binder.restoreCallingIdentity(origId);
1617 }
1618 }
1619
1620 @Override
1621 public int getFrontActivityScreenCompatMode() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001622 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001623 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001624 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001625 if (r == null) {
1626 return ActivityManager.COMPAT_MODE_UNKNOWN;
1627 }
Wale Ogunwale53783742018-09-16 10:21:51 -07001628 return mCompatModePackages.computeCompatModeLocked(r.info.applicationInfo);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001629 }
1630 }
1631
1632 @Override
1633 public void setFrontActivityScreenCompatMode(int mode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001634 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001635 "setFrontActivityScreenCompatMode");
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001636 ApplicationInfo ai;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001637 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001638 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001639 if (r == null) {
1640 Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity");
1641 return;
1642 }
1643 ai = r.info.applicationInfo;
Wale Ogunwale53783742018-09-16 10:21:51 -07001644 mCompatModePackages.setPackageScreenCompatModeLocked(ai, mode);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001645 }
1646 }
1647
1648 @Override
1649 public int getLaunchedFromUid(IBinder activityToken) {
1650 ActivityRecord srec;
1651 synchronized (mGlobalLock) {
1652 srec = ActivityRecord.forTokenLocked(activityToken);
1653 }
1654 if (srec == null) {
1655 return -1;
1656 }
1657 return srec.launchedFromUid;
1658 }
1659
1660 @Override
1661 public String getLaunchedFromPackage(IBinder activityToken) {
1662 ActivityRecord srec;
1663 synchronized (mGlobalLock) {
1664 srec = ActivityRecord.forTokenLocked(activityToken);
1665 }
1666 if (srec == null) {
1667 return null;
1668 }
1669 return srec.launchedFromPackage;
1670 }
1671
1672 @Override
1673 public boolean convertFromTranslucent(IBinder token) {
1674 final long origId = Binder.clearCallingIdentity();
1675 try {
1676 synchronized (mGlobalLock) {
1677 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1678 if (r == null) {
1679 return false;
1680 }
1681 final boolean translucentChanged = r.changeWindowTranslucency(true);
1682 if (translucentChanged) {
1683 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
1684 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001685 mWindowManager.setAppFullscreen(token, true);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001686 return translucentChanged;
1687 }
1688 } finally {
1689 Binder.restoreCallingIdentity(origId);
1690 }
1691 }
1692
1693 @Override
1694 public boolean convertToTranslucent(IBinder token, Bundle options) {
1695 SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
1696 final long origId = Binder.clearCallingIdentity();
1697 try {
1698 synchronized (mGlobalLock) {
1699 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1700 if (r == null) {
1701 return false;
1702 }
1703 final TaskRecord task = r.getTask();
1704 int index = task.mActivities.lastIndexOf(r);
1705 if (index > 0) {
1706 ActivityRecord under = task.mActivities.get(index - 1);
1707 under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
1708 }
1709 final boolean translucentChanged = r.changeWindowTranslucency(false);
1710 if (translucentChanged) {
1711 r.getStack().convertActivityToTranslucent(r);
1712 }
1713 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001714 mWindowManager.setAppFullscreen(token, false);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001715 return translucentChanged;
1716 }
1717 } finally {
1718 Binder.restoreCallingIdentity(origId);
1719 }
1720 }
1721
1722 @Override
1723 public void notifyActivityDrawn(IBinder token) {
1724 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
1725 synchronized (mGlobalLock) {
1726 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
1727 if (r != null) {
1728 r.getStack().notifyActivityDrawnLocked(r);
1729 }
1730 }
1731 }
1732
1733 @Override
1734 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
1735 synchronized (mGlobalLock) {
1736 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1737 if (r == null) {
1738 return;
1739 }
1740 r.reportFullyDrawnLocked(restoredFromBundle);
1741 }
1742 }
1743
1744 @Override
1745 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
1746 synchronized (mGlobalLock) {
1747 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
1748 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
1749 return stack.mDisplayId;
1750 }
1751 return DEFAULT_DISPLAY;
1752 }
1753 }
1754
1755 @Override
1756 public ActivityManager.StackInfo getFocusedStackInfo() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001757 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001758 long ident = Binder.clearCallingIdentity();
1759 try {
1760 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001761 ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001762 if (focusedStack != null) {
1763 return mStackSupervisor.getStackInfo(focusedStack.mStackId);
1764 }
1765 return null;
1766 }
1767 } finally {
1768 Binder.restoreCallingIdentity(ident);
1769 }
1770 }
1771
1772 @Override
1773 public void setFocusedStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001774 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001775 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
1776 final long callingId = Binder.clearCallingIdentity();
1777 try {
1778 synchronized (mGlobalLock) {
1779 final ActivityStack stack = mStackSupervisor.getStack(stackId);
1780 if (stack == null) {
1781 Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
1782 return;
1783 }
1784 final ActivityRecord r = stack.topRunningActivityLocked();
Louis Chang19443452018-10-09 12:10:21 +08001785 if (r != null && r.moveFocusableActivityToTop("setFocusedStack")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08001786 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001787 }
1788 }
1789 } finally {
1790 Binder.restoreCallingIdentity(callingId);
1791 }
1792 }
1793
1794 @Override
1795 public void setFocusedTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001796 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001797 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
1798 final long callingId = Binder.clearCallingIdentity();
1799 try {
1800 synchronized (mGlobalLock) {
1801 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1802 if (task == null) {
1803 return;
1804 }
1805 final ActivityRecord r = task.topRunningActivityLocked();
Louis Chang19443452018-10-09 12:10:21 +08001806 if (r != null && r.moveFocusableActivityToTop("setFocusedTask")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08001807 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001808 }
1809 }
1810 } finally {
1811 Binder.restoreCallingIdentity(callingId);
1812 }
1813 }
1814
1815 @Override
1816 public boolean removeTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001817 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001818 synchronized (mGlobalLock) {
1819 final long ident = Binder.clearCallingIdentity();
1820 try {
1821 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
1822 "remove-task");
1823 } finally {
1824 Binder.restoreCallingIdentity(ident);
1825 }
1826 }
1827 }
1828
1829 @Override
Winson Chunge6439102018-07-30 15:48:01 -07001830 public void removeAllVisibleRecentTasks() {
1831 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeAllVisibleRecentTasks()");
1832 synchronized (mGlobalLock) {
1833 final long ident = Binder.clearCallingIdentity();
1834 try {
1835 getRecentTasks().removeAllVisibleTasks();
1836 } finally {
1837 Binder.restoreCallingIdentity(ident);
1838 }
1839 }
1840 }
1841
1842 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001843 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
1844 synchronized (mGlobalLock) {
1845 final ActivityRecord srec = ActivityRecord.forTokenLocked(token);
1846 if (srec != null) {
1847 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
1848 }
1849 }
1850 return false;
1851 }
1852
1853 @Override
1854 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
1855 Intent resultData) {
1856
1857 synchronized (mGlobalLock) {
1858 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
1859 if (r != null) {
1860 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
1861 }
1862 return false;
1863 }
1864 }
1865
1866 /**
1867 * Attempts to move a task backwards in z-order (the order of activities within the task is
1868 * unchanged).
1869 *
1870 * There are several possible results of this call:
1871 * - if the task is locked, then we will show the lock toast
1872 * - if there is a task behind the provided task, then that task is made visible and resumed as
1873 * this task is moved to the back
1874 * - otherwise, if there are no other tasks in the stack:
1875 * - if this task is in the pinned stack, then we remove the stack completely, which will
1876 * have the effect of moving the task to the top or bottom of the fullscreen stack
1877 * (depending on whether it is visible)
1878 * - otherwise, we simply return home and hide this task
1879 *
1880 * @param token A reference to the activity we wish to move
1881 * @param nonRoot If false then this only works if the activity is the root
1882 * of a task; if true it will work for any activity in a task.
1883 * @return Returns true if the move completed, false if not.
1884 */
1885 @Override
1886 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001887 enforceNotIsolatedCaller("moveActivityTaskToBack");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001888 synchronized (mGlobalLock) {
1889 final long origId = Binder.clearCallingIdentity();
1890 try {
1891 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
1892 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1893 if (task != null) {
1894 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
1895 }
1896 } finally {
1897 Binder.restoreCallingIdentity(origId);
1898 }
1899 }
1900 return false;
1901 }
1902
1903 @Override
1904 public Rect getTaskBounds(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001905 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001906 long ident = Binder.clearCallingIdentity();
1907 Rect rect = new Rect();
1908 try {
1909 synchronized (mGlobalLock) {
1910 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
1911 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1912 if (task == null) {
1913 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
1914 return rect;
1915 }
1916 if (task.getStack() != null) {
1917 // Return the bounds from window manager since it will be adjusted for various
1918 // things like the presense of a docked stack for tasks that aren't resizeable.
1919 task.getWindowContainerBounds(rect);
1920 } else {
1921 // Task isn't in window manager yet since it isn't associated with a stack.
1922 // Return the persist value from activity manager
1923 if (!task.matchParentBounds()) {
1924 rect.set(task.getBounds());
1925 } else if (task.mLastNonFullscreenBounds != null) {
1926 rect.set(task.mLastNonFullscreenBounds);
1927 }
1928 }
1929 }
1930 } finally {
1931 Binder.restoreCallingIdentity(ident);
1932 }
1933 return rect;
1934 }
1935
1936 @Override
1937 public ActivityManager.TaskDescription getTaskDescription(int id) {
1938 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001939 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001940 MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
1941 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
1942 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1943 if (tr != null) {
1944 return tr.lastTaskDescription;
1945 }
1946 }
1947 return null;
1948 }
1949
1950 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001951 public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
1952 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
1953 setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
1954 toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
1955 return;
1956 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001957 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001958 synchronized (mGlobalLock) {
1959 final long ident = Binder.clearCallingIdentity();
1960 try {
1961 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1962 if (task == null) {
1963 Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
1964 return;
1965 }
1966
1967 if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
1968 + " to windowingMode=" + windowingMode + " toTop=" + toTop);
1969
1970 if (!task.isActivityTypeStandardOrUndefined()) {
1971 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
1972 + " non-standard task " + taskId + " to windowing mode="
1973 + windowingMode);
1974 }
1975
1976 final ActivityStack stack = task.getStack();
1977 if (toTop) {
1978 stack.moveToFront("setTaskWindowingMode", task);
1979 }
1980 stack.setWindowingMode(windowingMode);
1981 } finally {
1982 Binder.restoreCallingIdentity(ident);
1983 }
1984 }
1985 }
1986
1987 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001988 public String getCallingPackage(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001989 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001990 ActivityRecord r = getCallingRecordLocked(token);
1991 return r != null ? r.info.packageName : null;
1992 }
1993 }
1994
1995 @Override
1996 public ComponentName getCallingActivity(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001997 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001998 ActivityRecord r = getCallingRecordLocked(token);
1999 return r != null ? r.intent.getComponent() : null;
2000 }
2001 }
2002
2003 private ActivityRecord getCallingRecordLocked(IBinder token) {
2004 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2005 if (r == null) {
2006 return null;
2007 }
2008 return r.resultTo;
2009 }
2010
2011 @Override
2012 public void unhandledBack() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002013 mAmInternal.enforceCallingPermission(android.Manifest.permission.FORCE_BACK, "unhandledBack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002014
2015 synchronized (mGlobalLock) {
2016 final long origId = Binder.clearCallingIdentity();
2017 try {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002018 getTopDisplayFocusedStack().unhandledBackLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002019 } finally {
2020 Binder.restoreCallingIdentity(origId);
2021 }
2022 }
2023 }
2024
2025 /**
2026 * TODO: Add mController hook
2027 */
2028 @Override
2029 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002030 mAmInternal.enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002031
2032 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
2033 synchronized (mGlobalLock) {
2034 moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
2035 false /* fromRecents */);
2036 }
2037 }
2038
2039 void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
2040 boolean fromRecents) {
2041
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002042 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002043 Binder.getCallingUid(), -1, -1, "Task to front")) {
2044 SafeActivityOptions.abort(options);
2045 return;
2046 }
2047 final long origId = Binder.clearCallingIdentity();
2048 try {
2049 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2050 if (task == null) {
2051 Slog.d(TAG, "Could not find task for id: "+ taskId);
Winson Chungd0243682018-09-25 18:11:54 -07002052 SafeActivityOptions.abort(options);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002053 return;
2054 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002055 if (getLockTaskController().isLockTaskModeViolation(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002056 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
Winson Chungd0243682018-09-25 18:11:54 -07002057 SafeActivityOptions.abort(options);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002058 return;
2059 }
2060 ActivityOptions realOptions = options != null
2061 ? options.getOptions(mStackSupervisor)
2062 : null;
2063 mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
2064 false /* forceNonResizable */);
2065
2066 final ActivityRecord topActivity = task.getTopActivity();
2067 if (topActivity != null) {
2068
2069 // We are reshowing a task, use a starting window to hide the initial draw delay
2070 // so the transition can start earlier.
2071 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
2072 true /* taskSwitch */, fromRecents);
2073 }
2074 } finally {
2075 Binder.restoreCallingIdentity(origId);
2076 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002077 }
2078
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002079 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
2080 int callingPid, int callingUid, String name) {
2081 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
2082 return true;
2083 }
2084
2085 if (getRecentTasks().isCallerRecents(sourceUid)) {
2086 return true;
2087 }
2088
2089 int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
2090 if (perm == PackageManager.PERMISSION_GRANTED) {
2091 return true;
2092 }
2093 if (checkAllowAppSwitchUid(sourceUid)) {
2094 return true;
2095 }
2096
2097 // If the actual IPC caller is different from the logical source, then
2098 // also see if they are allowed to control app switches.
2099 if (callingUid != -1 && callingUid != sourceUid) {
2100 perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
2101 if (perm == PackageManager.PERMISSION_GRANTED) {
2102 return true;
2103 }
2104 if (checkAllowAppSwitchUid(callingUid)) {
2105 return true;
2106 }
2107 }
2108
2109 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
2110 return false;
2111 }
2112
2113 private boolean checkAllowAppSwitchUid(int uid) {
2114 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
2115 if (types != null) {
2116 for (int i = types.size() - 1; i >= 0; i--) {
2117 if (types.valueAt(i).intValue() == uid) {
2118 return true;
2119 }
2120 }
2121 }
2122 return false;
2123 }
2124
2125 @Override
2126 public void setActivityController(IActivityController controller, boolean imAMonkey) {
2127 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
2128 "setActivityController()");
2129 synchronized (mGlobalLock) {
2130 mController = controller;
2131 mControllerIsAMonkey = imAMonkey;
2132 Watchdog.getInstance().setActivityController(controller);
2133 }
2134 }
2135
2136 boolean isControllerAMonkey() {
2137 synchronized (mGlobalLock) {
2138 return mController != null && mControllerIsAMonkey;
2139 }
2140 }
2141
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002142 @Override
2143 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
2144 synchronized (mGlobalLock) {
2145 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
2146 }
2147 }
2148
2149 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002150 public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum) {
2151 return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
2152 }
2153
2154 @Override
2155 public List<ActivityManager.RunningTaskInfo> getFilteredTasks(int maxNum,
2156 @WindowConfiguration.ActivityType int ignoreActivityType,
2157 @WindowConfiguration.WindowingMode int ignoreWindowingMode) {
2158 final int callingUid = Binder.getCallingUid();
2159 ArrayList<ActivityManager.RunningTaskInfo> list = new ArrayList<>();
2160
2161 synchronized (mGlobalLock) {
2162 if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
2163
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002164 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002165 callingUid);
2166 mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
2167 ignoreWindowingMode, callingUid, allowed);
2168 }
2169
2170 return list;
2171 }
2172
2173 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002174 public final void finishSubActivity(IBinder token, String resultWho, int requestCode) {
2175 synchronized (mGlobalLock) {
2176 final long origId = Binder.clearCallingIdentity();
2177 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2178 if (r != null) {
2179 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
2180 }
2181 Binder.restoreCallingIdentity(origId);
2182 }
2183 }
2184
2185 @Override
2186 public boolean willActivityBeVisible(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002187 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002188 ActivityStack stack = ActivityRecord.getStackLocked(token);
2189 if (stack != null) {
2190 return stack.willActivityBeVisibleLocked(token);
2191 }
2192 return false;
2193 }
2194 }
2195
2196 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002197 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002198 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002199 synchronized (mGlobalLock) {
2200 final long ident = Binder.clearCallingIdentity();
2201 try {
2202 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2203 if (task == null) {
2204 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
2205 return;
2206 }
2207
2208 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
2209 + " to stackId=" + stackId + " toTop=" + toTop);
2210
2211 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2212 if (stack == null) {
2213 throw new IllegalStateException(
2214 "moveTaskToStack: No stack for stackId=" + stackId);
2215 }
2216 if (!stack.isActivityTypeStandardOrUndefined()) {
2217 throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
2218 + taskId + " to stack " + stackId);
2219 }
2220 if (stack.inSplitScreenPrimaryWindowingMode()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002221 mWindowManager.setDockedStackCreateState(
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002222 SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
2223 }
2224 task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
2225 "moveTaskToStack");
2226 } finally {
2227 Binder.restoreCallingIdentity(ident);
2228 }
2229 }
2230 }
2231
2232 @Override
2233 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
2234 boolean preserveWindows, boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002235 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002236
2237 final long ident = Binder.clearCallingIdentity();
2238 try {
2239 synchronized (mGlobalLock) {
2240 if (animate) {
2241 final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
2242 if (stack == null) {
2243 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2244 return;
2245 }
2246 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
2247 throw new IllegalArgumentException("Stack: " + stackId
2248 + " doesn't support animated resize.");
2249 }
2250 stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
2251 animationDuration, false /* fromFullscreen */);
2252 } else {
2253 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2254 if (stack == null) {
2255 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2256 return;
2257 }
2258 mStackSupervisor.resizeStackLocked(stack, destBounds,
2259 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
2260 preserveWindows, allowResizeInDockedMode, !DEFER_RESUME);
2261 }
2262 }
2263 } finally {
2264 Binder.restoreCallingIdentity(ident);
2265 }
2266 }
2267
2268 /**
2269 * Moves the specified task to the primary-split-screen stack.
2270 *
2271 * @param taskId Id of task to move.
2272 * @param createMode The mode the primary split screen stack should be created in if it doesn't
2273 * exist already. See
2274 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
2275 * and
2276 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
2277 * @param toTop If the task and stack should be moved to the top.
2278 * @param animate Whether we should play an animation for the moving the task.
2279 * @param initialBounds If the primary stack gets created, it will use these bounds for the
2280 * stack. Pass {@code null} to use default bounds.
2281 * @param showRecents If the recents activity should be shown on the other side of the task
2282 * going into split-screen mode.
2283 */
2284 @Override
2285 public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode,
2286 boolean toTop, boolean animate, Rect initialBounds, boolean showRecents) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002287 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002288 "setTaskWindowingModeSplitScreenPrimary()");
2289 synchronized (mGlobalLock) {
2290 final long ident = Binder.clearCallingIdentity();
2291 try {
2292 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2293 if (task == null) {
2294 Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
2295 return false;
2296 }
2297 if (DEBUG_STACK) Slog.d(TAG_STACK,
2298 "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
2299 + " to createMode=" + createMode + " toTop=" + toTop);
2300 if (!task.isActivityTypeStandardOrUndefined()) {
2301 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
2302 + " non-standard task " + taskId + " to split-screen windowing mode");
2303 }
2304
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002305 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002306 final int windowingMode = task.getWindowingMode();
2307 final ActivityStack stack = task.getStack();
2308 if (toTop) {
2309 stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
2310 }
2311 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
2312 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */);
2313 return windowingMode != task.getWindowingMode();
2314 } finally {
2315 Binder.restoreCallingIdentity(ident);
2316 }
2317 }
2318 }
2319
2320 /**
2321 * Removes stacks in the input windowing modes from the system if they are of activity type
2322 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
2323 */
2324 @Override
2325 public void removeStacksInWindowingModes(int[] windowingModes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002326 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002327 "removeStacksInWindowingModes()");
2328
2329 synchronized (mGlobalLock) {
2330 final long ident = Binder.clearCallingIdentity();
2331 try {
2332 mStackSupervisor.removeStacksInWindowingModes(windowingModes);
2333 } finally {
2334 Binder.restoreCallingIdentity(ident);
2335 }
2336 }
2337 }
2338
2339 @Override
2340 public void removeStacksWithActivityTypes(int[] activityTypes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002341 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002342 "removeStacksWithActivityTypes()");
2343
2344 synchronized (mGlobalLock) {
2345 final long ident = Binder.clearCallingIdentity();
2346 try {
2347 mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
2348 } finally {
2349 Binder.restoreCallingIdentity(ident);
2350 }
2351 }
2352 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002353
2354 @Override
2355 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
2356 int userId) {
2357 final int callingUid = Binder.getCallingUid();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002358 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, "getRecentTasks");
2359 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002360 callingUid);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002361 final boolean detailed = checkGetTasksPermission(
2362 android.Manifest.permission.GET_DETAILED_TASKS, Binder.getCallingPid(),
2363 UserHandle.getAppId(callingUid))
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002364 == PackageManager.PERMISSION_GRANTED;
2365
2366 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002367 return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002368 callingUid);
2369 }
2370 }
2371
2372 @Override
2373 public List<ActivityManager.StackInfo> getAllStackInfos() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002374 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002375 long ident = Binder.clearCallingIdentity();
2376 try {
2377 synchronized (mGlobalLock) {
2378 return mStackSupervisor.getAllStackInfosLocked();
2379 }
2380 } finally {
2381 Binder.restoreCallingIdentity(ident);
2382 }
2383 }
2384
2385 @Override
2386 public ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002387 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002388 long ident = Binder.clearCallingIdentity();
2389 try {
2390 synchronized (mGlobalLock) {
2391 return mStackSupervisor.getStackInfo(windowingMode, activityType);
2392 }
2393 } finally {
2394 Binder.restoreCallingIdentity(ident);
2395 }
2396 }
2397
2398 @Override
2399 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002400 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002401 final long callingUid = Binder.getCallingUid();
2402 final long origId = Binder.clearCallingIdentity();
2403 try {
2404 synchronized (mGlobalLock) {
2405 // Cancel the recents animation synchronously (do not hold the WM lock)
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002406 mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002407 ? REORDER_MOVE_TO_ORIGINAL_POSITION
2408 : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
2409 }
2410 } finally {
2411 Binder.restoreCallingIdentity(origId);
2412 }
2413 }
2414
2415 @Override
2416 public void startLockTaskModeByToken(IBinder token) {
2417 synchronized (mGlobalLock) {
2418 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2419 if (r == null) {
2420 return;
2421 }
2422 startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
2423 }
2424 }
2425
2426 @Override
2427 public void startSystemLockTaskMode(int taskId) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002428 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002429 // This makes inner call to look as if it was initiated by system.
2430 long ident = Binder.clearCallingIdentity();
2431 try {
2432 synchronized (mGlobalLock) {
2433 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2434
2435 // When starting lock task mode the stack must be in front and focused
2436 task.getStack().moveToFront("startSystemLockTaskMode");
2437 startLockTaskModeLocked(task, true /* isSystemCaller */);
2438 }
2439 } finally {
2440 Binder.restoreCallingIdentity(ident);
2441 }
2442 }
2443
2444 @Override
2445 public void stopLockTaskModeByToken(IBinder token) {
2446 synchronized (mGlobalLock) {
2447 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2448 if (r == null) {
2449 return;
2450 }
2451 stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
2452 }
2453 }
2454
2455 /**
2456 * This API should be called by SystemUI only when user perform certain action to dismiss
2457 * lock task mode. We should only dismiss pinned lock task mode in this case.
2458 */
2459 @Override
2460 public void stopSystemLockTaskMode() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002461 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002462 stopLockTaskModeInternal(null, true /* isSystemCaller */);
2463 }
2464
2465 private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
2466 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
2467 if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
2468 return;
2469 }
2470
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002471 final ActivityStack stack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002472 if (stack == null || task != stack.topTask()) {
2473 throw new IllegalArgumentException("Invalid task, not in foreground");
2474 }
2475
2476 // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
2477 // system or a specific app.
2478 // * System-initiated requests will only start the pinned mode (screen pinning)
2479 // * App-initiated requests
2480 // - will put the device in fully locked mode (LockTask), if the app is whitelisted
2481 // - will start the pinned mode, otherwise
2482 final int callingUid = Binder.getCallingUid();
2483 long ident = Binder.clearCallingIdentity();
2484 try {
2485 // When a task is locked, dismiss the pinned stack if it exists
2486 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2487
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002488 getLockTaskController().startLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002489 } finally {
2490 Binder.restoreCallingIdentity(ident);
2491 }
2492 }
2493
2494 private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
2495 final int callingUid = Binder.getCallingUid();
2496 long ident = Binder.clearCallingIdentity();
2497 try {
2498 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002499 getLockTaskController().stopLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002500 }
2501 // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
2502 // task and jumping straight into a call in the case of emergency call back.
2503 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
2504 if (tm != null) {
2505 tm.showInCallScreen(false);
2506 }
2507 } finally {
2508 Binder.restoreCallingIdentity(ident);
2509 }
2510 }
2511
2512 @Override
2513 public boolean isInLockTaskMode() {
2514 return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
2515 }
2516
2517 @Override
2518 public int getLockTaskModeState() {
2519 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002520 return getLockTaskController().getLockTaskModeState();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002521 }
2522 }
2523
2524 @Override
2525 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
2526 synchronized (mGlobalLock) {
2527 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2528 if (r != null) {
2529 r.setTaskDescription(td);
2530 final TaskRecord task = r.getTask();
2531 task.updateTaskDescription();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002532 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002533 }
2534 }
2535 }
2536
2537 @Override
2538 public Bundle getActivityOptions(IBinder token) {
2539 final long origId = Binder.clearCallingIdentity();
2540 try {
2541 synchronized (mGlobalLock) {
2542 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
2543 if (r != null) {
2544 final ActivityOptions activityOptions = r.takeOptionsLocked();
2545 return activityOptions == null ? null : activityOptions.toBundle();
2546 }
2547 return null;
2548 }
2549 } finally {
2550 Binder.restoreCallingIdentity(origId);
2551 }
2552 }
2553
2554 @Override
2555 public List<IBinder> getAppTasks(String callingPackage) {
2556 int callingUid = Binder.getCallingUid();
2557 long ident = Binder.clearCallingIdentity();
2558 try {
2559 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002560 return mRecentTasks.getAppTasksList(callingUid, callingPackage);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002561 }
2562 } finally {
2563 Binder.restoreCallingIdentity(ident);
2564 }
2565 }
2566
2567 @Override
2568 public void finishVoiceTask(IVoiceInteractionSession session) {
2569 synchronized (mGlobalLock) {
2570 final long origId = Binder.clearCallingIdentity();
2571 try {
2572 // TODO: VI Consider treating local voice interactions and voice tasks
2573 // differently here
2574 mStackSupervisor.finishVoiceTask(session);
2575 } finally {
2576 Binder.restoreCallingIdentity(origId);
2577 }
2578 }
2579
2580 }
2581
2582 @Override
2583 public boolean isTopOfTask(IBinder token) {
2584 synchronized (mGlobalLock) {
2585 ActivityRecord r = ActivityRecord.isInStackLocked(token);
Riddle Hsu66b74a82018-07-26 00:20:12 +08002586 return r != null && r.getTask().getTopActivity() == r;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002587 }
2588 }
2589
2590 @Override
2591 public void notifyLaunchTaskBehindComplete(IBinder token) {
2592 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
2593 }
2594
2595 @Override
2596 public void notifyEnterAnimationComplete(IBinder token) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002597 mH.post(() -> {
2598 synchronized (mGlobalLock) {
2599 ActivityRecord r = ActivityRecord.forTokenLocked(token);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002600 if (r != null && r.attachedToProcess()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002601 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002602 r.app.getThread().scheduleEnterAnimationComplete(r.appToken);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002603 } catch (RemoteException e) {
2604 }
2605 }
2606 }
2607
2608 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002609 }
2610
2611 /** Called from an app when assist data is ready. */
2612 @Override
2613 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
2614 AssistContent content, Uri referrer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002615 PendingAssistExtras pae = (PendingAssistExtras) token;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002616 synchronized (pae) {
2617 pae.result = extras;
2618 pae.structure = structure;
2619 pae.content = content;
2620 if (referrer != null) {
2621 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
2622 }
2623 if (structure != null) {
2624 structure.setHomeActivity(pae.isHome);
2625 }
2626 pae.haveResult = true;
2627 pae.notifyAll();
2628 if (pae.intent == null && pae.receiver == null) {
2629 // Caller is just waiting for the result.
2630 return;
2631 }
2632 }
2633 // We are now ready to launch the assist activity.
2634 IAssistDataReceiver sendReceiver = null;
2635 Bundle sendBundle = null;
2636 synchronized (mGlobalLock) {
2637 buildAssistBundleLocked(pae, extras);
2638 boolean exists = mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002639 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002640 if (!exists) {
2641 // Timed out.
2642 return;
2643 }
2644
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002645 if ((sendReceiver = pae.receiver) != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002646 // Caller wants result sent back to them.
2647 sendBundle = new Bundle();
2648 sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
2649 sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
2650 sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
2651 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
2652 }
2653 }
2654 if (sendReceiver != null) {
2655 try {
2656 sendReceiver.onHandleAssistData(sendBundle);
2657 } catch (RemoteException e) {
2658 }
2659 return;
2660 }
2661
2662 final long ident = Binder.clearCallingIdentity();
2663 try {
2664 if (TextUtils.equals(pae.intent.getAction(),
2665 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
2666 pae.intent.putExtras(pae.extras);
2667 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
2668 } else {
2669 pae.intent.replaceExtras(pae.extras);
2670 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
2671 | Intent.FLAG_ACTIVITY_SINGLE_TOP
2672 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Wale Ogunwale31913b52018-10-13 08:29:31 -07002673 mInternal.closeSystemDialogs("assist");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002674
2675 try {
2676 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
2677 } catch (ActivityNotFoundException e) {
2678 Slog.w(TAG, "No activity to handle assist action.", e);
2679 }
2680 }
2681 } finally {
2682 Binder.restoreCallingIdentity(ident);
2683 }
2684 }
2685
2686 @Override
2687 public int addAppTask(IBinder activityToken, Intent intent,
2688 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
2689 final int callingUid = Binder.getCallingUid();
2690 final long callingIdent = Binder.clearCallingIdentity();
2691
2692 try {
2693 synchronized (mGlobalLock) {
2694 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
2695 if (r == null) {
2696 throw new IllegalArgumentException("Activity does not exist; token="
2697 + activityToken);
2698 }
2699 ComponentName comp = intent.getComponent();
2700 if (comp == null) {
2701 throw new IllegalArgumentException("Intent " + intent
2702 + " must specify explicit component");
2703 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002704 if (thumbnail.getWidth() != mThumbnailWidth
2705 || thumbnail.getHeight() != mThumbnailHeight) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002706 throw new IllegalArgumentException("Bad thumbnail size: got "
2707 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002708 + mThumbnailWidth + "x" + mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002709 }
2710 if (intent.getSelector() != null) {
2711 intent.setSelector(null);
2712 }
2713 if (intent.getSourceBounds() != null) {
2714 intent.setSourceBounds(null);
2715 }
2716 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
2717 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
2718 // The caller has added this as an auto-remove task... that makes no
2719 // sense, so turn off auto-remove.
2720 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
2721 }
2722 }
2723 final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
2724 STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
2725 if (ainfo.applicationInfo.uid != callingUid) {
2726 throw new SecurityException(
2727 "Can't add task for another application: target uid="
2728 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
2729 }
2730
2731 final ActivityStack stack = r.getStack();
2732 final TaskRecord task = stack.createTaskRecord(
2733 mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent,
2734 null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002735 if (!mRecentTasks.addToBottom(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002736 // The app has too many tasks already and we can't add any more
2737 stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
2738 return INVALID_TASK_ID;
2739 }
2740 task.lastTaskDescription.copyFrom(description);
2741
2742 // TODO: Send the thumbnail to WM to store it.
2743
2744 return task.taskId;
2745 }
2746 } finally {
2747 Binder.restoreCallingIdentity(callingIdent);
2748 }
2749 }
2750
2751 @Override
2752 public Point getAppTaskThumbnailSize() {
2753 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002754 return new Point(mThumbnailWidth, mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002755 }
2756 }
2757
2758 @Override
2759 public void setTaskResizeable(int taskId, int resizeableMode) {
2760 synchronized (mGlobalLock) {
2761 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
2762 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
2763 if (task == null) {
2764 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
2765 return;
2766 }
2767 task.setResizeMode(resizeableMode);
2768 }
2769 }
2770
2771 @Override
2772 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002773 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002774 long ident = Binder.clearCallingIdentity();
2775 try {
2776 synchronized (mGlobalLock) {
2777 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2778 if (task == null) {
2779 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
2780 return;
2781 }
2782 // Place the task in the right stack if it isn't there already based on
2783 // the requested bounds.
2784 // The stack transition logic is:
2785 // - a null bounds on a freeform task moves that task to fullscreen
2786 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
2787 // that task to freeform
2788 // - otherwise the task is not moved
2789 ActivityStack stack = task.getStack();
2790 if (!task.getWindowConfiguration().canResizeTask()) {
2791 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
2792 }
2793 if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
2794 stack = stack.getDisplay().getOrCreateStack(
2795 WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
2796 } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
2797 stack = stack.getDisplay().getOrCreateStack(
2798 WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
2799 }
2800
2801 // Reparent the task to the right stack if necessary
2802 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
2803 if (stack != task.getStack()) {
2804 // Defer resume until the task is resized below
2805 task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
2806 DEFER_RESUME, "resizeTask");
2807 preserveWindow = false;
2808 }
2809
2810 // After reparenting (which only resizes the task to the stack bounds), resize the
2811 // task to the actual bounds provided
2812 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
2813 }
2814 } finally {
2815 Binder.restoreCallingIdentity(ident);
2816 }
2817 }
2818
2819 @Override
2820 public boolean releaseActivityInstance(IBinder token) {
2821 synchronized (mGlobalLock) {
2822 final long origId = Binder.clearCallingIdentity();
2823 try {
2824 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2825 if (r == null) {
2826 return false;
2827 }
2828 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
2829 } finally {
2830 Binder.restoreCallingIdentity(origId);
2831 }
2832 }
2833 }
2834
2835 @Override
2836 public void releaseSomeActivities(IApplicationThread appInt) {
2837 synchronized (mGlobalLock) {
2838 final long origId = Binder.clearCallingIdentity();
2839 try {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07002840 final WindowProcessController app = getProcessController(appInt);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002841 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
2842 } finally {
2843 Binder.restoreCallingIdentity(origId);
2844 }
2845 }
2846 }
2847
2848 @Override
2849 public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
2850 int secondaryDisplayShowing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002851 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002852 != PackageManager.PERMISSION_GRANTED) {
2853 throw new SecurityException("Requires permission "
2854 + android.Manifest.permission.DEVICE_POWER);
2855 }
2856
2857 synchronized (mGlobalLock) {
2858 long ident = Binder.clearCallingIdentity();
2859 if (mKeyguardShown != keyguardShowing) {
2860 mKeyguardShown = keyguardShowing;
Wale Ogunwale342fbe92018-10-09 08:44:10 -07002861 final Message msg = PooledLambda.obtainMessage(
2862 ActivityManagerInternal::reportCurKeyguardUsageEvent, mAmInternal,
2863 keyguardShowing);
2864 mH.sendMessage(msg);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002865 }
2866 try {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002867 mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002868 secondaryDisplayShowing);
2869 } finally {
2870 Binder.restoreCallingIdentity(ident);
2871 }
2872 }
2873
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002874 mH.post(() -> {
2875 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2876 mScreenObservers.get(i).onKeyguardStateChanged(keyguardShowing);
2877 }
2878 });
2879 }
2880
2881 void onScreenAwakeChanged(boolean isAwake) {
2882 mH.post(() -> {
2883 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2884 mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2885 }
2886 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002887 }
2888
2889 @Override
2890 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002891 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
2892 userId, "getTaskDescriptionIcon");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002893
2894 final File passedIconFile = new File(filePath);
2895 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
2896 passedIconFile.getName());
2897 if (!legitIconFile.getPath().equals(filePath)
2898 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
2899 throw new IllegalArgumentException("Bad file path: " + filePath
2900 + " passed for userId " + userId);
2901 }
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002902 return mRecentTasks.getTaskDescriptionIcon(filePath);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002903 }
2904
2905 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002906 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002907 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
2908 final ActivityOptions activityOptions = safeOptions != null
2909 ? safeOptions.getOptions(mStackSupervisor)
2910 : null;
2911 if (activityOptions == null
2912 || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
2913 || activityOptions.getCustomInPlaceResId() == 0) {
2914 throw new IllegalArgumentException("Expected in-place ActivityOption " +
2915 "with valid animation");
2916 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002917 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
2918 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002919 activityOptions.getCustomInPlaceResId());
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002920 mWindowManager.executeAppTransition();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002921 }
2922
2923 @Override
2924 public void removeStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002925 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002926 synchronized (mGlobalLock) {
2927 final long ident = Binder.clearCallingIdentity();
2928 try {
2929 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2930 if (stack == null) {
2931 Slog.w(TAG, "removeStack: No stack with id=" + stackId);
2932 return;
2933 }
2934 if (!stack.isActivityTypeStandardOrUndefined()) {
2935 throw new IllegalArgumentException(
2936 "Removing non-standard stack is not allowed.");
2937 }
2938 mStackSupervisor.removeStack(stack);
2939 } finally {
2940 Binder.restoreCallingIdentity(ident);
2941 }
2942 }
2943 }
2944
2945 @Override
2946 public void moveStackToDisplay(int stackId, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002947 mAmInternal.enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002948
2949 synchronized (mGlobalLock) {
2950 final long ident = Binder.clearCallingIdentity();
2951 try {
2952 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
2953 + " to displayId=" + displayId);
2954 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
2955 } finally {
2956 Binder.restoreCallingIdentity(ident);
2957 }
2958 }
2959 }
2960
2961 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002962 public void exitFreeformMode(IBinder token) {
2963 synchronized (mGlobalLock) {
2964 long ident = Binder.clearCallingIdentity();
2965 try {
2966 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2967 if (r == null) {
2968 throw new IllegalArgumentException(
2969 "exitFreeformMode: No activity record matching token=" + token);
2970 }
2971
2972 final ActivityStack stack = r.getStack();
2973 if (stack == null || !stack.inFreeformWindowingMode()) {
2974 throw new IllegalStateException(
2975 "exitFreeformMode: You can only go fullscreen from freeform.");
2976 }
2977
2978 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
2979 } finally {
2980 Binder.restoreCallingIdentity(ident);
2981 }
2982 }
2983 }
2984
2985 /** Sets the task stack listener that gets callbacks when a task stack changes. */
2986 @Override
2987 public void registerTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002988 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002989 "registerTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002990 mTaskChangeNotificationController.registerTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002991 }
2992
2993 /** Unregister a task stack listener so that it stops receiving callbacks. */
2994 @Override
2995 public void unregisterTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002996 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002997 "unregisterTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002998 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002999 }
3000
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003001 @Override
3002 public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
3003 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
3004 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
3005 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
3006 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
3007 }
3008
3009 @Override
3010 public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
3011 IBinder activityToken, int flags) {
3012 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
3013 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
3014 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
3015 }
3016
3017 @Override
3018 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
3019 Bundle args) {
3020 return enqueueAssistContext(requestType, intent, hint, null, null, null,
3021 true /* focused */, true /* newSessionId */, userHandle, args,
3022 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
3023 }
3024
3025 @Override
3026 public Bundle getAssistContextExtras(int requestType) {
3027 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
3028 null, null, true /* focused */, true /* newSessionId */,
3029 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
3030 if (pae == null) {
3031 return null;
3032 }
3033 synchronized (pae) {
3034 while (!pae.haveResult) {
3035 try {
3036 pae.wait();
3037 } catch (InterruptedException e) {
3038 }
3039 }
3040 }
3041 synchronized (mGlobalLock) {
3042 buildAssistBundleLocked(pae, pae.result);
3043 mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003044 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003045 }
3046 return pae.extras;
3047 }
3048
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003049 /**
3050 * Binder IPC calls go through the public entry point.
3051 * This can be called with or without the global lock held.
3052 */
3053 private static int checkCallingPermission(String permission) {
3054 return checkPermission(
3055 permission, Binder.getCallingPid(), UserHandle.getAppId(Binder.getCallingUid()));
3056 }
3057
3058 /** This can be called with or without the global lock held. */
Wale Ogunwale214f3482018-10-04 11:00:47 -07003059 private void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003060 if (!getRecentTasks().isCallerRecents(Binder.getCallingUid())) {
3061 mAmInternal.enforceCallingPermission(permission, func);
3062 }
3063 }
3064
3065 @VisibleForTesting
3066 int checkGetTasksPermission(String permission, int pid, int uid) {
3067 return checkPermission(permission, pid, uid);
3068 }
3069
3070 static int checkPermission(String permission, int pid, int uid) {
3071 if (permission == null) {
3072 return PackageManager.PERMISSION_DENIED;
3073 }
3074 return checkComponentPermission(permission, pid, uid, -1, true);
3075 }
3076
Wale Ogunwale214f3482018-10-04 11:00:47 -07003077 public static int checkComponentPermission(String permission, int pid, int uid,
3078 int owningUid, boolean exported) {
3079 return ActivityManagerService.checkComponentPermission(
3080 permission, pid, uid, owningUid, exported);
3081 }
3082
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003083 boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
3084 if (getRecentTasks().isCallerRecents(callingUid)) {
3085 // Always allow the recents component to get tasks
3086 return true;
3087 }
3088
3089 boolean allowed = checkGetTasksPermission(android.Manifest.permission.REAL_GET_TASKS,
3090 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
3091 if (!allowed) {
3092 if (checkGetTasksPermission(android.Manifest.permission.GET_TASKS,
3093 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
3094 // Temporary compatibility: some existing apps on the system image may
3095 // still be requesting the old permission and not switched to the new
3096 // one; if so, we'll still allow them full access. This means we need
3097 // to see if they are holding the old permission and are a system app.
3098 try {
3099 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
3100 allowed = true;
3101 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
3102 + " is using old GET_TASKS but privileged; allowing");
3103 }
3104 } catch (RemoteException e) {
3105 }
3106 }
3107 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
3108 + " does not hold REAL_GET_TASKS; limiting output");
3109 }
3110 return allowed;
3111 }
3112
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003113 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
3114 IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
3115 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
3116 int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003117 mAmInternal.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003118 "enqueueAssistContext()");
3119
3120 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003121 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003122 if (activity == null) {
3123 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
3124 return null;
3125 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003126 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003127 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
3128 return null;
3129 }
3130 if (focused) {
3131 if (activityToken != null) {
3132 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
3133 if (activity != caller) {
3134 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
3135 + " is not current top " + activity);
3136 return null;
3137 }
3138 }
3139 } else {
3140 activity = ActivityRecord.forTokenLocked(activityToken);
3141 if (activity == null) {
3142 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
3143 + " couldn't be found");
3144 return null;
3145 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003146 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003147 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
3148 return null;
3149 }
3150 }
3151
3152 PendingAssistExtras pae;
3153 Bundle extras = new Bundle();
3154 if (args != null) {
3155 extras.putAll(args);
3156 }
3157 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003158 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003159
3160 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
3161 userHandle);
3162 pae.isHome = activity.isActivityTypeHome();
3163
3164 // Increment the sessionId if necessary
3165 if (newSessionId) {
3166 mViSessionId++;
3167 }
3168 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003169 activity.app.getThread().requestAssistContextExtras(activity.appToken, pae,
3170 requestType, mViSessionId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003171 mPendingAssistExtras.add(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003172 mUiHandler.postDelayed(pae, timeout);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003173 } catch (RemoteException e) {
3174 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
3175 return null;
3176 }
3177 return pae;
3178 }
3179 }
3180
3181 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
3182 if (result != null) {
3183 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
3184 }
3185 if (pae.hint != null) {
3186 pae.extras.putBoolean(pae.hint, true);
3187 }
3188 }
3189
3190 private void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
3191 IAssistDataReceiver receiver;
3192 synchronized (mGlobalLock) {
3193 mPendingAssistExtras.remove(pae);
3194 receiver = pae.receiver;
3195 }
3196 if (receiver != null) {
3197 // Caller wants result sent back to them.
3198 Bundle sendBundle = new Bundle();
3199 // At least return the receiver extras
3200 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
3201 try {
3202 pae.receiver.onHandleAssistData(sendBundle);
3203 } catch (RemoteException e) {
3204 }
3205 }
3206 }
3207
3208 public class PendingAssistExtras extends Binder implements Runnable {
3209 public final ActivityRecord activity;
3210 public boolean isHome;
3211 public final Bundle extras;
3212 public final Intent intent;
3213 public final String hint;
3214 public final IAssistDataReceiver receiver;
3215 public final int userHandle;
3216 public boolean haveResult = false;
3217 public Bundle result = null;
3218 public AssistStructure structure = null;
3219 public AssistContent content = null;
3220 public Bundle receiverExtras;
3221
3222 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
3223 String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
3224 int _userHandle) {
3225 activity = _activity;
3226 extras = _extras;
3227 intent = _intent;
3228 hint = _hint;
3229 receiver = _receiver;
3230 receiverExtras = _receiverExtras;
3231 userHandle = _userHandle;
3232 }
3233
3234 @Override
3235 public void run() {
3236 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
3237 synchronized (this) {
3238 haveResult = true;
3239 notifyAll();
3240 }
3241 pendingAssistExtrasTimedOut(this);
3242 }
3243 }
3244
3245 @Override
3246 public boolean isAssistDataAllowedOnCurrentActivity() {
3247 int userId;
3248 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003249 final ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003250 if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
3251 return false;
3252 }
3253
3254 final ActivityRecord activity = focusedStack.getTopActivity();
3255 if (activity == null) {
3256 return false;
3257 }
3258 userId = activity.userId;
3259 }
3260 return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
3261 }
3262
3263 @Override
3264 public boolean showAssistFromActivity(IBinder token, Bundle args) {
3265 long ident = Binder.clearCallingIdentity();
3266 try {
3267 synchronized (mGlobalLock) {
3268 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003269 ActivityRecord top = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003270 if (top != caller) {
3271 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3272 + " is not current top " + top);
3273 return false;
3274 }
3275 if (!top.nowVisible) {
3276 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3277 + " is not visible");
3278 return false;
3279 }
3280 }
3281 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
3282 token);
3283 } finally {
3284 Binder.restoreCallingIdentity(ident);
3285 }
3286 }
3287
3288 @Override
3289 public boolean isRootVoiceInteraction(IBinder token) {
3290 synchronized (mGlobalLock) {
3291 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3292 if (r == null) {
3293 return false;
3294 }
3295 return r.rootVoiceInteraction;
3296 }
3297 }
3298
Wale Ogunwalef6733932018-06-27 05:14:34 -07003299 private void onLocalVoiceInteractionStartedLocked(IBinder activity,
3300 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
3301 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
3302 if (activityToCallback == null) return;
3303 activityToCallback.setVoiceSessionLocked(voiceSession);
3304
3305 // Inform the activity
3306 try {
3307 activityToCallback.app.getThread().scheduleLocalVoiceInteractionStarted(activity,
3308 voiceInteractor);
3309 long token = Binder.clearCallingIdentity();
3310 try {
3311 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
3312 } finally {
3313 Binder.restoreCallingIdentity(token);
3314 }
3315 // TODO: VI Should we cache the activity so that it's easier to find later
3316 // rather than scan through all the stacks and activities?
3317 } catch (RemoteException re) {
3318 activityToCallback.clearVoiceSessionLocked();
3319 // TODO: VI Should this terminate the voice session?
3320 }
3321 }
3322
3323 private void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
3324 Slog.d(TAG, "<<< startRunningVoiceLocked()");
3325 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
3326 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
3327 boolean wasRunningVoice = mRunningVoice != null;
3328 mRunningVoice = session;
3329 if (!wasRunningVoice) {
3330 mVoiceWakeLock.acquire();
3331 updateSleepIfNeededLocked();
3332 }
3333 }
3334 }
3335
3336 void finishRunningVoiceLocked() {
3337 if (mRunningVoice != null) {
3338 mRunningVoice = null;
3339 mVoiceWakeLock.release();
3340 updateSleepIfNeededLocked();
3341 }
3342 }
3343
3344 @Override
3345 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3346 synchronized (mGlobalLock) {
3347 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3348 if (keepAwake) {
3349 mVoiceWakeLock.acquire();
3350 } else {
3351 mVoiceWakeLock.release();
3352 }
3353 }
3354 }
3355 }
3356
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003357 @Override
3358 public ComponentName getActivityClassForToken(IBinder token) {
3359 synchronized (mGlobalLock) {
3360 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3361 if (r == null) {
3362 return null;
3363 }
3364 return r.intent.getComponent();
3365 }
3366 }
3367
3368 @Override
3369 public String getPackageForToken(IBinder token) {
3370 synchronized (mGlobalLock) {
3371 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3372 if (r == null) {
3373 return null;
3374 }
3375 return r.packageName;
3376 }
3377 }
3378
3379 @Override
3380 public void showLockTaskEscapeMessage(IBinder token) {
3381 synchronized (mGlobalLock) {
3382 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3383 if (r == null) {
3384 return;
3385 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003386 getLockTaskController().showLockTaskToast();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003387 }
3388 }
3389
3390 @Override
3391 public void keyguardGoingAway(int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003392 enforceNotIsolatedCaller("keyguardGoingAway");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003393 final long token = Binder.clearCallingIdentity();
3394 try {
3395 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003396 mKeyguardController.keyguardGoingAway(flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003397 }
3398 } finally {
3399 Binder.restoreCallingIdentity(token);
3400 }
3401 }
3402
3403 /**
3404 * Try to place task to provided position. The final position might be different depending on
3405 * current user and stacks state. The task will be moved to target stack if it's currently in
3406 * different stack.
3407 */
3408 @Override
3409 public void positionTaskInStack(int taskId, int stackId, int position) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003410 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003411 synchronized (mGlobalLock) {
3412 long ident = Binder.clearCallingIdentity();
3413 try {
3414 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
3415 + taskId + " in stackId=" + stackId + " at position=" + position);
3416 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3417 if (task == null) {
3418 throw new IllegalArgumentException("positionTaskInStack: no task for id="
3419 + taskId);
3420 }
3421
3422 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3423
3424 if (stack == null) {
3425 throw new IllegalArgumentException("positionTaskInStack: no stack for id="
3426 + stackId);
3427 }
3428 if (!stack.isActivityTypeStandardOrUndefined()) {
3429 throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
3430 + " the position of task " + taskId + " in/to non-standard stack");
3431 }
3432
3433 // TODO: Have the callers of this API call a separate reparent method if that is
3434 // what they intended to do vs. having this method also do reparenting.
3435 if (task.getStack() == stack) {
3436 // Change position in current stack.
3437 stack.positionChildAt(task, position);
3438 } else {
3439 // Reparent to new stack.
3440 task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
3441 !DEFER_RESUME, "positionTaskInStack");
3442 }
3443 } finally {
3444 Binder.restoreCallingIdentity(ident);
3445 }
3446 }
3447 }
3448
3449 @Override
3450 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
3451 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
3452 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
3453 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
3454 synchronized (mGlobalLock) {
3455 ActivityRecord record = ActivityRecord.isInStackLocked(token);
3456 if (record == null) {
3457 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
3458 + "found for: " + token);
3459 }
3460 record.setSizeConfigurations(horizontalSizeConfiguration,
3461 verticalSizeConfigurations, smallestSizeConfigurations);
3462 }
3463 }
3464
3465 /**
3466 * Dismisses split-screen multi-window mode.
3467 * @param toTop If true the current primary split-screen stack will be placed or left on top.
3468 */
3469 @Override
3470 public void dismissSplitScreenMode(boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003471 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003472 MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
3473 final long ident = Binder.clearCallingIdentity();
3474 try {
3475 synchronized (mGlobalLock) {
3476 final ActivityStack stack =
3477 mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
3478 if (stack == null) {
3479 Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
3480 return;
3481 }
3482
3483 if (toTop) {
3484 // Caller wants the current split-screen primary stack to be the top stack after
3485 // it goes fullscreen, so move it to the front.
3486 stack.moveToFront("dismissSplitScreenMode");
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003487 } else if (mStackSupervisor.isTopDisplayFocusedStack(stack)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003488 // In this case the current split-screen primary stack shouldn't be the top
3489 // stack after it goes fullscreen, but it current has focus, so we move the
3490 // focus to the top-most split-screen secondary stack next to it.
3491 final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
3492 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
3493 if (otherStack != null) {
3494 otherStack.moveToFront("dismissSplitScreenMode_other");
3495 }
3496 }
3497
Evan Rosky10475742018-09-05 19:02:48 -07003498 stack.setWindowingMode(WINDOWING_MODE_UNDEFINED);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003499 }
3500 } finally {
3501 Binder.restoreCallingIdentity(ident);
3502 }
3503 }
3504
3505 /**
3506 * Dismisses Pip
3507 * @param animate True if the dismissal should be animated.
3508 * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
3509 * default animation duration should be used.
3510 */
3511 @Override
3512 public void dismissPip(boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003513 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003514 final long ident = Binder.clearCallingIdentity();
3515 try {
3516 synchronized (mGlobalLock) {
3517 final PinnedActivityStack stack =
3518 mStackSupervisor.getDefaultDisplay().getPinnedStack();
3519 if (stack == null) {
3520 Slog.w(TAG, "dismissPip: pinned stack not found.");
3521 return;
3522 }
3523 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
3524 throw new IllegalArgumentException("Stack: " + stack
3525 + " doesn't support animated resize.");
3526 }
3527 if (animate) {
3528 stack.animateResizePinnedStack(null /* sourceHintBounds */,
3529 null /* destBounds */, animationDuration, false /* fromFullscreen */);
3530 } else {
3531 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
3532 }
3533 }
3534 } finally {
3535 Binder.restoreCallingIdentity(ident);
3536 }
3537 }
3538
3539 @Override
3540 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003541 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003542 synchronized (mGlobalLock) {
3543 mSuppressResizeConfigChanges = suppress;
3544 }
3545 }
3546
3547 /**
3548 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
3549 * animated the stack to the fullscreen, but can also be called if we are relaunching an
3550 * activity and clearing the task at the same time.
3551 */
3552 @Override
3553 // TODO: API should just be about changing windowing modes...
3554 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003555 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003556 "moveTasksToFullscreenStack()");
3557 synchronized (mGlobalLock) {
3558 final long origId = Binder.clearCallingIdentity();
3559 try {
3560 final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
3561 if (stack != null){
3562 if (!stack.isActivityTypeStandardOrUndefined()) {
3563 throw new IllegalArgumentException(
3564 "You can't move tasks from non-standard stacks.");
3565 }
3566 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
3567 }
3568 } finally {
3569 Binder.restoreCallingIdentity(origId);
3570 }
3571 }
3572 }
3573
3574 /**
3575 * Moves the top activity in the input stackId to the pinned stack.
3576 *
3577 * @param stackId Id of stack to move the top activity to pinned stack.
3578 * @param bounds Bounds to use for pinned stack.
3579 *
3580 * @return True if the top activity of the input stack was successfully moved to the pinned
3581 * stack.
3582 */
3583 @Override
3584 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003585 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003586 "moveTopActivityToPinnedStack()");
3587 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003588 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003589 throw new IllegalStateException("moveTopActivityToPinnedStack:"
3590 + "Device doesn't support picture-in-picture mode");
3591 }
3592
3593 long ident = Binder.clearCallingIdentity();
3594 try {
3595 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
3596 } finally {
3597 Binder.restoreCallingIdentity(ident);
3598 }
3599 }
3600 }
3601
3602 @Override
3603 public boolean isInMultiWindowMode(IBinder token) {
3604 final long origId = Binder.clearCallingIdentity();
3605 try {
3606 synchronized (mGlobalLock) {
3607 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3608 if (r == null) {
3609 return false;
3610 }
3611 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
3612 return r.inMultiWindowMode();
3613 }
3614 } finally {
3615 Binder.restoreCallingIdentity(origId);
3616 }
3617 }
3618
3619 @Override
3620 public boolean isInPictureInPictureMode(IBinder token) {
3621 final long origId = Binder.clearCallingIdentity();
3622 try {
3623 synchronized (mGlobalLock) {
3624 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
3625 }
3626 } finally {
3627 Binder.restoreCallingIdentity(origId);
3628 }
3629 }
3630
3631 private boolean isInPictureInPictureMode(ActivityRecord r) {
3632 if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
3633 || r.getStack().isInStackLocked(r) == null) {
3634 return false;
3635 }
3636
3637 // If we are animating to fullscreen then we have already dispatched the PIP mode
3638 // changed, so we should reflect that check here as well.
3639 final PinnedActivityStack stack = r.getStack();
3640 final PinnedStackWindowController windowController = stack.getWindowContainerController();
3641 return !windowController.isAnimatingBoundsToFullscreen();
3642 }
3643
3644 @Override
3645 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
3646 final long origId = Binder.clearCallingIdentity();
3647 try {
3648 synchronized (mGlobalLock) {
3649 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3650 "enterPictureInPictureMode", token, params);
3651
3652 // If the activity is already in picture in picture mode, then just return early
3653 if (isInPictureInPictureMode(r)) {
3654 return true;
3655 }
3656
3657 // Activity supports picture-in-picture, now check that we can enter PiP at this
3658 // point, if it is
3659 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
3660 false /* beforeStopping */)) {
3661 return false;
3662 }
3663
3664 final Runnable enterPipRunnable = () -> {
Wale Ogunwalef276a6f2018-06-15 08:26:07 -07003665 synchronized (mGlobalLock) {
3666 // Only update the saved args from the args that are set
3667 r.pictureInPictureArgs.copyOnlySet(params);
3668 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
3669 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
3670 // Adjust the source bounds by the insets for the transition down
3671 final Rect sourceBounds = new Rect(
3672 r.pictureInPictureArgs.getSourceRectHint());
3673 mStackSupervisor.moveActivityToPinnedStackLocked(
3674 r, sourceBounds, aspectRatio, "enterPictureInPictureMode");
3675 final PinnedActivityStack stack = r.getStack();
3676 stack.setPictureInPictureAspectRatio(aspectRatio);
3677 stack.setPictureInPictureActions(actions);
3678 MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
3679 r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
3680 logPictureInPictureArgs(params);
3681 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003682 };
3683
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003684 if (isKeyguardLocked()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003685 // If the keyguard is showing or occluded, then try and dismiss it before
3686 // entering picture-in-picture (this will prompt the user to authenticate if the
3687 // device is currently locked).
3688 dismissKeyguard(token, new KeyguardDismissCallback() {
3689 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003690 public void onDismissSucceeded() {
3691 mH.post(enterPipRunnable);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003692 }
3693 }, null /* message */);
3694 } else {
3695 // Enter picture in picture immediately otherwise
3696 enterPipRunnable.run();
3697 }
3698 return true;
3699 }
3700 } finally {
3701 Binder.restoreCallingIdentity(origId);
3702 }
3703 }
3704
3705 @Override
3706 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
3707 final long origId = Binder.clearCallingIdentity();
3708 try {
3709 synchronized (mGlobalLock) {
3710 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3711 "setPictureInPictureParams", token, params);
3712
3713 // Only update the saved args from the args that are set
3714 r.pictureInPictureArgs.copyOnlySet(params);
3715 if (r.inPinnedWindowingMode()) {
3716 // If the activity is already in picture-in-picture, update the pinned stack now
3717 // if it is not already expanding to fullscreen. Otherwise, the arguments will
3718 // be used the next time the activity enters PiP
3719 final PinnedActivityStack stack = r.getStack();
3720 if (!stack.isAnimatingBoundsToFullscreen()) {
3721 stack.setPictureInPictureAspectRatio(
3722 r.pictureInPictureArgs.getAspectRatio());
3723 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
3724 }
3725 }
3726 logPictureInPictureArgs(params);
3727 }
3728 } finally {
3729 Binder.restoreCallingIdentity(origId);
3730 }
3731 }
3732
3733 @Override
3734 public int getMaxNumPictureInPictureActions(IBinder token) {
3735 // Currently, this is a static constant, but later, we may change this to be dependent on
3736 // the context of the activity
3737 return 3;
3738 }
3739
3740 private void logPictureInPictureArgs(PictureInPictureParams params) {
3741 if (params.hasSetActions()) {
3742 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
3743 params.getActions().size());
3744 }
3745 if (params.hasSetAspectRatio()) {
3746 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
3747 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
3748 MetricsLogger.action(lm);
3749 }
3750 }
3751
3752 /**
3753 * Checks the state of the system and the activity associated with the given {@param token} to
3754 * verify that picture-in-picture is supported for that activity.
3755 *
3756 * @return the activity record for the given {@param token} if all the checks pass.
3757 */
3758 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
3759 IBinder token, PictureInPictureParams params) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003760 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003761 throw new IllegalStateException(caller
3762 + ": Device doesn't support picture-in-picture mode.");
3763 }
3764
3765 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3766 if (r == null) {
3767 throw new IllegalStateException(caller
3768 + ": Can't find activity for token=" + token);
3769 }
3770
3771 if (!r.supportsPictureInPicture()) {
3772 throw new IllegalStateException(caller
3773 + ": Current activity does not support picture-in-picture.");
3774 }
3775
3776 if (params.hasSetAspectRatio()
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003777 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003778 params.getAspectRatio())) {
3779 final float minAspectRatio = mContext.getResources().getFloat(
3780 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
3781 final float maxAspectRatio = mContext.getResources().getFloat(
3782 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
3783 throw new IllegalArgumentException(String.format(caller
3784 + ": Aspect ratio is too extreme (must be between %f and %f).",
3785 minAspectRatio, maxAspectRatio));
3786 }
3787
3788 // Truncate the number of actions if necessary
3789 params.truncateActions(getMaxNumPictureInPictureActions(token));
3790
3791 return r;
3792 }
3793
3794 @Override
3795 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003796 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003797 synchronized (mGlobalLock) {
3798 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
3799 if (r == null) {
3800 throw new IllegalArgumentException("Activity does not exist; token="
3801 + activityToken);
3802 }
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07003803 return r.getUriPermissionsLocked().getExternalToken();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003804 }
3805 }
3806
3807 @Override
3808 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
3809 Rect tempDockedTaskInsetBounds,
3810 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003811 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003812 long ident = Binder.clearCallingIdentity();
3813 try {
3814 synchronized (mGlobalLock) {
3815 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
3816 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
3817 PRESERVE_WINDOWS);
3818 }
3819 } finally {
3820 Binder.restoreCallingIdentity(ident);
3821 }
3822 }
3823
3824 @Override
3825 public void setSplitScreenResizing(boolean resizing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003826 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003827 final long ident = Binder.clearCallingIdentity();
3828 try {
3829 synchronized (mGlobalLock) {
3830 mStackSupervisor.setSplitScreenResizing(resizing);
3831 }
3832 } finally {
3833 Binder.restoreCallingIdentity(ident);
3834 }
3835 }
3836
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003837 /**
3838 * Check that we have the features required for VR-related API calls, and throw an exception if
3839 * not.
3840 */
3841 void enforceSystemHasVrFeature() {
3842 if (!mContext.getPackageManager().hasSystemFeature(
3843 PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
3844 throw new UnsupportedOperationException("VR mode not supported on this device!");
3845 }
3846 }
3847
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003848 @Override
3849 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003850 enforceSystemHasVrFeature();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003851
3852 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3853
3854 ActivityRecord r;
3855 synchronized (mGlobalLock) {
3856 r = ActivityRecord.isInStackLocked(token);
3857 }
3858
3859 if (r == null) {
3860 throw new IllegalArgumentException();
3861 }
3862
3863 int err;
3864 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
3865 VrManagerInternal.NO_ERROR) {
3866 return err;
3867 }
3868
3869 // Clear the binder calling uid since this path may call moveToTask().
3870 final long callingId = Binder.clearCallingIdentity();
3871 try {
3872 synchronized (mGlobalLock) {
3873 r.requestedVrComponent = (enabled) ? packageName : null;
3874
3875 // Update associated state if this activity is currently focused
Andrii Kulian52d255c2018-07-13 11:32:19 -07003876 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003877 applyUpdateVrModeLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003878 }
3879 return 0;
3880 }
3881 } finally {
3882 Binder.restoreCallingIdentity(callingId);
3883 }
3884 }
3885
3886 @Override
3887 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
3888 Slog.i(TAG, "Activity tried to startLocalVoiceInteraction");
3889 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003890 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003891 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
3892 throw new SecurityException("Only focused activity can call startVoiceInteraction");
3893 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07003894 if (mRunningVoice != null || activity.getTask().voiceSession != null
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003895 || activity.voiceSession != null) {
3896 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
3897 return;
3898 }
3899 if (activity.pendingVoiceInteractionStart) {
3900 Slog.w(TAG, "Pending start of voice interaction already.");
3901 return;
3902 }
3903 activity.pendingVoiceInteractionStart = true;
3904 }
3905 LocalServices.getService(VoiceInteractionManagerInternal.class)
3906 .startLocalVoiceInteraction(callingActivity, options);
3907 }
3908
3909 @Override
3910 public void stopLocalVoiceInteraction(IBinder callingActivity) {
3911 LocalServices.getService(VoiceInteractionManagerInternal.class)
3912 .stopLocalVoiceInteraction(callingActivity);
3913 }
3914
3915 @Override
3916 public boolean supportsLocalVoiceInteraction() {
3917 return LocalServices.getService(VoiceInteractionManagerInternal.class)
3918 .supportsLocalVoiceInteraction();
3919 }
3920
3921 /** Notifies all listeners when the pinned stack animation starts. */
3922 @Override
3923 public void notifyPinnedStackAnimationStarted() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003924 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003925 }
3926
3927 /** Notifies all listeners when the pinned stack animation ends. */
3928 @Override
3929 public void notifyPinnedStackAnimationEnded() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003930 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003931 }
3932
3933 @Override
3934 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003935 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003936 final long ident = Binder.clearCallingIdentity();
3937 try {
3938 synchronized (mGlobalLock) {
3939 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
3940 }
3941 } finally {
3942 Binder.restoreCallingIdentity(ident);
3943 }
3944 }
3945
3946 @Override
3947 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003948 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003949
3950 synchronized (mGlobalLock) {
3951 // Check if display is initialized in AM.
3952 if (!mStackSupervisor.isDisplayAdded(displayId)) {
3953 // Call might come when display is not yet added or has already been removed.
3954 if (DEBUG_CONFIGURATION) {
3955 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
3956 + displayId);
3957 }
3958 return false;
3959 }
3960
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003961 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003962 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003963 values = mWindowManager.computeNewConfiguration(displayId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003964 }
3965
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003966 if (mWindowManager != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07003967 final Message msg = PooledLambda.obtainMessage(
3968 ActivityManagerInternal::updateOomLevelsForDisplay, mAmInternal, displayId);
3969 mH.sendMessage(msg);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003970 }
3971
3972 final long origId = Binder.clearCallingIdentity();
3973 try {
3974 if (values != null) {
3975 Settings.System.clearConfiguration(values);
3976 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003977 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003978 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
3979 return mTmpUpdateConfigurationResult.changes != 0;
3980 } finally {
3981 Binder.restoreCallingIdentity(origId);
3982 }
3983 }
3984 }
3985
3986 @Override
3987 public boolean updateConfiguration(Configuration values) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003988 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003989
3990 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003991 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003992 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003993 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003994 }
3995
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003996 if (mWindowManager != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07003997 final Message msg = PooledLambda.obtainMessage(
3998 ActivityManagerInternal::updateOomLevelsForDisplay, mAmInternal,
3999 DEFAULT_DISPLAY);
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 updateConfigurationLocked(values, null, false, false /* persistent */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004009 UserHandle.USER_NULL, false /* deferResume */,
4010 mTmpUpdateConfigurationResult);
4011 return mTmpUpdateConfigurationResult.changes != 0;
4012 } finally {
4013 Binder.restoreCallingIdentity(origId);
4014 }
4015 }
4016 }
4017
4018 @Override
4019 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
4020 CharSequence message) {
4021 if (message != null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004022 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004023 Manifest.permission.SHOW_KEYGUARD_MESSAGE, "dismissKeyguard()");
4024 }
4025 final long callingId = Binder.clearCallingIdentity();
4026 try {
4027 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004028 mKeyguardController.dismissKeyguard(token, callback, message);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004029 }
4030 } finally {
4031 Binder.restoreCallingIdentity(callingId);
4032 }
4033 }
4034
4035 @Override
4036 public void cancelTaskWindowTransition(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004037 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004038 "cancelTaskWindowTransition()");
4039 final long ident = Binder.clearCallingIdentity();
4040 try {
4041 synchronized (mGlobalLock) {
4042 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
4043 MATCH_TASK_IN_STACKS_ONLY);
4044 if (task == null) {
4045 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
4046 return;
4047 }
4048 task.cancelWindowTransition();
4049 }
4050 } finally {
4051 Binder.restoreCallingIdentity(ident);
4052 }
4053 }
4054
4055 @Override
4056 public ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004057 enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004058 final long ident = Binder.clearCallingIdentity();
4059 try {
4060 final TaskRecord task;
4061 synchronized (mGlobalLock) {
4062 task = mStackSupervisor.anyTaskForIdLocked(taskId,
4063 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
4064 if (task == null) {
4065 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
4066 return null;
4067 }
4068 }
4069 // Don't call this while holding the lock as this operation might hit the disk.
4070 return task.getSnapshot(reducedResolution);
4071 } finally {
4072 Binder.restoreCallingIdentity(ident);
4073 }
4074 }
4075
4076 @Override
4077 public void setDisablePreviewScreenshots(IBinder token, boolean disable) {
4078 synchronized (mGlobalLock) {
4079 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4080 if (r == null) {
4081 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
4082 + token);
4083 return;
4084 }
4085 final long origId = Binder.clearCallingIdentity();
4086 try {
4087 r.setDisablePreviewScreenshots(disable);
4088 } finally {
4089 Binder.restoreCallingIdentity(origId);
4090 }
4091 }
4092 }
4093
4094 /** Return the user id of the last resumed activity. */
4095 @Override
4096 public @UserIdInt
4097 int getLastResumedActivityUserId() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004098 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004099 Manifest.permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
4100 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07004101 if (mLastResumedActivity == null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004102 return getCurrentUserId();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004103 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004104 return mLastResumedActivity.userId;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004105 }
4106 }
4107
4108 @Override
4109 public void updateLockTaskFeatures(int userId, int flags) {
4110 final int callingUid = Binder.getCallingUid();
4111 if (callingUid != 0 && callingUid != SYSTEM_UID) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004112 mAmInternal.enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004113 "updateLockTaskFeatures()");
4114 }
4115 synchronized (mGlobalLock) {
4116 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
4117 Integer.toHexString(flags));
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07004118 getLockTaskController().updateLockTaskFeatures(userId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004119 }
4120 }
4121
4122 @Override
4123 public void setShowWhenLocked(IBinder token, boolean showWhenLocked) {
4124 synchronized (mGlobalLock) {
4125 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4126 if (r == null) {
4127 return;
4128 }
4129 final long origId = Binder.clearCallingIdentity();
4130 try {
4131 r.setShowWhenLocked(showWhenLocked);
4132 } finally {
4133 Binder.restoreCallingIdentity(origId);
4134 }
4135 }
4136 }
4137
4138 @Override
4139 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) {
4140 synchronized (mGlobalLock) {
4141 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4142 if (r == null) {
4143 return;
4144 }
4145 final long origId = Binder.clearCallingIdentity();
4146 try {
4147 r.setTurnScreenOn(turnScreenOn);
4148 } finally {
4149 Binder.restoreCallingIdentity(origId);
4150 }
4151 }
4152 }
4153
4154 @Override
4155 public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004156 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004157 "registerRemoteAnimations");
4158 definition.setCallingPid(Binder.getCallingPid());
4159 synchronized (mGlobalLock) {
4160 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4161 if (r == null) {
4162 return;
4163 }
4164 final long origId = Binder.clearCallingIdentity();
4165 try {
4166 r.registerRemoteAnimations(definition);
4167 } finally {
4168 Binder.restoreCallingIdentity(origId);
4169 }
4170 }
4171 }
4172
4173 @Override
4174 public void registerRemoteAnimationForNextActivityStart(String packageName,
4175 RemoteAnimationAdapter adapter) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004176 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004177 "registerRemoteAnimationForNextActivityStart");
4178 adapter.setCallingPid(Binder.getCallingPid());
4179 synchronized (mGlobalLock) {
4180 final long origId = Binder.clearCallingIdentity();
4181 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07004182 getActivityStartController().registerRemoteAnimationForNextActivityStart(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004183 packageName, adapter);
4184 } finally {
4185 Binder.restoreCallingIdentity(origId);
4186 }
4187 }
4188 }
4189
4190 /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
4191 @Override
4192 public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
4193 synchronized (mGlobalLock) {
4194 final long origId = Binder.clearCallingIdentity();
4195 try {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004196 mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004197 } finally {
4198 Binder.restoreCallingIdentity(origId);
4199 }
4200 }
4201 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004202
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004203 @Override
4204 public void setVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004205 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004206 synchronized (mGlobalLock) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004207 final int pid = Binder.getCallingPid();
4208 final WindowProcessController wpc = mPidMap.get(pid);
4209 mVrController.setVrThreadLocked(tid, pid, wpc);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004210 }
4211 }
4212
4213 @Override
4214 public void setPersistentVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004215 if (checkCallingPermission(Manifest.permission.RESTRICTED_VR_ACCESS)
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004216 != PERMISSION_GRANTED) {
4217 final String msg = "Permission Denial: setPersistentVrThread() from pid="
4218 + Binder.getCallingPid()
4219 + ", uid=" + Binder.getCallingUid()
4220 + " requires " + Manifest.permission.RESTRICTED_VR_ACCESS;
4221 Slog.w(TAG, msg);
4222 throw new SecurityException(msg);
4223 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004224 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004225 synchronized (mGlobalLock) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004226 final int pid = Binder.getCallingPid();
4227 final WindowProcessController proc = mPidMap.get(pid);
4228 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004229 }
4230 }
4231
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004232 @Override
4233 public void stopAppSwitches() {
4234 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
4235 synchronized (mGlobalLock) {
4236 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME;
4237 mDidAppSwitch = false;
4238 getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
4239 }
4240 }
4241
4242 @Override
4243 public void resumeAppSwitches() {
4244 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
4245 synchronized (mGlobalLock) {
4246 // Note that we don't execute any pending app switches... we will
4247 // let those wait until either the timeout, or the next start
4248 // activity request.
4249 mAppSwitchesAllowedTime = 0;
4250 }
4251 }
4252
4253 void onStartActivitySetDidAppSwitch() {
4254 if (mDidAppSwitch) {
4255 // This is the second allowed switch since we stopped switches, so now just generally
4256 // allow switches. Use case:
4257 // - user presses home (switches disabled, switch to home, mDidAppSwitch now true);
4258 // - user taps a home icon (coming from home so allowed, we hit here and now allow
4259 // anyone to switch again).
4260 mAppSwitchesAllowedTime = 0;
4261 } else {
4262 mDidAppSwitch = true;
4263 }
4264 }
4265
4266 /** @return whether the system should disable UI modes incompatible with VR mode. */
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004267 boolean shouldDisableNonVrUiLocked() {
4268 return mVrController.shouldDisableNonVrUiLocked();
4269 }
4270
Wale Ogunwale53783742018-09-16 10:21:51 -07004271 private void applyUpdateVrModeLocked(ActivityRecord r) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004272 // VR apps are expected to run in a main display. If an app is turning on VR for
4273 // itself, but lives in a dynamic stack, then make sure that it is moved to the main
4274 // fullscreen stack before enabling VR Mode.
4275 // TODO: The goal of this code is to keep the VR app on the main display. When the
4276 // stack implementation changes in the future, keep in mind that the use of the fullscreen
4277 // stack is a means to move the activity to the main display and a moveActivityToDisplay()
4278 // option would be a better choice here.
4279 if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
4280 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
4281 + " to main stack for VR");
4282 final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
4283 WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
4284 moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
4285 }
4286 mH.post(() -> {
4287 if (!mVrController.onVrModeChanged(r)) {
4288 return;
4289 }
4290 synchronized (mGlobalLock) {
4291 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
4292 mWindowManager.disableNonVrUi(disableNonVrUi);
4293 if (disableNonVrUi) {
4294 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
4295 // then remove the pinned stack.
4296 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
4297 }
4298 }
4299 });
4300 }
4301
Wale Ogunwale53783742018-09-16 10:21:51 -07004302 @Override
4303 public int getPackageScreenCompatMode(String packageName) {
4304 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4305 synchronized (mGlobalLock) {
4306 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4307 }
4308 }
4309
4310 @Override
4311 public void setPackageScreenCompatMode(String packageName, int mode) {
4312 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4313 "setPackageScreenCompatMode");
4314 synchronized (mGlobalLock) {
4315 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4316 }
4317 }
4318
4319 @Override
4320 public boolean getPackageAskScreenCompat(String packageName) {
4321 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4322 synchronized (mGlobalLock) {
4323 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4324 }
4325 }
4326
4327 @Override
4328 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4329 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4330 "setPackageAskScreenCompat");
4331 synchronized (mGlobalLock) {
4332 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4333 }
4334 }
4335
Wale Ogunwale64258362018-10-16 15:13:37 -07004336 public static String relaunchReasonToString(int relaunchReason) {
4337 switch (relaunchReason) {
4338 case RELAUNCH_REASON_WINDOWING_MODE_RESIZE:
4339 return "window_resize";
4340 case RELAUNCH_REASON_FREE_RESIZE:
4341 return "free_resize";
4342 default:
4343 return null;
4344 }
4345 }
4346
Andrii Kulian5f750bc2018-07-17 08:57:23 -07004347 ActivityStack getTopDisplayFocusedStack() {
4348 return mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004349 }
4350
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004351 /** Pokes the task persister. */
4352 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
4353 mRecentTasks.notifyTaskPersisterLocked(task, flush);
4354 }
4355
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004356 void onTopProcChangedLocked(WindowProcessController proc) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004357 mVrController.onTopProcChangedLocked(proc);
4358 }
4359
4360 boolean isKeyguardLocked() {
4361 return mKeyguardController.isKeyguardLocked();
4362 }
4363
4364 boolean isNextTransitionForward() {
4365 int transit = mWindowManager.getPendingAppTransition();
4366 return transit == TRANSIT_ACTIVITY_OPEN
4367 || transit == TRANSIT_TASK_OPEN
4368 || transit == TRANSIT_TASK_TO_FRONT;
4369 }
4370
Wale Ogunwale31913b52018-10-13 08:29:31 -07004371 void dumpLastANRLocked(PrintWriter pw) {
4372 pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
4373 if (mLastANRState == null) {
4374 pw.println(" <no ANR has occurred since boot>");
4375 } else {
4376 pw.println(mLastANRState);
4377 }
4378 }
4379
4380 void dumpLastANRTracesLocked(PrintWriter pw) {
4381 pw.println("ACTIVITY MANAGER LAST ANR TRACES (dumpsys activity lastanr-traces)");
4382
4383 final File[] files = new File(ANR_TRACE_DIR).listFiles();
4384 if (ArrayUtils.isEmpty(files)) {
4385 pw.println(" <no ANR has occurred since boot>");
4386 return;
4387 }
4388 // Find the latest file.
4389 File latest = null;
4390 for (File f : files) {
4391 if ((latest == null) || (latest.lastModified() < f.lastModified())) {
4392 latest = f;
Wale Ogunwalef6733932018-06-27 05:14:34 -07004393 }
Wale Ogunwale31913b52018-10-13 08:29:31 -07004394 }
4395 pw.print("File: ");
4396 pw.print(latest.getName());
4397 pw.println();
4398 try (BufferedReader in = new BufferedReader(new FileReader(latest))) {
4399 String line;
4400 while ((line = in.readLine()) != null) {
4401 pw.println(line);
4402 }
4403 } catch (IOException e) {
4404 pw.print("Unable to read: ");
4405 pw.print(e);
4406 pw.println();
4407 }
4408 }
4409
4410 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
4411 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
4412 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
4413 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
4414 }
4415
4416 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
4417 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
4418 pw.println(header);
4419
4420 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
4421 dumpPackage);
4422 boolean needSep = printedAnything;
4423
4424 boolean printed = ActivityStackSupervisor.printThisActivity(pw,
4425 mStackSupervisor.getTopResumedActivity(), dumpPackage, needSep,
4426 " ResumedActivity: ");
4427 if (printed) {
4428 printedAnything = true;
4429 needSep = false;
4430 }
4431
4432 if (dumpPackage == null) {
4433 if (needSep) {
4434 pw.println();
4435 }
4436 printedAnything = true;
4437 mStackSupervisor.dump(pw, " ");
4438 }
4439
4440 if (!printedAnything) {
4441 pw.println(" (nothing)");
4442 }
4443 }
4444
4445 void dumpActivityContainersLocked(PrintWriter pw) {
4446 pw.println("ACTIVITY MANAGER STARTER (dumpsys activity containers)");
4447 mStackSupervisor.dumpChildrenNames(pw, " ");
4448 pw.println(" ");
4449 }
4450
4451 void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
4452 pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
4453 getActivityStartController().dump(pw, "", dumpPackage);
4454 }
4455
4456 /**
4457 * There are three things that cmd can be:
4458 * - a flattened component name that matches an existing activity
4459 * - the cmd arg isn't the flattened component name of an existing activity:
4460 * dump all activity whose component contains the cmd as a substring
4461 * - A hex number of the ActivityRecord object instance.
4462 *
4463 * @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
4464 * @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
4465 */
4466 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
4467 int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
4468 ArrayList<ActivityRecord> activities;
4469
4470 synchronized (mGlobalLock) {
4471 activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
4472 dumpFocusedStackOnly);
4473 }
4474
4475 if (activities.size() <= 0) {
4476 return false;
4477 }
4478
4479 String[] newArgs = new String[args.length - opti];
4480 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
4481
4482 TaskRecord lastTask = null;
4483 boolean needSep = false;
4484 for (int i = activities.size() - 1; i >= 0; i--) {
4485 ActivityRecord r = activities.get(i);
4486 if (needSep) {
4487 pw.println();
4488 }
4489 needSep = true;
4490 synchronized (mGlobalLock) {
4491 final TaskRecord task = r.getTask();
4492 if (lastTask != task) {
4493 lastTask = task;
4494 pw.print("TASK "); pw.print(lastTask.affinity);
4495 pw.print(" id="); pw.print(lastTask.taskId);
4496 pw.print(" userId="); pw.println(lastTask.userId);
4497 if (dumpAll) {
4498 lastTask.dump(pw, " ");
4499 }
4500 }
4501 }
4502 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
4503 }
4504 return true;
4505 }
4506
4507 /**
4508 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
4509 * there is a thread associated with the activity.
4510 */
4511 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
4512 final ActivityRecord r, String[] args, boolean dumpAll) {
4513 String innerPrefix = prefix + " ";
4514 synchronized (mGlobalLock) {
4515 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
4516 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
4517 pw.print(" pid=");
4518 if (r.hasProcess()) pw.println(r.app.getPid());
4519 else pw.println("(not running)");
4520 if (dumpAll) {
4521 r.dump(pw, innerPrefix);
4522 }
4523 }
4524 if (r.attachedToProcess()) {
4525 // flush anything that is already in the PrintWriter since the thread is going
4526 // to write to the file descriptor directly
4527 pw.flush();
4528 try {
4529 TransferPipe tp = new TransferPipe();
4530 try {
4531 r.app.getThread().dumpActivity(tp.getWriteFd(),
4532 r.appToken, innerPrefix, args);
4533 tp.go(fd);
4534 } finally {
4535 tp.kill();
4536 }
4537 } catch (IOException e) {
4538 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
4539 } catch (RemoteException e) {
4540 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
4541 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004542 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004543 }
4544
Wale Ogunwalef6733932018-06-27 05:14:34 -07004545 void writeSleepStateToProto(ProtoOutputStream proto) {
4546 for (ActivityTaskManagerInternal.SleepToken st : mStackSupervisor.mSleepTokens) {
4547 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS,
4548 st.toString());
4549 }
4550
4551 if (mRunningVoice != null) {
4552 final long vrToken = proto.start(
4553 ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
4554 proto.write(ActivityManagerServiceDumpProcessesProto.Voice.SESSION,
4555 mRunningVoice.toString());
4556 mVoiceWakeLock.writeToProto(
4557 proto, ActivityManagerServiceDumpProcessesProto.Voice.WAKELOCK);
4558 proto.end(vrToken);
4559 }
4560
4561 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
4562 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN,
4563 mShuttingDown);
4564 mVrController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004565 }
4566
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004567 int getCurrentUserId() {
4568 return mAmInternal.getCurrentUserId();
4569 }
4570
4571 private void enforceNotIsolatedCaller(String caller) {
4572 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4573 throw new SecurityException("Isolated process not allowed to call " + caller);
4574 }
4575 }
4576
Wale Ogunwalef6733932018-06-27 05:14:34 -07004577 public Configuration getConfiguration() {
4578 Configuration ci;
4579 synchronized(mGlobalLock) {
Yunfan Chen75157d72018-07-27 14:47:21 +09004580 ci = new Configuration(getGlobalConfigurationForCallingPid());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004581 ci.userSetLocale = false;
4582 }
4583 return ci;
4584 }
4585
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004586 /**
4587 * Current global configuration information. Contains general settings for the entire system,
4588 * also corresponds to the merged configuration of the default display.
4589 */
4590 Configuration getGlobalConfiguration() {
4591 return mStackSupervisor.getConfiguration();
4592 }
4593
4594 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4595 boolean initLocale) {
4596 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
4597 }
4598
4599 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4600 boolean initLocale, boolean deferResume) {
4601 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
4602 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
4603 UserHandle.USER_NULL, deferResume);
4604 }
4605
4606 void updatePersistentConfiguration(Configuration values, @UserIdInt int userId) {
4607 final long origId = Binder.clearCallingIdentity();
4608 try {
4609 synchronized (mGlobalLock) {
4610 updateConfigurationLocked(values, null, false, true, userId,
4611 false /* deferResume */);
4612 }
4613 } finally {
4614 Binder.restoreCallingIdentity(origId);
4615 }
4616 }
4617
4618 void updateUserConfiguration() {
4619 synchronized (mGlobalLock) {
4620 final Configuration configuration = new Configuration(getGlobalConfiguration());
4621 final int currentUserId = mAmInternal.getCurrentUserId();
4622 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
4623 currentUserId, Settings.System.canWrite(mContext));
4624 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
4625 false /* persistent */, currentUserId, false /* deferResume */);
4626 }
4627 }
4628
4629 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4630 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
4631 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
4632 deferResume, null /* result */);
4633 }
4634
4635 /**
4636 * Do either or both things: (1) change the current configuration, and (2)
4637 * make sure the given activity is running with the (now) current
4638 * configuration. Returns true if the activity has been left running, or
4639 * false if <var>starting</var> is being destroyed to match the new
4640 * configuration.
4641 *
4642 * @param userId is only used when persistent parameter is set to true to persist configuration
4643 * for that particular user
4644 */
4645 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4646 boolean initLocale, boolean persistent, int userId, boolean deferResume,
4647 ActivityTaskManagerService.UpdateConfigurationResult result) {
4648 int changes = 0;
4649 boolean kept = true;
4650
4651 if (mWindowManager != null) {
4652 mWindowManager.deferSurfaceLayout();
4653 }
4654 try {
4655 if (values != null) {
4656 changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
4657 deferResume);
4658 }
4659
4660 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4661 } finally {
4662 if (mWindowManager != null) {
4663 mWindowManager.continueSurfaceLayout();
4664 }
4665 }
4666
4667 if (result != null) {
4668 result.changes = changes;
4669 result.activityRelaunched = !kept;
4670 }
4671 return kept;
4672 }
4673
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004674 /** Update default (global) configuration and notify listeners about changes. */
4675 private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
4676 boolean persistent, int userId, boolean deferResume) {
4677 mTempConfig.setTo(getGlobalConfiguration());
4678 final int changes = mTempConfig.updateFrom(values);
4679 if (changes == 0) {
4680 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
4681 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
4682 // performDisplayOverrideConfigUpdate in order to send the new display configuration
4683 // (even if there are no actual changes) to unfreeze the window.
4684 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
4685 return 0;
4686 }
4687
4688 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
4689 "Updating global configuration to: " + values);
4690
4691 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
4692 StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
4693 values.colorMode,
4694 values.densityDpi,
4695 values.fontScale,
4696 values.hardKeyboardHidden,
4697 values.keyboard,
4698 values.keyboardHidden,
4699 values.mcc,
4700 values.mnc,
4701 values.navigation,
4702 values.navigationHidden,
4703 values.orientation,
4704 values.screenHeightDp,
4705 values.screenLayout,
4706 values.screenWidthDp,
4707 values.smallestScreenWidthDp,
4708 values.touchscreen,
4709 values.uiMode);
4710
4711
4712 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
4713 final LocaleList locales = values.getLocales();
4714 int bestLocaleIndex = 0;
4715 if (locales.size() > 1) {
4716 if (mSupportedSystemLocales == null) {
4717 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
4718 }
4719 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
4720 }
4721 SystemProperties.set("persist.sys.locale",
4722 locales.get(bestLocaleIndex).toLanguageTag());
4723 LocaleList.setDefault(locales, bestLocaleIndex);
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004724
4725 final Message m = PooledLambda.obtainMessage(
4726 ActivityTaskManagerService::sendLocaleToMountDaemonMsg, this,
4727 locales.get(bestLocaleIndex));
4728 mH.sendMessage(m);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004729 }
4730
Yunfan Chen75157d72018-07-27 14:47:21 +09004731 mTempConfig.seq = increaseConfigurationSeqLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004732
4733 // Update stored global config and notify everyone about the change.
4734 mStackSupervisor.onConfigurationChanged(mTempConfig);
4735
4736 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
4737 // TODO(multi-display): Update UsageEvents#Event to include displayId.
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004738 mUsageStatsInternal.reportConfigurationChange(mTempConfig, mAmInternal.getCurrentUserId());
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004739
4740 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
Wale Ogunwalef6733932018-06-27 05:14:34 -07004741 updateShouldShowDialogsLocked(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004742
4743 AttributeCache ac = AttributeCache.instance();
4744 if (ac != null) {
4745 ac.updateConfiguration(mTempConfig);
4746 }
4747
4748 // Make sure all resources in our process are updated right now, so that anyone who is going
4749 // to retrieve resource values after we return will be sure to get the new ones. This is
4750 // especially important during boot, where the first config change needs to guarantee all
4751 // resources have that config before following boot code is executed.
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004752 mSystemThread.applyConfigurationToResources(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004753
4754 // We need another copy of global config because we're scheduling some calls instead of
4755 // running them in place. We need to be sure that object we send will be handled unchanged.
4756 final Configuration configCopy = new Configuration(mTempConfig);
4757 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004758 final Message msg = PooledLambda.obtainMessage(
4759 ActivityTaskManagerService::sendPutConfigurationForUserMsg,
4760 this, userId, configCopy);
4761 mH.sendMessage(msg);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004762 }
4763
Yunfan Chen34fcc7a2018-10-11 16:26:09 -07004764 for (int i = mPidMap.size() - 1; i >= 0; i--) {
Yunfan Chen79b96062018-10-17 12:45:23 -07004765 final int pid = mPidMap.keyAt(i);
4766 final WindowProcessController app = mPidMap.get(pid);
Yunfan Chen34fcc7a2018-10-11 16:26:09 -07004767 if (DEBUG_CONFIGURATION) {
4768 Slog.v(TAG_CONFIGURATION, "Update process config of "
4769 + app.mName + " to new config " + configCopy);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004770 }
Yunfan Chen34fcc7a2018-10-11 16:26:09 -07004771 app.onConfigurationChanged(configCopy);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004772 }
4773
Wale Ogunwale2ea36d42018-10-18 10:27:31 -07004774 final Message msg = PooledLambda.obtainMessage(
4775 ActivityManagerInternal::broadcastGlobalConfigurationChanged,
4776 mAmInternal, changes, initLocale);
4777 mH.sendMessage(msg);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004778
4779 // Override configuration of the default display duplicates global config, so we need to
4780 // update it also. This will also notify WindowManager about changes.
4781 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
4782 DEFAULT_DISPLAY);
4783
4784 return changes;
4785 }
4786
4787 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
4788 boolean deferResume, int displayId) {
4789 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
4790 displayId, null /* result */);
4791 }
4792
4793 /**
4794 * Updates override configuration specific for the selected display. If no config is provided,
4795 * new one will be computed in WM based on current display info.
4796 */
4797 boolean updateDisplayOverrideConfigurationLocked(Configuration values,
4798 ActivityRecord starting, boolean deferResume, int displayId,
4799 ActivityTaskManagerService.UpdateConfigurationResult result) {
4800 int changes = 0;
4801 boolean kept = true;
4802
4803 if (mWindowManager != null) {
4804 mWindowManager.deferSurfaceLayout();
4805 }
4806 try {
4807 if (values != null) {
4808 if (displayId == DEFAULT_DISPLAY) {
4809 // Override configuration of the default display duplicates global config, so
4810 // we're calling global config update instead for default display. It will also
4811 // apply the correct override config.
4812 changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
4813 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
4814 } else {
4815 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
4816 }
4817 }
4818
4819 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4820 } finally {
4821 if (mWindowManager != null) {
4822 mWindowManager.continueSurfaceLayout();
4823 }
4824 }
4825
4826 if (result != null) {
4827 result.changes = changes;
4828 result.activityRelaunched = !kept;
4829 }
4830 return kept;
4831 }
4832
4833 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
4834 int displayId) {
4835 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
4836 final int changes = mTempConfig.updateFrom(values);
4837 if (changes != 0) {
4838 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
4839 + mTempConfig + " for displayId=" + displayId);
4840 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
4841
4842 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
4843 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004844 mAppWarnings.onDensityChanged();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004845
Wale Ogunwale5c918702018-10-18 11:06:33 -07004846 // Post message to start process to avoid possible deadlock of calling into AMS with
4847 // the ATMS lock held.
4848 final Message msg = PooledLambda.obtainMessage(
4849 ActivityManagerInternal::killAllBackgroundProcessesExcept, mAmInternal,
4850 N, ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
4851 mH.sendMessage(msg);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004852 }
4853 }
4854
4855 // Update the configuration with WM first and check if any of the stacks need to be resized
4856 // due to the configuration change. If so, resize the stacks now and do any relaunches if
4857 // necessary. This way we don't need to relaunch again afterwards in
4858 // ensureActivityConfiguration().
4859 if (mWindowManager != null) {
4860 final int[] resizedStacks =
4861 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
4862 if (resizedStacks != null) {
4863 for (int stackId : resizedStacks) {
4864 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
4865 }
4866 }
4867 }
4868
4869 return changes;
4870 }
4871
Wale Ogunwalef6733932018-06-27 05:14:34 -07004872 private void updateEventDispatchingLocked(boolean booted) {
4873 mWindowManager.setEventDispatching(booted && !mShuttingDown);
4874 }
4875
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004876 private void sendPutConfigurationForUserMsg(int userId, Configuration config) {
4877 final ContentResolver resolver = mContext.getContentResolver();
4878 Settings.System.putConfigurationForUser(resolver, config, userId);
4879 }
4880
4881 private void sendLocaleToMountDaemonMsg(Locale l) {
4882 try {
4883 IBinder service = ServiceManager.getService("mount");
4884 IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
4885 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
4886 storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
4887 } catch (RemoteException e) {
4888 Log.e(TAG, "Error storing locale for decryption UI", e);
4889 }
4890 }
4891
4892 boolean isActivityStartsLoggingEnabled() {
4893 return mAmInternal.isActivityStartsLoggingEnabled();
4894 }
4895
Wale Ogunwalef6733932018-06-27 05:14:34 -07004896 void enableScreenAfterBoot(boolean booted) {
4897 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4898 SystemClock.uptimeMillis());
4899 mWindowManager.enableScreenAfterBoot();
4900
4901 synchronized (mGlobalLock) {
4902 updateEventDispatchingLocked(booted);
4903 }
4904 }
4905
4906 boolean canShowErrorDialogs() {
4907 return mShowDialogs && !mSleeping && !mShuttingDown
4908 && !mKeyguardController.isKeyguardOrAodShowing(DEFAULT_DISPLAY)
4909 && !hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
Wale Ogunwale86b74462018-07-02 08:42:43 -07004910 mAmInternal.getCurrentUserId())
Wale Ogunwalef6733932018-06-27 05:14:34 -07004911 && !(UserManager.isDeviceInDemoMode(mContext)
Wale Ogunwale86b74462018-07-02 08:42:43 -07004912 && mAmInternal.getCurrentUser().isDemo());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004913 }
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 Ogunwale9e4f3e02018-05-17 09:35:39 -07005460 void logAppTooSlow(WindowProcessController app, long startTime, String msg) {
5461 if (true || Build.IS_USER) {
5462 return;
5463 }
5464
5465 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5466 StrictMode.allowThreadDiskWrites();
5467 try {
5468 File tracesDir = new File("/data/anr");
5469 File tracesFile = null;
5470 try {
5471 tracesFile = File.createTempFile("app_slow", null, tracesDir);
5472
5473 StringBuilder sb = new StringBuilder();
5474 Time tobj = new Time();
5475 tobj.set(System.currentTimeMillis());
5476 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5477 sb.append(": ");
5478 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5479 sb.append(" since ");
5480 sb.append(msg);
5481 FileOutputStream fos = new FileOutputStream(tracesFile);
5482 fos.write(sb.toString().getBytes());
5483 if (app == null) {
5484 fos.write("\n*** No application process!".getBytes());
5485 }
5486 fos.close();
5487 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5488 } catch (IOException e) {
5489 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesFile, e);
5490 return;
5491 }
5492
5493 if (app != null && app.getPid() > 0) {
5494 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5495 firstPids.add(app.getPid());
5496 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, null, null);
5497 }
5498
5499 File lastTracesFile = null;
5500 File curTracesFile = null;
5501 for (int i=9; i>=0; i--) {
5502 String name = String.format(Locale.US, "slow%02d.txt", i);
5503 curTracesFile = new File(tracesDir, name);
5504 if (curTracesFile.exists()) {
5505 if (lastTracesFile != null) {
5506 curTracesFile.renameTo(lastTracesFile);
5507 } else {
5508 curTracesFile.delete();
5509 }
5510 }
5511 lastTracesFile = curTracesFile;
5512 }
5513 tracesFile.renameTo(curTracesFile);
5514 } finally {
5515 StrictMode.setThreadPolicy(oldPolicy);
5516 }
5517 }
5518
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005519 final class H extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005520 static final int REPORT_TIME_TRACKER_MSG = 1;
Wale Ogunwale98875612018-10-12 07:53:02 -07005521 static final int FIRST_ACTIVITY_STACK_MSG = 100;
5522 static final int FIRST_SUPERVISOR_STACK_MSG = 200;
Wale Ogunwalef6733932018-06-27 05:14:34 -07005523
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005524 public H(Looper looper) {
5525 super(looper, null, true);
5526 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005527
5528 @Override
5529 public void handleMessage(Message msg) {
5530 switch (msg.what) {
5531 case REPORT_TIME_TRACKER_MSG: {
5532 AppTimeTracker tracker = (AppTimeTracker) msg.obj;
5533 tracker.deliverResult(mContext);
5534 } break;
5535 }
5536 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005537 }
5538
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005539 final class UiHandler extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005540 static final int DISMISS_DIALOG_UI_MSG = 1;
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005541
5542 public UiHandler() {
5543 super(com.android.server.UiThread.get().getLooper(), null, true);
5544 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005545
5546 @Override
5547 public void handleMessage(Message msg) {
5548 switch (msg.what) {
5549 case DISMISS_DIALOG_UI_MSG: {
5550 final Dialog d = (Dialog) msg.obj;
5551 d.dismiss();
5552 break;
5553 }
5554 }
5555 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005556 }
5557
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005558 final class LocalService extends ActivityTaskManagerInternal {
5559 @Override
5560 public SleepToken acquireSleepToken(String tag, int displayId) {
5561 Preconditions.checkNotNull(tag);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005562 return ActivityTaskManagerService.this.acquireSleepToken(tag, displayId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005563 }
5564
5565 @Override
5566 public ComponentName getHomeActivityForUser(int userId) {
5567 synchronized (mGlobalLock) {
Louis Changbd48dca2018-08-29 17:44:34 +08005568 ActivityRecord homeActivity =
5569 mStackSupervisor.getDefaultDisplayHomeActivityForUser(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005570 return homeActivity == null ? null : homeActivity.realActivity;
5571 }
5572 }
5573
5574 @Override
5575 public void onLocalVoiceInteractionStarted(IBinder activity,
5576 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
5577 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005578 onLocalVoiceInteractionStartedLocked(activity, voiceSession, voiceInteractor);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005579 }
5580 }
5581
5582 @Override
5583 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
5584 synchronized (mGlobalLock) {
5585 mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
5586 reasons, timestamp);
5587 }
5588 }
5589
5590 @Override
5591 public void notifyAppTransitionFinished() {
5592 synchronized (mGlobalLock) {
5593 mStackSupervisor.notifyAppTransitionDone();
5594 }
5595 }
5596
5597 @Override
5598 public void notifyAppTransitionCancelled() {
5599 synchronized (mGlobalLock) {
5600 mStackSupervisor.notifyAppTransitionDone();
5601 }
5602 }
5603
5604 @Override
5605 public List<IBinder> getTopVisibleActivities() {
5606 synchronized (mGlobalLock) {
5607 return mStackSupervisor.getTopVisibleActivities();
5608 }
5609 }
5610
5611 @Override
5612 public void notifyDockedStackMinimizedChanged(boolean minimized) {
5613 synchronized (mGlobalLock) {
5614 mStackSupervisor.setDockedStackMinimized(minimized);
5615 }
5616 }
5617
5618 @Override
5619 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
5620 Bundle bOptions) {
5621 Preconditions.checkNotNull(intents, "intents");
5622 final String[] resolvedTypes = new String[intents.length];
5623
5624 // UID of the package on user userId.
5625 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
5626 // packageUid may not be initialized.
5627 int packageUid = 0;
5628 final long ident = Binder.clearCallingIdentity();
5629
5630 try {
5631 for (int i = 0; i < intents.length; i++) {
5632 resolvedTypes[i] =
5633 intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
5634 }
5635
5636 packageUid = AppGlobals.getPackageManager().getPackageUid(
5637 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
5638 } catch (RemoteException e) {
5639 // Shouldn't happen.
5640 } finally {
5641 Binder.restoreCallingIdentity(ident);
5642 }
5643
5644 synchronized (mGlobalLock) {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07005645 return getActivityStartController().startActivitiesInPackage(
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005646 packageUid, packageName,
5647 intents, resolvedTypes, null /* resultTo */,
5648 SafeActivityOptions.fromBundle(bOptions), userId,
Michal Karpinski201bc0c2018-07-20 15:32:00 +01005649 false /* validateIncomingUser */, null /* originatingPendingIntent */);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005650 }
5651 }
5652
5653 @Override
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07005654 public int startActivitiesInPackage(int uid, String callingPackage, Intent[] intents,
5655 String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, int userId,
5656 boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent) {
5657 synchronized (mGlobalLock) {
5658 return getActivityStartController().startActivitiesInPackage(uid, callingPackage,
5659 intents, resolvedTypes, resultTo, options, userId, validateIncomingUser,
5660 originatingPendingIntent);
5661 }
5662 }
5663
5664 @Override
5665 public int startActivityInPackage(int uid, int realCallingPid, int realCallingUid,
5666 String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
5667 String resultWho, int requestCode, int startFlags, SafeActivityOptions options,
5668 int userId, TaskRecord inTask, String reason, boolean validateIncomingUser,
5669 PendingIntentRecord originatingPendingIntent) {
5670 synchronized (mGlobalLock) {
5671 return getActivityStartController().startActivityInPackage(uid, realCallingPid,
5672 realCallingUid, callingPackage, intent, resolvedType, resultTo, resultWho,
5673 requestCode, startFlags, options, userId, inTask, reason,
5674 validateIncomingUser, originatingPendingIntent);
5675 }
5676 }
5677
5678 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005679 public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
5680 Intent intent, Bundle options, int userId) {
5681 return ActivityTaskManagerService.this.startActivityAsUser(
5682 caller, callerPacakge, intent,
5683 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
5684 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
5685 false /*validateIncomingUser*/);
5686 }
5687
5688 @Override
5689 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
5690 synchronized (mGlobalLock) {
5691
5692 // We might change the visibilities here, so prepare an empty app transition which
5693 // might be overridden later if we actually change visibilities.
5694 final boolean wasTransitionSet =
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005695 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005696 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005697 mWindowManager.prepareAppTransition(TRANSIT_NONE,
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005698 false /* alwaysKeepCurrent */);
5699 }
5700 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5701
5702 // If there was a transition set already we don't want to interfere with it as we
5703 // might be starting it too early.
5704 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005705 mWindowManager.executeAppTransition();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005706 }
5707 }
5708 if (callback != null) {
5709 callback.run();
5710 }
5711 }
5712
5713 @Override
5714 public void notifyKeyguardTrustedChanged() {
5715 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005716 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005717 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5718 }
5719 }
5720 }
5721
5722 /**
5723 * Called after virtual display Id is updated by
5724 * {@link com.android.server.vr.Vr2dDisplay} with a specific
5725 * {@param vrVr2dDisplayId}.
5726 */
5727 @Override
5728 public void setVr2dDisplayId(int vr2dDisplayId) {
5729 if (DEBUG_STACK) Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
5730 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005731 mVr2dDisplayId = vr2dDisplayId;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005732 }
5733 }
5734
5735 @Override
5736 public void setFocusedActivity(IBinder token) {
5737 synchronized (mGlobalLock) {
5738 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
5739 if (r == null) {
5740 throw new IllegalArgumentException(
5741 "setFocusedActivity: No activity record matching token=" + token);
5742 }
Louis Chang19443452018-10-09 12:10:21 +08005743 if (r.moveFocusableActivityToTop("setFocusedActivity")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08005744 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005745 }
5746 }
5747 }
5748
5749 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005750 public void registerScreenObserver(ScreenObserver observer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005751 mScreenObservers.add(observer);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005752 }
5753
5754 @Override
5755 public boolean isCallerRecents(int callingUid) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005756 return getRecentTasks().isCallerRecents(callingUid);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005757 }
5758
5759 @Override
5760 public boolean isRecentsComponentHomeActivity(int userId) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005761 return getRecentTasks().isRecentsComponentHomeActivity(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005762 }
5763
5764 @Override
5765 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
5766 ActivityTaskManagerService.this.cancelRecentsAnimation(restoreHomeStackPosition);
5767 }
5768
5769 @Override
5770 public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005771 ActivityTaskManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005772 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005773
5774 @Override
5775 public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
5776 synchronized (mGlobalLock) {
5777 mActiveVoiceInteractionServiceComponent = component;
5778 }
5779 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005780
5781 @Override
5782 public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
5783 if (!mAmInternal.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
5784 return;
5785 }
5786 synchronized (mGlobalLock) {
5787 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
5788 if (types == null) {
5789 if (uid < 0) {
5790 return;
5791 }
5792 types = new ArrayMap<>();
5793 mAllowAppSwitchUids.put(userId, types);
5794 }
5795 if (uid < 0) {
5796 types.remove(type);
5797 } else {
5798 types.put(type, uid);
5799 }
5800 }
5801 }
5802
5803 @Override
5804 public void onUserStopped(int userId) {
5805 synchronized (mGlobalLock) {
5806 getRecentTasks().unloadUserDataFromMemoryLocked(userId);
5807 mAllowAppSwitchUids.remove(userId);
5808 }
5809 }
5810
5811 @Override
5812 public boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
5813 synchronized (mGlobalLock) {
5814 return ActivityTaskManagerService.this.isGetTasksAllowed(
5815 caller, callingPid, callingUid);
5816 }
5817 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005818
5819 @Override
5820 public void onProcessAdded(WindowProcessController proc) {
5821 synchronized (mGlobalLock) {
5822 mProcessNames.put(proc.mName, proc.mUid, proc);
5823 }
5824 }
5825
5826 @Override
5827 public void onProcessRemoved(String name, int uid) {
5828 synchronized (mGlobalLock) {
5829 mProcessNames.remove(name, uid);
5830 }
5831 }
5832
5833 @Override
5834 public void onCleanUpApplicationRecord(WindowProcessController proc) {
5835 synchronized (mGlobalLock) {
5836 if (proc == mHomeProcess) {
5837 mHomeProcess = null;
5838 }
5839 if (proc == mPreviousProcess) {
5840 mPreviousProcess = null;
5841 }
5842 }
5843 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005844
5845 @Override
5846 public int getTopProcessState() {
5847 synchronized (mGlobalLock) {
5848 return mTopProcessState;
5849 }
5850 }
5851
5852 @Override
Wale Ogunwale53783742018-09-16 10:21:51 -07005853 public boolean isHeavyWeightProcess(WindowProcessController proc) {
5854 synchronized (mGlobalLock) {
5855 return proc == mHeavyWeightProcess;
5856 }
5857 }
5858
5859 @Override
5860 public void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
5861 synchronized (mGlobalLock) {
5862 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(proc);
5863 }
5864 }
5865
5866 @Override
5867 public void finishHeavyWeightApp() {
5868 synchronized (mGlobalLock) {
Sudheer Shankaee1da272018-10-20 20:11:44 -07005869 if (mHeavyWeightProcess != null) {
5870 mHeavyWeightProcess.finishActivities();
5871 }
Wale Ogunwale53783742018-09-16 10:21:51 -07005872 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(
5873 mHeavyWeightProcess);
5874 }
5875 }
5876
5877 @Override
Wale Ogunwalef6733932018-06-27 05:14:34 -07005878 public boolean isSleeping() {
5879 synchronized (mGlobalLock) {
5880 return isSleepingLocked();
5881 }
5882 }
5883
5884 @Override
5885 public boolean isShuttingDown() {
5886 synchronized (mGlobalLock) {
5887 return mShuttingDown;
5888 }
5889 }
5890
5891 @Override
5892 public boolean shuttingDown(boolean booted, int timeout) {
5893 synchronized (mGlobalLock) {
5894 mShuttingDown = true;
5895 mStackSupervisor.prepareForShutdownLocked();
5896 updateEventDispatchingLocked(booted);
5897 return mStackSupervisor.shutdownLocked(timeout);
5898 }
5899 }
5900
5901 @Override
5902 public void enableScreenAfterBoot(boolean booted) {
5903 synchronized (mGlobalLock) {
5904 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5905 SystemClock.uptimeMillis());
5906 mWindowManager.enableScreenAfterBoot();
5907 updateEventDispatchingLocked(booted);
5908 }
5909 }
5910
5911 @Override
5912 public boolean showStrictModeViolationDialog() {
5913 synchronized (mGlobalLock) {
5914 return mShowDialogs && !mSleeping && !mShuttingDown;
5915 }
5916 }
5917
5918 @Override
5919 public void showSystemReadyErrorDialogsIfNeeded() {
5920 synchronized (mGlobalLock) {
5921 try {
5922 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
5923 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
5924 + " data partition or your device will be unstable.");
5925 mUiHandler.post(() -> {
5926 if (mShowDialogs) {
5927 AlertDialog d = new BaseErrorDialog(mUiContext);
5928 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5929 d.setCancelable(false);
5930 d.setTitle(mUiContext.getText(R.string.android_system_label));
5931 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
5932 d.setButton(DialogInterface.BUTTON_POSITIVE,
5933 mUiContext.getText(R.string.ok),
5934 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5935 d.show();
5936 }
5937 });
5938 }
5939 } catch (RemoteException e) {
5940 }
5941
5942 if (!Build.isBuildConsistent()) {
5943 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
5944 mUiHandler.post(() -> {
5945 if (mShowDialogs) {
5946 AlertDialog d = new BaseErrorDialog(mUiContext);
5947 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5948 d.setCancelable(false);
5949 d.setTitle(mUiContext.getText(R.string.android_system_label));
5950 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
5951 d.setButton(DialogInterface.BUTTON_POSITIVE,
5952 mUiContext.getText(R.string.ok),
5953 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5954 d.show();
5955 }
5956 });
5957 }
5958 }
5959 }
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005960
5961 @Override
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005962 public void onProcessMapped(int pid, WindowProcessController proc) {
5963 synchronized (mGlobalLock) {
5964 mPidMap.put(pid, proc);
5965 }
5966 }
5967
5968 @Override
5969 public void onProcessUnMapped(int pid) {
5970 synchronized (mGlobalLock) {
5971 mPidMap.remove(pid);
5972 }
5973 }
Wale Ogunwale008163e2018-07-23 23:11:08 -07005974
5975 @Override
5976 public void onPackageDataCleared(String name) {
5977 synchronized (mGlobalLock) {
Wale Ogunwale53783742018-09-16 10:21:51 -07005978 mCompatModePackages.handlePackageDataClearedLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07005979 mAppWarnings.onPackageDataCleared(name);
5980 }
5981 }
5982
5983 @Override
5984 public void onPackageUninstalled(String name) {
5985 synchronized (mGlobalLock) {
5986 mAppWarnings.onPackageUninstalled(name);
Wale Ogunwale53783742018-09-16 10:21:51 -07005987 mCompatModePackages.handlePackageUninstalledLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07005988 }
5989 }
Wale Ogunwale53783742018-09-16 10:21:51 -07005990
5991 @Override
5992 public void onPackageAdded(String name, boolean replacing) {
5993 synchronized (mGlobalLock) {
5994 mCompatModePackages.handlePackageAddedLocked(name, replacing);
5995 }
5996 }
5997
5998 @Override
Wale Ogunwale31913b52018-10-13 08:29:31 -07005999 public void onPackageReplaced(ApplicationInfo aInfo) {
6000 synchronized (mGlobalLock) {
6001 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
6002 }
6003 }
6004
6005 @Override
Wale Ogunwale53783742018-09-16 10:21:51 -07006006 public CompatibilityInfo compatibilityInfoForPackage(ApplicationInfo ai) {
6007 synchronized (mGlobalLock) {
6008 return compatibilityInfoForPackageLocked(ai);
6009 }
6010 }
6011
Yunfan Chen75157d72018-07-27 14:47:21 +09006012 /**
6013 * Set the corresponding display information for the process global configuration. To be
6014 * called when we need to show IME on a different display.
6015 *
6016 * @param pid The process id associated with the IME window.
6017 * @param displayId The ID of the display showing the IME.
6018 */
6019 @Override
Yunfan Chen79b96062018-10-17 12:45:23 -07006020 public void onImeWindowSetOnDisplay(final int pid, final int displayId) {
Yunfan Chen75157d72018-07-27 14:47:21 +09006021 if (pid == MY_PID || pid < 0) {
6022 if (DEBUG_CONFIGURATION) {
6023 Slog.w(TAG,
6024 "Trying to update display configuration for system/invalid process.");
6025 }
6026 return;
6027 }
6028 mH.post(() -> {
6029 synchronized (mGlobalLock) {
Yunfan Chen79b96062018-10-17 12:45:23 -07006030 final ActivityDisplay activityDisplay =
6031 mStackSupervisor.getActivityDisplay(displayId);
6032 if (activityDisplay == null) {
6033 // Call might come when display is not yet added or has been removed.
Yunfan Chen75157d72018-07-27 14:47:21 +09006034 if (DEBUG_CONFIGURATION) {
6035 Slog.w(TAG, "Trying to update display configuration for non-existing "
Yunfan Chen79b96062018-10-17 12:45:23 -07006036 + "displayId=" + displayId);
Yunfan Chen75157d72018-07-27 14:47:21 +09006037 }
6038 return;
6039 }
Yunfan Chen79b96062018-10-17 12:45:23 -07006040 final WindowProcessController process = mPidMap.get(pid);
6041 if (process == null) {
Yunfan Chen75157d72018-07-27 14:47:21 +09006042 if (DEBUG_CONFIGURATION) {
Yunfan Chen79b96062018-10-17 12:45:23 -07006043 Slog.w(TAG, "Trying to update display configuration for invalid "
6044 + "process, pid=" + pid);
Yunfan Chen75157d72018-07-27 14:47:21 +09006045 }
6046 return;
6047 }
Yunfan Chen79b96062018-10-17 12:45:23 -07006048 process.registerDisplayConfigurationListenerLocked(activityDisplay);
Yunfan Chen75157d72018-07-27 14:47:21 +09006049 }
6050 });
Yunfan Chen79b96062018-10-17 12:45:23 -07006051
Yunfan Chen75157d72018-07-27 14:47:21 +09006052 }
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07006053
6054 @Override
6055 public void sendActivityResult(int callingUid, IBinder activityToken, String resultWho,
6056 int requestCode, int resultCode, Intent data) {
6057 synchronized (mGlobalLock) {
6058 final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
6059 if (r != null && r.getStack() != null) {
6060 r.getStack().sendActivityResultLocked(callingUid, r, resultWho, requestCode,
6061 resultCode, data);
6062 }
6063 }
6064 }
6065
6066 @Override
6067 public void clearPendingResultForActivity(IBinder activityToken,
6068 WeakReference<PendingIntentRecord> pir) {
6069 synchronized (mGlobalLock) {
6070 final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
6071 if (r != null && r.pendingResults != null) {
6072 r.pendingResults.remove(pir);
6073 }
6074 }
6075 }
6076
6077 @Override
6078 public IIntentSender getIntentSender(int type, String packageName,
6079 int callingUid, int userId, IBinder token, String resultWho,
6080 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6081 Bundle bOptions) {
6082 synchronized (mGlobalLock) {
6083 return getIntentSenderLocked(type, packageName, callingUid, userId, token,
6084 resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6085 }
6086 }
Wale Ogunwalec4e63a42018-10-02 13:19:54 -07006087
6088 @Override
6089 public ActivityServiceConnectionsHolder getServiceConnectionsHolder(IBinder token) {
6090 synchronized (mGlobalLock) {
6091 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
6092 if (r == null) {
6093 return null;
6094 }
6095 if (r.mServiceConnectionsHolder == null) {
6096 r.mServiceConnectionsHolder = new ActivityServiceConnectionsHolder(
6097 ActivityTaskManagerService.this, r);
6098 }
6099
6100 return r.mServiceConnectionsHolder;
6101 }
6102 }
Wale Ogunwale214f3482018-10-04 11:00:47 -07006103
6104 @Override
6105 public Intent getHomeIntent() {
6106 synchronized (mGlobalLock) {
6107 return ActivityTaskManagerService.this.getHomeIntent();
6108 }
6109 }
6110
6111 @Override
6112 public boolean startHomeActivity(int userId, String reason) {
6113 synchronized (mGlobalLock) {
6114 return startHomeActivityLocked(userId, reason, DEFAULT_DISPLAY);
6115 }
6116 }
6117
6118 @Override
6119 public boolean isFactoryTestProcess(WindowProcessController wpc) {
6120 synchronized (mGlobalLock) {
6121 if (mFactoryTest == FACTORY_TEST_OFF) {
6122 return false;
6123 }
6124 if (mFactoryTest == FACTORY_TEST_LOW_LEVEL && mTopComponent != null
6125 && wpc.mName.equals(mTopComponent.getPackageName())) {
6126 return true;
6127 }
6128 return mFactoryTest == FACTORY_TEST_HIGH_LEVEL
6129 && (wpc.mInfo.flags & FLAG_FACTORY_TEST) != 0;
6130 }
6131 }
6132
6133 @Override
6134 public void updateTopComponentForFactoryTest() {
6135 synchronized (mGlobalLock) {
6136 if (mFactoryTest != FACTORY_TEST_LOW_LEVEL) {
6137 return;
6138 }
6139 final ResolveInfo ri = mContext.getPackageManager()
6140 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), STOCK_PM_FLAGS);
6141 final CharSequence errorMsg;
6142 if (ri != null) {
6143 final ActivityInfo ai = ri.activityInfo;
6144 final ApplicationInfo app = ai.applicationInfo;
6145 if ((app.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
6146 mTopAction = Intent.ACTION_FACTORY_TEST;
6147 mTopData = null;
6148 mTopComponent = new ComponentName(app.packageName, ai.name);
6149 errorMsg = null;
6150 } else {
6151 errorMsg = mContext.getResources().getText(
6152 com.android.internal.R.string.factorytest_not_system);
6153 }
6154 } else {
6155 errorMsg = mContext.getResources().getText(
6156 com.android.internal.R.string.factorytest_no_action);
6157 }
6158 if (errorMsg == null) {
6159 return;
6160 }
6161
6162 mTopAction = null;
6163 mTopData = null;
6164 mTopComponent = null;
6165 mUiHandler.post(() -> {
6166 Dialog d = new FactoryErrorDialog(mUiContext, errorMsg);
6167 d.show();
Wale Ogunwale342fbe92018-10-09 08:44:10 -07006168 mAmInternal.ensureBootCompleted();
Wale Ogunwale214f3482018-10-04 11:00:47 -07006169 });
6170 }
6171 }
Wale Ogunwale31913b52018-10-13 08:29:31 -07006172
6173 @Override
6174 public void handleAppDied(WindowProcessController wpc, boolean restarting,
6175 Runnable finishInstrumentationCallback) {
6176 synchronized (mGlobalLock) {
6177 // Remove this application's activities from active lists.
6178 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(wpc);
6179
6180 wpc.clearRecentTasks();
6181 wpc.clearActivities();
6182
6183 if (wpc.isInstrumenting()) {
6184 finishInstrumentationCallback.run();
6185 }
6186
6187 mWindowManager.deferSurfaceLayout();
6188 try {
6189 if (!restarting && hasVisibleActivities
6190 && !mStackSupervisor.resumeFocusedStacksTopActivitiesLocked()) {
6191 // If there was nothing to resume, and we are not already restarting this
6192 // process, but there is a visible activity that is hosted by the process...
6193 // then make sure all visible activities are running, taking care of
6194 // restarting this process.
6195 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6196 }
6197 } finally {
6198 mWindowManager.continueSurfaceLayout();
6199 }
6200 }
6201 }
6202
6203 @Override
6204 public void closeSystemDialogs(String reason) {
6205 enforceNotIsolatedCaller("closeSystemDialogs");
6206
6207 final int pid = Binder.getCallingPid();
6208 final int uid = Binder.getCallingUid();
6209 final long origId = Binder.clearCallingIdentity();
6210 try {
6211 synchronized (mGlobalLock) {
6212 // Only allow this from foreground processes, so that background
6213 // applications can't abuse it to prevent system UI from being shown.
6214 if (uid >= FIRST_APPLICATION_UID) {
6215 final WindowProcessController proc = mPidMap.get(pid);
6216 if (!proc.isPerceptible()) {
6217 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6218 + " from background process " + proc);
6219 return;
6220 }
6221 }
Wale Ogunwale31913b52018-10-13 08:29:31 -07006222 mWindowManager.closeSystemDialogs(reason);
6223
6224 mStackSupervisor.closeSystemDialogsLocked();
Wale Ogunwale31913b52018-10-13 08:29:31 -07006225 }
Wale Ogunwale2ea36d42018-10-18 10:27:31 -07006226 // Call into AM outside the synchronized block.
6227 mAmInternal.broadcastCloseSystemDialogs(reason);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006228 } finally {
6229 Binder.restoreCallingIdentity(origId);
6230 }
6231 }
6232
6233 @Override
6234 public void cleanupDisabledPackageComponents(
6235 String packageName, Set<String> disabledClasses, int userId, boolean booted) {
6236 synchronized (mGlobalLock) {
6237 // Clean-up disabled activities.
6238 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6239 packageName, disabledClasses, true, false, userId) && booted) {
6240 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
6241 mStackSupervisor.scheduleIdleLocked();
6242 }
6243
6244 // Clean-up disabled tasks
6245 getRecentTasks().cleanupDisabledPackageTasksLocked(
6246 packageName, disabledClasses, userId);
6247 }
6248 }
6249
6250 @Override
6251 public boolean onForceStopPackage(String packageName, boolean doit, boolean evenPersistent,
6252 int userId) {
6253 synchronized (mGlobalLock) {
6254
6255 boolean didSomething =
6256 getActivityStartController().clearPendingActivityLaunches(packageName);
6257 didSomething |= mStackSupervisor.finishDisabledPackageActivitiesLocked(packageName,
6258 null, doit, evenPersistent, userId);
6259 return didSomething;
6260 }
6261 }
6262
6263 @Override
6264 public void resumeTopActivities(boolean scheduleIdle) {
6265 synchronized (mGlobalLock) {
6266 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
6267 if (scheduleIdle) {
6268 mStackSupervisor.scheduleIdleLocked();
6269 }
6270 }
6271 }
6272
6273 @Override
6274 public void preBindApplication(WindowProcessController wpc) {
6275 synchronized (mGlobalLock) {
6276 mStackSupervisor.getActivityMetricsLogger().notifyBindApplication(wpc.mInfo);
6277 }
6278 }
6279
6280 @Override
6281 public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
6282 synchronized (mGlobalLock) {
6283 return mStackSupervisor.attachApplicationLocked(wpc);
6284 }
6285 }
6286
6287 @Override
6288 public void notifyLockedProfile(@UserIdInt int userId, int currentUserId) {
6289 try {
6290 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
6291 throw new SecurityException("Only privileged app can call notifyLockedProfile");
6292 }
6293 } catch (RemoteException ex) {
6294 throw new SecurityException("Fail to check is caller a privileged app", ex);
6295 }
6296
6297 synchronized (mGlobalLock) {
6298 final long ident = Binder.clearCallingIdentity();
6299 try {
6300 if (mAmInternal.shouldConfirmCredentials(userId)) {
6301 if (mKeyguardController.isKeyguardLocked()) {
6302 // Showing launcher to avoid user entering credential twice.
6303 startHomeActivity(currentUserId, "notifyLockedProfile");
6304 }
6305 mStackSupervisor.lockAllProfileTasks(userId);
6306 }
6307 } finally {
6308 Binder.restoreCallingIdentity(ident);
6309 }
6310 }
6311 }
6312
6313 @Override
6314 public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
6315 mAmInternal.enforceCallingPermission(
6316 MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
6317
6318 synchronized (mGlobalLock) {
6319 final long ident = Binder.clearCallingIdentity();
6320 try {
6321 intent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
6322 FLAG_ACTIVITY_TASK_ON_HOME);
6323 ActivityOptions activityOptions = options != null
6324 ? new ActivityOptions(options) : ActivityOptions.makeBasic();
6325 activityOptions.setLaunchTaskId(
6326 mStackSupervisor.getDefaultDisplayHomeActivity().getTask().taskId);
6327 mContext.startActivityAsUser(intent, activityOptions.toBundle(),
6328 UserHandle.CURRENT);
6329 } finally {
6330 Binder.restoreCallingIdentity(ident);
6331 }
6332 }
6333 }
6334
6335 @Override
6336 public void writeActivitiesToProto(ProtoOutputStream proto) {
6337 synchronized (mGlobalLock) {
6338 // The output proto of "activity --proto activities"
6339 // is ActivityManagerServiceDumpActivitiesProto
6340 mStackSupervisor.writeToProto(proto,
6341 ActivityManagerServiceDumpActivitiesProto.ACTIVITY_STACK_SUPERVISOR);
6342 }
6343 }
6344
6345 @Override
6346 public void saveANRState(String reason) {
6347 synchronized (mGlobalLock) {
6348 final StringWriter sw = new StringWriter();
6349 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
6350 pw.println(" ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
6351 if (reason != null) {
6352 pw.println(" Reason: " + reason);
6353 }
6354 pw.println();
6355 getActivityStartController().dump(pw, " ", null);
6356 pw.println();
6357 pw.println("-------------------------------------------------------------------------------");
6358 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
6359 true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
6360 "" /* header */);
6361 pw.println();
6362 pw.close();
6363
6364 mLastANRState = sw.toString();
6365 }
6366 }
6367
6368 @Override
6369 public void clearSavedANRState() {
6370 synchronized (mGlobalLock) {
6371 mLastANRState = null;
6372 }
6373 }
6374
6375 @Override
6376 public void dump(String cmd, FileDescriptor fd, PrintWriter pw, String[] args, int opti,
6377 boolean dumpAll, boolean dumpClient, String dumpPackage) {
6378 synchronized (mGlobalLock) {
6379 if (DUMP_ACTIVITIES_CMD.equals(cmd) || DUMP_ACTIVITIES_SHORT_CMD.equals(cmd)) {
6380 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
6381 } else if (DUMP_LASTANR_CMD.equals(cmd)) {
6382 dumpLastANRLocked(pw);
6383 } else if (DUMP_LASTANR_TRACES_CMD.equals(cmd)) {
6384 dumpLastANRTracesLocked(pw);
6385 } else if (DUMP_STARTER_CMD.equals(cmd)) {
6386 dumpActivityStarterLocked(pw, dumpPackage);
6387 } else if (DUMP_CONTAINERS_CMD.equals(cmd)) {
6388 dumpActivityContainersLocked(pw);
6389 } else if (DUMP_RECENTS_CMD.equals(cmd) || DUMP_RECENTS_SHORT_CMD.equals(cmd)) {
6390 if (getRecentTasks() != null) {
6391 getRecentTasks().dump(pw, dumpAll, dumpPackage);
6392 }
6393 }
6394 }
6395 }
6396
6397 @Override
6398 public boolean dumpForProcesses(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
6399 String dumpPackage, int dumpAppId, boolean needSep, boolean testPssMode,
6400 int wakefulness) {
6401 synchronized (mGlobalLock) {
6402 if (mHomeProcess != null && (dumpPackage == null
6403 || mHomeProcess.mPkgList.contains(dumpPackage))) {
6404 if (needSep) {
6405 pw.println();
6406 needSep = false;
6407 }
6408 pw.println(" mHomeProcess: " + mHomeProcess);
6409 }
6410 if (mPreviousProcess != null && (dumpPackage == null
6411 || mPreviousProcess.mPkgList.contains(dumpPackage))) {
6412 if (needSep) {
6413 pw.println();
6414 needSep = false;
6415 }
6416 pw.println(" mPreviousProcess: " + mPreviousProcess);
6417 }
6418 if (dumpAll && (mPreviousProcess == null || dumpPackage == null
6419 || mPreviousProcess.mPkgList.contains(dumpPackage))) {
6420 StringBuilder sb = new StringBuilder(128);
6421 sb.append(" mPreviousProcessVisibleTime: ");
6422 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
6423 pw.println(sb);
6424 }
6425 if (mHeavyWeightProcess != null && (dumpPackage == null
6426 || mHeavyWeightProcess.mPkgList.contains(dumpPackage))) {
6427 if (needSep) {
6428 pw.println();
6429 needSep = false;
6430 }
6431 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
6432 }
6433 if (dumpPackage == null) {
6434 pw.println(" mGlobalConfiguration: " + getGlobalConfiguration());
6435 mStackSupervisor.dumpDisplayConfigs(pw, " ");
6436 }
6437 if (dumpAll) {
6438 if (dumpPackage == null) {
6439 pw.println(" mConfigWillChange: "
6440 + getTopDisplayFocusedStack().mConfigWillChange);
6441 }
6442 if (mCompatModePackages.getPackages().size() > 0) {
6443 boolean printed = false;
6444 for (Map.Entry<String, Integer> entry
6445 : mCompatModePackages.getPackages().entrySet()) {
6446 String pkg = entry.getKey();
6447 int mode = entry.getValue();
6448 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
6449 continue;
6450 }
6451 if (!printed) {
6452 pw.println(" mScreenCompatPackages:");
6453 printed = true;
6454 }
6455 pw.println(" " + pkg + ": " + mode);
6456 }
6457 }
6458 }
6459
6460 if (dumpPackage == null) {
6461 pw.println(" mWakefulness="
6462 + PowerManagerInternal.wakefulnessToString(wakefulness));
6463 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
6464 if (mRunningVoice != null) {
6465 pw.println(" mRunningVoice=" + mRunningVoice);
6466 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
6467 }
6468 pw.println(" mSleeping=" + mSleeping);
6469 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + testPssMode);
6470 pw.println(" mVrController=" + mVrController);
6471 }
6472 if (mCurAppTimeTracker != null) {
6473 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
6474 }
6475 if (mAllowAppSwitchUids.size() > 0) {
6476 boolean printed = false;
6477 for (int i = 0; i < mAllowAppSwitchUids.size(); i++) {
6478 ArrayMap<String, Integer> types = mAllowAppSwitchUids.valueAt(i);
6479 for (int j = 0; j < types.size(); j++) {
6480 if (dumpPackage == null ||
6481 UserHandle.getAppId(types.valueAt(j).intValue()) == dumpAppId) {
6482 if (needSep) {
6483 pw.println();
6484 needSep = false;
6485 }
6486 if (!printed) {
6487 pw.println(" mAllowAppSwitchUids:");
6488 printed = true;
6489 }
6490 pw.print(" User ");
6491 pw.print(mAllowAppSwitchUids.keyAt(i));
6492 pw.print(": Type ");
6493 pw.print(types.keyAt(j));
6494 pw.print(" = ");
6495 UserHandle.formatUid(pw, types.valueAt(j).intValue());
6496 pw.println();
6497 }
6498 }
6499 }
6500 }
6501 if (dumpPackage == null) {
6502 if (mController != null) {
6503 pw.println(" mController=" + mController
6504 + " mControllerIsAMonkey=" + mControllerIsAMonkey);
6505 }
6506 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
6507 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
6508 }
6509
6510 return needSep;
6511 }
6512 }
6513
6514 @Override
6515 public void writeProcessesToProto(ProtoOutputStream proto, String dumpPackage) {
6516 synchronized (mGlobalLock) {
6517 if (dumpPackage == null) {
6518 getGlobalConfiguration().writeToProto(proto, GLOBAL_CONFIGURATION);
6519 proto.write(CONFIG_WILL_CHANGE, getTopDisplayFocusedStack().mConfigWillChange);
6520 writeSleepStateToProto(proto);
6521 if (mController != null) {
6522 final long token = proto.start(CONTROLLER);
6523 proto.write(CONTROLLER, mController.toString());
6524 proto.write(IS_A_MONKEY, mControllerIsAMonkey);
6525 proto.end(token);
6526 }
6527 mStackSupervisor.mGoingToSleep.writeToProto(proto, GOING_TO_SLEEP);
6528 mStackSupervisor.mLaunchingActivity.writeToProto(proto, LAUNCHING_ACTIVITY);
6529 }
6530
6531 if (mHomeProcess != null && (dumpPackage == null
6532 || mHomeProcess.mPkgList.contains(dumpPackage))) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07006533 mHomeProcess.writeToProto(proto, HOME_PROC);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006534 }
6535
6536 if (mPreviousProcess != null && (dumpPackage == null
6537 || mPreviousProcess.mPkgList.contains(dumpPackage))) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07006538 mPreviousProcess.writeToProto(proto, PREVIOUS_PROC);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006539 proto.write(PREVIOUS_PROC_VISIBLE_TIME_MS, mPreviousProcessVisibleTime);
6540 }
6541
6542 if (mHeavyWeightProcess != null && (dumpPackage == null
6543 || mHeavyWeightProcess.mPkgList.contains(dumpPackage))) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07006544 mHeavyWeightProcess.writeToProto(proto, HEAVY_WEIGHT_PROC);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006545 }
6546
6547 for (Map.Entry<String, Integer> entry
6548 : mCompatModePackages.getPackages().entrySet()) {
6549 String pkg = entry.getKey();
6550 int mode = entry.getValue();
6551 if (dumpPackage == null || dumpPackage.equals(pkg)) {
6552 long compatToken = proto.start(SCREEN_COMPAT_PACKAGES);
6553 proto.write(PACKAGE, pkg);
6554 proto.write(MODE, mode);
6555 proto.end(compatToken);
6556 }
6557 }
6558
6559 if (mCurAppTimeTracker != null) {
6560 mCurAppTimeTracker.writeToProto(proto, CURRENT_TRACKER, true);
6561 }
6562
6563 }
6564 }
6565
6566 @Override
6567 public boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name,
6568 String[] args, int opti, boolean dumpAll, boolean dumpVisibleStacksOnly,
6569 boolean dumpFocusedStackOnly) {
6570 synchronized (mGlobalLock) {
6571 return ActivityTaskManagerService.this.dumpActivity(fd, pw, name, args, opti,
6572 dumpAll, dumpVisibleStacksOnly, dumpFocusedStackOnly);
6573 }
6574 }
6575
6576 @Override
6577 public boolean canGcNow() {
6578 synchronized (mGlobalLock) {
6579 return isSleeping() || mStackSupervisor.allResumedActivitiesIdle();
6580 }
6581 }
6582
6583 @Override
6584 public WindowProcessController getTopApp() {
6585 synchronized (mGlobalLock) {
6586 final ActivityRecord top = mStackSupervisor.getTopResumedActivity();
6587 return top != null ? top.app : null;
6588 }
6589 }
6590
6591 @Override
6592 public void rankTaskLayersIfNeeded() {
6593 synchronized (mGlobalLock) {
6594 if (mStackSupervisor != null) {
6595 mStackSupervisor.rankTaskLayersIfNeeded();
6596 }
6597 }
6598 }
6599
6600 @Override
6601 public void scheduleDestroyAllActivities(String reason) {
6602 synchronized (mGlobalLock) {
6603 mStackSupervisor.scheduleDestroyAllActivities(null, reason);
6604 }
6605 }
6606
6607 @Override
6608 public void removeUser(int userId) {
6609 synchronized (mGlobalLock) {
6610 mStackSupervisor.removeUserLocked(userId);
6611 }
6612 }
6613
6614 @Override
6615 public boolean switchUser(int userId, UserState userState) {
6616 synchronized (mGlobalLock) {
6617 return mStackSupervisor.switchUserLocked(userId, userState);
6618 }
6619 }
6620
6621 @Override
6622 public void onHandleAppCrash(WindowProcessController wpc) {
6623 synchronized (mGlobalLock) {
6624 mStackSupervisor.handleAppCrashLocked(wpc);
6625 }
6626 }
Wale Ogunwale64258362018-10-16 15:13:37 -07006627
6628 @Override
6629 public int finishTopCrashedActivities(WindowProcessController crashedApp, String reason) {
6630 synchronized (mGlobalLock) {
6631 return mStackSupervisor.finishTopCrashedActivitiesLocked(crashedApp, reason);
6632 }
6633 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07006634 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07006635}