blob: 2790687822e578ce890902164ca0973b1c08e083 [file] [log] [blame]
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
Wale Ogunwale59507092018-10-29 09:00:30 -070017package com.android.server.wm;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070018
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070019import static android.Manifest.permission.BIND_VOICE_INTERACTION;
20import static android.Manifest.permission.CHANGE_CONFIGURATION;
21import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
22import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070023import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070024import static android.Manifest.permission.READ_FRAME_BUFFER;
25import static android.Manifest.permission.REMOVE_TASKS;
26import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070027import static android.Manifest.permission.STOP_APP_SWITCHES;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070028import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
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.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
59import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
60import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
Evan Rosky4505b352018-09-06 11:20:40 -070061import static android.provider.Settings.Global.HIDE_ERROR_DIALOGS;
62import static android.provider.Settings.System.FONT_SCALE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070063import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
Alison Cichowlas3e340502018-08-07 17:15:01 -040064import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070065import static android.view.Display.DEFAULT_DISPLAY;
66import static android.view.Display.INVALID_DISPLAY;
Wale Ogunwale6767eae2018-05-03 15:52:51 -070067import static android.view.WindowManager.TRANSIT_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070068import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
Evan Rosky4505b352018-09-06 11:20:40 -070069
Yunfan Chen79b96062018-10-17 12:45:23 -070070import static com.android.server.am.ActivityManagerService.ANR_TRACE_DIR;
71import static com.android.server.am.ActivityManagerService.MY_PID;
72import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS;
73import static com.android.server.am.ActivityManagerService.dumpStackTraces;
Wale Ogunwale31913b52018-10-13 08:29:31 -070074import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.CONFIG_WILL_CHANGE;
75import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.CONTROLLER;
76import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.CURRENT_TRACKER;
77import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.Controller.IS_A_MONKEY;
78import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.GLOBAL_CONFIGURATION;
79import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.GOING_TO_SLEEP;
80import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.HEAVY_WEIGHT_PROC;
81import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.HOME_PROC;
82import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.LAUNCHING_ACTIVITY;
83import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC;
Yunfan Chen279f5582018-12-12 15:24:50 -080084import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC_VISIBLE_TIME_MS;
Wale Ogunwale31913b52018-10-13 08:29:31 -070085import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.SCREEN_COMPAT_PACKAGES;
Yunfan Chen279f5582018-12-12 15:24:50 -080086import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.MODE;
87import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.PACKAGE;
Wale Ogunwale59507092018-10-29 09:00:30 -070088import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
89import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME;
Wale Ogunwale59507092018-10-29 09:00:30 -070090import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
91import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
92import static com.android.server.wm.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
93import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ALL;
94import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
95import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_FOCUS;
96import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_IMMERSIVE;
97import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_LOCKTASK;
98import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STACK;
99import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
100import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
101import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_VISIBILITY;
102import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
103import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS;
104import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_IMMERSIVE;
105import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_LOCKTASK;
106import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STACK;
107import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH;
108import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_VISIBILITY;
109import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
110import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
Evan Rosky4505b352018-09-06 11:20:40 -0700111import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT;
112import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_DATA;
113import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
114import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;
wilsonshihe7903ea2018-09-26 16:17:59 +0800115import static com.android.server.wm.ActivityTaskManagerService.H.REPORT_TIME_TRACKER_MSG;
116import static com.android.server.wm.ActivityTaskManagerService.UiHandler.DISMISS_DIALOG_UI_MSG;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700117import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
118import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800119import static com.android.server.wm.RootActivityContainer.MATCH_TASK_IN_STACKS_ONLY;
120import static com.android.server.wm.RootActivityContainer.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
wilsonshihe7903ea2018-09-26 16:17:59 +0800121import static com.android.server.wm.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
122import static com.android.server.wm.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
123import static com.android.server.wm.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700124
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700125import android.Manifest;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700126import android.annotation.NonNull;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700127import android.annotation.Nullable;
128import android.annotation.UserIdInt;
129import android.app.Activity;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700130import android.app.ActivityManager;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700131import android.app.ActivityManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700132import android.app.ActivityOptions;
133import android.app.ActivityTaskManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700134import android.app.ActivityThread;
135import android.app.AlertDialog;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700136import android.app.AppGlobals;
Evan Rosky4505b352018-09-06 11:20:40 -0700137import android.app.Dialog;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700138import android.app.IActivityController;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700139import android.app.IActivityTaskManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700140import android.app.IApplicationThread;
141import android.app.IAssistDataReceiver;
Wale Ogunwale53783742018-09-16 10:21:51 -0700142import android.app.INotificationManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700143import android.app.ITaskStackListener;
Wale Ogunwale53783742018-09-16 10:21:51 -0700144import android.app.Notification;
145import android.app.NotificationManager;
146import android.app.PendingIntent;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700147import android.app.PictureInPictureParams;
148import android.app.ProfilerInfo;
149import android.app.RemoteAction;
150import android.app.WaitResult;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700151import android.app.WindowConfiguration;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700152import android.app.admin.DevicePolicyCache;
153import android.app.assist.AssistContent;
154import android.app.assist.AssistStructure;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700155import android.app.usage.UsageStatsManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700156import android.content.ActivityNotFoundException;
157import android.content.ComponentName;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700158import android.content.ContentResolver;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700159import android.content.Context;
Evan Rosky4505b352018-09-06 11:20:40 -0700160import android.content.DialogInterface;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700161import android.content.IIntentSender;
162import android.content.Intent;
163import android.content.pm.ActivityInfo;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700164import android.content.pm.ApplicationInfo;
Yunfan Chen75157d72018-07-27 14:47:21 +0900165import android.content.pm.ConfigurationInfo;
Evan Rosky4505b352018-09-06 11:20:40 -0700166import android.content.pm.IPackageManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700167import android.content.pm.PackageManager;
Evan Rosky4505b352018-09-06 11:20:40 -0700168import android.content.pm.PackageManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700169import android.content.pm.ParceledListSlice;
170import android.content.pm.ResolveInfo;
Wale Ogunwale53783742018-09-16 10:21:51 -0700171import android.content.res.CompatibilityInfo;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700172import android.content.res.Configuration;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700173import android.content.res.Resources;
Evan Rosky4505b352018-09-06 11:20:40 -0700174import android.database.ContentObserver;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700175import android.graphics.Bitmap;
176import android.graphics.Point;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700177import android.graphics.Rect;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700178import android.metrics.LogMaker;
179import android.net.Uri;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700180import android.os.Binder;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700181import android.os.Build;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700182import android.os.Bundle;
Wale Ogunwale214f3482018-10-04 11:00:47 -0700183import android.os.FactoryTest;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700184import android.os.FileUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700185import android.os.Handler;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700186import android.os.IBinder;
Evan Rosky4505b352018-09-06 11:20:40 -0700187import android.os.IUserManager;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700188import android.os.LocaleList;
Riddle Hsud93a6c42018-11-29 21:50:06 +0800189import android.os.Looper;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700190import android.os.Message;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700191import android.os.PersistableBundle;
Evan Rosky4505b352018-09-06 11:20:40 -0700192import android.os.PowerManager;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700193import android.os.PowerManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700194import android.os.RemoteException;
Evan Rosky4505b352018-09-06 11:20:40 -0700195import android.os.ServiceManager;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700196import android.os.StrictMode;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700197import android.os.SystemClock;
198import android.os.SystemProperties;
Evan Rosky4505b352018-09-06 11:20:40 -0700199import android.os.Trace;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700200import android.os.UpdateLock;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700201import android.os.UserHandle;
Evan Rosky4505b352018-09-06 11:20:40 -0700202import android.os.UserManager;
203import android.os.WorkSource;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700204import android.os.storage.IStorageManager;
205import android.os.storage.StorageManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700206import android.provider.Settings;
207import android.service.voice.IVoiceInteractionSession;
208import android.service.voice.VoiceInteractionManagerInternal;
Kiyoung Kim0fe161d2018-12-20 18:26:10 +0900209import android.sysprop.DisplayProperties;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700210import android.telecom.TelecomManager;
211import android.text.TextUtils;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700212import android.text.format.Time;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700213import android.util.ArrayMap;
214import android.util.EventLog;
215import android.util.Log;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700216import android.util.Slog;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700217import android.util.SparseArray;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700218import android.util.SparseIntArray;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700219import android.util.StatsLog;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700220import android.util.TimeUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700221import android.util.proto.ProtoOutputStream;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700222import android.view.IRecentsAnimationRunner;
223import android.view.RemoteAnimationAdapter;
224import android.view.RemoteAnimationDefinition;
Evan Rosky4505b352018-09-06 11:20:40 -0700225import android.view.WindowManager;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700226
Evan Rosky4505b352018-09-06 11:20:40 -0700227import com.android.internal.R;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700228import com.android.internal.annotations.VisibleForTesting;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700229import com.android.internal.app.AssistUtils;
Evan Rosky4505b352018-09-06 11:20:40 -0700230import com.android.internal.app.IAppOpsService;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700231import com.android.internal.app.IVoiceInteractor;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700232import com.android.internal.app.ProcessMap;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700233import com.android.internal.logging.MetricsLogger;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700234import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Wale Ogunwale53783742018-09-16 10:21:51 -0700235import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
236import com.android.internal.notification.SystemNotificationChannels;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700237import com.android.internal.os.TransferPipe;
Evan Rosky4505b352018-09-06 11:20:40 -0700238import com.android.internal.os.logging.MetricsLoggerWrapper;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700239import com.android.internal.policy.IKeyguardDismissCallback;
240import com.android.internal.policy.KeyguardDismissCallback;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700241import com.android.internal.util.ArrayUtils;
242import com.android.internal.util.FastPrintWriter;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700243import com.android.internal.util.Preconditions;
Wale Ogunwale53783742018-09-16 10:21:51 -0700244import com.android.internal.util.function.pooled.PooledLambda;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700245import com.android.server.AttributeCache;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700246import com.android.server.LocalServices;
247import com.android.server.SystemService;
Evan Rosky4505b352018-09-06 11:20:40 -0700248import com.android.server.SystemServiceManager;
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -0800249import com.android.server.UiThread;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700250import com.android.server.Watchdog;
Wale Ogunwale59507092018-10-29 09:00:30 -0700251import com.android.server.am.ActivityManagerService;
252import com.android.server.am.ActivityManagerServiceDumpActivitiesProto;
253import com.android.server.am.ActivityManagerServiceDumpProcessesProto;
254import com.android.server.am.AppTimeTracker;
255import com.android.server.am.BaseErrorDialog;
256import com.android.server.am.EventLogTags;
257import com.android.server.am.PendingIntentController;
258import com.android.server.am.PendingIntentRecord;
259import com.android.server.am.UserState;
Kiyoung Kim0fe161d2018-12-20 18:26:10 +0900260import com.android.server.appop.AppOpsService;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700261import com.android.server.firewall.IntentFirewall;
Evan Rosky4505b352018-09-06 11:20:40 -0700262import com.android.server.pm.UserManagerService;
263import com.android.server.uri.UriGrantsManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700264import com.android.server.vr.VrManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700265
Wale Ogunwale31913b52018-10-13 08:29:31 -0700266import java.io.BufferedReader;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700267import java.io.File;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700268import java.io.FileDescriptor;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700269import java.io.FileOutputStream;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700270import java.io.FileReader;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700271import java.io.IOException;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700272import java.io.PrintWriter;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700273import java.io.StringWriter;
Riddle Hsua0536432019-02-16 00:38:59 +0800274import java.lang.annotation.ElementType;
275import java.lang.annotation.Retention;
276import java.lang.annotation.RetentionPolicy;
277import java.lang.annotation.Target;
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700278import java.lang.ref.WeakReference;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700279import java.text.DateFormat;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700280import java.util.ArrayList;
Wale Ogunwale27c48ae2018-10-25 19:01:01 -0700281import java.util.Arrays;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700282import java.util.Date;
Alison Cichowlas3e340502018-08-07 17:15:01 -0400283import java.util.HashMap;
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700284import java.util.HashSet;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700285import java.util.List;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700286import java.util.Locale;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700287import java.util.Map;
288import java.util.Set;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700289
290/**
291 * System service for managing activities and their containers (task, stacks, displays,... ).
292 *
293 * {@hide}
294 */
295public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
Wale Ogunwale98875612018-10-12 07:53:02 -0700296 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityTaskManagerService" : TAG_ATM;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700297 private static final String TAG_STACK = TAG + POSTFIX_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700298 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
299 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
300 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
301 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
302 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700303 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700304
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700305 // How long we wait until we timeout on key dispatching.
Wale Ogunwale51cc98a2018-10-15 10:41:05 -0700306 public static final int KEY_DISPATCHING_TIMEOUT_MS = 5 * 1000;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700307 // How long we wait until we timeout on key dispatching during instrumentation.
Wale Ogunwale51cc98a2018-10-15 10:41:05 -0700308 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS = 60 * 1000;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700309
Wale Ogunwale98875612018-10-12 07:53:02 -0700310 /** Used to indicate that an app transition should be animated. */
311 static final boolean ANIMATE = true;
312
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700313 /** Hardware-reported OpenGLES version. */
314 final int GL_ES_VERSION;
315
Wale Ogunwale31913b52018-10-13 08:29:31 -0700316 public static final String DUMP_ACTIVITIES_CMD = "activities" ;
317 public static final String DUMP_ACTIVITIES_SHORT_CMD = "a" ;
318 public static final String DUMP_LASTANR_CMD = "lastanr" ;
319 public static final String DUMP_LASTANR_TRACES_CMD = "lastanr-traces" ;
320 public static final String DUMP_STARTER_CMD = "starter" ;
321 public static final String DUMP_CONTAINERS_CMD = "containers" ;
322 public static final String DUMP_RECENTS_CMD = "recents" ;
323 public static final String DUMP_RECENTS_SHORT_CMD = "r" ;
324
Wale Ogunwale64258362018-10-16 15:13:37 -0700325 /** This activity is not being relaunched, or being relaunched for a non-resize reason. */
326 public static final int RELAUNCH_REASON_NONE = 0;
327 /** This activity is being relaunched due to windowing mode change. */
328 public static final int RELAUNCH_REASON_WINDOWING_MODE_RESIZE = 1;
329 /** This activity is being relaunched due to a free-resize operation. */
330 public static final int RELAUNCH_REASON_FREE_RESIZE = 2;
331
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700332 Context mContext;
Wale Ogunwale64258362018-10-16 15:13:37 -0700333
Wale Ogunwalef6733932018-06-27 05:14:34 -0700334 /**
335 * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
336 * change at runtime. Use mContext for non-UI purposes.
337 */
338 final Context mUiContext;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700339 final ActivityThread mSystemThread;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700340 H mH;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700341 UiHandler mUiHandler;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700342 ActivityManagerInternal mAmInternal;
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700343 UriGrantsManagerInternal mUgmInternal;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700344 private PackageManagerInternal mPmInternal;
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800345 @VisibleForTesting
346 final ActivityTaskManagerInternal mInternal;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700347 PowerManagerInternal mPowerManagerInternal;
348 private UsageStatsManagerInternal mUsageStatsInternal;
349
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700350 PendingIntentController mPendingIntentController;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700351 IntentFirewall mIntentFirewall;
352
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700353 /* Global service lock used by the package the owns this service. */
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -0800354 final WindowManagerGlobalLock mGlobalLock = new WindowManagerGlobalLock();
Riddle Hsud7088f82019-01-30 13:04:50 +0800355 /**
356 * It is the same instance as {@link mGlobalLock}, just declared as a type that the
357 * locked-region-code-injection does't recognize it. It is used to skip wrapping priority
358 * booster for places that are already in the scope of another booster (e.g. computing oom-adj).
359 *
360 * @see WindowManagerThreadPriorityBooster
361 */
362 final Object mGlobalLockWithoutBoost = mGlobalLock;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700363 ActivityStackSupervisor mStackSupervisor;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800364 RootActivityContainer mRootActivityContainer;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700365 WindowManagerService mWindowManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700366 private UserManagerService mUserManager;
367 private AppOpsService mAppOpsService;
Wale Ogunwalebff2df42018-10-18 17:09:19 -0700368 /** All active uids in the system. */
Riddle Hsua0536432019-02-16 00:38:59 +0800369 private final MirrorActiveUids mActiveUids = new MirrorActiveUids();
Wale Ogunwale9de19442018-10-18 19:05:03 -0700370 private final SparseArray<String> mPendingTempWhitelist = new SparseArray<>();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700371 /** All processes currently running that might have a window organized by name. */
372 final ProcessMap<WindowProcessController> mProcessNames = new ProcessMap<>();
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700373 /** All processes we currently have running mapped by pid */
374 final SparseArray<WindowProcessController> mPidMap = new SparseArray<>();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700375 /** This is the process holding what we currently consider to be the "home" activity. */
376 WindowProcessController mHomeProcess;
Wale Ogunwale53783742018-09-16 10:21:51 -0700377 /** The currently running heavy-weight process, if any. */
378 WindowProcessController mHeavyWeightProcess = null;
Wale Ogunwale214f3482018-10-04 11:00:47 -0700379 boolean mHasHeavyWeightFeature;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700380 /**
381 * This is the process holding the activity the user last visited that is in a different process
382 * from the one they are currently in.
383 */
384 WindowProcessController mPreviousProcess;
385 /** The time at which the previous process was last visible. */
386 long mPreviousProcessVisibleTime;
387
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700388 /** List of intents that were used to start the most recent tasks. */
389 private RecentTasks mRecentTasks;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700390 /** State of external calls telling us if the device is awake or asleep. */
391 private boolean mKeyguardShown = false;
392
393 // Wrapper around VoiceInteractionServiceManager
394 private AssistUtils mAssistUtils;
395
396 // VoiceInteraction session ID that changes for each new request except when
397 // being called for multi-window assist in a single session.
398 private int mViSessionId = 1000;
399
400 // How long to wait in getAssistContextExtras for the activity and foreground services
401 // to respond with the result.
402 private static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
403
404 // How long top wait when going through the modern assist (which doesn't need to block
405 // on getting this result before starting to launch its UI).
406 private static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
407
408 // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
409 private static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
410
Alison Cichowlas3e340502018-08-07 17:15:01 -0400411 // Permission tokens are used to temporarily granted a trusted app the ability to call
412 // #startActivityAsCaller. A client is expected to dump its token after this time has elapsed,
413 // showing any appropriate error messages to the user.
414 private static final long START_AS_CALLER_TOKEN_TIMEOUT =
415 10 * MINUTE_IN_MILLIS;
416
417 // How long before the service actually expires a token. This is slightly longer than
418 // START_AS_CALLER_TOKEN_TIMEOUT, to provide a buffer so clients will rarely encounter the
419 // expiration exception.
420 private static final long START_AS_CALLER_TOKEN_TIMEOUT_IMPL =
421 START_AS_CALLER_TOKEN_TIMEOUT + 2 * 1000;
422
423 // How long the service will remember expired tokens, for the purpose of providing error
424 // messaging when a client uses an expired token.
425 private static final long START_AS_CALLER_TOKEN_EXPIRED_TIMEOUT =
426 START_AS_CALLER_TOKEN_TIMEOUT_IMPL + 20 * MINUTE_IN_MILLIS;
427
428 // Activity tokens of system activities that are delegating their call to
429 // #startActivityByCaller, keyed by the permissionToken granted to the delegate.
430 final HashMap<IBinder, IBinder> mStartActivitySources = new HashMap<>();
431
432 // Permission tokens that have expired, but we remember for error reporting.
433 final ArrayList<IBinder> mExpiredStartAsCallerTokens = new ArrayList<>();
434
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700435 private final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
436
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700437 // Keeps track of the active voice interaction service component, notified from
438 // VoiceInteractionManagerService
439 ComponentName mActiveVoiceInteractionServiceComponent;
440
Wale Ogunwalee2172292018-10-25 10:11:10 -0700441 VrController mVrController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700442 KeyguardController mKeyguardController;
443 private final ClientLifecycleManager mLifecycleManager;
444 private TaskChangeNotificationController mTaskChangeNotificationController;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700445 /** The controller for all operations related to locktask. */
446 private LockTaskController mLockTaskController;
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700447 private ActivityStartController mActivityStartController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700448
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700449 boolean mSuppressResizeConfigChanges;
450
451 private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
452 new UpdateConfigurationResult();
453
454 static final class UpdateConfigurationResult {
455 // Configuration changes that were updated.
456 int changes;
457 // If the activity was relaunched to match the new configuration.
458 boolean activityRelaunched;
459
460 void reset() {
461 changes = 0;
462 activityRelaunched = false;
463 }
464 }
465
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700466 /** Current sequencing integer of the configuration, for skipping old configurations. */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700467 private int mConfigurationSeq;
468 // To cache the list of supported system locales
469 private String[] mSupportedSystemLocales = null;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700470
471 /**
472 * Temp object used when global and/or display override configuration is updated. It is also
473 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
474 * anyone...
475 */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700476 private Configuration mTempConfig = new Configuration();
477
Wale Ogunwalef6733932018-06-27 05:14:34 -0700478 /** Temporary to avoid allocations. */
479 final StringBuilder mStringBuilder = new StringBuilder(256);
480
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700481 // Amount of time after a call to stopAppSwitches() during which we will
482 // prevent further untrusted switches from happening.
483 private static final long APP_SWITCH_DELAY_TIME = 5 * 1000;
484
485 /**
486 * The time at which we will allow normal application switches again,
487 * after a call to {@link #stopAppSwitches()}.
488 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700489 private long mAppSwitchesAllowedTime;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700490 /**
491 * This is set to true after the first switch after mAppSwitchesAllowedTime
492 * is set; any switches after that will clear the time.
493 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700494 private boolean mDidAppSwitch;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700495
496 IActivityController mController = null;
497 boolean mControllerIsAMonkey = false;
498
Wale Ogunwale214f3482018-10-04 11:00:47 -0700499 final int mFactoryTest;
500
501 /** Used to control how we initialize the service. */
502 ComponentName mTopComponent;
503 String mTopAction = Intent.ACTION_MAIN;
504 String mTopData;
505
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -0800506 /** Profiling app information. */
507 String mProfileApp = null;
508 WindowProcessController mProfileProc = null;
509 ProfilerInfo mProfilerInfo = null;
510
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700511 /**
Wale Ogunwale31913b52018-10-13 08:29:31 -0700512 * Dump of the activity state at the time of the last ANR. Cleared after
513 * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
514 */
515 String mLastANRState;
516
517 /**
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700518 * Used to retain an update lock when the foreground activity is in
519 * immersive mode.
520 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700521 private final UpdateLock mUpdateLock = new UpdateLock("immersive");
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700522
523 /**
524 * Packages that are being allowed to perform unrestricted app switches. Mapping is
525 * User -> Type -> uid.
526 */
527 final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
528
529 /** The dimensions of the thumbnails in the Recents UI. */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700530 private int mThumbnailWidth;
531 private int mThumbnailHeight;
532 private float mFullscreenThumbnailScale;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700533
534 /**
535 * Flag that indicates if multi-window is enabled.
536 *
537 * For any particular form of multi-window to be enabled, generic multi-window must be enabled
538 * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
539 * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
540 * At least one of the forms of multi-window must be enabled in order for this flag to be
541 * initialized to 'true'.
542 *
543 * @see #mSupportsSplitScreenMultiWindow
544 * @see #mSupportsFreeformWindowManagement
545 * @see #mSupportsPictureInPicture
546 * @see #mSupportsMultiDisplay
547 */
548 boolean mSupportsMultiWindow;
549 boolean mSupportsSplitScreenMultiWindow;
550 boolean mSupportsFreeformWindowManagement;
551 boolean mSupportsPictureInPicture;
552 boolean mSupportsMultiDisplay;
553 boolean mForceResizableActivities;
554
555 final List<ActivityTaskManagerInternal.ScreenObserver> mScreenObservers = new ArrayList<>();
556
557 // VR Vr2d Display Id.
558 int mVr2dDisplayId = INVALID_DISPLAY;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700559
Wale Ogunwalef6733932018-06-27 05:14:34 -0700560 /**
561 * Set while we are wanting to sleep, to prevent any
562 * activities from being started/resumed.
563 *
564 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
565 *
566 * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
567 * while in the sleep state until there is a pending transition out of sleep, in which case
568 * mSleeping is set to false, and remains false while awake.
569 *
570 * Whether mSleeping can quickly toggled between true/false without the device actually
571 * display changing states is undefined.
572 */
573 private boolean mSleeping = false;
574
575 /**
576 * The process state used for processes that are running the top activities.
577 * This changes between TOP and TOP_SLEEPING to following mSleeping.
578 */
579 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
580
581 // Whether we should show our dialogs (ANR, crash, etc) or just perform their default action
582 // automatically. Important for devices without direct input devices.
583 private boolean mShowDialogs = true;
584
585 /** Set if we are shutting down the system, similar to sleeping. */
586 boolean mShuttingDown = false;
587
588 /**
589 * We want to hold a wake lock while running a voice interaction session, since
590 * this may happen with the screen off and we need to keep the CPU running to
591 * be able to continue to interact with the user.
592 */
593 PowerManager.WakeLock mVoiceWakeLock;
594
595 /**
596 * Set while we are running a voice interaction. This overrides sleeping while it is active.
597 */
598 IVoiceInteractionSession mRunningVoice;
599
600 /**
601 * The last resumed activity. This is identical to the current resumed activity most
602 * of the time but could be different when we're pausing one activity before we resume
603 * another activity.
604 */
605 ActivityRecord mLastResumedActivity;
606
607 /**
608 * The activity that is currently being traced as the active resumed activity.
609 *
610 * @see #updateResumedAppTrace
611 */
612 private @Nullable ActivityRecord mTracedResumedActivity;
613
614 /** If non-null, we are tracking the time the user spends in the currently focused app. */
615 AppTimeTracker mCurAppTimeTracker;
616
Wale Ogunwale008163e2018-07-23 23:11:08 -0700617 private AppWarnings mAppWarnings;
618
Wale Ogunwale53783742018-09-16 10:21:51 -0700619 /**
620 * Packages that the user has asked to have run in screen size
621 * compatibility mode instead of filling the screen.
622 */
623 CompatModePackages mCompatModePackages;
624
Wale Ogunwalef6733932018-06-27 05:14:34 -0700625 private FontScaleSettingObserver mFontScaleSettingObserver;
626
Michal Karpinski4026cae2019-02-12 11:51:47 +0000627 private String mDeviceOwnerPackageName;
628
Wale Ogunwalef6733932018-06-27 05:14:34 -0700629 private final class FontScaleSettingObserver extends ContentObserver {
630 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
631 private final Uri mHideErrorDialogsUri = Settings.Global.getUriFor(HIDE_ERROR_DIALOGS);
632
633 public FontScaleSettingObserver() {
634 super(mH);
635 final ContentResolver resolver = mContext.getContentResolver();
636 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
637 resolver.registerContentObserver(mHideErrorDialogsUri, false, this,
638 UserHandle.USER_ALL);
639 }
640
641 @Override
642 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
643 if (mFontScaleUri.equals(uri)) {
644 updateFontScaleIfNeeded(userId);
645 } else if (mHideErrorDialogsUri.equals(uri)) {
646 synchronized (mGlobalLock) {
647 updateShouldShowDialogsLocked(getGlobalConfiguration());
648 }
649 }
650 }
651 }
652
Riddle Hsua0536432019-02-16 00:38:59 +0800653 /** Indicates that the method may be invoked frequently or is sensitive to performance. */
654 @Target(ElementType.METHOD)
655 @Retention(RetentionPolicy.SOURCE)
656 @interface HotPath {
657 int NONE = 0;
658 int OOM_ADJUSTMENT = 1;
659 int LRU_UPDATE = 2;
660 int PROCESS_CHANGE = 3;
661 int caller() default NONE;
662 }
663
Charles Chen8d98dd22018-12-26 17:36:54 +0800664 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
665 public ActivityTaskManagerService(Context context) {
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700666 mContext = context;
Wale Ogunwale214f3482018-10-04 11:00:47 -0700667 mFactoryTest = FactoryTest.getMode();
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700668 mSystemThread = ActivityThread.currentActivityThread();
669 mUiContext = mSystemThread.getSystemUiContext();
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700670 mLifecycleManager = new ClientLifecycleManager();
Wale Ogunwaleb73f3962018-11-20 07:58:22 -0800671 mInternal = new LocalService();
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700672 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", GL_ES_VERSION_UNDEFINED);
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700673 }
674
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700675 public void onSystemReady() {
676 synchronized (mGlobalLock) {
677 mHasHeavyWeightFeature = mContext.getPackageManager().hasSystemFeature(
678 PackageManager.FEATURE_CANT_SAVE_STATE);
679 mAssistUtils = new AssistUtils(mContext);
680 mVrController.onSystemReady();
681 mRecentTasks.onSystemReadyLocked();
Garfield Tan891146c2018-10-09 12:14:00 -0700682 mStackSupervisor.onSystemReady();
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700683 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700684 }
685
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700686 public void onInitPowerManagement() {
687 synchronized (mGlobalLock) {
688 mStackSupervisor.initPowerManagement();
689 final PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
690 mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
691 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
692 mVoiceWakeLock.setReferenceCounted(false);
693 }
Wale Ogunwalef6733932018-06-27 05:14:34 -0700694 }
695
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700696 public void installSystemProviders() {
Wale Ogunwalef6733932018-06-27 05:14:34 -0700697 mFontScaleSettingObserver = new FontScaleSettingObserver();
698 }
699
Wale Ogunwale59507092018-10-29 09:00:30 -0700700 public void retrieveSettings(ContentResolver resolver) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700701 final boolean freeformWindowManagement =
702 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
703 || Settings.Global.getInt(
704 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
705
706 final boolean supportsMultiWindow = ActivityTaskManager.supportsMultiWindow(mContext);
707 final boolean supportsPictureInPicture = supportsMultiWindow &&
708 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
709 final boolean supportsSplitScreenMultiWindow =
710 ActivityTaskManager.supportsSplitScreenMultiWindow(mContext);
711 final boolean supportsMultiDisplay = mContext.getPackageManager()
712 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700713 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
714 final boolean forceResizable = Settings.Global.getInt(
715 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
Garfield Tane0846042018-07-26 13:42:04 -0700716 final boolean isPc = mContext.getPackageManager().hasSystemFeature(FEATURE_PC);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700717
718 // Transfer any global setting for forcing RTL layout, into a System Property
Kiyoung Kim0fe161d2018-12-20 18:26:10 +0900719 DisplayProperties.debug_force_rtl(forceRtl);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700720
721 final Configuration configuration = new Configuration();
722 Settings.System.getConfiguration(resolver, configuration);
723 if (forceRtl) {
724 // This will take care of setting the correct layout direction flags
725 configuration.setLayoutDirection(configuration.locale);
726 }
727
728 synchronized (mGlobalLock) {
729 mForceResizableActivities = forceResizable;
730 final boolean multiWindowFormEnabled = freeformWindowManagement
731 || supportsSplitScreenMultiWindow
732 || supportsPictureInPicture
733 || supportsMultiDisplay;
734 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
735 mSupportsMultiWindow = true;
736 mSupportsFreeformWindowManagement = freeformWindowManagement;
737 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
738 mSupportsPictureInPicture = supportsPictureInPicture;
739 mSupportsMultiDisplay = supportsMultiDisplay;
740 } else {
741 mSupportsMultiWindow = false;
742 mSupportsFreeformWindowManagement = false;
743 mSupportsSplitScreenMultiWindow = false;
744 mSupportsPictureInPicture = false;
745 mSupportsMultiDisplay = false;
746 }
747 mWindowManager.setForceResizableTasks(mForceResizableActivities);
748 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
Garfield Tane0846042018-07-26 13:42:04 -0700749 mWindowManager.setSupportsFreeformWindowManagement(mSupportsFreeformWindowManagement);
750 mWindowManager.setIsPc(isPc);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700751 // This happens before any activities are started, so we can change global configuration
752 // in-place.
753 updateConfigurationLocked(configuration, null, true);
754 final Configuration globalConfig = getGlobalConfiguration();
755 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
756
757 // Load resources only after the current configuration has been set.
758 final Resources res = mContext.getResources();
759 mThumbnailWidth = res.getDimensionPixelSize(
760 com.android.internal.R.dimen.thumbnail_width);
761 mThumbnailHeight = res.getDimensionPixelSize(
762 com.android.internal.R.dimen.thumbnail_height);
763
764 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
765 mFullscreenThumbnailScale = (float) res
766 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
767 (float) globalConfig.screenWidthDp;
768 } else {
769 mFullscreenThumbnailScale = res.getFraction(
770 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
771 }
772 }
773 }
774
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -0800775 public WindowManagerGlobalLock getGlobalLock() {
776 return mGlobalLock;
777 }
778
Yunfan Chen585f2932019-01-29 16:04:45 +0900779 /** For test purpose only. */
780 @VisibleForTesting
781 public ActivityTaskManagerInternal getAtmInternal() {
782 return mInternal;
783 }
784
Riddle Hsud93a6c42018-11-29 21:50:06 +0800785 public void initialize(IntentFirewall intentFirewall, PendingIntentController intentController,
786 Looper looper) {
787 mH = new H(looper);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700788 mUiHandler = new UiHandler();
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700789 mIntentFirewall = intentFirewall;
Wale Ogunwale53783742018-09-16 10:21:51 -0700790 final File systemDir = SystemServiceManager.ensureSystemDir();
791 mAppWarnings = new AppWarnings(this, mUiContext, mH, mUiHandler, systemDir);
792 mCompatModePackages = new CompatModePackages(this, systemDir, mH);
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700793 mPendingIntentController = intentController;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700794
795 mTempConfig.setToDefaults();
796 mTempConfig.setLocales(LocaleList.getDefault());
797 mConfigurationSeq = mTempConfig.seq = 1;
798 mStackSupervisor = createStackSupervisor();
Wale Ogunwaled32da472018-11-16 07:19:28 -0800799 mRootActivityContainer = new RootActivityContainer(this);
800 mRootActivityContainer.onConfigurationChanged(mTempConfig);
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700801
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700802 mTaskChangeNotificationController =
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700803 new TaskChangeNotificationController(mGlobalLock, mStackSupervisor, mH);
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700804 mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mH);
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700805 mActivityStartController = new ActivityStartController(this);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700806 mRecentTasks = createRecentTasks();
807 mStackSupervisor.setRecentTasks(mRecentTasks);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700808 mVrController = new VrController(mGlobalLock);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700809 mKeyguardController = mStackSupervisor.getKeyguardController();
810 }
811
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700812 public void onActivityManagerInternalAdded() {
813 synchronized (mGlobalLock) {
814 mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
815 mUgmInternal = LocalServices.getService(UriGrantsManagerInternal.class);
816 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700817 }
818
Yunfan Chen75157d72018-07-27 14:47:21 +0900819 int increaseConfigurationSeqLocked() {
820 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
821 return mConfigurationSeq;
822 }
823
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700824 protected ActivityStackSupervisor createStackSupervisor() {
825 final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mH.getLooper());
826 supervisor.initialize();
827 return supervisor;
828 }
829
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700830 public void setWindowManager(WindowManagerService wm) {
831 synchronized (mGlobalLock) {
832 mWindowManager = wm;
833 mLockTaskController.setWindowManager(wm);
834 mStackSupervisor.setWindowManager(wm);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800835 mRootActivityContainer.setWindowManager(wm);
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700836 }
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700837 }
838
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700839 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
840 synchronized (mGlobalLock) {
841 mUsageStatsInternal = usageStatsManager;
842 }
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700843 }
844
Wale Ogunwalef6733932018-06-27 05:14:34 -0700845 UserManagerService getUserManager() {
846 if (mUserManager == null) {
847 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
848 mUserManager = (UserManagerService) IUserManager.Stub.asInterface(b);
849 }
850 return mUserManager;
851 }
852
853 AppOpsService getAppOpsService() {
854 if (mAppOpsService == null) {
855 IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
856 mAppOpsService = (AppOpsService) IAppOpsService.Stub.asInterface(b);
857 }
858 return mAppOpsService;
859 }
860
861 boolean hasUserRestriction(String restriction, int userId) {
862 return getUserManager().hasUserRestriction(restriction, userId);
863 }
864
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700865 protected RecentTasks createRecentTasks() {
866 return new RecentTasks(this, mStackSupervisor);
867 }
868
869 RecentTasks getRecentTasks() {
870 return mRecentTasks;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700871 }
872
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700873 ClientLifecycleManager getLifecycleManager() {
874 return mLifecycleManager;
875 }
876
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700877 ActivityStartController getActivityStartController() {
878 return mActivityStartController;
879 }
880
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700881 TaskChangeNotificationController getTaskChangeNotificationController() {
882 return mTaskChangeNotificationController;
883 }
884
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700885 LockTaskController getLockTaskController() {
886 return mLockTaskController;
887 }
888
Yunfan Chen75157d72018-07-27 14:47:21 +0900889 /**
890 * Return the global configuration used by the process corresponding to the input pid. This is
891 * usually the global configuration with some overrides specific to that process.
892 */
893 Configuration getGlobalConfigurationForCallingPid() {
894 final int pid = Binder.getCallingPid();
Yunfan Chenc2ff6cf2018-12-04 16:56:21 -0800895 return getGlobalConfigurationForPid(pid);
896 }
897
898 /**
899 * Return the global configuration used by the process corresponding to the given pid.
900 */
901 Configuration getGlobalConfigurationForPid(int pid) {
Yunfan Chen75157d72018-07-27 14:47:21 +0900902 if (pid == MY_PID || pid < 0) {
903 return getGlobalConfiguration();
904 }
905 synchronized (mGlobalLock) {
906 final WindowProcessController app = mPidMap.get(pid);
907 return app != null ? app.getConfiguration() : getGlobalConfiguration();
908 }
909 }
910
911 /**
912 * Return the device configuration info used by the process corresponding to the input pid.
913 * The value is consistent with the global configuration for the process.
914 */
915 @Override
916 public ConfigurationInfo getDeviceConfigurationInfo() {
917 ConfigurationInfo config = new ConfigurationInfo();
918 synchronized (mGlobalLock) {
919 final Configuration globalConfig = getGlobalConfigurationForCallingPid();
920 config.reqTouchScreen = globalConfig.touchscreen;
921 config.reqKeyboardType = globalConfig.keyboard;
922 config.reqNavigation = globalConfig.navigation;
923 if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
924 || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
925 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
926 }
927 if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
928 && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
929 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
930 }
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700931 config.reqGlEsVersion = GL_ES_VERSION;
Yunfan Chen75157d72018-07-27 14:47:21 +0900932 }
933 return config;
934 }
935
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700936 private void start() {
Wale Ogunwale53783742018-09-16 10:21:51 -0700937 LocalServices.addService(ActivityTaskManagerInternal.class, mInternal);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700938 }
939
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700940 public static final class Lifecycle extends SystemService {
941 private final ActivityTaskManagerService mService;
942
943 public Lifecycle(Context context) {
944 super(context);
945 mService = new ActivityTaskManagerService(context);
946 }
947
948 @Override
949 public void onStart() {
950 publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700951 mService.start();
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700952 }
953
Garfield Tan891146c2018-10-09 12:14:00 -0700954 @Override
955 public void onUnlockUser(int userId) {
956 synchronized (mService.getGlobalLock()) {
Garfield Tan0d407f42019-03-07 11:47:01 -0800957 mService.mStackSupervisor.onUserUnlocked(userId);
Garfield Tan891146c2018-10-09 12:14:00 -0700958 }
959 }
960
961 @Override
962 public void onCleanupUser(int userId) {
963 synchronized (mService.getGlobalLock()) {
964 mService.mStackSupervisor.mLaunchParamsPersister.onCleanupUser(userId);
965 }
966 }
967
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700968 public ActivityTaskManagerService getService() {
969 return mService;
970 }
971 }
972
973 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700974 public final int startActivity(IApplicationThread caller, String callingPackage,
975 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
976 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
977 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
978 resultWho, requestCode, startFlags, profilerInfo, bOptions,
979 UserHandle.getCallingUserId());
980 }
981
982 @Override
983 public final int startActivities(IApplicationThread caller, String callingPackage,
984 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
985 int userId) {
986 final String reason = "startActivities";
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700987 enforceNotIsolatedCaller(reason);
988 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, reason);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700989 // TODO: Switch to user app stacks here.
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000990 return getActivityStartController().startActivities(caller, -1, 0, -1, callingPackage,
991 intents, resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId,
992 reason, null /* originatingPendingIntent */,
993 false /* allowBackgroundActivityStart */);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700994 }
995
996 @Override
997 public int startActivityAsUser(IApplicationThread caller, String callingPackage,
998 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
999 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
1000 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
1001 resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
1002 true /*validateIncomingUser*/);
1003 }
1004
1005 int startActivityAsUser(IApplicationThread caller, String callingPackage,
1006 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1007 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
1008 boolean validateIncomingUser) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001009 enforceNotIsolatedCaller("startActivityAsUser");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001010
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001011 userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001012 Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
1013
1014 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001015 return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001016 .setCaller(caller)
1017 .setCallingPackage(callingPackage)
1018 .setResolvedType(resolvedType)
1019 .setResultTo(resultTo)
1020 .setResultWho(resultWho)
1021 .setRequestCode(requestCode)
1022 .setStartFlags(startFlags)
1023 .setProfilerInfo(profilerInfo)
1024 .setActivityOptions(bOptions)
1025 .setMayWait(userId)
1026 .execute();
1027
1028 }
1029
1030 @Override
1031 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
1032 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001033 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions) {
1034 enforceNotIsolatedCaller("startActivityIntentSender");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001035 // Refuse possible leaked file descriptors
1036 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
1037 throw new IllegalArgumentException("File descriptors passed in Intent");
1038 }
1039
1040 if (!(target instanceof PendingIntentRecord)) {
1041 throw new IllegalArgumentException("Bad PendingIntent object");
1042 }
1043
1044 PendingIntentRecord pir = (PendingIntentRecord)target;
1045
1046 synchronized (mGlobalLock) {
1047 // If this is coming from the currently resumed activity, it is
1048 // effectively saying that app switches are allowed at this point.
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001049 final ActivityStack stack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001050 if (stack.mResumedActivity != null &&
1051 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001052 mAppSwitchesAllowedTime = 0;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001053 }
1054 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001055 return pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001056 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001057 }
1058
1059 @Override
1060 public boolean startNextMatchingActivity(IBinder callingActivity, Intent intent,
1061 Bundle bOptions) {
1062 // Refuse possible leaked file descriptors
1063 if (intent != null && intent.hasFileDescriptors()) {
1064 throw new IllegalArgumentException("File descriptors passed in Intent");
1065 }
1066 SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
1067
1068 synchronized (mGlobalLock) {
1069 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
1070 if (r == null) {
1071 SafeActivityOptions.abort(options);
1072 return false;
1073 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001074 if (!r.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001075 // The caller is not running... d'oh!
1076 SafeActivityOptions.abort(options);
1077 return false;
1078 }
1079 intent = new Intent(intent);
1080 // The caller is not allowed to change the data.
1081 intent.setDataAndType(r.intent.getData(), r.intent.getType());
1082 // And we are resetting to find the next component...
1083 intent.setComponent(null);
1084
1085 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
1086
1087 ActivityInfo aInfo = null;
1088 try {
1089 List<ResolveInfo> resolves =
1090 AppGlobals.getPackageManager().queryIntentActivities(
1091 intent, r.resolvedType,
1092 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
1093 UserHandle.getCallingUserId()).getList();
1094
1095 // Look for the original activity in the list...
1096 final int N = resolves != null ? resolves.size() : 0;
1097 for (int i=0; i<N; i++) {
1098 ResolveInfo rInfo = resolves.get(i);
1099 if (rInfo.activityInfo.packageName.equals(r.packageName)
1100 && rInfo.activityInfo.name.equals(r.info.name)) {
1101 // We found the current one... the next matching is
1102 // after it.
1103 i++;
1104 if (i<N) {
1105 aInfo = resolves.get(i).activityInfo;
1106 }
1107 if (debug) {
1108 Slog.v(TAG, "Next matching activity: found current " + r.packageName
1109 + "/" + r.info.name);
1110 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
1111 ? "null" : aInfo.packageName + "/" + aInfo.name));
1112 }
1113 break;
1114 }
1115 }
1116 } catch (RemoteException e) {
1117 }
1118
1119 if (aInfo == null) {
1120 // Nobody who is next!
1121 SafeActivityOptions.abort(options);
1122 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
1123 return false;
1124 }
1125
1126 intent.setComponent(new ComponentName(
1127 aInfo.applicationInfo.packageName, aInfo.name));
1128 intent.setFlags(intent.getFlags()&~(
1129 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
1130 Intent.FLAG_ACTIVITY_CLEAR_TOP|
1131 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
1132 FLAG_ACTIVITY_NEW_TASK));
1133
1134 // Okay now we need to start the new activity, replacing the currently running activity.
1135 // This is a little tricky because we want to start the new one as if the current one is
1136 // finished, but not finish the current one first so that there is no flicker.
1137 // And thus...
1138 final boolean wasFinishing = r.finishing;
1139 r.finishing = true;
1140
1141 // Propagate reply information over to the new activity.
1142 final ActivityRecord resultTo = r.resultTo;
1143 final String resultWho = r.resultWho;
1144 final int requestCode = r.requestCode;
1145 r.resultTo = null;
1146 if (resultTo != null) {
1147 resultTo.removeResultsLocked(r, resultWho, requestCode);
1148 }
1149
1150 final long origId = Binder.clearCallingIdentity();
1151 // TODO(b/64750076): Check if calling pid should really be -1.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001152 final int res = getActivityStartController()
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001153 .obtainStarter(intent, "startNextMatchingActivity")
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001154 .setCaller(r.app.getThread())
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001155 .setResolvedType(r.resolvedType)
1156 .setActivityInfo(aInfo)
1157 .setResultTo(resultTo != null ? resultTo.appToken : null)
1158 .setResultWho(resultWho)
1159 .setRequestCode(requestCode)
1160 .setCallingPid(-1)
1161 .setCallingUid(r.launchedFromUid)
1162 .setCallingPackage(r.launchedFromPackage)
1163 .setRealCallingPid(-1)
1164 .setRealCallingUid(r.launchedFromUid)
1165 .setActivityOptions(options)
1166 .execute();
1167 Binder.restoreCallingIdentity(origId);
1168
1169 r.finishing = wasFinishing;
1170 if (res != ActivityManager.START_SUCCESS) {
1171 return false;
1172 }
1173 return true;
1174 }
1175 }
1176
1177 @Override
1178 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
1179 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1180 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
1181 final WaitResult res = new WaitResult();
1182 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001183 enforceNotIsolatedCaller("startActivityAndWait");
1184 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
1185 userId, "startActivityAndWait");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001186 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001187 getActivityStartController().obtainStarter(intent, "startActivityAndWait")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001188 .setCaller(caller)
1189 .setCallingPackage(callingPackage)
1190 .setResolvedType(resolvedType)
1191 .setResultTo(resultTo)
1192 .setResultWho(resultWho)
1193 .setRequestCode(requestCode)
1194 .setStartFlags(startFlags)
1195 .setActivityOptions(bOptions)
1196 .setMayWait(userId)
1197 .setProfilerInfo(profilerInfo)
1198 .setWaitResult(res)
1199 .execute();
1200 }
1201 return res;
1202 }
1203
1204 @Override
1205 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
1206 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1207 int startFlags, Configuration config, Bundle bOptions, int userId) {
1208 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001209 enforceNotIsolatedCaller("startActivityWithConfig");
1210 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
1211 "startActivityWithConfig");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001212 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001213 return getActivityStartController().obtainStarter(intent, "startActivityWithConfig")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001214 .setCaller(caller)
1215 .setCallingPackage(callingPackage)
1216 .setResolvedType(resolvedType)
1217 .setResultTo(resultTo)
1218 .setResultWho(resultWho)
1219 .setRequestCode(requestCode)
1220 .setStartFlags(startFlags)
1221 .setGlobalConfiguration(config)
1222 .setActivityOptions(bOptions)
1223 .setMayWait(userId)
1224 .execute();
1225 }
1226 }
1227
Alison Cichowlas3e340502018-08-07 17:15:01 -04001228
1229 @Override
1230 public IBinder requestStartActivityPermissionToken(IBinder delegatorToken) {
1231 int callingUid = Binder.getCallingUid();
1232 if (UserHandle.getAppId(callingUid) != SYSTEM_UID) {
1233 throw new SecurityException("Only the system process can request a permission token, "
1234 + "received request from uid: " + callingUid);
1235 }
1236 IBinder permissionToken = new Binder();
1237 synchronized (mGlobalLock) {
1238 mStartActivitySources.put(permissionToken, delegatorToken);
1239 }
1240
1241 Message expireMsg = PooledLambda.obtainMessage(
1242 ActivityTaskManagerService::expireStartAsCallerTokenMsg, this, permissionToken);
1243 mUiHandler.sendMessageDelayed(expireMsg, START_AS_CALLER_TOKEN_TIMEOUT_IMPL);
1244
1245 Message forgetMsg = PooledLambda.obtainMessage(
1246 ActivityTaskManagerService::forgetStartAsCallerTokenMsg, this, permissionToken);
1247 mUiHandler.sendMessageDelayed(forgetMsg, START_AS_CALLER_TOKEN_EXPIRED_TIMEOUT);
1248
1249 return permissionToken;
1250 }
1251
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001252 @Override
1253 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
1254 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
Alison Cichowlas3e340502018-08-07 17:15:01 -04001255 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, IBinder permissionToken,
1256 boolean ignoreTargetSecurity, int userId) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001257 // This is very dangerous -- it allows you to perform a start activity (including
Alison Cichowlas3e340502018-08-07 17:15:01 -04001258 // permission grants) as any app that may launch one of your own activities. So we only
1259 // allow this in two cases:
1260 // 1) The caller is an activity that is part of the core framework, and then only when it
1261 // is running as the system.
1262 // 2) The caller provides a valid permissionToken. Permission tokens are one-time use and
1263 // can only be requested by a system activity, which may then delegate this call to
1264 // another app.
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001265 final ActivityRecord sourceRecord;
1266 final int targetUid;
1267 final String targetPackage;
1268 final boolean isResolver;
1269 synchronized (mGlobalLock) {
1270 if (resultTo == null) {
1271 throw new SecurityException("Must be called from an activity");
1272 }
Alison Cichowlas3e340502018-08-07 17:15:01 -04001273 final IBinder sourceToken;
1274 if (permissionToken != null) {
1275 // To even attempt to use a permissionToken, an app must also have this signature
1276 // permission.
1277 mAmInternal.enforceCallingPermission(
1278 android.Manifest.permission.START_ACTIVITY_AS_CALLER,
1279 "startActivityAsCaller");
1280 // If called with a permissionToken, we want the sourceRecord from the delegator
1281 // activity that requested this token.
1282 sourceToken = mStartActivitySources.remove(permissionToken);
1283 if (sourceToken == null) {
1284 // Invalid permissionToken, check if it recently expired.
1285 if (mExpiredStartAsCallerTokens.contains(permissionToken)) {
1286 throw new SecurityException("Called with expired permission token: "
1287 + permissionToken);
1288 } else {
1289 throw new SecurityException("Called with invalid permission token: "
1290 + permissionToken);
1291 }
1292 }
1293 } else {
1294 // This method was called directly by the source.
1295 sourceToken = resultTo;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001296 }
Alison Cichowlas3e340502018-08-07 17:15:01 -04001297
Wale Ogunwaled32da472018-11-16 07:19:28 -08001298 sourceRecord = mRootActivityContainer.isInAnyStack(sourceToken);
Alison Cichowlas3e340502018-08-07 17:15:01 -04001299 if (sourceRecord == null) {
1300 throw new SecurityException("Called with bad activity token: " + sourceToken);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001301 }
1302 if (sourceRecord.app == null) {
1303 throw new SecurityException("Called without a process attached to activity");
1304 }
Alison Cichowlas3e340502018-08-07 17:15:01 -04001305
1306 // Whether called directly or from a delegate, the source activity must be from the
1307 // android package.
1308 if (!sourceRecord.info.packageName.equals("android")) {
1309 throw new SecurityException("Must be called from an activity that is "
1310 + "declared in the android package");
1311 }
1312
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001313 if (UserHandle.getAppId(sourceRecord.app.mUid) != SYSTEM_UID) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001314 // This is still okay, as long as this activity is running under the
1315 // uid of the original calling activity.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001316 if (sourceRecord.app.mUid != sourceRecord.launchedFromUid) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001317 throw new SecurityException(
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001318 "Calling activity in uid " + sourceRecord.app.mUid
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001319 + " must be system uid or original calling uid "
1320 + sourceRecord.launchedFromUid);
1321 }
1322 }
1323 if (ignoreTargetSecurity) {
1324 if (intent.getComponent() == null) {
1325 throw new SecurityException(
1326 "Component must be specified with ignoreTargetSecurity");
1327 }
1328 if (intent.getSelector() != null) {
1329 throw new SecurityException(
1330 "Selector not allowed with ignoreTargetSecurity");
1331 }
1332 }
1333 targetUid = sourceRecord.launchedFromUid;
1334 targetPackage = sourceRecord.launchedFromPackage;
1335 isResolver = sourceRecord.isResolverOrChildActivity();
1336 }
1337
1338 if (userId == UserHandle.USER_NULL) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001339 userId = UserHandle.getUserId(sourceRecord.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001340 }
1341
1342 // TODO: Switch to user app stacks here.
1343 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001344 return getActivityStartController().obtainStarter(intent, "startActivityAsCaller")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001345 .setCallingUid(targetUid)
1346 .setCallingPackage(targetPackage)
1347 .setResolvedType(resolvedType)
1348 .setResultTo(resultTo)
1349 .setResultWho(resultWho)
1350 .setRequestCode(requestCode)
1351 .setStartFlags(startFlags)
1352 .setActivityOptions(bOptions)
1353 .setMayWait(userId)
1354 .setIgnoreTargetSecurity(ignoreTargetSecurity)
1355 .setFilterCallingUid(isResolver ? 0 /* system */ : targetUid)
1356 .execute();
1357 } catch (SecurityException e) {
1358 // XXX need to figure out how to propagate to original app.
1359 // A SecurityException here is generally actually a fault of the original
1360 // calling activity (such as a fairly granting permissions), so propagate it
1361 // back to them.
1362 /*
1363 StringBuilder msg = new StringBuilder();
1364 msg.append("While launching");
1365 msg.append(intent.toString());
1366 msg.append(": ");
1367 msg.append(e.getMessage());
1368 */
1369 throw e;
1370 }
1371 }
1372
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001373 int handleIncomingUser(int callingPid, int callingUid, int userId, String name) {
1374 return mAmInternal.handleIncomingUser(callingPid, callingUid, userId, false /* allowAll */,
1375 ALLOW_FULL_ONLY, name, null /* callerPackage */);
1376 }
1377
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001378 @Override
1379 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
1380 Intent intent, String resolvedType, IVoiceInteractionSession session,
1381 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
1382 Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001383 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001384 if (session == null || interactor == null) {
1385 throw new NullPointerException("null session or interactor");
1386 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001387 userId = handleIncomingUser(callingPid, callingUid, userId, "startVoiceActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001388 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001389 return getActivityStartController().obtainStarter(intent, "startVoiceActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001390 .setCallingUid(callingUid)
1391 .setCallingPackage(callingPackage)
1392 .setResolvedType(resolvedType)
1393 .setVoiceSession(session)
1394 .setVoiceInteractor(interactor)
1395 .setStartFlags(startFlags)
1396 .setProfilerInfo(profilerInfo)
1397 .setActivityOptions(bOptions)
1398 .setMayWait(userId)
Michal Karpinski85fa2022019-02-08 12:05:09 +00001399 .setAllowBackgroundActivityStart(true)
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001400 .execute();
1401 }
1402
1403 @Override
1404 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
1405 Intent intent, String resolvedType, Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001406 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
1407 userId = handleIncomingUser(callingPid, callingUid, userId, "startAssistantActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001408
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001409 return getActivityStartController().obtainStarter(intent, "startAssistantActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001410 .setCallingUid(callingUid)
1411 .setCallingPackage(callingPackage)
1412 .setResolvedType(resolvedType)
1413 .setActivityOptions(bOptions)
1414 .setMayWait(userId)
Michal Karpinski85fa2022019-02-08 12:05:09 +00001415 .setAllowBackgroundActivityStart(true)
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001416 .execute();
1417 }
1418
1419 @Override
1420 public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
1421 IRecentsAnimationRunner recentsAnimationRunner) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001422 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001423 final int callingPid = Binder.getCallingPid();
1424 final long origId = Binder.clearCallingIdentity();
1425 try {
1426 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07001427 final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
1428 final int recentsUid = mRecentTasks.getRecentsComponentUid();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001429
1430 // Start a new recents animation
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001431 final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
1432 getActivityStartController(), mWindowManager, callingPid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001433 anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
1434 recentsUid, assistDataReceiver);
1435 }
1436 } finally {
1437 Binder.restoreCallingIdentity(origId);
1438 }
1439 }
1440
1441 @Override
1442 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001443 enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001444 "startActivityFromRecents()");
1445
1446 final int callingPid = Binder.getCallingPid();
1447 final int callingUid = Binder.getCallingUid();
1448 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(bOptions);
1449 final long origId = Binder.clearCallingIdentity();
1450 try {
1451 synchronized (mGlobalLock) {
1452 return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
1453 safeOptions);
1454 }
1455 } finally {
1456 Binder.restoreCallingIdentity(origId);
1457 }
1458 }
1459
1460 /**
Andrii Kulian2eb84b22018-12-13 18:18:54 -08001461 * Public API to check if the client is allowed to start an activity on specified display.
1462 *
1463 * If the target display is private or virtual, some restrictions will apply.
1464 *
1465 * @param displayId Target display id.
1466 * @param intent Intent used to launch the activity.
1467 * @param resolvedType The MIME type of the intent.
1468 * @param userId The id of the user for whom the call is made.
1469 * @return {@code true} if a call to start an activity on the target display should succeed and
1470 * no {@link SecurityException} will be thrown, {@code false} otherwise.
1471 */
1472 @Override
1473 public final boolean isActivityStartAllowedOnDisplay(int displayId, Intent intent,
1474 String resolvedType, int userId) {
1475 final int callingUid = Binder.getCallingUid();
1476 final int callingPid = Binder.getCallingPid();
1477 final long origId = Binder.clearCallingIdentity();
1478
1479 try {
1480 // Collect information about the target of the Intent.
1481 ActivityInfo aInfo = mStackSupervisor.resolveActivity(intent, resolvedType,
1482 0 /* startFlags */, null /* profilerInfo */, userId,
1483 ActivityStarter.computeResolveFilterUid(callingUid, callingUid,
1484 UserHandle.USER_NULL));
1485 aInfo = mAmInternal.getActivityInfoForUser(aInfo, userId);
1486
1487 synchronized (mGlobalLock) {
1488 return mStackSupervisor.canPlaceEntityOnDisplay(displayId, callingPid, callingUid,
1489 aInfo);
1490 }
1491 } finally {
1492 Binder.restoreCallingIdentity(origId);
1493 }
1494 }
1495
1496 /**
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001497 * This is the internal entry point for handling Activity.finish().
1498 *
1499 * @param token The Binder token referencing the Activity we want to finish.
1500 * @param resultCode Result code, if any, from this Activity.
1501 * @param resultData Result data (Intent), if any, from this Activity.
1502 * @param finishTask Whether to finish the task associated with this Activity.
1503 *
1504 * @return Returns true if the activity successfully finished, or false if it is still running.
1505 */
1506 @Override
1507 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
1508 int finishTask) {
1509 // Refuse possible leaked file descriptors
1510 if (resultData != null && resultData.hasFileDescriptors()) {
1511 throw new IllegalArgumentException("File descriptors passed in Intent");
1512 }
1513
1514 synchronized (mGlobalLock) {
1515 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1516 if (r == null) {
1517 return true;
1518 }
1519 // Keep track of the root activity of the task before we finish it
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001520 final TaskRecord tr = r.getTaskRecord();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001521 ActivityRecord rootR = tr.getRootActivity();
1522 if (rootR == null) {
1523 Slog.w(TAG, "Finishing task with all activities already finished");
1524 }
1525 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
1526 // finish.
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001527 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001528 return false;
1529 }
1530
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001531 // TODO: There is a dup. of this block of code in ActivityStack.navigateUpToLocked
1532 // We should consolidate.
1533 if (mController != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001534 // Find the first activity that is not finishing.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001535 final ActivityRecord next = r.getActivityStack().topRunningActivityLocked(token, 0);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001536 if (next != null) {
1537 // ask watcher if this is allowed
1538 boolean resumeOK = true;
1539 try {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001540 resumeOK = mController.activityResuming(next.packageName);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001541 } catch (RemoteException e) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001542 mController = null;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001543 Watchdog.getInstance().setActivityController(null);
1544 }
1545
1546 if (!resumeOK) {
1547 Slog.i(TAG, "Not finishing activity because controller resumed");
1548 return false;
1549 }
1550 }
1551 }
1552 final long origId = Binder.clearCallingIdentity();
1553 try {
1554 boolean res;
1555 final boolean finishWithRootActivity =
1556 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
1557 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
1558 || (finishWithRootActivity && r == rootR)) {
1559 // If requested, remove the task that is associated to this activity only if it
1560 // was the root activity in the task. The result code and data is ignored
1561 // because we don't support returning them across task boundaries. Also, to
1562 // keep backwards compatibility we remove the task from recents when finishing
1563 // task with root activity.
1564 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
1565 finishWithRootActivity, "finish-activity");
1566 if (!res) {
1567 Slog.i(TAG, "Removing task failed to finish activity");
1568 }
Garfield Tan2746ab52018-07-25 12:33:01 -07001569 // Explicitly dismissing the activity so reset its relaunch flag.
Wale Ogunwale64258362018-10-16 15:13:37 -07001570 r.mRelaunchReason = RELAUNCH_REASON_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001571 } else {
1572 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
1573 resultData, "app-request", true);
1574 if (!res) {
1575 Slog.i(TAG, "Failed to finish by app-request");
1576 }
1577 }
1578 return res;
1579 } finally {
1580 Binder.restoreCallingIdentity(origId);
1581 }
1582 }
1583 }
1584
1585 @Override
1586 public boolean finishActivityAffinity(IBinder token) {
1587 synchronized (mGlobalLock) {
1588 final long origId = Binder.clearCallingIdentity();
1589 try {
1590 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1591 if (r == null) {
1592 return false;
1593 }
1594
1595 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
1596 // can finish.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001597 final TaskRecord task = r.getTaskRecord();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001598 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001599 return false;
1600 }
1601 return task.getStack().finishActivityAffinityLocked(r);
1602 } finally {
1603 Binder.restoreCallingIdentity(origId);
1604 }
1605 }
1606 }
1607
1608 @Override
1609 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
1610 final long origId = Binder.clearCallingIdentity();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001611 try {
1612 WindowProcessController proc = null;
1613 synchronized (mGlobalLock) {
1614 ActivityStack stack = ActivityRecord.getStackLocked(token);
1615 if (stack == null) {
1616 return;
1617 }
1618 final ActivityRecord r = mStackSupervisor.activityIdleInternalLocked(token,
1619 false /* fromTimeout */, false /* processPausingActivities */, config);
1620 if (r != null) {
1621 proc = r.app;
1622 }
1623 if (stopProfiling && proc != null) {
1624 proc.clearProfilerIfNeeded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001625 }
1626 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001627 } finally {
1628 Binder.restoreCallingIdentity(origId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001629 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001630 }
1631
1632 @Override
1633 public final void activityResumed(IBinder token) {
1634 final long origId = Binder.clearCallingIdentity();
1635 synchronized (mGlobalLock) {
1636 ActivityRecord.activityResumedLocked(token);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001637 mWindowManager.notifyAppResumedFinished(token);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001638 }
1639 Binder.restoreCallingIdentity(origId);
1640 }
1641
1642 @Override
Andrii Kulian86e70fc2019-02-12 11:04:10 +00001643 public final void activityTopResumedStateLost() {
1644 final long origId = Binder.clearCallingIdentity();
1645 synchronized (mGlobalLock) {
1646 mStackSupervisor.handleTopResumedStateReleased(false /* timeout */);
1647 }
1648 Binder.restoreCallingIdentity(origId);
1649 }
1650
1651 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001652 public final void activityPaused(IBinder token) {
1653 final long origId = Binder.clearCallingIdentity();
1654 synchronized (mGlobalLock) {
1655 ActivityStack stack = ActivityRecord.getStackLocked(token);
1656 if (stack != null) {
1657 stack.activityPausedLocked(token, false);
1658 }
1659 }
1660 Binder.restoreCallingIdentity(origId);
1661 }
1662
1663 @Override
1664 public final void activityStopped(IBinder token, Bundle icicle,
1665 PersistableBundle persistentState, CharSequence description) {
1666 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
1667
1668 // Refuse possible leaked file descriptors
1669 if (icicle != null && icicle.hasFileDescriptors()) {
1670 throw new IllegalArgumentException("File descriptors passed in Bundle");
1671 }
1672
1673 final long origId = Binder.clearCallingIdentity();
1674
Riddle Hsu7b766fd2019-01-28 21:14:59 +08001675 String restartingName = null;
1676 int restartingUid = 0;
1677 final ActivityRecord r;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001678 synchronized (mGlobalLock) {
Riddle Hsu7b766fd2019-01-28 21:14:59 +08001679 r = ActivityRecord.isInStackLocked(token);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001680 if (r != null) {
Riddle Hsu7b766fd2019-01-28 21:14:59 +08001681 if (r.attachedToProcess()
1682 && r.isState(ActivityStack.ActivityState.RESTARTING_PROCESS)) {
1683 // The activity was requested to restart from
1684 // {@link #restartActivityProcessIfVisible}.
1685 restartingName = r.app.mName;
1686 restartingUid = r.app.mUid;
1687 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001688 r.activityStoppedLocked(icicle, persistentState, description);
1689 }
1690 }
1691
Riddle Hsu7b766fd2019-01-28 21:14:59 +08001692 if (restartingName != null) {
1693 // In order to let the foreground activity can be restarted with its saved state from
1694 // {@link android.app.Activity#onSaveInstanceState}, the kill operation is postponed
1695 // until the activity reports stopped with the state. And the activity record will be
1696 // kept because the record state is restarting, then the activity will be restarted
1697 // immediately if it is still the top one.
1698 mStackSupervisor.removeRestartTimeouts(r);
1699 mAmInternal.killProcess(restartingName, restartingUid, "restartActivityProcess");
1700 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001701 mAmInternal.trimApplications();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001702
1703 Binder.restoreCallingIdentity(origId);
1704 }
1705
1706 @Override
1707 public final void activityDestroyed(IBinder token) {
1708 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
1709 synchronized (mGlobalLock) {
1710 ActivityStack stack = ActivityRecord.getStackLocked(token);
1711 if (stack != null) {
1712 stack.activityDestroyedLocked(token, "activityDestroyed");
1713 }
1714 }
1715 }
1716
1717 @Override
1718 public final void activityRelaunched(IBinder token) {
1719 final long origId = Binder.clearCallingIdentity();
1720 synchronized (mGlobalLock) {
1721 mStackSupervisor.activityRelaunchedLocked(token);
1722 }
1723 Binder.restoreCallingIdentity(origId);
1724 }
1725
1726 public final void activitySlept(IBinder token) {
1727 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
1728
1729 final long origId = Binder.clearCallingIdentity();
1730
1731 synchronized (mGlobalLock) {
1732 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1733 if (r != null) {
1734 mStackSupervisor.activitySleptLocked(r);
1735 }
1736 }
1737
1738 Binder.restoreCallingIdentity(origId);
1739 }
1740
1741 @Override
1742 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
1743 synchronized (mGlobalLock) {
1744 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1745 if (r == null) {
1746 return;
1747 }
1748 final long origId = Binder.clearCallingIdentity();
1749 try {
1750 r.setRequestedOrientation(requestedOrientation);
1751 } finally {
1752 Binder.restoreCallingIdentity(origId);
1753 }
1754 }
1755 }
1756
1757 @Override
1758 public int getRequestedOrientation(IBinder token) {
1759 synchronized (mGlobalLock) {
1760 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1761 if (r == null) {
1762 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
1763 }
Riddle Hsu0a343c32018-12-21 00:40:48 +08001764 return r.getOrientation();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001765 }
1766 }
1767
1768 @Override
1769 public void setImmersive(IBinder token, boolean immersive) {
1770 synchronized (mGlobalLock) {
1771 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1772 if (r == null) {
1773 throw new IllegalArgumentException();
1774 }
1775 r.immersive = immersive;
1776
1777 // update associated state if we're frontmost
Andrii Kulian52d255c2018-07-13 11:32:19 -07001778 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001779 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001780 applyUpdateLockStateLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001781 }
1782 }
1783 }
1784
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001785 void applyUpdateLockStateLocked(ActivityRecord r) {
1786 // Modifications to the UpdateLock state are done on our handler, outside
1787 // the activity manager's locks. The new state is determined based on the
1788 // state *now* of the relevant activity record. The object is passed to
1789 // the handler solely for logging detail, not to be consulted/modified.
1790 final boolean nextState = r != null && r.immersive;
1791 mH.post(() -> {
1792 if (mUpdateLock.isHeld() != nextState) {
1793 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1794 "Applying new update lock state '" + nextState + "' for " + r);
1795 if (nextState) {
1796 mUpdateLock.acquire();
1797 } else {
1798 mUpdateLock.release();
1799 }
1800 }
1801 });
1802 }
1803
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001804 @Override
1805 public boolean isImmersive(IBinder token) {
1806 synchronized (mGlobalLock) {
1807 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1808 if (r == null) {
1809 throw new IllegalArgumentException();
1810 }
1811 return r.immersive;
1812 }
1813 }
1814
1815 @Override
1816 public boolean isTopActivityImmersive() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001817 enforceNotIsolatedCaller("isTopActivityImmersive");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001818 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001819 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001820 return (r != null) ? r.immersive : false;
1821 }
1822 }
1823
1824 @Override
1825 public void overridePendingTransition(IBinder token, String packageName,
1826 int enterAnim, int exitAnim) {
1827 synchronized (mGlobalLock) {
1828 ActivityRecord self = ActivityRecord.isInStackLocked(token);
1829 if (self == null) {
1830 return;
1831 }
1832
1833 final long origId = Binder.clearCallingIdentity();
1834
1835 if (self.isState(
1836 ActivityStack.ActivityState.RESUMED, ActivityStack.ActivityState.PAUSING)) {
Wale Ogunwale3a256e62018-12-06 14:41:18 -08001837 self.getDisplay().mDisplayContent.mAppTransition.overridePendingAppTransition(
lumark588a3e82018-07-20 18:53:54 +08001838 packageName, enterAnim, exitAnim, null);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001839 }
1840
1841 Binder.restoreCallingIdentity(origId);
1842 }
1843 }
1844
1845 @Override
1846 public int getFrontActivityScreenCompatMode() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001847 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001848 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001849 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001850 if (r == null) {
1851 return ActivityManager.COMPAT_MODE_UNKNOWN;
1852 }
Wale Ogunwale53783742018-09-16 10:21:51 -07001853 return mCompatModePackages.computeCompatModeLocked(r.info.applicationInfo);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001854 }
1855 }
1856
1857 @Override
1858 public void setFrontActivityScreenCompatMode(int mode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001859 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001860 "setFrontActivityScreenCompatMode");
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001861 ApplicationInfo ai;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001862 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001863 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001864 if (r == null) {
1865 Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity");
1866 return;
1867 }
1868 ai = r.info.applicationInfo;
Wale Ogunwale53783742018-09-16 10:21:51 -07001869 mCompatModePackages.setPackageScreenCompatModeLocked(ai, mode);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001870 }
1871 }
1872
1873 @Override
1874 public int getLaunchedFromUid(IBinder activityToken) {
1875 ActivityRecord srec;
1876 synchronized (mGlobalLock) {
1877 srec = ActivityRecord.forTokenLocked(activityToken);
1878 }
1879 if (srec == null) {
1880 return -1;
1881 }
1882 return srec.launchedFromUid;
1883 }
1884
1885 @Override
1886 public String getLaunchedFromPackage(IBinder activityToken) {
1887 ActivityRecord srec;
1888 synchronized (mGlobalLock) {
1889 srec = ActivityRecord.forTokenLocked(activityToken);
1890 }
1891 if (srec == null) {
1892 return null;
1893 }
1894 return srec.launchedFromPackage;
1895 }
1896
1897 @Override
1898 public boolean convertFromTranslucent(IBinder token) {
1899 final long origId = Binder.clearCallingIdentity();
1900 try {
1901 synchronized (mGlobalLock) {
1902 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1903 if (r == null) {
1904 return false;
1905 }
1906 final boolean translucentChanged = r.changeWindowTranslucency(true);
1907 if (translucentChanged) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001908 mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001909 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001910 mWindowManager.setAppFullscreen(token, true);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001911 return translucentChanged;
1912 }
1913 } finally {
1914 Binder.restoreCallingIdentity(origId);
1915 }
1916 }
1917
1918 @Override
1919 public boolean convertToTranslucent(IBinder token, Bundle options) {
1920 SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
1921 final long origId = Binder.clearCallingIdentity();
1922 try {
1923 synchronized (mGlobalLock) {
1924 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1925 if (r == null) {
1926 return false;
1927 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001928 final TaskRecord task = r.getTaskRecord();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001929 int index = task.mActivities.lastIndexOf(r);
1930 if (index > 0) {
1931 ActivityRecord under = task.mActivities.get(index - 1);
1932 under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
1933 }
1934 final boolean translucentChanged = r.changeWindowTranslucency(false);
1935 if (translucentChanged) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001936 r.getActivityStack().convertActivityToTranslucent(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001937 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08001938 mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001939 mWindowManager.setAppFullscreen(token, false);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001940 return translucentChanged;
1941 }
1942 } finally {
1943 Binder.restoreCallingIdentity(origId);
1944 }
1945 }
1946
1947 @Override
1948 public void notifyActivityDrawn(IBinder token) {
1949 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
1950 synchronized (mGlobalLock) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001951 ActivityRecord r = mRootActivityContainer.isInAnyStack(token);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001952 if (r != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001953 r.getActivityStack().notifyActivityDrawnLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001954 }
1955 }
1956 }
1957
1958 @Override
1959 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
1960 synchronized (mGlobalLock) {
1961 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1962 if (r == null) {
1963 return;
1964 }
1965 r.reportFullyDrawnLocked(restoredFromBundle);
1966 }
1967 }
1968
1969 @Override
1970 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
1971 synchronized (mGlobalLock) {
1972 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
1973 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
1974 return stack.mDisplayId;
1975 }
1976 return DEFAULT_DISPLAY;
1977 }
1978 }
1979
1980 @Override
1981 public ActivityManager.StackInfo getFocusedStackInfo() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001982 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001983 long ident = Binder.clearCallingIdentity();
1984 try {
1985 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001986 ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001987 if (focusedStack != null) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001988 return mRootActivityContainer.getStackInfo(focusedStack.mStackId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001989 }
1990 return null;
1991 }
1992 } finally {
1993 Binder.restoreCallingIdentity(ident);
1994 }
1995 }
1996
1997 @Override
1998 public void setFocusedStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001999 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002000 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2001 final long callingId = Binder.clearCallingIdentity();
2002 try {
2003 synchronized (mGlobalLock) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002004 final ActivityStack stack = mRootActivityContainer.getStack(stackId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002005 if (stack == null) {
2006 Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
2007 return;
2008 }
2009 final ActivityRecord r = stack.topRunningActivityLocked();
Louis Chang19443452018-10-09 12:10:21 +08002010 if (r != null && r.moveFocusableActivityToTop("setFocusedStack")) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002011 mRootActivityContainer.resumeFocusedStacksTopActivities();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002012 }
2013 }
2014 } finally {
2015 Binder.restoreCallingIdentity(callingId);
2016 }
2017 }
2018
2019 @Override
2020 public void setFocusedTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002021 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002022 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2023 final long callingId = Binder.clearCallingIdentity();
2024 try {
2025 synchronized (mGlobalLock) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002026 final TaskRecord task = mRootActivityContainer.anyTaskForId(taskId,
Riddle Hsu090ac6f2018-10-31 12:55:29 +08002027 MATCH_TASK_IN_STACKS_ONLY);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002028 if (task == null) {
2029 return;
2030 }
2031 final ActivityRecord r = task.topRunningActivityLocked();
Louis Chang19443452018-10-09 12:10:21 +08002032 if (r != null && r.moveFocusableActivityToTop("setFocusedTask")) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002033 mRootActivityContainer.resumeFocusedStacksTopActivities();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002034 }
2035 }
2036 } finally {
2037 Binder.restoreCallingIdentity(callingId);
2038 }
2039 }
2040
2041 @Override
Riddle Hsu7b766fd2019-01-28 21:14:59 +08002042 public void restartActivityProcessIfVisible(IBinder activityToken) {
2043 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "restartActivityProcess()");
2044 final long callingId = Binder.clearCallingIdentity();
2045 try {
2046 synchronized (mGlobalLock) {
2047 final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
2048 if (r == null) {
2049 return;
2050 }
2051 r.restartProcessIfVisible();
2052 }
2053 } finally {
2054 Binder.restoreCallingIdentity(callingId);
2055 }
2056 }
2057
2058 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002059 public boolean removeTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002060 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002061 synchronized (mGlobalLock) {
2062 final long ident = Binder.clearCallingIdentity();
2063 try {
2064 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
2065 "remove-task");
2066 } finally {
2067 Binder.restoreCallingIdentity(ident);
2068 }
2069 }
2070 }
2071
2072 @Override
Winson Chunge6439102018-07-30 15:48:01 -07002073 public void removeAllVisibleRecentTasks() {
2074 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeAllVisibleRecentTasks()");
2075 synchronized (mGlobalLock) {
2076 final long ident = Binder.clearCallingIdentity();
2077 try {
2078 getRecentTasks().removeAllVisibleTasks();
2079 } finally {
2080 Binder.restoreCallingIdentity(ident);
2081 }
2082 }
2083 }
2084
2085 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002086 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
2087 synchronized (mGlobalLock) {
2088 final ActivityRecord srec = ActivityRecord.forTokenLocked(token);
2089 if (srec != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002090 return srec.getActivityStack().shouldUpRecreateTaskLocked(srec, destAffinity);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002091 }
2092 }
2093 return false;
2094 }
2095
2096 @Override
2097 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
2098 Intent resultData) {
2099
2100 synchronized (mGlobalLock) {
2101 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2102 if (r != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002103 return r.getActivityStack().navigateUpToLocked(
2104 r, destIntent, resultCode, resultData);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002105 }
2106 return false;
2107 }
2108 }
2109
2110 /**
2111 * Attempts to move a task backwards in z-order (the order of activities within the task is
2112 * unchanged).
2113 *
2114 * There are several possible results of this call:
2115 * - if the task is locked, then we will show the lock toast
2116 * - if there is a task behind the provided task, then that task is made visible and resumed as
2117 * this task is moved to the back
2118 * - otherwise, if there are no other tasks in the stack:
2119 * - if this task is in the pinned stack, then we remove the stack completely, which will
2120 * have the effect of moving the task to the top or bottom of the fullscreen stack
2121 * (depending on whether it is visible)
2122 * - otherwise, we simply return home and hide this task
2123 *
2124 * @param token A reference to the activity we wish to move
2125 * @param nonRoot If false then this only works if the activity is the root
2126 * of a task; if true it will work for any activity in a task.
2127 * @return Returns true if the move completed, false if not.
2128 */
2129 @Override
2130 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002131 enforceNotIsolatedCaller("moveActivityTaskToBack");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002132 synchronized (mGlobalLock) {
2133 final long origId = Binder.clearCallingIdentity();
2134 try {
2135 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002136 final TaskRecord task = mRootActivityContainer.anyTaskForId(taskId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002137 if (task != null) {
2138 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
2139 }
2140 } finally {
2141 Binder.restoreCallingIdentity(origId);
2142 }
2143 }
2144 return false;
2145 }
2146
2147 @Override
2148 public Rect getTaskBounds(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002149 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002150 long ident = Binder.clearCallingIdentity();
2151 Rect rect = new Rect();
2152 try {
2153 synchronized (mGlobalLock) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002154 final TaskRecord task = mRootActivityContainer.anyTaskForId(taskId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002155 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
2156 if (task == null) {
2157 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
2158 return rect;
2159 }
2160 if (task.getStack() != null) {
2161 // Return the bounds from window manager since it will be adjusted for various
2162 // things like the presense of a docked stack for tasks that aren't resizeable.
2163 task.getWindowContainerBounds(rect);
2164 } else {
2165 // Task isn't in window manager yet since it isn't associated with a stack.
2166 // Return the persist value from activity manager
2167 if (!task.matchParentBounds()) {
2168 rect.set(task.getBounds());
2169 } else if (task.mLastNonFullscreenBounds != null) {
2170 rect.set(task.mLastNonFullscreenBounds);
2171 }
2172 }
2173 }
2174 } finally {
2175 Binder.restoreCallingIdentity(ident);
2176 }
2177 return rect;
2178 }
2179
2180 @Override
2181 public ActivityManager.TaskDescription getTaskDescription(int id) {
2182 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002183 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002184 MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
Wale Ogunwaled32da472018-11-16 07:19:28 -08002185 final TaskRecord tr = mRootActivityContainer.anyTaskForId(id,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002186 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
2187 if (tr != null) {
2188 return tr.lastTaskDescription;
2189 }
2190 }
2191 return null;
2192 }
2193
2194 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002195 public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
2196 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
2197 setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
2198 toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
2199 return;
2200 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002201 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002202 synchronized (mGlobalLock) {
2203 final long ident = Binder.clearCallingIdentity();
2204 try {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002205 final TaskRecord task = mRootActivityContainer.anyTaskForId(taskId,
Riddle Hsu090ac6f2018-10-31 12:55:29 +08002206 MATCH_TASK_IN_STACKS_ONLY);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002207 if (task == null) {
2208 Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
2209 return;
2210 }
2211
2212 if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
2213 + " to windowingMode=" + windowingMode + " toTop=" + toTop);
2214
2215 if (!task.isActivityTypeStandardOrUndefined()) {
2216 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
2217 + " non-standard task " + taskId + " to windowing mode="
2218 + windowingMode);
2219 }
2220
2221 final ActivityStack stack = task.getStack();
2222 if (toTop) {
2223 stack.moveToFront("setTaskWindowingMode", task);
2224 }
2225 stack.setWindowingMode(windowingMode);
2226 } finally {
2227 Binder.restoreCallingIdentity(ident);
2228 }
2229 }
2230 }
2231
2232 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002233 public String getCallingPackage(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002234 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002235 ActivityRecord r = getCallingRecordLocked(token);
2236 return r != null ? r.info.packageName : null;
2237 }
2238 }
2239
2240 @Override
2241 public ComponentName getCallingActivity(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002242 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002243 ActivityRecord r = getCallingRecordLocked(token);
2244 return r != null ? r.intent.getComponent() : null;
2245 }
2246 }
2247
2248 private ActivityRecord getCallingRecordLocked(IBinder token) {
2249 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2250 if (r == null) {
2251 return null;
2252 }
2253 return r.resultTo;
2254 }
2255
2256 @Override
2257 public void unhandledBack() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002258 mAmInternal.enforceCallingPermission(android.Manifest.permission.FORCE_BACK, "unhandledBack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002259
2260 synchronized (mGlobalLock) {
2261 final long origId = Binder.clearCallingIdentity();
2262 try {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002263 getTopDisplayFocusedStack().unhandledBackLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002264 } finally {
2265 Binder.restoreCallingIdentity(origId);
2266 }
2267 }
2268 }
2269
2270 /**
2271 * TODO: Add mController hook
2272 */
2273 @Override
2274 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002275 mAmInternal.enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002276
2277 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
2278 synchronized (mGlobalLock) {
2279 moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
2280 false /* fromRecents */);
2281 }
2282 }
2283
2284 void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
2285 boolean fromRecents) {
2286
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002287 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002288 Binder.getCallingUid(), -1, -1, "Task to front")) {
2289 SafeActivityOptions.abort(options);
2290 return;
2291 }
2292 final long origId = Binder.clearCallingIdentity();
2293 try {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002294 final TaskRecord task = mRootActivityContainer.anyTaskForId(taskId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002295 if (task == null) {
2296 Slog.d(TAG, "Could not find task for id: "+ taskId);
Winson Chungd0243682018-09-25 18:11:54 -07002297 SafeActivityOptions.abort(options);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002298 return;
2299 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002300 if (getLockTaskController().isLockTaskModeViolation(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002301 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
Winson Chungd0243682018-09-25 18:11:54 -07002302 SafeActivityOptions.abort(options);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002303 return;
2304 }
2305 ActivityOptions realOptions = options != null
2306 ? options.getOptions(mStackSupervisor)
2307 : null;
2308 mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
2309 false /* forceNonResizable */);
2310
2311 final ActivityRecord topActivity = task.getTopActivity();
2312 if (topActivity != null) {
2313
2314 // We are reshowing a task, use a starting window to hide the initial draw delay
2315 // so the transition can start earlier.
2316 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
2317 true /* taskSwitch */, fromRecents);
2318 }
2319 } finally {
2320 Binder.restoreCallingIdentity(origId);
2321 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002322 }
2323
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002324 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
2325 int callingPid, int callingUid, String name) {
2326 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
2327 return true;
2328 }
2329
2330 if (getRecentTasks().isCallerRecents(sourceUid)) {
2331 return true;
2332 }
2333
2334 int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
2335 if (perm == PackageManager.PERMISSION_GRANTED) {
2336 return true;
2337 }
2338 if (checkAllowAppSwitchUid(sourceUid)) {
2339 return true;
2340 }
2341
2342 // If the actual IPC caller is different from the logical source, then
2343 // also see if they are allowed to control app switches.
2344 if (callingUid != -1 && callingUid != sourceUid) {
2345 perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
2346 if (perm == PackageManager.PERMISSION_GRANTED) {
2347 return true;
2348 }
2349 if (checkAllowAppSwitchUid(callingUid)) {
2350 return true;
2351 }
2352 }
2353
2354 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
2355 return false;
2356 }
2357
2358 private boolean checkAllowAppSwitchUid(int uid) {
2359 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
2360 if (types != null) {
2361 for (int i = types.size() - 1; i >= 0; i--) {
2362 if (types.valueAt(i).intValue() == uid) {
2363 return true;
2364 }
2365 }
2366 }
2367 return false;
2368 }
2369
2370 @Override
2371 public void setActivityController(IActivityController controller, boolean imAMonkey) {
2372 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
2373 "setActivityController()");
2374 synchronized (mGlobalLock) {
2375 mController = controller;
2376 mControllerIsAMonkey = imAMonkey;
2377 Watchdog.getInstance().setActivityController(controller);
2378 }
2379 }
2380
Wale Ogunwale387b34c2018-10-25 19:59:40 -07002381 public boolean isControllerAMonkey() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002382 synchronized (mGlobalLock) {
2383 return mController != null && mControllerIsAMonkey;
2384 }
2385 }
2386
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002387 @Override
2388 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
2389 synchronized (mGlobalLock) {
2390 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
2391 }
2392 }
2393
2394 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002395 public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum) {
2396 return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
2397 }
2398
2399 @Override
2400 public List<ActivityManager.RunningTaskInfo> getFilteredTasks(int maxNum,
2401 @WindowConfiguration.ActivityType int ignoreActivityType,
2402 @WindowConfiguration.WindowingMode int ignoreWindowingMode) {
2403 final int callingUid = Binder.getCallingUid();
2404 ArrayList<ActivityManager.RunningTaskInfo> list = new ArrayList<>();
2405
2406 synchronized (mGlobalLock) {
2407 if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
2408
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002409 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002410 callingUid);
Wale Ogunwaled32da472018-11-16 07:19:28 -08002411 mRootActivityContainer.getRunningTasks(maxNum, list, ignoreActivityType,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002412 ignoreWindowingMode, callingUid, allowed);
2413 }
2414
2415 return list;
2416 }
2417
2418 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002419 public final void finishSubActivity(IBinder token, String resultWho, int requestCode) {
2420 synchronized (mGlobalLock) {
2421 final long origId = Binder.clearCallingIdentity();
2422 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2423 if (r != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002424 r.getActivityStack().finishSubActivityLocked(r, resultWho, requestCode);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002425 }
2426 Binder.restoreCallingIdentity(origId);
2427 }
2428 }
2429
2430 @Override
2431 public boolean willActivityBeVisible(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002432 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002433 ActivityStack stack = ActivityRecord.getStackLocked(token);
2434 if (stack != null) {
2435 return stack.willActivityBeVisibleLocked(token);
2436 }
2437 return false;
2438 }
2439 }
2440
2441 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002442 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002443 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002444 synchronized (mGlobalLock) {
2445 final long ident = Binder.clearCallingIdentity();
2446 try {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002447 final TaskRecord task = mRootActivityContainer.anyTaskForId(taskId);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002448 if (task == null) {
2449 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
2450 return;
2451 }
2452
2453 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
2454 + " to stackId=" + stackId + " toTop=" + toTop);
2455
Wale Ogunwaled32da472018-11-16 07:19:28 -08002456 final ActivityStack stack = mRootActivityContainer.getStack(stackId);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002457 if (stack == null) {
2458 throw new IllegalStateException(
2459 "moveTaskToStack: No stack for stackId=" + stackId);
2460 }
2461 if (!stack.isActivityTypeStandardOrUndefined()) {
2462 throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
2463 + taskId + " to stack " + stackId);
2464 }
2465 if (stack.inSplitScreenPrimaryWindowingMode()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002466 mWindowManager.setDockedStackCreateState(
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002467 SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
2468 }
2469 task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
2470 "moveTaskToStack");
2471 } finally {
2472 Binder.restoreCallingIdentity(ident);
2473 }
2474 }
2475 }
2476
2477 @Override
2478 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
2479 boolean preserveWindows, boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002480 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002481
2482 final long ident = Binder.clearCallingIdentity();
2483 try {
2484 synchronized (mGlobalLock) {
2485 if (animate) {
Yunfan Chen279f5582018-12-12 15:24:50 -08002486 final ActivityStack stack = mRootActivityContainer.getStack(stackId);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002487 if (stack == null) {
2488 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2489 return;
2490 }
2491 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
2492 throw new IllegalArgumentException("Stack: " + stackId
2493 + " doesn't support animated resize.");
2494 }
2495 stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
2496 animationDuration, false /* fromFullscreen */);
2497 } else {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002498 final ActivityStack stack = mRootActivityContainer.getStack(stackId);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002499 if (stack == null) {
2500 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2501 return;
2502 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08002503 mRootActivityContainer.resizeStack(stack, destBounds,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002504 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
2505 preserveWindows, allowResizeInDockedMode, !DEFER_RESUME);
2506 }
2507 }
2508 } finally {
2509 Binder.restoreCallingIdentity(ident);
2510 }
2511 }
2512
wilsonshih5c4cf522019-01-25 09:03:47 +08002513 @Override
2514 public void offsetPinnedStackBounds(int stackId, Rect compareBounds, int xOffset, int yOffset,
2515 int animationDuration) {
2516 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "offsetPinnedStackBounds()");
2517
2518 final long ident = Binder.clearCallingIdentity();
2519 try {
2520 synchronized (mGlobalLock) {
2521 if (xOffset == 0 && yOffset == 0) {
2522 return;
2523 }
2524 final ActivityStack stack = mRootActivityContainer.getStack(stackId);
2525 if (stack == null) {
2526 Slog.w(TAG, "offsetPinnedStackBounds: stackId " + stackId + " not found.");
2527 return;
2528 }
2529 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
2530 throw new IllegalArgumentException("Stack: " + stackId
2531 + " doesn't support animated resize.");
2532 }
2533 final Rect destBounds = new Rect();
2534 stack.getAnimationOrCurrentBounds(destBounds);
wilsonshiha6e408c2019-02-19 17:30:03 +08002535 if (destBounds.isEmpty() || !destBounds.equals(compareBounds)) {
wilsonshih5c4cf522019-01-25 09:03:47 +08002536 Slog.w(TAG, "The current stack bounds does not matched! It may be obsolete.");
2537 return;
2538 }
2539 destBounds.offset(xOffset, yOffset);
2540 stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
2541 animationDuration, false /* fromFullscreen */);
2542 }
2543 } finally {
2544 Binder.restoreCallingIdentity(ident);
2545 }
2546 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002547 /**
2548 * Moves the specified task to the primary-split-screen stack.
2549 *
2550 * @param taskId Id of task to move.
2551 * @param createMode The mode the primary split screen stack should be created in if it doesn't
2552 * exist already. See
2553 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
2554 * and
2555 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
2556 * @param toTop If the task and stack should be moved to the top.
2557 * @param animate Whether we should play an animation for the moving the task.
2558 * @param initialBounds If the primary stack gets created, it will use these bounds for the
2559 * stack. Pass {@code null} to use default bounds.
2560 * @param showRecents If the recents activity should be shown on the other side of the task
2561 * going into split-screen mode.
2562 */
2563 @Override
2564 public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode,
2565 boolean toTop, boolean animate, Rect initialBounds, boolean showRecents) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002566 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002567 "setTaskWindowingModeSplitScreenPrimary()");
2568 synchronized (mGlobalLock) {
2569 final long ident = Binder.clearCallingIdentity();
2570 try {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002571 final TaskRecord task = mRootActivityContainer.anyTaskForId(taskId,
Riddle Hsu090ac6f2018-10-31 12:55:29 +08002572 MATCH_TASK_IN_STACKS_ONLY);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002573 if (task == null) {
2574 Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
2575 return false;
2576 }
2577 if (DEBUG_STACK) Slog.d(TAG_STACK,
2578 "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
2579 + " to createMode=" + createMode + " toTop=" + toTop);
2580 if (!task.isActivityTypeStandardOrUndefined()) {
2581 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
2582 + " non-standard task " + taskId + " to split-screen windowing mode");
2583 }
2584
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002585 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002586 final int windowingMode = task.getWindowingMode();
2587 final ActivityStack stack = task.getStack();
2588 if (toTop) {
2589 stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
2590 }
2591 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
Evan Roskyc5abbd82018-10-05 16:02:19 -07002592 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */,
2593 false /* creating */);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002594 return windowingMode != task.getWindowingMode();
2595 } finally {
2596 Binder.restoreCallingIdentity(ident);
2597 }
2598 }
2599 }
2600
2601 /**
2602 * Removes stacks in the input windowing modes from the system if they are of activity type
2603 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
2604 */
2605 @Override
2606 public void removeStacksInWindowingModes(int[] windowingModes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002607 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002608 "removeStacksInWindowingModes()");
2609
2610 synchronized (mGlobalLock) {
2611 final long ident = Binder.clearCallingIdentity();
2612 try {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002613 mRootActivityContainer.removeStacksInWindowingModes(windowingModes);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002614 } finally {
2615 Binder.restoreCallingIdentity(ident);
2616 }
2617 }
2618 }
2619
2620 @Override
2621 public void removeStacksWithActivityTypes(int[] activityTypes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002622 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002623 "removeStacksWithActivityTypes()");
2624
2625 synchronized (mGlobalLock) {
2626 final long ident = Binder.clearCallingIdentity();
2627 try {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002628 mRootActivityContainer.removeStacksWithActivityTypes(activityTypes);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002629 } finally {
2630 Binder.restoreCallingIdentity(ident);
2631 }
2632 }
2633 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002634
2635 @Override
2636 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
2637 int userId) {
2638 final int callingUid = Binder.getCallingUid();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002639 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, "getRecentTasks");
2640 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002641 callingUid);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002642 final boolean detailed = checkGetTasksPermission(
2643 android.Manifest.permission.GET_DETAILED_TASKS, Binder.getCallingPid(),
2644 UserHandle.getAppId(callingUid))
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002645 == PackageManager.PERMISSION_GRANTED;
2646
2647 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002648 return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002649 callingUid);
2650 }
2651 }
2652
2653 @Override
2654 public List<ActivityManager.StackInfo> getAllStackInfos() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002655 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002656 long ident = Binder.clearCallingIdentity();
2657 try {
2658 synchronized (mGlobalLock) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002659 return mRootActivityContainer.getAllStackInfos();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002660 }
2661 } finally {
2662 Binder.restoreCallingIdentity(ident);
2663 }
2664 }
2665
2666 @Override
2667 public ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002668 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002669 long ident = Binder.clearCallingIdentity();
2670 try {
2671 synchronized (mGlobalLock) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002672 return mRootActivityContainer.getStackInfo(windowingMode, activityType);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002673 }
2674 } finally {
2675 Binder.restoreCallingIdentity(ident);
2676 }
2677 }
2678
2679 @Override
2680 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002681 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002682 final long callingUid = Binder.getCallingUid();
2683 final long origId = Binder.clearCallingIdentity();
2684 try {
2685 synchronized (mGlobalLock) {
2686 // Cancel the recents animation synchronously (do not hold the WM lock)
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002687 mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002688 ? REORDER_MOVE_TO_ORIGINAL_POSITION
2689 : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
2690 }
2691 } finally {
2692 Binder.restoreCallingIdentity(origId);
2693 }
2694 }
2695
2696 @Override
2697 public void startLockTaskModeByToken(IBinder token) {
2698 synchronized (mGlobalLock) {
2699 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2700 if (r == null) {
2701 return;
2702 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002703 startLockTaskModeLocked(r.getTaskRecord(), false /* isSystemCaller */);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002704 }
2705 }
2706
2707 @Override
Riddle Hsu090ac6f2018-10-31 12:55:29 +08002708 public void startSystemLockTaskMode(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002709 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002710 // This makes inner call to look as if it was initiated by system.
2711 long ident = Binder.clearCallingIdentity();
2712 try {
2713 synchronized (mGlobalLock) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002714 final TaskRecord task = mRootActivityContainer.anyTaskForId(taskId,
Riddle Hsu090ac6f2018-10-31 12:55:29 +08002715 MATCH_TASK_IN_STACKS_ONLY);
2716 if (task == null) {
2717 return;
2718 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002719
2720 // When starting lock task mode the stack must be in front and focused
2721 task.getStack().moveToFront("startSystemLockTaskMode");
2722 startLockTaskModeLocked(task, true /* isSystemCaller */);
2723 }
2724 } finally {
2725 Binder.restoreCallingIdentity(ident);
2726 }
2727 }
2728
2729 @Override
2730 public void stopLockTaskModeByToken(IBinder token) {
2731 synchronized (mGlobalLock) {
2732 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2733 if (r == null) {
2734 return;
2735 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002736 stopLockTaskModeInternal(r.getTaskRecord(), false /* isSystemCaller */);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002737 }
2738 }
2739
2740 /**
2741 * This API should be called by SystemUI only when user perform certain action to dismiss
2742 * lock task mode. We should only dismiss pinned lock task mode in this case.
2743 */
2744 @Override
2745 public void stopSystemLockTaskMode() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002746 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002747 stopLockTaskModeInternal(null, true /* isSystemCaller */);
2748 }
2749
2750 private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
2751 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
2752 if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
2753 return;
2754 }
2755
Wale Ogunwaled32da472018-11-16 07:19:28 -08002756 final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002757 if (stack == null || task != stack.topTask()) {
2758 throw new IllegalArgumentException("Invalid task, not in foreground");
2759 }
2760
2761 // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
2762 // system or a specific app.
2763 // * System-initiated requests will only start the pinned mode (screen pinning)
2764 // * App-initiated requests
2765 // - will put the device in fully locked mode (LockTask), if the app is whitelisted
2766 // - will start the pinned mode, otherwise
2767 final int callingUid = Binder.getCallingUid();
2768 long ident = Binder.clearCallingIdentity();
2769 try {
2770 // When a task is locked, dismiss the pinned stack if it exists
Wale Ogunwaled32da472018-11-16 07:19:28 -08002771 mRootActivityContainer.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002772
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002773 getLockTaskController().startLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002774 } finally {
2775 Binder.restoreCallingIdentity(ident);
2776 }
2777 }
2778
2779 private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
2780 final int callingUid = Binder.getCallingUid();
2781 long ident = Binder.clearCallingIdentity();
2782 try {
2783 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002784 getLockTaskController().stopLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002785 }
2786 // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
2787 // task and jumping straight into a call in the case of emergency call back.
2788 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
2789 if (tm != null) {
2790 tm.showInCallScreen(false);
2791 }
2792 } finally {
2793 Binder.restoreCallingIdentity(ident);
2794 }
2795 }
2796
2797 @Override
Wale Ogunwale27c48ae2018-10-25 19:01:01 -07002798 public void updateLockTaskPackages(int userId, String[] packages) {
2799 final int callingUid = Binder.getCallingUid();
2800 if (callingUid != 0 && callingUid != SYSTEM_UID) {
2801 mAmInternal.enforceCallingPermission(Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
2802 "updateLockTaskPackages()");
2803 }
2804 synchronized (this) {
2805 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":"
2806 + Arrays.toString(packages));
2807 getLockTaskController().updateLockTaskPackages(userId, packages);
2808 }
2809 }
2810
2811 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002812 public boolean isInLockTaskMode() {
2813 return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
2814 }
2815
2816 @Override
2817 public int getLockTaskModeState() {
2818 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002819 return getLockTaskController().getLockTaskModeState();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002820 }
2821 }
2822
2823 @Override
2824 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
2825 synchronized (mGlobalLock) {
2826 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2827 if (r != null) {
2828 r.setTaskDescription(td);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002829 final TaskRecord task = r.getTaskRecord();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002830 task.updateTaskDescription();
Mark Renoufc808f062019-02-07 15:20:37 -05002831 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.getTaskInfo());
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002832 }
2833 }
2834 }
2835
2836 @Override
2837 public Bundle getActivityOptions(IBinder token) {
2838 final long origId = Binder.clearCallingIdentity();
2839 try {
2840 synchronized (mGlobalLock) {
2841 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
2842 if (r != null) {
2843 final ActivityOptions activityOptions = r.takeOptionsLocked();
2844 return activityOptions == null ? null : activityOptions.toBundle();
2845 }
2846 return null;
2847 }
2848 } finally {
2849 Binder.restoreCallingIdentity(origId);
2850 }
2851 }
2852
2853 @Override
2854 public List<IBinder> getAppTasks(String callingPackage) {
2855 int callingUid = Binder.getCallingUid();
2856 long ident = Binder.clearCallingIdentity();
2857 try {
2858 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002859 return mRecentTasks.getAppTasksList(callingUid, callingPackage);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002860 }
2861 } finally {
2862 Binder.restoreCallingIdentity(ident);
2863 }
2864 }
2865
2866 @Override
2867 public void finishVoiceTask(IVoiceInteractionSession session) {
2868 synchronized (mGlobalLock) {
2869 final long origId = Binder.clearCallingIdentity();
2870 try {
2871 // TODO: VI Consider treating local voice interactions and voice tasks
2872 // differently here
Wale Ogunwaled32da472018-11-16 07:19:28 -08002873 mRootActivityContainer.finishVoiceTask(session);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002874 } finally {
2875 Binder.restoreCallingIdentity(origId);
2876 }
2877 }
2878
2879 }
2880
2881 @Override
2882 public boolean isTopOfTask(IBinder token) {
2883 synchronized (mGlobalLock) {
2884 ActivityRecord r = ActivityRecord.isInStackLocked(token);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002885 return r != null && r.getTaskRecord().getTopActivity() == r;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002886 }
2887 }
2888
2889 @Override
2890 public void notifyLaunchTaskBehindComplete(IBinder token) {
2891 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
2892 }
2893
2894 @Override
2895 public void notifyEnterAnimationComplete(IBinder token) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002896 mH.post(() -> {
2897 synchronized (mGlobalLock) {
2898 ActivityRecord r = ActivityRecord.forTokenLocked(token);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002899 if (r != null && r.attachedToProcess()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002900 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002901 r.app.getThread().scheduleEnterAnimationComplete(r.appToken);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002902 } catch (RemoteException e) {
2903 }
2904 }
2905 }
2906
2907 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002908 }
2909
2910 /** Called from an app when assist data is ready. */
2911 @Override
2912 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
2913 AssistContent content, Uri referrer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002914 PendingAssistExtras pae = (PendingAssistExtras) token;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002915 synchronized (pae) {
2916 pae.result = extras;
2917 pae.structure = structure;
2918 pae.content = content;
2919 if (referrer != null) {
2920 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
2921 }
2922 if (structure != null) {
Winson Chung48b25652018-10-22 14:04:30 -07002923 // Pre-fill the task/activity component for all assist data receivers
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002924 structure.setTaskId(pae.activity.getTaskRecord().taskId);
2925 structure.setActivityComponent(pae.activity.mActivityComponent);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002926 structure.setHomeActivity(pae.isHome);
2927 }
2928 pae.haveResult = true;
2929 pae.notifyAll();
2930 if (pae.intent == null && pae.receiver == null) {
2931 // Caller is just waiting for the result.
2932 return;
2933 }
2934 }
2935 // We are now ready to launch the assist activity.
2936 IAssistDataReceiver sendReceiver = null;
2937 Bundle sendBundle = null;
2938 synchronized (mGlobalLock) {
2939 buildAssistBundleLocked(pae, extras);
2940 boolean exists = mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002941 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002942 if (!exists) {
2943 // Timed out.
2944 return;
2945 }
2946
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002947 if ((sendReceiver = pae.receiver) != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002948 // Caller wants result sent back to them.
2949 sendBundle = new Bundle();
2950 sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
2951 sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
2952 sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
2953 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
2954 }
2955 }
2956 if (sendReceiver != null) {
2957 try {
2958 sendReceiver.onHandleAssistData(sendBundle);
2959 } catch (RemoteException e) {
2960 }
2961 return;
2962 }
2963
2964 final long ident = Binder.clearCallingIdentity();
2965 try {
2966 if (TextUtils.equals(pae.intent.getAction(),
2967 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
2968 pae.intent.putExtras(pae.extras);
2969 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
2970 } else {
2971 pae.intent.replaceExtras(pae.extras);
2972 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
2973 | Intent.FLAG_ACTIVITY_SINGLE_TOP
2974 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Wale Ogunwale31913b52018-10-13 08:29:31 -07002975 mInternal.closeSystemDialogs("assist");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002976
2977 try {
2978 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
2979 } catch (ActivityNotFoundException e) {
2980 Slog.w(TAG, "No activity to handle assist action.", e);
2981 }
2982 }
2983 } finally {
2984 Binder.restoreCallingIdentity(ident);
2985 }
2986 }
2987
2988 @Override
2989 public int addAppTask(IBinder activityToken, Intent intent,
2990 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
2991 final int callingUid = Binder.getCallingUid();
2992 final long callingIdent = Binder.clearCallingIdentity();
2993
2994 try {
2995 synchronized (mGlobalLock) {
2996 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
2997 if (r == null) {
2998 throw new IllegalArgumentException("Activity does not exist; token="
2999 + activityToken);
3000 }
3001 ComponentName comp = intent.getComponent();
3002 if (comp == null) {
3003 throw new IllegalArgumentException("Intent " + intent
3004 + " must specify explicit component");
3005 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003006 if (thumbnail.getWidth() != mThumbnailWidth
3007 || thumbnail.getHeight() != mThumbnailHeight) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003008 throw new IllegalArgumentException("Bad thumbnail size: got "
3009 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003010 + mThumbnailWidth + "x" + mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003011 }
3012 if (intent.getSelector() != null) {
3013 intent.setSelector(null);
3014 }
3015 if (intent.getSourceBounds() != null) {
3016 intent.setSourceBounds(null);
3017 }
3018 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
3019 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
3020 // The caller has added this as an auto-remove task... that makes no
3021 // sense, so turn off auto-remove.
3022 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
3023 }
3024 }
3025 final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
3026 STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
3027 if (ainfo.applicationInfo.uid != callingUid) {
3028 throw new SecurityException(
3029 "Can't add task for another application: target uid="
3030 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
3031 }
3032
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003033 final ActivityStack stack = r.getActivityStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003034 final TaskRecord task = stack.createTaskRecord(
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003035 mStackSupervisor.getNextTaskIdForUserLocked(r.mUserId), ainfo, intent,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003036 null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
Wale Ogunwale16e505a2018-05-07 15:00:49 -07003037 if (!mRecentTasks.addToBottom(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003038 // The app has too many tasks already and we can't add any more
3039 stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
3040 return INVALID_TASK_ID;
3041 }
3042 task.lastTaskDescription.copyFrom(description);
3043
3044 // TODO: Send the thumbnail to WM to store it.
3045
3046 return task.taskId;
3047 }
3048 } finally {
3049 Binder.restoreCallingIdentity(callingIdent);
3050 }
3051 }
3052
3053 @Override
3054 public Point getAppTaskThumbnailSize() {
3055 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003056 return new Point(mThumbnailWidth, mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003057 }
3058 }
3059
3060 @Override
3061 public void setTaskResizeable(int taskId, int resizeableMode) {
3062 synchronized (mGlobalLock) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08003063 final TaskRecord task = mRootActivityContainer.anyTaskForId(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003064 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
3065 if (task == null) {
3066 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
3067 return;
3068 }
3069 task.setResizeMode(resizeableMode);
3070 }
3071 }
3072
3073 @Override
3074 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003075 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003076 long ident = Binder.clearCallingIdentity();
3077 try {
3078 synchronized (mGlobalLock) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08003079 final TaskRecord task = mRootActivityContainer.anyTaskForId(taskId,
Riddle Hsu090ac6f2018-10-31 12:55:29 +08003080 MATCH_TASK_IN_STACKS_ONLY);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003081 if (task == null) {
3082 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
3083 return;
3084 }
3085 // Place the task in the right stack if it isn't there already based on
3086 // the requested bounds.
3087 // The stack transition logic is:
3088 // - a null bounds on a freeform task moves that task to fullscreen
3089 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
3090 // that task to freeform
3091 // - otherwise the task is not moved
3092 ActivityStack stack = task.getStack();
3093 if (!task.getWindowConfiguration().canResizeTask()) {
3094 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
3095 }
3096 if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
3097 stack = stack.getDisplay().getOrCreateStack(
3098 WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
3099 } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
3100 stack = stack.getDisplay().getOrCreateStack(
3101 WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
3102 }
3103
3104 // Reparent the task to the right stack if necessary
3105 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
3106 if (stack != task.getStack()) {
3107 // Defer resume until the task is resized below
3108 task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
3109 DEFER_RESUME, "resizeTask");
3110 preserveWindow = false;
3111 }
3112
3113 // After reparenting (which only resizes the task to the stack bounds), resize the
3114 // task to the actual bounds provided
3115 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
3116 }
3117 } finally {
3118 Binder.restoreCallingIdentity(ident);
3119 }
3120 }
3121
3122 @Override
3123 public boolean releaseActivityInstance(IBinder token) {
3124 synchronized (mGlobalLock) {
3125 final long origId = Binder.clearCallingIdentity();
3126 try {
3127 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3128 if (r == null) {
3129 return false;
3130 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003131 return r.getActivityStack().safelyDestroyActivityLocked(r, "app-req");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003132 } finally {
3133 Binder.restoreCallingIdentity(origId);
3134 }
3135 }
3136 }
3137
3138 @Override
3139 public void releaseSomeActivities(IApplicationThread appInt) {
3140 synchronized (mGlobalLock) {
3141 final long origId = Binder.clearCallingIdentity();
3142 try {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07003143 final WindowProcessController app = getProcessController(appInt);
Wale Ogunwaled32da472018-11-16 07:19:28 -08003144 mRootActivityContainer.releaseSomeActivitiesLocked(app, "low-mem");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003145 } finally {
3146 Binder.restoreCallingIdentity(origId);
3147 }
3148 }
3149 }
3150
3151 @Override
wilsonshih177261f2019-02-22 12:02:18 +08003152 public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003153 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003154 != PackageManager.PERMISSION_GRANTED) {
3155 throw new SecurityException("Requires permission "
3156 + android.Manifest.permission.DEVICE_POWER);
3157 }
3158
3159 synchronized (mGlobalLock) {
3160 long ident = Binder.clearCallingIdentity();
3161 if (mKeyguardShown != keyguardShowing) {
3162 mKeyguardShown = keyguardShowing;
Wale Ogunwale342fbe92018-10-09 08:44:10 -07003163 final Message msg = PooledLambda.obtainMessage(
3164 ActivityManagerInternal::reportCurKeyguardUsageEvent, mAmInternal,
3165 keyguardShowing);
3166 mH.sendMessage(msg);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003167 }
3168 try {
wilsonshih177261f2019-02-22 12:02:18 +08003169 mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003170 } finally {
3171 Binder.restoreCallingIdentity(ident);
3172 }
3173 }
3174
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003175 mH.post(() -> {
3176 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
3177 mScreenObservers.get(i).onKeyguardStateChanged(keyguardShowing);
3178 }
3179 });
3180 }
3181
Wale Ogunwale387b34c2018-10-25 19:59:40 -07003182 public void onScreenAwakeChanged(boolean isAwake) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003183 mH.post(() -> {
3184 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
3185 mScreenObservers.get(i).onAwakeStateChanged(isAwake);
3186 }
3187 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003188 }
3189
3190 @Override
3191 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003192 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
3193 userId, "getTaskDescriptionIcon");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003194
3195 final File passedIconFile = new File(filePath);
3196 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
3197 passedIconFile.getName());
3198 if (!legitIconFile.getPath().equals(filePath)
3199 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
3200 throw new IllegalArgumentException("Bad file path: " + filePath
3201 + " passed for userId " + userId);
3202 }
Wale Ogunwale16e505a2018-05-07 15:00:49 -07003203 return mRecentTasks.getTaskDescriptionIcon(filePath);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003204 }
3205
3206 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003207 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003208 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
3209 final ActivityOptions activityOptions = safeOptions != null
3210 ? safeOptions.getOptions(mStackSupervisor)
3211 : null;
3212 if (activityOptions == null
3213 || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
3214 || activityOptions.getCustomInPlaceResId() == 0) {
3215 throw new IllegalArgumentException("Expected in-place ActivityOption " +
3216 "with valid animation");
3217 }
lumark588a3e82018-07-20 18:53:54 +08003218 // Get top display of front most application.
3219 final ActivityStack focusedStack = getTopDisplayFocusedStack();
3220 if (focusedStack != null) {
Wale Ogunwale3a256e62018-12-06 14:41:18 -08003221 final DisplayContent dc = focusedStack.getDisplay().mDisplayContent;
3222 dc.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
3223 dc.mAppTransition.overrideInPlaceAppTransition(activityOptions.getPackageName(),
lumark588a3e82018-07-20 18:53:54 +08003224 activityOptions.getCustomInPlaceResId());
Wale Ogunwale3a256e62018-12-06 14:41:18 -08003225 dc.executeAppTransition();
lumark588a3e82018-07-20 18:53:54 +08003226 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003227 }
3228
3229 @Override
3230 public void removeStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003231 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003232 synchronized (mGlobalLock) {
3233 final long ident = Binder.clearCallingIdentity();
3234 try {
Wale Ogunwaled32da472018-11-16 07:19:28 -08003235 final ActivityStack stack = mRootActivityContainer.getStack(stackId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003236 if (stack == null) {
3237 Slog.w(TAG, "removeStack: No stack with id=" + stackId);
3238 return;
3239 }
3240 if (!stack.isActivityTypeStandardOrUndefined()) {
3241 throw new IllegalArgumentException(
3242 "Removing non-standard stack is not allowed.");
3243 }
3244 mStackSupervisor.removeStack(stack);
3245 } finally {
3246 Binder.restoreCallingIdentity(ident);
3247 }
3248 }
3249 }
3250
3251 @Override
3252 public void moveStackToDisplay(int stackId, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003253 mAmInternal.enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003254
3255 synchronized (mGlobalLock) {
3256 final long ident = Binder.clearCallingIdentity();
3257 try {
3258 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
3259 + " to displayId=" + displayId);
Wale Ogunwaled32da472018-11-16 07:19:28 -08003260 mRootActivityContainer.moveStackToDisplay(stackId, displayId, ON_TOP);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003261 } finally {
3262 Binder.restoreCallingIdentity(ident);
3263 }
3264 }
3265 }
3266
3267 @Override
Yunfan Chend967af82019-01-17 18:30:18 +09003268 public void toggleFreeformWindowingMode(IBinder token) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003269 synchronized (mGlobalLock) {
3270 long ident = Binder.clearCallingIdentity();
3271 try {
3272 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3273 if (r == null) {
3274 throw new IllegalArgumentException(
Yunfan Chend967af82019-01-17 18:30:18 +09003275 "toggleFreeformWindowingMode: No activity record matching token="
3276 + token);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003277 }
3278
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003279 final ActivityStack stack = r.getActivityStack();
Yunfan Chend967af82019-01-17 18:30:18 +09003280 if (stack == null) {
3281 throw new IllegalStateException("toggleFreeformWindowingMode: the activity "
3282 + "doesn't have a stack");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003283 }
3284
Yunfan Chend967af82019-01-17 18:30:18 +09003285 if (!stack.inFreeformWindowingMode()
3286 && stack.getWindowingMode() != WINDOWING_MODE_FULLSCREEN) {
3287 throw new IllegalStateException("toggleFreeformWindowingMode: You can only "
3288 + "toggle between fullscreen and freeform.");
3289 }
3290
3291 if (stack.inFreeformWindowingMode()) {
3292 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
3293 } else {
3294 stack.setWindowingMode(WINDOWING_MODE_FREEFORM);
3295 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003296 } finally {
3297 Binder.restoreCallingIdentity(ident);
3298 }
3299 }
3300 }
3301
3302 /** Sets the task stack listener that gets callbacks when a task stack changes. */
3303 @Override
3304 public void registerTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003305 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003306 "registerTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003307 mTaskChangeNotificationController.registerTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003308 }
3309
3310 /** Unregister a task stack listener so that it stops receiving callbacks. */
3311 @Override
3312 public void unregisterTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003313 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003314 "unregisterTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003315 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003316 }
3317
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003318 @Override
3319 public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
3320 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
3321 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
3322 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
3323 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
3324 }
3325
3326 @Override
3327 public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
3328 IBinder activityToken, int flags) {
3329 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
3330 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
3331 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
3332 }
3333
3334 @Override
3335 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
3336 Bundle args) {
3337 return enqueueAssistContext(requestType, intent, hint, null, null, null,
3338 true /* focused */, true /* newSessionId */, userHandle, args,
3339 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
3340 }
3341
3342 @Override
3343 public Bundle getAssistContextExtras(int requestType) {
3344 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
3345 null, null, true /* focused */, true /* newSessionId */,
3346 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
3347 if (pae == null) {
3348 return null;
3349 }
3350 synchronized (pae) {
3351 while (!pae.haveResult) {
3352 try {
3353 pae.wait();
3354 } catch (InterruptedException e) {
3355 }
3356 }
3357 }
3358 synchronized (mGlobalLock) {
3359 buildAssistBundleLocked(pae, pae.result);
3360 mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003361 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003362 }
3363 return pae.extras;
3364 }
3365
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003366 /**
3367 * Binder IPC calls go through the public entry point.
3368 * This can be called with or without the global lock held.
3369 */
3370 private static int checkCallingPermission(String permission) {
3371 return checkPermission(
3372 permission, Binder.getCallingPid(), UserHandle.getAppId(Binder.getCallingUid()));
3373 }
3374
3375 /** This can be called with or without the global lock held. */
Wale Ogunwale214f3482018-10-04 11:00:47 -07003376 private void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003377 if (!getRecentTasks().isCallerRecents(Binder.getCallingUid())) {
3378 mAmInternal.enforceCallingPermission(permission, func);
3379 }
3380 }
3381
3382 @VisibleForTesting
3383 int checkGetTasksPermission(String permission, int pid, int uid) {
3384 return checkPermission(permission, pid, uid);
3385 }
3386
3387 static int checkPermission(String permission, int pid, int uid) {
3388 if (permission == null) {
3389 return PackageManager.PERMISSION_DENIED;
3390 }
3391 return checkComponentPermission(permission, pid, uid, -1, true);
3392 }
3393
Wale Ogunwale214f3482018-10-04 11:00:47 -07003394 public static int checkComponentPermission(String permission, int pid, int uid,
3395 int owningUid, boolean exported) {
3396 return ActivityManagerService.checkComponentPermission(
3397 permission, pid, uid, owningUid, exported);
3398 }
3399
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003400 boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
3401 if (getRecentTasks().isCallerRecents(callingUid)) {
3402 // Always allow the recents component to get tasks
3403 return true;
3404 }
3405
3406 boolean allowed = checkGetTasksPermission(android.Manifest.permission.REAL_GET_TASKS,
3407 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
3408 if (!allowed) {
3409 if (checkGetTasksPermission(android.Manifest.permission.GET_TASKS,
3410 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
3411 // Temporary compatibility: some existing apps on the system image may
3412 // still be requesting the old permission and not switched to the new
3413 // one; if so, we'll still allow them full access. This means we need
3414 // to see if they are holding the old permission and are a system app.
3415 try {
3416 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
3417 allowed = true;
3418 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
3419 + " is using old GET_TASKS but privileged; allowing");
3420 }
3421 } catch (RemoteException e) {
3422 }
3423 }
3424 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
3425 + " does not hold REAL_GET_TASKS; limiting output");
3426 }
3427 return allowed;
3428 }
3429
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003430 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
3431 IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
3432 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
3433 int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003434 mAmInternal.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003435 "enqueueAssistContext()");
3436
3437 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003438 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003439 if (activity == null) {
3440 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
3441 return null;
3442 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003443 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003444 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
3445 return null;
3446 }
3447 if (focused) {
3448 if (activityToken != null) {
3449 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
3450 if (activity != caller) {
3451 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
3452 + " is not current top " + activity);
3453 return null;
3454 }
3455 }
3456 } else {
3457 activity = ActivityRecord.forTokenLocked(activityToken);
3458 if (activity == null) {
3459 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
3460 + " couldn't be found");
3461 return null;
3462 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003463 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003464 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
3465 return null;
3466 }
3467 }
3468
3469 PendingAssistExtras pae;
3470 Bundle extras = new Bundle();
3471 if (args != null) {
3472 extras.putAll(args);
3473 }
3474 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003475 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003476
3477 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
3478 userHandle);
3479 pae.isHome = activity.isActivityTypeHome();
3480
3481 // Increment the sessionId if necessary
3482 if (newSessionId) {
3483 mViSessionId++;
3484 }
3485 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003486 activity.app.getThread().requestAssistContextExtras(activity.appToken, pae,
3487 requestType, mViSessionId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003488 mPendingAssistExtras.add(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003489 mUiHandler.postDelayed(pae, timeout);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003490 } catch (RemoteException e) {
3491 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
3492 return null;
3493 }
3494 return pae;
3495 }
3496 }
3497
3498 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
3499 if (result != null) {
3500 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
3501 }
3502 if (pae.hint != null) {
3503 pae.extras.putBoolean(pae.hint, true);
3504 }
3505 }
3506
3507 private void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
3508 IAssistDataReceiver receiver;
3509 synchronized (mGlobalLock) {
3510 mPendingAssistExtras.remove(pae);
3511 receiver = pae.receiver;
3512 }
3513 if (receiver != null) {
3514 // Caller wants result sent back to them.
3515 Bundle sendBundle = new Bundle();
3516 // At least return the receiver extras
3517 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
3518 try {
3519 pae.receiver.onHandleAssistData(sendBundle);
3520 } catch (RemoteException e) {
3521 }
3522 }
3523 }
3524
3525 public class PendingAssistExtras extends Binder implements Runnable {
3526 public final ActivityRecord activity;
3527 public boolean isHome;
3528 public final Bundle extras;
3529 public final Intent intent;
3530 public final String hint;
3531 public final IAssistDataReceiver receiver;
3532 public final int userHandle;
3533 public boolean haveResult = false;
3534 public Bundle result = null;
3535 public AssistStructure structure = null;
3536 public AssistContent content = null;
3537 public Bundle receiverExtras;
3538
3539 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
3540 String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
3541 int _userHandle) {
3542 activity = _activity;
3543 extras = _extras;
3544 intent = _intent;
3545 hint = _hint;
3546 receiver = _receiver;
3547 receiverExtras = _receiverExtras;
3548 userHandle = _userHandle;
3549 }
3550
3551 @Override
3552 public void run() {
3553 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
3554 synchronized (this) {
3555 haveResult = true;
3556 notifyAll();
3557 }
3558 pendingAssistExtrasTimedOut(this);
3559 }
3560 }
3561
3562 @Override
3563 public boolean isAssistDataAllowedOnCurrentActivity() {
3564 int userId;
3565 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003566 final ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003567 if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
3568 return false;
3569 }
3570
3571 final ActivityRecord activity = focusedStack.getTopActivity();
3572 if (activity == null) {
3573 return false;
3574 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003575 userId = activity.mUserId;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003576 }
3577 return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
3578 }
3579
3580 @Override
3581 public boolean showAssistFromActivity(IBinder token, Bundle args) {
3582 long ident = Binder.clearCallingIdentity();
3583 try {
3584 synchronized (mGlobalLock) {
3585 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003586 ActivityRecord top = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003587 if (top != caller) {
3588 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3589 + " is not current top " + top);
3590 return false;
3591 }
3592 if (!top.nowVisible) {
3593 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3594 + " is not visible");
3595 return false;
3596 }
3597 }
3598 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
3599 token);
3600 } finally {
3601 Binder.restoreCallingIdentity(ident);
3602 }
3603 }
3604
3605 @Override
3606 public boolean isRootVoiceInteraction(IBinder token) {
3607 synchronized (mGlobalLock) {
3608 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3609 if (r == null) {
3610 return false;
3611 }
3612 return r.rootVoiceInteraction;
3613 }
3614 }
3615
Wale Ogunwalef6733932018-06-27 05:14:34 -07003616 private void onLocalVoiceInteractionStartedLocked(IBinder activity,
3617 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
3618 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
3619 if (activityToCallback == null) return;
3620 activityToCallback.setVoiceSessionLocked(voiceSession);
3621
3622 // Inform the activity
3623 try {
3624 activityToCallback.app.getThread().scheduleLocalVoiceInteractionStarted(activity,
3625 voiceInteractor);
3626 long token = Binder.clearCallingIdentity();
3627 try {
3628 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
3629 } finally {
3630 Binder.restoreCallingIdentity(token);
3631 }
3632 // TODO: VI Should we cache the activity so that it's easier to find later
3633 // rather than scan through all the stacks and activities?
3634 } catch (RemoteException re) {
3635 activityToCallback.clearVoiceSessionLocked();
3636 // TODO: VI Should this terminate the voice session?
3637 }
3638 }
3639
3640 private void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
3641 Slog.d(TAG, "<<< startRunningVoiceLocked()");
3642 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
3643 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
3644 boolean wasRunningVoice = mRunningVoice != null;
3645 mRunningVoice = session;
3646 if (!wasRunningVoice) {
3647 mVoiceWakeLock.acquire();
3648 updateSleepIfNeededLocked();
3649 }
3650 }
3651 }
3652
3653 void finishRunningVoiceLocked() {
3654 if (mRunningVoice != null) {
3655 mRunningVoice = null;
3656 mVoiceWakeLock.release();
3657 updateSleepIfNeededLocked();
3658 }
3659 }
3660
3661 @Override
3662 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3663 synchronized (mGlobalLock) {
3664 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3665 if (keepAwake) {
3666 mVoiceWakeLock.acquire();
3667 } else {
3668 mVoiceWakeLock.release();
3669 }
3670 }
3671 }
3672 }
3673
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003674 @Override
3675 public ComponentName getActivityClassForToken(IBinder token) {
3676 synchronized (mGlobalLock) {
3677 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3678 if (r == null) {
3679 return null;
3680 }
3681 return r.intent.getComponent();
3682 }
3683 }
3684
3685 @Override
3686 public String getPackageForToken(IBinder token) {
3687 synchronized (mGlobalLock) {
3688 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3689 if (r == null) {
3690 return null;
3691 }
3692 return r.packageName;
3693 }
3694 }
3695
3696 @Override
3697 public void showLockTaskEscapeMessage(IBinder token) {
3698 synchronized (mGlobalLock) {
3699 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3700 if (r == null) {
3701 return;
3702 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003703 getLockTaskController().showLockTaskToast();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003704 }
3705 }
3706
3707 @Override
3708 public void keyguardGoingAway(int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003709 enforceNotIsolatedCaller("keyguardGoingAway");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003710 final long token = Binder.clearCallingIdentity();
3711 try {
3712 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003713 mKeyguardController.keyguardGoingAway(flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003714 }
3715 } finally {
3716 Binder.restoreCallingIdentity(token);
3717 }
3718 }
3719
3720 /**
3721 * Try to place task to provided position. The final position might be different depending on
3722 * current user and stacks state. The task will be moved to target stack if it's currently in
3723 * different stack.
3724 */
3725 @Override
3726 public void positionTaskInStack(int taskId, int stackId, int position) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003727 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003728 synchronized (mGlobalLock) {
3729 long ident = Binder.clearCallingIdentity();
3730 try {
3731 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
3732 + taskId + " in stackId=" + stackId + " at position=" + position);
Wale Ogunwaled32da472018-11-16 07:19:28 -08003733 final TaskRecord task = mRootActivityContainer.anyTaskForId(taskId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003734 if (task == null) {
3735 throw new IllegalArgumentException("positionTaskInStack: no task for id="
3736 + taskId);
3737 }
3738
Wale Ogunwaled32da472018-11-16 07:19:28 -08003739 final ActivityStack stack = mRootActivityContainer.getStack(stackId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003740
3741 if (stack == null) {
3742 throw new IllegalArgumentException("positionTaskInStack: no stack for id="
3743 + stackId);
3744 }
3745 if (!stack.isActivityTypeStandardOrUndefined()) {
3746 throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
3747 + " the position of task " + taskId + " in/to non-standard stack");
3748 }
3749
3750 // TODO: Have the callers of this API call a separate reparent method if that is
3751 // what they intended to do vs. having this method also do reparenting.
3752 if (task.getStack() == stack) {
3753 // Change position in current stack.
3754 stack.positionChildAt(task, position);
3755 } else {
3756 // Reparent to new stack.
3757 task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
3758 !DEFER_RESUME, "positionTaskInStack");
3759 }
3760 } finally {
3761 Binder.restoreCallingIdentity(ident);
3762 }
3763 }
3764 }
3765
3766 @Override
3767 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
3768 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
3769 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
3770 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
3771 synchronized (mGlobalLock) {
3772 ActivityRecord record = ActivityRecord.isInStackLocked(token);
3773 if (record == null) {
3774 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
3775 + "found for: " + token);
3776 }
3777 record.setSizeConfigurations(horizontalSizeConfiguration,
3778 verticalSizeConfigurations, smallestSizeConfigurations);
3779 }
3780 }
3781
3782 /**
3783 * Dismisses split-screen multi-window mode.
3784 * @param toTop If true the current primary split-screen stack will be placed or left on top.
3785 */
3786 @Override
3787 public void dismissSplitScreenMode(boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003788 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003789 MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
3790 final long ident = Binder.clearCallingIdentity();
3791 try {
3792 synchronized (mGlobalLock) {
3793 final ActivityStack stack =
Wale Ogunwaled32da472018-11-16 07:19:28 -08003794 mRootActivityContainer.getDefaultDisplay().getSplitScreenPrimaryStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003795 if (stack == null) {
3796 Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
3797 return;
3798 }
3799
3800 if (toTop) {
3801 // Caller wants the current split-screen primary stack to be the top stack after
3802 // it goes fullscreen, so move it to the front.
3803 stack.moveToFront("dismissSplitScreenMode");
Wale Ogunwaled32da472018-11-16 07:19:28 -08003804 } else if (mRootActivityContainer.isTopDisplayFocusedStack(stack)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003805 // In this case the current split-screen primary stack shouldn't be the top
3806 // stack after it goes fullscreen, but it current has focus, so we move the
3807 // focus to the top-most split-screen secondary stack next to it.
3808 final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
3809 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
3810 if (otherStack != null) {
3811 otherStack.moveToFront("dismissSplitScreenMode_other");
3812 }
3813 }
3814
Evan Rosky10475742018-09-05 19:02:48 -07003815 stack.setWindowingMode(WINDOWING_MODE_UNDEFINED);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003816 }
3817 } finally {
3818 Binder.restoreCallingIdentity(ident);
3819 }
3820 }
3821
3822 /**
3823 * Dismisses Pip
3824 * @param animate True if the dismissal should be animated.
3825 * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
3826 * default animation duration should be used.
3827 */
3828 @Override
3829 public void dismissPip(boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003830 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003831 final long ident = Binder.clearCallingIdentity();
3832 try {
3833 synchronized (mGlobalLock) {
Yunfan Chen279f5582018-12-12 15:24:50 -08003834 final ActivityStack stack =
Wale Ogunwaled32da472018-11-16 07:19:28 -08003835 mRootActivityContainer.getDefaultDisplay().getPinnedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003836 if (stack == null) {
3837 Slog.w(TAG, "dismissPip: pinned stack not found.");
3838 return;
3839 }
3840 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
3841 throw new IllegalArgumentException("Stack: " + stack
3842 + " doesn't support animated resize.");
3843 }
3844 if (animate) {
3845 stack.animateResizePinnedStack(null /* sourceHintBounds */,
3846 null /* destBounds */, animationDuration, false /* fromFullscreen */);
3847 } else {
3848 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
3849 }
3850 }
3851 } finally {
3852 Binder.restoreCallingIdentity(ident);
3853 }
3854 }
3855
3856 @Override
3857 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003858 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003859 synchronized (mGlobalLock) {
3860 mSuppressResizeConfigChanges = suppress;
3861 }
3862 }
3863
3864 /**
3865 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
3866 * animated the stack to the fullscreen, but can also be called if we are relaunching an
3867 * activity and clearing the task at the same time.
3868 */
3869 @Override
3870 // TODO: API should just be about changing windowing modes...
3871 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003872 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003873 "moveTasksToFullscreenStack()");
3874 synchronized (mGlobalLock) {
3875 final long origId = Binder.clearCallingIdentity();
3876 try {
Wale Ogunwaled32da472018-11-16 07:19:28 -08003877 final ActivityStack stack = mRootActivityContainer.getStack(fromStackId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003878 if (stack != null){
3879 if (!stack.isActivityTypeStandardOrUndefined()) {
3880 throw new IllegalArgumentException(
3881 "You can't move tasks from non-standard stacks.");
3882 }
3883 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
3884 }
3885 } finally {
3886 Binder.restoreCallingIdentity(origId);
3887 }
3888 }
3889 }
3890
3891 /**
3892 * Moves the top activity in the input stackId to the pinned stack.
3893 *
3894 * @param stackId Id of stack to move the top activity to pinned stack.
3895 * @param bounds Bounds to use for pinned stack.
3896 *
3897 * @return True if the top activity of the input stack was successfully moved to the pinned
3898 * stack.
3899 */
3900 @Override
3901 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003902 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003903 "moveTopActivityToPinnedStack()");
3904 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003905 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003906 throw new IllegalStateException("moveTopActivityToPinnedStack:"
3907 + "Device doesn't support picture-in-picture mode");
3908 }
3909
3910 long ident = Binder.clearCallingIdentity();
3911 try {
Wale Ogunwaled32da472018-11-16 07:19:28 -08003912 return mRootActivityContainer.moveTopStackActivityToPinnedStack(stackId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003913 } finally {
3914 Binder.restoreCallingIdentity(ident);
3915 }
3916 }
3917 }
3918
3919 @Override
3920 public boolean isInMultiWindowMode(IBinder token) {
3921 final long origId = Binder.clearCallingIdentity();
3922 try {
3923 synchronized (mGlobalLock) {
3924 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3925 if (r == null) {
3926 return false;
3927 }
3928 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
3929 return r.inMultiWindowMode();
3930 }
3931 } finally {
3932 Binder.restoreCallingIdentity(origId);
3933 }
3934 }
3935
3936 @Override
3937 public boolean isInPictureInPictureMode(IBinder token) {
3938 final long origId = Binder.clearCallingIdentity();
3939 try {
3940 synchronized (mGlobalLock) {
3941 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
3942 }
3943 } finally {
3944 Binder.restoreCallingIdentity(origId);
3945 }
3946 }
3947
3948 private boolean isInPictureInPictureMode(ActivityRecord r) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003949 if (r == null || r.getActivityStack() == null || !r.inPinnedWindowingMode()
3950 || r.getActivityStack().isInStackLocked(r) == null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003951 return false;
3952 }
3953
3954 // If we are animating to fullscreen then we have already dispatched the PIP mode
3955 // changed, so we should reflect that check here as well.
Yunfan Chen279f5582018-12-12 15:24:50 -08003956 final TaskStack taskStack = r.getActivityStack().getTaskStack();
3957 return !taskStack.isAnimatingBoundsToFullscreen();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003958 }
3959
3960 @Override
3961 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
3962 final long origId = Binder.clearCallingIdentity();
3963 try {
3964 synchronized (mGlobalLock) {
3965 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3966 "enterPictureInPictureMode", token, params);
3967
3968 // If the activity is already in picture in picture mode, then just return early
3969 if (isInPictureInPictureMode(r)) {
3970 return true;
3971 }
3972
3973 // Activity supports picture-in-picture, now check that we can enter PiP at this
3974 // point, if it is
3975 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
3976 false /* beforeStopping */)) {
3977 return false;
3978 }
3979
3980 final Runnable enterPipRunnable = () -> {
Wale Ogunwalef276a6f2018-06-15 08:26:07 -07003981 synchronized (mGlobalLock) {
3982 // Only update the saved args from the args that are set
3983 r.pictureInPictureArgs.copyOnlySet(params);
3984 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
3985 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
3986 // Adjust the source bounds by the insets for the transition down
3987 final Rect sourceBounds = new Rect(
3988 r.pictureInPictureArgs.getSourceRectHint());
Wale Ogunwaled32da472018-11-16 07:19:28 -08003989 mRootActivityContainer.moveActivityToPinnedStack(
Wale Ogunwalef276a6f2018-06-15 08:26:07 -07003990 r, sourceBounds, aspectRatio, "enterPictureInPictureMode");
Yunfan Chen279f5582018-12-12 15:24:50 -08003991 final ActivityStack stack = r.getActivityStack();
Wale Ogunwalef276a6f2018-06-15 08:26:07 -07003992 stack.setPictureInPictureAspectRatio(aspectRatio);
3993 stack.setPictureInPictureActions(actions);
3994 MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
3995 r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
3996 logPictureInPictureArgs(params);
3997 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003998 };
3999
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004000 if (isKeyguardLocked()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004001 // If the keyguard is showing or occluded, then try and dismiss it before
4002 // entering picture-in-picture (this will prompt the user to authenticate if the
4003 // device is currently locked).
4004 dismissKeyguard(token, new KeyguardDismissCallback() {
4005 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004006 public void onDismissSucceeded() {
4007 mH.post(enterPipRunnable);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004008 }
4009 }, null /* message */);
4010 } else {
4011 // Enter picture in picture immediately otherwise
4012 enterPipRunnable.run();
4013 }
4014 return true;
4015 }
4016 } finally {
4017 Binder.restoreCallingIdentity(origId);
4018 }
4019 }
4020
4021 @Override
4022 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
4023 final long origId = Binder.clearCallingIdentity();
4024 try {
4025 synchronized (mGlobalLock) {
4026 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
4027 "setPictureInPictureParams", token, params);
4028
4029 // Only update the saved args from the args that are set
4030 r.pictureInPictureArgs.copyOnlySet(params);
4031 if (r.inPinnedWindowingMode()) {
4032 // If the activity is already in picture-in-picture, update the pinned stack now
4033 // if it is not already expanding to fullscreen. Otherwise, the arguments will
4034 // be used the next time the activity enters PiP
Yunfan Chen279f5582018-12-12 15:24:50 -08004035 final ActivityStack stack = r.getActivityStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004036 if (!stack.isAnimatingBoundsToFullscreen()) {
4037 stack.setPictureInPictureAspectRatio(
4038 r.pictureInPictureArgs.getAspectRatio());
4039 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
4040 }
4041 }
4042 logPictureInPictureArgs(params);
4043 }
4044 } finally {
4045 Binder.restoreCallingIdentity(origId);
4046 }
4047 }
4048
4049 @Override
4050 public int getMaxNumPictureInPictureActions(IBinder token) {
4051 // Currently, this is a static constant, but later, we may change this to be dependent on
4052 // the context of the activity
4053 return 3;
4054 }
4055
4056 private void logPictureInPictureArgs(PictureInPictureParams params) {
4057 if (params.hasSetActions()) {
4058 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
4059 params.getActions().size());
4060 }
4061 if (params.hasSetAspectRatio()) {
4062 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
4063 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
4064 MetricsLogger.action(lm);
4065 }
4066 }
4067
4068 /**
4069 * Checks the state of the system and the activity associated with the given {@param token} to
4070 * verify that picture-in-picture is supported for that activity.
4071 *
4072 * @return the activity record for the given {@param token} if all the checks pass.
4073 */
4074 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
4075 IBinder token, PictureInPictureParams params) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004076 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004077 throw new IllegalStateException(caller
4078 + ": Device doesn't support picture-in-picture mode.");
4079 }
4080
4081 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
4082 if (r == null) {
4083 throw new IllegalStateException(caller
4084 + ": Can't find activity for token=" + token);
4085 }
4086
4087 if (!r.supportsPictureInPicture()) {
4088 throw new IllegalStateException(caller
4089 + ": Current activity does not support picture-in-picture.");
4090 }
4091
4092 if (params.hasSetAspectRatio()
Wale Ogunwale8b19de92018-11-29 19:58:26 -08004093 && !mWindowManager.isValidPictureInPictureAspectRatio(
4094 r.getActivityStack().mDisplayId, params.getAspectRatio())) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004095 final float minAspectRatio = mContext.getResources().getFloat(
4096 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
4097 final float maxAspectRatio = mContext.getResources().getFloat(
4098 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
4099 throw new IllegalArgumentException(String.format(caller
4100 + ": Aspect ratio is too extreme (must be between %f and %f).",
4101 minAspectRatio, maxAspectRatio));
4102 }
4103
4104 // Truncate the number of actions if necessary
4105 params.truncateActions(getMaxNumPictureInPictureActions(token));
4106
4107 return r;
4108 }
4109
4110 @Override
4111 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004112 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004113 synchronized (mGlobalLock) {
4114 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
4115 if (r == null) {
4116 throw new IllegalArgumentException("Activity does not exist; token="
4117 + activityToken);
4118 }
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07004119 return r.getUriPermissionsLocked().getExternalToken();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004120 }
4121 }
4122
4123 @Override
4124 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
4125 Rect tempDockedTaskInsetBounds,
4126 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004127 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004128 long ident = Binder.clearCallingIdentity();
4129 try {
4130 synchronized (mGlobalLock) {
4131 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
4132 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
4133 PRESERVE_WINDOWS);
4134 }
4135 } finally {
4136 Binder.restoreCallingIdentity(ident);
4137 }
4138 }
4139
4140 @Override
4141 public void setSplitScreenResizing(boolean resizing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004142 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004143 final long ident = Binder.clearCallingIdentity();
4144 try {
4145 synchronized (mGlobalLock) {
4146 mStackSupervisor.setSplitScreenResizing(resizing);
4147 }
4148 } finally {
4149 Binder.restoreCallingIdentity(ident);
4150 }
4151 }
4152
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004153 /**
4154 * Check that we have the features required for VR-related API calls, and throw an exception if
4155 * not.
4156 */
Wale Ogunwale59507092018-10-29 09:00:30 -07004157 public void enforceSystemHasVrFeature() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004158 if (!mContext.getPackageManager().hasSystemFeature(
4159 PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
4160 throw new UnsupportedOperationException("VR mode not supported on this device!");
4161 }
4162 }
4163
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004164 @Override
4165 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004166 enforceSystemHasVrFeature();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004167
4168 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
4169
4170 ActivityRecord r;
4171 synchronized (mGlobalLock) {
4172 r = ActivityRecord.isInStackLocked(token);
4173 }
4174
4175 if (r == null) {
4176 throw new IllegalArgumentException();
4177 }
4178
4179 int err;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08004180 if ((err = vrService.hasVrPackage(packageName, r.mUserId)) !=
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004181 VrManagerInternal.NO_ERROR) {
4182 return err;
4183 }
4184
4185 // Clear the binder calling uid since this path may call moveToTask().
4186 final long callingId = Binder.clearCallingIdentity();
4187 try {
4188 synchronized (mGlobalLock) {
4189 r.requestedVrComponent = (enabled) ? packageName : null;
4190
4191 // Update associated state if this activity is currently focused
Andrii Kulian52d255c2018-07-13 11:32:19 -07004192 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004193 applyUpdateVrModeLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004194 }
4195 return 0;
4196 }
4197 } finally {
4198 Binder.restoreCallingIdentity(callingId);
4199 }
4200 }
4201
4202 @Override
4203 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
4204 Slog.i(TAG, "Activity tried to startLocalVoiceInteraction");
4205 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07004206 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004207 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4208 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4209 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08004210 if (mRunningVoice != null || activity.getTaskRecord().voiceSession != null
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004211 || activity.voiceSession != null) {
4212 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4213 return;
4214 }
4215 if (activity.pendingVoiceInteractionStart) {
4216 Slog.w(TAG, "Pending start of voice interaction already.");
4217 return;
4218 }
4219 activity.pendingVoiceInteractionStart = true;
4220 }
4221 LocalServices.getService(VoiceInteractionManagerInternal.class)
4222 .startLocalVoiceInteraction(callingActivity, options);
4223 }
4224
4225 @Override
4226 public void stopLocalVoiceInteraction(IBinder callingActivity) {
4227 LocalServices.getService(VoiceInteractionManagerInternal.class)
4228 .stopLocalVoiceInteraction(callingActivity);
4229 }
4230
4231 @Override
4232 public boolean supportsLocalVoiceInteraction() {
4233 return LocalServices.getService(VoiceInteractionManagerInternal.class)
4234 .supportsLocalVoiceInteraction();
4235 }
4236
4237 /** Notifies all listeners when the pinned stack animation starts. */
4238 @Override
4239 public void notifyPinnedStackAnimationStarted() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004240 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004241 }
4242
4243 /** Notifies all listeners when the pinned stack animation ends. */
4244 @Override
4245 public void notifyPinnedStackAnimationEnded() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004246 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004247 }
4248
4249 @Override
4250 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004251 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004252 final long ident = Binder.clearCallingIdentity();
4253 try {
4254 synchronized (mGlobalLock) {
4255 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
4256 }
4257 } finally {
4258 Binder.restoreCallingIdentity(ident);
4259 }
4260 }
4261
4262 @Override
4263 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004264 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004265
4266 synchronized (mGlobalLock) {
4267 // Check if display is initialized in AM.
Wale Ogunwaled32da472018-11-16 07:19:28 -08004268 if (!mRootActivityContainer.isDisplayAdded(displayId)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004269 // Call might come when display is not yet added or has already been removed.
4270 if (DEBUG_CONFIGURATION) {
4271 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
4272 + displayId);
4273 }
4274 return false;
4275 }
4276
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004277 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004278 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004279 values = mWindowManager.computeNewConfiguration(displayId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004280 }
4281
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004282 if (mWindowManager != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004283 final Message msg = PooledLambda.obtainMessage(
4284 ActivityManagerInternal::updateOomLevelsForDisplay, mAmInternal, displayId);
4285 mH.sendMessage(msg);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004286 }
4287
4288 final long origId = Binder.clearCallingIdentity();
4289 try {
4290 if (values != null) {
4291 Settings.System.clearConfiguration(values);
4292 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004293 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004294 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
4295 return mTmpUpdateConfigurationResult.changes != 0;
4296 } finally {
4297 Binder.restoreCallingIdentity(origId);
4298 }
4299 }
4300 }
4301
4302 @Override
4303 public boolean updateConfiguration(Configuration values) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004304 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004305
4306 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004307 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004308 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004309 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004310 }
4311
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004312 if (mWindowManager != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004313 final Message msg = PooledLambda.obtainMessage(
4314 ActivityManagerInternal::updateOomLevelsForDisplay, mAmInternal,
4315 DEFAULT_DISPLAY);
4316 mH.sendMessage(msg);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004317 }
4318
4319 final long origId = Binder.clearCallingIdentity();
4320 try {
4321 if (values != null) {
4322 Settings.System.clearConfiguration(values);
4323 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004324 updateConfigurationLocked(values, null, false, false /* persistent */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004325 UserHandle.USER_NULL, false /* deferResume */,
4326 mTmpUpdateConfigurationResult);
4327 return mTmpUpdateConfigurationResult.changes != 0;
4328 } finally {
4329 Binder.restoreCallingIdentity(origId);
4330 }
4331 }
4332 }
4333
4334 @Override
4335 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
4336 CharSequence message) {
4337 if (message != null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004338 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004339 Manifest.permission.SHOW_KEYGUARD_MESSAGE, "dismissKeyguard()");
4340 }
4341 final long callingId = Binder.clearCallingIdentity();
4342 try {
4343 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004344 mKeyguardController.dismissKeyguard(token, callback, message);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004345 }
4346 } finally {
4347 Binder.restoreCallingIdentity(callingId);
4348 }
4349 }
4350
4351 @Override
4352 public void cancelTaskWindowTransition(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004353 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004354 "cancelTaskWindowTransition()");
4355 final long ident = Binder.clearCallingIdentity();
4356 try {
4357 synchronized (mGlobalLock) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08004358 final TaskRecord task = mRootActivityContainer.anyTaskForId(taskId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004359 MATCH_TASK_IN_STACKS_ONLY);
4360 if (task == null) {
4361 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
4362 return;
4363 }
4364 task.cancelWindowTransition();
4365 }
4366 } finally {
4367 Binder.restoreCallingIdentity(ident);
4368 }
4369 }
4370
4371 @Override
4372 public ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004373 enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004374 final long ident = Binder.clearCallingIdentity();
4375 try {
4376 final TaskRecord task;
4377 synchronized (mGlobalLock) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08004378 task = mRootActivityContainer.anyTaskForId(taskId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004379 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
4380 if (task == null) {
4381 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
4382 return null;
4383 }
4384 }
4385 // Don't call this while holding the lock as this operation might hit the disk.
4386 return task.getSnapshot(reducedResolution);
4387 } finally {
4388 Binder.restoreCallingIdentity(ident);
4389 }
4390 }
4391
4392 @Override
4393 public void setDisablePreviewScreenshots(IBinder token, boolean disable) {
4394 synchronized (mGlobalLock) {
4395 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4396 if (r == null) {
4397 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
4398 + token);
4399 return;
4400 }
4401 final long origId = Binder.clearCallingIdentity();
4402 try {
4403 r.setDisablePreviewScreenshots(disable);
4404 } finally {
4405 Binder.restoreCallingIdentity(origId);
4406 }
4407 }
4408 }
4409
4410 /** Return the user id of the last resumed activity. */
4411 @Override
4412 public @UserIdInt
4413 int getLastResumedActivityUserId() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004414 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004415 Manifest.permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
4416 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07004417 if (mLastResumedActivity == null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004418 return getCurrentUserId();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004419 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08004420 return mLastResumedActivity.mUserId;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004421 }
4422 }
4423
4424 @Override
4425 public void updateLockTaskFeatures(int userId, int flags) {
4426 final int callingUid = Binder.getCallingUid();
4427 if (callingUid != 0 && callingUid != SYSTEM_UID) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004428 mAmInternal.enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004429 "updateLockTaskFeatures()");
4430 }
4431 synchronized (mGlobalLock) {
4432 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
4433 Integer.toHexString(flags));
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07004434 getLockTaskController().updateLockTaskFeatures(userId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004435 }
4436 }
4437
4438 @Override
4439 public void setShowWhenLocked(IBinder token, boolean showWhenLocked) {
4440 synchronized (mGlobalLock) {
4441 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4442 if (r == null) {
4443 return;
4444 }
4445 final long origId = Binder.clearCallingIdentity();
4446 try {
4447 r.setShowWhenLocked(showWhenLocked);
4448 } finally {
4449 Binder.restoreCallingIdentity(origId);
4450 }
4451 }
4452 }
4453
4454 @Override
Issei Suzuki74e1eb22018-12-20 17:42:52 +01004455 public void setInheritShowWhenLocked(IBinder token, boolean inheritShowWhenLocked) {
4456 synchronized (mGlobalLock) {
4457 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4458 if (r == null) {
4459 return;
4460 }
4461 final long origId = Binder.clearCallingIdentity();
4462 try {
4463 r.setInheritShowWhenLocked(inheritShowWhenLocked);
4464 } finally {
4465 Binder.restoreCallingIdentity(origId);
4466 }
4467 }
4468 }
4469
4470 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004471 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) {
4472 synchronized (mGlobalLock) {
4473 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4474 if (r == null) {
4475 return;
4476 }
4477 final long origId = Binder.clearCallingIdentity();
4478 try {
4479 r.setTurnScreenOn(turnScreenOn);
4480 } finally {
4481 Binder.restoreCallingIdentity(origId);
4482 }
4483 }
4484 }
4485
4486 @Override
4487 public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004488 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004489 "registerRemoteAnimations");
4490 definition.setCallingPid(Binder.getCallingPid());
4491 synchronized (mGlobalLock) {
4492 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4493 if (r == null) {
4494 return;
4495 }
4496 final long origId = Binder.clearCallingIdentity();
4497 try {
4498 r.registerRemoteAnimations(definition);
4499 } finally {
4500 Binder.restoreCallingIdentity(origId);
4501 }
4502 }
4503 }
4504
4505 @Override
4506 public void registerRemoteAnimationForNextActivityStart(String packageName,
4507 RemoteAnimationAdapter adapter) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004508 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004509 "registerRemoteAnimationForNextActivityStart");
4510 adapter.setCallingPid(Binder.getCallingPid());
4511 synchronized (mGlobalLock) {
4512 final long origId = Binder.clearCallingIdentity();
4513 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07004514 getActivityStartController().registerRemoteAnimationForNextActivityStart(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004515 packageName, adapter);
4516 } finally {
4517 Binder.restoreCallingIdentity(origId);
4518 }
4519 }
4520 }
4521
Evan Rosky966759f2019-01-15 10:33:58 -08004522 @Override
4523 public void registerRemoteAnimationsForDisplay(int displayId,
4524 RemoteAnimationDefinition definition) {
4525 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
4526 "registerRemoteAnimations");
4527 definition.setCallingPid(Binder.getCallingPid());
4528 synchronized (mGlobalLock) {
4529 final ActivityDisplay display = mRootActivityContainer.getActivityDisplay(displayId);
4530 if (display == null) {
4531 Slog.e(TAG, "Couldn't find display with id: " + displayId);
4532 return;
4533 }
4534 final long origId = Binder.clearCallingIdentity();
4535 try {
4536 display.mDisplayContent.registerRemoteAnimations(definition);
4537 } finally {
4538 Binder.restoreCallingIdentity(origId);
4539 }
4540 }
4541 }
4542
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004543 /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
4544 @Override
4545 public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
4546 synchronized (mGlobalLock) {
4547 final long origId = Binder.clearCallingIdentity();
4548 try {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004549 mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004550 } finally {
4551 Binder.restoreCallingIdentity(origId);
4552 }
4553 }
4554 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004555
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004556 @Override
4557 public void setVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004558 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004559 synchronized (mGlobalLock) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004560 final int pid = Binder.getCallingPid();
4561 final WindowProcessController wpc = mPidMap.get(pid);
4562 mVrController.setVrThreadLocked(tid, pid, wpc);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004563 }
4564 }
4565
4566 @Override
4567 public void setPersistentVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004568 if (checkCallingPermission(Manifest.permission.RESTRICTED_VR_ACCESS)
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004569 != PERMISSION_GRANTED) {
4570 final String msg = "Permission Denial: setPersistentVrThread() from pid="
4571 + Binder.getCallingPid()
4572 + ", uid=" + Binder.getCallingUid()
4573 + " requires " + Manifest.permission.RESTRICTED_VR_ACCESS;
4574 Slog.w(TAG, msg);
4575 throw new SecurityException(msg);
4576 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004577 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004578 synchronized (mGlobalLock) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004579 final int pid = Binder.getCallingPid();
4580 final WindowProcessController proc = mPidMap.get(pid);
4581 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004582 }
4583 }
4584
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004585 @Override
4586 public void stopAppSwitches() {
4587 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
4588 synchronized (mGlobalLock) {
4589 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME;
4590 mDidAppSwitch = false;
4591 getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
4592 }
4593 }
4594
4595 @Override
4596 public void resumeAppSwitches() {
4597 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
4598 synchronized (mGlobalLock) {
4599 // Note that we don't execute any pending app switches... we will
4600 // let those wait until either the timeout, or the next start
4601 // activity request.
4602 mAppSwitchesAllowedTime = 0;
4603 }
4604 }
4605
4606 void onStartActivitySetDidAppSwitch() {
4607 if (mDidAppSwitch) {
4608 // This is the second allowed switch since we stopped switches, so now just generally
4609 // allow switches. Use case:
4610 // - user presses home (switches disabled, switch to home, mDidAppSwitch now true);
4611 // - user taps a home icon (coming from home so allowed, we hit here and now allow
4612 // anyone to switch again).
4613 mAppSwitchesAllowedTime = 0;
4614 } else {
4615 mDidAppSwitch = true;
4616 }
4617 }
4618
4619 /** @return whether the system should disable UI modes incompatible with VR mode. */
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004620 boolean shouldDisableNonVrUiLocked() {
4621 return mVrController.shouldDisableNonVrUiLocked();
4622 }
4623
Wale Ogunwale53783742018-09-16 10:21:51 -07004624 private void applyUpdateVrModeLocked(ActivityRecord r) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004625 // VR apps are expected to run in a main display. If an app is turning on VR for
4626 // itself, but lives in a dynamic stack, then make sure that it is moved to the main
4627 // fullscreen stack before enabling VR Mode.
4628 // TODO: The goal of this code is to keep the VR app on the main display. When the
4629 // stack implementation changes in the future, keep in mind that the use of the fullscreen
4630 // stack is a means to move the activity to the main display and a moveActivityToDisplay()
4631 // option would be a better choice here.
4632 if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
4633 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
4634 + " to main stack for VR");
Wale Ogunwaled32da472018-11-16 07:19:28 -08004635 final ActivityStack stack = mRootActivityContainer.getDefaultDisplay().getOrCreateStack(
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004636 WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08004637 moveTaskToStack(r.getTaskRecord().taskId, stack.mStackId, true /* toTop */);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004638 }
4639 mH.post(() -> {
4640 if (!mVrController.onVrModeChanged(r)) {
4641 return;
4642 }
4643 synchronized (mGlobalLock) {
4644 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
4645 mWindowManager.disableNonVrUi(disableNonVrUi);
4646 if (disableNonVrUi) {
4647 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
4648 // then remove the pinned stack.
Wale Ogunwaled32da472018-11-16 07:19:28 -08004649 mRootActivityContainer.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004650 }
4651 }
4652 });
4653 }
4654
Wale Ogunwale53783742018-09-16 10:21:51 -07004655 @Override
4656 public int getPackageScreenCompatMode(String packageName) {
4657 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4658 synchronized (mGlobalLock) {
4659 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4660 }
4661 }
4662
4663 @Override
4664 public void setPackageScreenCompatMode(String packageName, int mode) {
4665 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4666 "setPackageScreenCompatMode");
4667 synchronized (mGlobalLock) {
4668 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4669 }
4670 }
4671
4672 @Override
4673 public boolean getPackageAskScreenCompat(String packageName) {
4674 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4675 synchronized (mGlobalLock) {
4676 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4677 }
4678 }
4679
4680 @Override
4681 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4682 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4683 "setPackageAskScreenCompat");
4684 synchronized (mGlobalLock) {
4685 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4686 }
4687 }
4688
Wale Ogunwale64258362018-10-16 15:13:37 -07004689 public static String relaunchReasonToString(int relaunchReason) {
4690 switch (relaunchReason) {
4691 case RELAUNCH_REASON_WINDOWING_MODE_RESIZE:
4692 return "window_resize";
4693 case RELAUNCH_REASON_FREE_RESIZE:
4694 return "free_resize";
4695 default:
4696 return null;
4697 }
4698 }
4699
Andrii Kulian5f750bc2018-07-17 08:57:23 -07004700 ActivityStack getTopDisplayFocusedStack() {
Wale Ogunwaled32da472018-11-16 07:19:28 -08004701 return mRootActivityContainer.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004702 }
4703
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004704 /** Pokes the task persister. */
4705 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
4706 mRecentTasks.notifyTaskPersisterLocked(task, flush);
4707 }
4708
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004709 boolean isKeyguardLocked() {
4710 return mKeyguardController.isKeyguardLocked();
4711 }
4712
Garfield Tan01548632018-11-27 10:15:48 -08004713 /**
4714 * Clears launch params for the given package.
4715 * @param packageNames the names of the packages of which the launch params are to be cleared
4716 */
4717 @Override
4718 public void clearLaunchParamsForPackages(List<String> packageNames) {
4719 mAmInternal.enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS,
4720 "clearLaunchParamsForPackages");
4721 synchronized (mGlobalLock) {
4722 for (int i = 0; i < packageNames.size(); ++i) {
4723 mStackSupervisor.mLaunchParamsPersister.removeRecordForPackage(packageNames.get(i));
4724 }
4725 }
4726 }
4727
Wale Ogunwale9e737db2018-12-17 15:42:37 -08004728 /**
4729 * Makes the display with the given id a single task instance display. I.e the display can only
4730 * contain one task.
4731 */
4732 @Override
4733 public void setDisplayToSingleTaskInstance(int displayId) {
4734 mAmInternal.enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS,
4735 "setDisplayToSingleTaskInstance");
4736 final long origId = Binder.clearCallingIdentity();
4737 try {
4738 final ActivityDisplay display =
4739 mRootActivityContainer.getActivityDisplayOrCreate(displayId);
4740 if (display != null) {
4741 display.setDisplayToSingleTaskInstance();
4742 }
4743 } finally {
4744 Binder.restoreCallingIdentity(origId);
4745 }
4746 }
4747
Wale Ogunwale31913b52018-10-13 08:29:31 -07004748 void dumpLastANRLocked(PrintWriter pw) {
4749 pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
4750 if (mLastANRState == null) {
4751 pw.println(" <no ANR has occurred since boot>");
4752 } else {
4753 pw.println(mLastANRState);
4754 }
4755 }
4756
4757 void dumpLastANRTracesLocked(PrintWriter pw) {
4758 pw.println("ACTIVITY MANAGER LAST ANR TRACES (dumpsys activity lastanr-traces)");
4759
4760 final File[] files = new File(ANR_TRACE_DIR).listFiles();
4761 if (ArrayUtils.isEmpty(files)) {
4762 pw.println(" <no ANR has occurred since boot>");
4763 return;
4764 }
4765 // Find the latest file.
4766 File latest = null;
4767 for (File f : files) {
4768 if ((latest == null) || (latest.lastModified() < f.lastModified())) {
4769 latest = f;
Wale Ogunwalef6733932018-06-27 05:14:34 -07004770 }
Wale Ogunwale31913b52018-10-13 08:29:31 -07004771 }
4772 pw.print("File: ");
4773 pw.print(latest.getName());
4774 pw.println();
4775 try (BufferedReader in = new BufferedReader(new FileReader(latest))) {
4776 String line;
4777 while ((line = in.readLine()) != null) {
4778 pw.println(line);
4779 }
4780 } catch (IOException e) {
4781 pw.print("Unable to read: ");
4782 pw.print(e);
4783 pw.println();
4784 }
4785 }
4786
4787 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
4788 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
4789 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
4790 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
4791 }
4792
4793 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
4794 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
4795 pw.println(header);
4796
Wale Ogunwaled32da472018-11-16 07:19:28 -08004797 boolean printedAnything = mRootActivityContainer.dumpActivities(fd, pw, dumpAll, dumpClient,
Wale Ogunwale31913b52018-10-13 08:29:31 -07004798 dumpPackage);
4799 boolean needSep = printedAnything;
4800
4801 boolean printed = ActivityStackSupervisor.printThisActivity(pw,
Wale Ogunwaled32da472018-11-16 07:19:28 -08004802 mRootActivityContainer.getTopResumedActivity(), dumpPackage, needSep,
Wale Ogunwale31913b52018-10-13 08:29:31 -07004803 " ResumedActivity: ");
4804 if (printed) {
4805 printedAnything = true;
4806 needSep = false;
4807 }
4808
4809 if (dumpPackage == null) {
4810 if (needSep) {
4811 pw.println();
4812 }
4813 printedAnything = true;
4814 mStackSupervisor.dump(pw, " ");
4815 }
4816
4817 if (!printedAnything) {
4818 pw.println(" (nothing)");
4819 }
4820 }
4821
4822 void dumpActivityContainersLocked(PrintWriter pw) {
4823 pw.println("ACTIVITY MANAGER STARTER (dumpsys activity containers)");
Wale Ogunwaled32da472018-11-16 07:19:28 -08004824 mRootActivityContainer.dumpChildrenNames(pw, " ");
Wale Ogunwale31913b52018-10-13 08:29:31 -07004825 pw.println(" ");
4826 }
4827
4828 void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
4829 pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
4830 getActivityStartController().dump(pw, "", dumpPackage);
4831 }
4832
4833 /**
4834 * There are three things that cmd can be:
4835 * - a flattened component name that matches an existing activity
4836 * - the cmd arg isn't the flattened component name of an existing activity:
4837 * dump all activity whose component contains the cmd as a substring
4838 * - A hex number of the ActivityRecord object instance.
4839 *
4840 * @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
4841 * @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
4842 */
4843 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
4844 int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
4845 ArrayList<ActivityRecord> activities;
4846
4847 synchronized (mGlobalLock) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08004848 activities = mRootActivityContainer.getDumpActivities(name, dumpVisibleStacksOnly,
Wale Ogunwale31913b52018-10-13 08:29:31 -07004849 dumpFocusedStackOnly);
4850 }
4851
4852 if (activities.size() <= 0) {
4853 return false;
4854 }
4855
4856 String[] newArgs = new String[args.length - opti];
4857 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
4858
4859 TaskRecord lastTask = null;
4860 boolean needSep = false;
4861 for (int i = activities.size() - 1; i >= 0; i--) {
4862 ActivityRecord r = activities.get(i);
4863 if (needSep) {
4864 pw.println();
4865 }
4866 needSep = true;
4867 synchronized (mGlobalLock) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08004868 final TaskRecord task = r.getTaskRecord();
Wale Ogunwale31913b52018-10-13 08:29:31 -07004869 if (lastTask != task) {
4870 lastTask = task;
4871 pw.print("TASK "); pw.print(lastTask.affinity);
4872 pw.print(" id="); pw.print(lastTask.taskId);
4873 pw.print(" userId="); pw.println(lastTask.userId);
4874 if (dumpAll) {
4875 lastTask.dump(pw, " ");
4876 }
4877 }
4878 }
4879 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
4880 }
4881 return true;
4882 }
4883
4884 /**
4885 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
4886 * there is a thread associated with the activity.
4887 */
4888 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
4889 final ActivityRecord r, String[] args, boolean dumpAll) {
4890 String innerPrefix = prefix + " ";
4891 synchronized (mGlobalLock) {
4892 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
4893 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
4894 pw.print(" pid=");
4895 if (r.hasProcess()) pw.println(r.app.getPid());
4896 else pw.println("(not running)");
4897 if (dumpAll) {
4898 r.dump(pw, innerPrefix);
4899 }
4900 }
4901 if (r.attachedToProcess()) {
4902 // flush anything that is already in the PrintWriter since the thread is going
4903 // to write to the file descriptor directly
4904 pw.flush();
4905 try {
4906 TransferPipe tp = new TransferPipe();
4907 try {
4908 r.app.getThread().dumpActivity(tp.getWriteFd(),
4909 r.appToken, innerPrefix, args);
4910 tp.go(fd);
4911 } finally {
4912 tp.kill();
4913 }
4914 } catch (IOException e) {
4915 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
4916 } catch (RemoteException e) {
4917 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
4918 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004919 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004920 }
4921
sanryhuang498e77e2018-12-06 14:57:01 +08004922 private void writeSleepStateToProto(ProtoOutputStream proto, int wakeFullness,
4923 boolean testPssMode) {
4924 final long sleepToken = proto.start(ActivityManagerServiceDumpProcessesProto.SLEEP_STATUS);
4925 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.WAKEFULNESS,
4926 PowerManagerInternal.wakefulnessToProtoEnum(wakeFullness));
Wale Ogunwaled32da472018-11-16 07:19:28 -08004927 for (ActivityTaskManagerInternal.SleepToken st : mRootActivityContainer.mSleepTokens) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07004928 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS,
4929 st.toString());
4930 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004931 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
4932 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN,
4933 mShuttingDown);
sanryhuang498e77e2018-12-06 14:57:01 +08004934 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.TEST_PSS_MODE,
4935 testPssMode);
4936 proto.end(sleepToken);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004937 }
4938
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004939 int getCurrentUserId() {
4940 return mAmInternal.getCurrentUserId();
4941 }
4942
4943 private void enforceNotIsolatedCaller(String caller) {
4944 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4945 throw new SecurityException("Isolated process not allowed to call " + caller);
4946 }
4947 }
4948
Wale Ogunwalef6733932018-06-27 05:14:34 -07004949 public Configuration getConfiguration() {
4950 Configuration ci;
4951 synchronized(mGlobalLock) {
Yunfan Chen75157d72018-07-27 14:47:21 +09004952 ci = new Configuration(getGlobalConfigurationForCallingPid());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004953 ci.userSetLocale = false;
4954 }
4955 return ci;
4956 }
4957
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004958 /**
4959 * Current global configuration information. Contains general settings for the entire system,
4960 * also corresponds to the merged configuration of the default display.
4961 */
4962 Configuration getGlobalConfiguration() {
Wale Ogunwaled32da472018-11-16 07:19:28 -08004963 return mRootActivityContainer.getConfiguration();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004964 }
4965
4966 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4967 boolean initLocale) {
4968 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
4969 }
4970
4971 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4972 boolean initLocale, boolean deferResume) {
4973 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
4974 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
4975 UserHandle.USER_NULL, deferResume);
4976 }
4977
Wale Ogunwale59507092018-10-29 09:00:30 -07004978 public void updatePersistentConfiguration(Configuration values, @UserIdInt int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004979 final long origId = Binder.clearCallingIdentity();
4980 try {
4981 synchronized (mGlobalLock) {
4982 updateConfigurationLocked(values, null, false, true, userId,
4983 false /* deferResume */);
4984 }
4985 } finally {
4986 Binder.restoreCallingIdentity(origId);
4987 }
4988 }
4989
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004990 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4991 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
4992 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
4993 deferResume, null /* result */);
4994 }
4995
4996 /**
4997 * Do either or both things: (1) change the current configuration, and (2)
4998 * make sure the given activity is running with the (now) current
4999 * configuration. Returns true if the activity has been left running, or
5000 * false if <var>starting</var> is being destroyed to match the new
5001 * configuration.
5002 *
5003 * @param userId is only used when persistent parameter is set to true to persist configuration
5004 * for that particular user
5005 */
5006 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
5007 boolean initLocale, boolean persistent, int userId, boolean deferResume,
5008 ActivityTaskManagerService.UpdateConfigurationResult result) {
5009 int changes = 0;
5010 boolean kept = true;
5011
5012 if (mWindowManager != null) {
5013 mWindowManager.deferSurfaceLayout();
5014 }
5015 try {
5016 if (values != null) {
5017 changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
5018 deferResume);
5019 }
5020
5021 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
5022 } finally {
5023 if (mWindowManager != null) {
5024 mWindowManager.continueSurfaceLayout();
5025 }
5026 }
5027
5028 if (result != null) {
5029 result.changes = changes;
5030 result.activityRelaunched = !kept;
5031 }
5032 return kept;
5033 }
5034
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005035 /** Update default (global) configuration and notify listeners about changes. */
5036 private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
5037 boolean persistent, int userId, boolean deferResume) {
5038 mTempConfig.setTo(getGlobalConfiguration());
5039 final int changes = mTempConfig.updateFrom(values);
5040 if (changes == 0) {
5041 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
5042 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
5043 // performDisplayOverrideConfigUpdate in order to send the new display configuration
5044 // (even if there are no actual changes) to unfreeze the window.
5045 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
5046 return 0;
5047 }
5048
5049 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
5050 "Updating global configuration to: " + values);
5051
5052 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
5053 StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
5054 values.colorMode,
5055 values.densityDpi,
5056 values.fontScale,
5057 values.hardKeyboardHidden,
5058 values.keyboard,
5059 values.keyboardHidden,
5060 values.mcc,
5061 values.mnc,
5062 values.navigation,
5063 values.navigationHidden,
5064 values.orientation,
5065 values.screenHeightDp,
5066 values.screenLayout,
5067 values.screenWidthDp,
5068 values.smallestScreenWidthDp,
5069 values.touchscreen,
5070 values.uiMode);
5071
5072
5073 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
5074 final LocaleList locales = values.getLocales();
5075 int bestLocaleIndex = 0;
5076 if (locales.size() > 1) {
5077 if (mSupportedSystemLocales == null) {
5078 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
5079 }
5080 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
5081 }
5082 SystemProperties.set("persist.sys.locale",
5083 locales.get(bestLocaleIndex).toLanguageTag());
5084 LocaleList.setDefault(locales, bestLocaleIndex);
Wale Ogunwale342fbe92018-10-09 08:44:10 -07005085
5086 final Message m = PooledLambda.obtainMessage(
5087 ActivityTaskManagerService::sendLocaleToMountDaemonMsg, this,
5088 locales.get(bestLocaleIndex));
5089 mH.sendMessage(m);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005090 }
5091
Yunfan Chen75157d72018-07-27 14:47:21 +09005092 mTempConfig.seq = increaseConfigurationSeqLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005093
5094 // Update stored global config and notify everyone about the change.
Wale Ogunwaled32da472018-11-16 07:19:28 -08005095 mRootActivityContainer.onConfigurationChanged(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005096
5097 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
5098 // TODO(multi-display): Update UsageEvents#Event to include displayId.
Wale Ogunwale342fbe92018-10-09 08:44:10 -07005099 mUsageStatsInternal.reportConfigurationChange(mTempConfig, mAmInternal.getCurrentUserId());
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005100
5101 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
Wale Ogunwalef6733932018-06-27 05:14:34 -07005102 updateShouldShowDialogsLocked(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005103
5104 AttributeCache ac = AttributeCache.instance();
5105 if (ac != null) {
5106 ac.updateConfiguration(mTempConfig);
5107 }
5108
5109 // Make sure all resources in our process are updated right now, so that anyone who is going
5110 // to retrieve resource values after we return will be sure to get the new ones. This is
5111 // especially important during boot, where the first config change needs to guarantee all
5112 // resources have that config before following boot code is executed.
Wale Ogunwale342fbe92018-10-09 08:44:10 -07005113 mSystemThread.applyConfigurationToResources(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005114
5115 // We need another copy of global config because we're scheduling some calls instead of
5116 // running them in place. We need to be sure that object we send will be handled unchanged.
5117 final Configuration configCopy = new Configuration(mTempConfig);
5118 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07005119 final Message msg = PooledLambda.obtainMessage(
5120 ActivityTaskManagerService::sendPutConfigurationForUserMsg,
5121 this, userId, configCopy);
5122 mH.sendMessage(msg);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005123 }
5124
Yunfan Chen34fcc7a2018-10-11 16:26:09 -07005125 for (int i = mPidMap.size() - 1; i >= 0; i--) {
Yunfan Chen79b96062018-10-17 12:45:23 -07005126 final int pid = mPidMap.keyAt(i);
5127 final WindowProcessController app = mPidMap.get(pid);
Yunfan Chen34fcc7a2018-10-11 16:26:09 -07005128 if (DEBUG_CONFIGURATION) {
5129 Slog.v(TAG_CONFIGURATION, "Update process config of "
5130 + app.mName + " to new config " + configCopy);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005131 }
Yunfan Chen34fcc7a2018-10-11 16:26:09 -07005132 app.onConfigurationChanged(configCopy);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005133 }
5134
Wale Ogunwale2ea36d42018-10-18 10:27:31 -07005135 final Message msg = PooledLambda.obtainMessage(
5136 ActivityManagerInternal::broadcastGlobalConfigurationChanged,
5137 mAmInternal, changes, initLocale);
5138 mH.sendMessage(msg);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005139
5140 // Override configuration of the default display duplicates global config, so we need to
5141 // update it also. This will also notify WindowManager about changes.
Wale Ogunwaled32da472018-11-16 07:19:28 -08005142 performDisplayOverrideConfigUpdate(mRootActivityContainer.getConfiguration(), deferResume,
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005143 DEFAULT_DISPLAY);
5144
5145 return changes;
5146 }
5147
5148 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
5149 boolean deferResume, int displayId) {
5150 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
5151 displayId, null /* result */);
5152 }
5153
5154 /**
5155 * Updates override configuration specific for the selected display. If no config is provided,
5156 * new one will be computed in WM based on current display info.
5157 */
5158 boolean updateDisplayOverrideConfigurationLocked(Configuration values,
5159 ActivityRecord starting, boolean deferResume, int displayId,
5160 ActivityTaskManagerService.UpdateConfigurationResult result) {
5161 int changes = 0;
5162 boolean kept = true;
5163
5164 if (mWindowManager != null) {
5165 mWindowManager.deferSurfaceLayout();
5166 }
5167 try {
5168 if (values != null) {
5169 if (displayId == DEFAULT_DISPLAY) {
5170 // Override configuration of the default display duplicates global config, so
5171 // we're calling global config update instead for default display. It will also
5172 // apply the correct override config.
5173 changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
5174 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
5175 } else {
5176 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
5177 }
5178 }
5179
5180 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
5181 } finally {
5182 if (mWindowManager != null) {
5183 mWindowManager.continueSurfaceLayout();
5184 }
5185 }
5186
5187 if (result != null) {
5188 result.changes = changes;
5189 result.activityRelaunched = !kept;
5190 }
5191 return kept;
5192 }
5193
5194 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
5195 int displayId) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08005196 mTempConfig.setTo(mRootActivityContainer.getDisplayOverrideConfiguration(displayId));
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005197 final int changes = mTempConfig.updateFrom(values);
5198 if (changes != 0) {
5199 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
5200 + mTempConfig + " for displayId=" + displayId);
Wale Ogunwaled32da472018-11-16 07:19:28 -08005201 mRootActivityContainer.setDisplayOverrideConfiguration(mTempConfig, displayId);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005202
5203 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
5204 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
Wale Ogunwale008163e2018-07-23 23:11:08 -07005205 mAppWarnings.onDensityChanged();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005206
Wale Ogunwale5c918702018-10-18 11:06:33 -07005207 // Post message to start process to avoid possible deadlock of calling into AMS with
5208 // the ATMS lock held.
5209 final Message msg = PooledLambda.obtainMessage(
5210 ActivityManagerInternal::killAllBackgroundProcessesExcept, mAmInternal,
5211 N, ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
5212 mH.sendMessage(msg);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005213 }
5214 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005215 return changes;
5216 }
5217
Wale Ogunwalef6733932018-06-27 05:14:34 -07005218 private void updateEventDispatchingLocked(boolean booted) {
5219 mWindowManager.setEventDispatching(booted && !mShuttingDown);
5220 }
5221
Wale Ogunwale342fbe92018-10-09 08:44:10 -07005222 private void sendPutConfigurationForUserMsg(int userId, Configuration config) {
5223 final ContentResolver resolver = mContext.getContentResolver();
5224 Settings.System.putConfigurationForUser(resolver, config, userId);
5225 }
5226
5227 private void sendLocaleToMountDaemonMsg(Locale l) {
5228 try {
5229 IBinder service = ServiceManager.getService("mount");
5230 IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
5231 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
5232 storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
5233 } catch (RemoteException e) {
5234 Log.e(TAG, "Error storing locale for decryption UI", e);
5235 }
5236 }
5237
Alison Cichowlas3e340502018-08-07 17:15:01 -04005238 private void expireStartAsCallerTokenMsg(IBinder permissionToken) {
5239 mStartActivitySources.remove(permissionToken);
5240 mExpiredStartAsCallerTokens.add(permissionToken);
5241 }
5242
5243 private void forgetStartAsCallerTokenMsg(IBinder permissionToken) {
5244 mExpiredStartAsCallerTokens.remove(permissionToken);
5245 }
5246
Wale Ogunwale342fbe92018-10-09 08:44:10 -07005247 boolean isActivityStartsLoggingEnabled() {
5248 return mAmInternal.isActivityStartsLoggingEnabled();
5249 }
5250
Michal Karpinski8596ded2018-11-14 14:43:48 +00005251 boolean isBackgroundActivityStartsEnabled() {
5252 return mAmInternal.isBackgroundActivityStartsEnabled();
5253 }
5254
Michal Karpinski666631b2019-02-26 16:59:11 +00005255 boolean isPackageNameWhitelistedForBgActivityStarts(String packageName) {
5256 return mAmInternal.isPackageNameWhitelistedForBgActivityStarts(packageName);
5257 }
5258
Wale Ogunwalef6733932018-06-27 05:14:34 -07005259 void enableScreenAfterBoot(boolean booted) {
5260 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5261 SystemClock.uptimeMillis());
5262 mWindowManager.enableScreenAfterBoot();
5263
5264 synchronized (mGlobalLock) {
5265 updateEventDispatchingLocked(booted);
5266 }
5267 }
5268
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005269 static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
5270 if (r == null || !r.hasProcess()) {
5271 return KEY_DISPATCHING_TIMEOUT_MS;
5272 }
5273 return getInputDispatchingTimeoutLocked(r.app);
5274 }
5275
5276 private static long getInputDispatchingTimeoutLocked(WindowProcessController r) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07005277 return r != null ? r.getInputDispatchingTimeout() : KEY_DISPATCHING_TIMEOUT_MS;
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005278 }
5279
Wale Ogunwalef6733932018-06-27 05:14:34 -07005280 /**
5281 * Decide based on the configuration whether we should show the ANR,
5282 * crash, etc dialogs. The idea is that if there is no affordance to
5283 * press the on-screen buttons, or the user experience would be more
5284 * greatly impacted than the crash itself, we shouldn't show the dialog.
5285 *
5286 * A thought: SystemUI might also want to get told about this, the Power
5287 * dialog / global actions also might want different behaviors.
5288 */
5289 private void updateShouldShowDialogsLocked(Configuration config) {
5290 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
5291 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
5292 && config.navigation == Configuration.NAVIGATION_NONAV);
5293 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
5294 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
5295 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
5296 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
5297 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
5298 final boolean hideDialogsSet = Settings.Global.getInt(mContext.getContentResolver(),
5299 HIDE_ERROR_DIALOGS, 0) != 0;
5300 mShowDialogs = inputMethodExists && uiModeSupportsDialogs && !hideDialogsSet;
5301 }
5302
5303 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
5304 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
5305 FONT_SCALE, 1.0f, userId);
5306
5307 synchronized (this) {
5308 if (getGlobalConfiguration().fontScale == scaleFactor) {
5309 return;
5310 }
5311
5312 final Configuration configuration
5313 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
5314 configuration.fontScale = scaleFactor;
5315 updatePersistentConfiguration(configuration, userId);
5316 }
5317 }
5318
5319 // Actually is sleeping or shutting down or whatever else in the future
5320 // is an inactive state.
5321 boolean isSleepingOrShuttingDownLocked() {
5322 return isSleepingLocked() || mShuttingDown;
5323 }
5324
5325 boolean isSleepingLocked() {
5326 return mSleeping;
5327 }
5328
Riddle Hsu16567132018-08-16 21:37:47 +08005329 /** Update AMS states when an activity is resumed. */
Wale Ogunwalef6733932018-06-27 05:14:34 -07005330 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08005331 final TaskRecord task = r.getTaskRecord();
Wale Ogunwalef6733932018-06-27 05:14:34 -07005332 if (task.isActivityTypeStandard()) {
5333 if (mCurAppTimeTracker != r.appTimeTracker) {
5334 // We are switching app tracking. Complete the current one.
5335 if (mCurAppTimeTracker != null) {
5336 mCurAppTimeTracker.stop();
5337 mH.obtainMessage(
5338 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
Wale Ogunwaled32da472018-11-16 07:19:28 -08005339 mRootActivityContainer.clearOtherAppTimeTrackers(r.appTimeTracker);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005340 mCurAppTimeTracker = null;
5341 }
5342 if (r.appTimeTracker != null) {
5343 mCurAppTimeTracker = r.appTimeTracker;
5344 startTimeTrackingFocusedActivityLocked();
5345 }
5346 } else {
5347 startTimeTrackingFocusedActivityLocked();
5348 }
5349 } else {
5350 r.appTimeTracker = null;
5351 }
5352 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
5353 // TODO: Probably not, because we don't want to resume voice on switching
5354 // back to this activity
5355 if (task.voiceInteractor != null) {
5356 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
5357 } else {
5358 finishRunningVoiceLocked();
5359
5360 if (mLastResumedActivity != null) {
5361 final IVoiceInteractionSession session;
5362
Wale Ogunwale8b19de92018-11-29 19:58:26 -08005363 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTaskRecord();
Wale Ogunwalef6733932018-06-27 05:14:34 -07005364 if (lastResumedActivityTask != null
5365 && lastResumedActivityTask.voiceSession != null) {
5366 session = lastResumedActivityTask.voiceSession;
5367 } else {
5368 session = mLastResumedActivity.voiceSession;
5369 }
5370
5371 if (session != null) {
5372 // We had been in a voice interaction session, but now focused has
5373 // move to something different. Just finish the session, we can't
5374 // return to it and retain the proper state and synchronization with
5375 // the voice interaction service.
5376 finishVoiceTask(session);
5377 }
5378 }
5379 }
5380
Wale Ogunwale8b19de92018-11-29 19:58:26 -08005381 if (mLastResumedActivity != null && r.mUserId != mLastResumedActivity.mUserId) {
5382 mAmInternal.sendForegroundProfileChanged(r.mUserId);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005383 }
5384 updateResumedAppTrace(r);
5385 mLastResumedActivity = r;
5386
Tiger Huang1e5b10a2018-07-30 20:19:51 +08005387 r.getDisplay().setFocusedApp(r, true);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005388
5389 applyUpdateLockStateLocked(r);
5390 applyUpdateVrModeLocked(r);
5391
5392 EventLogTags.writeAmSetResumedActivity(
Wale Ogunwale8b19de92018-11-29 19:58:26 -08005393 r == null ? -1 : r.mUserId,
Wale Ogunwalef6733932018-06-27 05:14:34 -07005394 r == null ? "NULL" : r.shortComponentName,
5395 reason);
5396 }
5397
5398 ActivityTaskManagerInternal.SleepToken acquireSleepToken(String tag, int displayId) {
5399 synchronized (mGlobalLock) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08005400 final ActivityTaskManagerInternal.SleepToken token =
5401 mRootActivityContainer.createSleepToken(tag, displayId);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005402 updateSleepIfNeededLocked();
5403 return token;
5404 }
5405 }
5406
5407 void updateSleepIfNeededLocked() {
Wale Ogunwaled32da472018-11-16 07:19:28 -08005408 final boolean shouldSleep = !mRootActivityContainer.hasAwakeDisplay();
Wale Ogunwalef6733932018-06-27 05:14:34 -07005409 final boolean wasSleeping = mSleeping;
5410 boolean updateOomAdj = false;
5411
5412 if (!shouldSleep) {
5413 // If wasSleeping is true, we need to wake up activity manager state from when
5414 // we started sleeping. In either case, we need to apply the sleep tokens, which
5415 // will wake up stacks or put them to sleep as appropriate.
5416 if (wasSleeping) {
5417 mSleeping = false;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07005418 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
5419 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__AWAKE);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005420 startTimeTrackingFocusedActivityLocked();
5421 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
5422 mStackSupervisor.comeOutOfSleepIfNeededLocked();
5423 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08005424 mRootActivityContainer.applySleepTokens(true /* applyToStacks */);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005425 if (wasSleeping) {
5426 updateOomAdj = true;
5427 }
5428 } else if (!mSleeping && shouldSleep) {
5429 mSleeping = true;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07005430 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
5431 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__ASLEEP);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005432 if (mCurAppTimeTracker != null) {
5433 mCurAppTimeTracker.stop();
5434 }
5435 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
5436 mStackSupervisor.goingToSleepLocked();
5437 updateResumedAppTrace(null /* resumed */);
5438 updateOomAdj = true;
5439 }
5440 if (updateOomAdj) {
5441 mH.post(mAmInternal::updateOomAdj);
5442 }
5443 }
5444
5445 void updateOomAdj() {
5446 mH.post(mAmInternal::updateOomAdj);
5447 }
5448
Wale Ogunwale53783742018-09-16 10:21:51 -07005449 void updateCpuStats() {
5450 mH.post(mAmInternal::updateCpuStats);
5451 }
5452
Hui Yu03d12402018-12-06 18:00:37 -08005453 void updateBatteryStats(ActivityRecord component, boolean resumed) {
5454 final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::updateBatteryStats,
Wale Ogunwale8b19de92018-11-29 19:58:26 -08005455 mAmInternal, component.mActivityComponent, component.app.mUid, component.mUserId,
5456 resumed);
Wale Ogunwale53783742018-09-16 10:21:51 -07005457 mH.sendMessage(m);
5458 }
5459
Hui Yu03d12402018-12-06 18:00:37 -08005460 void updateActivityUsageStats(ActivityRecord activity, int event) {
Michael Wachenschwanz0b4ab1f2019-01-07 13:59:10 -08005461 ComponentName taskRoot = null;
5462 final TaskRecord task = activity.getTaskRecord();
5463 if (task != null) {
5464 final ActivityRecord rootActivity = task.getRootActivity();
5465 if (rootActivity != null) {
5466 taskRoot = rootActivity.mActivityComponent;
5467 }
5468 }
5469
Hui Yu03d12402018-12-06 18:00:37 -08005470 final Message m = PooledLambda.obtainMessage(
5471 ActivityManagerInternal::updateActivityUsageStats, mAmInternal,
Michael Wachenschwanz0b4ab1f2019-01-07 13:59:10 -08005472 activity.mActivityComponent, activity.mUserId, event, activity.appToken, taskRoot);
Hui Yu03d12402018-12-06 18:00:37 -08005473 mH.sendMessage(m);
5474 }
5475
Wale Ogunwale53783742018-09-16 10:21:51 -07005476 void setBooting(boolean booting) {
5477 mAmInternal.setBooting(booting);
5478 }
5479
5480 boolean isBooting() {
5481 return mAmInternal.isBooting();
5482 }
5483
5484 void setBooted(boolean booted) {
5485 mAmInternal.setBooted(booted);
5486 }
5487
5488 boolean isBooted() {
5489 return mAmInternal.isBooted();
5490 }
5491
5492 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
5493 mH.post(() -> {
5494 if (finishBooting) {
5495 mAmInternal.finishBooting();
5496 }
5497 if (enableScreen) {
5498 mInternal.enableScreenAfterBoot(isBooted());
5499 }
5500 });
5501 }
5502
5503 void setHeavyWeightProcess(ActivityRecord root) {
5504 mHeavyWeightProcess = root.app;
5505 final Message m = PooledLambda.obtainMessage(
5506 ActivityTaskManagerService::postHeavyWeightProcessNotification, this,
Wale Ogunwale8b19de92018-11-29 19:58:26 -08005507 root.app, root.intent, root.mUserId);
Wale Ogunwale53783742018-09-16 10:21:51 -07005508 mH.sendMessage(m);
5509 }
5510
5511 void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
5512 if (mHeavyWeightProcess == null || mHeavyWeightProcess != proc) {
5513 return;
5514 }
5515
5516 mHeavyWeightProcess = null;
5517 final Message m = PooledLambda.obtainMessage(
5518 ActivityTaskManagerService::cancelHeavyWeightProcessNotification, this,
5519 proc.mUserId);
5520 mH.sendMessage(m);
5521 }
5522
5523 private void cancelHeavyWeightProcessNotification(int userId) {
5524 final INotificationManager inm = NotificationManager.getService();
5525 if (inm == null) {
5526 return;
5527 }
5528 try {
5529 inm.cancelNotificationWithTag("android", null,
5530 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, userId);
5531 } catch (RuntimeException e) {
5532 Slog.w(TAG, "Error canceling notification for service", e);
5533 } catch (RemoteException e) {
5534 }
5535
5536 }
5537
5538 private void postHeavyWeightProcessNotification(
5539 WindowProcessController proc, Intent intent, int userId) {
5540 if (proc == null) {
5541 return;
5542 }
5543
5544 final INotificationManager inm = NotificationManager.getService();
5545 if (inm == null) {
5546 return;
5547 }
5548
5549 try {
5550 Context context = mContext.createPackageContext(proc.mInfo.packageName, 0);
5551 String text = mContext.getString(R.string.heavy_weight_notification,
5552 context.getApplicationInfo().loadLabel(context.getPackageManager()));
5553 Notification notification =
5554 new Notification.Builder(context,
5555 SystemNotificationChannels.HEAVY_WEIGHT_APP)
5556 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
5557 .setWhen(0)
5558 .setOngoing(true)
5559 .setTicker(text)
5560 .setColor(mContext.getColor(
5561 com.android.internal.R.color.system_notification_accent_color))
5562 .setContentTitle(text)
5563 .setContentText(
5564 mContext.getText(R.string.heavy_weight_notification_detail))
5565 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
5566 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
5567 new UserHandle(userId)))
5568 .build();
5569 try {
5570 inm.enqueueNotificationWithTag("android", "android", null,
5571 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, notification, userId);
5572 } catch (RuntimeException e) {
5573 Slog.w(TAG, "Error showing notification for heavy-weight app", e);
5574 } catch (RemoteException e) {
5575 }
5576 } catch (PackageManager.NameNotFoundException e) {
5577 Slog.w(TAG, "Unable to create context for heavy notification", e);
5578 }
5579
5580 }
5581
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07005582 IIntentSender getIntentSenderLocked(int type, String packageName, int callingUid, int userId,
5583 IBinder token, String resultWho, int requestCode, Intent[] intents,
5584 String[] resolvedTypes, int flags, Bundle bOptions) {
5585
5586 ActivityRecord activity = null;
5587 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5588 activity = ActivityRecord.isInStackLocked(token);
5589 if (activity == null) {
5590 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
5591 return null;
5592 }
5593 if (activity.finishing) {
5594 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
5595 return null;
5596 }
5597 }
5598
5599 final PendingIntentRecord rec = mPendingIntentController.getIntentSender(type, packageName,
5600 callingUid, userId, token, resultWho, requestCode, intents, resolvedTypes, flags,
5601 bOptions);
5602 final boolean noCreate = (flags & PendingIntent.FLAG_NO_CREATE) != 0;
5603 if (noCreate) {
5604 return rec;
5605 }
5606 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5607 if (activity.pendingResults == null) {
5608 activity.pendingResults = new HashSet<>();
5609 }
5610 activity.pendingResults.add(rec.ref);
5611 }
5612 return rec;
5613 }
5614
Andrii Kulian52d255c2018-07-13 11:32:19 -07005615 // TODO(b/111541062): Update app time tracking to make it aware of multiple resumed activities
Wale Ogunwalef6733932018-06-27 05:14:34 -07005616 private void startTimeTrackingFocusedActivityLocked() {
Wale Ogunwaled32da472018-11-16 07:19:28 -08005617 final ActivityRecord resumedActivity = mRootActivityContainer.getTopResumedActivity();
Wale Ogunwalef6733932018-06-27 05:14:34 -07005618 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
5619 mCurAppTimeTracker.start(resumedActivity.packageName);
5620 }
5621 }
5622
5623 private void updateResumedAppTrace(@Nullable ActivityRecord resumed) {
5624 if (mTracedResumedActivity != null) {
5625 Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER,
5626 constructResumedTraceName(mTracedResumedActivity.packageName), 0);
5627 }
5628 if (resumed != null) {
5629 Trace.asyncTraceBegin(TRACE_TAG_ACTIVITY_MANAGER,
5630 constructResumedTraceName(resumed.packageName), 0);
5631 }
5632 mTracedResumedActivity = resumed;
5633 }
5634
5635 private String constructResumedTraceName(String packageName) {
5636 return "focused app: " + packageName;
5637 }
5638
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005639 /** Applies latest configuration and/or visibility updates if needed. */
5640 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
5641 boolean kept = true;
Wale Ogunwaled32da472018-11-16 07:19:28 -08005642 final ActivityStack mainStack = mRootActivityContainer.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005643 // mainStack is null during startup.
5644 if (mainStack != null) {
5645 if (changes != 0 && starting == null) {
5646 // If the configuration changed, and the caller is not already
5647 // in the process of starting an activity, then find the top
5648 // activity to check if its configuration needs to change.
5649 starting = mainStack.topRunningActivityLocked();
5650 }
5651
5652 if (starting != null) {
5653 kept = starting.ensureActivityConfiguration(changes,
5654 false /* preserveWindow */);
5655 // And we need to make sure at this point that all other activities
5656 // are made visible with the correct configuration.
Wale Ogunwaled32da472018-11-16 07:19:28 -08005657 mRootActivityContainer.ensureActivitiesVisible(starting, changes,
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005658 !PRESERVE_WINDOWS);
5659 }
5660 }
5661
5662 return kept;
5663 }
5664
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005665 void scheduleAppGcsLocked() {
5666 mH.post(() -> mAmInternal.scheduleAppGcs());
5667 }
5668
Wale Ogunwale53783742018-09-16 10:21:51 -07005669 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
5670 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
5671 }
5672
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005673 /**
5674 * Returns the PackageManager. Used by classes hosted by {@link ActivityTaskManagerService}. The
5675 * PackageManager could be unavailable at construction time and therefore needs to be accessed
5676 * on demand.
5677 */
5678 IPackageManager getPackageManager() {
5679 return AppGlobals.getPackageManager();
5680 }
5681
5682 PackageManagerInternal getPackageManagerInternalLocked() {
5683 if (mPmInternal == null) {
5684 mPmInternal = LocalServices.getService(PackageManagerInternal.class);
5685 }
5686 return mPmInternal;
5687 }
5688
Wale Ogunwale008163e2018-07-23 23:11:08 -07005689 AppWarnings getAppWarningsLocked() {
5690 return mAppWarnings;
5691 }
5692
Wale Ogunwale214f3482018-10-04 11:00:47 -07005693 Intent getHomeIntent() {
5694 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
5695 intent.setComponent(mTopComponent);
5696 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
5697 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5698 intent.addCategory(Intent.CATEGORY_HOME);
5699 }
5700 return intent;
5701 }
5702
Chilun2ef71f72018-11-16 17:57:15 +08005703 /**
5704 * Return the intent set with {@link Intent#CATEGORY_SECONDARY_HOME} to resolve secondary home
5705 * activities.
5706 *
5707 * @param preferredPackage Specify a preferred package name, otherwise use secondary home
5708 * component defined in config_secondaryHomeComponent.
5709 * @return the intent set with {@link Intent#CATEGORY_SECONDARY_HOME}
5710 */
5711 Intent getSecondaryHomeIntent(String preferredPackage) {
5712 final Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
5713 if (preferredPackage == null) {
5714 // Using the component stored in config if no package name.
5715 final String secondaryHomeComponent = mContext.getResources().getString(
5716 com.android.internal.R.string.config_secondaryHomeComponent);
5717 intent.setComponent(ComponentName.unflattenFromString(secondaryHomeComponent));
5718 } else {
5719 intent.setPackage(preferredPackage);
5720 }
5721 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
5722 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5723 intent.addCategory(Intent.CATEGORY_SECONDARY_HOME);
5724 }
5725 return intent;
5726 }
5727
Wale Ogunwale214f3482018-10-04 11:00:47 -07005728 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
5729 if (info == null) return null;
5730 ApplicationInfo newInfo = new ApplicationInfo(info);
5731 newInfo.initForUser(userId);
5732 return newInfo;
5733 }
5734
Wale Ogunwale9c103022018-10-18 07:44:54 -07005735 WindowProcessController getProcessController(String processName, int uid) {
Wale Ogunwale214f3482018-10-04 11:00:47 -07005736 if (uid == SYSTEM_UID) {
5737 // The system gets to run in any process. If there are multiple processes with the same
5738 // uid, just pick the first (this should never happen).
5739 final SparseArray<WindowProcessController> procs =
5740 mProcessNames.getMap().get(processName);
5741 if (procs == null) return null;
5742 final int procCount = procs.size();
5743 for (int i = 0; i < procCount; i++) {
5744 final int procUid = procs.keyAt(i);
5745 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
5746 // Don't use an app process or different user process for system component.
5747 continue;
5748 }
5749 return procs.valueAt(i);
5750 }
5751 }
5752
5753 return mProcessNames.get(processName, uid);
5754 }
5755
Wale Ogunwale342fbe92018-10-09 08:44:10 -07005756 WindowProcessController getProcessController(IApplicationThread thread) {
5757 if (thread == null) {
5758 return null;
5759 }
5760
5761 final IBinder threadBinder = thread.asBinder();
5762 final ArrayMap<String, SparseArray<WindowProcessController>> pmap = mProcessNames.getMap();
5763 for (int i = pmap.size()-1; i >= 0; i--) {
5764 final SparseArray<WindowProcessController> procs = pmap.valueAt(i);
5765 for (int j = procs.size() - 1; j >= 0; j--) {
5766 final WindowProcessController proc = procs.valueAt(j);
5767 if (proc.hasThread() && proc.getThread().asBinder() == threadBinder) {
5768 return proc;
5769 }
5770 }
5771 }
5772
5773 return null;
5774 }
5775
Michal Karpinski9cbb20b2019-02-05 17:31:50 +00005776 WindowProcessController getProcessController(int pid, int uid) {
5777 final ArrayMap<String, SparseArray<WindowProcessController>> pmap = mProcessNames.getMap();
5778 for (int i = pmap.size()-1; i >= 0; i--) {
5779 final SparseArray<WindowProcessController> procs = pmap.valueAt(i);
5780 for (int j = procs.size() - 1; j >= 0; j--) {
5781 final WindowProcessController proc = procs.valueAt(j);
5782 if (UserHandle.isApp(uid) && proc.getPid() == pid && proc.mUid == uid) {
5783 return proc;
5784 }
5785 }
5786 }
5787 return null;
5788 }
5789
Riddle Hsua0536432019-02-16 00:38:59 +08005790 int getUidState(int uid) {
5791 return mActiveUids.getUidState(uid);
Wale Ogunwalebff2df42018-10-18 17:09:19 -07005792 }
5793
Michal Karpinskicc88d7e2019-01-24 15:32:12 +00005794 boolean isUidForeground(int uid) {
Riddle Hsua0536432019-02-16 00:38:59 +08005795 return (getUidState(uid) == ActivityManager.PROCESS_STATE_TOP)
Michal Karpinskicc88d7e2019-01-24 15:32:12 +00005796 || mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(uid);
5797 }
5798
Michal Karpinski4026cae2019-02-12 11:51:47 +00005799 boolean isDeviceOwner(String packageName) {
5800 if (packageName == null) {
5801 return false;
5802 }
5803 return packageName.equals(mDeviceOwnerPackageName);
5804 }
5805
5806 void setDeviceOwnerPackageName(String deviceOwnerPkg) {
5807 mDeviceOwnerPackageName = deviceOwnerPkg;
5808 }
5809
Wale Ogunwale9de19442018-10-18 19:05:03 -07005810 /**
5811 * @return whitelist tag for a uid from mPendingTempWhitelist, null if not currently on
5812 * the whitelist
5813 */
5814 String getPendingTempWhitelistTagForUidLocked(int uid) {
5815 return mPendingTempWhitelist.get(uid);
5816 }
5817
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005818 void logAppTooSlow(WindowProcessController app, long startTime, String msg) {
5819 if (true || Build.IS_USER) {
5820 return;
5821 }
5822
5823 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5824 StrictMode.allowThreadDiskWrites();
5825 try {
5826 File tracesDir = new File("/data/anr");
5827 File tracesFile = null;
5828 try {
5829 tracesFile = File.createTempFile("app_slow", null, tracesDir);
5830
5831 StringBuilder sb = new StringBuilder();
5832 Time tobj = new Time();
5833 tobj.set(System.currentTimeMillis());
5834 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5835 sb.append(": ");
5836 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5837 sb.append(" since ");
5838 sb.append(msg);
5839 FileOutputStream fos = new FileOutputStream(tracesFile);
5840 fos.write(sb.toString().getBytes());
5841 if (app == null) {
5842 fos.write("\n*** No application process!".getBytes());
5843 }
5844 fos.close();
5845 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5846 } catch (IOException e) {
5847 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesFile, e);
5848 return;
5849 }
5850
5851 if (app != null && app.getPid() > 0) {
5852 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5853 firstPids.add(app.getPid());
5854 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, null, null);
5855 }
5856
5857 File lastTracesFile = null;
5858 File curTracesFile = null;
5859 for (int i=9; i>=0; i--) {
5860 String name = String.format(Locale.US, "slow%02d.txt", i);
5861 curTracesFile = new File(tracesDir, name);
5862 if (curTracesFile.exists()) {
5863 if (lastTracesFile != null) {
5864 curTracesFile.renameTo(lastTracesFile);
5865 } else {
5866 curTracesFile.delete();
5867 }
5868 }
5869 lastTracesFile = curTracesFile;
5870 }
5871 tracesFile.renameTo(curTracesFile);
5872 } finally {
5873 StrictMode.setThreadPolicy(oldPolicy);
5874 }
5875 }
5876
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005877 final class H extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005878 static final int REPORT_TIME_TRACKER_MSG = 1;
Alison Cichowlas3e340502018-08-07 17:15:01 -04005879
5880
Wale Ogunwale98875612018-10-12 07:53:02 -07005881 static final int FIRST_ACTIVITY_STACK_MSG = 100;
5882 static final int FIRST_SUPERVISOR_STACK_MSG = 200;
Wale Ogunwalef6733932018-06-27 05:14:34 -07005883
Riddle Hsud93a6c42018-11-29 21:50:06 +08005884 H(Looper looper) {
5885 super(looper);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005886 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005887
5888 @Override
5889 public void handleMessage(Message msg) {
5890 switch (msg.what) {
5891 case REPORT_TIME_TRACKER_MSG: {
5892 AppTimeTracker tracker = (AppTimeTracker) msg.obj;
5893 tracker.deliverResult(mContext);
5894 } break;
5895 }
5896 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005897 }
5898
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005899 final class UiHandler extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005900 static final int DISMISS_DIALOG_UI_MSG = 1;
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005901
5902 public UiHandler() {
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -08005903 super(UiThread.get().getLooper(), null, true);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005904 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005905
5906 @Override
5907 public void handleMessage(Message msg) {
5908 switch (msg.what) {
5909 case DISMISS_DIALOG_UI_MSG: {
5910 final Dialog d = (Dialog) msg.obj;
5911 d.dismiss();
5912 break;
5913 }
5914 }
5915 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005916 }
5917
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005918 final class LocalService extends ActivityTaskManagerInternal {
5919 @Override
5920 public SleepToken acquireSleepToken(String tag, int displayId) {
5921 Preconditions.checkNotNull(tag);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005922 return ActivityTaskManagerService.this.acquireSleepToken(tag, displayId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005923 }
5924
5925 @Override
5926 public ComponentName getHomeActivityForUser(int userId) {
5927 synchronized (mGlobalLock) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08005928 final ActivityRecord homeActivity =
5929 mRootActivityContainer.getDefaultDisplayHomeActivityForUser(userId);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08005930 return homeActivity == null ? null : homeActivity.mActivityComponent;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005931 }
5932 }
5933
5934 @Override
5935 public void onLocalVoiceInteractionStarted(IBinder activity,
5936 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
5937 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005938 onLocalVoiceInteractionStartedLocked(activity, voiceSession, voiceInteractor);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005939 }
5940 }
5941
5942 @Override
5943 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
5944 synchronized (mGlobalLock) {
5945 mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
5946 reasons, timestamp);
5947 }
5948 }
5949
5950 @Override
5951 public void notifyAppTransitionFinished() {
5952 synchronized (mGlobalLock) {
5953 mStackSupervisor.notifyAppTransitionDone();
5954 }
5955 }
5956
5957 @Override
5958 public void notifyAppTransitionCancelled() {
5959 synchronized (mGlobalLock) {
5960 mStackSupervisor.notifyAppTransitionDone();
5961 }
5962 }
5963
5964 @Override
5965 public List<IBinder> getTopVisibleActivities() {
5966 synchronized (mGlobalLock) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08005967 return mRootActivityContainer.getTopVisibleActivities();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005968 }
5969 }
5970
5971 @Override
5972 public void notifyDockedStackMinimizedChanged(boolean minimized) {
5973 synchronized (mGlobalLock) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08005974 mRootActivityContainer.setDockedStackMinimized(minimized);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005975 }
5976 }
5977
5978 @Override
5979 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
5980 Bundle bOptions) {
5981 Preconditions.checkNotNull(intents, "intents");
5982 final String[] resolvedTypes = new String[intents.length];
5983
5984 // UID of the package on user userId.
5985 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
5986 // packageUid may not be initialized.
5987 int packageUid = 0;
5988 final long ident = Binder.clearCallingIdentity();
5989
5990 try {
5991 for (int i = 0; i < intents.length; i++) {
5992 resolvedTypes[i] =
5993 intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
5994 }
5995
5996 packageUid = AppGlobals.getPackageManager().getPackageUid(
5997 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
5998 } catch (RemoteException e) {
5999 // Shouldn't happen.
6000 } finally {
6001 Binder.restoreCallingIdentity(ident);
6002 }
6003
Riddle Hsu591bf612019-02-14 17:55:31 +08006004 return getActivityStartController().startActivitiesInPackage(
6005 packageUid, packageName,
6006 intents, resolvedTypes, null /* resultTo */,
6007 SafeActivityOptions.fromBundle(bOptions), userId,
6008 false /* validateIncomingUser */, null /* originatingPendingIntent */,
6009 false /* allowBackgroundActivityStart */);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07006010 }
6011
6012 @Override
Michal Karpinski84d9ebd2019-01-17 18:28:59 +00006013 public int startActivitiesInPackage(int uid, int realCallingPid, int realCallingUid,
6014 String callingPackage, Intent[] intents, String[] resolvedTypes, IBinder resultTo,
6015 SafeActivityOptions options, int userId, boolean validateIncomingUser,
6016 PendingIntentRecord originatingPendingIntent,
Michal Karpinskiac116df2018-12-10 17:51:42 +00006017 boolean allowBackgroundActivityStart) {
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07006018 synchronized (mGlobalLock) {
Michal Karpinski84d9ebd2019-01-17 18:28:59 +00006019 return getActivityStartController().startActivitiesInPackage(uid, realCallingPid,
6020 realCallingUid, callingPackage, intents, resolvedTypes, resultTo, options,
6021 userId, validateIncomingUser, originatingPendingIntent,
6022 allowBackgroundActivityStart);
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07006023 }
6024 }
6025
6026 @Override
6027 public int startActivityInPackage(int uid, int realCallingPid, int realCallingUid,
6028 String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
6029 String resultWho, int requestCode, int startFlags, SafeActivityOptions options,
6030 int userId, TaskRecord inTask, String reason, boolean validateIncomingUser,
Michal Karpinskiac116df2018-12-10 17:51:42 +00006031 PendingIntentRecord originatingPendingIntent,
6032 boolean allowBackgroundActivityStart) {
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07006033 synchronized (mGlobalLock) {
6034 return getActivityStartController().startActivityInPackage(uid, realCallingPid,
6035 realCallingUid, callingPackage, intent, resolvedType, resultTo, resultWho,
6036 requestCode, startFlags, options, userId, inTask, reason,
Michal Karpinskiac116df2018-12-10 17:51:42 +00006037 validateIncomingUser, originatingPendingIntent,
6038 allowBackgroundActivityStart);
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07006039 }
6040 }
6041
6042 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07006043 public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
6044 Intent intent, Bundle options, int userId) {
6045 return ActivityTaskManagerService.this.startActivityAsUser(
6046 caller, callerPacakge, intent,
6047 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
6048 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
6049 false /*validateIncomingUser*/);
6050 }
6051
6052 @Override
lumark588a3e82018-07-20 18:53:54 +08006053 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback, int displayId) {
Wale Ogunwale6767eae2018-05-03 15:52:51 -07006054 synchronized (mGlobalLock) {
6055
6056 // We might change the visibilities here, so prepare an empty app transition which
6057 // might be overridden later if we actually change visibilities.
lumark52ea28e2018-11-09 17:30:47 +08006058 final ActivityDisplay activityDisplay =
Wale Ogunwaled32da472018-11-16 07:19:28 -08006059 mRootActivityContainer.getActivityDisplay(displayId);
lumark52ea28e2018-11-09 17:30:47 +08006060 if (activityDisplay == null) {
6061 return;
6062 }
Wale Ogunwale3a256e62018-12-06 14:41:18 -08006063 final DisplayContent dc = activityDisplay.mDisplayContent;
6064 final boolean wasTransitionSet =
6065 dc.mAppTransition.getAppTransition() != TRANSIT_NONE;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07006066 if (!wasTransitionSet) {
Wale Ogunwale3a256e62018-12-06 14:41:18 -08006067 dc.prepareAppTransition(TRANSIT_NONE, false /* alwaysKeepCurrent */);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07006068 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08006069 mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07006070
6071 // If there was a transition set already we don't want to interfere with it as we
6072 // might be starting it too early.
6073 if (!wasTransitionSet) {
Wale Ogunwale3a256e62018-12-06 14:41:18 -08006074 dc.executeAppTransition();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07006075 }
6076 }
6077 if (callback != null) {
6078 callback.run();
6079 }
6080 }
6081
6082 @Override
6083 public void notifyKeyguardTrustedChanged() {
6084 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07006085 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08006086 mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07006087 }
6088 }
6089 }
6090
6091 /**
6092 * Called after virtual display Id is updated by
6093 * {@link com.android.server.vr.Vr2dDisplay} with a specific
6094 * {@param vrVr2dDisplayId}.
6095 */
6096 @Override
6097 public void setVr2dDisplayId(int vr2dDisplayId) {
6098 if (DEBUG_STACK) Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
6099 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07006100 mVr2dDisplayId = vr2dDisplayId;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07006101 }
6102 }
6103
6104 @Override
6105 public void setFocusedActivity(IBinder token) {
6106 synchronized (mGlobalLock) {
6107 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
6108 if (r == null) {
6109 throw new IllegalArgumentException(
6110 "setFocusedActivity: No activity record matching token=" + token);
6111 }
Louis Chang19443452018-10-09 12:10:21 +08006112 if (r.moveFocusableActivityToTop("setFocusedActivity")) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08006113 mRootActivityContainer.resumeFocusedStacksTopActivities();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07006114 }
6115 }
6116 }
6117
6118 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07006119 public void registerScreenObserver(ScreenObserver observer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07006120 mScreenObservers.add(observer);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07006121 }
6122
6123 @Override
6124 public boolean isCallerRecents(int callingUid) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07006125 return getRecentTasks().isCallerRecents(callingUid);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07006126 }
6127
6128 @Override
6129 public boolean isRecentsComponentHomeActivity(int userId) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07006130 return getRecentTasks().isRecentsComponentHomeActivity(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07006131 }
6132
6133 @Override
6134 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
6135 ActivityTaskManagerService.this.cancelRecentsAnimation(restoreHomeStackPosition);
6136 }
6137
6138 @Override
6139 public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07006140 ActivityTaskManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07006141 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07006142
6143 @Override
6144 public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
6145 synchronized (mGlobalLock) {
6146 mActiveVoiceInteractionServiceComponent = component;
6147 }
6148 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07006149
6150 @Override
6151 public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
6152 if (!mAmInternal.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
6153 return;
6154 }
6155 synchronized (mGlobalLock) {
6156 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
6157 if (types == null) {
6158 if (uid < 0) {
6159 return;
6160 }
6161 types = new ArrayMap<>();
6162 mAllowAppSwitchUids.put(userId, types);
6163 }
6164 if (uid < 0) {
6165 types.remove(type);
6166 } else {
6167 types.put(type, uid);
6168 }
6169 }
6170 }
6171
6172 @Override
6173 public void onUserStopped(int userId) {
6174 synchronized (mGlobalLock) {
6175 getRecentTasks().unloadUserDataFromMemoryLocked(userId);
6176 mAllowAppSwitchUids.remove(userId);
6177 }
6178 }
6179
6180 @Override
6181 public boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
6182 synchronized (mGlobalLock) {
6183 return ActivityTaskManagerService.this.isGetTasksAllowed(
6184 caller, callingPid, callingUid);
6185 }
6186 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07006187
Riddle Hsua0536432019-02-16 00:38:59 +08006188 @HotPath(caller = HotPath.PROCESS_CHANGE)
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07006189 @Override
6190 public void onProcessAdded(WindowProcessController proc) {
Riddle Hsua0536432019-02-16 00:38:59 +08006191 synchronized (mGlobalLockWithoutBoost) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07006192 mProcessNames.put(proc.mName, proc.mUid, proc);
6193 }
6194 }
6195
Riddle Hsua0536432019-02-16 00:38:59 +08006196 @HotPath(caller = HotPath.PROCESS_CHANGE)
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07006197 @Override
6198 public void onProcessRemoved(String name, int uid) {
Riddle Hsua0536432019-02-16 00:38:59 +08006199 synchronized (mGlobalLockWithoutBoost) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07006200 mProcessNames.remove(name, uid);
6201 }
6202 }
6203
Riddle Hsua0536432019-02-16 00:38:59 +08006204 @HotPath(caller = HotPath.PROCESS_CHANGE)
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07006205 @Override
6206 public void onCleanUpApplicationRecord(WindowProcessController proc) {
Riddle Hsua0536432019-02-16 00:38:59 +08006207 synchronized (mGlobalLockWithoutBoost) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07006208 if (proc == mHomeProcess) {
6209 mHomeProcess = null;
6210 }
6211 if (proc == mPreviousProcess) {
6212 mPreviousProcess = null;
6213 }
6214 }
6215 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07006216
Riddle Hsua0536432019-02-16 00:38:59 +08006217 @HotPath(caller = HotPath.OOM_ADJUSTMENT)
Wale Ogunwalef6733932018-06-27 05:14:34 -07006218 @Override
6219 public int getTopProcessState() {
Riddle Hsua0536432019-02-16 00:38:59 +08006220 synchronized (mGlobalLockWithoutBoost) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07006221 return mTopProcessState;
6222 }
6223 }
6224
Riddle Hsua0536432019-02-16 00:38:59 +08006225 @HotPath(caller = HotPath.OOM_ADJUSTMENT)
Wale Ogunwalef6733932018-06-27 05:14:34 -07006226 @Override
Wale Ogunwale53783742018-09-16 10:21:51 -07006227 public boolean isHeavyWeightProcess(WindowProcessController proc) {
Riddle Hsua0536432019-02-16 00:38:59 +08006228 synchronized (mGlobalLockWithoutBoost) {
Wale Ogunwale53783742018-09-16 10:21:51 -07006229 return proc == mHeavyWeightProcess;
6230 }
6231 }
6232
Riddle Hsua0536432019-02-16 00:38:59 +08006233 @HotPath(caller = HotPath.PROCESS_CHANGE)
Wale Ogunwale53783742018-09-16 10:21:51 -07006234 @Override
6235 public void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
Riddle Hsua0536432019-02-16 00:38:59 +08006236 synchronized (mGlobalLockWithoutBoost) {
Wale Ogunwale53783742018-09-16 10:21:51 -07006237 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(proc);
6238 }
6239 }
6240
6241 @Override
6242 public void finishHeavyWeightApp() {
6243 synchronized (mGlobalLock) {
Sudheer Shankaee1da272018-10-20 20:11:44 -07006244 if (mHeavyWeightProcess != null) {
6245 mHeavyWeightProcess.finishActivities();
6246 }
Wale Ogunwale53783742018-09-16 10:21:51 -07006247 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(
6248 mHeavyWeightProcess);
6249 }
6250 }
6251
Riddle Hsua0536432019-02-16 00:38:59 +08006252 @HotPath(caller = HotPath.OOM_ADJUSTMENT)
Wale Ogunwale53783742018-09-16 10:21:51 -07006253 @Override
Wale Ogunwalef6733932018-06-27 05:14:34 -07006254 public boolean isSleeping() {
Riddle Hsua0536432019-02-16 00:38:59 +08006255 synchronized (mGlobalLockWithoutBoost) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07006256 return isSleepingLocked();
6257 }
6258 }
6259
6260 @Override
6261 public boolean isShuttingDown() {
6262 synchronized (mGlobalLock) {
6263 return mShuttingDown;
6264 }
6265 }
6266
6267 @Override
6268 public boolean shuttingDown(boolean booted, int timeout) {
6269 synchronized (mGlobalLock) {
6270 mShuttingDown = true;
Wale Ogunwaled32da472018-11-16 07:19:28 -08006271 mRootActivityContainer.prepareForShutdown();
Wale Ogunwalef6733932018-06-27 05:14:34 -07006272 updateEventDispatchingLocked(booted);
Wale Ogunwaled4d67d02018-10-25 18:09:39 -07006273 notifyTaskPersisterLocked(null, true);
Wale Ogunwalef6733932018-06-27 05:14:34 -07006274 return mStackSupervisor.shutdownLocked(timeout);
6275 }
6276 }
6277
6278 @Override
6279 public void enableScreenAfterBoot(boolean booted) {
6280 synchronized (mGlobalLock) {
6281 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6282 SystemClock.uptimeMillis());
6283 mWindowManager.enableScreenAfterBoot();
6284 updateEventDispatchingLocked(booted);
6285 }
6286 }
6287
6288 @Override
6289 public boolean showStrictModeViolationDialog() {
6290 synchronized (mGlobalLock) {
6291 return mShowDialogs && !mSleeping && !mShuttingDown;
6292 }
6293 }
6294
6295 @Override
6296 public void showSystemReadyErrorDialogsIfNeeded() {
6297 synchronized (mGlobalLock) {
6298 try {
6299 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
6300 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
6301 + " data partition or your device will be unstable.");
6302 mUiHandler.post(() -> {
6303 if (mShowDialogs) {
6304 AlertDialog d = new BaseErrorDialog(mUiContext);
6305 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
6306 d.setCancelable(false);
6307 d.setTitle(mUiContext.getText(R.string.android_system_label));
6308 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
6309 d.setButton(DialogInterface.BUTTON_POSITIVE,
6310 mUiContext.getText(R.string.ok),
6311 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
6312 d.show();
6313 }
6314 });
6315 }
6316 } catch (RemoteException e) {
6317 }
6318
6319 if (!Build.isBuildConsistent()) {
6320 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
6321 mUiHandler.post(() -> {
6322 if (mShowDialogs) {
6323 AlertDialog d = new BaseErrorDialog(mUiContext);
6324 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
6325 d.setCancelable(false);
6326 d.setTitle(mUiContext.getText(R.string.android_system_label));
6327 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
6328 d.setButton(DialogInterface.BUTTON_POSITIVE,
6329 mUiContext.getText(R.string.ok),
6330 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
6331 d.show();
6332 }
6333 });
6334 }
6335 }
6336 }
Wale Ogunwale906f9c62018-07-23 11:23:44 -07006337
6338 @Override
Wale Ogunwale906f9c62018-07-23 11:23:44 -07006339 public void onProcessMapped(int pid, WindowProcessController proc) {
6340 synchronized (mGlobalLock) {
6341 mPidMap.put(pid, proc);
6342 }
6343 }
6344
6345 @Override
6346 public void onProcessUnMapped(int pid) {
6347 synchronized (mGlobalLock) {
6348 mPidMap.remove(pid);
6349 }
6350 }
Wale Ogunwale008163e2018-07-23 23:11:08 -07006351
6352 @Override
6353 public void onPackageDataCleared(String name) {
6354 synchronized (mGlobalLock) {
Wale Ogunwale53783742018-09-16 10:21:51 -07006355 mCompatModePackages.handlePackageDataClearedLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07006356 mAppWarnings.onPackageDataCleared(name);
6357 }
6358 }
6359
6360 @Override
6361 public void onPackageUninstalled(String name) {
6362 synchronized (mGlobalLock) {
6363 mAppWarnings.onPackageUninstalled(name);
Wale Ogunwale53783742018-09-16 10:21:51 -07006364 mCompatModePackages.handlePackageUninstalledLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07006365 }
6366 }
Wale Ogunwale53783742018-09-16 10:21:51 -07006367
6368 @Override
6369 public void onPackageAdded(String name, boolean replacing) {
6370 synchronized (mGlobalLock) {
6371 mCompatModePackages.handlePackageAddedLocked(name, replacing);
6372 }
6373 }
6374
6375 @Override
Wale Ogunwale31913b52018-10-13 08:29:31 -07006376 public void onPackageReplaced(ApplicationInfo aInfo) {
6377 synchronized (mGlobalLock) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08006378 mRootActivityContainer.updateActivityApplicationInfo(aInfo);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006379 }
6380 }
6381
6382 @Override
Wale Ogunwale53783742018-09-16 10:21:51 -07006383 public CompatibilityInfo compatibilityInfoForPackage(ApplicationInfo ai) {
6384 synchronized (mGlobalLock) {
6385 return compatibilityInfoForPackageLocked(ai);
6386 }
6387 }
6388
Yunfan Chen75157d72018-07-27 14:47:21 +09006389 /**
6390 * Set the corresponding display information for the process global configuration. To be
6391 * called when we need to show IME on a different display.
6392 *
6393 * @param pid The process id associated with the IME window.
6394 * @param displayId The ID of the display showing the IME.
6395 */
6396 @Override
Yunfan Chen79b96062018-10-17 12:45:23 -07006397 public void onImeWindowSetOnDisplay(final int pid, final int displayId) {
Yunfan Chen75157d72018-07-27 14:47:21 +09006398 if (pid == MY_PID || pid < 0) {
6399 if (DEBUG_CONFIGURATION) {
6400 Slog.w(TAG,
6401 "Trying to update display configuration for system/invalid process.");
6402 }
6403 return;
6404 }
Yunfan Chencafc7062019-01-22 17:21:32 +09006405 synchronized (mGlobalLock) {
6406 final ActivityDisplay activityDisplay =
6407 mRootActivityContainer.getActivityDisplay(displayId);
6408 if (activityDisplay == null) {
6409 // Call might come when display is not yet added or has been removed.
6410 if (DEBUG_CONFIGURATION) {
6411 Slog.w(TAG, "Trying to update display configuration for non-existing "
6412 + "displayId=" + displayId);
Yunfan Chen75157d72018-07-27 14:47:21 +09006413 }
Yunfan Chencafc7062019-01-22 17:21:32 +09006414 return;
Yunfan Chen75157d72018-07-27 14:47:21 +09006415 }
Yunfan Chencafc7062019-01-22 17:21:32 +09006416 final WindowProcessController process = mPidMap.get(pid);
6417 if (process == null) {
6418 if (DEBUG_CONFIGURATION) {
6419 Slog.w(TAG, "Trying to update display configuration for invalid "
6420 + "process, pid=" + pid);
6421 }
6422 return;
6423 }
6424 process.registerDisplayConfigurationListenerLocked(activityDisplay);
6425 }
Yunfan Chen75157d72018-07-27 14:47:21 +09006426 }
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07006427
6428 @Override
6429 public void sendActivityResult(int callingUid, IBinder activityToken, String resultWho,
6430 int requestCode, int resultCode, Intent data) {
6431 synchronized (mGlobalLock) {
6432 final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08006433 if (r != null && r.getActivityStack() != null) {
6434 r.getActivityStack().sendActivityResultLocked(callingUid, r, resultWho,
6435 requestCode, resultCode, data);
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07006436 }
6437 }
6438 }
6439
6440 @Override
6441 public void clearPendingResultForActivity(IBinder activityToken,
6442 WeakReference<PendingIntentRecord> pir) {
6443 synchronized (mGlobalLock) {
6444 final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
6445 if (r != null && r.pendingResults != null) {
6446 r.pendingResults.remove(pir);
6447 }
6448 }
6449 }
6450
6451 @Override
6452 public IIntentSender getIntentSender(int type, String packageName,
6453 int callingUid, int userId, IBinder token, String resultWho,
6454 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6455 Bundle bOptions) {
6456 synchronized (mGlobalLock) {
6457 return getIntentSenderLocked(type, packageName, callingUid, userId, token,
6458 resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6459 }
6460 }
Wale Ogunwalec4e63a42018-10-02 13:19:54 -07006461
6462 @Override
6463 public ActivityServiceConnectionsHolder getServiceConnectionsHolder(IBinder token) {
6464 synchronized (mGlobalLock) {
6465 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
6466 if (r == null) {
6467 return null;
6468 }
6469 if (r.mServiceConnectionsHolder == null) {
6470 r.mServiceConnectionsHolder = new ActivityServiceConnectionsHolder(
6471 ActivityTaskManagerService.this, r);
6472 }
6473
6474 return r.mServiceConnectionsHolder;
6475 }
6476 }
Wale Ogunwale214f3482018-10-04 11:00:47 -07006477
6478 @Override
6479 public Intent getHomeIntent() {
6480 synchronized (mGlobalLock) {
6481 return ActivityTaskManagerService.this.getHomeIntent();
6482 }
6483 }
6484
6485 @Override
6486 public boolean startHomeActivity(int userId, String reason) {
6487 synchronized (mGlobalLock) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08006488 return mRootActivityContainer.startHomeOnDisplay(userId, reason, DEFAULT_DISPLAY);
Louis Chang89f43fc2018-10-05 10:59:14 +08006489 }
6490 }
6491
6492 @Override
Chilun8b1f1be2019-03-13 17:14:36 +08006493 public boolean startHomeOnDisplay(int userId, String reason, int displayId,
6494 boolean fromHomeKey) {
6495 return mRootActivityContainer.startHomeOnDisplay(userId, reason, displayId,
6496 fromHomeKey);
6497 }
6498
6499 @Override
Louis Chang89f43fc2018-10-05 10:59:14 +08006500 public boolean startHomeOnAllDisplays(int userId, String reason) {
6501 synchronized (mGlobalLock) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08006502 return mRootActivityContainer.startHomeOnAllDisplays(userId, reason);
Wale Ogunwale214f3482018-10-04 11:00:47 -07006503 }
6504 }
6505
Riddle Hsua0536432019-02-16 00:38:59 +08006506 @HotPath(caller = HotPath.PROCESS_CHANGE)
Wale Ogunwale214f3482018-10-04 11:00:47 -07006507 @Override
6508 public boolean isFactoryTestProcess(WindowProcessController wpc) {
Riddle Hsua0536432019-02-16 00:38:59 +08006509 synchronized (mGlobalLockWithoutBoost) {
Wale Ogunwale214f3482018-10-04 11:00:47 -07006510 if (mFactoryTest == FACTORY_TEST_OFF) {
6511 return false;
6512 }
6513 if (mFactoryTest == FACTORY_TEST_LOW_LEVEL && mTopComponent != null
6514 && wpc.mName.equals(mTopComponent.getPackageName())) {
6515 return true;
6516 }
6517 return mFactoryTest == FACTORY_TEST_HIGH_LEVEL
6518 && (wpc.mInfo.flags & FLAG_FACTORY_TEST) != 0;
6519 }
6520 }
6521
6522 @Override
6523 public void updateTopComponentForFactoryTest() {
6524 synchronized (mGlobalLock) {
6525 if (mFactoryTest != FACTORY_TEST_LOW_LEVEL) {
6526 return;
6527 }
6528 final ResolveInfo ri = mContext.getPackageManager()
6529 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), STOCK_PM_FLAGS);
6530 final CharSequence errorMsg;
6531 if (ri != null) {
6532 final ActivityInfo ai = ri.activityInfo;
6533 final ApplicationInfo app = ai.applicationInfo;
6534 if ((app.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
6535 mTopAction = Intent.ACTION_FACTORY_TEST;
6536 mTopData = null;
6537 mTopComponent = new ComponentName(app.packageName, ai.name);
6538 errorMsg = null;
6539 } else {
6540 errorMsg = mContext.getResources().getText(
6541 com.android.internal.R.string.factorytest_not_system);
6542 }
6543 } else {
6544 errorMsg = mContext.getResources().getText(
6545 com.android.internal.R.string.factorytest_no_action);
6546 }
6547 if (errorMsg == null) {
6548 return;
6549 }
6550
6551 mTopAction = null;
6552 mTopData = null;
6553 mTopComponent = null;
6554 mUiHandler.post(() -> {
6555 Dialog d = new FactoryErrorDialog(mUiContext, errorMsg);
6556 d.show();
Wale Ogunwale342fbe92018-10-09 08:44:10 -07006557 mAmInternal.ensureBootCompleted();
Wale Ogunwale214f3482018-10-04 11:00:47 -07006558 });
6559 }
6560 }
Wale Ogunwale31913b52018-10-13 08:29:31 -07006561
Riddle Hsua0536432019-02-16 00:38:59 +08006562 @HotPath(caller = HotPath.PROCESS_CHANGE)
Wale Ogunwale31913b52018-10-13 08:29:31 -07006563 @Override
6564 public void handleAppDied(WindowProcessController wpc, boolean restarting,
6565 Runnable finishInstrumentationCallback) {
Riddle Hsua0536432019-02-16 00:38:59 +08006566 synchronized (mGlobalLockWithoutBoost) {
Wale Ogunwale31913b52018-10-13 08:29:31 -07006567 // Remove this application's activities from active lists.
Wale Ogunwaled32da472018-11-16 07:19:28 -08006568 boolean hasVisibleActivities = mRootActivityContainer.handleAppDied(wpc);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006569
6570 wpc.clearRecentTasks();
6571 wpc.clearActivities();
6572
6573 if (wpc.isInstrumenting()) {
6574 finishInstrumentationCallback.run();
6575 }
6576
Jorim Jaggid0752812018-10-16 16:07:20 +02006577 if (!restarting && hasVisibleActivities) {
6578 mWindowManager.deferSurfaceLayout();
6579 try {
6580 if (!mRootActivityContainer.resumeFocusedStacksTopActivities()) {
6581 // If there was nothing to resume, and we are not already restarting
6582 // this process, but there is a visible activity that is hosted by the
6583 // process...then make sure all visible activities are running, taking
6584 // care of restarting this process.
6585 mRootActivityContainer.ensureActivitiesVisible(null, 0,
6586 !PRESERVE_WINDOWS);
6587 }
6588 } finally {
6589 mWindowManager.continueSurfaceLayout();
Wale Ogunwale31913b52018-10-13 08:29:31 -07006590 }
Wale Ogunwale31913b52018-10-13 08:29:31 -07006591 }
6592 }
6593 }
6594
6595 @Override
6596 public void closeSystemDialogs(String reason) {
6597 enforceNotIsolatedCaller("closeSystemDialogs");
6598
6599 final int pid = Binder.getCallingPid();
6600 final int uid = Binder.getCallingUid();
6601 final long origId = Binder.clearCallingIdentity();
6602 try {
6603 synchronized (mGlobalLock) {
6604 // Only allow this from foreground processes, so that background
6605 // applications can't abuse it to prevent system UI from being shown.
6606 if (uid >= FIRST_APPLICATION_UID) {
6607 final WindowProcessController proc = mPidMap.get(pid);
6608 if (!proc.isPerceptible()) {
6609 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6610 + " from background process " + proc);
6611 return;
6612 }
6613 }
Wale Ogunwale31913b52018-10-13 08:29:31 -07006614 mWindowManager.closeSystemDialogs(reason);
6615
Wale Ogunwaled32da472018-11-16 07:19:28 -08006616 mRootActivityContainer.closeSystemDialogs();
Wale Ogunwale31913b52018-10-13 08:29:31 -07006617 }
Wale Ogunwale2ea36d42018-10-18 10:27:31 -07006618 // Call into AM outside the synchronized block.
6619 mAmInternal.broadcastCloseSystemDialogs(reason);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006620 } finally {
6621 Binder.restoreCallingIdentity(origId);
6622 }
6623 }
6624
6625 @Override
6626 public void cleanupDisabledPackageComponents(
6627 String packageName, Set<String> disabledClasses, int userId, boolean booted) {
6628 synchronized (mGlobalLock) {
6629 // Clean-up disabled activities.
Wale Ogunwaled32da472018-11-16 07:19:28 -08006630 if (mRootActivityContainer.finishDisabledPackageActivities(
Wale Ogunwale31913b52018-10-13 08:29:31 -07006631 packageName, disabledClasses, true, false, userId) && booted) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08006632 mRootActivityContainer.resumeFocusedStacksTopActivities();
Wale Ogunwale31913b52018-10-13 08:29:31 -07006633 mStackSupervisor.scheduleIdleLocked();
6634 }
6635
6636 // Clean-up disabled tasks
6637 getRecentTasks().cleanupDisabledPackageTasksLocked(
6638 packageName, disabledClasses, userId);
6639 }
6640 }
6641
6642 @Override
6643 public boolean onForceStopPackage(String packageName, boolean doit, boolean evenPersistent,
6644 int userId) {
6645 synchronized (mGlobalLock) {
6646
6647 boolean didSomething =
6648 getActivityStartController().clearPendingActivityLaunches(packageName);
Wale Ogunwaled32da472018-11-16 07:19:28 -08006649 didSomething |= mRootActivityContainer.finishDisabledPackageActivities(packageName,
Wale Ogunwale31913b52018-10-13 08:29:31 -07006650 null, doit, evenPersistent, userId);
6651 return didSomething;
6652 }
6653 }
6654
6655 @Override
6656 public void resumeTopActivities(boolean scheduleIdle) {
6657 synchronized (mGlobalLock) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08006658 mRootActivityContainer.resumeFocusedStacksTopActivities();
Wale Ogunwale31913b52018-10-13 08:29:31 -07006659 if (scheduleIdle) {
6660 mStackSupervisor.scheduleIdleLocked();
6661 }
6662 }
6663 }
6664
Riddle Hsua0536432019-02-16 00:38:59 +08006665 @HotPath(caller = HotPath.PROCESS_CHANGE)
Wale Ogunwale31913b52018-10-13 08:29:31 -07006666 @Override
6667 public void preBindApplication(WindowProcessController wpc) {
Riddle Hsua0536432019-02-16 00:38:59 +08006668 synchronized (mGlobalLockWithoutBoost) {
Wale Ogunwale31913b52018-10-13 08:29:31 -07006669 mStackSupervisor.getActivityMetricsLogger().notifyBindApplication(wpc.mInfo);
6670 }
6671 }
6672
Riddle Hsua0536432019-02-16 00:38:59 +08006673 @HotPath(caller = HotPath.PROCESS_CHANGE)
Wale Ogunwale31913b52018-10-13 08:29:31 -07006674 @Override
6675 public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
Riddle Hsua0536432019-02-16 00:38:59 +08006676 synchronized (mGlobalLockWithoutBoost) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08006677 return mRootActivityContainer.attachApplication(wpc);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006678 }
6679 }
6680
6681 @Override
6682 public void notifyLockedProfile(@UserIdInt int userId, int currentUserId) {
6683 try {
6684 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
6685 throw new SecurityException("Only privileged app can call notifyLockedProfile");
6686 }
6687 } catch (RemoteException ex) {
6688 throw new SecurityException("Fail to check is caller a privileged app", ex);
6689 }
6690
6691 synchronized (mGlobalLock) {
6692 final long ident = Binder.clearCallingIdentity();
6693 try {
6694 if (mAmInternal.shouldConfirmCredentials(userId)) {
6695 if (mKeyguardController.isKeyguardLocked()) {
6696 // Showing launcher to avoid user entering credential twice.
6697 startHomeActivity(currentUserId, "notifyLockedProfile");
6698 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08006699 mRootActivityContainer.lockAllProfileTasks(userId);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006700 }
6701 } finally {
6702 Binder.restoreCallingIdentity(ident);
6703 }
6704 }
6705 }
6706
6707 @Override
6708 public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
6709 mAmInternal.enforceCallingPermission(
6710 MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
6711
6712 synchronized (mGlobalLock) {
6713 final long ident = Binder.clearCallingIdentity();
6714 try {
6715 intent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
6716 FLAG_ACTIVITY_TASK_ON_HOME);
6717 ActivityOptions activityOptions = options != null
6718 ? new ActivityOptions(options) : ActivityOptions.makeBasic();
Martijn Coenen2a5c8392018-10-01 10:17:06 +02006719 final ActivityRecord homeActivity =
Wale Ogunwaled32da472018-11-16 07:19:28 -08006720 mRootActivityContainer.getDefaultDisplayHomeActivity();
Martijn Coenen2a5c8392018-10-01 10:17:06 +02006721 if (homeActivity != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08006722 activityOptions.setLaunchTaskId(homeActivity.getTaskRecord().taskId);
Martijn Coenen2a5c8392018-10-01 10:17:06 +02006723 }
Wale Ogunwale31913b52018-10-13 08:29:31 -07006724 mContext.startActivityAsUser(intent, activityOptions.toBundle(),
6725 UserHandle.CURRENT);
6726 } finally {
6727 Binder.restoreCallingIdentity(ident);
6728 }
6729 }
6730 }
6731
6732 @Override
6733 public void writeActivitiesToProto(ProtoOutputStream proto) {
6734 synchronized (mGlobalLock) {
6735 // The output proto of "activity --proto activities"
6736 // is ActivityManagerServiceDumpActivitiesProto
Wale Ogunwaled32da472018-11-16 07:19:28 -08006737 mRootActivityContainer.writeToProto(proto,
Nataniel Borges023ecb52019-01-16 14:15:43 -08006738 ActivityManagerServiceDumpActivitiesProto.ACTIVITY_STACK_SUPERVISOR,
6739 WindowTraceLogLevel.ALL);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006740 }
6741 }
6742
6743 @Override
6744 public void saveANRState(String reason) {
6745 synchronized (mGlobalLock) {
6746 final StringWriter sw = new StringWriter();
6747 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
6748 pw.println(" ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
6749 if (reason != null) {
6750 pw.println(" Reason: " + reason);
6751 }
6752 pw.println();
6753 getActivityStartController().dump(pw, " ", null);
6754 pw.println();
6755 pw.println("-------------------------------------------------------------------------------");
6756 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
6757 true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
6758 "" /* header */);
6759 pw.println();
6760 pw.close();
6761
6762 mLastANRState = sw.toString();
6763 }
6764 }
6765
6766 @Override
6767 public void clearSavedANRState() {
6768 synchronized (mGlobalLock) {
6769 mLastANRState = null;
6770 }
6771 }
6772
6773 @Override
6774 public void dump(String cmd, FileDescriptor fd, PrintWriter pw, String[] args, int opti,
6775 boolean dumpAll, boolean dumpClient, String dumpPackage) {
6776 synchronized (mGlobalLock) {
6777 if (DUMP_ACTIVITIES_CMD.equals(cmd) || DUMP_ACTIVITIES_SHORT_CMD.equals(cmd)) {
6778 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
6779 } else if (DUMP_LASTANR_CMD.equals(cmd)) {
6780 dumpLastANRLocked(pw);
6781 } else if (DUMP_LASTANR_TRACES_CMD.equals(cmd)) {
6782 dumpLastANRTracesLocked(pw);
6783 } else if (DUMP_STARTER_CMD.equals(cmd)) {
6784 dumpActivityStarterLocked(pw, dumpPackage);
6785 } else if (DUMP_CONTAINERS_CMD.equals(cmd)) {
6786 dumpActivityContainersLocked(pw);
6787 } else if (DUMP_RECENTS_CMD.equals(cmd) || DUMP_RECENTS_SHORT_CMD.equals(cmd)) {
6788 if (getRecentTasks() != null) {
6789 getRecentTasks().dump(pw, dumpAll, dumpPackage);
6790 }
6791 }
6792 }
6793 }
6794
6795 @Override
6796 public boolean dumpForProcesses(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
6797 String dumpPackage, int dumpAppId, boolean needSep, boolean testPssMode,
6798 int wakefulness) {
6799 synchronized (mGlobalLock) {
6800 if (mHomeProcess != null && (dumpPackage == null
6801 || mHomeProcess.mPkgList.contains(dumpPackage))) {
6802 if (needSep) {
6803 pw.println();
6804 needSep = false;
6805 }
6806 pw.println(" mHomeProcess: " + mHomeProcess);
6807 }
6808 if (mPreviousProcess != null && (dumpPackage == null
6809 || mPreviousProcess.mPkgList.contains(dumpPackage))) {
6810 if (needSep) {
6811 pw.println();
6812 needSep = false;
6813 }
6814 pw.println(" mPreviousProcess: " + mPreviousProcess);
6815 }
6816 if (dumpAll && (mPreviousProcess == null || dumpPackage == null
6817 || mPreviousProcess.mPkgList.contains(dumpPackage))) {
6818 StringBuilder sb = new StringBuilder(128);
6819 sb.append(" mPreviousProcessVisibleTime: ");
6820 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
6821 pw.println(sb);
6822 }
6823 if (mHeavyWeightProcess != null && (dumpPackage == null
6824 || mHeavyWeightProcess.mPkgList.contains(dumpPackage))) {
6825 if (needSep) {
6826 pw.println();
6827 needSep = false;
6828 }
6829 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
6830 }
6831 if (dumpPackage == null) {
6832 pw.println(" mGlobalConfiguration: " + getGlobalConfiguration());
Wale Ogunwaled32da472018-11-16 07:19:28 -08006833 mRootActivityContainer.dumpDisplayConfigs(pw, " ");
Wale Ogunwale31913b52018-10-13 08:29:31 -07006834 }
6835 if (dumpAll) {
6836 if (dumpPackage == null) {
6837 pw.println(" mConfigWillChange: "
6838 + getTopDisplayFocusedStack().mConfigWillChange);
6839 }
6840 if (mCompatModePackages.getPackages().size() > 0) {
6841 boolean printed = false;
6842 for (Map.Entry<String, Integer> entry
6843 : mCompatModePackages.getPackages().entrySet()) {
6844 String pkg = entry.getKey();
6845 int mode = entry.getValue();
6846 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
6847 continue;
6848 }
6849 if (!printed) {
6850 pw.println(" mScreenCompatPackages:");
6851 printed = true;
6852 }
6853 pw.println(" " + pkg + ": " + mode);
6854 }
6855 }
6856 }
6857
6858 if (dumpPackage == null) {
6859 pw.println(" mWakefulness="
6860 + PowerManagerInternal.wakefulnessToString(wakefulness));
Wale Ogunwaled32da472018-11-16 07:19:28 -08006861 pw.println(" mSleepTokens=" + mRootActivityContainer.mSleepTokens);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006862 if (mRunningVoice != null) {
6863 pw.println(" mRunningVoice=" + mRunningVoice);
6864 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
6865 }
6866 pw.println(" mSleeping=" + mSleeping);
6867 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + testPssMode);
6868 pw.println(" mVrController=" + mVrController);
6869 }
6870 if (mCurAppTimeTracker != null) {
6871 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
6872 }
6873 if (mAllowAppSwitchUids.size() > 0) {
6874 boolean printed = false;
6875 for (int i = 0; i < mAllowAppSwitchUids.size(); i++) {
6876 ArrayMap<String, Integer> types = mAllowAppSwitchUids.valueAt(i);
6877 for (int j = 0; j < types.size(); j++) {
6878 if (dumpPackage == null ||
6879 UserHandle.getAppId(types.valueAt(j).intValue()) == dumpAppId) {
6880 if (needSep) {
6881 pw.println();
6882 needSep = false;
6883 }
6884 if (!printed) {
6885 pw.println(" mAllowAppSwitchUids:");
6886 printed = true;
6887 }
6888 pw.print(" User ");
6889 pw.print(mAllowAppSwitchUids.keyAt(i));
6890 pw.print(": Type ");
6891 pw.print(types.keyAt(j));
6892 pw.print(" = ");
6893 UserHandle.formatUid(pw, types.valueAt(j).intValue());
6894 pw.println();
6895 }
6896 }
6897 }
6898 }
6899 if (dumpPackage == null) {
6900 if (mController != null) {
6901 pw.println(" mController=" + mController
6902 + " mControllerIsAMonkey=" + mControllerIsAMonkey);
6903 }
Andrii Kulianc598b2d2019-02-07 17:16:38 -08006904 pw.println(" mGoingToSleepWakeLock=" + mStackSupervisor.mGoingToSleepWakeLock);
6905 pw.println(" mLaunchingActivityWakeLock="
6906 + mStackSupervisor.mLaunchingActivityWakeLock);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006907 }
6908
6909 return needSep;
6910 }
6911 }
6912
6913 @Override
sanryhuang498e77e2018-12-06 14:57:01 +08006914 public void writeProcessesToProto(ProtoOutputStream proto, String dumpPackage,
6915 int wakeFullness, boolean testPssMode) {
Wale Ogunwale31913b52018-10-13 08:29:31 -07006916 synchronized (mGlobalLock) {
6917 if (dumpPackage == null) {
6918 getGlobalConfiguration().writeToProto(proto, GLOBAL_CONFIGURATION);
6919 proto.write(CONFIG_WILL_CHANGE, getTopDisplayFocusedStack().mConfigWillChange);
sanryhuang498e77e2018-12-06 14:57:01 +08006920 writeSleepStateToProto(proto, wakeFullness, testPssMode);
6921 if (mRunningVoice != null) {
6922 final long vrToken = proto.start(
6923 ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
6924 proto.write(ActivityManagerServiceDumpProcessesProto.Voice.SESSION,
6925 mRunningVoice.toString());
6926 mVoiceWakeLock.writeToProto(
6927 proto, ActivityManagerServiceDumpProcessesProto.Voice.WAKELOCK);
6928 proto.end(vrToken);
6929 }
6930 mVrController.writeToProto(proto,
6931 ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006932 if (mController != null) {
6933 final long token = proto.start(CONTROLLER);
6934 proto.write(CONTROLLER, mController.toString());
6935 proto.write(IS_A_MONKEY, mControllerIsAMonkey);
6936 proto.end(token);
6937 }
Andrii Kulianc598b2d2019-02-07 17:16:38 -08006938 mStackSupervisor.mGoingToSleepWakeLock.writeToProto(proto, GOING_TO_SLEEP);
6939 mStackSupervisor.mLaunchingActivityWakeLock.writeToProto(proto,
6940 LAUNCHING_ACTIVITY);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006941 }
6942
6943 if (mHomeProcess != null && (dumpPackage == null
6944 || mHomeProcess.mPkgList.contains(dumpPackage))) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07006945 mHomeProcess.writeToProto(proto, HOME_PROC);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006946 }
6947
6948 if (mPreviousProcess != null && (dumpPackage == null
6949 || mPreviousProcess.mPkgList.contains(dumpPackage))) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07006950 mPreviousProcess.writeToProto(proto, PREVIOUS_PROC);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006951 proto.write(PREVIOUS_PROC_VISIBLE_TIME_MS, mPreviousProcessVisibleTime);
6952 }
6953
6954 if (mHeavyWeightProcess != null && (dumpPackage == null
6955 || mHeavyWeightProcess.mPkgList.contains(dumpPackage))) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07006956 mHeavyWeightProcess.writeToProto(proto, HEAVY_WEIGHT_PROC);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006957 }
6958
6959 for (Map.Entry<String, Integer> entry
6960 : mCompatModePackages.getPackages().entrySet()) {
6961 String pkg = entry.getKey();
6962 int mode = entry.getValue();
6963 if (dumpPackage == null || dumpPackage.equals(pkg)) {
6964 long compatToken = proto.start(SCREEN_COMPAT_PACKAGES);
6965 proto.write(PACKAGE, pkg);
6966 proto.write(MODE, mode);
6967 proto.end(compatToken);
6968 }
6969 }
6970
6971 if (mCurAppTimeTracker != null) {
6972 mCurAppTimeTracker.writeToProto(proto, CURRENT_TRACKER, true);
6973 }
6974
6975 }
6976 }
6977
6978 @Override
6979 public boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name,
6980 String[] args, int opti, boolean dumpAll, boolean dumpVisibleStacksOnly,
6981 boolean dumpFocusedStackOnly) {
6982 synchronized (mGlobalLock) {
6983 return ActivityTaskManagerService.this.dumpActivity(fd, pw, name, args, opti,
6984 dumpAll, dumpVisibleStacksOnly, dumpFocusedStackOnly);
6985 }
6986 }
6987
6988 @Override
Wale Ogunwaled4d67d02018-10-25 18:09:39 -07006989 public void dumpForOom(PrintWriter pw) {
6990 synchronized (mGlobalLock) {
6991 pw.println(" mHomeProcess: " + mHomeProcess);
6992 pw.println(" mPreviousProcess: " + mPreviousProcess);
6993 if (mHeavyWeightProcess != null) {
6994 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
6995 }
6996 }
6997 }
6998
6999 @Override
Wale Ogunwale31913b52018-10-13 08:29:31 -07007000 public boolean canGcNow() {
7001 synchronized (mGlobalLock) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08007002 return isSleeping() || mRootActivityContainer.allResumedActivitiesIdle();
Wale Ogunwale31913b52018-10-13 08:29:31 -07007003 }
7004 }
7005
Riddle Hsua0536432019-02-16 00:38:59 +08007006 @HotPath(caller = HotPath.OOM_ADJUSTMENT)
Wale Ogunwale31913b52018-10-13 08:29:31 -07007007 @Override
7008 public WindowProcessController getTopApp() {
Riddle Hsud7088f82019-01-30 13:04:50 +08007009 synchronized (mGlobalLockWithoutBoost) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08007010 final ActivityRecord top = mRootActivityContainer.getTopResumedActivity();
Wale Ogunwale31913b52018-10-13 08:29:31 -07007011 return top != null ? top.app : null;
7012 }
7013 }
7014
Riddle Hsua0536432019-02-16 00:38:59 +08007015 @HotPath(caller = HotPath.OOM_ADJUSTMENT)
Wale Ogunwale31913b52018-10-13 08:29:31 -07007016 @Override
7017 public void rankTaskLayersIfNeeded() {
Riddle Hsud7088f82019-01-30 13:04:50 +08007018 synchronized (mGlobalLockWithoutBoost) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08007019 if (mRootActivityContainer != null) {
7020 mRootActivityContainer.rankTaskLayersIfNeeded();
Wale Ogunwale31913b52018-10-13 08:29:31 -07007021 }
7022 }
7023 }
7024
7025 @Override
7026 public void scheduleDestroyAllActivities(String reason) {
7027 synchronized (mGlobalLock) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08007028 mRootActivityContainer.scheduleDestroyAllActivities(null, reason);
Wale Ogunwale31913b52018-10-13 08:29:31 -07007029 }
7030 }
7031
7032 @Override
7033 public void removeUser(int userId) {
7034 synchronized (mGlobalLock) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08007035 mRootActivityContainer.removeUser(userId);
Wale Ogunwale31913b52018-10-13 08:29:31 -07007036 }
7037 }
7038
7039 @Override
7040 public boolean switchUser(int userId, UserState userState) {
7041 synchronized (mGlobalLock) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08007042 return mRootActivityContainer.switchUser(userId, userState);
Wale Ogunwale31913b52018-10-13 08:29:31 -07007043 }
7044 }
7045
7046 @Override
7047 public void onHandleAppCrash(WindowProcessController wpc) {
7048 synchronized (mGlobalLock) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08007049 mRootActivityContainer.handleAppCrash(wpc);
Wale Ogunwale31913b52018-10-13 08:29:31 -07007050 }
7051 }
Wale Ogunwale64258362018-10-16 15:13:37 -07007052
7053 @Override
7054 public int finishTopCrashedActivities(WindowProcessController crashedApp, String reason) {
7055 synchronized (mGlobalLock) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08007056 return mRootActivityContainer.finishTopCrashedActivities(crashedApp, reason);
Wale Ogunwale64258362018-10-16 15:13:37 -07007057 }
7058 }
Wale Ogunwalebff2df42018-10-18 17:09:19 -07007059
Riddle Hsua0536432019-02-16 00:38:59 +08007060 @HotPath(caller = HotPath.OOM_ADJUSTMENT)
Wale Ogunwalebff2df42018-10-18 17:09:19 -07007061 @Override
7062 public void onUidActive(int uid, int procState) {
Riddle Hsua0536432019-02-16 00:38:59 +08007063 mActiveUids.onUidActive(uid, procState);
Wale Ogunwalebff2df42018-10-18 17:09:19 -07007064 }
7065
Riddle Hsua0536432019-02-16 00:38:59 +08007066 @HotPath(caller = HotPath.OOM_ADJUSTMENT)
Wale Ogunwalebff2df42018-10-18 17:09:19 -07007067 @Override
7068 public void onUidInactive(int uid) {
Riddle Hsua0536432019-02-16 00:38:59 +08007069 mActiveUids.onUidInactive(uid);
Wale Ogunwalebff2df42018-10-18 17:09:19 -07007070 }
7071
Riddle Hsua0536432019-02-16 00:38:59 +08007072 @HotPath(caller = HotPath.OOM_ADJUSTMENT)
Wale Ogunwalebff2df42018-10-18 17:09:19 -07007073 @Override
7074 public void onActiveUidsCleared() {
Riddle Hsua0536432019-02-16 00:38:59 +08007075 mActiveUids.onActiveUidsCleared();
Wale Ogunwalebff2df42018-10-18 17:09:19 -07007076 }
7077
Riddle Hsua0536432019-02-16 00:38:59 +08007078 @HotPath(caller = HotPath.OOM_ADJUSTMENT)
Wale Ogunwalebff2df42018-10-18 17:09:19 -07007079 @Override
7080 public void onUidProcStateChanged(int uid, int procState) {
Riddle Hsua0536432019-02-16 00:38:59 +08007081 mActiveUids.onUidProcStateChanged(uid, procState);
Wale Ogunwalebff2df42018-10-18 17:09:19 -07007082 }
Wale Ogunwale9de19442018-10-18 19:05:03 -07007083
7084 @Override
7085 public void onUidAddedToPendingTempWhitelist(int uid, String tag) {
Riddle Hsud7088f82019-01-30 13:04:50 +08007086 synchronized (mGlobalLockWithoutBoost) {
Wale Ogunwale9de19442018-10-18 19:05:03 -07007087 mPendingTempWhitelist.put(uid, tag);
7088 }
7089 }
7090
7091 @Override
7092 public void onUidRemovedFromPendingTempWhitelist(int uid) {
Riddle Hsud7088f82019-01-30 13:04:50 +08007093 synchronized (mGlobalLockWithoutBoost) {
Wale Ogunwale9de19442018-10-18 19:05:03 -07007094 mPendingTempWhitelist.remove(uid);
7095 }
7096 }
Wale Ogunwalee2172292018-10-25 10:11:10 -07007097
7098 @Override
7099 public boolean handleAppCrashInActivityController(String processName, int pid,
7100 String shortMsg, String longMsg, long timeMillis, String stackTrace,
7101 Runnable killCrashingAppCallback) {
7102 synchronized (mGlobalLock) {
7103 if (mController == null) {
7104 return false;
7105 }
7106
7107 try {
7108 if (!mController.appCrashed(processName, pid, shortMsg, longMsg, timeMillis,
7109 stackTrace)) {
7110 killCrashingAppCallback.run();
7111 return true;
7112 }
7113 } catch (RemoteException e) {
7114 mController = null;
7115 Watchdog.getInstance().setActivityController(null);
7116 }
7117 return false;
7118 }
7119 }
Wale Ogunwaled7889f52018-10-25 11:03:20 -07007120
7121 @Override
7122 public void removeRecentTasksByPackageName(String packageName, int userId) {
7123 synchronized (mGlobalLock) {
7124 mRecentTasks.removeTasksByPackageName(packageName, userId);
7125 }
7126 }
7127
7128 @Override
7129 public void cleanupRecentTasksForUser(int userId) {
7130 synchronized (mGlobalLock) {
7131 mRecentTasks.cleanupLocked(userId);
7132 }
7133 }
7134
7135 @Override
7136 public void loadRecentTasksForUser(int userId) {
7137 synchronized (mGlobalLock) {
7138 mRecentTasks.loadUserRecentsLocked(userId);
7139 }
7140 }
7141
7142 @Override
7143 public void onPackagesSuspendedChanged(String[] packages, boolean suspended, int userId) {
7144 synchronized (mGlobalLock) {
7145 mRecentTasks.onPackagesSuspendedChanged(packages, suspended, userId);
7146 }
7147 }
7148
7149 @Override
7150 public void flushRecentTasks() {
7151 mRecentTasks.flush();
7152 }
Wale Ogunwaled4d67d02018-10-25 18:09:39 -07007153
7154 @Override
7155 public WindowProcessController getHomeProcess() {
7156 synchronized (mGlobalLock) {
7157 return mHomeProcess;
7158 }
7159 }
7160
7161 @Override
7162 public WindowProcessController getPreviousProcess() {
7163 synchronized (mGlobalLock) {
7164 return mPreviousProcess;
7165 }
7166 }
Wale Ogunwale27c48ae2018-10-25 19:01:01 -07007167
7168 @Override
7169 public void clearLockedTasks(String reason) {
7170 synchronized (mGlobalLock) {
7171 getLockTaskController().clearLockedTasks(reason);
7172 }
7173 }
7174
7175 @Override
7176 public void updateUserConfiguration() {
7177 synchronized (mGlobalLock) {
7178 final Configuration configuration = new Configuration(getGlobalConfiguration());
7179 final int currentUserId = mAmInternal.getCurrentUserId();
7180 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(),
7181 configuration, currentUserId, Settings.System.canWrite(mContext));
7182 updateConfigurationLocked(configuration, null /* starting */,
7183 false /* initLocale */, false /* persistent */, currentUserId,
7184 false /* deferResume */);
7185 }
7186 }
Wale Ogunwale387b34c2018-10-25 19:59:40 -07007187
7188 @Override
7189 public boolean canShowErrorDialogs() {
7190 synchronized (mGlobalLock) {
7191 return mShowDialogs && !mSleeping && !mShuttingDown
7192 && !mKeyguardController.isKeyguardOrAodShowing(DEFAULT_DISPLAY)
7193 && !hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
7194 mAmInternal.getCurrentUserId())
7195 && !(UserManager.isDeviceInDemoMode(mContext)
7196 && mAmInternal.getCurrentUser().isDemo());
7197 }
7198 }
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -08007199
7200 @Override
7201 public void setProfileApp(String profileApp) {
7202 synchronized (mGlobalLock) {
7203 mProfileApp = profileApp;
7204 }
7205 }
7206
7207 @Override
7208 public void setProfileProc(WindowProcessController wpc) {
7209 synchronized (mGlobalLock) {
7210 mProfileProc = wpc;
7211 }
7212 }
7213
7214 @Override
7215 public void setProfilerInfo(ProfilerInfo profilerInfo) {
7216 synchronized (mGlobalLock) {
7217 mProfilerInfo = profilerInfo;
7218 }
7219 }
Igor Murashkinc0b47e42018-11-07 15:54:18 -08007220
7221 @Override
7222 public ActivityMetricsLaunchObserverRegistry getLaunchObserverRegistry() {
7223 synchronized (mGlobalLock) {
7224 return mStackSupervisor.getActivityMetricsLogger().getLaunchObserverRegistry();
7225 }
7226 }
Winson Chung3fb0f252019-01-08 17:41:55 -08007227
7228 @Override
7229 public ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
7230 synchronized (mGlobalLock) {
7231 return ActivityTaskManagerService.this.getTaskSnapshot(taskId, reducedResolution);
7232 }
7233 }
Michal Karpinskicc88d7e2019-01-24 15:32:12 +00007234
7235 @Override
7236 public boolean isUidForeground(int uid) {
7237 synchronized (mGlobalLock) {
7238 return ActivityTaskManagerService.this.isUidForeground(uid);
7239 }
7240 }
Michal Karpinski4026cae2019-02-12 11:51:47 +00007241
7242 @Override
7243 public void setDeviceOwnerPackageName(String deviceOwnerPkg) {
7244 synchronized (mGlobalLock) {
7245 ActivityTaskManagerService.this.setDeviceOwnerPackageName(deviceOwnerPkg);
7246 }
7247 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07007248 }
Wale Ogunwaleb73f3962018-11-20 07:58:22 -08007249}