blob: 2d2701785d03d297720b47843b3a4b07b03c9ce6 [file] [log] [blame]
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.server.am;
18
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070019import static android.Manifest.permission.BIND_VOICE_INTERACTION;
20import static android.Manifest.permission.CHANGE_CONFIGURATION;
21import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
Wale Ogunwale906f9c62018-07-23 11:23:44 -070022import static android.Manifest.permission.FILTER_EVENTS;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070023import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070024import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070025import static android.Manifest.permission.READ_FRAME_BUFFER;
26import static android.Manifest.permission.REMOVE_TASKS;
27import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070028import static android.Manifest.permission.STOP_APP_SWITCHES;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070029import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
Evan Rosky4505b352018-09-06 11:20:40 -070030import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
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;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070033import static android.app.AppOpsManager.OP_NONE;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070034import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070035import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
36import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070037import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
38import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070039import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070040import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Wale Ogunwale31913b52018-10-13 08:29:31 -070041import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070042import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
Wale Ogunwale31913b52018-10-13 08:29:31 -070043import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
Wale Ogunwale214f3482018-10-04 11:00:47 -070044import static android.content.pm.ApplicationInfo.FLAG_FACTORY_TEST;
Wale Ogunwale342fbe92018-10-09 08:44:10 -070045import static android.content.pm.ConfigurationInfo.GL_ES_VERSION_UNDEFINED;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070046import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
47import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
Evan Rosky4505b352018-09-06 11:20:40 -070048import static android.content.pm.PackageManager.FEATURE_PC;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070049import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070050import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070051import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
52import static android.os.Build.VERSION_CODES.N;
Wale Ogunwale214f3482018-10-04 11:00:47 -070053import static android.os.FactoryTest.FACTORY_TEST_HIGH_LEVEL;
54import static android.os.FactoryTest.FACTORY_TEST_LOW_LEVEL;
55import static android.os.FactoryTest.FACTORY_TEST_OFF;
Wale Ogunwale31913b52018-10-13 08:29:31 -070056import static android.os.Process.FIRST_APPLICATION_UID;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070057import static android.os.Process.SYSTEM_UID;
Evan Rosky4505b352018-09-06 11:20:40 -070058import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070059import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
60import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
61import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
62import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
Evan Rosky4505b352018-09-06 11:20:40 -070063import static android.provider.Settings.Global.HIDE_ERROR_DIALOGS;
64import static android.provider.Settings.System.FONT_SCALE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070065import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
66import static android.view.Display.DEFAULT_DISPLAY;
67import static android.view.Display.INVALID_DISPLAY;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070068import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
Wale Ogunwale6767eae2018-05-03 15:52:51 -070069import static android.view.WindowManager.TRANSIT_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070070import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070071import static android.view.WindowManager.TRANSIT_TASK_OPEN;
72import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
Evan Rosky4505b352018-09-06 11:20:40 -070073
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;
84import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC_VISIBLE_TIME_MS;
85import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.SCREEN_COMPAT_PACKAGES;
86import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.MODE;
87import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.PACKAGE;
Wale Ogunwale98875612018-10-12 07:53:02 -070088import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_ALL;
Wale Ogunwale31913b52018-10-13 08:29:31 -070089import static com.android.server.am.ActivityManagerService.ANR_TRACE_DIR;
Wale Ogunwale98875612018-10-12 07:53:02 -070090import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
91import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_FOCUS;
92import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_IMMERSIVE;
93import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_LOCKTASK;
94import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_STACK;
95import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
96import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
97import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_VISIBILITY;
98import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
99import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS;
100import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_IMMERSIVE;
101import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_LOCKTASK;
102import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_STACK;
103import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH;
104import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_VISIBILITY;
105import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_ATM;
106import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700107import static com.android.server.am.ActivityManagerService.MY_PID;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700108import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS;
Evan Rosky4505b352018-09-06 11:20:40 -0700109import static com.android.server.am.ActivityManagerService.dumpStackTraces;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700110import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700111import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700112import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
113import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
114import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
115import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
116import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
Evan Rosky4505b352018-09-06 11:20:40 -0700117import static com.android.server.am.ActivityTaskManagerService.H.REPORT_TIME_TRACKER_MSG;
118import static com.android.server.am.ActivityTaskManagerService.UiHandler.DISMISS_DIALOG_UI_MSG;
Wale Ogunwale98875612018-10-12 07:53:02 -0700119import static android.app.ActivityTaskManager.INVALID_TASK_ID;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700120import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700121import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700122import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
Evan Rosky4505b352018-09-06 11:20:40 -0700123import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT;
124import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_DATA;
125import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
126import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700127import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
128import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700129
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700130import android.Manifest;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700131import android.annotation.NonNull;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700132import android.annotation.Nullable;
133import android.annotation.UserIdInt;
134import android.app.Activity;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700135import android.app.ActivityManager;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700136import android.app.ActivityManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700137import android.app.ActivityOptions;
138import android.app.ActivityTaskManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700139import android.app.ActivityThread;
140import android.app.AlertDialog;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700141import android.app.AppGlobals;
Evan Rosky4505b352018-09-06 11:20:40 -0700142import android.app.Dialog;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700143import android.app.IActivityController;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700144import android.app.IActivityTaskManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700145import android.app.IApplicationThread;
146import android.app.IAssistDataReceiver;
Wale Ogunwale53783742018-09-16 10:21:51 -0700147import android.app.INotificationManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700148import android.app.ITaskStackListener;
Wale Ogunwale53783742018-09-16 10:21:51 -0700149import android.app.Notification;
150import android.app.NotificationManager;
151import android.app.PendingIntent;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700152import android.app.PictureInPictureParams;
153import android.app.ProfilerInfo;
154import android.app.RemoteAction;
155import android.app.WaitResult;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700156import android.app.WindowConfiguration;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700157import android.app.admin.DevicePolicyCache;
158import android.app.assist.AssistContent;
159import android.app.assist.AssistStructure;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700160import android.app.usage.UsageStatsManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700161import android.content.ActivityNotFoundException;
162import android.content.ComponentName;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700163import android.content.ContentResolver;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700164import android.content.Context;
Evan Rosky4505b352018-09-06 11:20:40 -0700165import android.content.DialogInterface;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700166import android.content.IIntentSender;
167import android.content.Intent;
168import android.content.pm.ActivityInfo;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700169import android.content.pm.ApplicationInfo;
Yunfan Chen75157d72018-07-27 14:47:21 +0900170import android.content.pm.ConfigurationInfo;
Evan Rosky4505b352018-09-06 11:20:40 -0700171import android.content.pm.IPackageManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700172import android.content.pm.PackageManager;
Evan Rosky4505b352018-09-06 11:20:40 -0700173import android.content.pm.PackageManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700174import android.content.pm.ParceledListSlice;
175import android.content.pm.ResolveInfo;
Wale Ogunwale53783742018-09-16 10:21:51 -0700176import android.content.res.CompatibilityInfo;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700177import android.content.res.Configuration;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700178import android.content.res.Resources;
Evan Rosky4505b352018-09-06 11:20:40 -0700179import android.database.ContentObserver;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700180import android.graphics.Bitmap;
181import android.graphics.Point;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700182import android.graphics.Rect;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700183import android.metrics.LogMaker;
184import android.net.Uri;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700185import android.os.Binder;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700186import android.os.Build;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700187import android.os.Bundle;
Wale Ogunwale214f3482018-10-04 11:00:47 -0700188import android.os.FactoryTest;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700189import android.os.FileUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700190import android.os.Handler;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700191import android.os.IBinder;
Evan Rosky4505b352018-09-06 11:20:40 -0700192import android.os.IUserManager;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700193import android.os.LocaleList;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700194import android.os.Looper;
195import android.os.Message;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700196import android.os.PersistableBundle;
Evan Rosky4505b352018-09-06 11:20:40 -0700197import android.os.PowerManager;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700198import android.os.PowerManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700199import android.os.RemoteException;
Evan Rosky4505b352018-09-06 11:20:40 -0700200import android.os.ServiceManager;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700201import android.os.StrictMode;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700202import android.os.SystemClock;
203import android.os.SystemProperties;
Evan Rosky4505b352018-09-06 11:20:40 -0700204import android.os.Trace;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700205import android.os.UpdateLock;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700206import android.os.UserHandle;
Evan Rosky4505b352018-09-06 11:20:40 -0700207import android.os.UserManager;
208import android.os.WorkSource;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700209import android.os.storage.IStorageManager;
210import android.os.storage.StorageManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700211import android.provider.Settings;
212import android.service.voice.IVoiceInteractionSession;
213import android.service.voice.VoiceInteractionManagerInternal;
214import android.telecom.TelecomManager;
215import android.text.TextUtils;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700216import android.text.format.Time;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700217import android.util.ArrayMap;
218import android.util.EventLog;
219import android.util.Log;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700220import android.util.Slog;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700221import android.util.SparseArray;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700222import android.util.SparseIntArray;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700223import android.util.StatsLog;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700224import android.util.TimeUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700225import android.util.proto.ProtoOutputStream;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700226import android.view.IRecentsAnimationRunner;
227import android.view.RemoteAnimationAdapter;
228import android.view.RemoteAnimationDefinition;
Evan Rosky4505b352018-09-06 11:20:40 -0700229import android.view.WindowManager;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700230
Evan Rosky4505b352018-09-06 11:20:40 -0700231import com.android.internal.R;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700232import com.android.internal.annotations.VisibleForTesting;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700233import com.android.internal.app.AssistUtils;
Evan Rosky4505b352018-09-06 11:20:40 -0700234import com.android.internal.app.IAppOpsService;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700235import com.android.internal.app.IVoiceInteractor;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700236import com.android.internal.app.ProcessMap;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700237import com.android.internal.logging.MetricsLogger;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700238import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Wale Ogunwale53783742018-09-16 10:21:51 -0700239import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
240import com.android.internal.notification.SystemNotificationChannels;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700241import com.android.internal.os.TransferPipe;
Evan Rosky4505b352018-09-06 11:20:40 -0700242import com.android.internal.os.logging.MetricsLoggerWrapper;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700243import com.android.internal.policy.IKeyguardDismissCallback;
244import com.android.internal.policy.KeyguardDismissCallback;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700245import com.android.internal.util.ArrayUtils;
246import com.android.internal.util.FastPrintWriter;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700247import com.android.internal.util.Preconditions;
Wale Ogunwale53783742018-09-16 10:21:51 -0700248import com.android.internal.util.function.pooled.PooledLambda;
Evan Rosky4505b352018-09-06 11:20:40 -0700249import com.android.server.AppOpsService;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700250import com.android.server.AttributeCache;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700251import com.android.server.LocalServices;
252import com.android.server.SystemService;
Evan Rosky4505b352018-09-06 11:20:40 -0700253import com.android.server.SystemServiceManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700254import com.android.server.Watchdog;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700255import com.android.server.firewall.IntentFirewall;
Evan Rosky4505b352018-09-06 11:20:40 -0700256import com.android.server.pm.UserManagerService;
257import com.android.server.uri.UriGrantsManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700258import com.android.server.vr.VrManagerInternal;
Evan Rosky4505b352018-09-06 11:20:40 -0700259import com.android.server.wm.ActivityTaskManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700260import com.android.server.wm.PinnedStackWindowController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700261import com.android.server.wm.WindowManagerService;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700262
Wale Ogunwale31913b52018-10-13 08:29:31 -0700263import java.io.BufferedReader;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700264import java.io.File;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700265import java.io.FileDescriptor;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700266import java.io.FileOutputStream;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700267import java.io.FileReader;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700268import java.io.IOException;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700269import java.io.PrintWriter;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700270import java.io.StringWriter;
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700271import java.lang.ref.WeakReference;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700272import java.text.DateFormat;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700273import java.util.ArrayList;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700274import java.util.Date;
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700275import java.util.HashSet;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700276import java.util.List;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700277import java.util.Locale;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700278import java.util.Map;
279import java.util.Set;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700280
281/**
282 * System service for managing activities and their containers (task, stacks, displays,... ).
283 *
284 * {@hide}
285 */
286public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
Wale Ogunwale98875612018-10-12 07:53:02 -0700287 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityTaskManagerService" : TAG_ATM;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700288 private static final String TAG_STACK = TAG + POSTFIX_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700289 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
290 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
291 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
292 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
293 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700294 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700295
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700296 // How long we wait until we timeout on key dispatching.
Wale Ogunwale51cc98a2018-10-15 10:41:05 -0700297 public static final int KEY_DISPATCHING_TIMEOUT_MS = 5 * 1000;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700298 // How long we wait until we timeout on key dispatching during instrumentation.
Wale Ogunwale51cc98a2018-10-15 10:41:05 -0700299 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS = 60 * 1000;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700300
Wale Ogunwale98875612018-10-12 07:53:02 -0700301 /** Used to indicate that an app transition should be animated. */
302 static final boolean ANIMATE = true;
303
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700304 /** Hardware-reported OpenGLES version. */
305 final int GL_ES_VERSION;
306
Wale Ogunwale31913b52018-10-13 08:29:31 -0700307 public static final String DUMP_ACTIVITIES_CMD = "activities" ;
308 public static final String DUMP_ACTIVITIES_SHORT_CMD = "a" ;
309 public static final String DUMP_LASTANR_CMD = "lastanr" ;
310 public static final String DUMP_LASTANR_TRACES_CMD = "lastanr-traces" ;
311 public static final String DUMP_STARTER_CMD = "starter" ;
312 public static final String DUMP_CONTAINERS_CMD = "containers" ;
313 public static final String DUMP_RECENTS_CMD = "recents" ;
314 public static final String DUMP_RECENTS_SHORT_CMD = "r" ;
315
Wale Ogunwale64258362018-10-16 15:13:37 -0700316 /** This activity is not being relaunched, or being relaunched for a non-resize reason. */
317 public static final int RELAUNCH_REASON_NONE = 0;
318 /** This activity is being relaunched due to windowing mode change. */
319 public static final int RELAUNCH_REASON_WINDOWING_MODE_RESIZE = 1;
320 /** This activity is being relaunched due to a free-resize operation. */
321 public static final int RELAUNCH_REASON_FREE_RESIZE = 2;
322
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700323 Context mContext;
Wale Ogunwale64258362018-10-16 15:13:37 -0700324
Wale Ogunwalef6733932018-06-27 05:14:34 -0700325 /**
326 * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
327 * change at runtime. Use mContext for non-UI purposes.
328 */
329 final Context mUiContext;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700330 final ActivityThread mSystemThread;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700331 H mH;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700332 UiHandler mUiHandler;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700333 ActivityManagerService mAm;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700334 ActivityManagerInternal mAmInternal;
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700335 UriGrantsManagerInternal mUgmInternal;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700336 private PackageManagerInternal mPmInternal;
Wale Ogunwale53783742018-09-16 10:21:51 -0700337 private ActivityTaskManagerInternal mInternal;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700338 PowerManagerInternal mPowerManagerInternal;
339 private UsageStatsManagerInternal mUsageStatsInternal;
340
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700341 PendingIntentController mPendingIntentController;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700342 IntentFirewall mIntentFirewall;
343
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700344 /* Global service lock used by the package the owns this service. */
345 Object mGlobalLock;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700346 ActivityStackSupervisor mStackSupervisor;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700347 WindowManagerService mWindowManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700348 private UserManagerService mUserManager;
349 private AppOpsService mAppOpsService;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700350 /** All processes currently running that might have a window organized by name. */
351 final ProcessMap<WindowProcessController> mProcessNames = new ProcessMap<>();
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700352 /** All processes we currently have running mapped by pid */
353 final SparseArray<WindowProcessController> mPidMap = new SparseArray<>();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700354 /** This is the process holding what we currently consider to be the "home" activity. */
355 WindowProcessController mHomeProcess;
Wale Ogunwale53783742018-09-16 10:21:51 -0700356 /** The currently running heavy-weight process, if any. */
357 WindowProcessController mHeavyWeightProcess = null;
Wale Ogunwale214f3482018-10-04 11:00:47 -0700358 boolean mHasHeavyWeightFeature;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700359 /**
360 * This is the process holding the activity the user last visited that is in a different process
361 * from the one they are currently in.
362 */
363 WindowProcessController mPreviousProcess;
364 /** The time at which the previous process was last visible. */
365 long mPreviousProcessVisibleTime;
366
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700367 /** List of intents that were used to start the most recent tasks. */
368 private RecentTasks mRecentTasks;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700369 /** State of external calls telling us if the device is awake or asleep. */
370 private boolean mKeyguardShown = false;
371
372 // Wrapper around VoiceInteractionServiceManager
373 private AssistUtils mAssistUtils;
374
375 // VoiceInteraction session ID that changes for each new request except when
376 // being called for multi-window assist in a single session.
377 private int mViSessionId = 1000;
378
379 // How long to wait in getAssistContextExtras for the activity and foreground services
380 // to respond with the result.
381 private static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
382
383 // How long top wait when going through the modern assist (which doesn't need to block
384 // on getting this result before starting to launch its UI).
385 private static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
386
387 // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
388 private static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
389
390 private final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
391
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700392 // Keeps track of the active voice interaction service component, notified from
393 // VoiceInteractionManagerService
394 ComponentName mActiveVoiceInteractionServiceComponent;
395
396 private VrController mVrController;
397 KeyguardController mKeyguardController;
398 private final ClientLifecycleManager mLifecycleManager;
399 private TaskChangeNotificationController mTaskChangeNotificationController;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700400 /** The controller for all operations related to locktask. */
401 private LockTaskController mLockTaskController;
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700402 private ActivityStartController mActivityStartController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700403
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700404 boolean mSuppressResizeConfigChanges;
405
406 private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
407 new UpdateConfigurationResult();
408
409 static final class UpdateConfigurationResult {
410 // Configuration changes that were updated.
411 int changes;
412 // If the activity was relaunched to match the new configuration.
413 boolean activityRelaunched;
414
415 void reset() {
416 changes = 0;
417 activityRelaunched = false;
418 }
419 }
420
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700421 /** Current sequencing integer of the configuration, for skipping old configurations. */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700422 private int mConfigurationSeq;
423 // To cache the list of supported system locales
424 private String[] mSupportedSystemLocales = null;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700425
426 /**
427 * Temp object used when global and/or display override configuration is updated. It is also
428 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
429 * anyone...
430 */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700431 private Configuration mTempConfig = new Configuration();
432
Wale Ogunwalef6733932018-06-27 05:14:34 -0700433 /** Temporary to avoid allocations. */
434 final StringBuilder mStringBuilder = new StringBuilder(256);
435
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700436 // Amount of time after a call to stopAppSwitches() during which we will
437 // prevent further untrusted switches from happening.
438 private static final long APP_SWITCH_DELAY_TIME = 5 * 1000;
439
440 /**
441 * The time at which we will allow normal application switches again,
442 * after a call to {@link #stopAppSwitches()}.
443 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700444 private long mAppSwitchesAllowedTime;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700445 /**
446 * This is set to true after the first switch after mAppSwitchesAllowedTime
447 * is set; any switches after that will clear the time.
448 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700449 private boolean mDidAppSwitch;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700450
451 IActivityController mController = null;
452 boolean mControllerIsAMonkey = false;
453
Wale Ogunwale214f3482018-10-04 11:00:47 -0700454 final int mFactoryTest;
455
456 /** Used to control how we initialize the service. */
457 ComponentName mTopComponent;
458 String mTopAction = Intent.ACTION_MAIN;
459 String mTopData;
460
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700461 /**
Wale Ogunwale31913b52018-10-13 08:29:31 -0700462 * Dump of the activity state at the time of the last ANR. Cleared after
463 * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
464 */
465 String mLastANRState;
466
467 /**
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700468 * Used to retain an update lock when the foreground activity is in
469 * immersive mode.
470 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700471 private final UpdateLock mUpdateLock = new UpdateLock("immersive");
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700472
473 /**
474 * Packages that are being allowed to perform unrestricted app switches. Mapping is
475 * User -> Type -> uid.
476 */
477 final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
478
479 /** The dimensions of the thumbnails in the Recents UI. */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700480 private int mThumbnailWidth;
481 private int mThumbnailHeight;
482 private float mFullscreenThumbnailScale;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700483
484 /**
485 * Flag that indicates if multi-window is enabled.
486 *
487 * For any particular form of multi-window to be enabled, generic multi-window must be enabled
488 * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
489 * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
490 * At least one of the forms of multi-window must be enabled in order for this flag to be
491 * initialized to 'true'.
492 *
493 * @see #mSupportsSplitScreenMultiWindow
494 * @see #mSupportsFreeformWindowManagement
495 * @see #mSupportsPictureInPicture
496 * @see #mSupportsMultiDisplay
497 */
498 boolean mSupportsMultiWindow;
499 boolean mSupportsSplitScreenMultiWindow;
500 boolean mSupportsFreeformWindowManagement;
501 boolean mSupportsPictureInPicture;
502 boolean mSupportsMultiDisplay;
503 boolean mForceResizableActivities;
504
505 final List<ActivityTaskManagerInternal.ScreenObserver> mScreenObservers = new ArrayList<>();
506
507 // VR Vr2d Display Id.
508 int mVr2dDisplayId = INVALID_DISPLAY;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700509
Wale Ogunwalef6733932018-06-27 05:14:34 -0700510 /**
511 * Set while we are wanting to sleep, to prevent any
512 * activities from being started/resumed.
513 *
514 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
515 *
516 * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
517 * while in the sleep state until there is a pending transition out of sleep, in which case
518 * mSleeping is set to false, and remains false while awake.
519 *
520 * Whether mSleeping can quickly toggled between true/false without the device actually
521 * display changing states is undefined.
522 */
523 private boolean mSleeping = false;
524
525 /**
526 * The process state used for processes that are running the top activities.
527 * This changes between TOP and TOP_SLEEPING to following mSleeping.
528 */
529 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
530
531 // Whether we should show our dialogs (ANR, crash, etc) or just perform their default action
532 // automatically. Important for devices without direct input devices.
533 private boolean mShowDialogs = true;
534
535 /** Set if we are shutting down the system, similar to sleeping. */
536 boolean mShuttingDown = false;
537
538 /**
539 * We want to hold a wake lock while running a voice interaction session, since
540 * this may happen with the screen off and we need to keep the CPU running to
541 * be able to continue to interact with the user.
542 */
543 PowerManager.WakeLock mVoiceWakeLock;
544
545 /**
546 * Set while we are running a voice interaction. This overrides sleeping while it is active.
547 */
548 IVoiceInteractionSession mRunningVoice;
549
550 /**
551 * The last resumed activity. This is identical to the current resumed activity most
552 * of the time but could be different when we're pausing one activity before we resume
553 * another activity.
554 */
555 ActivityRecord mLastResumedActivity;
556
557 /**
558 * The activity that is currently being traced as the active resumed activity.
559 *
560 * @see #updateResumedAppTrace
561 */
562 private @Nullable ActivityRecord mTracedResumedActivity;
563
564 /** If non-null, we are tracking the time the user spends in the currently focused app. */
565 AppTimeTracker mCurAppTimeTracker;
566
Wale Ogunwale008163e2018-07-23 23:11:08 -0700567 private AppWarnings mAppWarnings;
568
Wale Ogunwale53783742018-09-16 10:21:51 -0700569 /**
570 * Packages that the user has asked to have run in screen size
571 * compatibility mode instead of filling the screen.
572 */
573 CompatModePackages mCompatModePackages;
574
Wale Ogunwalef6733932018-06-27 05:14:34 -0700575 private FontScaleSettingObserver mFontScaleSettingObserver;
576
577 private final class FontScaleSettingObserver extends ContentObserver {
578 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
579 private final Uri mHideErrorDialogsUri = Settings.Global.getUriFor(HIDE_ERROR_DIALOGS);
580
581 public FontScaleSettingObserver() {
582 super(mH);
583 final ContentResolver resolver = mContext.getContentResolver();
584 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
585 resolver.registerContentObserver(mHideErrorDialogsUri, false, this,
586 UserHandle.USER_ALL);
587 }
588
589 @Override
590 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
591 if (mFontScaleUri.equals(uri)) {
592 updateFontScaleIfNeeded(userId);
593 } else if (mHideErrorDialogsUri.equals(uri)) {
594 synchronized (mGlobalLock) {
595 updateShouldShowDialogsLocked(getGlobalConfiguration());
596 }
597 }
598 }
599 }
600
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700601 ActivityTaskManagerService(Context context) {
602 mContext = context;
Wale Ogunwale214f3482018-10-04 11:00:47 -0700603 mFactoryTest = FactoryTest.getMode();
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700604 mSystemThread = ActivityThread.currentActivityThread();
605 mUiContext = mSystemThread.getSystemUiContext();
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700606 mLifecycleManager = new ClientLifecycleManager();
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700607 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", GL_ES_VERSION_UNDEFINED);
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700608 }
609
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700610 void onSystemReady() {
Wale Ogunwale214f3482018-10-04 11:00:47 -0700611 mHasHeavyWeightFeature = mContext.getPackageManager().hasSystemFeature(
612 PackageManager.FEATURE_CANT_SAVE_STATE);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700613 mAssistUtils = new AssistUtils(mContext);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700614 mVrController.onSystemReady();
615 mRecentTasks.onSystemReadyLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700616 }
617
Wale Ogunwalef6733932018-06-27 05:14:34 -0700618 void onInitPowerManagement() {
619 mStackSupervisor.initPowerManagement();
620 final PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700621 mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
Wale Ogunwalef6733932018-06-27 05:14:34 -0700622 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
623 mVoiceWakeLock.setReferenceCounted(false);
624 }
625
626 void installSystemProviders() {
627 mFontScaleSettingObserver = new FontScaleSettingObserver();
628 }
629
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700630 void retrieveSettings(ContentResolver resolver) {
631 final boolean freeformWindowManagement =
632 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
633 || Settings.Global.getInt(
634 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
635
636 final boolean supportsMultiWindow = ActivityTaskManager.supportsMultiWindow(mContext);
637 final boolean supportsPictureInPicture = supportsMultiWindow &&
638 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
639 final boolean supportsSplitScreenMultiWindow =
640 ActivityTaskManager.supportsSplitScreenMultiWindow(mContext);
641 final boolean supportsMultiDisplay = mContext.getPackageManager()
642 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
643 final boolean alwaysFinishActivities =
644 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
645 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
646 final boolean forceResizable = Settings.Global.getInt(
647 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
Garfield Tane0846042018-07-26 13:42:04 -0700648 final boolean isPc = mContext.getPackageManager().hasSystemFeature(FEATURE_PC);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700649
650 // Transfer any global setting for forcing RTL layout, into a System Property
651 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
652
653 final Configuration configuration = new Configuration();
654 Settings.System.getConfiguration(resolver, configuration);
655 if (forceRtl) {
656 // This will take care of setting the correct layout direction flags
657 configuration.setLayoutDirection(configuration.locale);
658 }
659
660 synchronized (mGlobalLock) {
661 mForceResizableActivities = forceResizable;
662 final boolean multiWindowFormEnabled = freeformWindowManagement
663 || supportsSplitScreenMultiWindow
664 || supportsPictureInPicture
665 || supportsMultiDisplay;
666 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
667 mSupportsMultiWindow = true;
668 mSupportsFreeformWindowManagement = freeformWindowManagement;
669 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
670 mSupportsPictureInPicture = supportsPictureInPicture;
671 mSupportsMultiDisplay = supportsMultiDisplay;
672 } else {
673 mSupportsMultiWindow = false;
674 mSupportsFreeformWindowManagement = false;
675 mSupportsSplitScreenMultiWindow = false;
676 mSupportsPictureInPicture = false;
677 mSupportsMultiDisplay = false;
678 }
679 mWindowManager.setForceResizableTasks(mForceResizableActivities);
680 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
Garfield Tane0846042018-07-26 13:42:04 -0700681 mWindowManager.setSupportsFreeformWindowManagement(mSupportsFreeformWindowManagement);
682 mWindowManager.setIsPc(isPc);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700683 // This happens before any activities are started, so we can change global configuration
684 // in-place.
685 updateConfigurationLocked(configuration, null, true);
686 final Configuration globalConfig = getGlobalConfiguration();
687 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
688
689 // Load resources only after the current configuration has been set.
690 final Resources res = mContext.getResources();
691 mThumbnailWidth = res.getDimensionPixelSize(
692 com.android.internal.R.dimen.thumbnail_width);
693 mThumbnailHeight = res.getDimensionPixelSize(
694 com.android.internal.R.dimen.thumbnail_height);
695
696 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
697 mFullscreenThumbnailScale = (float) res
698 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
699 (float) globalConfig.screenWidthDp;
700 } else {
701 mFullscreenThumbnailScale = res.getFraction(
702 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
703 }
704 }
705 }
706
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700707 // TODO: Will be converted to WM lock once transition is complete.
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700708 void setActivityManagerService(ActivityManagerService am, Looper looper,
709 IntentFirewall intentFirewall, PendingIntentController intentController) {
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700710 mAm = am;
711 mGlobalLock = mAm;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700712 mH = new H(looper);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700713 mUiHandler = new UiHandler();
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700714 mIntentFirewall = intentFirewall;
Wale Ogunwale53783742018-09-16 10:21:51 -0700715 final File systemDir = SystemServiceManager.ensureSystemDir();
716 mAppWarnings = new AppWarnings(this, mUiContext, mH, mUiHandler, systemDir);
717 mCompatModePackages = new CompatModePackages(this, systemDir, mH);
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700718 mPendingIntentController = intentController;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700719
720 mTempConfig.setToDefaults();
721 mTempConfig.setLocales(LocaleList.getDefault());
722 mConfigurationSeq = mTempConfig.seq = 1;
723 mStackSupervisor = createStackSupervisor();
724 mStackSupervisor.onConfigurationChanged(mTempConfig);
725
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700726 mTaskChangeNotificationController =
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700727 new TaskChangeNotificationController(mGlobalLock, mStackSupervisor, mH);
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700728 mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mH);
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700729 mActivityStartController = new ActivityStartController(this);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700730 mRecentTasks = createRecentTasks();
731 mStackSupervisor.setRecentTasks(mRecentTasks);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700732 mVrController = new VrController(mGlobalLock);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700733 mKeyguardController = mStackSupervisor.getKeyguardController();
734 }
735
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700736 void onActivityManagerInternalAdded() {
737 mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700738 mUgmInternal = LocalServices.getService(UriGrantsManagerInternal.class);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700739 }
740
Yunfan Chen75157d72018-07-27 14:47:21 +0900741 int increaseConfigurationSeqLocked() {
742 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
743 return mConfigurationSeq;
744 }
745
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700746 protected ActivityStackSupervisor createStackSupervisor() {
747 final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mH.getLooper());
748 supervisor.initialize();
749 return supervisor;
750 }
751
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700752 void setWindowManager(WindowManagerService wm) {
753 mWindowManager = wm;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700754 mLockTaskController.setWindowManager(wm);
Wale Ogunwale31913b52018-10-13 08:29:31 -0700755 mStackSupervisor.setWindowManager(wm);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700756 }
757
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700758 void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
759 mUsageStatsInternal = usageStatsManager;
760 }
761
Wale Ogunwalef6733932018-06-27 05:14:34 -0700762 UserManagerService getUserManager() {
763 if (mUserManager == null) {
764 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
765 mUserManager = (UserManagerService) IUserManager.Stub.asInterface(b);
766 }
767 return mUserManager;
768 }
769
770 AppOpsService getAppOpsService() {
771 if (mAppOpsService == null) {
772 IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
773 mAppOpsService = (AppOpsService) IAppOpsService.Stub.asInterface(b);
774 }
775 return mAppOpsService;
776 }
777
778 boolean hasUserRestriction(String restriction, int userId) {
779 return getUserManager().hasUserRestriction(restriction, userId);
780 }
781
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700782 protected RecentTasks createRecentTasks() {
783 return new RecentTasks(this, mStackSupervisor);
784 }
785
786 RecentTasks getRecentTasks() {
787 return mRecentTasks;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700788 }
789
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700790 ClientLifecycleManager getLifecycleManager() {
791 return mLifecycleManager;
792 }
793
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700794 ActivityStartController getActivityStartController() {
795 return mActivityStartController;
796 }
797
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700798 TaskChangeNotificationController getTaskChangeNotificationController() {
799 return mTaskChangeNotificationController;
800 }
801
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700802 LockTaskController getLockTaskController() {
803 return mLockTaskController;
804 }
805
Yunfan Chen75157d72018-07-27 14:47:21 +0900806 /**
807 * Return the global configuration used by the process corresponding to the input pid. This is
808 * usually the global configuration with some overrides specific to that process.
809 */
810 Configuration getGlobalConfigurationForCallingPid() {
811 final int pid = Binder.getCallingPid();
812 if (pid == MY_PID || pid < 0) {
813 return getGlobalConfiguration();
814 }
815 synchronized (mGlobalLock) {
816 final WindowProcessController app = mPidMap.get(pid);
817 return app != null ? app.getConfiguration() : getGlobalConfiguration();
818 }
819 }
820
821 /**
822 * Return the device configuration info used by the process corresponding to the input pid.
823 * The value is consistent with the global configuration for the process.
824 */
825 @Override
826 public ConfigurationInfo getDeviceConfigurationInfo() {
827 ConfigurationInfo config = new ConfigurationInfo();
828 synchronized (mGlobalLock) {
829 final Configuration globalConfig = getGlobalConfigurationForCallingPid();
830 config.reqTouchScreen = globalConfig.touchscreen;
831 config.reqKeyboardType = globalConfig.keyboard;
832 config.reqNavigation = globalConfig.navigation;
833 if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
834 || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
835 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
836 }
837 if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
838 && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
839 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
840 }
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700841 config.reqGlEsVersion = GL_ES_VERSION;
Yunfan Chen75157d72018-07-27 14:47:21 +0900842 }
843 return config;
844 }
845
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700846 private void start() {
Wale Ogunwale53783742018-09-16 10:21:51 -0700847 mInternal = new LocalService();
848 LocalServices.addService(ActivityTaskManagerInternal.class, mInternal);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700849 }
850
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700851 public static final class Lifecycle extends SystemService {
852 private final ActivityTaskManagerService mService;
853
854 public Lifecycle(Context context) {
855 super(context);
856 mService = new ActivityTaskManagerService(context);
857 }
858
859 @Override
860 public void onStart() {
861 publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700862 mService.start();
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700863 }
864
865 public ActivityTaskManagerService getService() {
866 return mService;
867 }
868 }
869
870 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700871 public final int startActivity(IApplicationThread caller, String callingPackage,
872 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
873 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
874 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
875 resultWho, requestCode, startFlags, profilerInfo, bOptions,
876 UserHandle.getCallingUserId());
877 }
878
879 @Override
880 public final int startActivities(IApplicationThread caller, String callingPackage,
881 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
882 int userId) {
883 final String reason = "startActivities";
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700884 enforceNotIsolatedCaller(reason);
885 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, reason);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700886 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700887 return getActivityStartController().startActivities(caller, -1, callingPackage, intents,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100888 resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId, reason,
889 null /* originatingPendingIntent */);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700890 }
891
892 @Override
893 public int startActivityAsUser(IApplicationThread caller, String callingPackage,
894 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
895 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
896 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
897 resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
898 true /*validateIncomingUser*/);
899 }
900
901 int startActivityAsUser(IApplicationThread caller, String callingPackage,
902 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
903 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
904 boolean validateIncomingUser) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700905 enforceNotIsolatedCaller("startActivityAsUser");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700906
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700907 userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700908 Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
909
910 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700911 return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700912 .setCaller(caller)
913 .setCallingPackage(callingPackage)
914 .setResolvedType(resolvedType)
915 .setResultTo(resultTo)
916 .setResultWho(resultWho)
917 .setRequestCode(requestCode)
918 .setStartFlags(startFlags)
919 .setProfilerInfo(profilerInfo)
920 .setActivityOptions(bOptions)
921 .setMayWait(userId)
922 .execute();
923
924 }
925
926 @Override
927 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
928 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700929 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions) {
930 enforceNotIsolatedCaller("startActivityIntentSender");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700931 // Refuse possible leaked file descriptors
932 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
933 throw new IllegalArgumentException("File descriptors passed in Intent");
934 }
935
936 if (!(target instanceof PendingIntentRecord)) {
937 throw new IllegalArgumentException("Bad PendingIntent object");
938 }
939
940 PendingIntentRecord pir = (PendingIntentRecord)target;
941
942 synchronized (mGlobalLock) {
943 // If this is coming from the currently resumed activity, it is
944 // effectively saying that app switches are allowed at this point.
Andrii Kulian5f750bc2018-07-17 08:57:23 -0700945 final ActivityStack stack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700946 if (stack.mResumedActivity != null &&
947 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700948 mAppSwitchesAllowedTime = 0;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700949 }
950 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700951 return pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700952 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700953 }
954
955 @Override
956 public boolean startNextMatchingActivity(IBinder callingActivity, Intent intent,
957 Bundle bOptions) {
958 // Refuse possible leaked file descriptors
959 if (intent != null && intent.hasFileDescriptors()) {
960 throw new IllegalArgumentException("File descriptors passed in Intent");
961 }
962 SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
963
964 synchronized (mGlobalLock) {
965 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
966 if (r == null) {
967 SafeActivityOptions.abort(options);
968 return false;
969 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700970 if (!r.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700971 // The caller is not running... d'oh!
972 SafeActivityOptions.abort(options);
973 return false;
974 }
975 intent = new Intent(intent);
976 // The caller is not allowed to change the data.
977 intent.setDataAndType(r.intent.getData(), r.intent.getType());
978 // And we are resetting to find the next component...
979 intent.setComponent(null);
980
981 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
982
983 ActivityInfo aInfo = null;
984 try {
985 List<ResolveInfo> resolves =
986 AppGlobals.getPackageManager().queryIntentActivities(
987 intent, r.resolvedType,
988 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
989 UserHandle.getCallingUserId()).getList();
990
991 // Look for the original activity in the list...
992 final int N = resolves != null ? resolves.size() : 0;
993 for (int i=0; i<N; i++) {
994 ResolveInfo rInfo = resolves.get(i);
995 if (rInfo.activityInfo.packageName.equals(r.packageName)
996 && rInfo.activityInfo.name.equals(r.info.name)) {
997 // We found the current one... the next matching is
998 // after it.
999 i++;
1000 if (i<N) {
1001 aInfo = resolves.get(i).activityInfo;
1002 }
1003 if (debug) {
1004 Slog.v(TAG, "Next matching activity: found current " + r.packageName
1005 + "/" + r.info.name);
1006 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
1007 ? "null" : aInfo.packageName + "/" + aInfo.name));
1008 }
1009 break;
1010 }
1011 }
1012 } catch (RemoteException e) {
1013 }
1014
1015 if (aInfo == null) {
1016 // Nobody who is next!
1017 SafeActivityOptions.abort(options);
1018 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
1019 return false;
1020 }
1021
1022 intent.setComponent(new ComponentName(
1023 aInfo.applicationInfo.packageName, aInfo.name));
1024 intent.setFlags(intent.getFlags()&~(
1025 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
1026 Intent.FLAG_ACTIVITY_CLEAR_TOP|
1027 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
1028 FLAG_ACTIVITY_NEW_TASK));
1029
1030 // Okay now we need to start the new activity, replacing the currently running activity.
1031 // This is a little tricky because we want to start the new one as if the current one is
1032 // finished, but not finish the current one first so that there is no flicker.
1033 // And thus...
1034 final boolean wasFinishing = r.finishing;
1035 r.finishing = true;
1036
1037 // Propagate reply information over to the new activity.
1038 final ActivityRecord resultTo = r.resultTo;
1039 final String resultWho = r.resultWho;
1040 final int requestCode = r.requestCode;
1041 r.resultTo = null;
1042 if (resultTo != null) {
1043 resultTo.removeResultsLocked(r, resultWho, requestCode);
1044 }
1045
1046 final long origId = Binder.clearCallingIdentity();
1047 // TODO(b/64750076): Check if calling pid should really be -1.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001048 final int res = getActivityStartController()
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001049 .obtainStarter(intent, "startNextMatchingActivity")
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001050 .setCaller(r.app.getThread())
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001051 .setResolvedType(r.resolvedType)
1052 .setActivityInfo(aInfo)
1053 .setResultTo(resultTo != null ? resultTo.appToken : null)
1054 .setResultWho(resultWho)
1055 .setRequestCode(requestCode)
1056 .setCallingPid(-1)
1057 .setCallingUid(r.launchedFromUid)
1058 .setCallingPackage(r.launchedFromPackage)
1059 .setRealCallingPid(-1)
1060 .setRealCallingUid(r.launchedFromUid)
1061 .setActivityOptions(options)
1062 .execute();
1063 Binder.restoreCallingIdentity(origId);
1064
1065 r.finishing = wasFinishing;
1066 if (res != ActivityManager.START_SUCCESS) {
1067 return false;
1068 }
1069 return true;
1070 }
1071 }
1072
1073 @Override
1074 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
1075 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1076 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
1077 final WaitResult res = new WaitResult();
1078 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001079 enforceNotIsolatedCaller("startActivityAndWait");
1080 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
1081 userId, "startActivityAndWait");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001082 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001083 getActivityStartController().obtainStarter(intent, "startActivityAndWait")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001084 .setCaller(caller)
1085 .setCallingPackage(callingPackage)
1086 .setResolvedType(resolvedType)
1087 .setResultTo(resultTo)
1088 .setResultWho(resultWho)
1089 .setRequestCode(requestCode)
1090 .setStartFlags(startFlags)
1091 .setActivityOptions(bOptions)
1092 .setMayWait(userId)
1093 .setProfilerInfo(profilerInfo)
1094 .setWaitResult(res)
1095 .execute();
1096 }
1097 return res;
1098 }
1099
1100 @Override
1101 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
1102 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1103 int startFlags, Configuration config, Bundle bOptions, int userId) {
1104 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001105 enforceNotIsolatedCaller("startActivityWithConfig");
1106 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
1107 "startActivityWithConfig");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001108 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001109 return getActivityStartController().obtainStarter(intent, "startActivityWithConfig")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001110 .setCaller(caller)
1111 .setCallingPackage(callingPackage)
1112 .setResolvedType(resolvedType)
1113 .setResultTo(resultTo)
1114 .setResultWho(resultWho)
1115 .setRequestCode(requestCode)
1116 .setStartFlags(startFlags)
1117 .setGlobalConfiguration(config)
1118 .setActivityOptions(bOptions)
1119 .setMayWait(userId)
1120 .execute();
1121 }
1122 }
1123
1124 @Override
1125 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
1126 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1127 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
1128 int userId) {
1129
1130 // This is very dangerous -- it allows you to perform a start activity (including
1131 // permission grants) as any app that may launch one of your own activities. So
1132 // we will only allow this to be done from activities that are part of the core framework,
1133 // and then only when they are running as the system.
1134 final ActivityRecord sourceRecord;
1135 final int targetUid;
1136 final String targetPackage;
1137 final boolean isResolver;
1138 synchronized (mGlobalLock) {
1139 if (resultTo == null) {
1140 throw new SecurityException("Must be called from an activity");
1141 }
1142 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
1143 if (sourceRecord == null) {
1144 throw new SecurityException("Called with bad activity token: " + resultTo);
1145 }
1146 if (!sourceRecord.info.packageName.equals("android")) {
1147 throw new SecurityException(
1148 "Must be called from an activity that is declared in the android package");
1149 }
1150 if (sourceRecord.app == null) {
1151 throw new SecurityException("Called without a process attached to activity");
1152 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001153 if (UserHandle.getAppId(sourceRecord.app.mUid) != SYSTEM_UID) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001154 // This is still okay, as long as this activity is running under the
1155 // uid of the original calling activity.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001156 if (sourceRecord.app.mUid != sourceRecord.launchedFromUid) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001157 throw new SecurityException(
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001158 "Calling activity in uid " + sourceRecord.app.mUid
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001159 + " must be system uid or original calling uid "
1160 + sourceRecord.launchedFromUid);
1161 }
1162 }
1163 if (ignoreTargetSecurity) {
1164 if (intent.getComponent() == null) {
1165 throw new SecurityException(
1166 "Component must be specified with ignoreTargetSecurity");
1167 }
1168 if (intent.getSelector() != null) {
1169 throw new SecurityException(
1170 "Selector not allowed with ignoreTargetSecurity");
1171 }
1172 }
1173 targetUid = sourceRecord.launchedFromUid;
1174 targetPackage = sourceRecord.launchedFromPackage;
1175 isResolver = sourceRecord.isResolverOrChildActivity();
1176 }
1177
1178 if (userId == UserHandle.USER_NULL) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001179 userId = UserHandle.getUserId(sourceRecord.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001180 }
1181
1182 // TODO: Switch to user app stacks here.
1183 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001184 return getActivityStartController().obtainStarter(intent, "startActivityAsCaller")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001185 .setCallingUid(targetUid)
1186 .setCallingPackage(targetPackage)
1187 .setResolvedType(resolvedType)
1188 .setResultTo(resultTo)
1189 .setResultWho(resultWho)
1190 .setRequestCode(requestCode)
1191 .setStartFlags(startFlags)
1192 .setActivityOptions(bOptions)
1193 .setMayWait(userId)
1194 .setIgnoreTargetSecurity(ignoreTargetSecurity)
1195 .setFilterCallingUid(isResolver ? 0 /* system */ : targetUid)
1196 .execute();
1197 } catch (SecurityException e) {
1198 // XXX need to figure out how to propagate to original app.
1199 // A SecurityException here is generally actually a fault of the original
1200 // calling activity (such as a fairly granting permissions), so propagate it
1201 // back to them.
1202 /*
1203 StringBuilder msg = new StringBuilder();
1204 msg.append("While launching");
1205 msg.append(intent.toString());
1206 msg.append(": ");
1207 msg.append(e.getMessage());
1208 */
1209 throw e;
1210 }
1211 }
1212
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001213 int handleIncomingUser(int callingPid, int callingUid, int userId, String name) {
1214 return mAmInternal.handleIncomingUser(callingPid, callingUid, userId, false /* allowAll */,
1215 ALLOW_FULL_ONLY, name, null /* callerPackage */);
1216 }
1217
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001218 @Override
1219 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
1220 Intent intent, String resolvedType, IVoiceInteractionSession session,
1221 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
1222 Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001223 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001224 if (session == null || interactor == null) {
1225 throw new NullPointerException("null session or interactor");
1226 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001227 userId = handleIncomingUser(callingPid, callingUid, userId, "startVoiceActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001228 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001229 return getActivityStartController().obtainStarter(intent, "startVoiceActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001230 .setCallingUid(callingUid)
1231 .setCallingPackage(callingPackage)
1232 .setResolvedType(resolvedType)
1233 .setVoiceSession(session)
1234 .setVoiceInteractor(interactor)
1235 .setStartFlags(startFlags)
1236 .setProfilerInfo(profilerInfo)
1237 .setActivityOptions(bOptions)
1238 .setMayWait(userId)
1239 .execute();
1240 }
1241
1242 @Override
1243 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
1244 Intent intent, String resolvedType, Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001245 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
1246 userId = handleIncomingUser(callingPid, callingUid, userId, "startAssistantActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001247
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001248 return getActivityStartController().obtainStarter(intent, "startAssistantActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001249 .setCallingUid(callingUid)
1250 .setCallingPackage(callingPackage)
1251 .setResolvedType(resolvedType)
1252 .setActivityOptions(bOptions)
1253 .setMayWait(userId)
1254 .execute();
1255 }
1256
1257 @Override
1258 public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
1259 IRecentsAnimationRunner recentsAnimationRunner) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001260 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001261 final int callingPid = Binder.getCallingPid();
1262 final long origId = Binder.clearCallingIdentity();
1263 try {
1264 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07001265 final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
1266 final int recentsUid = mRecentTasks.getRecentsComponentUid();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001267
1268 // Start a new recents animation
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001269 final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
1270 getActivityStartController(), mWindowManager, callingPid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001271 anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
1272 recentsUid, assistDataReceiver);
1273 }
1274 } finally {
1275 Binder.restoreCallingIdentity(origId);
1276 }
1277 }
1278
1279 @Override
1280 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001281 enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001282 "startActivityFromRecents()");
1283
1284 final int callingPid = Binder.getCallingPid();
1285 final int callingUid = Binder.getCallingUid();
1286 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(bOptions);
1287 final long origId = Binder.clearCallingIdentity();
1288 try {
1289 synchronized (mGlobalLock) {
1290 return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
1291 safeOptions);
1292 }
1293 } finally {
1294 Binder.restoreCallingIdentity(origId);
1295 }
1296 }
1297
1298 /**
1299 * This is the internal entry point for handling Activity.finish().
1300 *
1301 * @param token The Binder token referencing the Activity we want to finish.
1302 * @param resultCode Result code, if any, from this Activity.
1303 * @param resultData Result data (Intent), if any, from this Activity.
1304 * @param finishTask Whether to finish the task associated with this Activity.
1305 *
1306 * @return Returns true if the activity successfully finished, or false if it is still running.
1307 */
1308 @Override
1309 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
1310 int finishTask) {
1311 // Refuse possible leaked file descriptors
1312 if (resultData != null && resultData.hasFileDescriptors()) {
1313 throw new IllegalArgumentException("File descriptors passed in Intent");
1314 }
1315
1316 synchronized (mGlobalLock) {
1317 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1318 if (r == null) {
1319 return true;
1320 }
1321 // Keep track of the root activity of the task before we finish it
1322 TaskRecord tr = r.getTask();
1323 ActivityRecord rootR = tr.getRootActivity();
1324 if (rootR == null) {
1325 Slog.w(TAG, "Finishing task with all activities already finished");
1326 }
1327 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
1328 // finish.
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001329 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001330 return false;
1331 }
1332
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001333 // TODO: There is a dup. of this block of code in ActivityStack.navigateUpToLocked
1334 // We should consolidate.
1335 if (mController != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001336 // Find the first activity that is not finishing.
1337 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
1338 if (next != null) {
1339 // ask watcher if this is allowed
1340 boolean resumeOK = true;
1341 try {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001342 resumeOK = mController.activityResuming(next.packageName);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001343 } catch (RemoteException e) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001344 mController = null;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001345 Watchdog.getInstance().setActivityController(null);
1346 }
1347
1348 if (!resumeOK) {
1349 Slog.i(TAG, "Not finishing activity because controller resumed");
1350 return false;
1351 }
1352 }
1353 }
1354 final long origId = Binder.clearCallingIdentity();
1355 try {
1356 boolean res;
1357 final boolean finishWithRootActivity =
1358 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
1359 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
1360 || (finishWithRootActivity && r == rootR)) {
1361 // If requested, remove the task that is associated to this activity only if it
1362 // was the root activity in the task. The result code and data is ignored
1363 // because we don't support returning them across task boundaries. Also, to
1364 // keep backwards compatibility we remove the task from recents when finishing
1365 // task with root activity.
1366 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
1367 finishWithRootActivity, "finish-activity");
1368 if (!res) {
1369 Slog.i(TAG, "Removing task failed to finish activity");
1370 }
Garfield Tan2746ab52018-07-25 12:33:01 -07001371 // Explicitly dismissing the activity so reset its relaunch flag.
Wale Ogunwale64258362018-10-16 15:13:37 -07001372 r.mRelaunchReason = RELAUNCH_REASON_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001373 } else {
1374 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
1375 resultData, "app-request", true);
1376 if (!res) {
1377 Slog.i(TAG, "Failed to finish by app-request");
1378 }
1379 }
1380 return res;
1381 } finally {
1382 Binder.restoreCallingIdentity(origId);
1383 }
1384 }
1385 }
1386
1387 @Override
1388 public boolean finishActivityAffinity(IBinder token) {
1389 synchronized (mGlobalLock) {
1390 final long origId = Binder.clearCallingIdentity();
1391 try {
1392 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1393 if (r == null) {
1394 return false;
1395 }
1396
1397 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
1398 // can finish.
1399 final TaskRecord task = r.getTask();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001400 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001401 return false;
1402 }
1403 return task.getStack().finishActivityAffinityLocked(r);
1404 } finally {
1405 Binder.restoreCallingIdentity(origId);
1406 }
1407 }
1408 }
1409
1410 @Override
1411 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
1412 final long origId = Binder.clearCallingIdentity();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001413 try {
1414 WindowProcessController proc = null;
1415 synchronized (mGlobalLock) {
1416 ActivityStack stack = ActivityRecord.getStackLocked(token);
1417 if (stack == null) {
1418 return;
1419 }
1420 final ActivityRecord r = mStackSupervisor.activityIdleInternalLocked(token,
1421 false /* fromTimeout */, false /* processPausingActivities */, config);
1422 if (r != null) {
1423 proc = r.app;
1424 }
1425 if (stopProfiling && proc != null) {
1426 proc.clearProfilerIfNeeded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001427 }
1428 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001429 } finally {
1430 Binder.restoreCallingIdentity(origId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001431 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001432 }
1433
1434 @Override
1435 public final void activityResumed(IBinder token) {
1436 final long origId = Binder.clearCallingIdentity();
1437 synchronized (mGlobalLock) {
1438 ActivityRecord.activityResumedLocked(token);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001439 mWindowManager.notifyAppResumedFinished(token);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001440 }
1441 Binder.restoreCallingIdentity(origId);
1442 }
1443
1444 @Override
1445 public final void activityPaused(IBinder token) {
1446 final long origId = Binder.clearCallingIdentity();
1447 synchronized (mGlobalLock) {
1448 ActivityStack stack = ActivityRecord.getStackLocked(token);
1449 if (stack != null) {
1450 stack.activityPausedLocked(token, false);
1451 }
1452 }
1453 Binder.restoreCallingIdentity(origId);
1454 }
1455
1456 @Override
1457 public final void activityStopped(IBinder token, Bundle icicle,
1458 PersistableBundle persistentState, CharSequence description) {
1459 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
1460
1461 // Refuse possible leaked file descriptors
1462 if (icicle != null && icicle.hasFileDescriptors()) {
1463 throw new IllegalArgumentException("File descriptors passed in Bundle");
1464 }
1465
1466 final long origId = Binder.clearCallingIdentity();
1467
1468 synchronized (mGlobalLock) {
1469 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1470 if (r != null) {
1471 r.activityStoppedLocked(icicle, persistentState, description);
1472 }
1473 }
1474
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001475 mAmInternal.trimApplications();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001476
1477 Binder.restoreCallingIdentity(origId);
1478 }
1479
1480 @Override
1481 public final void activityDestroyed(IBinder token) {
1482 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
1483 synchronized (mGlobalLock) {
1484 ActivityStack stack = ActivityRecord.getStackLocked(token);
1485 if (stack != null) {
1486 stack.activityDestroyedLocked(token, "activityDestroyed");
1487 }
1488 }
1489 }
1490
1491 @Override
1492 public final void activityRelaunched(IBinder token) {
1493 final long origId = Binder.clearCallingIdentity();
1494 synchronized (mGlobalLock) {
1495 mStackSupervisor.activityRelaunchedLocked(token);
1496 }
1497 Binder.restoreCallingIdentity(origId);
1498 }
1499
1500 public final void activitySlept(IBinder token) {
1501 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
1502
1503 final long origId = Binder.clearCallingIdentity();
1504
1505 synchronized (mGlobalLock) {
1506 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1507 if (r != null) {
1508 mStackSupervisor.activitySleptLocked(r);
1509 }
1510 }
1511
1512 Binder.restoreCallingIdentity(origId);
1513 }
1514
1515 @Override
1516 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
1517 synchronized (mGlobalLock) {
1518 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1519 if (r == null) {
1520 return;
1521 }
1522 final long origId = Binder.clearCallingIdentity();
1523 try {
1524 r.setRequestedOrientation(requestedOrientation);
1525 } finally {
1526 Binder.restoreCallingIdentity(origId);
1527 }
1528 }
1529 }
1530
1531 @Override
1532 public int getRequestedOrientation(IBinder token) {
1533 synchronized (mGlobalLock) {
1534 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1535 if (r == null) {
1536 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
1537 }
1538 return r.getRequestedOrientation();
1539 }
1540 }
1541
1542 @Override
1543 public void setImmersive(IBinder token, boolean immersive) {
1544 synchronized (mGlobalLock) {
1545 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1546 if (r == null) {
1547 throw new IllegalArgumentException();
1548 }
1549 r.immersive = immersive;
1550
1551 // update associated state if we're frontmost
Andrii Kulian52d255c2018-07-13 11:32:19 -07001552 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001553 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001554 applyUpdateLockStateLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001555 }
1556 }
1557 }
1558
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001559 void applyUpdateLockStateLocked(ActivityRecord r) {
1560 // Modifications to the UpdateLock state are done on our handler, outside
1561 // the activity manager's locks. The new state is determined based on the
1562 // state *now* of the relevant activity record. The object is passed to
1563 // the handler solely for logging detail, not to be consulted/modified.
1564 final boolean nextState = r != null && r.immersive;
1565 mH.post(() -> {
1566 if (mUpdateLock.isHeld() != nextState) {
1567 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1568 "Applying new update lock state '" + nextState + "' for " + r);
1569 if (nextState) {
1570 mUpdateLock.acquire();
1571 } else {
1572 mUpdateLock.release();
1573 }
1574 }
1575 });
1576 }
1577
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001578 @Override
1579 public boolean isImmersive(IBinder token) {
1580 synchronized (mGlobalLock) {
1581 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1582 if (r == null) {
1583 throw new IllegalArgumentException();
1584 }
1585 return r.immersive;
1586 }
1587 }
1588
1589 @Override
1590 public boolean isTopActivityImmersive() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001591 enforceNotIsolatedCaller("isTopActivityImmersive");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001592 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001593 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001594 return (r != null) ? r.immersive : false;
1595 }
1596 }
1597
1598 @Override
1599 public void overridePendingTransition(IBinder token, String packageName,
1600 int enterAnim, int exitAnim) {
1601 synchronized (mGlobalLock) {
1602 ActivityRecord self = ActivityRecord.isInStackLocked(token);
1603 if (self == null) {
1604 return;
1605 }
1606
1607 final long origId = Binder.clearCallingIdentity();
1608
1609 if (self.isState(
1610 ActivityStack.ActivityState.RESUMED, ActivityStack.ActivityState.PAUSING)) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001611 mWindowManager.overridePendingAppTransition(packageName,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001612 enterAnim, exitAnim, null);
1613 }
1614
1615 Binder.restoreCallingIdentity(origId);
1616 }
1617 }
1618
1619 @Override
1620 public int getFrontActivityScreenCompatMode() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001621 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001622 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001623 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001624 if (r == null) {
1625 return ActivityManager.COMPAT_MODE_UNKNOWN;
1626 }
Wale Ogunwale53783742018-09-16 10:21:51 -07001627 return mCompatModePackages.computeCompatModeLocked(r.info.applicationInfo);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001628 }
1629 }
1630
1631 @Override
1632 public void setFrontActivityScreenCompatMode(int mode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001633 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001634 "setFrontActivityScreenCompatMode");
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001635 ApplicationInfo ai;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001636 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001637 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001638 if (r == null) {
1639 Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity");
1640 return;
1641 }
1642 ai = r.info.applicationInfo;
Wale Ogunwale53783742018-09-16 10:21:51 -07001643 mCompatModePackages.setPackageScreenCompatModeLocked(ai, mode);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001644 }
1645 }
1646
1647 @Override
1648 public int getLaunchedFromUid(IBinder activityToken) {
1649 ActivityRecord srec;
1650 synchronized (mGlobalLock) {
1651 srec = ActivityRecord.forTokenLocked(activityToken);
1652 }
1653 if (srec == null) {
1654 return -1;
1655 }
1656 return srec.launchedFromUid;
1657 }
1658
1659 @Override
1660 public String getLaunchedFromPackage(IBinder activityToken) {
1661 ActivityRecord srec;
1662 synchronized (mGlobalLock) {
1663 srec = ActivityRecord.forTokenLocked(activityToken);
1664 }
1665 if (srec == null) {
1666 return null;
1667 }
1668 return srec.launchedFromPackage;
1669 }
1670
1671 @Override
1672 public boolean convertFromTranslucent(IBinder token) {
1673 final long origId = Binder.clearCallingIdentity();
1674 try {
1675 synchronized (mGlobalLock) {
1676 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1677 if (r == null) {
1678 return false;
1679 }
1680 final boolean translucentChanged = r.changeWindowTranslucency(true);
1681 if (translucentChanged) {
1682 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
1683 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001684 mWindowManager.setAppFullscreen(token, true);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001685 return translucentChanged;
1686 }
1687 } finally {
1688 Binder.restoreCallingIdentity(origId);
1689 }
1690 }
1691
1692 @Override
1693 public boolean convertToTranslucent(IBinder token, Bundle options) {
1694 SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
1695 final long origId = Binder.clearCallingIdentity();
1696 try {
1697 synchronized (mGlobalLock) {
1698 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1699 if (r == null) {
1700 return false;
1701 }
1702 final TaskRecord task = r.getTask();
1703 int index = task.mActivities.lastIndexOf(r);
1704 if (index > 0) {
1705 ActivityRecord under = task.mActivities.get(index - 1);
1706 under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
1707 }
1708 final boolean translucentChanged = r.changeWindowTranslucency(false);
1709 if (translucentChanged) {
1710 r.getStack().convertActivityToTranslucent(r);
1711 }
1712 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001713 mWindowManager.setAppFullscreen(token, false);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001714 return translucentChanged;
1715 }
1716 } finally {
1717 Binder.restoreCallingIdentity(origId);
1718 }
1719 }
1720
1721 @Override
1722 public void notifyActivityDrawn(IBinder token) {
1723 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
1724 synchronized (mGlobalLock) {
1725 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
1726 if (r != null) {
1727 r.getStack().notifyActivityDrawnLocked(r);
1728 }
1729 }
1730 }
1731
1732 @Override
1733 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
1734 synchronized (mGlobalLock) {
1735 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1736 if (r == null) {
1737 return;
1738 }
1739 r.reportFullyDrawnLocked(restoredFromBundle);
1740 }
1741 }
1742
1743 @Override
1744 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
1745 synchronized (mGlobalLock) {
1746 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
1747 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
1748 return stack.mDisplayId;
1749 }
1750 return DEFAULT_DISPLAY;
1751 }
1752 }
1753
1754 @Override
1755 public ActivityManager.StackInfo getFocusedStackInfo() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001756 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001757 long ident = Binder.clearCallingIdentity();
1758 try {
1759 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001760 ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001761 if (focusedStack != null) {
1762 return mStackSupervisor.getStackInfo(focusedStack.mStackId);
1763 }
1764 return null;
1765 }
1766 } finally {
1767 Binder.restoreCallingIdentity(ident);
1768 }
1769 }
1770
1771 @Override
1772 public void setFocusedStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001773 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001774 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
1775 final long callingId = Binder.clearCallingIdentity();
1776 try {
1777 synchronized (mGlobalLock) {
1778 final ActivityStack stack = mStackSupervisor.getStack(stackId);
1779 if (stack == null) {
1780 Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
1781 return;
1782 }
1783 final ActivityRecord r = stack.topRunningActivityLocked();
Louis Chang19443452018-10-09 12:10:21 +08001784 if (r != null && r.moveFocusableActivityToTop("setFocusedStack")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08001785 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001786 }
1787 }
1788 } finally {
1789 Binder.restoreCallingIdentity(callingId);
1790 }
1791 }
1792
1793 @Override
1794 public void setFocusedTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001795 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001796 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
1797 final long callingId = Binder.clearCallingIdentity();
1798 try {
1799 synchronized (mGlobalLock) {
1800 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1801 if (task == null) {
1802 return;
1803 }
1804 final ActivityRecord r = task.topRunningActivityLocked();
Louis Chang19443452018-10-09 12:10:21 +08001805 if (r != null && r.moveFocusableActivityToTop("setFocusedTask")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08001806 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001807 }
1808 }
1809 } finally {
1810 Binder.restoreCallingIdentity(callingId);
1811 }
1812 }
1813
1814 @Override
1815 public boolean removeTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001816 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001817 synchronized (mGlobalLock) {
1818 final long ident = Binder.clearCallingIdentity();
1819 try {
1820 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
1821 "remove-task");
1822 } finally {
1823 Binder.restoreCallingIdentity(ident);
1824 }
1825 }
1826 }
1827
1828 @Override
Winson Chunge6439102018-07-30 15:48:01 -07001829 public void removeAllVisibleRecentTasks() {
1830 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeAllVisibleRecentTasks()");
1831 synchronized (mGlobalLock) {
1832 final long ident = Binder.clearCallingIdentity();
1833 try {
1834 getRecentTasks().removeAllVisibleTasks();
1835 } finally {
1836 Binder.restoreCallingIdentity(ident);
1837 }
1838 }
1839 }
1840
1841 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001842 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
1843 synchronized (mGlobalLock) {
1844 final ActivityRecord srec = ActivityRecord.forTokenLocked(token);
1845 if (srec != null) {
1846 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
1847 }
1848 }
1849 return false;
1850 }
1851
1852 @Override
1853 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
1854 Intent resultData) {
1855
1856 synchronized (mGlobalLock) {
1857 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
1858 if (r != null) {
1859 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
1860 }
1861 return false;
1862 }
1863 }
1864
1865 /**
1866 * Attempts to move a task backwards in z-order (the order of activities within the task is
1867 * unchanged).
1868 *
1869 * There are several possible results of this call:
1870 * - if the task is locked, then we will show the lock toast
1871 * - if there is a task behind the provided task, then that task is made visible and resumed as
1872 * this task is moved to the back
1873 * - otherwise, if there are no other tasks in the stack:
1874 * - if this task is in the pinned stack, then we remove the stack completely, which will
1875 * have the effect of moving the task to the top or bottom of the fullscreen stack
1876 * (depending on whether it is visible)
1877 * - otherwise, we simply return home and hide this task
1878 *
1879 * @param token A reference to the activity we wish to move
1880 * @param nonRoot If false then this only works if the activity is the root
1881 * of a task; if true it will work for any activity in a task.
1882 * @return Returns true if the move completed, false if not.
1883 */
1884 @Override
1885 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001886 enforceNotIsolatedCaller("moveActivityTaskToBack");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001887 synchronized (mGlobalLock) {
1888 final long origId = Binder.clearCallingIdentity();
1889 try {
1890 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
1891 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1892 if (task != null) {
1893 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
1894 }
1895 } finally {
1896 Binder.restoreCallingIdentity(origId);
1897 }
1898 }
1899 return false;
1900 }
1901
1902 @Override
1903 public Rect getTaskBounds(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001904 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001905 long ident = Binder.clearCallingIdentity();
1906 Rect rect = new Rect();
1907 try {
1908 synchronized (mGlobalLock) {
1909 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
1910 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1911 if (task == null) {
1912 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
1913 return rect;
1914 }
1915 if (task.getStack() != null) {
1916 // Return the bounds from window manager since it will be adjusted for various
1917 // things like the presense of a docked stack for tasks that aren't resizeable.
1918 task.getWindowContainerBounds(rect);
1919 } else {
1920 // Task isn't in window manager yet since it isn't associated with a stack.
1921 // Return the persist value from activity manager
1922 if (!task.matchParentBounds()) {
1923 rect.set(task.getBounds());
1924 } else if (task.mLastNonFullscreenBounds != null) {
1925 rect.set(task.mLastNonFullscreenBounds);
1926 }
1927 }
1928 }
1929 } finally {
1930 Binder.restoreCallingIdentity(ident);
1931 }
1932 return rect;
1933 }
1934
1935 @Override
1936 public ActivityManager.TaskDescription getTaskDescription(int id) {
1937 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001938 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001939 MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
1940 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
1941 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1942 if (tr != null) {
1943 return tr.lastTaskDescription;
1944 }
1945 }
1946 return null;
1947 }
1948
1949 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001950 public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
1951 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
1952 setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
1953 toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
1954 return;
1955 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001956 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001957 synchronized (mGlobalLock) {
1958 final long ident = Binder.clearCallingIdentity();
1959 try {
1960 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1961 if (task == null) {
1962 Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
1963 return;
1964 }
1965
1966 if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
1967 + " to windowingMode=" + windowingMode + " toTop=" + toTop);
1968
1969 if (!task.isActivityTypeStandardOrUndefined()) {
1970 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
1971 + " non-standard task " + taskId + " to windowing mode="
1972 + windowingMode);
1973 }
1974
1975 final ActivityStack stack = task.getStack();
1976 if (toTop) {
1977 stack.moveToFront("setTaskWindowingMode", task);
1978 }
1979 stack.setWindowingMode(windowingMode);
1980 } finally {
1981 Binder.restoreCallingIdentity(ident);
1982 }
1983 }
1984 }
1985
1986 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001987 public String getCallingPackage(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001988 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001989 ActivityRecord r = getCallingRecordLocked(token);
1990 return r != null ? r.info.packageName : null;
1991 }
1992 }
1993
1994 @Override
1995 public ComponentName getCallingActivity(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001996 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001997 ActivityRecord r = getCallingRecordLocked(token);
1998 return r != null ? r.intent.getComponent() : null;
1999 }
2000 }
2001
2002 private ActivityRecord getCallingRecordLocked(IBinder token) {
2003 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2004 if (r == null) {
2005 return null;
2006 }
2007 return r.resultTo;
2008 }
2009
2010 @Override
2011 public void unhandledBack() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002012 mAmInternal.enforceCallingPermission(android.Manifest.permission.FORCE_BACK, "unhandledBack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002013
2014 synchronized (mGlobalLock) {
2015 final long origId = Binder.clearCallingIdentity();
2016 try {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002017 getTopDisplayFocusedStack().unhandledBackLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002018 } finally {
2019 Binder.restoreCallingIdentity(origId);
2020 }
2021 }
2022 }
2023
2024 /**
2025 * TODO: Add mController hook
2026 */
2027 @Override
2028 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002029 mAmInternal.enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002030
2031 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
2032 synchronized (mGlobalLock) {
2033 moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
2034 false /* fromRecents */);
2035 }
2036 }
2037
2038 void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
2039 boolean fromRecents) {
2040
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002041 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002042 Binder.getCallingUid(), -1, -1, "Task to front")) {
2043 SafeActivityOptions.abort(options);
2044 return;
2045 }
2046 final long origId = Binder.clearCallingIdentity();
2047 try {
2048 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2049 if (task == null) {
2050 Slog.d(TAG, "Could not find task for id: "+ taskId);
Winson Chungd0243682018-09-25 18:11:54 -07002051 SafeActivityOptions.abort(options);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002052 return;
2053 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002054 if (getLockTaskController().isLockTaskModeViolation(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002055 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
Winson Chungd0243682018-09-25 18:11:54 -07002056 SafeActivityOptions.abort(options);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002057 return;
2058 }
2059 ActivityOptions realOptions = options != null
2060 ? options.getOptions(mStackSupervisor)
2061 : null;
2062 mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
2063 false /* forceNonResizable */);
2064
2065 final ActivityRecord topActivity = task.getTopActivity();
2066 if (topActivity != null) {
2067
2068 // We are reshowing a task, use a starting window to hide the initial draw delay
2069 // so the transition can start earlier.
2070 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
2071 true /* taskSwitch */, fromRecents);
2072 }
2073 } finally {
2074 Binder.restoreCallingIdentity(origId);
2075 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002076 }
2077
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002078 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
2079 int callingPid, int callingUid, String name) {
2080 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
2081 return true;
2082 }
2083
2084 if (getRecentTasks().isCallerRecents(sourceUid)) {
2085 return true;
2086 }
2087
2088 int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
2089 if (perm == PackageManager.PERMISSION_GRANTED) {
2090 return true;
2091 }
2092 if (checkAllowAppSwitchUid(sourceUid)) {
2093 return true;
2094 }
2095
2096 // If the actual IPC caller is different from the logical source, then
2097 // also see if they are allowed to control app switches.
2098 if (callingUid != -1 && callingUid != sourceUid) {
2099 perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
2100 if (perm == PackageManager.PERMISSION_GRANTED) {
2101 return true;
2102 }
2103 if (checkAllowAppSwitchUid(callingUid)) {
2104 return true;
2105 }
2106 }
2107
2108 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
2109 return false;
2110 }
2111
2112 private boolean checkAllowAppSwitchUid(int uid) {
2113 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
2114 if (types != null) {
2115 for (int i = types.size() - 1; i >= 0; i--) {
2116 if (types.valueAt(i).intValue() == uid) {
2117 return true;
2118 }
2119 }
2120 }
2121 return false;
2122 }
2123
2124 @Override
2125 public void setActivityController(IActivityController controller, boolean imAMonkey) {
2126 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
2127 "setActivityController()");
2128 synchronized (mGlobalLock) {
2129 mController = controller;
2130 mControllerIsAMonkey = imAMonkey;
2131 Watchdog.getInstance().setActivityController(controller);
2132 }
2133 }
2134
2135 boolean isControllerAMonkey() {
2136 synchronized (mGlobalLock) {
2137 return mController != null && mControllerIsAMonkey;
2138 }
2139 }
2140
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002141 @Override
2142 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
2143 synchronized (mGlobalLock) {
2144 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
2145 }
2146 }
2147
2148 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002149 public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum) {
2150 return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
2151 }
2152
2153 @Override
2154 public List<ActivityManager.RunningTaskInfo> getFilteredTasks(int maxNum,
2155 @WindowConfiguration.ActivityType int ignoreActivityType,
2156 @WindowConfiguration.WindowingMode int ignoreWindowingMode) {
2157 final int callingUid = Binder.getCallingUid();
2158 ArrayList<ActivityManager.RunningTaskInfo> list = new ArrayList<>();
2159
2160 synchronized (mGlobalLock) {
2161 if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
2162
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002163 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002164 callingUid);
2165 mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
2166 ignoreWindowingMode, callingUid, allowed);
2167 }
2168
2169 return list;
2170 }
2171
2172 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002173 public final void finishSubActivity(IBinder token, String resultWho, int requestCode) {
2174 synchronized (mGlobalLock) {
2175 final long origId = Binder.clearCallingIdentity();
2176 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2177 if (r != null) {
2178 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
2179 }
2180 Binder.restoreCallingIdentity(origId);
2181 }
2182 }
2183
2184 @Override
2185 public boolean willActivityBeVisible(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002186 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002187 ActivityStack stack = ActivityRecord.getStackLocked(token);
2188 if (stack != null) {
2189 return stack.willActivityBeVisibleLocked(token);
2190 }
2191 return false;
2192 }
2193 }
2194
2195 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002196 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002197 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002198 synchronized (mGlobalLock) {
2199 final long ident = Binder.clearCallingIdentity();
2200 try {
2201 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2202 if (task == null) {
2203 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
2204 return;
2205 }
2206
2207 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
2208 + " to stackId=" + stackId + " toTop=" + toTop);
2209
2210 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2211 if (stack == null) {
2212 throw new IllegalStateException(
2213 "moveTaskToStack: No stack for stackId=" + stackId);
2214 }
2215 if (!stack.isActivityTypeStandardOrUndefined()) {
2216 throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
2217 + taskId + " to stack " + stackId);
2218 }
2219 if (stack.inSplitScreenPrimaryWindowingMode()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002220 mWindowManager.setDockedStackCreateState(
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002221 SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
2222 }
2223 task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
2224 "moveTaskToStack");
2225 } finally {
2226 Binder.restoreCallingIdentity(ident);
2227 }
2228 }
2229 }
2230
2231 @Override
2232 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
2233 boolean preserveWindows, boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002234 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002235
2236 final long ident = Binder.clearCallingIdentity();
2237 try {
2238 synchronized (mGlobalLock) {
2239 if (animate) {
2240 final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
2241 if (stack == null) {
2242 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2243 return;
2244 }
2245 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
2246 throw new IllegalArgumentException("Stack: " + stackId
2247 + " doesn't support animated resize.");
2248 }
2249 stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
2250 animationDuration, false /* fromFullscreen */);
2251 } else {
2252 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2253 if (stack == null) {
2254 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2255 return;
2256 }
2257 mStackSupervisor.resizeStackLocked(stack, destBounds,
2258 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
2259 preserveWindows, allowResizeInDockedMode, !DEFER_RESUME);
2260 }
2261 }
2262 } finally {
2263 Binder.restoreCallingIdentity(ident);
2264 }
2265 }
2266
2267 /**
2268 * Moves the specified task to the primary-split-screen stack.
2269 *
2270 * @param taskId Id of task to move.
2271 * @param createMode The mode the primary split screen stack should be created in if it doesn't
2272 * exist already. See
2273 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
2274 * and
2275 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
2276 * @param toTop If the task and stack should be moved to the top.
2277 * @param animate Whether we should play an animation for the moving the task.
2278 * @param initialBounds If the primary stack gets created, it will use these bounds for the
2279 * stack. Pass {@code null} to use default bounds.
2280 * @param showRecents If the recents activity should be shown on the other side of the task
2281 * going into split-screen mode.
2282 */
2283 @Override
2284 public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode,
2285 boolean toTop, boolean animate, Rect initialBounds, boolean showRecents) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002286 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002287 "setTaskWindowingModeSplitScreenPrimary()");
2288 synchronized (mGlobalLock) {
2289 final long ident = Binder.clearCallingIdentity();
2290 try {
2291 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2292 if (task == null) {
2293 Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
2294 return false;
2295 }
2296 if (DEBUG_STACK) Slog.d(TAG_STACK,
2297 "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
2298 + " to createMode=" + createMode + " toTop=" + toTop);
2299 if (!task.isActivityTypeStandardOrUndefined()) {
2300 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
2301 + " non-standard task " + taskId + " to split-screen windowing mode");
2302 }
2303
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002304 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002305 final int windowingMode = task.getWindowingMode();
2306 final ActivityStack stack = task.getStack();
2307 if (toTop) {
2308 stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
2309 }
2310 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
2311 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */);
2312 return windowingMode != task.getWindowingMode();
2313 } finally {
2314 Binder.restoreCallingIdentity(ident);
2315 }
2316 }
2317 }
2318
2319 /**
2320 * Removes stacks in the input windowing modes from the system if they are of activity type
2321 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
2322 */
2323 @Override
2324 public void removeStacksInWindowingModes(int[] windowingModes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002325 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002326 "removeStacksInWindowingModes()");
2327
2328 synchronized (mGlobalLock) {
2329 final long ident = Binder.clearCallingIdentity();
2330 try {
2331 mStackSupervisor.removeStacksInWindowingModes(windowingModes);
2332 } finally {
2333 Binder.restoreCallingIdentity(ident);
2334 }
2335 }
2336 }
2337
2338 @Override
2339 public void removeStacksWithActivityTypes(int[] activityTypes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002340 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002341 "removeStacksWithActivityTypes()");
2342
2343 synchronized (mGlobalLock) {
2344 final long ident = Binder.clearCallingIdentity();
2345 try {
2346 mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
2347 } finally {
2348 Binder.restoreCallingIdentity(ident);
2349 }
2350 }
2351 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002352
2353 @Override
2354 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
2355 int userId) {
2356 final int callingUid = Binder.getCallingUid();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002357 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, "getRecentTasks");
2358 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002359 callingUid);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002360 final boolean detailed = checkGetTasksPermission(
2361 android.Manifest.permission.GET_DETAILED_TASKS, Binder.getCallingPid(),
2362 UserHandle.getAppId(callingUid))
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002363 == PackageManager.PERMISSION_GRANTED;
2364
2365 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002366 return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002367 callingUid);
2368 }
2369 }
2370
2371 @Override
2372 public List<ActivityManager.StackInfo> getAllStackInfos() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002373 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002374 long ident = Binder.clearCallingIdentity();
2375 try {
2376 synchronized (mGlobalLock) {
2377 return mStackSupervisor.getAllStackInfosLocked();
2378 }
2379 } finally {
2380 Binder.restoreCallingIdentity(ident);
2381 }
2382 }
2383
2384 @Override
2385 public ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002386 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002387 long ident = Binder.clearCallingIdentity();
2388 try {
2389 synchronized (mGlobalLock) {
2390 return mStackSupervisor.getStackInfo(windowingMode, activityType);
2391 }
2392 } finally {
2393 Binder.restoreCallingIdentity(ident);
2394 }
2395 }
2396
2397 @Override
2398 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002399 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002400 final long callingUid = Binder.getCallingUid();
2401 final long origId = Binder.clearCallingIdentity();
2402 try {
2403 synchronized (mGlobalLock) {
2404 // Cancel the recents animation synchronously (do not hold the WM lock)
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002405 mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002406 ? REORDER_MOVE_TO_ORIGINAL_POSITION
2407 : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
2408 }
2409 } finally {
2410 Binder.restoreCallingIdentity(origId);
2411 }
2412 }
2413
2414 @Override
2415 public void startLockTaskModeByToken(IBinder token) {
2416 synchronized (mGlobalLock) {
2417 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2418 if (r == null) {
2419 return;
2420 }
2421 startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
2422 }
2423 }
2424
2425 @Override
2426 public void startSystemLockTaskMode(int taskId) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002427 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002428 // This makes inner call to look as if it was initiated by system.
2429 long ident = Binder.clearCallingIdentity();
2430 try {
2431 synchronized (mGlobalLock) {
2432 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2433
2434 // When starting lock task mode the stack must be in front and focused
2435 task.getStack().moveToFront("startSystemLockTaskMode");
2436 startLockTaskModeLocked(task, true /* isSystemCaller */);
2437 }
2438 } finally {
2439 Binder.restoreCallingIdentity(ident);
2440 }
2441 }
2442
2443 @Override
2444 public void stopLockTaskModeByToken(IBinder token) {
2445 synchronized (mGlobalLock) {
2446 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2447 if (r == null) {
2448 return;
2449 }
2450 stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
2451 }
2452 }
2453
2454 /**
2455 * This API should be called by SystemUI only when user perform certain action to dismiss
2456 * lock task mode. We should only dismiss pinned lock task mode in this case.
2457 */
2458 @Override
2459 public void stopSystemLockTaskMode() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002460 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002461 stopLockTaskModeInternal(null, true /* isSystemCaller */);
2462 }
2463
2464 private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
2465 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
2466 if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
2467 return;
2468 }
2469
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002470 final ActivityStack stack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002471 if (stack == null || task != stack.topTask()) {
2472 throw new IllegalArgumentException("Invalid task, not in foreground");
2473 }
2474
2475 // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
2476 // system or a specific app.
2477 // * System-initiated requests will only start the pinned mode (screen pinning)
2478 // * App-initiated requests
2479 // - will put the device in fully locked mode (LockTask), if the app is whitelisted
2480 // - will start the pinned mode, otherwise
2481 final int callingUid = Binder.getCallingUid();
2482 long ident = Binder.clearCallingIdentity();
2483 try {
2484 // When a task is locked, dismiss the pinned stack if it exists
2485 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2486
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002487 getLockTaskController().startLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002488 } finally {
2489 Binder.restoreCallingIdentity(ident);
2490 }
2491 }
2492
2493 private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
2494 final int callingUid = Binder.getCallingUid();
2495 long ident = Binder.clearCallingIdentity();
2496 try {
2497 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002498 getLockTaskController().stopLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002499 }
2500 // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
2501 // task and jumping straight into a call in the case of emergency call back.
2502 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
2503 if (tm != null) {
2504 tm.showInCallScreen(false);
2505 }
2506 } finally {
2507 Binder.restoreCallingIdentity(ident);
2508 }
2509 }
2510
2511 @Override
2512 public boolean isInLockTaskMode() {
2513 return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
2514 }
2515
2516 @Override
2517 public int getLockTaskModeState() {
2518 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002519 return getLockTaskController().getLockTaskModeState();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002520 }
2521 }
2522
2523 @Override
2524 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
2525 synchronized (mGlobalLock) {
2526 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2527 if (r != null) {
2528 r.setTaskDescription(td);
2529 final TaskRecord task = r.getTask();
2530 task.updateTaskDescription();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002531 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002532 }
2533 }
2534 }
2535
2536 @Override
2537 public Bundle getActivityOptions(IBinder token) {
2538 final long origId = Binder.clearCallingIdentity();
2539 try {
2540 synchronized (mGlobalLock) {
2541 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
2542 if (r != null) {
2543 final ActivityOptions activityOptions = r.takeOptionsLocked();
2544 return activityOptions == null ? null : activityOptions.toBundle();
2545 }
2546 return null;
2547 }
2548 } finally {
2549 Binder.restoreCallingIdentity(origId);
2550 }
2551 }
2552
2553 @Override
2554 public List<IBinder> getAppTasks(String callingPackage) {
2555 int callingUid = Binder.getCallingUid();
2556 long ident = Binder.clearCallingIdentity();
2557 try {
2558 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002559 return mRecentTasks.getAppTasksList(callingUid, callingPackage);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002560 }
2561 } finally {
2562 Binder.restoreCallingIdentity(ident);
2563 }
2564 }
2565
2566 @Override
2567 public void finishVoiceTask(IVoiceInteractionSession session) {
2568 synchronized (mGlobalLock) {
2569 final long origId = Binder.clearCallingIdentity();
2570 try {
2571 // TODO: VI Consider treating local voice interactions and voice tasks
2572 // differently here
2573 mStackSupervisor.finishVoiceTask(session);
2574 } finally {
2575 Binder.restoreCallingIdentity(origId);
2576 }
2577 }
2578
2579 }
2580
2581 @Override
2582 public boolean isTopOfTask(IBinder token) {
2583 synchronized (mGlobalLock) {
2584 ActivityRecord r = ActivityRecord.isInStackLocked(token);
Riddle Hsu66b74a82018-07-26 00:20:12 +08002585 return r != null && r.getTask().getTopActivity() == r;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002586 }
2587 }
2588
2589 @Override
2590 public void notifyLaunchTaskBehindComplete(IBinder token) {
2591 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
2592 }
2593
2594 @Override
2595 public void notifyEnterAnimationComplete(IBinder token) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002596 mH.post(() -> {
2597 synchronized (mGlobalLock) {
2598 ActivityRecord r = ActivityRecord.forTokenLocked(token);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002599 if (r != null && r.attachedToProcess()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002600 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002601 r.app.getThread().scheduleEnterAnimationComplete(r.appToken);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002602 } catch (RemoteException e) {
2603 }
2604 }
2605 }
2606
2607 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002608 }
2609
2610 /** Called from an app when assist data is ready. */
2611 @Override
2612 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
2613 AssistContent content, Uri referrer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002614 PendingAssistExtras pae = (PendingAssistExtras) token;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002615 synchronized (pae) {
2616 pae.result = extras;
2617 pae.structure = structure;
2618 pae.content = content;
2619 if (referrer != null) {
2620 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
2621 }
2622 if (structure != null) {
2623 structure.setHomeActivity(pae.isHome);
2624 }
2625 pae.haveResult = true;
2626 pae.notifyAll();
2627 if (pae.intent == null && pae.receiver == null) {
2628 // Caller is just waiting for the result.
2629 return;
2630 }
2631 }
2632 // We are now ready to launch the assist activity.
2633 IAssistDataReceiver sendReceiver = null;
2634 Bundle sendBundle = null;
2635 synchronized (mGlobalLock) {
2636 buildAssistBundleLocked(pae, extras);
2637 boolean exists = mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002638 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002639 if (!exists) {
2640 // Timed out.
2641 return;
2642 }
2643
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002644 if ((sendReceiver = pae.receiver) != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002645 // Caller wants result sent back to them.
2646 sendBundle = new Bundle();
2647 sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
2648 sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
2649 sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
2650 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
2651 }
2652 }
2653 if (sendReceiver != null) {
2654 try {
2655 sendReceiver.onHandleAssistData(sendBundle);
2656 } catch (RemoteException e) {
2657 }
2658 return;
2659 }
2660
2661 final long ident = Binder.clearCallingIdentity();
2662 try {
2663 if (TextUtils.equals(pae.intent.getAction(),
2664 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
2665 pae.intent.putExtras(pae.extras);
2666 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
2667 } else {
2668 pae.intent.replaceExtras(pae.extras);
2669 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
2670 | Intent.FLAG_ACTIVITY_SINGLE_TOP
2671 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Wale Ogunwale31913b52018-10-13 08:29:31 -07002672 mInternal.closeSystemDialogs("assist");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002673
2674 try {
2675 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
2676 } catch (ActivityNotFoundException e) {
2677 Slog.w(TAG, "No activity to handle assist action.", e);
2678 }
2679 }
2680 } finally {
2681 Binder.restoreCallingIdentity(ident);
2682 }
2683 }
2684
2685 @Override
2686 public int addAppTask(IBinder activityToken, Intent intent,
2687 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
2688 final int callingUid = Binder.getCallingUid();
2689 final long callingIdent = Binder.clearCallingIdentity();
2690
2691 try {
2692 synchronized (mGlobalLock) {
2693 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
2694 if (r == null) {
2695 throw new IllegalArgumentException("Activity does not exist; token="
2696 + activityToken);
2697 }
2698 ComponentName comp = intent.getComponent();
2699 if (comp == null) {
2700 throw new IllegalArgumentException("Intent " + intent
2701 + " must specify explicit component");
2702 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002703 if (thumbnail.getWidth() != mThumbnailWidth
2704 || thumbnail.getHeight() != mThumbnailHeight) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002705 throw new IllegalArgumentException("Bad thumbnail size: got "
2706 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002707 + mThumbnailWidth + "x" + mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002708 }
2709 if (intent.getSelector() != null) {
2710 intent.setSelector(null);
2711 }
2712 if (intent.getSourceBounds() != null) {
2713 intent.setSourceBounds(null);
2714 }
2715 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
2716 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
2717 // The caller has added this as an auto-remove task... that makes no
2718 // sense, so turn off auto-remove.
2719 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
2720 }
2721 }
2722 final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
2723 STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
2724 if (ainfo.applicationInfo.uid != callingUid) {
2725 throw new SecurityException(
2726 "Can't add task for another application: target uid="
2727 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
2728 }
2729
2730 final ActivityStack stack = r.getStack();
2731 final TaskRecord task = stack.createTaskRecord(
2732 mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent,
2733 null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002734 if (!mRecentTasks.addToBottom(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002735 // The app has too many tasks already and we can't add any more
2736 stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
2737 return INVALID_TASK_ID;
2738 }
2739 task.lastTaskDescription.copyFrom(description);
2740
2741 // TODO: Send the thumbnail to WM to store it.
2742
2743 return task.taskId;
2744 }
2745 } finally {
2746 Binder.restoreCallingIdentity(callingIdent);
2747 }
2748 }
2749
2750 @Override
2751 public Point getAppTaskThumbnailSize() {
2752 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002753 return new Point(mThumbnailWidth, mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002754 }
2755 }
2756
2757 @Override
2758 public void setTaskResizeable(int taskId, int resizeableMode) {
2759 synchronized (mGlobalLock) {
2760 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
2761 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
2762 if (task == null) {
2763 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
2764 return;
2765 }
2766 task.setResizeMode(resizeableMode);
2767 }
2768 }
2769
2770 @Override
2771 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002772 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002773 long ident = Binder.clearCallingIdentity();
2774 try {
2775 synchronized (mGlobalLock) {
2776 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2777 if (task == null) {
2778 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
2779 return;
2780 }
2781 // Place the task in the right stack if it isn't there already based on
2782 // the requested bounds.
2783 // The stack transition logic is:
2784 // - a null bounds on a freeform task moves that task to fullscreen
2785 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
2786 // that task to freeform
2787 // - otherwise the task is not moved
2788 ActivityStack stack = task.getStack();
2789 if (!task.getWindowConfiguration().canResizeTask()) {
2790 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
2791 }
2792 if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
2793 stack = stack.getDisplay().getOrCreateStack(
2794 WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
2795 } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
2796 stack = stack.getDisplay().getOrCreateStack(
2797 WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
2798 }
2799
2800 // Reparent the task to the right stack if necessary
2801 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
2802 if (stack != task.getStack()) {
2803 // Defer resume until the task is resized below
2804 task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
2805 DEFER_RESUME, "resizeTask");
2806 preserveWindow = false;
2807 }
2808
2809 // After reparenting (which only resizes the task to the stack bounds), resize the
2810 // task to the actual bounds provided
2811 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
2812 }
2813 } finally {
2814 Binder.restoreCallingIdentity(ident);
2815 }
2816 }
2817
2818 @Override
2819 public boolean releaseActivityInstance(IBinder token) {
2820 synchronized (mGlobalLock) {
2821 final long origId = Binder.clearCallingIdentity();
2822 try {
2823 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2824 if (r == null) {
2825 return false;
2826 }
2827 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
2828 } finally {
2829 Binder.restoreCallingIdentity(origId);
2830 }
2831 }
2832 }
2833
2834 @Override
2835 public void releaseSomeActivities(IApplicationThread appInt) {
2836 synchronized (mGlobalLock) {
2837 final long origId = Binder.clearCallingIdentity();
2838 try {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07002839 final WindowProcessController app = getProcessController(appInt);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002840 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
2841 } finally {
2842 Binder.restoreCallingIdentity(origId);
2843 }
2844 }
2845 }
2846
2847 @Override
2848 public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
2849 int secondaryDisplayShowing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002850 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002851 != PackageManager.PERMISSION_GRANTED) {
2852 throw new SecurityException("Requires permission "
2853 + android.Manifest.permission.DEVICE_POWER);
2854 }
2855
2856 synchronized (mGlobalLock) {
2857 long ident = Binder.clearCallingIdentity();
2858 if (mKeyguardShown != keyguardShowing) {
2859 mKeyguardShown = keyguardShowing;
Wale Ogunwale342fbe92018-10-09 08:44:10 -07002860 final Message msg = PooledLambda.obtainMessage(
2861 ActivityManagerInternal::reportCurKeyguardUsageEvent, mAmInternal,
2862 keyguardShowing);
2863 mH.sendMessage(msg);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002864 }
2865 try {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002866 mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002867 secondaryDisplayShowing);
2868 } finally {
2869 Binder.restoreCallingIdentity(ident);
2870 }
2871 }
2872
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002873 mH.post(() -> {
2874 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2875 mScreenObservers.get(i).onKeyguardStateChanged(keyguardShowing);
2876 }
2877 });
2878 }
2879
2880 void onScreenAwakeChanged(boolean isAwake) {
2881 mH.post(() -> {
2882 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2883 mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2884 }
2885 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002886 }
2887
2888 @Override
2889 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002890 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
2891 userId, "getTaskDescriptionIcon");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002892
2893 final File passedIconFile = new File(filePath);
2894 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
2895 passedIconFile.getName());
2896 if (!legitIconFile.getPath().equals(filePath)
2897 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
2898 throw new IllegalArgumentException("Bad file path: " + filePath
2899 + " passed for userId " + userId);
2900 }
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002901 return mRecentTasks.getTaskDescriptionIcon(filePath);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002902 }
2903
2904 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002905 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002906 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
2907 final ActivityOptions activityOptions = safeOptions != null
2908 ? safeOptions.getOptions(mStackSupervisor)
2909 : null;
2910 if (activityOptions == null
2911 || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
2912 || activityOptions.getCustomInPlaceResId() == 0) {
2913 throw new IllegalArgumentException("Expected in-place ActivityOption " +
2914 "with valid animation");
2915 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002916 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
2917 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002918 activityOptions.getCustomInPlaceResId());
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002919 mWindowManager.executeAppTransition();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002920 }
2921
2922 @Override
2923 public void removeStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002924 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002925 synchronized (mGlobalLock) {
2926 final long ident = Binder.clearCallingIdentity();
2927 try {
2928 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2929 if (stack == null) {
2930 Slog.w(TAG, "removeStack: No stack with id=" + stackId);
2931 return;
2932 }
2933 if (!stack.isActivityTypeStandardOrUndefined()) {
2934 throw new IllegalArgumentException(
2935 "Removing non-standard stack is not allowed.");
2936 }
2937 mStackSupervisor.removeStack(stack);
2938 } finally {
2939 Binder.restoreCallingIdentity(ident);
2940 }
2941 }
2942 }
2943
2944 @Override
2945 public void moveStackToDisplay(int stackId, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002946 mAmInternal.enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002947
2948 synchronized (mGlobalLock) {
2949 final long ident = Binder.clearCallingIdentity();
2950 try {
2951 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
2952 + " to displayId=" + displayId);
2953 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
2954 } finally {
2955 Binder.restoreCallingIdentity(ident);
2956 }
2957 }
2958 }
2959
2960 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002961 public void exitFreeformMode(IBinder token) {
2962 synchronized (mGlobalLock) {
2963 long ident = Binder.clearCallingIdentity();
2964 try {
2965 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2966 if (r == null) {
2967 throw new IllegalArgumentException(
2968 "exitFreeformMode: No activity record matching token=" + token);
2969 }
2970
2971 final ActivityStack stack = r.getStack();
2972 if (stack == null || !stack.inFreeformWindowingMode()) {
2973 throw new IllegalStateException(
2974 "exitFreeformMode: You can only go fullscreen from freeform.");
2975 }
2976
2977 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
2978 } finally {
2979 Binder.restoreCallingIdentity(ident);
2980 }
2981 }
2982 }
2983
2984 /** Sets the task stack listener that gets callbacks when a task stack changes. */
2985 @Override
2986 public void registerTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002987 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002988 "registerTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002989 mTaskChangeNotificationController.registerTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002990 }
2991
2992 /** Unregister a task stack listener so that it stops receiving callbacks. */
2993 @Override
2994 public void unregisterTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002995 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002996 "unregisterTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002997 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002998 }
2999
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003000 @Override
3001 public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
3002 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
3003 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
3004 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
3005 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
3006 }
3007
3008 @Override
3009 public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
3010 IBinder activityToken, int flags) {
3011 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
3012 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
3013 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
3014 }
3015
3016 @Override
3017 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
3018 Bundle args) {
3019 return enqueueAssistContext(requestType, intent, hint, null, null, null,
3020 true /* focused */, true /* newSessionId */, userHandle, args,
3021 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
3022 }
3023
3024 @Override
3025 public Bundle getAssistContextExtras(int requestType) {
3026 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
3027 null, null, true /* focused */, true /* newSessionId */,
3028 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
3029 if (pae == null) {
3030 return null;
3031 }
3032 synchronized (pae) {
3033 while (!pae.haveResult) {
3034 try {
3035 pae.wait();
3036 } catch (InterruptedException e) {
3037 }
3038 }
3039 }
3040 synchronized (mGlobalLock) {
3041 buildAssistBundleLocked(pae, pae.result);
3042 mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003043 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003044 }
3045 return pae.extras;
3046 }
3047
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003048 /**
3049 * Binder IPC calls go through the public entry point.
3050 * This can be called with or without the global lock held.
3051 */
3052 private static int checkCallingPermission(String permission) {
3053 return checkPermission(
3054 permission, Binder.getCallingPid(), UserHandle.getAppId(Binder.getCallingUid()));
3055 }
3056
3057 /** This can be called with or without the global lock held. */
Wale Ogunwale214f3482018-10-04 11:00:47 -07003058 private void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003059 if (!getRecentTasks().isCallerRecents(Binder.getCallingUid())) {
3060 mAmInternal.enforceCallingPermission(permission, func);
3061 }
3062 }
3063
3064 @VisibleForTesting
3065 int checkGetTasksPermission(String permission, int pid, int uid) {
3066 return checkPermission(permission, pid, uid);
3067 }
3068
3069 static int checkPermission(String permission, int pid, int uid) {
3070 if (permission == null) {
3071 return PackageManager.PERMISSION_DENIED;
3072 }
3073 return checkComponentPermission(permission, pid, uid, -1, true);
3074 }
3075
Wale Ogunwale214f3482018-10-04 11:00:47 -07003076 public static int checkComponentPermission(String permission, int pid, int uid,
3077 int owningUid, boolean exported) {
3078 return ActivityManagerService.checkComponentPermission(
3079 permission, pid, uid, owningUid, exported);
3080 }
3081
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003082 boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
3083 if (getRecentTasks().isCallerRecents(callingUid)) {
3084 // Always allow the recents component to get tasks
3085 return true;
3086 }
3087
3088 boolean allowed = checkGetTasksPermission(android.Manifest.permission.REAL_GET_TASKS,
3089 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
3090 if (!allowed) {
3091 if (checkGetTasksPermission(android.Manifest.permission.GET_TASKS,
3092 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
3093 // Temporary compatibility: some existing apps on the system image may
3094 // still be requesting the old permission and not switched to the new
3095 // one; if so, we'll still allow them full access. This means we need
3096 // to see if they are holding the old permission and are a system app.
3097 try {
3098 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
3099 allowed = true;
3100 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
3101 + " is using old GET_TASKS but privileged; allowing");
3102 }
3103 } catch (RemoteException e) {
3104 }
3105 }
3106 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
3107 + " does not hold REAL_GET_TASKS; limiting output");
3108 }
3109 return allowed;
3110 }
3111
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003112 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
3113 IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
3114 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
3115 int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003116 mAmInternal.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003117 "enqueueAssistContext()");
3118
3119 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003120 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003121 if (activity == null) {
3122 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
3123 return null;
3124 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003125 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003126 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
3127 return null;
3128 }
3129 if (focused) {
3130 if (activityToken != null) {
3131 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
3132 if (activity != caller) {
3133 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
3134 + " is not current top " + activity);
3135 return null;
3136 }
3137 }
3138 } else {
3139 activity = ActivityRecord.forTokenLocked(activityToken);
3140 if (activity == null) {
3141 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
3142 + " couldn't be found");
3143 return null;
3144 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003145 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003146 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
3147 return null;
3148 }
3149 }
3150
3151 PendingAssistExtras pae;
3152 Bundle extras = new Bundle();
3153 if (args != null) {
3154 extras.putAll(args);
3155 }
3156 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003157 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003158
3159 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
3160 userHandle);
3161 pae.isHome = activity.isActivityTypeHome();
3162
3163 // Increment the sessionId if necessary
3164 if (newSessionId) {
3165 mViSessionId++;
3166 }
3167 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003168 activity.app.getThread().requestAssistContextExtras(activity.appToken, pae,
3169 requestType, mViSessionId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003170 mPendingAssistExtras.add(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003171 mUiHandler.postDelayed(pae, timeout);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003172 } catch (RemoteException e) {
3173 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
3174 return null;
3175 }
3176 return pae;
3177 }
3178 }
3179
3180 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
3181 if (result != null) {
3182 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
3183 }
3184 if (pae.hint != null) {
3185 pae.extras.putBoolean(pae.hint, true);
3186 }
3187 }
3188
3189 private void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
3190 IAssistDataReceiver receiver;
3191 synchronized (mGlobalLock) {
3192 mPendingAssistExtras.remove(pae);
3193 receiver = pae.receiver;
3194 }
3195 if (receiver != null) {
3196 // Caller wants result sent back to them.
3197 Bundle sendBundle = new Bundle();
3198 // At least return the receiver extras
3199 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
3200 try {
3201 pae.receiver.onHandleAssistData(sendBundle);
3202 } catch (RemoteException e) {
3203 }
3204 }
3205 }
3206
3207 public class PendingAssistExtras extends Binder implements Runnable {
3208 public final ActivityRecord activity;
3209 public boolean isHome;
3210 public final Bundle extras;
3211 public final Intent intent;
3212 public final String hint;
3213 public final IAssistDataReceiver receiver;
3214 public final int userHandle;
3215 public boolean haveResult = false;
3216 public Bundle result = null;
3217 public AssistStructure structure = null;
3218 public AssistContent content = null;
3219 public Bundle receiverExtras;
3220
3221 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
3222 String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
3223 int _userHandle) {
3224 activity = _activity;
3225 extras = _extras;
3226 intent = _intent;
3227 hint = _hint;
3228 receiver = _receiver;
3229 receiverExtras = _receiverExtras;
3230 userHandle = _userHandle;
3231 }
3232
3233 @Override
3234 public void run() {
3235 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
3236 synchronized (this) {
3237 haveResult = true;
3238 notifyAll();
3239 }
3240 pendingAssistExtrasTimedOut(this);
3241 }
3242 }
3243
3244 @Override
3245 public boolean isAssistDataAllowedOnCurrentActivity() {
3246 int userId;
3247 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003248 final ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003249 if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
3250 return false;
3251 }
3252
3253 final ActivityRecord activity = focusedStack.getTopActivity();
3254 if (activity == null) {
3255 return false;
3256 }
3257 userId = activity.userId;
3258 }
3259 return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
3260 }
3261
3262 @Override
3263 public boolean showAssistFromActivity(IBinder token, Bundle args) {
3264 long ident = Binder.clearCallingIdentity();
3265 try {
3266 synchronized (mGlobalLock) {
3267 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003268 ActivityRecord top = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003269 if (top != caller) {
3270 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3271 + " is not current top " + top);
3272 return false;
3273 }
3274 if (!top.nowVisible) {
3275 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3276 + " is not visible");
3277 return false;
3278 }
3279 }
3280 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
3281 token);
3282 } finally {
3283 Binder.restoreCallingIdentity(ident);
3284 }
3285 }
3286
3287 @Override
3288 public boolean isRootVoiceInteraction(IBinder token) {
3289 synchronized (mGlobalLock) {
3290 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3291 if (r == null) {
3292 return false;
3293 }
3294 return r.rootVoiceInteraction;
3295 }
3296 }
3297
Wale Ogunwalef6733932018-06-27 05:14:34 -07003298 private void onLocalVoiceInteractionStartedLocked(IBinder activity,
3299 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
3300 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
3301 if (activityToCallback == null) return;
3302 activityToCallback.setVoiceSessionLocked(voiceSession);
3303
3304 // Inform the activity
3305 try {
3306 activityToCallback.app.getThread().scheduleLocalVoiceInteractionStarted(activity,
3307 voiceInteractor);
3308 long token = Binder.clearCallingIdentity();
3309 try {
3310 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
3311 } finally {
3312 Binder.restoreCallingIdentity(token);
3313 }
3314 // TODO: VI Should we cache the activity so that it's easier to find later
3315 // rather than scan through all the stacks and activities?
3316 } catch (RemoteException re) {
3317 activityToCallback.clearVoiceSessionLocked();
3318 // TODO: VI Should this terminate the voice session?
3319 }
3320 }
3321
3322 private void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
3323 Slog.d(TAG, "<<< startRunningVoiceLocked()");
3324 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
3325 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
3326 boolean wasRunningVoice = mRunningVoice != null;
3327 mRunningVoice = session;
3328 if (!wasRunningVoice) {
3329 mVoiceWakeLock.acquire();
3330 updateSleepIfNeededLocked();
3331 }
3332 }
3333 }
3334
3335 void finishRunningVoiceLocked() {
3336 if (mRunningVoice != null) {
3337 mRunningVoice = null;
3338 mVoiceWakeLock.release();
3339 updateSleepIfNeededLocked();
3340 }
3341 }
3342
3343 @Override
3344 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3345 synchronized (mGlobalLock) {
3346 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3347 if (keepAwake) {
3348 mVoiceWakeLock.acquire();
3349 } else {
3350 mVoiceWakeLock.release();
3351 }
3352 }
3353 }
3354 }
3355
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003356 @Override
3357 public ComponentName getActivityClassForToken(IBinder token) {
3358 synchronized (mGlobalLock) {
3359 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3360 if (r == null) {
3361 return null;
3362 }
3363 return r.intent.getComponent();
3364 }
3365 }
3366
3367 @Override
3368 public String getPackageForToken(IBinder token) {
3369 synchronized (mGlobalLock) {
3370 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3371 if (r == null) {
3372 return null;
3373 }
3374 return r.packageName;
3375 }
3376 }
3377
3378 @Override
3379 public void showLockTaskEscapeMessage(IBinder token) {
3380 synchronized (mGlobalLock) {
3381 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3382 if (r == null) {
3383 return;
3384 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003385 getLockTaskController().showLockTaskToast();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003386 }
3387 }
3388
3389 @Override
3390 public void keyguardGoingAway(int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003391 enforceNotIsolatedCaller("keyguardGoingAway");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003392 final long token = Binder.clearCallingIdentity();
3393 try {
3394 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003395 mKeyguardController.keyguardGoingAway(flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003396 }
3397 } finally {
3398 Binder.restoreCallingIdentity(token);
3399 }
3400 }
3401
3402 /**
3403 * Try to place task to provided position. The final position might be different depending on
3404 * current user and stacks state. The task will be moved to target stack if it's currently in
3405 * different stack.
3406 */
3407 @Override
3408 public void positionTaskInStack(int taskId, int stackId, int position) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003409 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003410 synchronized (mGlobalLock) {
3411 long ident = Binder.clearCallingIdentity();
3412 try {
3413 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
3414 + taskId + " in stackId=" + stackId + " at position=" + position);
3415 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3416 if (task == null) {
3417 throw new IllegalArgumentException("positionTaskInStack: no task for id="
3418 + taskId);
3419 }
3420
3421 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3422
3423 if (stack == null) {
3424 throw new IllegalArgumentException("positionTaskInStack: no stack for id="
3425 + stackId);
3426 }
3427 if (!stack.isActivityTypeStandardOrUndefined()) {
3428 throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
3429 + " the position of task " + taskId + " in/to non-standard stack");
3430 }
3431
3432 // TODO: Have the callers of this API call a separate reparent method if that is
3433 // what they intended to do vs. having this method also do reparenting.
3434 if (task.getStack() == stack) {
3435 // Change position in current stack.
3436 stack.positionChildAt(task, position);
3437 } else {
3438 // Reparent to new stack.
3439 task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
3440 !DEFER_RESUME, "positionTaskInStack");
3441 }
3442 } finally {
3443 Binder.restoreCallingIdentity(ident);
3444 }
3445 }
3446 }
3447
3448 @Override
3449 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
3450 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
3451 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
3452 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
3453 synchronized (mGlobalLock) {
3454 ActivityRecord record = ActivityRecord.isInStackLocked(token);
3455 if (record == null) {
3456 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
3457 + "found for: " + token);
3458 }
3459 record.setSizeConfigurations(horizontalSizeConfiguration,
3460 verticalSizeConfigurations, smallestSizeConfigurations);
3461 }
3462 }
3463
3464 /**
3465 * Dismisses split-screen multi-window mode.
3466 * @param toTop If true the current primary split-screen stack will be placed or left on top.
3467 */
3468 @Override
3469 public void dismissSplitScreenMode(boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003470 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003471 MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
3472 final long ident = Binder.clearCallingIdentity();
3473 try {
3474 synchronized (mGlobalLock) {
3475 final ActivityStack stack =
3476 mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
3477 if (stack == null) {
3478 Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
3479 return;
3480 }
3481
3482 if (toTop) {
3483 // Caller wants the current split-screen primary stack to be the top stack after
3484 // it goes fullscreen, so move it to the front.
3485 stack.moveToFront("dismissSplitScreenMode");
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003486 } else if (mStackSupervisor.isTopDisplayFocusedStack(stack)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003487 // In this case the current split-screen primary stack shouldn't be the top
3488 // stack after it goes fullscreen, but it current has focus, so we move the
3489 // focus to the top-most split-screen secondary stack next to it.
3490 final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
3491 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
3492 if (otherStack != null) {
3493 otherStack.moveToFront("dismissSplitScreenMode_other");
3494 }
3495 }
3496
Evan Rosky10475742018-09-05 19:02:48 -07003497 stack.setWindowingMode(WINDOWING_MODE_UNDEFINED);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003498 }
3499 } finally {
3500 Binder.restoreCallingIdentity(ident);
3501 }
3502 }
3503
3504 /**
3505 * Dismisses Pip
3506 * @param animate True if the dismissal should be animated.
3507 * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
3508 * default animation duration should be used.
3509 */
3510 @Override
3511 public void dismissPip(boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003512 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003513 final long ident = Binder.clearCallingIdentity();
3514 try {
3515 synchronized (mGlobalLock) {
3516 final PinnedActivityStack stack =
3517 mStackSupervisor.getDefaultDisplay().getPinnedStack();
3518 if (stack == null) {
3519 Slog.w(TAG, "dismissPip: pinned stack not found.");
3520 return;
3521 }
3522 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
3523 throw new IllegalArgumentException("Stack: " + stack
3524 + " doesn't support animated resize.");
3525 }
3526 if (animate) {
3527 stack.animateResizePinnedStack(null /* sourceHintBounds */,
3528 null /* destBounds */, animationDuration, false /* fromFullscreen */);
3529 } else {
3530 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
3531 }
3532 }
3533 } finally {
3534 Binder.restoreCallingIdentity(ident);
3535 }
3536 }
3537
3538 @Override
3539 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003540 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003541 synchronized (mGlobalLock) {
3542 mSuppressResizeConfigChanges = suppress;
3543 }
3544 }
3545
3546 /**
3547 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
3548 * animated the stack to the fullscreen, but can also be called if we are relaunching an
3549 * activity and clearing the task at the same time.
3550 */
3551 @Override
3552 // TODO: API should just be about changing windowing modes...
3553 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003554 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003555 "moveTasksToFullscreenStack()");
3556 synchronized (mGlobalLock) {
3557 final long origId = Binder.clearCallingIdentity();
3558 try {
3559 final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
3560 if (stack != null){
3561 if (!stack.isActivityTypeStandardOrUndefined()) {
3562 throw new IllegalArgumentException(
3563 "You can't move tasks from non-standard stacks.");
3564 }
3565 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
3566 }
3567 } finally {
3568 Binder.restoreCallingIdentity(origId);
3569 }
3570 }
3571 }
3572
3573 /**
3574 * Moves the top activity in the input stackId to the pinned stack.
3575 *
3576 * @param stackId Id of stack to move the top activity to pinned stack.
3577 * @param bounds Bounds to use for pinned stack.
3578 *
3579 * @return True if the top activity of the input stack was successfully moved to the pinned
3580 * stack.
3581 */
3582 @Override
3583 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003584 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003585 "moveTopActivityToPinnedStack()");
3586 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003587 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003588 throw new IllegalStateException("moveTopActivityToPinnedStack:"
3589 + "Device doesn't support picture-in-picture mode");
3590 }
3591
3592 long ident = Binder.clearCallingIdentity();
3593 try {
3594 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
3595 } finally {
3596 Binder.restoreCallingIdentity(ident);
3597 }
3598 }
3599 }
3600
3601 @Override
3602 public boolean isInMultiWindowMode(IBinder token) {
3603 final long origId = Binder.clearCallingIdentity();
3604 try {
3605 synchronized (mGlobalLock) {
3606 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3607 if (r == null) {
3608 return false;
3609 }
3610 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
3611 return r.inMultiWindowMode();
3612 }
3613 } finally {
3614 Binder.restoreCallingIdentity(origId);
3615 }
3616 }
3617
3618 @Override
3619 public boolean isInPictureInPictureMode(IBinder token) {
3620 final long origId = Binder.clearCallingIdentity();
3621 try {
3622 synchronized (mGlobalLock) {
3623 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
3624 }
3625 } finally {
3626 Binder.restoreCallingIdentity(origId);
3627 }
3628 }
3629
3630 private boolean isInPictureInPictureMode(ActivityRecord r) {
3631 if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
3632 || r.getStack().isInStackLocked(r) == null) {
3633 return false;
3634 }
3635
3636 // If we are animating to fullscreen then we have already dispatched the PIP mode
3637 // changed, so we should reflect that check here as well.
3638 final PinnedActivityStack stack = r.getStack();
3639 final PinnedStackWindowController windowController = stack.getWindowContainerController();
3640 return !windowController.isAnimatingBoundsToFullscreen();
3641 }
3642
3643 @Override
3644 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
3645 final long origId = Binder.clearCallingIdentity();
3646 try {
3647 synchronized (mGlobalLock) {
3648 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3649 "enterPictureInPictureMode", token, params);
3650
3651 // If the activity is already in picture in picture mode, then just return early
3652 if (isInPictureInPictureMode(r)) {
3653 return true;
3654 }
3655
3656 // Activity supports picture-in-picture, now check that we can enter PiP at this
3657 // point, if it is
3658 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
3659 false /* beforeStopping */)) {
3660 return false;
3661 }
3662
3663 final Runnable enterPipRunnable = () -> {
Wale Ogunwalef276a6f2018-06-15 08:26:07 -07003664 synchronized (mGlobalLock) {
3665 // Only update the saved args from the args that are set
3666 r.pictureInPictureArgs.copyOnlySet(params);
3667 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
3668 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
3669 // Adjust the source bounds by the insets for the transition down
3670 final Rect sourceBounds = new Rect(
3671 r.pictureInPictureArgs.getSourceRectHint());
3672 mStackSupervisor.moveActivityToPinnedStackLocked(
3673 r, sourceBounds, aspectRatio, "enterPictureInPictureMode");
3674 final PinnedActivityStack stack = r.getStack();
3675 stack.setPictureInPictureAspectRatio(aspectRatio);
3676 stack.setPictureInPictureActions(actions);
3677 MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
3678 r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
3679 logPictureInPictureArgs(params);
3680 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003681 };
3682
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003683 if (isKeyguardLocked()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003684 // If the keyguard is showing or occluded, then try and dismiss it before
3685 // entering picture-in-picture (this will prompt the user to authenticate if the
3686 // device is currently locked).
3687 dismissKeyguard(token, new KeyguardDismissCallback() {
3688 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003689 public void onDismissSucceeded() {
3690 mH.post(enterPipRunnable);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003691 }
3692 }, null /* message */);
3693 } else {
3694 // Enter picture in picture immediately otherwise
3695 enterPipRunnable.run();
3696 }
3697 return true;
3698 }
3699 } finally {
3700 Binder.restoreCallingIdentity(origId);
3701 }
3702 }
3703
3704 @Override
3705 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
3706 final long origId = Binder.clearCallingIdentity();
3707 try {
3708 synchronized (mGlobalLock) {
3709 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3710 "setPictureInPictureParams", token, params);
3711
3712 // Only update the saved args from the args that are set
3713 r.pictureInPictureArgs.copyOnlySet(params);
3714 if (r.inPinnedWindowingMode()) {
3715 // If the activity is already in picture-in-picture, update the pinned stack now
3716 // if it is not already expanding to fullscreen. Otherwise, the arguments will
3717 // be used the next time the activity enters PiP
3718 final PinnedActivityStack stack = r.getStack();
3719 if (!stack.isAnimatingBoundsToFullscreen()) {
3720 stack.setPictureInPictureAspectRatio(
3721 r.pictureInPictureArgs.getAspectRatio());
3722 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
3723 }
3724 }
3725 logPictureInPictureArgs(params);
3726 }
3727 } finally {
3728 Binder.restoreCallingIdentity(origId);
3729 }
3730 }
3731
3732 @Override
3733 public int getMaxNumPictureInPictureActions(IBinder token) {
3734 // Currently, this is a static constant, but later, we may change this to be dependent on
3735 // the context of the activity
3736 return 3;
3737 }
3738
3739 private void logPictureInPictureArgs(PictureInPictureParams params) {
3740 if (params.hasSetActions()) {
3741 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
3742 params.getActions().size());
3743 }
3744 if (params.hasSetAspectRatio()) {
3745 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
3746 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
3747 MetricsLogger.action(lm);
3748 }
3749 }
3750
3751 /**
3752 * Checks the state of the system and the activity associated with the given {@param token} to
3753 * verify that picture-in-picture is supported for that activity.
3754 *
3755 * @return the activity record for the given {@param token} if all the checks pass.
3756 */
3757 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
3758 IBinder token, PictureInPictureParams params) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003759 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003760 throw new IllegalStateException(caller
3761 + ": Device doesn't support picture-in-picture mode.");
3762 }
3763
3764 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3765 if (r == null) {
3766 throw new IllegalStateException(caller
3767 + ": Can't find activity for token=" + token);
3768 }
3769
3770 if (!r.supportsPictureInPicture()) {
3771 throw new IllegalStateException(caller
3772 + ": Current activity does not support picture-in-picture.");
3773 }
3774
3775 if (params.hasSetAspectRatio()
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003776 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003777 params.getAspectRatio())) {
3778 final float minAspectRatio = mContext.getResources().getFloat(
3779 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
3780 final float maxAspectRatio = mContext.getResources().getFloat(
3781 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
3782 throw new IllegalArgumentException(String.format(caller
3783 + ": Aspect ratio is too extreme (must be between %f and %f).",
3784 minAspectRatio, maxAspectRatio));
3785 }
3786
3787 // Truncate the number of actions if necessary
3788 params.truncateActions(getMaxNumPictureInPictureActions(token));
3789
3790 return r;
3791 }
3792
3793 @Override
3794 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003795 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003796 synchronized (mGlobalLock) {
3797 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
3798 if (r == null) {
3799 throw new IllegalArgumentException("Activity does not exist; token="
3800 + activityToken);
3801 }
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07003802 return r.getUriPermissionsLocked().getExternalToken();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003803 }
3804 }
3805
3806 @Override
3807 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
3808 Rect tempDockedTaskInsetBounds,
3809 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003810 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003811 long ident = Binder.clearCallingIdentity();
3812 try {
3813 synchronized (mGlobalLock) {
3814 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
3815 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
3816 PRESERVE_WINDOWS);
3817 }
3818 } finally {
3819 Binder.restoreCallingIdentity(ident);
3820 }
3821 }
3822
3823 @Override
3824 public void setSplitScreenResizing(boolean resizing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003825 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003826 final long ident = Binder.clearCallingIdentity();
3827 try {
3828 synchronized (mGlobalLock) {
3829 mStackSupervisor.setSplitScreenResizing(resizing);
3830 }
3831 } finally {
3832 Binder.restoreCallingIdentity(ident);
3833 }
3834 }
3835
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003836 /**
3837 * Check that we have the features required for VR-related API calls, and throw an exception if
3838 * not.
3839 */
3840 void enforceSystemHasVrFeature() {
3841 if (!mContext.getPackageManager().hasSystemFeature(
3842 PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
3843 throw new UnsupportedOperationException("VR mode not supported on this device!");
3844 }
3845 }
3846
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003847 @Override
3848 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003849 enforceSystemHasVrFeature();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003850
3851 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3852
3853 ActivityRecord r;
3854 synchronized (mGlobalLock) {
3855 r = ActivityRecord.isInStackLocked(token);
3856 }
3857
3858 if (r == null) {
3859 throw new IllegalArgumentException();
3860 }
3861
3862 int err;
3863 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
3864 VrManagerInternal.NO_ERROR) {
3865 return err;
3866 }
3867
3868 // Clear the binder calling uid since this path may call moveToTask().
3869 final long callingId = Binder.clearCallingIdentity();
3870 try {
3871 synchronized (mGlobalLock) {
3872 r.requestedVrComponent = (enabled) ? packageName : null;
3873
3874 // Update associated state if this activity is currently focused
Andrii Kulian52d255c2018-07-13 11:32:19 -07003875 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003876 applyUpdateVrModeLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003877 }
3878 return 0;
3879 }
3880 } finally {
3881 Binder.restoreCallingIdentity(callingId);
3882 }
3883 }
3884
3885 @Override
3886 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
3887 Slog.i(TAG, "Activity tried to startLocalVoiceInteraction");
3888 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003889 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003890 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
3891 throw new SecurityException("Only focused activity can call startVoiceInteraction");
3892 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07003893 if (mRunningVoice != null || activity.getTask().voiceSession != null
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003894 || activity.voiceSession != null) {
3895 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
3896 return;
3897 }
3898 if (activity.pendingVoiceInteractionStart) {
3899 Slog.w(TAG, "Pending start of voice interaction already.");
3900 return;
3901 }
3902 activity.pendingVoiceInteractionStart = true;
3903 }
3904 LocalServices.getService(VoiceInteractionManagerInternal.class)
3905 .startLocalVoiceInteraction(callingActivity, options);
3906 }
3907
3908 @Override
3909 public void stopLocalVoiceInteraction(IBinder callingActivity) {
3910 LocalServices.getService(VoiceInteractionManagerInternal.class)
3911 .stopLocalVoiceInteraction(callingActivity);
3912 }
3913
3914 @Override
3915 public boolean supportsLocalVoiceInteraction() {
3916 return LocalServices.getService(VoiceInteractionManagerInternal.class)
3917 .supportsLocalVoiceInteraction();
3918 }
3919
3920 /** Notifies all listeners when the pinned stack animation starts. */
3921 @Override
3922 public void notifyPinnedStackAnimationStarted() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003923 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003924 }
3925
3926 /** Notifies all listeners when the pinned stack animation ends. */
3927 @Override
3928 public void notifyPinnedStackAnimationEnded() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003929 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003930 }
3931
3932 @Override
3933 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003934 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003935 final long ident = Binder.clearCallingIdentity();
3936 try {
3937 synchronized (mGlobalLock) {
3938 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
3939 }
3940 } finally {
3941 Binder.restoreCallingIdentity(ident);
3942 }
3943 }
3944
3945 @Override
3946 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003947 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003948
3949 synchronized (mGlobalLock) {
3950 // Check if display is initialized in AM.
3951 if (!mStackSupervisor.isDisplayAdded(displayId)) {
3952 // Call might come when display is not yet added or has already been removed.
3953 if (DEBUG_CONFIGURATION) {
3954 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
3955 + displayId);
3956 }
3957 return false;
3958 }
3959
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003960 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003961 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003962 values = mWindowManager.computeNewConfiguration(displayId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003963 }
3964
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003965 if (mWindowManager != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07003966 final Message msg = PooledLambda.obtainMessage(
3967 ActivityManagerInternal::updateOomLevelsForDisplay, mAmInternal, displayId);
3968 mH.sendMessage(msg);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003969 }
3970
3971 final long origId = Binder.clearCallingIdentity();
3972 try {
3973 if (values != null) {
3974 Settings.System.clearConfiguration(values);
3975 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003976 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003977 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
3978 return mTmpUpdateConfigurationResult.changes != 0;
3979 } finally {
3980 Binder.restoreCallingIdentity(origId);
3981 }
3982 }
3983 }
3984
3985 @Override
3986 public boolean updateConfiguration(Configuration values) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003987 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003988
3989 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003990 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003991 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003992 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003993 }
3994
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003995 if (mWindowManager != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07003996 final Message msg = PooledLambda.obtainMessage(
3997 ActivityManagerInternal::updateOomLevelsForDisplay, mAmInternal,
3998 DEFAULT_DISPLAY);
3999 mH.sendMessage(msg);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004000 }
4001
4002 final long origId = Binder.clearCallingIdentity();
4003 try {
4004 if (values != null) {
4005 Settings.System.clearConfiguration(values);
4006 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004007 updateConfigurationLocked(values, null, false, false /* persistent */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004008 UserHandle.USER_NULL, false /* deferResume */,
4009 mTmpUpdateConfigurationResult);
4010 return mTmpUpdateConfigurationResult.changes != 0;
4011 } finally {
4012 Binder.restoreCallingIdentity(origId);
4013 }
4014 }
4015 }
4016
4017 @Override
4018 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
4019 CharSequence message) {
4020 if (message != null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004021 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004022 Manifest.permission.SHOW_KEYGUARD_MESSAGE, "dismissKeyguard()");
4023 }
4024 final long callingId = Binder.clearCallingIdentity();
4025 try {
4026 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004027 mKeyguardController.dismissKeyguard(token, callback, message);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004028 }
4029 } finally {
4030 Binder.restoreCallingIdentity(callingId);
4031 }
4032 }
4033
4034 @Override
4035 public void cancelTaskWindowTransition(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004036 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004037 "cancelTaskWindowTransition()");
4038 final long ident = Binder.clearCallingIdentity();
4039 try {
4040 synchronized (mGlobalLock) {
4041 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
4042 MATCH_TASK_IN_STACKS_ONLY);
4043 if (task == null) {
4044 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
4045 return;
4046 }
4047 task.cancelWindowTransition();
4048 }
4049 } finally {
4050 Binder.restoreCallingIdentity(ident);
4051 }
4052 }
4053
4054 @Override
4055 public ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004056 enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004057 final long ident = Binder.clearCallingIdentity();
4058 try {
4059 final TaskRecord task;
4060 synchronized (mGlobalLock) {
4061 task = mStackSupervisor.anyTaskForIdLocked(taskId,
4062 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
4063 if (task == null) {
4064 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
4065 return null;
4066 }
4067 }
4068 // Don't call this while holding the lock as this operation might hit the disk.
4069 return task.getSnapshot(reducedResolution);
4070 } finally {
4071 Binder.restoreCallingIdentity(ident);
4072 }
4073 }
4074
4075 @Override
4076 public void setDisablePreviewScreenshots(IBinder token, boolean disable) {
4077 synchronized (mGlobalLock) {
4078 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4079 if (r == null) {
4080 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
4081 + token);
4082 return;
4083 }
4084 final long origId = Binder.clearCallingIdentity();
4085 try {
4086 r.setDisablePreviewScreenshots(disable);
4087 } finally {
4088 Binder.restoreCallingIdentity(origId);
4089 }
4090 }
4091 }
4092
4093 /** Return the user id of the last resumed activity. */
4094 @Override
4095 public @UserIdInt
4096 int getLastResumedActivityUserId() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004097 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004098 Manifest.permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
4099 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07004100 if (mLastResumedActivity == null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004101 return getCurrentUserId();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004102 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004103 return mLastResumedActivity.userId;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004104 }
4105 }
4106
4107 @Override
4108 public void updateLockTaskFeatures(int userId, int flags) {
4109 final int callingUid = Binder.getCallingUid();
4110 if (callingUid != 0 && callingUid != SYSTEM_UID) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004111 mAmInternal.enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004112 "updateLockTaskFeatures()");
4113 }
4114 synchronized (mGlobalLock) {
4115 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
4116 Integer.toHexString(flags));
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07004117 getLockTaskController().updateLockTaskFeatures(userId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004118 }
4119 }
4120
4121 @Override
4122 public void setShowWhenLocked(IBinder token, boolean showWhenLocked) {
4123 synchronized (mGlobalLock) {
4124 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4125 if (r == null) {
4126 return;
4127 }
4128 final long origId = Binder.clearCallingIdentity();
4129 try {
4130 r.setShowWhenLocked(showWhenLocked);
4131 } finally {
4132 Binder.restoreCallingIdentity(origId);
4133 }
4134 }
4135 }
4136
4137 @Override
4138 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) {
4139 synchronized (mGlobalLock) {
4140 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4141 if (r == null) {
4142 return;
4143 }
4144 final long origId = Binder.clearCallingIdentity();
4145 try {
4146 r.setTurnScreenOn(turnScreenOn);
4147 } finally {
4148 Binder.restoreCallingIdentity(origId);
4149 }
4150 }
4151 }
4152
4153 @Override
4154 public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004155 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004156 "registerRemoteAnimations");
4157 definition.setCallingPid(Binder.getCallingPid());
4158 synchronized (mGlobalLock) {
4159 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4160 if (r == null) {
4161 return;
4162 }
4163 final long origId = Binder.clearCallingIdentity();
4164 try {
4165 r.registerRemoteAnimations(definition);
4166 } finally {
4167 Binder.restoreCallingIdentity(origId);
4168 }
4169 }
4170 }
4171
4172 @Override
4173 public void registerRemoteAnimationForNextActivityStart(String packageName,
4174 RemoteAnimationAdapter adapter) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004175 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004176 "registerRemoteAnimationForNextActivityStart");
4177 adapter.setCallingPid(Binder.getCallingPid());
4178 synchronized (mGlobalLock) {
4179 final long origId = Binder.clearCallingIdentity();
4180 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07004181 getActivityStartController().registerRemoteAnimationForNextActivityStart(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004182 packageName, adapter);
4183 } finally {
4184 Binder.restoreCallingIdentity(origId);
4185 }
4186 }
4187 }
4188
4189 /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
4190 @Override
4191 public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
4192 synchronized (mGlobalLock) {
4193 final long origId = Binder.clearCallingIdentity();
4194 try {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004195 mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004196 } finally {
4197 Binder.restoreCallingIdentity(origId);
4198 }
4199 }
4200 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004201
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004202 @Override
4203 public void setVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004204 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004205 synchronized (mGlobalLock) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004206 final int pid = Binder.getCallingPid();
4207 final WindowProcessController wpc = mPidMap.get(pid);
4208 mVrController.setVrThreadLocked(tid, pid, wpc);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004209 }
4210 }
4211
4212 @Override
4213 public void setPersistentVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004214 if (checkCallingPermission(Manifest.permission.RESTRICTED_VR_ACCESS)
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004215 != PERMISSION_GRANTED) {
4216 final String msg = "Permission Denial: setPersistentVrThread() from pid="
4217 + Binder.getCallingPid()
4218 + ", uid=" + Binder.getCallingUid()
4219 + " requires " + Manifest.permission.RESTRICTED_VR_ACCESS;
4220 Slog.w(TAG, msg);
4221 throw new SecurityException(msg);
4222 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004223 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004224 synchronized (mGlobalLock) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004225 final int pid = Binder.getCallingPid();
4226 final WindowProcessController proc = mPidMap.get(pid);
4227 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004228 }
4229 }
4230
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004231 @Override
4232 public void stopAppSwitches() {
4233 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
4234 synchronized (mGlobalLock) {
4235 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME;
4236 mDidAppSwitch = false;
4237 getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
4238 }
4239 }
4240
4241 @Override
4242 public void resumeAppSwitches() {
4243 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
4244 synchronized (mGlobalLock) {
4245 // Note that we don't execute any pending app switches... we will
4246 // let those wait until either the timeout, or the next start
4247 // activity request.
4248 mAppSwitchesAllowedTime = 0;
4249 }
4250 }
4251
4252 void onStartActivitySetDidAppSwitch() {
4253 if (mDidAppSwitch) {
4254 // This is the second allowed switch since we stopped switches, so now just generally
4255 // allow switches. Use case:
4256 // - user presses home (switches disabled, switch to home, mDidAppSwitch now true);
4257 // - user taps a home icon (coming from home so allowed, we hit here and now allow
4258 // anyone to switch again).
4259 mAppSwitchesAllowedTime = 0;
4260 } else {
4261 mDidAppSwitch = true;
4262 }
4263 }
4264
4265 /** @return whether the system should disable UI modes incompatible with VR mode. */
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004266 boolean shouldDisableNonVrUiLocked() {
4267 return mVrController.shouldDisableNonVrUiLocked();
4268 }
4269
Wale Ogunwale53783742018-09-16 10:21:51 -07004270 private void applyUpdateVrModeLocked(ActivityRecord r) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004271 // VR apps are expected to run in a main display. If an app is turning on VR for
4272 // itself, but lives in a dynamic stack, then make sure that it is moved to the main
4273 // fullscreen stack before enabling VR Mode.
4274 // TODO: The goal of this code is to keep the VR app on the main display. When the
4275 // stack implementation changes in the future, keep in mind that the use of the fullscreen
4276 // stack is a means to move the activity to the main display and a moveActivityToDisplay()
4277 // option would be a better choice here.
4278 if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
4279 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
4280 + " to main stack for VR");
4281 final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
4282 WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
4283 moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
4284 }
4285 mH.post(() -> {
4286 if (!mVrController.onVrModeChanged(r)) {
4287 return;
4288 }
4289 synchronized (mGlobalLock) {
4290 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
4291 mWindowManager.disableNonVrUi(disableNonVrUi);
4292 if (disableNonVrUi) {
4293 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
4294 // then remove the pinned stack.
4295 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
4296 }
4297 }
4298 });
4299 }
4300
Wale Ogunwale53783742018-09-16 10:21:51 -07004301 @Override
4302 public int getPackageScreenCompatMode(String packageName) {
4303 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4304 synchronized (mGlobalLock) {
4305 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4306 }
4307 }
4308
4309 @Override
4310 public void setPackageScreenCompatMode(String packageName, int mode) {
4311 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4312 "setPackageScreenCompatMode");
4313 synchronized (mGlobalLock) {
4314 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4315 }
4316 }
4317
4318 @Override
4319 public boolean getPackageAskScreenCompat(String packageName) {
4320 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4321 synchronized (mGlobalLock) {
4322 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4323 }
4324 }
4325
4326 @Override
4327 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4328 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4329 "setPackageAskScreenCompat");
4330 synchronized (mGlobalLock) {
4331 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4332 }
4333 }
4334
Wale Ogunwale64258362018-10-16 15:13:37 -07004335 public static String relaunchReasonToString(int relaunchReason) {
4336 switch (relaunchReason) {
4337 case RELAUNCH_REASON_WINDOWING_MODE_RESIZE:
4338 return "window_resize";
4339 case RELAUNCH_REASON_FREE_RESIZE:
4340 return "free_resize";
4341 default:
4342 return null;
4343 }
4344 }
4345
Andrii Kulian5f750bc2018-07-17 08:57:23 -07004346 ActivityStack getTopDisplayFocusedStack() {
4347 return mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004348 }
4349
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004350 /** Pokes the task persister. */
4351 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
4352 mRecentTasks.notifyTaskPersisterLocked(task, flush);
4353 }
4354
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004355 void onTopProcChangedLocked(WindowProcessController proc) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004356 mVrController.onTopProcChangedLocked(proc);
4357 }
4358
4359 boolean isKeyguardLocked() {
4360 return mKeyguardController.isKeyguardLocked();
4361 }
4362
4363 boolean isNextTransitionForward() {
4364 int transit = mWindowManager.getPendingAppTransition();
4365 return transit == TRANSIT_ACTIVITY_OPEN
4366 || transit == TRANSIT_TASK_OPEN
4367 || transit == TRANSIT_TASK_TO_FRONT;
4368 }
4369
Wale Ogunwale31913b52018-10-13 08:29:31 -07004370 void dumpLastANRLocked(PrintWriter pw) {
4371 pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
4372 if (mLastANRState == null) {
4373 pw.println(" <no ANR has occurred since boot>");
4374 } else {
4375 pw.println(mLastANRState);
4376 }
4377 }
4378
4379 void dumpLastANRTracesLocked(PrintWriter pw) {
4380 pw.println("ACTIVITY MANAGER LAST ANR TRACES (dumpsys activity lastanr-traces)");
4381
4382 final File[] files = new File(ANR_TRACE_DIR).listFiles();
4383 if (ArrayUtils.isEmpty(files)) {
4384 pw.println(" <no ANR has occurred since boot>");
4385 return;
4386 }
4387 // Find the latest file.
4388 File latest = null;
4389 for (File f : files) {
4390 if ((latest == null) || (latest.lastModified() < f.lastModified())) {
4391 latest = f;
Wale Ogunwalef6733932018-06-27 05:14:34 -07004392 }
Wale Ogunwale31913b52018-10-13 08:29:31 -07004393 }
4394 pw.print("File: ");
4395 pw.print(latest.getName());
4396 pw.println();
4397 try (BufferedReader in = new BufferedReader(new FileReader(latest))) {
4398 String line;
4399 while ((line = in.readLine()) != null) {
4400 pw.println(line);
4401 }
4402 } catch (IOException e) {
4403 pw.print("Unable to read: ");
4404 pw.print(e);
4405 pw.println();
4406 }
4407 }
4408
4409 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
4410 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
4411 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
4412 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
4413 }
4414
4415 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
4416 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
4417 pw.println(header);
4418
4419 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
4420 dumpPackage);
4421 boolean needSep = printedAnything;
4422
4423 boolean printed = ActivityStackSupervisor.printThisActivity(pw,
4424 mStackSupervisor.getTopResumedActivity(), dumpPackage, needSep,
4425 " ResumedActivity: ");
4426 if (printed) {
4427 printedAnything = true;
4428 needSep = false;
4429 }
4430
4431 if (dumpPackage == null) {
4432 if (needSep) {
4433 pw.println();
4434 }
4435 printedAnything = true;
4436 mStackSupervisor.dump(pw, " ");
4437 }
4438
4439 if (!printedAnything) {
4440 pw.println(" (nothing)");
4441 }
4442 }
4443
4444 void dumpActivityContainersLocked(PrintWriter pw) {
4445 pw.println("ACTIVITY MANAGER STARTER (dumpsys activity containers)");
4446 mStackSupervisor.dumpChildrenNames(pw, " ");
4447 pw.println(" ");
4448 }
4449
4450 void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
4451 pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
4452 getActivityStartController().dump(pw, "", dumpPackage);
4453 }
4454
4455 /**
4456 * There are three things that cmd can be:
4457 * - a flattened component name that matches an existing activity
4458 * - the cmd arg isn't the flattened component name of an existing activity:
4459 * dump all activity whose component contains the cmd as a substring
4460 * - A hex number of the ActivityRecord object instance.
4461 *
4462 * @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
4463 * @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
4464 */
4465 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
4466 int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
4467 ArrayList<ActivityRecord> activities;
4468
4469 synchronized (mGlobalLock) {
4470 activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
4471 dumpFocusedStackOnly);
4472 }
4473
4474 if (activities.size() <= 0) {
4475 return false;
4476 }
4477
4478 String[] newArgs = new String[args.length - opti];
4479 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
4480
4481 TaskRecord lastTask = null;
4482 boolean needSep = false;
4483 for (int i = activities.size() - 1; i >= 0; i--) {
4484 ActivityRecord r = activities.get(i);
4485 if (needSep) {
4486 pw.println();
4487 }
4488 needSep = true;
4489 synchronized (mGlobalLock) {
4490 final TaskRecord task = r.getTask();
4491 if (lastTask != task) {
4492 lastTask = task;
4493 pw.print("TASK "); pw.print(lastTask.affinity);
4494 pw.print(" id="); pw.print(lastTask.taskId);
4495 pw.print(" userId="); pw.println(lastTask.userId);
4496 if (dumpAll) {
4497 lastTask.dump(pw, " ");
4498 }
4499 }
4500 }
4501 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
4502 }
4503 return true;
4504 }
4505
4506 /**
4507 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
4508 * there is a thread associated with the activity.
4509 */
4510 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
4511 final ActivityRecord r, String[] args, boolean dumpAll) {
4512 String innerPrefix = prefix + " ";
4513 synchronized (mGlobalLock) {
4514 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
4515 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
4516 pw.print(" pid=");
4517 if (r.hasProcess()) pw.println(r.app.getPid());
4518 else pw.println("(not running)");
4519 if (dumpAll) {
4520 r.dump(pw, innerPrefix);
4521 }
4522 }
4523 if (r.attachedToProcess()) {
4524 // flush anything that is already in the PrintWriter since the thread is going
4525 // to write to the file descriptor directly
4526 pw.flush();
4527 try {
4528 TransferPipe tp = new TransferPipe();
4529 try {
4530 r.app.getThread().dumpActivity(tp.getWriteFd(),
4531 r.appToken, innerPrefix, args);
4532 tp.go(fd);
4533 } finally {
4534 tp.kill();
4535 }
4536 } catch (IOException e) {
4537 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
4538 } catch (RemoteException e) {
4539 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
4540 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004541 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004542 }
4543
Wale Ogunwalef6733932018-06-27 05:14:34 -07004544 void writeSleepStateToProto(ProtoOutputStream proto) {
4545 for (ActivityTaskManagerInternal.SleepToken st : mStackSupervisor.mSleepTokens) {
4546 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS,
4547 st.toString());
4548 }
4549
4550 if (mRunningVoice != null) {
4551 final long vrToken = proto.start(
4552 ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
4553 proto.write(ActivityManagerServiceDumpProcessesProto.Voice.SESSION,
4554 mRunningVoice.toString());
4555 mVoiceWakeLock.writeToProto(
4556 proto, ActivityManagerServiceDumpProcessesProto.Voice.WAKELOCK);
4557 proto.end(vrToken);
4558 }
4559
4560 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
4561 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN,
4562 mShuttingDown);
4563 mVrController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004564 }
4565
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004566 int getCurrentUserId() {
4567 return mAmInternal.getCurrentUserId();
4568 }
4569
4570 private void enforceNotIsolatedCaller(String caller) {
4571 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4572 throw new SecurityException("Isolated process not allowed to call " + caller);
4573 }
4574 }
4575
Wale Ogunwalef6733932018-06-27 05:14:34 -07004576 public Configuration getConfiguration() {
4577 Configuration ci;
4578 synchronized(mGlobalLock) {
Yunfan Chen75157d72018-07-27 14:47:21 +09004579 ci = new Configuration(getGlobalConfigurationForCallingPid());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004580 ci.userSetLocale = false;
4581 }
4582 return ci;
4583 }
4584
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004585 /**
4586 * Current global configuration information. Contains general settings for the entire system,
4587 * also corresponds to the merged configuration of the default display.
4588 */
4589 Configuration getGlobalConfiguration() {
4590 return mStackSupervisor.getConfiguration();
4591 }
4592
4593 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4594 boolean initLocale) {
4595 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
4596 }
4597
4598 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4599 boolean initLocale, boolean deferResume) {
4600 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
4601 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
4602 UserHandle.USER_NULL, deferResume);
4603 }
4604
4605 void updatePersistentConfiguration(Configuration values, @UserIdInt int userId) {
4606 final long origId = Binder.clearCallingIdentity();
4607 try {
4608 synchronized (mGlobalLock) {
4609 updateConfigurationLocked(values, null, false, true, userId,
4610 false /* deferResume */);
4611 }
4612 } finally {
4613 Binder.restoreCallingIdentity(origId);
4614 }
4615 }
4616
4617 void updateUserConfiguration() {
4618 synchronized (mGlobalLock) {
4619 final Configuration configuration = new Configuration(getGlobalConfiguration());
4620 final int currentUserId = mAmInternal.getCurrentUserId();
4621 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
4622 currentUserId, Settings.System.canWrite(mContext));
4623 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
4624 false /* persistent */, currentUserId, false /* deferResume */);
4625 }
4626 }
4627
4628 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4629 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
4630 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
4631 deferResume, null /* result */);
4632 }
4633
4634 /**
4635 * Do either or both things: (1) change the current configuration, and (2)
4636 * make sure the given activity is running with the (now) current
4637 * configuration. Returns true if the activity has been left running, or
4638 * false if <var>starting</var> is being destroyed to match the new
4639 * configuration.
4640 *
4641 * @param userId is only used when persistent parameter is set to true to persist configuration
4642 * for that particular user
4643 */
4644 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4645 boolean initLocale, boolean persistent, int userId, boolean deferResume,
4646 ActivityTaskManagerService.UpdateConfigurationResult result) {
4647 int changes = 0;
4648 boolean kept = true;
4649
4650 if (mWindowManager != null) {
4651 mWindowManager.deferSurfaceLayout();
4652 }
4653 try {
4654 if (values != null) {
4655 changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
4656 deferResume);
4657 }
4658
4659 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4660 } finally {
4661 if (mWindowManager != null) {
4662 mWindowManager.continueSurfaceLayout();
4663 }
4664 }
4665
4666 if (result != null) {
4667 result.changes = changes;
4668 result.activityRelaunched = !kept;
4669 }
4670 return kept;
4671 }
4672
4673 /**
4674 * Returns true if this configuration change is interesting enough to send an
4675 * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
4676 */
4677 private static boolean isSplitConfigurationChange(int configDiff) {
4678 return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
4679 }
4680
4681 /** Update default (global) configuration and notify listeners about changes. */
4682 private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
4683 boolean persistent, int userId, boolean deferResume) {
4684 mTempConfig.setTo(getGlobalConfiguration());
4685 final int changes = mTempConfig.updateFrom(values);
4686 if (changes == 0) {
4687 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
4688 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
4689 // performDisplayOverrideConfigUpdate in order to send the new display configuration
4690 // (even if there are no actual changes) to unfreeze the window.
4691 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
4692 return 0;
4693 }
4694
4695 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
4696 "Updating global configuration to: " + values);
4697
4698 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
4699 StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
4700 values.colorMode,
4701 values.densityDpi,
4702 values.fontScale,
4703 values.hardKeyboardHidden,
4704 values.keyboard,
4705 values.keyboardHidden,
4706 values.mcc,
4707 values.mnc,
4708 values.navigation,
4709 values.navigationHidden,
4710 values.orientation,
4711 values.screenHeightDp,
4712 values.screenLayout,
4713 values.screenWidthDp,
4714 values.smallestScreenWidthDp,
4715 values.touchscreen,
4716 values.uiMode);
4717
4718
4719 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
4720 final LocaleList locales = values.getLocales();
4721 int bestLocaleIndex = 0;
4722 if (locales.size() > 1) {
4723 if (mSupportedSystemLocales == null) {
4724 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
4725 }
4726 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
4727 }
4728 SystemProperties.set("persist.sys.locale",
4729 locales.get(bestLocaleIndex).toLanguageTag());
4730 LocaleList.setDefault(locales, bestLocaleIndex);
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004731
4732 final Message m = PooledLambda.obtainMessage(
4733 ActivityTaskManagerService::sendLocaleToMountDaemonMsg, this,
4734 locales.get(bestLocaleIndex));
4735 mH.sendMessage(m);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004736 }
4737
Yunfan Chen75157d72018-07-27 14:47:21 +09004738 mTempConfig.seq = increaseConfigurationSeqLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004739
4740 // Update stored global config and notify everyone about the change.
4741 mStackSupervisor.onConfigurationChanged(mTempConfig);
4742
4743 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
4744 // TODO(multi-display): Update UsageEvents#Event to include displayId.
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004745 mUsageStatsInternal.reportConfigurationChange(mTempConfig, mAmInternal.getCurrentUserId());
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004746
4747 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
Wale Ogunwalef6733932018-06-27 05:14:34 -07004748 updateShouldShowDialogsLocked(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004749
4750 AttributeCache ac = AttributeCache.instance();
4751 if (ac != null) {
4752 ac.updateConfiguration(mTempConfig);
4753 }
4754
4755 // Make sure all resources in our process are updated right now, so that anyone who is going
4756 // to retrieve resource values after we return will be sure to get the new ones. This is
4757 // especially important during boot, where the first config change needs to guarantee all
4758 // resources have that config before following boot code is executed.
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004759 mSystemThread.applyConfigurationToResources(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004760
4761 // We need another copy of global config because we're scheduling some calls instead of
4762 // running them in place. We need to be sure that object we send will be handled unchanged.
4763 final Configuration configCopy = new Configuration(mTempConfig);
4764 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004765 final Message msg = PooledLambda.obtainMessage(
4766 ActivityTaskManagerService::sendPutConfigurationForUserMsg,
4767 this, userId, configCopy);
4768 mH.sendMessage(msg);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004769 }
4770
Yunfan Chen34fcc7a2018-10-11 16:26:09 -07004771 for (int i = mPidMap.size() - 1; i >= 0; i--) {
4772 WindowProcessController app = mPidMap.get(mPidMap.keyAt(i));
4773 if (DEBUG_CONFIGURATION) {
4774 Slog.v(TAG_CONFIGURATION, "Update process config of "
4775 + app.mName + " to new config " + configCopy);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004776 }
Yunfan Chen34fcc7a2018-10-11 16:26:09 -07004777 app.onConfigurationChanged(configCopy);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004778 }
4779
4780 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
4781 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
4782 | Intent.FLAG_RECEIVER_FOREGROUND
4783 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4784 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4785 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4786 UserHandle.USER_ALL);
4787 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
4788 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
4789 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
4790 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
4791 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4792 if (initLocale || !mAm.mProcessesReady) {
4793 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
4794 }
4795 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4796 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4797 UserHandle.USER_ALL);
4798 }
4799
4800 // Send a broadcast to PackageInstallers if the configuration change is interesting
4801 // for the purposes of installing additional splits.
4802 if (!initLocale && isSplitConfigurationChange(changes)) {
4803 intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
4804 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
4805 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
4806
4807 // Typically only app stores will have this permission.
4808 String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES };
4809 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions,
4810 OP_NONE, null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
4811 }
4812
4813 // Override configuration of the default display duplicates global config, so we need to
4814 // update it also. This will also notify WindowManager about changes.
4815 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
4816 DEFAULT_DISPLAY);
4817
4818 return changes;
4819 }
4820
4821 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
4822 boolean deferResume, int displayId) {
4823 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
4824 displayId, null /* result */);
4825 }
4826
4827 /**
4828 * Updates override configuration specific for the selected display. If no config is provided,
4829 * new one will be computed in WM based on current display info.
4830 */
4831 boolean updateDisplayOverrideConfigurationLocked(Configuration values,
4832 ActivityRecord starting, boolean deferResume, int displayId,
4833 ActivityTaskManagerService.UpdateConfigurationResult result) {
4834 int changes = 0;
4835 boolean kept = true;
4836
4837 if (mWindowManager != null) {
4838 mWindowManager.deferSurfaceLayout();
4839 }
4840 try {
4841 if (values != null) {
4842 if (displayId == DEFAULT_DISPLAY) {
4843 // Override configuration of the default display duplicates global config, so
4844 // we're calling global config update instead for default display. It will also
4845 // apply the correct override config.
4846 changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
4847 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
4848 } else {
4849 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
4850 }
4851 }
4852
4853 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4854 } finally {
4855 if (mWindowManager != null) {
4856 mWindowManager.continueSurfaceLayout();
4857 }
4858 }
4859
4860 if (result != null) {
4861 result.changes = changes;
4862 result.activityRelaunched = !kept;
4863 }
4864 return kept;
4865 }
4866
4867 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
4868 int displayId) {
4869 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
4870 final int changes = mTempConfig.updateFrom(values);
4871 if (changes != 0) {
4872 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
4873 + mTempConfig + " for displayId=" + displayId);
4874 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
4875
4876 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
4877 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004878 mAppWarnings.onDensityChanged();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004879
4880 mAm.killAllBackgroundProcessesExcept(N,
4881 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
4882 }
4883 }
4884
4885 // Update the configuration with WM first and check if any of the stacks need to be resized
4886 // due to the configuration change. If so, resize the stacks now and do any relaunches if
4887 // necessary. This way we don't need to relaunch again afterwards in
4888 // ensureActivityConfiguration().
4889 if (mWindowManager != null) {
4890 final int[] resizedStacks =
4891 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
4892 if (resizedStacks != null) {
4893 for (int stackId : resizedStacks) {
4894 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
4895 }
4896 }
4897 }
4898
4899 return changes;
4900 }
4901
Wale Ogunwalef6733932018-06-27 05:14:34 -07004902 private void updateEventDispatchingLocked(boolean booted) {
4903 mWindowManager.setEventDispatching(booted && !mShuttingDown);
4904 }
4905
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004906 private void sendPutConfigurationForUserMsg(int userId, Configuration config) {
4907 final ContentResolver resolver = mContext.getContentResolver();
4908 Settings.System.putConfigurationForUser(resolver, config, userId);
4909 }
4910
4911 private void sendLocaleToMountDaemonMsg(Locale l) {
4912 try {
4913 IBinder service = ServiceManager.getService("mount");
4914 IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
4915 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
4916 storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
4917 } catch (RemoteException e) {
4918 Log.e(TAG, "Error storing locale for decryption UI", e);
4919 }
4920 }
4921
4922 boolean isActivityStartsLoggingEnabled() {
4923 return mAmInternal.isActivityStartsLoggingEnabled();
4924 }
4925
Wale Ogunwalef6733932018-06-27 05:14:34 -07004926 void enableScreenAfterBoot(boolean booted) {
4927 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4928 SystemClock.uptimeMillis());
4929 mWindowManager.enableScreenAfterBoot();
4930
4931 synchronized (mGlobalLock) {
4932 updateEventDispatchingLocked(booted);
4933 }
4934 }
4935
4936 boolean canShowErrorDialogs() {
4937 return mShowDialogs && !mSleeping && !mShuttingDown
4938 && !mKeyguardController.isKeyguardOrAodShowing(DEFAULT_DISPLAY)
4939 && !hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
Wale Ogunwale86b74462018-07-02 08:42:43 -07004940 mAmInternal.getCurrentUserId())
Wale Ogunwalef6733932018-06-27 05:14:34 -07004941 && !(UserManager.isDeviceInDemoMode(mContext)
Wale Ogunwale86b74462018-07-02 08:42:43 -07004942 && mAmInternal.getCurrentUser().isDemo());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004943 }
4944
Wale Ogunwale906f9c62018-07-23 11:23:44 -07004945 static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
4946 if (r == null || !r.hasProcess()) {
4947 return KEY_DISPATCHING_TIMEOUT_MS;
4948 }
4949 return getInputDispatchingTimeoutLocked(r.app);
4950 }
4951
4952 private static long getInputDispatchingTimeoutLocked(WindowProcessController r) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07004953 return r != null ? r.getInputDispatchingTimeout() : KEY_DISPATCHING_TIMEOUT_MS;
Wale Ogunwale906f9c62018-07-23 11:23:44 -07004954 }
4955
Wale Ogunwalef6733932018-06-27 05:14:34 -07004956 /**
4957 * Decide based on the configuration whether we should show the ANR,
4958 * crash, etc dialogs. The idea is that if there is no affordance to
4959 * press the on-screen buttons, or the user experience would be more
4960 * greatly impacted than the crash itself, we shouldn't show the dialog.
4961 *
4962 * A thought: SystemUI might also want to get told about this, the Power
4963 * dialog / global actions also might want different behaviors.
4964 */
4965 private void updateShouldShowDialogsLocked(Configuration config) {
4966 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
4967 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
4968 && config.navigation == Configuration.NAVIGATION_NONAV);
4969 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
4970 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
4971 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
4972 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
4973 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
4974 final boolean hideDialogsSet = Settings.Global.getInt(mContext.getContentResolver(),
4975 HIDE_ERROR_DIALOGS, 0) != 0;
4976 mShowDialogs = inputMethodExists && uiModeSupportsDialogs && !hideDialogsSet;
4977 }
4978
4979 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
4980 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
4981 FONT_SCALE, 1.0f, userId);
4982
4983 synchronized (this) {
4984 if (getGlobalConfiguration().fontScale == scaleFactor) {
4985 return;
4986 }
4987
4988 final Configuration configuration
4989 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
4990 configuration.fontScale = scaleFactor;
4991 updatePersistentConfiguration(configuration, userId);
4992 }
4993 }
4994
4995 // Actually is sleeping or shutting down or whatever else in the future
4996 // is an inactive state.
4997 boolean isSleepingOrShuttingDownLocked() {
4998 return isSleepingLocked() || mShuttingDown;
4999 }
5000
5001 boolean isSleepingLocked() {
5002 return mSleeping;
5003 }
5004
Riddle Hsu16567132018-08-16 21:37:47 +08005005 /** Update AMS states when an activity is resumed. */
Wale Ogunwalef6733932018-06-27 05:14:34 -07005006 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
5007 final TaskRecord task = r.getTask();
5008 if (task.isActivityTypeStandard()) {
5009 if (mCurAppTimeTracker != r.appTimeTracker) {
5010 // We are switching app tracking. Complete the current one.
5011 if (mCurAppTimeTracker != null) {
5012 mCurAppTimeTracker.stop();
5013 mH.obtainMessage(
5014 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
5015 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
5016 mCurAppTimeTracker = null;
5017 }
5018 if (r.appTimeTracker != null) {
5019 mCurAppTimeTracker = r.appTimeTracker;
5020 startTimeTrackingFocusedActivityLocked();
5021 }
5022 } else {
5023 startTimeTrackingFocusedActivityLocked();
5024 }
5025 } else {
5026 r.appTimeTracker = null;
5027 }
5028 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
5029 // TODO: Probably not, because we don't want to resume voice on switching
5030 // back to this activity
5031 if (task.voiceInteractor != null) {
5032 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
5033 } else {
5034 finishRunningVoiceLocked();
5035
5036 if (mLastResumedActivity != null) {
5037 final IVoiceInteractionSession session;
5038
5039 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
5040 if (lastResumedActivityTask != null
5041 && lastResumedActivityTask.voiceSession != null) {
5042 session = lastResumedActivityTask.voiceSession;
5043 } else {
5044 session = mLastResumedActivity.voiceSession;
5045 }
5046
5047 if (session != null) {
5048 // We had been in a voice interaction session, but now focused has
5049 // move to something different. Just finish the session, we can't
5050 // return to it and retain the proper state and synchronization with
5051 // the voice interaction service.
5052 finishVoiceTask(session);
5053 }
5054 }
5055 }
5056
5057 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
5058 mAmInternal.sendForegroundProfileChanged(r.userId);
5059 }
5060 updateResumedAppTrace(r);
5061 mLastResumedActivity = r;
5062
Tiger Huang1e5b10a2018-07-30 20:19:51 +08005063 r.getDisplay().setFocusedApp(r, true);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005064
5065 applyUpdateLockStateLocked(r);
5066 applyUpdateVrModeLocked(r);
5067
5068 EventLogTags.writeAmSetResumedActivity(
5069 r == null ? -1 : r.userId,
5070 r == null ? "NULL" : r.shortComponentName,
5071 reason);
5072 }
5073
5074 ActivityTaskManagerInternal.SleepToken acquireSleepToken(String tag, int displayId) {
5075 synchronized (mGlobalLock) {
5076 final ActivityTaskManagerInternal.SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
5077 updateSleepIfNeededLocked();
5078 return token;
5079 }
5080 }
5081
5082 void updateSleepIfNeededLocked() {
5083 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
5084 final boolean wasSleeping = mSleeping;
5085 boolean updateOomAdj = false;
5086
5087 if (!shouldSleep) {
5088 // If wasSleeping is true, we need to wake up activity manager state from when
5089 // we started sleeping. In either case, we need to apply the sleep tokens, which
5090 // will wake up stacks or put them to sleep as appropriate.
5091 if (wasSleeping) {
5092 mSleeping = false;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07005093 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
5094 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__AWAKE);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005095 startTimeTrackingFocusedActivityLocked();
5096 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
5097 mStackSupervisor.comeOutOfSleepIfNeededLocked();
5098 }
5099 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
5100 if (wasSleeping) {
5101 updateOomAdj = true;
5102 }
5103 } else if (!mSleeping && shouldSleep) {
5104 mSleeping = true;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07005105 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
5106 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__ASLEEP);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005107 if (mCurAppTimeTracker != null) {
5108 mCurAppTimeTracker.stop();
5109 }
5110 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
5111 mStackSupervisor.goingToSleepLocked();
5112 updateResumedAppTrace(null /* resumed */);
5113 updateOomAdj = true;
5114 }
5115 if (updateOomAdj) {
5116 mH.post(mAmInternal::updateOomAdj);
5117 }
5118 }
5119
5120 void updateOomAdj() {
5121 mH.post(mAmInternal::updateOomAdj);
5122 }
5123
Wale Ogunwale53783742018-09-16 10:21:51 -07005124 void updateCpuStats() {
5125 mH.post(mAmInternal::updateCpuStats);
5126 }
5127
5128 void updateUsageStats(ActivityRecord component, boolean resumed) {
5129 final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::updateUsageStats,
5130 mAmInternal, component.realActivity, component.app.mUid, component.userId, resumed);
5131 mH.sendMessage(m);
5132 }
5133
5134 void setBooting(boolean booting) {
5135 mAmInternal.setBooting(booting);
5136 }
5137
5138 boolean isBooting() {
5139 return mAmInternal.isBooting();
5140 }
5141
5142 void setBooted(boolean booted) {
5143 mAmInternal.setBooted(booted);
5144 }
5145
5146 boolean isBooted() {
5147 return mAmInternal.isBooted();
5148 }
5149
5150 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
5151 mH.post(() -> {
5152 if (finishBooting) {
5153 mAmInternal.finishBooting();
5154 }
5155 if (enableScreen) {
5156 mInternal.enableScreenAfterBoot(isBooted());
5157 }
5158 });
5159 }
5160
5161 void setHeavyWeightProcess(ActivityRecord root) {
5162 mHeavyWeightProcess = root.app;
5163 final Message m = PooledLambda.obtainMessage(
5164 ActivityTaskManagerService::postHeavyWeightProcessNotification, this,
5165 root.app, root.intent, root.userId);
5166 mH.sendMessage(m);
5167 }
5168
5169 void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
5170 if (mHeavyWeightProcess == null || mHeavyWeightProcess != proc) {
5171 return;
5172 }
5173
5174 mHeavyWeightProcess = null;
5175 final Message m = PooledLambda.obtainMessage(
5176 ActivityTaskManagerService::cancelHeavyWeightProcessNotification, this,
5177 proc.mUserId);
5178 mH.sendMessage(m);
5179 }
5180
5181 private void cancelHeavyWeightProcessNotification(int userId) {
5182 final INotificationManager inm = NotificationManager.getService();
5183 if (inm == null) {
5184 return;
5185 }
5186 try {
5187 inm.cancelNotificationWithTag("android", null,
5188 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, userId);
5189 } catch (RuntimeException e) {
5190 Slog.w(TAG, "Error canceling notification for service", e);
5191 } catch (RemoteException e) {
5192 }
5193
5194 }
5195
5196 private void postHeavyWeightProcessNotification(
5197 WindowProcessController proc, Intent intent, int userId) {
5198 if (proc == null) {
5199 return;
5200 }
5201
5202 final INotificationManager inm = NotificationManager.getService();
5203 if (inm == null) {
5204 return;
5205 }
5206
5207 try {
5208 Context context = mContext.createPackageContext(proc.mInfo.packageName, 0);
5209 String text = mContext.getString(R.string.heavy_weight_notification,
5210 context.getApplicationInfo().loadLabel(context.getPackageManager()));
5211 Notification notification =
5212 new Notification.Builder(context,
5213 SystemNotificationChannels.HEAVY_WEIGHT_APP)
5214 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
5215 .setWhen(0)
5216 .setOngoing(true)
5217 .setTicker(text)
5218 .setColor(mContext.getColor(
5219 com.android.internal.R.color.system_notification_accent_color))
5220 .setContentTitle(text)
5221 .setContentText(
5222 mContext.getText(R.string.heavy_weight_notification_detail))
5223 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
5224 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
5225 new UserHandle(userId)))
5226 .build();
5227 try {
5228 inm.enqueueNotificationWithTag("android", "android", null,
5229 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, notification, userId);
5230 } catch (RuntimeException e) {
5231 Slog.w(TAG, "Error showing notification for heavy-weight app", e);
5232 } catch (RemoteException e) {
5233 }
5234 } catch (PackageManager.NameNotFoundException e) {
5235 Slog.w(TAG, "Unable to create context for heavy notification", e);
5236 }
5237
5238 }
5239
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07005240 IIntentSender getIntentSenderLocked(int type, String packageName, int callingUid, int userId,
5241 IBinder token, String resultWho, int requestCode, Intent[] intents,
5242 String[] resolvedTypes, int flags, Bundle bOptions) {
5243
5244 ActivityRecord activity = null;
5245 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5246 activity = ActivityRecord.isInStackLocked(token);
5247 if (activity == null) {
5248 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
5249 return null;
5250 }
5251 if (activity.finishing) {
5252 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
5253 return null;
5254 }
5255 }
5256
5257 final PendingIntentRecord rec = mPendingIntentController.getIntentSender(type, packageName,
5258 callingUid, userId, token, resultWho, requestCode, intents, resolvedTypes, flags,
5259 bOptions);
5260 final boolean noCreate = (flags & PendingIntent.FLAG_NO_CREATE) != 0;
5261 if (noCreate) {
5262 return rec;
5263 }
5264 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5265 if (activity.pendingResults == null) {
5266 activity.pendingResults = new HashSet<>();
5267 }
5268 activity.pendingResults.add(rec.ref);
5269 }
5270 return rec;
5271 }
5272
Andrii Kulian52d255c2018-07-13 11:32:19 -07005273 // TODO(b/111541062): Update app time tracking to make it aware of multiple resumed activities
Wale Ogunwalef6733932018-06-27 05:14:34 -07005274 private void startTimeTrackingFocusedActivityLocked() {
Andrii Kulian52d255c2018-07-13 11:32:19 -07005275 final ActivityRecord resumedActivity = mStackSupervisor.getTopResumedActivity();
Wale Ogunwalef6733932018-06-27 05:14:34 -07005276 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
5277 mCurAppTimeTracker.start(resumedActivity.packageName);
5278 }
5279 }
5280
5281 private void updateResumedAppTrace(@Nullable ActivityRecord resumed) {
5282 if (mTracedResumedActivity != null) {
5283 Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER,
5284 constructResumedTraceName(mTracedResumedActivity.packageName), 0);
5285 }
5286 if (resumed != null) {
5287 Trace.asyncTraceBegin(TRACE_TAG_ACTIVITY_MANAGER,
5288 constructResumedTraceName(resumed.packageName), 0);
5289 }
5290 mTracedResumedActivity = resumed;
5291 }
5292
5293 private String constructResumedTraceName(String packageName) {
5294 return "focused app: " + packageName;
5295 }
5296
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005297 /** Helper method that requests bounds from WM and applies them to stack. */
5298 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
5299 final Rect newStackBounds = new Rect();
5300 final ActivityStack stack = mStackSupervisor.getStack(stackId);
5301
5302 // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
5303 if (stack == null) {
5304 final StringWriter writer = new StringWriter();
5305 final PrintWriter printWriter = new PrintWriter(writer);
5306 mStackSupervisor.dumpDisplays(printWriter);
5307 printWriter.flush();
5308
5309 Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
5310 }
5311
5312 stack.getBoundsForNewConfiguration(newStackBounds);
5313 mStackSupervisor.resizeStackLocked(
5314 stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
5315 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
5316 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
5317 }
5318
5319 /** Applies latest configuration and/or visibility updates if needed. */
5320 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
5321 boolean kept = true;
Andrii Kulian5f750bc2018-07-17 08:57:23 -07005322 final ActivityStack mainStack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005323 // mainStack is null during startup.
5324 if (mainStack != null) {
5325 if (changes != 0 && starting == null) {
5326 // If the configuration changed, and the caller is not already
5327 // in the process of starting an activity, then find the top
5328 // activity to check if its configuration needs to change.
5329 starting = mainStack.topRunningActivityLocked();
5330 }
5331
5332 if (starting != null) {
5333 kept = starting.ensureActivityConfiguration(changes,
5334 false /* preserveWindow */);
5335 // And we need to make sure at this point that all other activities
5336 // are made visible with the correct configuration.
5337 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
5338 !PRESERVE_WINDOWS);
5339 }
5340 }
5341
5342 return kept;
5343 }
5344
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005345 void scheduleAppGcsLocked() {
5346 mH.post(() -> mAmInternal.scheduleAppGcs());
5347 }
5348
Wale Ogunwale53783742018-09-16 10:21:51 -07005349 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
5350 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
5351 }
5352
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005353 /**
5354 * Returns the PackageManager. Used by classes hosted by {@link ActivityTaskManagerService}. The
5355 * PackageManager could be unavailable at construction time and therefore needs to be accessed
5356 * on demand.
5357 */
5358 IPackageManager getPackageManager() {
5359 return AppGlobals.getPackageManager();
5360 }
5361
5362 PackageManagerInternal getPackageManagerInternalLocked() {
5363 if (mPmInternal == null) {
5364 mPmInternal = LocalServices.getService(PackageManagerInternal.class);
5365 }
5366 return mPmInternal;
5367 }
5368
Wale Ogunwale008163e2018-07-23 23:11:08 -07005369 AppWarnings getAppWarningsLocked() {
5370 return mAppWarnings;
5371 }
5372
Wale Ogunwale214f3482018-10-04 11:00:47 -07005373 Intent getHomeIntent() {
5374 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
5375 intent.setComponent(mTopComponent);
5376 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
5377 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5378 intent.addCategory(Intent.CATEGORY_HOME);
5379 }
5380 return intent;
5381 }
5382
5383 /**
5384 * This starts home activity on displays that can have system decorations and only if the
5385 * home activity can have multiple instances.
5386 */
5387 boolean startHomeActivityLocked(int userId, String reason, int displayId) {
5388 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL && mTopAction == null) {
5389 // We are running in factory test mode, but unable to find the factory test app, so just
5390 // sit around displaying the error message and don't try to start anything.
5391 return false;
5392 }
5393
5394 final Intent intent = getHomeIntent();
5395 ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
5396 if (aInfo != null) {
5397 intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
5398 // Don't do this if the home app is currently being instrumented.
5399 aInfo = new ActivityInfo(aInfo);
5400 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
5401 WindowProcessController app =
5402 getProcessController(aInfo.processName, aInfo.applicationInfo.uid);
5403 if (app == null || !app.isInstrumenting()) {
5404 intent.setFlags(intent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
5405 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
5406 // For ANR debugging to verify if the user activity is the one that actually
5407 // launched.
5408 final String myReason = reason + ":" + userId + ":" + resolvedUserId;
5409 getActivityStartController().startHomeActivity(intent, aInfo, myReason, displayId);
5410 }
5411 } else {
5412 Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
5413 }
5414
5415 return true;
5416 }
5417
5418 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
5419 ActivityInfo ai = null;
5420 final ComponentName comp = intent.getComponent();
5421 try {
5422 if (comp != null) {
5423 // Factory test.
5424 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
5425 } else {
5426 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
5427 intent,
5428 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
5429 flags, userId);
5430
5431 if (info != null) {
5432 ai = info.activityInfo;
5433 }
5434 }
5435 } catch (RemoteException e) {
5436 // ignore
5437 }
5438
5439 return ai;
5440 }
5441
5442 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
5443 if (info == null) return null;
5444 ApplicationInfo newInfo = new ApplicationInfo(info);
5445 newInfo.initForUser(userId);
5446 return newInfo;
5447 }
5448
5449 private WindowProcessController getProcessController(String processName, int uid) {
5450 if (uid == SYSTEM_UID) {
5451 // The system gets to run in any process. If there are multiple processes with the same
5452 // uid, just pick the first (this should never happen).
5453 final SparseArray<WindowProcessController> procs =
5454 mProcessNames.getMap().get(processName);
5455 if (procs == null) return null;
5456 final int procCount = procs.size();
5457 for (int i = 0; i < procCount; i++) {
5458 final int procUid = procs.keyAt(i);
5459 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
5460 // Don't use an app process or different user process for system component.
5461 continue;
5462 }
5463 return procs.valueAt(i);
5464 }
5465 }
5466
5467 return mProcessNames.get(processName, uid);
5468 }
5469
Wale Ogunwale342fbe92018-10-09 08:44:10 -07005470 WindowProcessController getProcessController(IApplicationThread thread) {
5471 if (thread == null) {
5472 return null;
5473 }
5474
5475 final IBinder threadBinder = thread.asBinder();
5476 final ArrayMap<String, SparseArray<WindowProcessController>> pmap = mProcessNames.getMap();
5477 for (int i = pmap.size()-1; i >= 0; i--) {
5478 final SparseArray<WindowProcessController> procs = pmap.valueAt(i);
5479 for (int j = procs.size() - 1; j >= 0; j--) {
5480 final WindowProcessController proc = procs.valueAt(j);
5481 if (proc.hasThread() && proc.getThread().asBinder() == threadBinder) {
5482 return proc;
5483 }
5484 }
5485 }
5486
5487 return null;
5488 }
5489
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005490 void logAppTooSlow(WindowProcessController app, long startTime, String msg) {
5491 if (true || Build.IS_USER) {
5492 return;
5493 }
5494
5495 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5496 StrictMode.allowThreadDiskWrites();
5497 try {
5498 File tracesDir = new File("/data/anr");
5499 File tracesFile = null;
5500 try {
5501 tracesFile = File.createTempFile("app_slow", null, tracesDir);
5502
5503 StringBuilder sb = new StringBuilder();
5504 Time tobj = new Time();
5505 tobj.set(System.currentTimeMillis());
5506 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5507 sb.append(": ");
5508 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5509 sb.append(" since ");
5510 sb.append(msg);
5511 FileOutputStream fos = new FileOutputStream(tracesFile);
5512 fos.write(sb.toString().getBytes());
5513 if (app == null) {
5514 fos.write("\n*** No application process!".getBytes());
5515 }
5516 fos.close();
5517 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5518 } catch (IOException e) {
5519 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesFile, e);
5520 return;
5521 }
5522
5523 if (app != null && app.getPid() > 0) {
5524 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5525 firstPids.add(app.getPid());
5526 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, null, null);
5527 }
5528
5529 File lastTracesFile = null;
5530 File curTracesFile = null;
5531 for (int i=9; i>=0; i--) {
5532 String name = String.format(Locale.US, "slow%02d.txt", i);
5533 curTracesFile = new File(tracesDir, name);
5534 if (curTracesFile.exists()) {
5535 if (lastTracesFile != null) {
5536 curTracesFile.renameTo(lastTracesFile);
5537 } else {
5538 curTracesFile.delete();
5539 }
5540 }
5541 lastTracesFile = curTracesFile;
5542 }
5543 tracesFile.renameTo(curTracesFile);
5544 } finally {
5545 StrictMode.setThreadPolicy(oldPolicy);
5546 }
5547 }
5548
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005549 final class H extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005550 static final int REPORT_TIME_TRACKER_MSG = 1;
Wale Ogunwale98875612018-10-12 07:53:02 -07005551 static final int FIRST_ACTIVITY_STACK_MSG = 100;
5552 static final int FIRST_SUPERVISOR_STACK_MSG = 200;
Wale Ogunwalef6733932018-06-27 05:14:34 -07005553
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005554 public H(Looper looper) {
5555 super(looper, null, true);
5556 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005557
5558 @Override
5559 public void handleMessage(Message msg) {
5560 switch (msg.what) {
5561 case REPORT_TIME_TRACKER_MSG: {
5562 AppTimeTracker tracker = (AppTimeTracker) msg.obj;
5563 tracker.deliverResult(mContext);
5564 } break;
5565 }
5566 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005567 }
5568
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005569 final class UiHandler extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005570 static final int DISMISS_DIALOG_UI_MSG = 1;
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005571
5572 public UiHandler() {
5573 super(com.android.server.UiThread.get().getLooper(), null, true);
5574 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005575
5576 @Override
5577 public void handleMessage(Message msg) {
5578 switch (msg.what) {
5579 case DISMISS_DIALOG_UI_MSG: {
5580 final Dialog d = (Dialog) msg.obj;
5581 d.dismiss();
5582 break;
5583 }
5584 }
5585 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005586 }
5587
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005588 final class LocalService extends ActivityTaskManagerInternal {
5589 @Override
5590 public SleepToken acquireSleepToken(String tag, int displayId) {
5591 Preconditions.checkNotNull(tag);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005592 return ActivityTaskManagerService.this.acquireSleepToken(tag, displayId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005593 }
5594
5595 @Override
5596 public ComponentName getHomeActivityForUser(int userId) {
5597 synchronized (mGlobalLock) {
Louis Changbd48dca2018-08-29 17:44:34 +08005598 ActivityRecord homeActivity =
5599 mStackSupervisor.getDefaultDisplayHomeActivityForUser(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005600 return homeActivity == null ? null : homeActivity.realActivity;
5601 }
5602 }
5603
5604 @Override
5605 public void onLocalVoiceInteractionStarted(IBinder activity,
5606 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
5607 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005608 onLocalVoiceInteractionStartedLocked(activity, voiceSession, voiceInteractor);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005609 }
5610 }
5611
5612 @Override
5613 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
5614 synchronized (mGlobalLock) {
5615 mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
5616 reasons, timestamp);
5617 }
5618 }
5619
5620 @Override
5621 public void notifyAppTransitionFinished() {
5622 synchronized (mGlobalLock) {
5623 mStackSupervisor.notifyAppTransitionDone();
5624 }
5625 }
5626
5627 @Override
5628 public void notifyAppTransitionCancelled() {
5629 synchronized (mGlobalLock) {
5630 mStackSupervisor.notifyAppTransitionDone();
5631 }
5632 }
5633
5634 @Override
5635 public List<IBinder> getTopVisibleActivities() {
5636 synchronized (mGlobalLock) {
5637 return mStackSupervisor.getTopVisibleActivities();
5638 }
5639 }
5640
5641 @Override
5642 public void notifyDockedStackMinimizedChanged(boolean minimized) {
5643 synchronized (mGlobalLock) {
5644 mStackSupervisor.setDockedStackMinimized(minimized);
5645 }
5646 }
5647
5648 @Override
5649 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
5650 Bundle bOptions) {
5651 Preconditions.checkNotNull(intents, "intents");
5652 final String[] resolvedTypes = new String[intents.length];
5653
5654 // UID of the package on user userId.
5655 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
5656 // packageUid may not be initialized.
5657 int packageUid = 0;
5658 final long ident = Binder.clearCallingIdentity();
5659
5660 try {
5661 for (int i = 0; i < intents.length; i++) {
5662 resolvedTypes[i] =
5663 intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
5664 }
5665
5666 packageUid = AppGlobals.getPackageManager().getPackageUid(
5667 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
5668 } catch (RemoteException e) {
5669 // Shouldn't happen.
5670 } finally {
5671 Binder.restoreCallingIdentity(ident);
5672 }
5673
5674 synchronized (mGlobalLock) {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07005675 return getActivityStartController().startActivitiesInPackage(
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005676 packageUid, packageName,
5677 intents, resolvedTypes, null /* resultTo */,
5678 SafeActivityOptions.fromBundle(bOptions), userId,
Michal Karpinski201bc0c2018-07-20 15:32:00 +01005679 false /* validateIncomingUser */, null /* originatingPendingIntent */);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005680 }
5681 }
5682
5683 @Override
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07005684 public int startActivitiesInPackage(int uid, String callingPackage, Intent[] intents,
5685 String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, int userId,
5686 boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent) {
5687 synchronized (mGlobalLock) {
5688 return getActivityStartController().startActivitiesInPackage(uid, callingPackage,
5689 intents, resolvedTypes, resultTo, options, userId, validateIncomingUser,
5690 originatingPendingIntent);
5691 }
5692 }
5693
5694 @Override
5695 public int startActivityInPackage(int uid, int realCallingPid, int realCallingUid,
5696 String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
5697 String resultWho, int requestCode, int startFlags, SafeActivityOptions options,
5698 int userId, TaskRecord inTask, String reason, boolean validateIncomingUser,
5699 PendingIntentRecord originatingPendingIntent) {
5700 synchronized (mGlobalLock) {
5701 return getActivityStartController().startActivityInPackage(uid, realCallingPid,
5702 realCallingUid, callingPackage, intent, resolvedType, resultTo, resultWho,
5703 requestCode, startFlags, options, userId, inTask, reason,
5704 validateIncomingUser, originatingPendingIntent);
5705 }
5706 }
5707
5708 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005709 public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
5710 Intent intent, Bundle options, int userId) {
5711 return ActivityTaskManagerService.this.startActivityAsUser(
5712 caller, callerPacakge, intent,
5713 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
5714 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
5715 false /*validateIncomingUser*/);
5716 }
5717
5718 @Override
5719 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
5720 synchronized (mGlobalLock) {
5721
5722 // We might change the visibilities here, so prepare an empty app transition which
5723 // might be overridden later if we actually change visibilities.
5724 final boolean wasTransitionSet =
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005725 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005726 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005727 mWindowManager.prepareAppTransition(TRANSIT_NONE,
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005728 false /* alwaysKeepCurrent */);
5729 }
5730 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5731
5732 // If there was a transition set already we don't want to interfere with it as we
5733 // might be starting it too early.
5734 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005735 mWindowManager.executeAppTransition();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005736 }
5737 }
5738 if (callback != null) {
5739 callback.run();
5740 }
5741 }
5742
5743 @Override
5744 public void notifyKeyguardTrustedChanged() {
5745 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005746 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005747 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5748 }
5749 }
5750 }
5751
5752 /**
5753 * Called after virtual display Id is updated by
5754 * {@link com.android.server.vr.Vr2dDisplay} with a specific
5755 * {@param vrVr2dDisplayId}.
5756 */
5757 @Override
5758 public void setVr2dDisplayId(int vr2dDisplayId) {
5759 if (DEBUG_STACK) Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
5760 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005761 mVr2dDisplayId = vr2dDisplayId;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005762 }
5763 }
5764
5765 @Override
5766 public void setFocusedActivity(IBinder token) {
5767 synchronized (mGlobalLock) {
5768 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
5769 if (r == null) {
5770 throw new IllegalArgumentException(
5771 "setFocusedActivity: No activity record matching token=" + token);
5772 }
Louis Chang19443452018-10-09 12:10:21 +08005773 if (r.moveFocusableActivityToTop("setFocusedActivity")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08005774 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005775 }
5776 }
5777 }
5778
5779 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005780 public void registerScreenObserver(ScreenObserver observer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005781 mScreenObservers.add(observer);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005782 }
5783
5784 @Override
5785 public boolean isCallerRecents(int callingUid) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005786 return getRecentTasks().isCallerRecents(callingUid);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005787 }
5788
5789 @Override
5790 public boolean isRecentsComponentHomeActivity(int userId) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005791 return getRecentTasks().isRecentsComponentHomeActivity(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005792 }
5793
5794 @Override
5795 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
5796 ActivityTaskManagerService.this.cancelRecentsAnimation(restoreHomeStackPosition);
5797 }
5798
5799 @Override
5800 public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005801 ActivityTaskManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005802 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005803
5804 @Override
5805 public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
5806 synchronized (mGlobalLock) {
5807 mActiveVoiceInteractionServiceComponent = component;
5808 }
5809 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005810
5811 @Override
5812 public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
5813 if (!mAmInternal.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
5814 return;
5815 }
5816 synchronized (mGlobalLock) {
5817 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
5818 if (types == null) {
5819 if (uid < 0) {
5820 return;
5821 }
5822 types = new ArrayMap<>();
5823 mAllowAppSwitchUids.put(userId, types);
5824 }
5825 if (uid < 0) {
5826 types.remove(type);
5827 } else {
5828 types.put(type, uid);
5829 }
5830 }
5831 }
5832
5833 @Override
5834 public void onUserStopped(int userId) {
5835 synchronized (mGlobalLock) {
5836 getRecentTasks().unloadUserDataFromMemoryLocked(userId);
5837 mAllowAppSwitchUids.remove(userId);
5838 }
5839 }
5840
5841 @Override
5842 public boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
5843 synchronized (mGlobalLock) {
5844 return ActivityTaskManagerService.this.isGetTasksAllowed(
5845 caller, callingPid, callingUid);
5846 }
5847 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005848
5849 @Override
5850 public void onProcessAdded(WindowProcessController proc) {
5851 synchronized (mGlobalLock) {
5852 mProcessNames.put(proc.mName, proc.mUid, proc);
5853 }
5854 }
5855
5856 @Override
5857 public void onProcessRemoved(String name, int uid) {
5858 synchronized (mGlobalLock) {
5859 mProcessNames.remove(name, uid);
5860 }
5861 }
5862
5863 @Override
5864 public void onCleanUpApplicationRecord(WindowProcessController proc) {
5865 synchronized (mGlobalLock) {
5866 if (proc == mHomeProcess) {
5867 mHomeProcess = null;
5868 }
5869 if (proc == mPreviousProcess) {
5870 mPreviousProcess = null;
5871 }
5872 }
5873 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005874
5875 @Override
5876 public int getTopProcessState() {
5877 synchronized (mGlobalLock) {
5878 return mTopProcessState;
5879 }
5880 }
5881
5882 @Override
Wale Ogunwale53783742018-09-16 10:21:51 -07005883 public boolean isHeavyWeightProcess(WindowProcessController proc) {
5884 synchronized (mGlobalLock) {
5885 return proc == mHeavyWeightProcess;
5886 }
5887 }
5888
5889 @Override
5890 public void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
5891 synchronized (mGlobalLock) {
5892 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(proc);
5893 }
5894 }
5895
5896 @Override
5897 public void finishHeavyWeightApp() {
5898 synchronized (mGlobalLock) {
5899 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(
5900 mHeavyWeightProcess);
5901 }
5902 }
5903
5904 @Override
Wale Ogunwalef6733932018-06-27 05:14:34 -07005905 public boolean isSleeping() {
5906 synchronized (mGlobalLock) {
5907 return isSleepingLocked();
5908 }
5909 }
5910
5911 @Override
5912 public boolean isShuttingDown() {
5913 synchronized (mGlobalLock) {
5914 return mShuttingDown;
5915 }
5916 }
5917
5918 @Override
5919 public boolean shuttingDown(boolean booted, int timeout) {
5920 synchronized (mGlobalLock) {
5921 mShuttingDown = true;
5922 mStackSupervisor.prepareForShutdownLocked();
5923 updateEventDispatchingLocked(booted);
5924 return mStackSupervisor.shutdownLocked(timeout);
5925 }
5926 }
5927
5928 @Override
5929 public void enableScreenAfterBoot(boolean booted) {
5930 synchronized (mGlobalLock) {
5931 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5932 SystemClock.uptimeMillis());
5933 mWindowManager.enableScreenAfterBoot();
5934 updateEventDispatchingLocked(booted);
5935 }
5936 }
5937
5938 @Override
5939 public boolean showStrictModeViolationDialog() {
5940 synchronized (mGlobalLock) {
5941 return mShowDialogs && !mSleeping && !mShuttingDown;
5942 }
5943 }
5944
5945 @Override
5946 public void showSystemReadyErrorDialogsIfNeeded() {
5947 synchronized (mGlobalLock) {
5948 try {
5949 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
5950 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
5951 + " data partition or your device will be unstable.");
5952 mUiHandler.post(() -> {
5953 if (mShowDialogs) {
5954 AlertDialog d = new BaseErrorDialog(mUiContext);
5955 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5956 d.setCancelable(false);
5957 d.setTitle(mUiContext.getText(R.string.android_system_label));
5958 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
5959 d.setButton(DialogInterface.BUTTON_POSITIVE,
5960 mUiContext.getText(R.string.ok),
5961 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5962 d.show();
5963 }
5964 });
5965 }
5966 } catch (RemoteException e) {
5967 }
5968
5969 if (!Build.isBuildConsistent()) {
5970 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
5971 mUiHandler.post(() -> {
5972 if (mShowDialogs) {
5973 AlertDialog d = new BaseErrorDialog(mUiContext);
5974 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5975 d.setCancelable(false);
5976 d.setTitle(mUiContext.getText(R.string.android_system_label));
5977 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
5978 d.setButton(DialogInterface.BUTTON_POSITIVE,
5979 mUiContext.getText(R.string.ok),
5980 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5981 d.show();
5982 }
5983 });
5984 }
5985 }
5986 }
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005987
5988 @Override
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005989 public void onProcessMapped(int pid, WindowProcessController proc) {
5990 synchronized (mGlobalLock) {
5991 mPidMap.put(pid, proc);
5992 }
5993 }
5994
5995 @Override
5996 public void onProcessUnMapped(int pid) {
5997 synchronized (mGlobalLock) {
5998 mPidMap.remove(pid);
5999 }
6000 }
Wale Ogunwale008163e2018-07-23 23:11:08 -07006001
6002 @Override
6003 public void onPackageDataCleared(String name) {
6004 synchronized (mGlobalLock) {
Wale Ogunwale53783742018-09-16 10:21:51 -07006005 mCompatModePackages.handlePackageDataClearedLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07006006 mAppWarnings.onPackageDataCleared(name);
6007 }
6008 }
6009
6010 @Override
6011 public void onPackageUninstalled(String name) {
6012 synchronized (mGlobalLock) {
6013 mAppWarnings.onPackageUninstalled(name);
Wale Ogunwale53783742018-09-16 10:21:51 -07006014 mCompatModePackages.handlePackageUninstalledLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07006015 }
6016 }
Wale Ogunwale53783742018-09-16 10:21:51 -07006017
6018 @Override
6019 public void onPackageAdded(String name, boolean replacing) {
6020 synchronized (mGlobalLock) {
6021 mCompatModePackages.handlePackageAddedLocked(name, replacing);
6022 }
6023 }
6024
6025 @Override
Wale Ogunwale31913b52018-10-13 08:29:31 -07006026 public void onPackageReplaced(ApplicationInfo aInfo) {
6027 synchronized (mGlobalLock) {
6028 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
6029 }
6030 }
6031
6032 @Override
Wale Ogunwale53783742018-09-16 10:21:51 -07006033 public CompatibilityInfo compatibilityInfoForPackage(ApplicationInfo ai) {
6034 synchronized (mGlobalLock) {
6035 return compatibilityInfoForPackageLocked(ai);
6036 }
6037 }
6038
Yunfan Chen75157d72018-07-27 14:47:21 +09006039 /**
6040 * Set the corresponding display information for the process global configuration. To be
6041 * called when we need to show IME on a different display.
6042 *
6043 * @param pid The process id associated with the IME window.
6044 * @param displayId The ID of the display showing the IME.
6045 */
6046 @Override
6047 public void onImeWindowSetOnDisplay(int pid, int displayId) {
6048 if (pid == MY_PID || pid < 0) {
6049 if (DEBUG_CONFIGURATION) {
6050 Slog.w(TAG,
6051 "Trying to update display configuration for system/invalid process.");
6052 }
6053 return;
6054 }
6055 mH.post(() -> {
6056 synchronized (mGlobalLock) {
6057 // Check if display is initialized in AM.
6058 if (!mStackSupervisor.isDisplayAdded(displayId)) {
6059 // Call come when display is not yet added or has already been removed.
6060 if (DEBUG_CONFIGURATION) {
6061 Slog.w(TAG, "Trying to update display configuration for non-existing "
6062 + "displayId=" + displayId);
6063 }
6064 return;
6065 }
6066 final WindowProcessController imeProcess = mPidMap.get(pid);
6067 if (imeProcess == null) {
6068 if (DEBUG_CONFIGURATION) {
6069 Slog.w(TAG, "Trying to update display configuration for invalid pid: "
6070 + pid);
6071 }
6072 return;
6073 }
6074 // Fetch the current override configuration of the display and set it to the
6075 // process global configuration.
6076 imeProcess.onConfigurationChanged(
6077 mStackSupervisor.getDisplayOverrideConfiguration(displayId));
6078 }
6079 });
6080 }
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07006081
6082 @Override
6083 public void sendActivityResult(int callingUid, IBinder activityToken, String resultWho,
6084 int requestCode, int resultCode, Intent data) {
6085 synchronized (mGlobalLock) {
6086 final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
6087 if (r != null && r.getStack() != null) {
6088 r.getStack().sendActivityResultLocked(callingUid, r, resultWho, requestCode,
6089 resultCode, data);
6090 }
6091 }
6092 }
6093
6094 @Override
6095 public void clearPendingResultForActivity(IBinder activityToken,
6096 WeakReference<PendingIntentRecord> pir) {
6097 synchronized (mGlobalLock) {
6098 final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
6099 if (r != null && r.pendingResults != null) {
6100 r.pendingResults.remove(pir);
6101 }
6102 }
6103 }
6104
6105 @Override
6106 public IIntentSender getIntentSender(int type, String packageName,
6107 int callingUid, int userId, IBinder token, String resultWho,
6108 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6109 Bundle bOptions) {
6110 synchronized (mGlobalLock) {
6111 return getIntentSenderLocked(type, packageName, callingUid, userId, token,
6112 resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6113 }
6114 }
Wale Ogunwalec4e63a42018-10-02 13:19:54 -07006115
6116 @Override
6117 public ActivityServiceConnectionsHolder getServiceConnectionsHolder(IBinder token) {
6118 synchronized (mGlobalLock) {
6119 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
6120 if (r == null) {
6121 return null;
6122 }
6123 if (r.mServiceConnectionsHolder == null) {
6124 r.mServiceConnectionsHolder = new ActivityServiceConnectionsHolder(
6125 ActivityTaskManagerService.this, r);
6126 }
6127
6128 return r.mServiceConnectionsHolder;
6129 }
6130 }
Wale Ogunwale214f3482018-10-04 11:00:47 -07006131
6132 @Override
6133 public Intent getHomeIntent() {
6134 synchronized (mGlobalLock) {
6135 return ActivityTaskManagerService.this.getHomeIntent();
6136 }
6137 }
6138
6139 @Override
6140 public boolean startHomeActivity(int userId, String reason) {
6141 synchronized (mGlobalLock) {
6142 return startHomeActivityLocked(userId, reason, DEFAULT_DISPLAY);
6143 }
6144 }
6145
6146 @Override
6147 public boolean isFactoryTestProcess(WindowProcessController wpc) {
6148 synchronized (mGlobalLock) {
6149 if (mFactoryTest == FACTORY_TEST_OFF) {
6150 return false;
6151 }
6152 if (mFactoryTest == FACTORY_TEST_LOW_LEVEL && mTopComponent != null
6153 && wpc.mName.equals(mTopComponent.getPackageName())) {
6154 return true;
6155 }
6156 return mFactoryTest == FACTORY_TEST_HIGH_LEVEL
6157 && (wpc.mInfo.flags & FLAG_FACTORY_TEST) != 0;
6158 }
6159 }
6160
6161 @Override
6162 public void updateTopComponentForFactoryTest() {
6163 synchronized (mGlobalLock) {
6164 if (mFactoryTest != FACTORY_TEST_LOW_LEVEL) {
6165 return;
6166 }
6167 final ResolveInfo ri = mContext.getPackageManager()
6168 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), STOCK_PM_FLAGS);
6169 final CharSequence errorMsg;
6170 if (ri != null) {
6171 final ActivityInfo ai = ri.activityInfo;
6172 final ApplicationInfo app = ai.applicationInfo;
6173 if ((app.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
6174 mTopAction = Intent.ACTION_FACTORY_TEST;
6175 mTopData = null;
6176 mTopComponent = new ComponentName(app.packageName, ai.name);
6177 errorMsg = null;
6178 } else {
6179 errorMsg = mContext.getResources().getText(
6180 com.android.internal.R.string.factorytest_not_system);
6181 }
6182 } else {
6183 errorMsg = mContext.getResources().getText(
6184 com.android.internal.R.string.factorytest_no_action);
6185 }
6186 if (errorMsg == null) {
6187 return;
6188 }
6189
6190 mTopAction = null;
6191 mTopData = null;
6192 mTopComponent = null;
6193 mUiHandler.post(() -> {
6194 Dialog d = new FactoryErrorDialog(mUiContext, errorMsg);
6195 d.show();
Wale Ogunwale342fbe92018-10-09 08:44:10 -07006196 mAmInternal.ensureBootCompleted();
Wale Ogunwale214f3482018-10-04 11:00:47 -07006197 });
6198 }
6199 }
Wale Ogunwale31913b52018-10-13 08:29:31 -07006200
6201 @Override
6202 public void handleAppDied(WindowProcessController wpc, boolean restarting,
6203 Runnable finishInstrumentationCallback) {
6204 synchronized (mGlobalLock) {
6205 // Remove this application's activities from active lists.
6206 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(wpc);
6207
6208 wpc.clearRecentTasks();
6209 wpc.clearActivities();
6210
6211 if (wpc.isInstrumenting()) {
6212 finishInstrumentationCallback.run();
6213 }
6214
6215 mWindowManager.deferSurfaceLayout();
6216 try {
6217 if (!restarting && hasVisibleActivities
6218 && !mStackSupervisor.resumeFocusedStacksTopActivitiesLocked()) {
6219 // If there was nothing to resume, and we are not already restarting this
6220 // process, but there is a visible activity that is hosted by the process...
6221 // then make sure all visible activities are running, taking care of
6222 // restarting this process.
6223 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6224 }
6225 } finally {
6226 mWindowManager.continueSurfaceLayout();
6227 }
6228 }
6229 }
6230
6231 @Override
6232 public void closeSystemDialogs(String reason) {
6233 enforceNotIsolatedCaller("closeSystemDialogs");
6234
6235 final int pid = Binder.getCallingPid();
6236 final int uid = Binder.getCallingUid();
6237 final long origId = Binder.clearCallingIdentity();
6238 try {
6239 synchronized (mGlobalLock) {
6240 // Only allow this from foreground processes, so that background
6241 // applications can't abuse it to prevent system UI from being shown.
6242 if (uid >= FIRST_APPLICATION_UID) {
6243 final WindowProcessController proc = mPidMap.get(pid);
6244 if (!proc.isPerceptible()) {
6245 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6246 + " from background process " + proc);
6247 return;
6248 }
6249 }
6250 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6251 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6252 | Intent.FLAG_RECEIVER_FOREGROUND);
6253 if (reason != null) {
6254 intent.putExtra("reason", reason);
6255 }
6256 mWindowManager.closeSystemDialogs(reason);
6257
6258 mStackSupervisor.closeSystemDialogsLocked();
6259
6260 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6261 OP_NONE, null, false, false,
6262 -1, SYSTEM_UID, UserHandle.USER_ALL);
6263 }
6264 } finally {
6265 Binder.restoreCallingIdentity(origId);
6266 }
6267 }
6268
6269 @Override
6270 public void cleanupDisabledPackageComponents(
6271 String packageName, Set<String> disabledClasses, int userId, boolean booted) {
6272 synchronized (mGlobalLock) {
6273 // Clean-up disabled activities.
6274 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6275 packageName, disabledClasses, true, false, userId) && booted) {
6276 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
6277 mStackSupervisor.scheduleIdleLocked();
6278 }
6279
6280 // Clean-up disabled tasks
6281 getRecentTasks().cleanupDisabledPackageTasksLocked(
6282 packageName, disabledClasses, userId);
6283 }
6284 }
6285
6286 @Override
6287 public boolean onForceStopPackage(String packageName, boolean doit, boolean evenPersistent,
6288 int userId) {
6289 synchronized (mGlobalLock) {
6290
6291 boolean didSomething =
6292 getActivityStartController().clearPendingActivityLaunches(packageName);
6293 didSomething |= mStackSupervisor.finishDisabledPackageActivitiesLocked(packageName,
6294 null, doit, evenPersistent, userId);
6295 return didSomething;
6296 }
6297 }
6298
6299 @Override
6300 public void resumeTopActivities(boolean scheduleIdle) {
6301 synchronized (mGlobalLock) {
6302 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
6303 if (scheduleIdle) {
6304 mStackSupervisor.scheduleIdleLocked();
6305 }
6306 }
6307 }
6308
6309 @Override
6310 public void preBindApplication(WindowProcessController wpc) {
6311 synchronized (mGlobalLock) {
6312 mStackSupervisor.getActivityMetricsLogger().notifyBindApplication(wpc.mInfo);
6313 }
6314 }
6315
6316 @Override
6317 public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
6318 synchronized (mGlobalLock) {
6319 return mStackSupervisor.attachApplicationLocked(wpc);
6320 }
6321 }
6322
6323 @Override
6324 public void notifyLockedProfile(@UserIdInt int userId, int currentUserId) {
6325 try {
6326 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
6327 throw new SecurityException("Only privileged app can call notifyLockedProfile");
6328 }
6329 } catch (RemoteException ex) {
6330 throw new SecurityException("Fail to check is caller a privileged app", ex);
6331 }
6332
6333 synchronized (mGlobalLock) {
6334 final long ident = Binder.clearCallingIdentity();
6335 try {
6336 if (mAmInternal.shouldConfirmCredentials(userId)) {
6337 if (mKeyguardController.isKeyguardLocked()) {
6338 // Showing launcher to avoid user entering credential twice.
6339 startHomeActivity(currentUserId, "notifyLockedProfile");
6340 }
6341 mStackSupervisor.lockAllProfileTasks(userId);
6342 }
6343 } finally {
6344 Binder.restoreCallingIdentity(ident);
6345 }
6346 }
6347 }
6348
6349 @Override
6350 public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
6351 mAmInternal.enforceCallingPermission(
6352 MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
6353
6354 synchronized (mGlobalLock) {
6355 final long ident = Binder.clearCallingIdentity();
6356 try {
6357 intent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
6358 FLAG_ACTIVITY_TASK_ON_HOME);
6359 ActivityOptions activityOptions = options != null
6360 ? new ActivityOptions(options) : ActivityOptions.makeBasic();
6361 activityOptions.setLaunchTaskId(
6362 mStackSupervisor.getDefaultDisplayHomeActivity().getTask().taskId);
6363 mContext.startActivityAsUser(intent, activityOptions.toBundle(),
6364 UserHandle.CURRENT);
6365 } finally {
6366 Binder.restoreCallingIdentity(ident);
6367 }
6368 }
6369 }
6370
6371 @Override
6372 public void writeActivitiesToProto(ProtoOutputStream proto) {
6373 synchronized (mGlobalLock) {
6374 // The output proto of "activity --proto activities"
6375 // is ActivityManagerServiceDumpActivitiesProto
6376 mStackSupervisor.writeToProto(proto,
6377 ActivityManagerServiceDumpActivitiesProto.ACTIVITY_STACK_SUPERVISOR);
6378 }
6379 }
6380
6381 @Override
6382 public void saveANRState(String reason) {
6383 synchronized (mGlobalLock) {
6384 final StringWriter sw = new StringWriter();
6385 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
6386 pw.println(" ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
6387 if (reason != null) {
6388 pw.println(" Reason: " + reason);
6389 }
6390 pw.println();
6391 getActivityStartController().dump(pw, " ", null);
6392 pw.println();
6393 pw.println("-------------------------------------------------------------------------------");
6394 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
6395 true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
6396 "" /* header */);
6397 pw.println();
6398 pw.close();
6399
6400 mLastANRState = sw.toString();
6401 }
6402 }
6403
6404 @Override
6405 public void clearSavedANRState() {
6406 synchronized (mGlobalLock) {
6407 mLastANRState = null;
6408 }
6409 }
6410
6411 @Override
6412 public void dump(String cmd, FileDescriptor fd, PrintWriter pw, String[] args, int opti,
6413 boolean dumpAll, boolean dumpClient, String dumpPackage) {
6414 synchronized (mGlobalLock) {
6415 if (DUMP_ACTIVITIES_CMD.equals(cmd) || DUMP_ACTIVITIES_SHORT_CMD.equals(cmd)) {
6416 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
6417 } else if (DUMP_LASTANR_CMD.equals(cmd)) {
6418 dumpLastANRLocked(pw);
6419 } else if (DUMP_LASTANR_TRACES_CMD.equals(cmd)) {
6420 dumpLastANRTracesLocked(pw);
6421 } else if (DUMP_STARTER_CMD.equals(cmd)) {
6422 dumpActivityStarterLocked(pw, dumpPackage);
6423 } else if (DUMP_CONTAINERS_CMD.equals(cmd)) {
6424 dumpActivityContainersLocked(pw);
6425 } else if (DUMP_RECENTS_CMD.equals(cmd) || DUMP_RECENTS_SHORT_CMD.equals(cmd)) {
6426 if (getRecentTasks() != null) {
6427 getRecentTasks().dump(pw, dumpAll, dumpPackage);
6428 }
6429 }
6430 }
6431 }
6432
6433 @Override
6434 public boolean dumpForProcesses(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
6435 String dumpPackage, int dumpAppId, boolean needSep, boolean testPssMode,
6436 int wakefulness) {
6437 synchronized (mGlobalLock) {
6438 if (mHomeProcess != null && (dumpPackage == null
6439 || mHomeProcess.mPkgList.contains(dumpPackage))) {
6440 if (needSep) {
6441 pw.println();
6442 needSep = false;
6443 }
6444 pw.println(" mHomeProcess: " + mHomeProcess);
6445 }
6446 if (mPreviousProcess != null && (dumpPackage == null
6447 || mPreviousProcess.mPkgList.contains(dumpPackage))) {
6448 if (needSep) {
6449 pw.println();
6450 needSep = false;
6451 }
6452 pw.println(" mPreviousProcess: " + mPreviousProcess);
6453 }
6454 if (dumpAll && (mPreviousProcess == null || dumpPackage == null
6455 || mPreviousProcess.mPkgList.contains(dumpPackage))) {
6456 StringBuilder sb = new StringBuilder(128);
6457 sb.append(" mPreviousProcessVisibleTime: ");
6458 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
6459 pw.println(sb);
6460 }
6461 if (mHeavyWeightProcess != null && (dumpPackage == null
6462 || mHeavyWeightProcess.mPkgList.contains(dumpPackage))) {
6463 if (needSep) {
6464 pw.println();
6465 needSep = false;
6466 }
6467 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
6468 }
6469 if (dumpPackage == null) {
6470 pw.println(" mGlobalConfiguration: " + getGlobalConfiguration());
6471 mStackSupervisor.dumpDisplayConfigs(pw, " ");
6472 }
6473 if (dumpAll) {
6474 if (dumpPackage == null) {
6475 pw.println(" mConfigWillChange: "
6476 + getTopDisplayFocusedStack().mConfigWillChange);
6477 }
6478 if (mCompatModePackages.getPackages().size() > 0) {
6479 boolean printed = false;
6480 for (Map.Entry<String, Integer> entry
6481 : mCompatModePackages.getPackages().entrySet()) {
6482 String pkg = entry.getKey();
6483 int mode = entry.getValue();
6484 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
6485 continue;
6486 }
6487 if (!printed) {
6488 pw.println(" mScreenCompatPackages:");
6489 printed = true;
6490 }
6491 pw.println(" " + pkg + ": " + mode);
6492 }
6493 }
6494 }
6495
6496 if (dumpPackage == null) {
6497 pw.println(" mWakefulness="
6498 + PowerManagerInternal.wakefulnessToString(wakefulness));
6499 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
6500 if (mRunningVoice != null) {
6501 pw.println(" mRunningVoice=" + mRunningVoice);
6502 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
6503 }
6504 pw.println(" mSleeping=" + mSleeping);
6505 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + testPssMode);
6506 pw.println(" mVrController=" + mVrController);
6507 }
6508 if (mCurAppTimeTracker != null) {
6509 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
6510 }
6511 if (mAllowAppSwitchUids.size() > 0) {
6512 boolean printed = false;
6513 for (int i = 0; i < mAllowAppSwitchUids.size(); i++) {
6514 ArrayMap<String, Integer> types = mAllowAppSwitchUids.valueAt(i);
6515 for (int j = 0; j < types.size(); j++) {
6516 if (dumpPackage == null ||
6517 UserHandle.getAppId(types.valueAt(j).intValue()) == dumpAppId) {
6518 if (needSep) {
6519 pw.println();
6520 needSep = false;
6521 }
6522 if (!printed) {
6523 pw.println(" mAllowAppSwitchUids:");
6524 printed = true;
6525 }
6526 pw.print(" User ");
6527 pw.print(mAllowAppSwitchUids.keyAt(i));
6528 pw.print(": Type ");
6529 pw.print(types.keyAt(j));
6530 pw.print(" = ");
6531 UserHandle.formatUid(pw, types.valueAt(j).intValue());
6532 pw.println();
6533 }
6534 }
6535 }
6536 }
6537 if (dumpPackage == null) {
6538 if (mController != null) {
6539 pw.println(" mController=" + mController
6540 + " mControllerIsAMonkey=" + mControllerIsAMonkey);
6541 }
6542 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
6543 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
6544 }
6545
6546 return needSep;
6547 }
6548 }
6549
6550 @Override
6551 public void writeProcessesToProto(ProtoOutputStream proto, String dumpPackage) {
6552 synchronized (mGlobalLock) {
6553 if (dumpPackage == null) {
6554 getGlobalConfiguration().writeToProto(proto, GLOBAL_CONFIGURATION);
6555 proto.write(CONFIG_WILL_CHANGE, getTopDisplayFocusedStack().mConfigWillChange);
6556 writeSleepStateToProto(proto);
6557 if (mController != null) {
6558 final long token = proto.start(CONTROLLER);
6559 proto.write(CONTROLLER, mController.toString());
6560 proto.write(IS_A_MONKEY, mControllerIsAMonkey);
6561 proto.end(token);
6562 }
6563 mStackSupervisor.mGoingToSleep.writeToProto(proto, GOING_TO_SLEEP);
6564 mStackSupervisor.mLaunchingActivity.writeToProto(proto, LAUNCHING_ACTIVITY);
6565 }
6566
6567 if (mHomeProcess != null && (dumpPackage == null
6568 || mHomeProcess.mPkgList.contains(dumpPackage))) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07006569 mHomeProcess.writeToProto(proto, HOME_PROC);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006570 }
6571
6572 if (mPreviousProcess != null && (dumpPackage == null
6573 || mPreviousProcess.mPkgList.contains(dumpPackage))) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07006574 mPreviousProcess.writeToProto(proto, PREVIOUS_PROC);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006575 proto.write(PREVIOUS_PROC_VISIBLE_TIME_MS, mPreviousProcessVisibleTime);
6576 }
6577
6578 if (mHeavyWeightProcess != null && (dumpPackage == null
6579 || mHeavyWeightProcess.mPkgList.contains(dumpPackage))) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07006580 mHeavyWeightProcess.writeToProto(proto, HEAVY_WEIGHT_PROC);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006581 }
6582
6583 for (Map.Entry<String, Integer> entry
6584 : mCompatModePackages.getPackages().entrySet()) {
6585 String pkg = entry.getKey();
6586 int mode = entry.getValue();
6587 if (dumpPackage == null || dumpPackage.equals(pkg)) {
6588 long compatToken = proto.start(SCREEN_COMPAT_PACKAGES);
6589 proto.write(PACKAGE, pkg);
6590 proto.write(MODE, mode);
6591 proto.end(compatToken);
6592 }
6593 }
6594
6595 if (mCurAppTimeTracker != null) {
6596 mCurAppTimeTracker.writeToProto(proto, CURRENT_TRACKER, true);
6597 }
6598
6599 }
6600 }
6601
6602 @Override
6603 public boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name,
6604 String[] args, int opti, boolean dumpAll, boolean dumpVisibleStacksOnly,
6605 boolean dumpFocusedStackOnly) {
6606 synchronized (mGlobalLock) {
6607 return ActivityTaskManagerService.this.dumpActivity(fd, pw, name, args, opti,
6608 dumpAll, dumpVisibleStacksOnly, dumpFocusedStackOnly);
6609 }
6610 }
6611
6612 @Override
6613 public boolean canGcNow() {
6614 synchronized (mGlobalLock) {
6615 return isSleeping() || mStackSupervisor.allResumedActivitiesIdle();
6616 }
6617 }
6618
6619 @Override
6620 public WindowProcessController getTopApp() {
6621 synchronized (mGlobalLock) {
6622 final ActivityRecord top = mStackSupervisor.getTopResumedActivity();
6623 return top != null ? top.app : null;
6624 }
6625 }
6626
6627 @Override
6628 public void rankTaskLayersIfNeeded() {
6629 synchronized (mGlobalLock) {
6630 if (mStackSupervisor != null) {
6631 mStackSupervisor.rankTaskLayersIfNeeded();
6632 }
6633 }
6634 }
6635
6636 @Override
6637 public void scheduleDestroyAllActivities(String reason) {
6638 synchronized (mGlobalLock) {
6639 mStackSupervisor.scheduleDestroyAllActivities(null, reason);
6640 }
6641 }
6642
6643 @Override
6644 public void removeUser(int userId) {
6645 synchronized (mGlobalLock) {
6646 mStackSupervisor.removeUserLocked(userId);
6647 }
6648 }
6649
6650 @Override
6651 public boolean switchUser(int userId, UserState userState) {
6652 synchronized (mGlobalLock) {
6653 return mStackSupervisor.switchUserLocked(userId, userState);
6654 }
6655 }
6656
6657 @Override
6658 public void onHandleAppCrash(WindowProcessController wpc) {
6659 synchronized (mGlobalLock) {
6660 mStackSupervisor.handleAppCrashLocked(wpc);
6661 }
6662 }
Wale Ogunwale64258362018-10-16 15:13:37 -07006663
6664 @Override
6665 public int finishTopCrashedActivities(WindowProcessController crashedApp, String reason) {
6666 synchronized (mGlobalLock) {
6667 return mStackSupervisor.finishTopCrashedActivitiesLocked(crashedApp, reason);
6668 }
6669 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07006670 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07006671}