blob: 5e3c1da2310beec3cebedb3959376ca9a7b297cc [file] [log] [blame]
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.server.am;
18
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070019import static android.Manifest.permission.BIND_VOICE_INTERACTION;
20import static android.Manifest.permission.CHANGE_CONFIGURATION;
21import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
22import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070023import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070024import static android.Manifest.permission.READ_FRAME_BUFFER;
25import static android.Manifest.permission.REMOVE_TASKS;
26import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070027import static android.Manifest.permission.STOP_APP_SWITCHES;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070028import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
Wale Ogunwalebff2df42018-10-18 17:09:19 -070029import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
Evan Rosky4505b352018-09-06 11:20:40 -070030import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
Yunfan Chen79b96062018-10-17 12:45:23 -070031import static android.app.ActivityTaskManager.INVALID_TASK_ID;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070032import static android.app.ActivityTaskManager.RESIZE_MODE_PRESERVE_WINDOW;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070033import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
34import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070035import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
36import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070037import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
38import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070039import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070040import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Wale Ogunwale31913b52018-10-13 08:29:31 -070041import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070042import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
Wale Ogunwale31913b52018-10-13 08:29:31 -070043import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
Wale Ogunwale214f3482018-10-04 11:00:47 -070044import static android.content.pm.ApplicationInfo.FLAG_FACTORY_TEST;
Wale Ogunwale342fbe92018-10-09 08:44:10 -070045import static android.content.pm.ConfigurationInfo.GL_ES_VERSION_UNDEFINED;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070046import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
47import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
Evan Rosky4505b352018-09-06 11:20:40 -070048import static android.content.pm.PackageManager.FEATURE_PC;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070049import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070050import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070051import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
52import static android.os.Build.VERSION_CODES.N;
Wale Ogunwale214f3482018-10-04 11:00:47 -070053import static android.os.FactoryTest.FACTORY_TEST_HIGH_LEVEL;
54import static android.os.FactoryTest.FACTORY_TEST_LOW_LEVEL;
55import static android.os.FactoryTest.FACTORY_TEST_OFF;
Wale Ogunwale31913b52018-10-13 08:29:31 -070056import static android.os.Process.FIRST_APPLICATION_UID;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070057import static android.os.Process.SYSTEM_UID;
Evan Rosky4505b352018-09-06 11:20:40 -070058import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070059import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
60import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
61import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
62import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
Evan Rosky4505b352018-09-06 11:20:40 -070063import static android.provider.Settings.Global.HIDE_ERROR_DIALOGS;
64import static android.provider.Settings.System.FONT_SCALE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070065import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
66import static android.view.Display.DEFAULT_DISPLAY;
67import static android.view.Display.INVALID_DISPLAY;
Wale 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
Yunfan Chen79b96062018-10-17 12:45:23 -070074import static com.android.server.am.ActivityManagerService.ANR_TRACE_DIR;
75import static com.android.server.am.ActivityManagerService.MY_PID;
76import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS;
77import static com.android.server.am.ActivityManagerService.dumpStackTraces;
Wale Ogunwale31913b52018-10-13 08:29:31 -070078import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.CONFIG_WILL_CHANGE;
79import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.CONTROLLER;
80import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.CURRENT_TRACKER;
81import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.Controller.IS_A_MONKEY;
82import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.GLOBAL_CONFIGURATION;
83import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.GOING_TO_SLEEP;
84import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.HEAVY_WEIGHT_PROC;
85import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.HOME_PROC;
86import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.LAUNCHING_ACTIVITY;
87import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC;
Louis Chang89f43fc2018-10-05 10:59:14 +080088import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC_VISIBLE_TIME_MS;
Wale Ogunwale31913b52018-10-13 08:29:31 -070089import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.SCREEN_COMPAT_PACKAGES;
Louis Chang89f43fc2018-10-05 10:59:14 +080090import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.MODE;
91import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.PACKAGE;
Yunfan Chen79b96062018-10-17 12:45:23 -070092import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
93import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
94import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
95import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
96import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
97import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
98import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
Wale Ogunwale98875612018-10-12 07:53:02 -070099import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_ALL;
100import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
101import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_FOCUS;
102import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_IMMERSIVE;
103import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_LOCKTASK;
104import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_STACK;
105import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
106import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
107import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_VISIBILITY;
108import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
109import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS;
110import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_IMMERSIVE;
111import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_LOCKTASK;
112import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_STACK;
113import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH;
114import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_VISIBILITY;
115import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_ATM;
116import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
Evan Rosky4505b352018-09-06 11:20:40 -0700117import static com.android.server.am.ActivityTaskManagerService.H.REPORT_TIME_TRACKER_MSG;
118import static com.android.server.am.ActivityTaskManagerService.UiHandler.DISMISS_DIALOG_UI_MSG;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700119import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700120import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700121import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
Evan Rosky4505b352018-09-06 11:20:40 -0700122import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT;
123import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_DATA;
124import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
125import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700126import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
127import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700128
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700129import android.Manifest;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700130import android.annotation.NonNull;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700131import android.annotation.Nullable;
132import android.annotation.UserIdInt;
133import android.app.Activity;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700134import android.app.ActivityManager;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700135import android.app.ActivityManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700136import android.app.ActivityOptions;
137import android.app.ActivityTaskManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700138import android.app.ActivityThread;
139import android.app.AlertDialog;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700140import android.app.AppGlobals;
Evan Rosky4505b352018-09-06 11:20:40 -0700141import android.app.Dialog;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700142import android.app.IActivityController;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700143import android.app.IActivityTaskManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700144import android.app.IApplicationThread;
145import android.app.IAssistDataReceiver;
Wale Ogunwale53783742018-09-16 10:21:51 -0700146import android.app.INotificationManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700147import android.app.ITaskStackListener;
Wale Ogunwale53783742018-09-16 10:21:51 -0700148import android.app.Notification;
149import android.app.NotificationManager;
150import android.app.PendingIntent;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700151import android.app.PictureInPictureParams;
152import android.app.ProfilerInfo;
153import android.app.RemoteAction;
154import android.app.WaitResult;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700155import android.app.WindowConfiguration;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700156import android.app.admin.DevicePolicyCache;
157import android.app.assist.AssistContent;
158import android.app.assist.AssistStructure;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700159import android.app.usage.UsageStatsManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700160import android.content.ActivityNotFoundException;
161import android.content.ComponentName;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700162import android.content.ContentResolver;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700163import android.content.Context;
Evan Rosky4505b352018-09-06 11:20:40 -0700164import android.content.DialogInterface;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700165import android.content.IIntentSender;
166import android.content.Intent;
167import android.content.pm.ActivityInfo;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700168import android.content.pm.ApplicationInfo;
Yunfan Chen75157d72018-07-27 14:47:21 +0900169import android.content.pm.ConfigurationInfo;
Evan Rosky4505b352018-09-06 11:20:40 -0700170import android.content.pm.IPackageManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700171import android.content.pm.PackageManager;
Evan Rosky4505b352018-09-06 11:20:40 -0700172import android.content.pm.PackageManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700173import android.content.pm.ParceledListSlice;
174import android.content.pm.ResolveInfo;
Wale Ogunwale53783742018-09-16 10:21:51 -0700175import android.content.res.CompatibilityInfo;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700176import android.content.res.Configuration;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700177import android.content.res.Resources;
Evan Rosky4505b352018-09-06 11:20:40 -0700178import android.database.ContentObserver;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700179import android.graphics.Bitmap;
180import android.graphics.Point;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700181import android.graphics.Rect;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700182import android.metrics.LogMaker;
183import android.net.Uri;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700184import android.os.Binder;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700185import android.os.Build;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700186import android.os.Bundle;
Wale Ogunwale214f3482018-10-04 11:00:47 -0700187import android.os.FactoryTest;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700188import android.os.FileUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700189import android.os.Handler;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700190import android.os.IBinder;
Evan Rosky4505b352018-09-06 11:20:40 -0700191import android.os.IUserManager;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700192import android.os.LocaleList;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700193import android.os.Looper;
194import android.os.Message;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700195import android.os.PersistableBundle;
Evan Rosky4505b352018-09-06 11:20:40 -0700196import android.os.PowerManager;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700197import android.os.PowerManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700198import android.os.RemoteException;
Evan Rosky4505b352018-09-06 11:20:40 -0700199import android.os.ServiceManager;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700200import android.os.StrictMode;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700201import android.os.SystemClock;
202import android.os.SystemProperties;
Evan Rosky4505b352018-09-06 11:20:40 -0700203import android.os.Trace;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700204import android.os.UpdateLock;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700205import android.os.UserHandle;
Evan Rosky4505b352018-09-06 11:20:40 -0700206import android.os.UserManager;
207import android.os.WorkSource;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700208import android.os.storage.IStorageManager;
209import android.os.storage.StorageManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700210import android.provider.Settings;
211import android.service.voice.IVoiceInteractionSession;
212import android.service.voice.VoiceInteractionManagerInternal;
213import android.telecom.TelecomManager;
214import android.text.TextUtils;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700215import android.text.format.Time;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700216import android.util.ArrayMap;
217import android.util.EventLog;
218import android.util.Log;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700219import android.util.Slog;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700220import android.util.SparseArray;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700221import android.util.SparseIntArray;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700222import android.util.StatsLog;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700223import android.util.TimeUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700224import android.util.proto.ProtoOutputStream;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700225import android.view.IRecentsAnimationRunner;
226import android.view.RemoteAnimationAdapter;
227import android.view.RemoteAnimationDefinition;
Evan Rosky4505b352018-09-06 11:20:40 -0700228import android.view.WindowManager;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700229
Evan Rosky4505b352018-09-06 11:20:40 -0700230import com.android.internal.R;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700231import com.android.internal.annotations.VisibleForTesting;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700232import com.android.internal.app.AssistUtils;
Evan Rosky4505b352018-09-06 11:20:40 -0700233import com.android.internal.app.IAppOpsService;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700234import com.android.internal.app.IVoiceInteractor;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700235import com.android.internal.app.ProcessMap;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700236import com.android.internal.logging.MetricsLogger;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700237import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Wale Ogunwale53783742018-09-16 10:21:51 -0700238import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
239import com.android.internal.notification.SystemNotificationChannels;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700240import com.android.internal.os.TransferPipe;
Evan Rosky4505b352018-09-06 11:20:40 -0700241import com.android.internal.os.logging.MetricsLoggerWrapper;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700242import com.android.internal.policy.IKeyguardDismissCallback;
243import com.android.internal.policy.KeyguardDismissCallback;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700244import com.android.internal.util.ArrayUtils;
245import com.android.internal.util.FastPrintWriter;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700246import com.android.internal.util.Preconditions;
Wale Ogunwale53783742018-09-16 10:21:51 -0700247import com.android.internal.util.function.pooled.PooledLambda;
Evan Rosky4505b352018-09-06 11:20:40 -0700248import com.android.server.AppOpsService;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700249import com.android.server.AttributeCache;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700250import com.android.server.LocalServices;
251import com.android.server.SystemService;
Evan Rosky4505b352018-09-06 11:20:40 -0700252import com.android.server.SystemServiceManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700253import com.android.server.Watchdog;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700254import com.android.server.firewall.IntentFirewall;
Evan Rosky4505b352018-09-06 11:20:40 -0700255import com.android.server.pm.UserManagerService;
256import com.android.server.uri.UriGrantsManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700257import com.android.server.vr.VrManagerInternal;
Evan Rosky4505b352018-09-06 11:20:40 -0700258import com.android.server.wm.ActivityTaskManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700259import com.android.server.wm.PinnedStackWindowController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700260import com.android.server.wm.WindowManagerService;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700261
Wale Ogunwale31913b52018-10-13 08:29:31 -0700262import java.io.BufferedReader;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700263import java.io.File;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700264import java.io.FileDescriptor;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700265import java.io.FileOutputStream;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700266import java.io.FileReader;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700267import java.io.IOException;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700268import java.io.PrintWriter;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700269import java.io.StringWriter;
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700270import java.lang.ref.WeakReference;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700271import java.text.DateFormat;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700272import java.util.ArrayList;
Wale Ogunwale27c48ae2018-10-25 19:01:01 -0700273import java.util.Arrays;
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 Ogunwalea6191b42018-05-09 07:41:32 -0700333 ActivityManagerInternal mAmInternal;
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700334 UriGrantsManagerInternal mUgmInternal;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700335 private PackageManagerInternal mPmInternal;
Wale Ogunwale53783742018-09-16 10:21:51 -0700336 private ActivityTaskManagerInternal mInternal;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700337 PowerManagerInternal mPowerManagerInternal;
338 private UsageStatsManagerInternal mUsageStatsInternal;
339
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700340 PendingIntentController mPendingIntentController;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700341 IntentFirewall mIntentFirewall;
342
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700343 /* Global service lock used by the package the owns this service. */
344 Object mGlobalLock;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700345 ActivityStackSupervisor mStackSupervisor;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700346 WindowManagerService mWindowManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700347 private UserManagerService mUserManager;
348 private AppOpsService mAppOpsService;
Wale Ogunwalebff2df42018-10-18 17:09:19 -0700349 /** All active uids in the system. */
Wale Ogunwale9de19442018-10-18 19:05:03 -0700350 private final SparseArray<Integer> mActiveUids = new SparseArray<>();
351 private final SparseArray<String> mPendingTempWhitelist = new SparseArray<>();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700352 /** All processes currently running that might have a window organized by name. */
353 final ProcessMap<WindowProcessController> mProcessNames = new ProcessMap<>();
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700354 /** All processes we currently have running mapped by pid */
355 final SparseArray<WindowProcessController> mPidMap = new SparseArray<>();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700356 /** This is the process holding what we currently consider to be the "home" activity. */
357 WindowProcessController mHomeProcess;
Wale Ogunwale53783742018-09-16 10:21:51 -0700358 /** The currently running heavy-weight process, if any. */
359 WindowProcessController mHeavyWeightProcess = null;
Wale Ogunwale214f3482018-10-04 11:00:47 -0700360 boolean mHasHeavyWeightFeature;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700361 /**
362 * This is the process holding the activity the user last visited that is in a different process
363 * from the one they are currently in.
364 */
365 WindowProcessController mPreviousProcess;
366 /** The time at which the previous process was last visible. */
367 long mPreviousProcessVisibleTime;
368
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700369 /** List of intents that were used to start the most recent tasks. */
370 private RecentTasks mRecentTasks;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700371 /** State of external calls telling us if the device is awake or asleep. */
372 private boolean mKeyguardShown = false;
373
374 // Wrapper around VoiceInteractionServiceManager
375 private AssistUtils mAssistUtils;
376
377 // VoiceInteraction session ID that changes for each new request except when
378 // being called for multi-window assist in a single session.
379 private int mViSessionId = 1000;
380
381 // How long to wait in getAssistContextExtras for the activity and foreground services
382 // to respond with the result.
383 private static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
384
385 // How long top wait when going through the modern assist (which doesn't need to block
386 // on getting this result before starting to launch its UI).
387 private static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
388
389 // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
390 private static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
391
392 private final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
393
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700394 // Keeps track of the active voice interaction service component, notified from
395 // VoiceInteractionManagerService
396 ComponentName mActiveVoiceInteractionServiceComponent;
397
Wale Ogunwalee2172292018-10-25 10:11:10 -0700398 VrController mVrController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700399 KeyguardController mKeyguardController;
400 private final ClientLifecycleManager mLifecycleManager;
401 private TaskChangeNotificationController mTaskChangeNotificationController;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700402 /** The controller for all operations related to locktask. */
403 private LockTaskController mLockTaskController;
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700404 private ActivityStartController mActivityStartController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700405
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700406 boolean mSuppressResizeConfigChanges;
407
408 private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
409 new UpdateConfigurationResult();
410
411 static final class UpdateConfigurationResult {
412 // Configuration changes that were updated.
413 int changes;
414 // If the activity was relaunched to match the new configuration.
415 boolean activityRelaunched;
416
417 void reset() {
418 changes = 0;
419 activityRelaunched = false;
420 }
421 }
422
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700423 /** Current sequencing integer of the configuration, for skipping old configurations. */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700424 private int mConfigurationSeq;
425 // To cache the list of supported system locales
426 private String[] mSupportedSystemLocales = null;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700427
428 /**
429 * Temp object used when global and/or display override configuration is updated. It is also
430 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
431 * anyone...
432 */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700433 private Configuration mTempConfig = new Configuration();
434
Wale Ogunwalef6733932018-06-27 05:14:34 -0700435 /** Temporary to avoid allocations. */
436 final StringBuilder mStringBuilder = new StringBuilder(256);
437
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700438 // Amount of time after a call to stopAppSwitches() during which we will
439 // prevent further untrusted switches from happening.
440 private static final long APP_SWITCH_DELAY_TIME = 5 * 1000;
441
442 /**
443 * The time at which we will allow normal application switches again,
444 * after a call to {@link #stopAppSwitches()}.
445 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700446 private long mAppSwitchesAllowedTime;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700447 /**
448 * This is set to true after the first switch after mAppSwitchesAllowedTime
449 * is set; any switches after that will clear the time.
450 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700451 private boolean mDidAppSwitch;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700452
453 IActivityController mController = null;
454 boolean mControllerIsAMonkey = false;
455
Wale Ogunwale214f3482018-10-04 11:00:47 -0700456 final int mFactoryTest;
457
458 /** Used to control how we initialize the service. */
459 ComponentName mTopComponent;
460 String mTopAction = Intent.ACTION_MAIN;
461 String mTopData;
462
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700463 /**
Wale Ogunwale31913b52018-10-13 08:29:31 -0700464 * Dump of the activity state at the time of the last ANR. Cleared after
465 * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
466 */
467 String mLastANRState;
468
469 /**
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700470 * Used to retain an update lock when the foreground activity is in
471 * immersive mode.
472 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700473 private final UpdateLock mUpdateLock = new UpdateLock("immersive");
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700474
475 /**
476 * Packages that are being allowed to perform unrestricted app switches. Mapping is
477 * User -> Type -> uid.
478 */
479 final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
480
481 /** The dimensions of the thumbnails in the Recents UI. */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700482 private int mThumbnailWidth;
483 private int mThumbnailHeight;
484 private float mFullscreenThumbnailScale;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700485
486 /**
487 * Flag that indicates if multi-window is enabled.
488 *
489 * For any particular form of multi-window to be enabled, generic multi-window must be enabled
490 * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
491 * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
492 * At least one of the forms of multi-window must be enabled in order for this flag to be
493 * initialized to 'true'.
494 *
495 * @see #mSupportsSplitScreenMultiWindow
496 * @see #mSupportsFreeformWindowManagement
497 * @see #mSupportsPictureInPicture
498 * @see #mSupportsMultiDisplay
499 */
500 boolean mSupportsMultiWindow;
501 boolean mSupportsSplitScreenMultiWindow;
502 boolean mSupportsFreeformWindowManagement;
503 boolean mSupportsPictureInPicture;
504 boolean mSupportsMultiDisplay;
505 boolean mForceResizableActivities;
506
507 final List<ActivityTaskManagerInternal.ScreenObserver> mScreenObservers = new ArrayList<>();
508
509 // VR Vr2d Display Id.
510 int mVr2dDisplayId = INVALID_DISPLAY;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700511
Wale Ogunwalef6733932018-06-27 05:14:34 -0700512 /**
513 * Set while we are wanting to sleep, to prevent any
514 * activities from being started/resumed.
515 *
516 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
517 *
518 * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
519 * while in the sleep state until there is a pending transition out of sleep, in which case
520 * mSleeping is set to false, and remains false while awake.
521 *
522 * Whether mSleeping can quickly toggled between true/false without the device actually
523 * display changing states is undefined.
524 */
525 private boolean mSleeping = false;
526
527 /**
528 * The process state used for processes that are running the top activities.
529 * This changes between TOP and TOP_SLEEPING to following mSleeping.
530 */
531 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
532
533 // Whether we should show our dialogs (ANR, crash, etc) or just perform their default action
534 // automatically. Important for devices without direct input devices.
535 private boolean mShowDialogs = true;
536
537 /** Set if we are shutting down the system, similar to sleeping. */
538 boolean mShuttingDown = false;
539
540 /**
541 * We want to hold a wake lock while running a voice interaction session, since
542 * this may happen with the screen off and we need to keep the CPU running to
543 * be able to continue to interact with the user.
544 */
545 PowerManager.WakeLock mVoiceWakeLock;
546
547 /**
548 * Set while we are running a voice interaction. This overrides sleeping while it is active.
549 */
550 IVoiceInteractionSession mRunningVoice;
551
552 /**
553 * The last resumed activity. This is identical to the current resumed activity most
554 * of the time but could be different when we're pausing one activity before we resume
555 * another activity.
556 */
557 ActivityRecord mLastResumedActivity;
558
559 /**
560 * The activity that is currently being traced as the active resumed activity.
561 *
562 * @see #updateResumedAppTrace
563 */
564 private @Nullable ActivityRecord mTracedResumedActivity;
565
566 /** If non-null, we are tracking the time the user spends in the currently focused app. */
567 AppTimeTracker mCurAppTimeTracker;
568
Wale Ogunwale008163e2018-07-23 23:11:08 -0700569 private AppWarnings mAppWarnings;
570
Wale Ogunwale53783742018-09-16 10:21:51 -0700571 /**
572 * Packages that the user has asked to have run in screen size
573 * compatibility mode instead of filling the screen.
574 */
575 CompatModePackages mCompatModePackages;
576
Wale Ogunwalef6733932018-06-27 05:14:34 -0700577 private FontScaleSettingObserver mFontScaleSettingObserver;
578
579 private final class FontScaleSettingObserver extends ContentObserver {
580 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
581 private final Uri mHideErrorDialogsUri = Settings.Global.getUriFor(HIDE_ERROR_DIALOGS);
582
583 public FontScaleSettingObserver() {
584 super(mH);
585 final ContentResolver resolver = mContext.getContentResolver();
586 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
587 resolver.registerContentObserver(mHideErrorDialogsUri, false, this,
588 UserHandle.USER_ALL);
589 }
590
591 @Override
592 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
593 if (mFontScaleUri.equals(uri)) {
594 updateFontScaleIfNeeded(userId);
595 } else if (mHideErrorDialogsUri.equals(uri)) {
596 synchronized (mGlobalLock) {
597 updateShouldShowDialogsLocked(getGlobalConfiguration());
598 }
599 }
600 }
601 }
602
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700603 ActivityTaskManagerService(Context context) {
604 mContext = context;
Wale Ogunwale214f3482018-10-04 11:00:47 -0700605 mFactoryTest = FactoryTest.getMode();
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700606 mSystemThread = ActivityThread.currentActivityThread();
607 mUiContext = mSystemThread.getSystemUiContext();
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700608 mLifecycleManager = new ClientLifecycleManager();
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700609 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", GL_ES_VERSION_UNDEFINED);
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700610 }
611
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700612 public void onSystemReady() {
613 synchronized (mGlobalLock) {
614 mHasHeavyWeightFeature = mContext.getPackageManager().hasSystemFeature(
615 PackageManager.FEATURE_CANT_SAVE_STATE);
616 mAssistUtils = new AssistUtils(mContext);
617 mVrController.onSystemReady();
618 mRecentTasks.onSystemReadyLocked();
619 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700620 }
621
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700622 public void onInitPowerManagement() {
623 synchronized (mGlobalLock) {
624 mStackSupervisor.initPowerManagement();
625 final PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
626 mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
627 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
628 mVoiceWakeLock.setReferenceCounted(false);
629 }
Wale Ogunwalef6733932018-06-27 05:14:34 -0700630 }
631
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700632 public void installSystemProviders() {
Wale Ogunwalef6733932018-06-27 05:14:34 -0700633 mFontScaleSettingObserver = new FontScaleSettingObserver();
634 }
635
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700636 void retrieveSettings(ContentResolver resolver) {
637 final boolean freeformWindowManagement =
638 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
639 || Settings.Global.getInt(
640 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
641
642 final boolean supportsMultiWindow = ActivityTaskManager.supportsMultiWindow(mContext);
643 final boolean supportsPictureInPicture = supportsMultiWindow &&
644 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
645 final boolean supportsSplitScreenMultiWindow =
646 ActivityTaskManager.supportsSplitScreenMultiWindow(mContext);
647 final boolean supportsMultiDisplay = mContext.getPackageManager()
648 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
649 final boolean alwaysFinishActivities =
650 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
651 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
652 final boolean forceResizable = Settings.Global.getInt(
653 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
Garfield Tane0846042018-07-26 13:42:04 -0700654 final boolean isPc = mContext.getPackageManager().hasSystemFeature(FEATURE_PC);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700655
656 // Transfer any global setting for forcing RTL layout, into a System Property
657 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
658
659 final Configuration configuration = new Configuration();
660 Settings.System.getConfiguration(resolver, configuration);
661 if (forceRtl) {
662 // This will take care of setting the correct layout direction flags
663 configuration.setLayoutDirection(configuration.locale);
664 }
665
666 synchronized (mGlobalLock) {
667 mForceResizableActivities = forceResizable;
668 final boolean multiWindowFormEnabled = freeformWindowManagement
669 || supportsSplitScreenMultiWindow
670 || supportsPictureInPicture
671 || supportsMultiDisplay;
672 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
673 mSupportsMultiWindow = true;
674 mSupportsFreeformWindowManagement = freeformWindowManagement;
675 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
676 mSupportsPictureInPicture = supportsPictureInPicture;
677 mSupportsMultiDisplay = supportsMultiDisplay;
678 } else {
679 mSupportsMultiWindow = false;
680 mSupportsFreeformWindowManagement = false;
681 mSupportsSplitScreenMultiWindow = false;
682 mSupportsPictureInPicture = false;
683 mSupportsMultiDisplay = false;
684 }
685 mWindowManager.setForceResizableTasks(mForceResizableActivities);
686 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
Garfield Tane0846042018-07-26 13:42:04 -0700687 mWindowManager.setSupportsFreeformWindowManagement(mSupportsFreeformWindowManagement);
688 mWindowManager.setIsPc(isPc);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700689 // This happens before any activities are started, so we can change global configuration
690 // in-place.
691 updateConfigurationLocked(configuration, null, true);
692 final Configuration globalConfig = getGlobalConfiguration();
693 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
694
695 // Load resources only after the current configuration has been set.
696 final Resources res = mContext.getResources();
697 mThumbnailWidth = res.getDimensionPixelSize(
698 com.android.internal.R.dimen.thumbnail_width);
699 mThumbnailHeight = res.getDimensionPixelSize(
700 com.android.internal.R.dimen.thumbnail_height);
701
702 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
703 mFullscreenThumbnailScale = (float) res
704 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
705 (float) globalConfig.screenWidthDp;
706 } else {
707 mFullscreenThumbnailScale = res.getFraction(
708 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
709 }
710 }
711 }
712
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700713 // TODO: Will be converted to WM lock once transition is complete.
Wale Ogunwale9de19442018-10-18 19:05:03 -0700714 void setActivityManagerService(Object globalLock, Looper looper,
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700715 IntentFirewall intentFirewall, PendingIntentController intentController) {
Wale Ogunwale9de19442018-10-18 19:05:03 -0700716 mGlobalLock = globalLock;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700717 mH = new H(looper);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700718 mUiHandler = new UiHandler();
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700719 mIntentFirewall = intentFirewall;
Wale Ogunwale53783742018-09-16 10:21:51 -0700720 final File systemDir = SystemServiceManager.ensureSystemDir();
721 mAppWarnings = new AppWarnings(this, mUiContext, mH, mUiHandler, systemDir);
722 mCompatModePackages = new CompatModePackages(this, systemDir, mH);
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700723 mPendingIntentController = intentController;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700724
725 mTempConfig.setToDefaults();
726 mTempConfig.setLocales(LocaleList.getDefault());
727 mConfigurationSeq = mTempConfig.seq = 1;
728 mStackSupervisor = createStackSupervisor();
729 mStackSupervisor.onConfigurationChanged(mTempConfig);
730
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700731 mTaskChangeNotificationController =
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700732 new TaskChangeNotificationController(mGlobalLock, mStackSupervisor, mH);
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700733 mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mH);
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700734 mActivityStartController = new ActivityStartController(this);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700735 mRecentTasks = createRecentTasks();
736 mStackSupervisor.setRecentTasks(mRecentTasks);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700737 mVrController = new VrController(mGlobalLock);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700738 mKeyguardController = mStackSupervisor.getKeyguardController();
739 }
740
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700741 public void onActivityManagerInternalAdded() {
742 synchronized (mGlobalLock) {
743 mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
744 mUgmInternal = LocalServices.getService(UriGrantsManagerInternal.class);
745 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700746 }
747
Yunfan Chen75157d72018-07-27 14:47:21 +0900748 int increaseConfigurationSeqLocked() {
749 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
750 return mConfigurationSeq;
751 }
752
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700753 protected ActivityStackSupervisor createStackSupervisor() {
754 final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mH.getLooper());
755 supervisor.initialize();
756 return supervisor;
757 }
758
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700759 public void setWindowManager(WindowManagerService wm) {
760 synchronized (mGlobalLock) {
761 mWindowManager = wm;
762 mLockTaskController.setWindowManager(wm);
763 mStackSupervisor.setWindowManager(wm);
764 }
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700765 }
766
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700767 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
768 synchronized (mGlobalLock) {
769 mUsageStatsInternal = usageStatsManager;
770 }
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700771 }
772
Wale Ogunwalef6733932018-06-27 05:14:34 -0700773 UserManagerService getUserManager() {
774 if (mUserManager == null) {
775 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
776 mUserManager = (UserManagerService) IUserManager.Stub.asInterface(b);
777 }
778 return mUserManager;
779 }
780
781 AppOpsService getAppOpsService() {
782 if (mAppOpsService == null) {
783 IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
784 mAppOpsService = (AppOpsService) IAppOpsService.Stub.asInterface(b);
785 }
786 return mAppOpsService;
787 }
788
789 boolean hasUserRestriction(String restriction, int userId) {
790 return getUserManager().hasUserRestriction(restriction, userId);
791 }
792
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700793 protected RecentTasks createRecentTasks() {
794 return new RecentTasks(this, mStackSupervisor);
795 }
796
797 RecentTasks getRecentTasks() {
798 return mRecentTasks;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700799 }
800
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700801 ClientLifecycleManager getLifecycleManager() {
802 return mLifecycleManager;
803 }
804
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700805 ActivityStartController getActivityStartController() {
806 return mActivityStartController;
807 }
808
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700809 TaskChangeNotificationController getTaskChangeNotificationController() {
810 return mTaskChangeNotificationController;
811 }
812
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700813 LockTaskController getLockTaskController() {
814 return mLockTaskController;
815 }
816
Yunfan Chen75157d72018-07-27 14:47:21 +0900817 /**
818 * Return the global configuration used by the process corresponding to the input pid. This is
819 * usually the global configuration with some overrides specific to that process.
820 */
821 Configuration getGlobalConfigurationForCallingPid() {
822 final int pid = Binder.getCallingPid();
823 if (pid == MY_PID || pid < 0) {
824 return getGlobalConfiguration();
825 }
826 synchronized (mGlobalLock) {
827 final WindowProcessController app = mPidMap.get(pid);
828 return app != null ? app.getConfiguration() : getGlobalConfiguration();
829 }
830 }
831
832 /**
833 * Return the device configuration info used by the process corresponding to the input pid.
834 * The value is consistent with the global configuration for the process.
835 */
836 @Override
837 public ConfigurationInfo getDeviceConfigurationInfo() {
838 ConfigurationInfo config = new ConfigurationInfo();
839 synchronized (mGlobalLock) {
840 final Configuration globalConfig = getGlobalConfigurationForCallingPid();
841 config.reqTouchScreen = globalConfig.touchscreen;
842 config.reqKeyboardType = globalConfig.keyboard;
843 config.reqNavigation = globalConfig.navigation;
844 if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
845 || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
846 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
847 }
848 if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
849 && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
850 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
851 }
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700852 config.reqGlEsVersion = GL_ES_VERSION;
Yunfan Chen75157d72018-07-27 14:47:21 +0900853 }
854 return config;
855 }
856
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700857 private void start() {
Wale Ogunwale53783742018-09-16 10:21:51 -0700858 mInternal = new LocalService();
859 LocalServices.addService(ActivityTaskManagerInternal.class, mInternal);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700860 }
861
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700862 public static final class Lifecycle extends SystemService {
863 private final ActivityTaskManagerService mService;
864
865 public Lifecycle(Context context) {
866 super(context);
867 mService = new ActivityTaskManagerService(context);
868 }
869
870 @Override
871 public void onStart() {
872 publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700873 mService.start();
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700874 }
875
876 public ActivityTaskManagerService getService() {
877 return mService;
878 }
879 }
880
881 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700882 public final int startActivity(IApplicationThread caller, String callingPackage,
883 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
884 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
885 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
886 resultWho, requestCode, startFlags, profilerInfo, bOptions,
887 UserHandle.getCallingUserId());
888 }
889
890 @Override
891 public final int startActivities(IApplicationThread caller, String callingPackage,
892 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
893 int userId) {
894 final String reason = "startActivities";
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700895 enforceNotIsolatedCaller(reason);
896 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, reason);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700897 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700898 return getActivityStartController().startActivities(caller, -1, callingPackage, intents,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100899 resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId, reason,
900 null /* originatingPendingIntent */);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700901 }
902
903 @Override
904 public int startActivityAsUser(IApplicationThread caller, String callingPackage,
905 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
906 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
907 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
908 resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
909 true /*validateIncomingUser*/);
910 }
911
912 int startActivityAsUser(IApplicationThread caller, String callingPackage,
913 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
914 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
915 boolean validateIncomingUser) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700916 enforceNotIsolatedCaller("startActivityAsUser");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700917
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700918 userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700919 Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
920
921 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700922 return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700923 .setCaller(caller)
924 .setCallingPackage(callingPackage)
925 .setResolvedType(resolvedType)
926 .setResultTo(resultTo)
927 .setResultWho(resultWho)
928 .setRequestCode(requestCode)
929 .setStartFlags(startFlags)
930 .setProfilerInfo(profilerInfo)
931 .setActivityOptions(bOptions)
932 .setMayWait(userId)
933 .execute();
934
935 }
936
937 @Override
938 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
939 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700940 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions) {
941 enforceNotIsolatedCaller("startActivityIntentSender");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700942 // Refuse possible leaked file descriptors
943 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
944 throw new IllegalArgumentException("File descriptors passed in Intent");
945 }
946
947 if (!(target instanceof PendingIntentRecord)) {
948 throw new IllegalArgumentException("Bad PendingIntent object");
949 }
950
951 PendingIntentRecord pir = (PendingIntentRecord)target;
952
953 synchronized (mGlobalLock) {
954 // If this is coming from the currently resumed activity, it is
955 // effectively saying that app switches are allowed at this point.
Andrii Kulian5f750bc2018-07-17 08:57:23 -0700956 final ActivityStack stack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700957 if (stack.mResumedActivity != null &&
958 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700959 mAppSwitchesAllowedTime = 0;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700960 }
961 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700962 return pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700963 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700964 }
965
966 @Override
967 public boolean startNextMatchingActivity(IBinder callingActivity, Intent intent,
968 Bundle bOptions) {
969 // Refuse possible leaked file descriptors
970 if (intent != null && intent.hasFileDescriptors()) {
971 throw new IllegalArgumentException("File descriptors passed in Intent");
972 }
973 SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
974
975 synchronized (mGlobalLock) {
976 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
977 if (r == null) {
978 SafeActivityOptions.abort(options);
979 return false;
980 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700981 if (!r.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700982 // The caller is not running... d'oh!
983 SafeActivityOptions.abort(options);
984 return false;
985 }
986 intent = new Intent(intent);
987 // The caller is not allowed to change the data.
988 intent.setDataAndType(r.intent.getData(), r.intent.getType());
989 // And we are resetting to find the next component...
990 intent.setComponent(null);
991
992 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
993
994 ActivityInfo aInfo = null;
995 try {
996 List<ResolveInfo> resolves =
997 AppGlobals.getPackageManager().queryIntentActivities(
998 intent, r.resolvedType,
999 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
1000 UserHandle.getCallingUserId()).getList();
1001
1002 // Look for the original activity in the list...
1003 final int N = resolves != null ? resolves.size() : 0;
1004 for (int i=0; i<N; i++) {
1005 ResolveInfo rInfo = resolves.get(i);
1006 if (rInfo.activityInfo.packageName.equals(r.packageName)
1007 && rInfo.activityInfo.name.equals(r.info.name)) {
1008 // We found the current one... the next matching is
1009 // after it.
1010 i++;
1011 if (i<N) {
1012 aInfo = resolves.get(i).activityInfo;
1013 }
1014 if (debug) {
1015 Slog.v(TAG, "Next matching activity: found current " + r.packageName
1016 + "/" + r.info.name);
1017 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
1018 ? "null" : aInfo.packageName + "/" + aInfo.name));
1019 }
1020 break;
1021 }
1022 }
1023 } catch (RemoteException e) {
1024 }
1025
1026 if (aInfo == null) {
1027 // Nobody who is next!
1028 SafeActivityOptions.abort(options);
1029 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
1030 return false;
1031 }
1032
1033 intent.setComponent(new ComponentName(
1034 aInfo.applicationInfo.packageName, aInfo.name));
1035 intent.setFlags(intent.getFlags()&~(
1036 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
1037 Intent.FLAG_ACTIVITY_CLEAR_TOP|
1038 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
1039 FLAG_ACTIVITY_NEW_TASK));
1040
1041 // Okay now we need to start the new activity, replacing the currently running activity.
1042 // This is a little tricky because we want to start the new one as if the current one is
1043 // finished, but not finish the current one first so that there is no flicker.
1044 // And thus...
1045 final boolean wasFinishing = r.finishing;
1046 r.finishing = true;
1047
1048 // Propagate reply information over to the new activity.
1049 final ActivityRecord resultTo = r.resultTo;
1050 final String resultWho = r.resultWho;
1051 final int requestCode = r.requestCode;
1052 r.resultTo = null;
1053 if (resultTo != null) {
1054 resultTo.removeResultsLocked(r, resultWho, requestCode);
1055 }
1056
1057 final long origId = Binder.clearCallingIdentity();
1058 // TODO(b/64750076): Check if calling pid should really be -1.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001059 final int res = getActivityStartController()
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001060 .obtainStarter(intent, "startNextMatchingActivity")
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001061 .setCaller(r.app.getThread())
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001062 .setResolvedType(r.resolvedType)
1063 .setActivityInfo(aInfo)
1064 .setResultTo(resultTo != null ? resultTo.appToken : null)
1065 .setResultWho(resultWho)
1066 .setRequestCode(requestCode)
1067 .setCallingPid(-1)
1068 .setCallingUid(r.launchedFromUid)
1069 .setCallingPackage(r.launchedFromPackage)
1070 .setRealCallingPid(-1)
1071 .setRealCallingUid(r.launchedFromUid)
1072 .setActivityOptions(options)
1073 .execute();
1074 Binder.restoreCallingIdentity(origId);
1075
1076 r.finishing = wasFinishing;
1077 if (res != ActivityManager.START_SUCCESS) {
1078 return false;
1079 }
1080 return true;
1081 }
1082 }
1083
1084 @Override
1085 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
1086 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1087 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
1088 final WaitResult res = new WaitResult();
1089 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001090 enforceNotIsolatedCaller("startActivityAndWait");
1091 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
1092 userId, "startActivityAndWait");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001093 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001094 getActivityStartController().obtainStarter(intent, "startActivityAndWait")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001095 .setCaller(caller)
1096 .setCallingPackage(callingPackage)
1097 .setResolvedType(resolvedType)
1098 .setResultTo(resultTo)
1099 .setResultWho(resultWho)
1100 .setRequestCode(requestCode)
1101 .setStartFlags(startFlags)
1102 .setActivityOptions(bOptions)
1103 .setMayWait(userId)
1104 .setProfilerInfo(profilerInfo)
1105 .setWaitResult(res)
1106 .execute();
1107 }
1108 return res;
1109 }
1110
1111 @Override
1112 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
1113 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1114 int startFlags, Configuration config, Bundle bOptions, int userId) {
1115 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001116 enforceNotIsolatedCaller("startActivityWithConfig");
1117 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
1118 "startActivityWithConfig");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001119 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001120 return getActivityStartController().obtainStarter(intent, "startActivityWithConfig")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001121 .setCaller(caller)
1122 .setCallingPackage(callingPackage)
1123 .setResolvedType(resolvedType)
1124 .setResultTo(resultTo)
1125 .setResultWho(resultWho)
1126 .setRequestCode(requestCode)
1127 .setStartFlags(startFlags)
1128 .setGlobalConfiguration(config)
1129 .setActivityOptions(bOptions)
1130 .setMayWait(userId)
1131 .execute();
1132 }
1133 }
1134
1135 @Override
1136 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
1137 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1138 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
1139 int userId) {
1140
1141 // This is very dangerous -- it allows you to perform a start activity (including
1142 // permission grants) as any app that may launch one of your own activities. So
1143 // we will only allow this to be done from activities that are part of the core framework,
1144 // and then only when they are running as the system.
1145 final ActivityRecord sourceRecord;
1146 final int targetUid;
1147 final String targetPackage;
1148 final boolean isResolver;
1149 synchronized (mGlobalLock) {
1150 if (resultTo == null) {
1151 throw new SecurityException("Must be called from an activity");
1152 }
1153 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
1154 if (sourceRecord == null) {
1155 throw new SecurityException("Called with bad activity token: " + resultTo);
1156 }
1157 if (!sourceRecord.info.packageName.equals("android")) {
1158 throw new SecurityException(
1159 "Must be called from an activity that is declared in the android package");
1160 }
1161 if (sourceRecord.app == null) {
1162 throw new SecurityException("Called without a process attached to activity");
1163 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001164 if (UserHandle.getAppId(sourceRecord.app.mUid) != SYSTEM_UID) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001165 // This is still okay, as long as this activity is running under the
1166 // uid of the original calling activity.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001167 if (sourceRecord.app.mUid != sourceRecord.launchedFromUid) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001168 throw new SecurityException(
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001169 "Calling activity in uid " + sourceRecord.app.mUid
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001170 + " must be system uid or original calling uid "
1171 + sourceRecord.launchedFromUid);
1172 }
1173 }
1174 if (ignoreTargetSecurity) {
1175 if (intent.getComponent() == null) {
1176 throw new SecurityException(
1177 "Component must be specified with ignoreTargetSecurity");
1178 }
1179 if (intent.getSelector() != null) {
1180 throw new SecurityException(
1181 "Selector not allowed with ignoreTargetSecurity");
1182 }
1183 }
1184 targetUid = sourceRecord.launchedFromUid;
1185 targetPackage = sourceRecord.launchedFromPackage;
1186 isResolver = sourceRecord.isResolverOrChildActivity();
1187 }
1188
1189 if (userId == UserHandle.USER_NULL) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001190 userId = UserHandle.getUserId(sourceRecord.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001191 }
1192
1193 // TODO: Switch to user app stacks here.
1194 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001195 return getActivityStartController().obtainStarter(intent, "startActivityAsCaller")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001196 .setCallingUid(targetUid)
1197 .setCallingPackage(targetPackage)
1198 .setResolvedType(resolvedType)
1199 .setResultTo(resultTo)
1200 .setResultWho(resultWho)
1201 .setRequestCode(requestCode)
1202 .setStartFlags(startFlags)
1203 .setActivityOptions(bOptions)
1204 .setMayWait(userId)
1205 .setIgnoreTargetSecurity(ignoreTargetSecurity)
1206 .setFilterCallingUid(isResolver ? 0 /* system */ : targetUid)
1207 .execute();
1208 } catch (SecurityException e) {
1209 // XXX need to figure out how to propagate to original app.
1210 // A SecurityException here is generally actually a fault of the original
1211 // calling activity (such as a fairly granting permissions), so propagate it
1212 // back to them.
1213 /*
1214 StringBuilder msg = new StringBuilder();
1215 msg.append("While launching");
1216 msg.append(intent.toString());
1217 msg.append(": ");
1218 msg.append(e.getMessage());
1219 */
1220 throw e;
1221 }
1222 }
1223
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001224 int handleIncomingUser(int callingPid, int callingUid, int userId, String name) {
1225 return mAmInternal.handleIncomingUser(callingPid, callingUid, userId, false /* allowAll */,
1226 ALLOW_FULL_ONLY, name, null /* callerPackage */);
1227 }
1228
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001229 @Override
1230 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
1231 Intent intent, String resolvedType, IVoiceInteractionSession session,
1232 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
1233 Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001234 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001235 if (session == null || interactor == null) {
1236 throw new NullPointerException("null session or interactor");
1237 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001238 userId = handleIncomingUser(callingPid, callingUid, userId, "startVoiceActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001239 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001240 return getActivityStartController().obtainStarter(intent, "startVoiceActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001241 .setCallingUid(callingUid)
1242 .setCallingPackage(callingPackage)
1243 .setResolvedType(resolvedType)
1244 .setVoiceSession(session)
1245 .setVoiceInteractor(interactor)
1246 .setStartFlags(startFlags)
1247 .setProfilerInfo(profilerInfo)
1248 .setActivityOptions(bOptions)
1249 .setMayWait(userId)
1250 .execute();
1251 }
1252
1253 @Override
1254 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
1255 Intent intent, String resolvedType, Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001256 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
1257 userId = handleIncomingUser(callingPid, callingUid, userId, "startAssistantActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001258
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001259 return getActivityStartController().obtainStarter(intent, "startAssistantActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001260 .setCallingUid(callingUid)
1261 .setCallingPackage(callingPackage)
1262 .setResolvedType(resolvedType)
1263 .setActivityOptions(bOptions)
1264 .setMayWait(userId)
1265 .execute();
1266 }
1267
1268 @Override
1269 public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
1270 IRecentsAnimationRunner recentsAnimationRunner) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001271 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001272 final int callingPid = Binder.getCallingPid();
1273 final long origId = Binder.clearCallingIdentity();
1274 try {
1275 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07001276 final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
1277 final int recentsUid = mRecentTasks.getRecentsComponentUid();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001278
1279 // Start a new recents animation
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001280 final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
1281 getActivityStartController(), mWindowManager, callingPid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001282 anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
1283 recentsUid, assistDataReceiver);
1284 }
1285 } finally {
1286 Binder.restoreCallingIdentity(origId);
1287 }
1288 }
1289
1290 @Override
1291 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001292 enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001293 "startActivityFromRecents()");
1294
1295 final int callingPid = Binder.getCallingPid();
1296 final int callingUid = Binder.getCallingUid();
1297 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(bOptions);
1298 final long origId = Binder.clearCallingIdentity();
1299 try {
1300 synchronized (mGlobalLock) {
1301 return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
1302 safeOptions);
1303 }
1304 } finally {
1305 Binder.restoreCallingIdentity(origId);
1306 }
1307 }
1308
1309 /**
1310 * This is the internal entry point for handling Activity.finish().
1311 *
1312 * @param token The Binder token referencing the Activity we want to finish.
1313 * @param resultCode Result code, if any, from this Activity.
1314 * @param resultData Result data (Intent), if any, from this Activity.
1315 * @param finishTask Whether to finish the task associated with this Activity.
1316 *
1317 * @return Returns true if the activity successfully finished, or false if it is still running.
1318 */
1319 @Override
1320 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
1321 int finishTask) {
1322 // Refuse possible leaked file descriptors
1323 if (resultData != null && resultData.hasFileDescriptors()) {
1324 throw new IllegalArgumentException("File descriptors passed in Intent");
1325 }
1326
1327 synchronized (mGlobalLock) {
1328 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1329 if (r == null) {
1330 return true;
1331 }
1332 // Keep track of the root activity of the task before we finish it
1333 TaskRecord tr = r.getTask();
1334 ActivityRecord rootR = tr.getRootActivity();
1335 if (rootR == null) {
1336 Slog.w(TAG, "Finishing task with all activities already finished");
1337 }
1338 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
1339 // finish.
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001340 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001341 return false;
1342 }
1343
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001344 // TODO: There is a dup. of this block of code in ActivityStack.navigateUpToLocked
1345 // We should consolidate.
1346 if (mController != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001347 // Find the first activity that is not finishing.
1348 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
1349 if (next != null) {
1350 // ask watcher if this is allowed
1351 boolean resumeOK = true;
1352 try {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001353 resumeOK = mController.activityResuming(next.packageName);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001354 } catch (RemoteException e) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001355 mController = null;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001356 Watchdog.getInstance().setActivityController(null);
1357 }
1358
1359 if (!resumeOK) {
1360 Slog.i(TAG, "Not finishing activity because controller resumed");
1361 return false;
1362 }
1363 }
1364 }
1365 final long origId = Binder.clearCallingIdentity();
1366 try {
1367 boolean res;
1368 final boolean finishWithRootActivity =
1369 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
1370 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
1371 || (finishWithRootActivity && r == rootR)) {
1372 // If requested, remove the task that is associated to this activity only if it
1373 // was the root activity in the task. The result code and data is ignored
1374 // because we don't support returning them across task boundaries. Also, to
1375 // keep backwards compatibility we remove the task from recents when finishing
1376 // task with root activity.
1377 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
1378 finishWithRootActivity, "finish-activity");
1379 if (!res) {
1380 Slog.i(TAG, "Removing task failed to finish activity");
1381 }
Garfield Tan2746ab52018-07-25 12:33:01 -07001382 // Explicitly dismissing the activity so reset its relaunch flag.
Wale Ogunwale64258362018-10-16 15:13:37 -07001383 r.mRelaunchReason = RELAUNCH_REASON_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001384 } else {
1385 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
1386 resultData, "app-request", true);
1387 if (!res) {
1388 Slog.i(TAG, "Failed to finish by app-request");
1389 }
1390 }
1391 return res;
1392 } finally {
1393 Binder.restoreCallingIdentity(origId);
1394 }
1395 }
1396 }
1397
1398 @Override
1399 public boolean finishActivityAffinity(IBinder token) {
1400 synchronized (mGlobalLock) {
1401 final long origId = Binder.clearCallingIdentity();
1402 try {
1403 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1404 if (r == null) {
1405 return false;
1406 }
1407
1408 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
1409 // can finish.
1410 final TaskRecord task = r.getTask();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001411 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001412 return false;
1413 }
1414 return task.getStack().finishActivityAffinityLocked(r);
1415 } finally {
1416 Binder.restoreCallingIdentity(origId);
1417 }
1418 }
1419 }
1420
1421 @Override
1422 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
1423 final long origId = Binder.clearCallingIdentity();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001424 try {
1425 WindowProcessController proc = null;
1426 synchronized (mGlobalLock) {
1427 ActivityStack stack = ActivityRecord.getStackLocked(token);
1428 if (stack == null) {
1429 return;
1430 }
1431 final ActivityRecord r = mStackSupervisor.activityIdleInternalLocked(token,
1432 false /* fromTimeout */, false /* processPausingActivities */, config);
1433 if (r != null) {
1434 proc = r.app;
1435 }
1436 if (stopProfiling && proc != null) {
1437 proc.clearProfilerIfNeeded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001438 }
1439 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001440 } finally {
1441 Binder.restoreCallingIdentity(origId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001442 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001443 }
1444
1445 @Override
1446 public final void activityResumed(IBinder token) {
1447 final long origId = Binder.clearCallingIdentity();
1448 synchronized (mGlobalLock) {
1449 ActivityRecord.activityResumedLocked(token);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001450 mWindowManager.notifyAppResumedFinished(token);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001451 }
1452 Binder.restoreCallingIdentity(origId);
1453 }
1454
1455 @Override
1456 public final void activityPaused(IBinder token) {
1457 final long origId = Binder.clearCallingIdentity();
1458 synchronized (mGlobalLock) {
1459 ActivityStack stack = ActivityRecord.getStackLocked(token);
1460 if (stack != null) {
1461 stack.activityPausedLocked(token, false);
1462 }
1463 }
1464 Binder.restoreCallingIdentity(origId);
1465 }
1466
1467 @Override
1468 public final void activityStopped(IBinder token, Bundle icicle,
1469 PersistableBundle persistentState, CharSequence description) {
1470 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
1471
1472 // Refuse possible leaked file descriptors
1473 if (icicle != null && icicle.hasFileDescriptors()) {
1474 throw new IllegalArgumentException("File descriptors passed in Bundle");
1475 }
1476
1477 final long origId = Binder.clearCallingIdentity();
1478
1479 synchronized (mGlobalLock) {
1480 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1481 if (r != null) {
1482 r.activityStoppedLocked(icicle, persistentState, description);
1483 }
1484 }
1485
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001486 mAmInternal.trimApplications();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001487
1488 Binder.restoreCallingIdentity(origId);
1489 }
1490
1491 @Override
1492 public final void activityDestroyed(IBinder token) {
1493 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
1494 synchronized (mGlobalLock) {
1495 ActivityStack stack = ActivityRecord.getStackLocked(token);
1496 if (stack != null) {
1497 stack.activityDestroyedLocked(token, "activityDestroyed");
1498 }
1499 }
1500 }
1501
1502 @Override
1503 public final void activityRelaunched(IBinder token) {
1504 final long origId = Binder.clearCallingIdentity();
1505 synchronized (mGlobalLock) {
1506 mStackSupervisor.activityRelaunchedLocked(token);
1507 }
1508 Binder.restoreCallingIdentity(origId);
1509 }
1510
1511 public final void activitySlept(IBinder token) {
1512 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
1513
1514 final long origId = Binder.clearCallingIdentity();
1515
1516 synchronized (mGlobalLock) {
1517 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1518 if (r != null) {
1519 mStackSupervisor.activitySleptLocked(r);
1520 }
1521 }
1522
1523 Binder.restoreCallingIdentity(origId);
1524 }
1525
1526 @Override
1527 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
1528 synchronized (mGlobalLock) {
1529 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1530 if (r == null) {
1531 return;
1532 }
1533 final long origId = Binder.clearCallingIdentity();
1534 try {
1535 r.setRequestedOrientation(requestedOrientation);
1536 } finally {
1537 Binder.restoreCallingIdentity(origId);
1538 }
1539 }
1540 }
1541
1542 @Override
1543 public int getRequestedOrientation(IBinder token) {
1544 synchronized (mGlobalLock) {
1545 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1546 if (r == null) {
1547 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
1548 }
1549 return r.getRequestedOrientation();
1550 }
1551 }
1552
1553 @Override
1554 public void setImmersive(IBinder token, boolean immersive) {
1555 synchronized (mGlobalLock) {
1556 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1557 if (r == null) {
1558 throw new IllegalArgumentException();
1559 }
1560 r.immersive = immersive;
1561
1562 // update associated state if we're frontmost
Andrii Kulian52d255c2018-07-13 11:32:19 -07001563 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001564 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001565 applyUpdateLockStateLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001566 }
1567 }
1568 }
1569
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001570 void applyUpdateLockStateLocked(ActivityRecord r) {
1571 // Modifications to the UpdateLock state are done on our handler, outside
1572 // the activity manager's locks. The new state is determined based on the
1573 // state *now* of the relevant activity record. The object is passed to
1574 // the handler solely for logging detail, not to be consulted/modified.
1575 final boolean nextState = r != null && r.immersive;
1576 mH.post(() -> {
1577 if (mUpdateLock.isHeld() != nextState) {
1578 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1579 "Applying new update lock state '" + nextState + "' for " + r);
1580 if (nextState) {
1581 mUpdateLock.acquire();
1582 } else {
1583 mUpdateLock.release();
1584 }
1585 }
1586 });
1587 }
1588
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001589 @Override
1590 public boolean isImmersive(IBinder token) {
1591 synchronized (mGlobalLock) {
1592 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1593 if (r == null) {
1594 throw new IllegalArgumentException();
1595 }
1596 return r.immersive;
1597 }
1598 }
1599
1600 @Override
1601 public boolean isTopActivityImmersive() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001602 enforceNotIsolatedCaller("isTopActivityImmersive");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001603 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001604 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001605 return (r != null) ? r.immersive : false;
1606 }
1607 }
1608
1609 @Override
1610 public void overridePendingTransition(IBinder token, String packageName,
1611 int enterAnim, int exitAnim) {
1612 synchronized (mGlobalLock) {
1613 ActivityRecord self = ActivityRecord.isInStackLocked(token);
1614 if (self == null) {
1615 return;
1616 }
1617
1618 final long origId = Binder.clearCallingIdentity();
1619
1620 if (self.isState(
1621 ActivityStack.ActivityState.RESUMED, ActivityStack.ActivityState.PAUSING)) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001622 mWindowManager.overridePendingAppTransition(packageName,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001623 enterAnim, exitAnim, null);
1624 }
1625
1626 Binder.restoreCallingIdentity(origId);
1627 }
1628 }
1629
1630 @Override
1631 public int getFrontActivityScreenCompatMode() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001632 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001633 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001634 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001635 if (r == null) {
1636 return ActivityManager.COMPAT_MODE_UNKNOWN;
1637 }
Wale Ogunwale53783742018-09-16 10:21:51 -07001638 return mCompatModePackages.computeCompatModeLocked(r.info.applicationInfo);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001639 }
1640 }
1641
1642 @Override
1643 public void setFrontActivityScreenCompatMode(int mode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001644 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001645 "setFrontActivityScreenCompatMode");
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001646 ApplicationInfo ai;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001647 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001648 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001649 if (r == null) {
1650 Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity");
1651 return;
1652 }
1653 ai = r.info.applicationInfo;
Wale Ogunwale53783742018-09-16 10:21:51 -07001654 mCompatModePackages.setPackageScreenCompatModeLocked(ai, mode);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001655 }
1656 }
1657
1658 @Override
1659 public int getLaunchedFromUid(IBinder activityToken) {
1660 ActivityRecord srec;
1661 synchronized (mGlobalLock) {
1662 srec = ActivityRecord.forTokenLocked(activityToken);
1663 }
1664 if (srec == null) {
1665 return -1;
1666 }
1667 return srec.launchedFromUid;
1668 }
1669
1670 @Override
1671 public String getLaunchedFromPackage(IBinder activityToken) {
1672 ActivityRecord srec;
1673 synchronized (mGlobalLock) {
1674 srec = ActivityRecord.forTokenLocked(activityToken);
1675 }
1676 if (srec == null) {
1677 return null;
1678 }
1679 return srec.launchedFromPackage;
1680 }
1681
1682 @Override
1683 public boolean convertFromTranslucent(IBinder token) {
1684 final long origId = Binder.clearCallingIdentity();
1685 try {
1686 synchronized (mGlobalLock) {
1687 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1688 if (r == null) {
1689 return false;
1690 }
1691 final boolean translucentChanged = r.changeWindowTranslucency(true);
1692 if (translucentChanged) {
1693 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
1694 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001695 mWindowManager.setAppFullscreen(token, true);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001696 return translucentChanged;
1697 }
1698 } finally {
1699 Binder.restoreCallingIdentity(origId);
1700 }
1701 }
1702
1703 @Override
1704 public boolean convertToTranslucent(IBinder token, Bundle options) {
1705 SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
1706 final long origId = Binder.clearCallingIdentity();
1707 try {
1708 synchronized (mGlobalLock) {
1709 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1710 if (r == null) {
1711 return false;
1712 }
1713 final TaskRecord task = r.getTask();
1714 int index = task.mActivities.lastIndexOf(r);
1715 if (index > 0) {
1716 ActivityRecord under = task.mActivities.get(index - 1);
1717 under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
1718 }
1719 final boolean translucentChanged = r.changeWindowTranslucency(false);
1720 if (translucentChanged) {
1721 r.getStack().convertActivityToTranslucent(r);
1722 }
1723 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001724 mWindowManager.setAppFullscreen(token, false);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001725 return translucentChanged;
1726 }
1727 } finally {
1728 Binder.restoreCallingIdentity(origId);
1729 }
1730 }
1731
1732 @Override
1733 public void notifyActivityDrawn(IBinder token) {
1734 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
1735 synchronized (mGlobalLock) {
1736 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
1737 if (r != null) {
1738 r.getStack().notifyActivityDrawnLocked(r);
1739 }
1740 }
1741 }
1742
1743 @Override
1744 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
1745 synchronized (mGlobalLock) {
1746 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1747 if (r == null) {
1748 return;
1749 }
1750 r.reportFullyDrawnLocked(restoredFromBundle);
1751 }
1752 }
1753
1754 @Override
1755 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
1756 synchronized (mGlobalLock) {
1757 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
1758 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
1759 return stack.mDisplayId;
1760 }
1761 return DEFAULT_DISPLAY;
1762 }
1763 }
1764
1765 @Override
1766 public ActivityManager.StackInfo getFocusedStackInfo() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001767 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001768 long ident = Binder.clearCallingIdentity();
1769 try {
1770 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001771 ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001772 if (focusedStack != null) {
1773 return mStackSupervisor.getStackInfo(focusedStack.mStackId);
1774 }
1775 return null;
1776 }
1777 } finally {
1778 Binder.restoreCallingIdentity(ident);
1779 }
1780 }
1781
1782 @Override
1783 public void setFocusedStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001784 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001785 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
1786 final long callingId = Binder.clearCallingIdentity();
1787 try {
1788 synchronized (mGlobalLock) {
1789 final ActivityStack stack = mStackSupervisor.getStack(stackId);
1790 if (stack == null) {
1791 Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
1792 return;
1793 }
1794 final ActivityRecord r = stack.topRunningActivityLocked();
Louis Chang19443452018-10-09 12:10:21 +08001795 if (r != null && r.moveFocusableActivityToTop("setFocusedStack")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08001796 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001797 }
1798 }
1799 } finally {
1800 Binder.restoreCallingIdentity(callingId);
1801 }
1802 }
1803
1804 @Override
1805 public void setFocusedTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001806 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001807 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
1808 final long callingId = Binder.clearCallingIdentity();
1809 try {
1810 synchronized (mGlobalLock) {
1811 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1812 if (task == null) {
1813 return;
1814 }
1815 final ActivityRecord r = task.topRunningActivityLocked();
Louis Chang19443452018-10-09 12:10:21 +08001816 if (r != null && r.moveFocusableActivityToTop("setFocusedTask")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08001817 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001818 }
1819 }
1820 } finally {
1821 Binder.restoreCallingIdentity(callingId);
1822 }
1823 }
1824
1825 @Override
1826 public boolean removeTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001827 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001828 synchronized (mGlobalLock) {
1829 final long ident = Binder.clearCallingIdentity();
1830 try {
1831 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
1832 "remove-task");
1833 } finally {
1834 Binder.restoreCallingIdentity(ident);
1835 }
1836 }
1837 }
1838
1839 @Override
Winson Chunge6439102018-07-30 15:48:01 -07001840 public void removeAllVisibleRecentTasks() {
1841 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeAllVisibleRecentTasks()");
1842 synchronized (mGlobalLock) {
1843 final long ident = Binder.clearCallingIdentity();
1844 try {
1845 getRecentTasks().removeAllVisibleTasks();
1846 } finally {
1847 Binder.restoreCallingIdentity(ident);
1848 }
1849 }
1850 }
1851
1852 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001853 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
1854 synchronized (mGlobalLock) {
1855 final ActivityRecord srec = ActivityRecord.forTokenLocked(token);
1856 if (srec != null) {
1857 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
1858 }
1859 }
1860 return false;
1861 }
1862
1863 @Override
1864 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
1865 Intent resultData) {
1866
1867 synchronized (mGlobalLock) {
1868 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
1869 if (r != null) {
1870 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
1871 }
1872 return false;
1873 }
1874 }
1875
1876 /**
1877 * Attempts to move a task backwards in z-order (the order of activities within the task is
1878 * unchanged).
1879 *
1880 * There are several possible results of this call:
1881 * - if the task is locked, then we will show the lock toast
1882 * - if there is a task behind the provided task, then that task is made visible and resumed as
1883 * this task is moved to the back
1884 * - otherwise, if there are no other tasks in the stack:
1885 * - if this task is in the pinned stack, then we remove the stack completely, which will
1886 * have the effect of moving the task to the top or bottom of the fullscreen stack
1887 * (depending on whether it is visible)
1888 * - otherwise, we simply return home and hide this task
1889 *
1890 * @param token A reference to the activity we wish to move
1891 * @param nonRoot If false then this only works if the activity is the root
1892 * of a task; if true it will work for any activity in a task.
1893 * @return Returns true if the move completed, false if not.
1894 */
1895 @Override
1896 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001897 enforceNotIsolatedCaller("moveActivityTaskToBack");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001898 synchronized (mGlobalLock) {
1899 final long origId = Binder.clearCallingIdentity();
1900 try {
1901 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
1902 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1903 if (task != null) {
1904 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
1905 }
1906 } finally {
1907 Binder.restoreCallingIdentity(origId);
1908 }
1909 }
1910 return false;
1911 }
1912
1913 @Override
1914 public Rect getTaskBounds(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001915 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001916 long ident = Binder.clearCallingIdentity();
1917 Rect rect = new Rect();
1918 try {
1919 synchronized (mGlobalLock) {
1920 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
1921 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1922 if (task == null) {
1923 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
1924 return rect;
1925 }
1926 if (task.getStack() != null) {
1927 // Return the bounds from window manager since it will be adjusted for various
1928 // things like the presense of a docked stack for tasks that aren't resizeable.
1929 task.getWindowContainerBounds(rect);
1930 } else {
1931 // Task isn't in window manager yet since it isn't associated with a stack.
1932 // Return the persist value from activity manager
1933 if (!task.matchParentBounds()) {
1934 rect.set(task.getBounds());
1935 } else if (task.mLastNonFullscreenBounds != null) {
1936 rect.set(task.mLastNonFullscreenBounds);
1937 }
1938 }
1939 }
1940 } finally {
1941 Binder.restoreCallingIdentity(ident);
1942 }
1943 return rect;
1944 }
1945
1946 @Override
1947 public ActivityManager.TaskDescription getTaskDescription(int id) {
1948 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001949 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001950 MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
1951 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
1952 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1953 if (tr != null) {
1954 return tr.lastTaskDescription;
1955 }
1956 }
1957 return null;
1958 }
1959
1960 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001961 public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
1962 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
1963 setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
1964 toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
1965 return;
1966 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001967 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001968 synchronized (mGlobalLock) {
1969 final long ident = Binder.clearCallingIdentity();
1970 try {
1971 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1972 if (task == null) {
1973 Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
1974 return;
1975 }
1976
1977 if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
1978 + " to windowingMode=" + windowingMode + " toTop=" + toTop);
1979
1980 if (!task.isActivityTypeStandardOrUndefined()) {
1981 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
1982 + " non-standard task " + taskId + " to windowing mode="
1983 + windowingMode);
1984 }
1985
1986 final ActivityStack stack = task.getStack();
1987 if (toTop) {
1988 stack.moveToFront("setTaskWindowingMode", task);
1989 }
1990 stack.setWindowingMode(windowingMode);
1991 } finally {
1992 Binder.restoreCallingIdentity(ident);
1993 }
1994 }
1995 }
1996
1997 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001998 public String getCallingPackage(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001999 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002000 ActivityRecord r = getCallingRecordLocked(token);
2001 return r != null ? r.info.packageName : null;
2002 }
2003 }
2004
2005 @Override
2006 public ComponentName getCallingActivity(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002007 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002008 ActivityRecord r = getCallingRecordLocked(token);
2009 return r != null ? r.intent.getComponent() : null;
2010 }
2011 }
2012
2013 private ActivityRecord getCallingRecordLocked(IBinder token) {
2014 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2015 if (r == null) {
2016 return null;
2017 }
2018 return r.resultTo;
2019 }
2020
2021 @Override
2022 public void unhandledBack() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002023 mAmInternal.enforceCallingPermission(android.Manifest.permission.FORCE_BACK, "unhandledBack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002024
2025 synchronized (mGlobalLock) {
2026 final long origId = Binder.clearCallingIdentity();
2027 try {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002028 getTopDisplayFocusedStack().unhandledBackLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002029 } finally {
2030 Binder.restoreCallingIdentity(origId);
2031 }
2032 }
2033 }
2034
2035 /**
2036 * TODO: Add mController hook
2037 */
2038 @Override
2039 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002040 mAmInternal.enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002041
2042 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
2043 synchronized (mGlobalLock) {
2044 moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
2045 false /* fromRecents */);
2046 }
2047 }
2048
2049 void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
2050 boolean fromRecents) {
2051
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002052 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002053 Binder.getCallingUid(), -1, -1, "Task to front")) {
2054 SafeActivityOptions.abort(options);
2055 return;
2056 }
2057 final long origId = Binder.clearCallingIdentity();
2058 try {
2059 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2060 if (task == null) {
2061 Slog.d(TAG, "Could not find task for id: "+ taskId);
Winson Chungd0243682018-09-25 18:11:54 -07002062 SafeActivityOptions.abort(options);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002063 return;
2064 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002065 if (getLockTaskController().isLockTaskModeViolation(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002066 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
Winson Chungd0243682018-09-25 18:11:54 -07002067 SafeActivityOptions.abort(options);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002068 return;
2069 }
2070 ActivityOptions realOptions = options != null
2071 ? options.getOptions(mStackSupervisor)
2072 : null;
2073 mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
2074 false /* forceNonResizable */);
2075
2076 final ActivityRecord topActivity = task.getTopActivity();
2077 if (topActivity != null) {
2078
2079 // We are reshowing a task, use a starting window to hide the initial draw delay
2080 // so the transition can start earlier.
2081 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
2082 true /* taskSwitch */, fromRecents);
2083 }
2084 } finally {
2085 Binder.restoreCallingIdentity(origId);
2086 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002087 }
2088
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002089 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
2090 int callingPid, int callingUid, String name) {
2091 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
2092 return true;
2093 }
2094
2095 if (getRecentTasks().isCallerRecents(sourceUid)) {
2096 return true;
2097 }
2098
2099 int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
2100 if (perm == PackageManager.PERMISSION_GRANTED) {
2101 return true;
2102 }
2103 if (checkAllowAppSwitchUid(sourceUid)) {
2104 return true;
2105 }
2106
2107 // If the actual IPC caller is different from the logical source, then
2108 // also see if they are allowed to control app switches.
2109 if (callingUid != -1 && callingUid != sourceUid) {
2110 perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
2111 if (perm == PackageManager.PERMISSION_GRANTED) {
2112 return true;
2113 }
2114 if (checkAllowAppSwitchUid(callingUid)) {
2115 return true;
2116 }
2117 }
2118
2119 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
2120 return false;
2121 }
2122
2123 private boolean checkAllowAppSwitchUid(int uid) {
2124 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
2125 if (types != null) {
2126 for (int i = types.size() - 1; i >= 0; i--) {
2127 if (types.valueAt(i).intValue() == uid) {
2128 return true;
2129 }
2130 }
2131 }
2132 return false;
2133 }
2134
2135 @Override
2136 public void setActivityController(IActivityController controller, boolean imAMonkey) {
2137 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
2138 "setActivityController()");
2139 synchronized (mGlobalLock) {
2140 mController = controller;
2141 mControllerIsAMonkey = imAMonkey;
2142 Watchdog.getInstance().setActivityController(controller);
2143 }
2144 }
2145
Wale Ogunwale387b34c2018-10-25 19:59:40 -07002146 public boolean isControllerAMonkey() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002147 synchronized (mGlobalLock) {
2148 return mController != null && mControllerIsAMonkey;
2149 }
2150 }
2151
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002152 @Override
2153 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
2154 synchronized (mGlobalLock) {
2155 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
2156 }
2157 }
2158
2159 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002160 public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum) {
2161 return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
2162 }
2163
2164 @Override
2165 public List<ActivityManager.RunningTaskInfo> getFilteredTasks(int maxNum,
2166 @WindowConfiguration.ActivityType int ignoreActivityType,
2167 @WindowConfiguration.WindowingMode int ignoreWindowingMode) {
2168 final int callingUid = Binder.getCallingUid();
2169 ArrayList<ActivityManager.RunningTaskInfo> list = new ArrayList<>();
2170
2171 synchronized (mGlobalLock) {
2172 if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
2173
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002174 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002175 callingUid);
2176 mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
2177 ignoreWindowingMode, callingUid, allowed);
2178 }
2179
2180 return list;
2181 }
2182
2183 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002184 public final void finishSubActivity(IBinder token, String resultWho, int requestCode) {
2185 synchronized (mGlobalLock) {
2186 final long origId = Binder.clearCallingIdentity();
2187 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2188 if (r != null) {
2189 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
2190 }
2191 Binder.restoreCallingIdentity(origId);
2192 }
2193 }
2194
2195 @Override
2196 public boolean willActivityBeVisible(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002197 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002198 ActivityStack stack = ActivityRecord.getStackLocked(token);
2199 if (stack != null) {
2200 return stack.willActivityBeVisibleLocked(token);
2201 }
2202 return false;
2203 }
2204 }
2205
2206 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002207 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002208 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002209 synchronized (mGlobalLock) {
2210 final long ident = Binder.clearCallingIdentity();
2211 try {
2212 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2213 if (task == null) {
2214 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
2215 return;
2216 }
2217
2218 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
2219 + " to stackId=" + stackId + " toTop=" + toTop);
2220
2221 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2222 if (stack == null) {
2223 throw new IllegalStateException(
2224 "moveTaskToStack: No stack for stackId=" + stackId);
2225 }
2226 if (!stack.isActivityTypeStandardOrUndefined()) {
2227 throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
2228 + taskId + " to stack " + stackId);
2229 }
2230 if (stack.inSplitScreenPrimaryWindowingMode()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002231 mWindowManager.setDockedStackCreateState(
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002232 SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
2233 }
2234 task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
2235 "moveTaskToStack");
2236 } finally {
2237 Binder.restoreCallingIdentity(ident);
2238 }
2239 }
2240 }
2241
2242 @Override
2243 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
2244 boolean preserveWindows, boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002245 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002246
2247 final long ident = Binder.clearCallingIdentity();
2248 try {
2249 synchronized (mGlobalLock) {
2250 if (animate) {
2251 final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
2252 if (stack == null) {
2253 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2254 return;
2255 }
2256 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
2257 throw new IllegalArgumentException("Stack: " + stackId
2258 + " doesn't support animated resize.");
2259 }
2260 stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
2261 animationDuration, false /* fromFullscreen */);
2262 } else {
2263 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2264 if (stack == null) {
2265 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2266 return;
2267 }
2268 mStackSupervisor.resizeStackLocked(stack, destBounds,
2269 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
2270 preserveWindows, allowResizeInDockedMode, !DEFER_RESUME);
2271 }
2272 }
2273 } finally {
2274 Binder.restoreCallingIdentity(ident);
2275 }
2276 }
2277
2278 /**
2279 * Moves the specified task to the primary-split-screen stack.
2280 *
2281 * @param taskId Id of task to move.
2282 * @param createMode The mode the primary split screen stack should be created in if it doesn't
2283 * exist already. See
2284 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
2285 * and
2286 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
2287 * @param toTop If the task and stack should be moved to the top.
2288 * @param animate Whether we should play an animation for the moving the task.
2289 * @param initialBounds If the primary stack gets created, it will use these bounds for the
2290 * stack. Pass {@code null} to use default bounds.
2291 * @param showRecents If the recents activity should be shown on the other side of the task
2292 * going into split-screen mode.
2293 */
2294 @Override
2295 public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode,
2296 boolean toTop, boolean animate, Rect initialBounds, boolean showRecents) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002297 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002298 "setTaskWindowingModeSplitScreenPrimary()");
2299 synchronized (mGlobalLock) {
2300 final long ident = Binder.clearCallingIdentity();
2301 try {
2302 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2303 if (task == null) {
2304 Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
2305 return false;
2306 }
2307 if (DEBUG_STACK) Slog.d(TAG_STACK,
2308 "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
2309 + " to createMode=" + createMode + " toTop=" + toTop);
2310 if (!task.isActivityTypeStandardOrUndefined()) {
2311 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
2312 + " non-standard task " + taskId + " to split-screen windowing mode");
2313 }
2314
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002315 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002316 final int windowingMode = task.getWindowingMode();
2317 final ActivityStack stack = task.getStack();
2318 if (toTop) {
2319 stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
2320 }
2321 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
2322 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */);
2323 return windowingMode != task.getWindowingMode();
2324 } finally {
2325 Binder.restoreCallingIdentity(ident);
2326 }
2327 }
2328 }
2329
2330 /**
2331 * Removes stacks in the input windowing modes from the system if they are of activity type
2332 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
2333 */
2334 @Override
2335 public void removeStacksInWindowingModes(int[] windowingModes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002336 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002337 "removeStacksInWindowingModes()");
2338
2339 synchronized (mGlobalLock) {
2340 final long ident = Binder.clearCallingIdentity();
2341 try {
2342 mStackSupervisor.removeStacksInWindowingModes(windowingModes);
2343 } finally {
2344 Binder.restoreCallingIdentity(ident);
2345 }
2346 }
2347 }
2348
2349 @Override
2350 public void removeStacksWithActivityTypes(int[] activityTypes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002351 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002352 "removeStacksWithActivityTypes()");
2353
2354 synchronized (mGlobalLock) {
2355 final long ident = Binder.clearCallingIdentity();
2356 try {
2357 mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
2358 } finally {
2359 Binder.restoreCallingIdentity(ident);
2360 }
2361 }
2362 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002363
2364 @Override
2365 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
2366 int userId) {
2367 final int callingUid = Binder.getCallingUid();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002368 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, "getRecentTasks");
2369 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002370 callingUid);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002371 final boolean detailed = checkGetTasksPermission(
2372 android.Manifest.permission.GET_DETAILED_TASKS, Binder.getCallingPid(),
2373 UserHandle.getAppId(callingUid))
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002374 == PackageManager.PERMISSION_GRANTED;
2375
2376 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002377 return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002378 callingUid);
2379 }
2380 }
2381
2382 @Override
2383 public List<ActivityManager.StackInfo> getAllStackInfos() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002384 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002385 long ident = Binder.clearCallingIdentity();
2386 try {
2387 synchronized (mGlobalLock) {
2388 return mStackSupervisor.getAllStackInfosLocked();
2389 }
2390 } finally {
2391 Binder.restoreCallingIdentity(ident);
2392 }
2393 }
2394
2395 @Override
2396 public ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002397 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002398 long ident = Binder.clearCallingIdentity();
2399 try {
2400 synchronized (mGlobalLock) {
2401 return mStackSupervisor.getStackInfo(windowingMode, activityType);
2402 }
2403 } finally {
2404 Binder.restoreCallingIdentity(ident);
2405 }
2406 }
2407
2408 @Override
2409 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002410 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002411 final long callingUid = Binder.getCallingUid();
2412 final long origId = Binder.clearCallingIdentity();
2413 try {
2414 synchronized (mGlobalLock) {
2415 // Cancel the recents animation synchronously (do not hold the WM lock)
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002416 mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002417 ? REORDER_MOVE_TO_ORIGINAL_POSITION
2418 : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
2419 }
2420 } finally {
2421 Binder.restoreCallingIdentity(origId);
2422 }
2423 }
2424
2425 @Override
2426 public void startLockTaskModeByToken(IBinder token) {
2427 synchronized (mGlobalLock) {
2428 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2429 if (r == null) {
2430 return;
2431 }
2432 startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
2433 }
2434 }
2435
2436 @Override
2437 public void startSystemLockTaskMode(int taskId) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002438 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002439 // This makes inner call to look as if it was initiated by system.
2440 long ident = Binder.clearCallingIdentity();
2441 try {
2442 synchronized (mGlobalLock) {
2443 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2444
2445 // When starting lock task mode the stack must be in front and focused
2446 task.getStack().moveToFront("startSystemLockTaskMode");
2447 startLockTaskModeLocked(task, true /* isSystemCaller */);
2448 }
2449 } finally {
2450 Binder.restoreCallingIdentity(ident);
2451 }
2452 }
2453
2454 @Override
2455 public void stopLockTaskModeByToken(IBinder token) {
2456 synchronized (mGlobalLock) {
2457 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2458 if (r == null) {
2459 return;
2460 }
2461 stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
2462 }
2463 }
2464
2465 /**
2466 * This API should be called by SystemUI only when user perform certain action to dismiss
2467 * lock task mode. We should only dismiss pinned lock task mode in this case.
2468 */
2469 @Override
2470 public void stopSystemLockTaskMode() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002471 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002472 stopLockTaskModeInternal(null, true /* isSystemCaller */);
2473 }
2474
2475 private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
2476 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
2477 if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
2478 return;
2479 }
2480
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002481 final ActivityStack stack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002482 if (stack == null || task != stack.topTask()) {
2483 throw new IllegalArgumentException("Invalid task, not in foreground");
2484 }
2485
2486 // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
2487 // system or a specific app.
2488 // * System-initiated requests will only start the pinned mode (screen pinning)
2489 // * App-initiated requests
2490 // - will put the device in fully locked mode (LockTask), if the app is whitelisted
2491 // - will start the pinned mode, otherwise
2492 final int callingUid = Binder.getCallingUid();
2493 long ident = Binder.clearCallingIdentity();
2494 try {
2495 // When a task is locked, dismiss the pinned stack if it exists
2496 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2497
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002498 getLockTaskController().startLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002499 } finally {
2500 Binder.restoreCallingIdentity(ident);
2501 }
2502 }
2503
2504 private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
2505 final int callingUid = Binder.getCallingUid();
2506 long ident = Binder.clearCallingIdentity();
2507 try {
2508 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002509 getLockTaskController().stopLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002510 }
2511 // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
2512 // task and jumping straight into a call in the case of emergency call back.
2513 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
2514 if (tm != null) {
2515 tm.showInCallScreen(false);
2516 }
2517 } finally {
2518 Binder.restoreCallingIdentity(ident);
2519 }
2520 }
2521
2522 @Override
Wale Ogunwale27c48ae2018-10-25 19:01:01 -07002523 public void updateLockTaskPackages(int userId, String[] packages) {
2524 final int callingUid = Binder.getCallingUid();
2525 if (callingUid != 0 && callingUid != SYSTEM_UID) {
2526 mAmInternal.enforceCallingPermission(Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
2527 "updateLockTaskPackages()");
2528 }
2529 synchronized (this) {
2530 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":"
2531 + Arrays.toString(packages));
2532 getLockTaskController().updateLockTaskPackages(userId, packages);
2533 }
2534 }
2535
2536 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002537 public boolean isInLockTaskMode() {
2538 return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
2539 }
2540
2541 @Override
2542 public int getLockTaskModeState() {
2543 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002544 return getLockTaskController().getLockTaskModeState();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002545 }
2546 }
2547
2548 @Override
2549 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
2550 synchronized (mGlobalLock) {
2551 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2552 if (r != null) {
2553 r.setTaskDescription(td);
2554 final TaskRecord task = r.getTask();
2555 task.updateTaskDescription();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002556 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002557 }
2558 }
2559 }
2560
2561 @Override
2562 public Bundle getActivityOptions(IBinder token) {
2563 final long origId = Binder.clearCallingIdentity();
2564 try {
2565 synchronized (mGlobalLock) {
2566 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
2567 if (r != null) {
2568 final ActivityOptions activityOptions = r.takeOptionsLocked();
2569 return activityOptions == null ? null : activityOptions.toBundle();
2570 }
2571 return null;
2572 }
2573 } finally {
2574 Binder.restoreCallingIdentity(origId);
2575 }
2576 }
2577
2578 @Override
2579 public List<IBinder> getAppTasks(String callingPackage) {
2580 int callingUid = Binder.getCallingUid();
2581 long ident = Binder.clearCallingIdentity();
2582 try {
2583 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002584 return mRecentTasks.getAppTasksList(callingUid, callingPackage);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002585 }
2586 } finally {
2587 Binder.restoreCallingIdentity(ident);
2588 }
2589 }
2590
2591 @Override
2592 public void finishVoiceTask(IVoiceInteractionSession session) {
2593 synchronized (mGlobalLock) {
2594 final long origId = Binder.clearCallingIdentity();
2595 try {
2596 // TODO: VI Consider treating local voice interactions and voice tasks
2597 // differently here
2598 mStackSupervisor.finishVoiceTask(session);
2599 } finally {
2600 Binder.restoreCallingIdentity(origId);
2601 }
2602 }
2603
2604 }
2605
2606 @Override
2607 public boolean isTopOfTask(IBinder token) {
2608 synchronized (mGlobalLock) {
2609 ActivityRecord r = ActivityRecord.isInStackLocked(token);
Riddle Hsu66b74a82018-07-26 00:20:12 +08002610 return r != null && r.getTask().getTopActivity() == r;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002611 }
2612 }
2613
2614 @Override
2615 public void notifyLaunchTaskBehindComplete(IBinder token) {
2616 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
2617 }
2618
2619 @Override
2620 public void notifyEnterAnimationComplete(IBinder token) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002621 mH.post(() -> {
2622 synchronized (mGlobalLock) {
2623 ActivityRecord r = ActivityRecord.forTokenLocked(token);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002624 if (r != null && r.attachedToProcess()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002625 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002626 r.app.getThread().scheduleEnterAnimationComplete(r.appToken);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002627 } catch (RemoteException e) {
2628 }
2629 }
2630 }
2631
2632 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002633 }
2634
2635 /** Called from an app when assist data is ready. */
2636 @Override
2637 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
2638 AssistContent content, Uri referrer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002639 PendingAssistExtras pae = (PendingAssistExtras) token;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002640 synchronized (pae) {
2641 pae.result = extras;
2642 pae.structure = structure;
2643 pae.content = content;
2644 if (referrer != null) {
2645 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
2646 }
2647 if (structure != null) {
2648 structure.setHomeActivity(pae.isHome);
2649 }
2650 pae.haveResult = true;
2651 pae.notifyAll();
2652 if (pae.intent == null && pae.receiver == null) {
2653 // Caller is just waiting for the result.
2654 return;
2655 }
2656 }
2657 // We are now ready to launch the assist activity.
2658 IAssistDataReceiver sendReceiver = null;
2659 Bundle sendBundle = null;
2660 synchronized (mGlobalLock) {
2661 buildAssistBundleLocked(pae, extras);
2662 boolean exists = mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002663 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002664 if (!exists) {
2665 // Timed out.
2666 return;
2667 }
2668
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002669 if ((sendReceiver = pae.receiver) != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002670 // Caller wants result sent back to them.
2671 sendBundle = new Bundle();
2672 sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
2673 sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
2674 sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
2675 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
2676 }
2677 }
2678 if (sendReceiver != null) {
2679 try {
2680 sendReceiver.onHandleAssistData(sendBundle);
2681 } catch (RemoteException e) {
2682 }
2683 return;
2684 }
2685
2686 final long ident = Binder.clearCallingIdentity();
2687 try {
2688 if (TextUtils.equals(pae.intent.getAction(),
2689 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
2690 pae.intent.putExtras(pae.extras);
2691 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
2692 } else {
2693 pae.intent.replaceExtras(pae.extras);
2694 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
2695 | Intent.FLAG_ACTIVITY_SINGLE_TOP
2696 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Wale Ogunwale31913b52018-10-13 08:29:31 -07002697 mInternal.closeSystemDialogs("assist");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002698
2699 try {
2700 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
2701 } catch (ActivityNotFoundException e) {
2702 Slog.w(TAG, "No activity to handle assist action.", e);
2703 }
2704 }
2705 } finally {
2706 Binder.restoreCallingIdentity(ident);
2707 }
2708 }
2709
2710 @Override
2711 public int addAppTask(IBinder activityToken, Intent intent,
2712 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
2713 final int callingUid = Binder.getCallingUid();
2714 final long callingIdent = Binder.clearCallingIdentity();
2715
2716 try {
2717 synchronized (mGlobalLock) {
2718 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
2719 if (r == null) {
2720 throw new IllegalArgumentException("Activity does not exist; token="
2721 + activityToken);
2722 }
2723 ComponentName comp = intent.getComponent();
2724 if (comp == null) {
2725 throw new IllegalArgumentException("Intent " + intent
2726 + " must specify explicit component");
2727 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002728 if (thumbnail.getWidth() != mThumbnailWidth
2729 || thumbnail.getHeight() != mThumbnailHeight) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002730 throw new IllegalArgumentException("Bad thumbnail size: got "
2731 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002732 + mThumbnailWidth + "x" + mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002733 }
2734 if (intent.getSelector() != null) {
2735 intent.setSelector(null);
2736 }
2737 if (intent.getSourceBounds() != null) {
2738 intent.setSourceBounds(null);
2739 }
2740 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
2741 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
2742 // The caller has added this as an auto-remove task... that makes no
2743 // sense, so turn off auto-remove.
2744 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
2745 }
2746 }
2747 final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
2748 STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
2749 if (ainfo.applicationInfo.uid != callingUid) {
2750 throw new SecurityException(
2751 "Can't add task for another application: target uid="
2752 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
2753 }
2754
2755 final ActivityStack stack = r.getStack();
2756 final TaskRecord task = stack.createTaskRecord(
2757 mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent,
2758 null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002759 if (!mRecentTasks.addToBottom(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002760 // The app has too many tasks already and we can't add any more
2761 stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
2762 return INVALID_TASK_ID;
2763 }
2764 task.lastTaskDescription.copyFrom(description);
2765
2766 // TODO: Send the thumbnail to WM to store it.
2767
2768 return task.taskId;
2769 }
2770 } finally {
2771 Binder.restoreCallingIdentity(callingIdent);
2772 }
2773 }
2774
2775 @Override
2776 public Point getAppTaskThumbnailSize() {
2777 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002778 return new Point(mThumbnailWidth, mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002779 }
2780 }
2781
2782 @Override
2783 public void setTaskResizeable(int taskId, int resizeableMode) {
2784 synchronized (mGlobalLock) {
2785 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
2786 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
2787 if (task == null) {
2788 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
2789 return;
2790 }
2791 task.setResizeMode(resizeableMode);
2792 }
2793 }
2794
2795 @Override
2796 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002797 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002798 long ident = Binder.clearCallingIdentity();
2799 try {
2800 synchronized (mGlobalLock) {
2801 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2802 if (task == null) {
2803 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
2804 return;
2805 }
2806 // Place the task in the right stack if it isn't there already based on
2807 // the requested bounds.
2808 // The stack transition logic is:
2809 // - a null bounds on a freeform task moves that task to fullscreen
2810 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
2811 // that task to freeform
2812 // - otherwise the task is not moved
2813 ActivityStack stack = task.getStack();
2814 if (!task.getWindowConfiguration().canResizeTask()) {
2815 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
2816 }
2817 if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
2818 stack = stack.getDisplay().getOrCreateStack(
2819 WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
2820 } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
2821 stack = stack.getDisplay().getOrCreateStack(
2822 WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
2823 }
2824
2825 // Reparent the task to the right stack if necessary
2826 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
2827 if (stack != task.getStack()) {
2828 // Defer resume until the task is resized below
2829 task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
2830 DEFER_RESUME, "resizeTask");
2831 preserveWindow = false;
2832 }
2833
2834 // After reparenting (which only resizes the task to the stack bounds), resize the
2835 // task to the actual bounds provided
2836 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
2837 }
2838 } finally {
2839 Binder.restoreCallingIdentity(ident);
2840 }
2841 }
2842
2843 @Override
2844 public boolean releaseActivityInstance(IBinder token) {
2845 synchronized (mGlobalLock) {
2846 final long origId = Binder.clearCallingIdentity();
2847 try {
2848 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2849 if (r == null) {
2850 return false;
2851 }
2852 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
2853 } finally {
2854 Binder.restoreCallingIdentity(origId);
2855 }
2856 }
2857 }
2858
2859 @Override
2860 public void releaseSomeActivities(IApplicationThread appInt) {
2861 synchronized (mGlobalLock) {
2862 final long origId = Binder.clearCallingIdentity();
2863 try {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07002864 final WindowProcessController app = getProcessController(appInt);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002865 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
2866 } finally {
2867 Binder.restoreCallingIdentity(origId);
2868 }
2869 }
2870 }
2871
2872 @Override
2873 public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
2874 int secondaryDisplayShowing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002875 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002876 != PackageManager.PERMISSION_GRANTED) {
2877 throw new SecurityException("Requires permission "
2878 + android.Manifest.permission.DEVICE_POWER);
2879 }
2880
2881 synchronized (mGlobalLock) {
2882 long ident = Binder.clearCallingIdentity();
2883 if (mKeyguardShown != keyguardShowing) {
2884 mKeyguardShown = keyguardShowing;
Wale Ogunwale342fbe92018-10-09 08:44:10 -07002885 final Message msg = PooledLambda.obtainMessage(
2886 ActivityManagerInternal::reportCurKeyguardUsageEvent, mAmInternal,
2887 keyguardShowing);
2888 mH.sendMessage(msg);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002889 }
2890 try {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002891 mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002892 secondaryDisplayShowing);
2893 } finally {
2894 Binder.restoreCallingIdentity(ident);
2895 }
2896 }
2897
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002898 mH.post(() -> {
2899 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2900 mScreenObservers.get(i).onKeyguardStateChanged(keyguardShowing);
2901 }
2902 });
2903 }
2904
Wale Ogunwale387b34c2018-10-25 19:59:40 -07002905 public void onScreenAwakeChanged(boolean isAwake) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002906 mH.post(() -> {
2907 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2908 mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2909 }
2910 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002911 }
2912
2913 @Override
2914 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002915 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
2916 userId, "getTaskDescriptionIcon");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002917
2918 final File passedIconFile = new File(filePath);
2919 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
2920 passedIconFile.getName());
2921 if (!legitIconFile.getPath().equals(filePath)
2922 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
2923 throw new IllegalArgumentException("Bad file path: " + filePath
2924 + " passed for userId " + userId);
2925 }
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002926 return mRecentTasks.getTaskDescriptionIcon(filePath);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002927 }
2928
2929 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002930 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002931 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
2932 final ActivityOptions activityOptions = safeOptions != null
2933 ? safeOptions.getOptions(mStackSupervisor)
2934 : null;
2935 if (activityOptions == null
2936 || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
2937 || activityOptions.getCustomInPlaceResId() == 0) {
2938 throw new IllegalArgumentException("Expected in-place ActivityOption " +
2939 "with valid animation");
2940 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002941 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
2942 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002943 activityOptions.getCustomInPlaceResId());
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002944 mWindowManager.executeAppTransition();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002945 }
2946
2947 @Override
2948 public void removeStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002949 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002950 synchronized (mGlobalLock) {
2951 final long ident = Binder.clearCallingIdentity();
2952 try {
2953 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2954 if (stack == null) {
2955 Slog.w(TAG, "removeStack: No stack with id=" + stackId);
2956 return;
2957 }
2958 if (!stack.isActivityTypeStandardOrUndefined()) {
2959 throw new IllegalArgumentException(
2960 "Removing non-standard stack is not allowed.");
2961 }
2962 mStackSupervisor.removeStack(stack);
2963 } finally {
2964 Binder.restoreCallingIdentity(ident);
2965 }
2966 }
2967 }
2968
2969 @Override
2970 public void moveStackToDisplay(int stackId, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002971 mAmInternal.enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002972
2973 synchronized (mGlobalLock) {
2974 final long ident = Binder.clearCallingIdentity();
2975 try {
2976 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
2977 + " to displayId=" + displayId);
2978 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
2979 } finally {
2980 Binder.restoreCallingIdentity(ident);
2981 }
2982 }
2983 }
2984
2985 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002986 public void exitFreeformMode(IBinder token) {
2987 synchronized (mGlobalLock) {
2988 long ident = Binder.clearCallingIdentity();
2989 try {
2990 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2991 if (r == null) {
2992 throw new IllegalArgumentException(
2993 "exitFreeformMode: No activity record matching token=" + token);
2994 }
2995
2996 final ActivityStack stack = r.getStack();
2997 if (stack == null || !stack.inFreeformWindowingMode()) {
2998 throw new IllegalStateException(
2999 "exitFreeformMode: You can only go fullscreen from freeform.");
3000 }
3001
3002 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
3003 } finally {
3004 Binder.restoreCallingIdentity(ident);
3005 }
3006 }
3007 }
3008
3009 /** Sets the task stack listener that gets callbacks when a task stack changes. */
3010 @Override
3011 public void registerTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003012 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003013 "registerTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003014 mTaskChangeNotificationController.registerTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003015 }
3016
3017 /** Unregister a task stack listener so that it stops receiving callbacks. */
3018 @Override
3019 public void unregisterTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003020 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003021 "unregisterTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003022 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003023 }
3024
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003025 @Override
3026 public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
3027 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
3028 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
3029 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
3030 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
3031 }
3032
3033 @Override
3034 public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
3035 IBinder activityToken, int flags) {
3036 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
3037 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
3038 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
3039 }
3040
3041 @Override
3042 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
3043 Bundle args) {
3044 return enqueueAssistContext(requestType, intent, hint, null, null, null,
3045 true /* focused */, true /* newSessionId */, userHandle, args,
3046 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
3047 }
3048
3049 @Override
3050 public Bundle getAssistContextExtras(int requestType) {
3051 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
3052 null, null, true /* focused */, true /* newSessionId */,
3053 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
3054 if (pae == null) {
3055 return null;
3056 }
3057 synchronized (pae) {
3058 while (!pae.haveResult) {
3059 try {
3060 pae.wait();
3061 } catch (InterruptedException e) {
3062 }
3063 }
3064 }
3065 synchronized (mGlobalLock) {
3066 buildAssistBundleLocked(pae, pae.result);
3067 mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003068 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003069 }
3070 return pae.extras;
3071 }
3072
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003073 /**
3074 * Binder IPC calls go through the public entry point.
3075 * This can be called with or without the global lock held.
3076 */
3077 private static int checkCallingPermission(String permission) {
3078 return checkPermission(
3079 permission, Binder.getCallingPid(), UserHandle.getAppId(Binder.getCallingUid()));
3080 }
3081
3082 /** This can be called with or without the global lock held. */
Wale Ogunwale214f3482018-10-04 11:00:47 -07003083 private void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003084 if (!getRecentTasks().isCallerRecents(Binder.getCallingUid())) {
3085 mAmInternal.enforceCallingPermission(permission, func);
3086 }
3087 }
3088
3089 @VisibleForTesting
3090 int checkGetTasksPermission(String permission, int pid, int uid) {
3091 return checkPermission(permission, pid, uid);
3092 }
3093
3094 static int checkPermission(String permission, int pid, int uid) {
3095 if (permission == null) {
3096 return PackageManager.PERMISSION_DENIED;
3097 }
3098 return checkComponentPermission(permission, pid, uid, -1, true);
3099 }
3100
Wale Ogunwale214f3482018-10-04 11:00:47 -07003101 public static int checkComponentPermission(String permission, int pid, int uid,
3102 int owningUid, boolean exported) {
3103 return ActivityManagerService.checkComponentPermission(
3104 permission, pid, uid, owningUid, exported);
3105 }
3106
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003107 boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
3108 if (getRecentTasks().isCallerRecents(callingUid)) {
3109 // Always allow the recents component to get tasks
3110 return true;
3111 }
3112
3113 boolean allowed = checkGetTasksPermission(android.Manifest.permission.REAL_GET_TASKS,
3114 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
3115 if (!allowed) {
3116 if (checkGetTasksPermission(android.Manifest.permission.GET_TASKS,
3117 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
3118 // Temporary compatibility: some existing apps on the system image may
3119 // still be requesting the old permission and not switched to the new
3120 // one; if so, we'll still allow them full access. This means we need
3121 // to see if they are holding the old permission and are a system app.
3122 try {
3123 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
3124 allowed = true;
3125 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
3126 + " is using old GET_TASKS but privileged; allowing");
3127 }
3128 } catch (RemoteException e) {
3129 }
3130 }
3131 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
3132 + " does not hold REAL_GET_TASKS; limiting output");
3133 }
3134 return allowed;
3135 }
3136
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003137 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
3138 IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
3139 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
3140 int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003141 mAmInternal.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003142 "enqueueAssistContext()");
3143
3144 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003145 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003146 if (activity == null) {
3147 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
3148 return null;
3149 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003150 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003151 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
3152 return null;
3153 }
3154 if (focused) {
3155 if (activityToken != null) {
3156 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
3157 if (activity != caller) {
3158 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
3159 + " is not current top " + activity);
3160 return null;
3161 }
3162 }
3163 } else {
3164 activity = ActivityRecord.forTokenLocked(activityToken);
3165 if (activity == null) {
3166 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
3167 + " couldn't be found");
3168 return null;
3169 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003170 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003171 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
3172 return null;
3173 }
3174 }
3175
3176 PendingAssistExtras pae;
3177 Bundle extras = new Bundle();
3178 if (args != null) {
3179 extras.putAll(args);
3180 }
3181 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003182 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003183
3184 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
3185 userHandle);
3186 pae.isHome = activity.isActivityTypeHome();
3187
3188 // Increment the sessionId if necessary
3189 if (newSessionId) {
3190 mViSessionId++;
3191 }
3192 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003193 activity.app.getThread().requestAssistContextExtras(activity.appToken, pae,
3194 requestType, mViSessionId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003195 mPendingAssistExtras.add(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003196 mUiHandler.postDelayed(pae, timeout);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003197 } catch (RemoteException e) {
3198 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
3199 return null;
3200 }
3201 return pae;
3202 }
3203 }
3204
3205 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
3206 if (result != null) {
3207 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
3208 }
3209 if (pae.hint != null) {
3210 pae.extras.putBoolean(pae.hint, true);
3211 }
3212 }
3213
3214 private void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
3215 IAssistDataReceiver receiver;
3216 synchronized (mGlobalLock) {
3217 mPendingAssistExtras.remove(pae);
3218 receiver = pae.receiver;
3219 }
3220 if (receiver != null) {
3221 // Caller wants result sent back to them.
3222 Bundle sendBundle = new Bundle();
3223 // At least return the receiver extras
3224 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
3225 try {
3226 pae.receiver.onHandleAssistData(sendBundle);
3227 } catch (RemoteException e) {
3228 }
3229 }
3230 }
3231
3232 public class PendingAssistExtras extends Binder implements Runnable {
3233 public final ActivityRecord activity;
3234 public boolean isHome;
3235 public final Bundle extras;
3236 public final Intent intent;
3237 public final String hint;
3238 public final IAssistDataReceiver receiver;
3239 public final int userHandle;
3240 public boolean haveResult = false;
3241 public Bundle result = null;
3242 public AssistStructure structure = null;
3243 public AssistContent content = null;
3244 public Bundle receiverExtras;
3245
3246 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
3247 String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
3248 int _userHandle) {
3249 activity = _activity;
3250 extras = _extras;
3251 intent = _intent;
3252 hint = _hint;
3253 receiver = _receiver;
3254 receiverExtras = _receiverExtras;
3255 userHandle = _userHandle;
3256 }
3257
3258 @Override
3259 public void run() {
3260 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
3261 synchronized (this) {
3262 haveResult = true;
3263 notifyAll();
3264 }
3265 pendingAssistExtrasTimedOut(this);
3266 }
3267 }
3268
3269 @Override
3270 public boolean isAssistDataAllowedOnCurrentActivity() {
3271 int userId;
3272 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003273 final ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003274 if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
3275 return false;
3276 }
3277
3278 final ActivityRecord activity = focusedStack.getTopActivity();
3279 if (activity == null) {
3280 return false;
3281 }
3282 userId = activity.userId;
3283 }
3284 return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
3285 }
3286
3287 @Override
3288 public boolean showAssistFromActivity(IBinder token, Bundle args) {
3289 long ident = Binder.clearCallingIdentity();
3290 try {
3291 synchronized (mGlobalLock) {
3292 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003293 ActivityRecord top = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003294 if (top != caller) {
3295 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3296 + " is not current top " + top);
3297 return false;
3298 }
3299 if (!top.nowVisible) {
3300 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3301 + " is not visible");
3302 return false;
3303 }
3304 }
3305 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
3306 token);
3307 } finally {
3308 Binder.restoreCallingIdentity(ident);
3309 }
3310 }
3311
3312 @Override
3313 public boolean isRootVoiceInteraction(IBinder token) {
3314 synchronized (mGlobalLock) {
3315 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3316 if (r == null) {
3317 return false;
3318 }
3319 return r.rootVoiceInteraction;
3320 }
3321 }
3322
Wale Ogunwalef6733932018-06-27 05:14:34 -07003323 private void onLocalVoiceInteractionStartedLocked(IBinder activity,
3324 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
3325 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
3326 if (activityToCallback == null) return;
3327 activityToCallback.setVoiceSessionLocked(voiceSession);
3328
3329 // Inform the activity
3330 try {
3331 activityToCallback.app.getThread().scheduleLocalVoiceInteractionStarted(activity,
3332 voiceInteractor);
3333 long token = Binder.clearCallingIdentity();
3334 try {
3335 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
3336 } finally {
3337 Binder.restoreCallingIdentity(token);
3338 }
3339 // TODO: VI Should we cache the activity so that it's easier to find later
3340 // rather than scan through all the stacks and activities?
3341 } catch (RemoteException re) {
3342 activityToCallback.clearVoiceSessionLocked();
3343 // TODO: VI Should this terminate the voice session?
3344 }
3345 }
3346
3347 private void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
3348 Slog.d(TAG, "<<< startRunningVoiceLocked()");
3349 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
3350 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
3351 boolean wasRunningVoice = mRunningVoice != null;
3352 mRunningVoice = session;
3353 if (!wasRunningVoice) {
3354 mVoiceWakeLock.acquire();
3355 updateSleepIfNeededLocked();
3356 }
3357 }
3358 }
3359
3360 void finishRunningVoiceLocked() {
3361 if (mRunningVoice != null) {
3362 mRunningVoice = null;
3363 mVoiceWakeLock.release();
3364 updateSleepIfNeededLocked();
3365 }
3366 }
3367
3368 @Override
3369 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3370 synchronized (mGlobalLock) {
3371 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3372 if (keepAwake) {
3373 mVoiceWakeLock.acquire();
3374 } else {
3375 mVoiceWakeLock.release();
3376 }
3377 }
3378 }
3379 }
3380
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003381 @Override
3382 public ComponentName getActivityClassForToken(IBinder token) {
3383 synchronized (mGlobalLock) {
3384 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3385 if (r == null) {
3386 return null;
3387 }
3388 return r.intent.getComponent();
3389 }
3390 }
3391
3392 @Override
3393 public String getPackageForToken(IBinder token) {
3394 synchronized (mGlobalLock) {
3395 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3396 if (r == null) {
3397 return null;
3398 }
3399 return r.packageName;
3400 }
3401 }
3402
3403 @Override
3404 public void showLockTaskEscapeMessage(IBinder token) {
3405 synchronized (mGlobalLock) {
3406 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3407 if (r == null) {
3408 return;
3409 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003410 getLockTaskController().showLockTaskToast();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003411 }
3412 }
3413
3414 @Override
3415 public void keyguardGoingAway(int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003416 enforceNotIsolatedCaller("keyguardGoingAway");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003417 final long token = Binder.clearCallingIdentity();
3418 try {
3419 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003420 mKeyguardController.keyguardGoingAway(flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003421 }
3422 } finally {
3423 Binder.restoreCallingIdentity(token);
3424 }
3425 }
3426
3427 /**
3428 * Try to place task to provided position. The final position might be different depending on
3429 * current user and stacks state. The task will be moved to target stack if it's currently in
3430 * different stack.
3431 */
3432 @Override
3433 public void positionTaskInStack(int taskId, int stackId, int position) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003434 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003435 synchronized (mGlobalLock) {
3436 long ident = Binder.clearCallingIdentity();
3437 try {
3438 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
3439 + taskId + " in stackId=" + stackId + " at position=" + position);
3440 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3441 if (task == null) {
3442 throw new IllegalArgumentException("positionTaskInStack: no task for id="
3443 + taskId);
3444 }
3445
3446 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3447
3448 if (stack == null) {
3449 throw new IllegalArgumentException("positionTaskInStack: no stack for id="
3450 + stackId);
3451 }
3452 if (!stack.isActivityTypeStandardOrUndefined()) {
3453 throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
3454 + " the position of task " + taskId + " in/to non-standard stack");
3455 }
3456
3457 // TODO: Have the callers of this API call a separate reparent method if that is
3458 // what they intended to do vs. having this method also do reparenting.
3459 if (task.getStack() == stack) {
3460 // Change position in current stack.
3461 stack.positionChildAt(task, position);
3462 } else {
3463 // Reparent to new stack.
3464 task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
3465 !DEFER_RESUME, "positionTaskInStack");
3466 }
3467 } finally {
3468 Binder.restoreCallingIdentity(ident);
3469 }
3470 }
3471 }
3472
3473 @Override
3474 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
3475 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
3476 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
3477 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
3478 synchronized (mGlobalLock) {
3479 ActivityRecord record = ActivityRecord.isInStackLocked(token);
3480 if (record == null) {
3481 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
3482 + "found for: " + token);
3483 }
3484 record.setSizeConfigurations(horizontalSizeConfiguration,
3485 verticalSizeConfigurations, smallestSizeConfigurations);
3486 }
3487 }
3488
3489 /**
3490 * Dismisses split-screen multi-window mode.
3491 * @param toTop If true the current primary split-screen stack will be placed or left on top.
3492 */
3493 @Override
3494 public void dismissSplitScreenMode(boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003495 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003496 MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
3497 final long ident = Binder.clearCallingIdentity();
3498 try {
3499 synchronized (mGlobalLock) {
3500 final ActivityStack stack =
3501 mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
3502 if (stack == null) {
3503 Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
3504 return;
3505 }
3506
3507 if (toTop) {
3508 // Caller wants the current split-screen primary stack to be the top stack after
3509 // it goes fullscreen, so move it to the front.
3510 stack.moveToFront("dismissSplitScreenMode");
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003511 } else if (mStackSupervisor.isTopDisplayFocusedStack(stack)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003512 // In this case the current split-screen primary stack shouldn't be the top
3513 // stack after it goes fullscreen, but it current has focus, so we move the
3514 // focus to the top-most split-screen secondary stack next to it.
3515 final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
3516 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
3517 if (otherStack != null) {
3518 otherStack.moveToFront("dismissSplitScreenMode_other");
3519 }
3520 }
3521
Evan Rosky10475742018-09-05 19:02:48 -07003522 stack.setWindowingMode(WINDOWING_MODE_UNDEFINED);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003523 }
3524 } finally {
3525 Binder.restoreCallingIdentity(ident);
3526 }
3527 }
3528
3529 /**
3530 * Dismisses Pip
3531 * @param animate True if the dismissal should be animated.
3532 * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
3533 * default animation duration should be used.
3534 */
3535 @Override
3536 public void dismissPip(boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003537 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003538 final long ident = Binder.clearCallingIdentity();
3539 try {
3540 synchronized (mGlobalLock) {
3541 final PinnedActivityStack stack =
3542 mStackSupervisor.getDefaultDisplay().getPinnedStack();
3543 if (stack == null) {
3544 Slog.w(TAG, "dismissPip: pinned stack not found.");
3545 return;
3546 }
3547 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
3548 throw new IllegalArgumentException("Stack: " + stack
3549 + " doesn't support animated resize.");
3550 }
3551 if (animate) {
3552 stack.animateResizePinnedStack(null /* sourceHintBounds */,
3553 null /* destBounds */, animationDuration, false /* fromFullscreen */);
3554 } else {
3555 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
3556 }
3557 }
3558 } finally {
3559 Binder.restoreCallingIdentity(ident);
3560 }
3561 }
3562
3563 @Override
3564 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003565 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003566 synchronized (mGlobalLock) {
3567 mSuppressResizeConfigChanges = suppress;
3568 }
3569 }
3570
3571 /**
3572 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
3573 * animated the stack to the fullscreen, but can also be called if we are relaunching an
3574 * activity and clearing the task at the same time.
3575 */
3576 @Override
3577 // TODO: API should just be about changing windowing modes...
3578 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003579 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003580 "moveTasksToFullscreenStack()");
3581 synchronized (mGlobalLock) {
3582 final long origId = Binder.clearCallingIdentity();
3583 try {
3584 final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
3585 if (stack != null){
3586 if (!stack.isActivityTypeStandardOrUndefined()) {
3587 throw new IllegalArgumentException(
3588 "You can't move tasks from non-standard stacks.");
3589 }
3590 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
3591 }
3592 } finally {
3593 Binder.restoreCallingIdentity(origId);
3594 }
3595 }
3596 }
3597
3598 /**
3599 * Moves the top activity in the input stackId to the pinned stack.
3600 *
3601 * @param stackId Id of stack to move the top activity to pinned stack.
3602 * @param bounds Bounds to use for pinned stack.
3603 *
3604 * @return True if the top activity of the input stack was successfully moved to the pinned
3605 * stack.
3606 */
3607 @Override
3608 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003609 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003610 "moveTopActivityToPinnedStack()");
3611 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003612 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003613 throw new IllegalStateException("moveTopActivityToPinnedStack:"
3614 + "Device doesn't support picture-in-picture mode");
3615 }
3616
3617 long ident = Binder.clearCallingIdentity();
3618 try {
3619 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
3620 } finally {
3621 Binder.restoreCallingIdentity(ident);
3622 }
3623 }
3624 }
3625
3626 @Override
3627 public boolean isInMultiWindowMode(IBinder token) {
3628 final long origId = Binder.clearCallingIdentity();
3629 try {
3630 synchronized (mGlobalLock) {
3631 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3632 if (r == null) {
3633 return false;
3634 }
3635 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
3636 return r.inMultiWindowMode();
3637 }
3638 } finally {
3639 Binder.restoreCallingIdentity(origId);
3640 }
3641 }
3642
3643 @Override
3644 public boolean isInPictureInPictureMode(IBinder token) {
3645 final long origId = Binder.clearCallingIdentity();
3646 try {
3647 synchronized (mGlobalLock) {
3648 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
3649 }
3650 } finally {
3651 Binder.restoreCallingIdentity(origId);
3652 }
3653 }
3654
3655 private boolean isInPictureInPictureMode(ActivityRecord r) {
3656 if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
3657 || r.getStack().isInStackLocked(r) == null) {
3658 return false;
3659 }
3660
3661 // If we are animating to fullscreen then we have already dispatched the PIP mode
3662 // changed, so we should reflect that check here as well.
3663 final PinnedActivityStack stack = r.getStack();
3664 final PinnedStackWindowController windowController = stack.getWindowContainerController();
3665 return !windowController.isAnimatingBoundsToFullscreen();
3666 }
3667
3668 @Override
3669 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
3670 final long origId = Binder.clearCallingIdentity();
3671 try {
3672 synchronized (mGlobalLock) {
3673 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3674 "enterPictureInPictureMode", token, params);
3675
3676 // If the activity is already in picture in picture mode, then just return early
3677 if (isInPictureInPictureMode(r)) {
3678 return true;
3679 }
3680
3681 // Activity supports picture-in-picture, now check that we can enter PiP at this
3682 // point, if it is
3683 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
3684 false /* beforeStopping */)) {
3685 return false;
3686 }
3687
3688 final Runnable enterPipRunnable = () -> {
Wale Ogunwalef276a6f2018-06-15 08:26:07 -07003689 synchronized (mGlobalLock) {
3690 // Only update the saved args from the args that are set
3691 r.pictureInPictureArgs.copyOnlySet(params);
3692 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
3693 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
3694 // Adjust the source bounds by the insets for the transition down
3695 final Rect sourceBounds = new Rect(
3696 r.pictureInPictureArgs.getSourceRectHint());
3697 mStackSupervisor.moveActivityToPinnedStackLocked(
3698 r, sourceBounds, aspectRatio, "enterPictureInPictureMode");
3699 final PinnedActivityStack stack = r.getStack();
3700 stack.setPictureInPictureAspectRatio(aspectRatio);
3701 stack.setPictureInPictureActions(actions);
3702 MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
3703 r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
3704 logPictureInPictureArgs(params);
3705 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003706 };
3707
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003708 if (isKeyguardLocked()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003709 // If the keyguard is showing or occluded, then try and dismiss it before
3710 // entering picture-in-picture (this will prompt the user to authenticate if the
3711 // device is currently locked).
3712 dismissKeyguard(token, new KeyguardDismissCallback() {
3713 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003714 public void onDismissSucceeded() {
3715 mH.post(enterPipRunnable);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003716 }
3717 }, null /* message */);
3718 } else {
3719 // Enter picture in picture immediately otherwise
3720 enterPipRunnable.run();
3721 }
3722 return true;
3723 }
3724 } finally {
3725 Binder.restoreCallingIdentity(origId);
3726 }
3727 }
3728
3729 @Override
3730 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
3731 final long origId = Binder.clearCallingIdentity();
3732 try {
3733 synchronized (mGlobalLock) {
3734 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3735 "setPictureInPictureParams", token, params);
3736
3737 // Only update the saved args from the args that are set
3738 r.pictureInPictureArgs.copyOnlySet(params);
3739 if (r.inPinnedWindowingMode()) {
3740 // If the activity is already in picture-in-picture, update the pinned stack now
3741 // if it is not already expanding to fullscreen. Otherwise, the arguments will
3742 // be used the next time the activity enters PiP
3743 final PinnedActivityStack stack = r.getStack();
3744 if (!stack.isAnimatingBoundsToFullscreen()) {
3745 stack.setPictureInPictureAspectRatio(
3746 r.pictureInPictureArgs.getAspectRatio());
3747 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
3748 }
3749 }
3750 logPictureInPictureArgs(params);
3751 }
3752 } finally {
3753 Binder.restoreCallingIdentity(origId);
3754 }
3755 }
3756
3757 @Override
3758 public int getMaxNumPictureInPictureActions(IBinder token) {
3759 // Currently, this is a static constant, but later, we may change this to be dependent on
3760 // the context of the activity
3761 return 3;
3762 }
3763
3764 private void logPictureInPictureArgs(PictureInPictureParams params) {
3765 if (params.hasSetActions()) {
3766 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
3767 params.getActions().size());
3768 }
3769 if (params.hasSetAspectRatio()) {
3770 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
3771 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
3772 MetricsLogger.action(lm);
3773 }
3774 }
3775
3776 /**
3777 * Checks the state of the system and the activity associated with the given {@param token} to
3778 * verify that picture-in-picture is supported for that activity.
3779 *
3780 * @return the activity record for the given {@param token} if all the checks pass.
3781 */
3782 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
3783 IBinder token, PictureInPictureParams params) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003784 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003785 throw new IllegalStateException(caller
3786 + ": Device doesn't support picture-in-picture mode.");
3787 }
3788
3789 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3790 if (r == null) {
3791 throw new IllegalStateException(caller
3792 + ": Can't find activity for token=" + token);
3793 }
3794
3795 if (!r.supportsPictureInPicture()) {
3796 throw new IllegalStateException(caller
3797 + ": Current activity does not support picture-in-picture.");
3798 }
3799
3800 if (params.hasSetAspectRatio()
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003801 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003802 params.getAspectRatio())) {
3803 final float minAspectRatio = mContext.getResources().getFloat(
3804 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
3805 final float maxAspectRatio = mContext.getResources().getFloat(
3806 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
3807 throw new IllegalArgumentException(String.format(caller
3808 + ": Aspect ratio is too extreme (must be between %f and %f).",
3809 minAspectRatio, maxAspectRatio));
3810 }
3811
3812 // Truncate the number of actions if necessary
3813 params.truncateActions(getMaxNumPictureInPictureActions(token));
3814
3815 return r;
3816 }
3817
3818 @Override
3819 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003820 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003821 synchronized (mGlobalLock) {
3822 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
3823 if (r == null) {
3824 throw new IllegalArgumentException("Activity does not exist; token="
3825 + activityToken);
3826 }
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07003827 return r.getUriPermissionsLocked().getExternalToken();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003828 }
3829 }
3830
3831 @Override
3832 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
3833 Rect tempDockedTaskInsetBounds,
3834 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003835 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003836 long ident = Binder.clearCallingIdentity();
3837 try {
3838 synchronized (mGlobalLock) {
3839 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
3840 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
3841 PRESERVE_WINDOWS);
3842 }
3843 } finally {
3844 Binder.restoreCallingIdentity(ident);
3845 }
3846 }
3847
3848 @Override
3849 public void setSplitScreenResizing(boolean resizing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003850 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003851 final long ident = Binder.clearCallingIdentity();
3852 try {
3853 synchronized (mGlobalLock) {
3854 mStackSupervisor.setSplitScreenResizing(resizing);
3855 }
3856 } finally {
3857 Binder.restoreCallingIdentity(ident);
3858 }
3859 }
3860
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003861 /**
3862 * Check that we have the features required for VR-related API calls, and throw an exception if
3863 * not.
3864 */
3865 void enforceSystemHasVrFeature() {
3866 if (!mContext.getPackageManager().hasSystemFeature(
3867 PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
3868 throw new UnsupportedOperationException("VR mode not supported on this device!");
3869 }
3870 }
3871
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003872 @Override
3873 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003874 enforceSystemHasVrFeature();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003875
3876 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3877
3878 ActivityRecord r;
3879 synchronized (mGlobalLock) {
3880 r = ActivityRecord.isInStackLocked(token);
3881 }
3882
3883 if (r == null) {
3884 throw new IllegalArgumentException();
3885 }
3886
3887 int err;
3888 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
3889 VrManagerInternal.NO_ERROR) {
3890 return err;
3891 }
3892
3893 // Clear the binder calling uid since this path may call moveToTask().
3894 final long callingId = Binder.clearCallingIdentity();
3895 try {
3896 synchronized (mGlobalLock) {
3897 r.requestedVrComponent = (enabled) ? packageName : null;
3898
3899 // Update associated state if this activity is currently focused
Andrii Kulian52d255c2018-07-13 11:32:19 -07003900 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003901 applyUpdateVrModeLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003902 }
3903 return 0;
3904 }
3905 } finally {
3906 Binder.restoreCallingIdentity(callingId);
3907 }
3908 }
3909
3910 @Override
3911 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
3912 Slog.i(TAG, "Activity tried to startLocalVoiceInteraction");
3913 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003914 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003915 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
3916 throw new SecurityException("Only focused activity can call startVoiceInteraction");
3917 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07003918 if (mRunningVoice != null || activity.getTask().voiceSession != null
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003919 || activity.voiceSession != null) {
3920 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
3921 return;
3922 }
3923 if (activity.pendingVoiceInteractionStart) {
3924 Slog.w(TAG, "Pending start of voice interaction already.");
3925 return;
3926 }
3927 activity.pendingVoiceInteractionStart = true;
3928 }
3929 LocalServices.getService(VoiceInteractionManagerInternal.class)
3930 .startLocalVoiceInteraction(callingActivity, options);
3931 }
3932
3933 @Override
3934 public void stopLocalVoiceInteraction(IBinder callingActivity) {
3935 LocalServices.getService(VoiceInteractionManagerInternal.class)
3936 .stopLocalVoiceInteraction(callingActivity);
3937 }
3938
3939 @Override
3940 public boolean supportsLocalVoiceInteraction() {
3941 return LocalServices.getService(VoiceInteractionManagerInternal.class)
3942 .supportsLocalVoiceInteraction();
3943 }
3944
3945 /** Notifies all listeners when the pinned stack animation starts. */
3946 @Override
3947 public void notifyPinnedStackAnimationStarted() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003948 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003949 }
3950
3951 /** Notifies all listeners when the pinned stack animation ends. */
3952 @Override
3953 public void notifyPinnedStackAnimationEnded() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003954 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003955 }
3956
3957 @Override
3958 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003959 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003960 final long ident = Binder.clearCallingIdentity();
3961 try {
3962 synchronized (mGlobalLock) {
3963 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
3964 }
3965 } finally {
3966 Binder.restoreCallingIdentity(ident);
3967 }
3968 }
3969
3970 @Override
3971 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003972 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003973
3974 synchronized (mGlobalLock) {
3975 // Check if display is initialized in AM.
3976 if (!mStackSupervisor.isDisplayAdded(displayId)) {
3977 // Call might come when display is not yet added or has already been removed.
3978 if (DEBUG_CONFIGURATION) {
3979 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
3980 + displayId);
3981 }
3982 return false;
3983 }
3984
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003985 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003986 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003987 values = mWindowManager.computeNewConfiguration(displayId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003988 }
3989
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003990 if (mWindowManager != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07003991 final Message msg = PooledLambda.obtainMessage(
3992 ActivityManagerInternal::updateOomLevelsForDisplay, mAmInternal, displayId);
3993 mH.sendMessage(msg);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003994 }
3995
3996 final long origId = Binder.clearCallingIdentity();
3997 try {
3998 if (values != null) {
3999 Settings.System.clearConfiguration(values);
4000 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004001 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004002 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
4003 return mTmpUpdateConfigurationResult.changes != 0;
4004 } finally {
4005 Binder.restoreCallingIdentity(origId);
4006 }
4007 }
4008 }
4009
4010 @Override
4011 public boolean updateConfiguration(Configuration values) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004012 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004013
4014 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004015 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004016 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004017 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004018 }
4019
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004020 if (mWindowManager != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004021 final Message msg = PooledLambda.obtainMessage(
4022 ActivityManagerInternal::updateOomLevelsForDisplay, mAmInternal,
4023 DEFAULT_DISPLAY);
4024 mH.sendMessage(msg);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004025 }
4026
4027 final long origId = Binder.clearCallingIdentity();
4028 try {
4029 if (values != null) {
4030 Settings.System.clearConfiguration(values);
4031 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004032 updateConfigurationLocked(values, null, false, false /* persistent */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004033 UserHandle.USER_NULL, false /* deferResume */,
4034 mTmpUpdateConfigurationResult);
4035 return mTmpUpdateConfigurationResult.changes != 0;
4036 } finally {
4037 Binder.restoreCallingIdentity(origId);
4038 }
4039 }
4040 }
4041
4042 @Override
4043 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
4044 CharSequence message) {
4045 if (message != null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004046 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004047 Manifest.permission.SHOW_KEYGUARD_MESSAGE, "dismissKeyguard()");
4048 }
4049 final long callingId = Binder.clearCallingIdentity();
4050 try {
4051 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004052 mKeyguardController.dismissKeyguard(token, callback, message);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004053 }
4054 } finally {
4055 Binder.restoreCallingIdentity(callingId);
4056 }
4057 }
4058
4059 @Override
4060 public void cancelTaskWindowTransition(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004061 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004062 "cancelTaskWindowTransition()");
4063 final long ident = Binder.clearCallingIdentity();
4064 try {
4065 synchronized (mGlobalLock) {
4066 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
4067 MATCH_TASK_IN_STACKS_ONLY);
4068 if (task == null) {
4069 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
4070 return;
4071 }
4072 task.cancelWindowTransition();
4073 }
4074 } finally {
4075 Binder.restoreCallingIdentity(ident);
4076 }
4077 }
4078
4079 @Override
4080 public ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004081 enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004082 final long ident = Binder.clearCallingIdentity();
4083 try {
4084 final TaskRecord task;
4085 synchronized (mGlobalLock) {
4086 task = mStackSupervisor.anyTaskForIdLocked(taskId,
4087 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
4088 if (task == null) {
4089 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
4090 return null;
4091 }
4092 }
4093 // Don't call this while holding the lock as this operation might hit the disk.
4094 return task.getSnapshot(reducedResolution);
4095 } finally {
4096 Binder.restoreCallingIdentity(ident);
4097 }
4098 }
4099
4100 @Override
4101 public void setDisablePreviewScreenshots(IBinder token, boolean disable) {
4102 synchronized (mGlobalLock) {
4103 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4104 if (r == null) {
4105 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
4106 + token);
4107 return;
4108 }
4109 final long origId = Binder.clearCallingIdentity();
4110 try {
4111 r.setDisablePreviewScreenshots(disable);
4112 } finally {
4113 Binder.restoreCallingIdentity(origId);
4114 }
4115 }
4116 }
4117
4118 /** Return the user id of the last resumed activity. */
4119 @Override
4120 public @UserIdInt
4121 int getLastResumedActivityUserId() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004122 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004123 Manifest.permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
4124 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07004125 if (mLastResumedActivity == null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004126 return getCurrentUserId();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004127 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004128 return mLastResumedActivity.userId;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004129 }
4130 }
4131
4132 @Override
4133 public void updateLockTaskFeatures(int userId, int flags) {
4134 final int callingUid = Binder.getCallingUid();
4135 if (callingUid != 0 && callingUid != SYSTEM_UID) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004136 mAmInternal.enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004137 "updateLockTaskFeatures()");
4138 }
4139 synchronized (mGlobalLock) {
4140 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
4141 Integer.toHexString(flags));
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07004142 getLockTaskController().updateLockTaskFeatures(userId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004143 }
4144 }
4145
4146 @Override
4147 public void setShowWhenLocked(IBinder token, boolean showWhenLocked) {
4148 synchronized (mGlobalLock) {
4149 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4150 if (r == null) {
4151 return;
4152 }
4153 final long origId = Binder.clearCallingIdentity();
4154 try {
4155 r.setShowWhenLocked(showWhenLocked);
4156 } finally {
4157 Binder.restoreCallingIdentity(origId);
4158 }
4159 }
4160 }
4161
4162 @Override
4163 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) {
4164 synchronized (mGlobalLock) {
4165 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4166 if (r == null) {
4167 return;
4168 }
4169 final long origId = Binder.clearCallingIdentity();
4170 try {
4171 r.setTurnScreenOn(turnScreenOn);
4172 } finally {
4173 Binder.restoreCallingIdentity(origId);
4174 }
4175 }
4176 }
4177
4178 @Override
4179 public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004180 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004181 "registerRemoteAnimations");
4182 definition.setCallingPid(Binder.getCallingPid());
4183 synchronized (mGlobalLock) {
4184 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4185 if (r == null) {
4186 return;
4187 }
4188 final long origId = Binder.clearCallingIdentity();
4189 try {
4190 r.registerRemoteAnimations(definition);
4191 } finally {
4192 Binder.restoreCallingIdentity(origId);
4193 }
4194 }
4195 }
4196
4197 @Override
4198 public void registerRemoteAnimationForNextActivityStart(String packageName,
4199 RemoteAnimationAdapter adapter) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004200 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004201 "registerRemoteAnimationForNextActivityStart");
4202 adapter.setCallingPid(Binder.getCallingPid());
4203 synchronized (mGlobalLock) {
4204 final long origId = Binder.clearCallingIdentity();
4205 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07004206 getActivityStartController().registerRemoteAnimationForNextActivityStart(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004207 packageName, adapter);
4208 } finally {
4209 Binder.restoreCallingIdentity(origId);
4210 }
4211 }
4212 }
4213
4214 /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
4215 @Override
4216 public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
4217 synchronized (mGlobalLock) {
4218 final long origId = Binder.clearCallingIdentity();
4219 try {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004220 mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004221 } finally {
4222 Binder.restoreCallingIdentity(origId);
4223 }
4224 }
4225 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004226
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004227 @Override
4228 public void setVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004229 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004230 synchronized (mGlobalLock) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004231 final int pid = Binder.getCallingPid();
4232 final WindowProcessController wpc = mPidMap.get(pid);
4233 mVrController.setVrThreadLocked(tid, pid, wpc);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004234 }
4235 }
4236
4237 @Override
4238 public void setPersistentVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004239 if (checkCallingPermission(Manifest.permission.RESTRICTED_VR_ACCESS)
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004240 != PERMISSION_GRANTED) {
4241 final String msg = "Permission Denial: setPersistentVrThread() from pid="
4242 + Binder.getCallingPid()
4243 + ", uid=" + Binder.getCallingUid()
4244 + " requires " + Manifest.permission.RESTRICTED_VR_ACCESS;
4245 Slog.w(TAG, msg);
4246 throw new SecurityException(msg);
4247 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004248 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004249 synchronized (mGlobalLock) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004250 final int pid = Binder.getCallingPid();
4251 final WindowProcessController proc = mPidMap.get(pid);
4252 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004253 }
4254 }
4255
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004256 @Override
4257 public void stopAppSwitches() {
4258 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
4259 synchronized (mGlobalLock) {
4260 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME;
4261 mDidAppSwitch = false;
4262 getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
4263 }
4264 }
4265
4266 @Override
4267 public void resumeAppSwitches() {
4268 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
4269 synchronized (mGlobalLock) {
4270 // Note that we don't execute any pending app switches... we will
4271 // let those wait until either the timeout, or the next start
4272 // activity request.
4273 mAppSwitchesAllowedTime = 0;
4274 }
4275 }
4276
4277 void onStartActivitySetDidAppSwitch() {
4278 if (mDidAppSwitch) {
4279 // This is the second allowed switch since we stopped switches, so now just generally
4280 // allow switches. Use case:
4281 // - user presses home (switches disabled, switch to home, mDidAppSwitch now true);
4282 // - user taps a home icon (coming from home so allowed, we hit here and now allow
4283 // anyone to switch again).
4284 mAppSwitchesAllowedTime = 0;
4285 } else {
4286 mDidAppSwitch = true;
4287 }
4288 }
4289
4290 /** @return whether the system should disable UI modes incompatible with VR mode. */
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004291 boolean shouldDisableNonVrUiLocked() {
4292 return mVrController.shouldDisableNonVrUiLocked();
4293 }
4294
Wale Ogunwale53783742018-09-16 10:21:51 -07004295 private void applyUpdateVrModeLocked(ActivityRecord r) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004296 // VR apps are expected to run in a main display. If an app is turning on VR for
4297 // itself, but lives in a dynamic stack, then make sure that it is moved to the main
4298 // fullscreen stack before enabling VR Mode.
4299 // TODO: The goal of this code is to keep the VR app on the main display. When the
4300 // stack implementation changes in the future, keep in mind that the use of the fullscreen
4301 // stack is a means to move the activity to the main display and a moveActivityToDisplay()
4302 // option would be a better choice here.
4303 if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
4304 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
4305 + " to main stack for VR");
4306 final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
4307 WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
4308 moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
4309 }
4310 mH.post(() -> {
4311 if (!mVrController.onVrModeChanged(r)) {
4312 return;
4313 }
4314 synchronized (mGlobalLock) {
4315 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
4316 mWindowManager.disableNonVrUi(disableNonVrUi);
4317 if (disableNonVrUi) {
4318 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
4319 // then remove the pinned stack.
4320 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
4321 }
4322 }
4323 });
4324 }
4325
Wale Ogunwale53783742018-09-16 10:21:51 -07004326 @Override
4327 public int getPackageScreenCompatMode(String packageName) {
4328 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4329 synchronized (mGlobalLock) {
4330 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4331 }
4332 }
4333
4334 @Override
4335 public void setPackageScreenCompatMode(String packageName, int mode) {
4336 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4337 "setPackageScreenCompatMode");
4338 synchronized (mGlobalLock) {
4339 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4340 }
4341 }
4342
4343 @Override
4344 public boolean getPackageAskScreenCompat(String packageName) {
4345 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4346 synchronized (mGlobalLock) {
4347 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4348 }
4349 }
4350
4351 @Override
4352 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4353 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4354 "setPackageAskScreenCompat");
4355 synchronized (mGlobalLock) {
4356 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4357 }
4358 }
4359
Wale Ogunwale64258362018-10-16 15:13:37 -07004360 public static String relaunchReasonToString(int relaunchReason) {
4361 switch (relaunchReason) {
4362 case RELAUNCH_REASON_WINDOWING_MODE_RESIZE:
4363 return "window_resize";
4364 case RELAUNCH_REASON_FREE_RESIZE:
4365 return "free_resize";
4366 default:
4367 return null;
4368 }
4369 }
4370
Andrii Kulian5f750bc2018-07-17 08:57:23 -07004371 ActivityStack getTopDisplayFocusedStack() {
4372 return mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004373 }
4374
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004375 /** Pokes the task persister. */
4376 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
4377 mRecentTasks.notifyTaskPersisterLocked(task, flush);
4378 }
4379
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004380 boolean isKeyguardLocked() {
4381 return mKeyguardController.isKeyguardLocked();
4382 }
4383
4384 boolean isNextTransitionForward() {
4385 int transit = mWindowManager.getPendingAppTransition();
4386 return transit == TRANSIT_ACTIVITY_OPEN
4387 || transit == TRANSIT_TASK_OPEN
4388 || transit == TRANSIT_TASK_TO_FRONT;
4389 }
4390
Wale Ogunwale31913b52018-10-13 08:29:31 -07004391 void dumpLastANRLocked(PrintWriter pw) {
4392 pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
4393 if (mLastANRState == null) {
4394 pw.println(" <no ANR has occurred since boot>");
4395 } else {
4396 pw.println(mLastANRState);
4397 }
4398 }
4399
4400 void dumpLastANRTracesLocked(PrintWriter pw) {
4401 pw.println("ACTIVITY MANAGER LAST ANR TRACES (dumpsys activity lastanr-traces)");
4402
4403 final File[] files = new File(ANR_TRACE_DIR).listFiles();
4404 if (ArrayUtils.isEmpty(files)) {
4405 pw.println(" <no ANR has occurred since boot>");
4406 return;
4407 }
4408 // Find the latest file.
4409 File latest = null;
4410 for (File f : files) {
4411 if ((latest == null) || (latest.lastModified() < f.lastModified())) {
4412 latest = f;
Wale Ogunwalef6733932018-06-27 05:14:34 -07004413 }
Wale Ogunwale31913b52018-10-13 08:29:31 -07004414 }
4415 pw.print("File: ");
4416 pw.print(latest.getName());
4417 pw.println();
4418 try (BufferedReader in = new BufferedReader(new FileReader(latest))) {
4419 String line;
4420 while ((line = in.readLine()) != null) {
4421 pw.println(line);
4422 }
4423 } catch (IOException e) {
4424 pw.print("Unable to read: ");
4425 pw.print(e);
4426 pw.println();
4427 }
4428 }
4429
4430 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
4431 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
4432 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
4433 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
4434 }
4435
4436 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
4437 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
4438 pw.println(header);
4439
4440 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
4441 dumpPackage);
4442 boolean needSep = printedAnything;
4443
4444 boolean printed = ActivityStackSupervisor.printThisActivity(pw,
4445 mStackSupervisor.getTopResumedActivity(), dumpPackage, needSep,
4446 " ResumedActivity: ");
4447 if (printed) {
4448 printedAnything = true;
4449 needSep = false;
4450 }
4451
4452 if (dumpPackage == null) {
4453 if (needSep) {
4454 pw.println();
4455 }
4456 printedAnything = true;
4457 mStackSupervisor.dump(pw, " ");
4458 }
4459
4460 if (!printedAnything) {
4461 pw.println(" (nothing)");
4462 }
4463 }
4464
4465 void dumpActivityContainersLocked(PrintWriter pw) {
4466 pw.println("ACTIVITY MANAGER STARTER (dumpsys activity containers)");
4467 mStackSupervisor.dumpChildrenNames(pw, " ");
4468 pw.println(" ");
4469 }
4470
4471 void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
4472 pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
4473 getActivityStartController().dump(pw, "", dumpPackage);
4474 }
4475
4476 /**
4477 * There are three things that cmd can be:
4478 * - a flattened component name that matches an existing activity
4479 * - the cmd arg isn't the flattened component name of an existing activity:
4480 * dump all activity whose component contains the cmd as a substring
4481 * - A hex number of the ActivityRecord object instance.
4482 *
4483 * @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
4484 * @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
4485 */
4486 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
4487 int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
4488 ArrayList<ActivityRecord> activities;
4489
4490 synchronized (mGlobalLock) {
4491 activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
4492 dumpFocusedStackOnly);
4493 }
4494
4495 if (activities.size() <= 0) {
4496 return false;
4497 }
4498
4499 String[] newArgs = new String[args.length - opti];
4500 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
4501
4502 TaskRecord lastTask = null;
4503 boolean needSep = false;
4504 for (int i = activities.size() - 1; i >= 0; i--) {
4505 ActivityRecord r = activities.get(i);
4506 if (needSep) {
4507 pw.println();
4508 }
4509 needSep = true;
4510 synchronized (mGlobalLock) {
4511 final TaskRecord task = r.getTask();
4512 if (lastTask != task) {
4513 lastTask = task;
4514 pw.print("TASK "); pw.print(lastTask.affinity);
4515 pw.print(" id="); pw.print(lastTask.taskId);
4516 pw.print(" userId="); pw.println(lastTask.userId);
4517 if (dumpAll) {
4518 lastTask.dump(pw, " ");
4519 }
4520 }
4521 }
4522 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
4523 }
4524 return true;
4525 }
4526
4527 /**
4528 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
4529 * there is a thread associated with the activity.
4530 */
4531 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
4532 final ActivityRecord r, String[] args, boolean dumpAll) {
4533 String innerPrefix = prefix + " ";
4534 synchronized (mGlobalLock) {
4535 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
4536 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
4537 pw.print(" pid=");
4538 if (r.hasProcess()) pw.println(r.app.getPid());
4539 else pw.println("(not running)");
4540 if (dumpAll) {
4541 r.dump(pw, innerPrefix);
4542 }
4543 }
4544 if (r.attachedToProcess()) {
4545 // flush anything that is already in the PrintWriter since the thread is going
4546 // to write to the file descriptor directly
4547 pw.flush();
4548 try {
4549 TransferPipe tp = new TransferPipe();
4550 try {
4551 r.app.getThread().dumpActivity(tp.getWriteFd(),
4552 r.appToken, innerPrefix, args);
4553 tp.go(fd);
4554 } finally {
4555 tp.kill();
4556 }
4557 } catch (IOException e) {
4558 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
4559 } catch (RemoteException e) {
4560 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
4561 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004562 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004563 }
4564
Wale Ogunwalef6733932018-06-27 05:14:34 -07004565 void writeSleepStateToProto(ProtoOutputStream proto) {
4566 for (ActivityTaskManagerInternal.SleepToken st : mStackSupervisor.mSleepTokens) {
4567 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS,
4568 st.toString());
4569 }
4570
4571 if (mRunningVoice != null) {
4572 final long vrToken = proto.start(
4573 ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
4574 proto.write(ActivityManagerServiceDumpProcessesProto.Voice.SESSION,
4575 mRunningVoice.toString());
4576 mVoiceWakeLock.writeToProto(
4577 proto, ActivityManagerServiceDumpProcessesProto.Voice.WAKELOCK);
4578 proto.end(vrToken);
4579 }
4580
4581 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
4582 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN,
4583 mShuttingDown);
4584 mVrController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004585 }
4586
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004587 int getCurrentUserId() {
4588 return mAmInternal.getCurrentUserId();
4589 }
4590
4591 private void enforceNotIsolatedCaller(String caller) {
4592 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4593 throw new SecurityException("Isolated process not allowed to call " + caller);
4594 }
4595 }
4596
Wale Ogunwalef6733932018-06-27 05:14:34 -07004597 public Configuration getConfiguration() {
4598 Configuration ci;
4599 synchronized(mGlobalLock) {
Yunfan Chen75157d72018-07-27 14:47:21 +09004600 ci = new Configuration(getGlobalConfigurationForCallingPid());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004601 ci.userSetLocale = false;
4602 }
4603 return ci;
4604 }
4605
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004606 /**
4607 * Current global configuration information. Contains general settings for the entire system,
4608 * also corresponds to the merged configuration of the default display.
4609 */
4610 Configuration getGlobalConfiguration() {
4611 return mStackSupervisor.getConfiguration();
4612 }
4613
4614 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4615 boolean initLocale) {
4616 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
4617 }
4618
4619 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4620 boolean initLocale, boolean deferResume) {
4621 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
4622 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
4623 UserHandle.USER_NULL, deferResume);
4624 }
4625
4626 void updatePersistentConfiguration(Configuration values, @UserIdInt int userId) {
4627 final long origId = Binder.clearCallingIdentity();
4628 try {
4629 synchronized (mGlobalLock) {
4630 updateConfigurationLocked(values, null, false, true, userId,
4631 false /* deferResume */);
4632 }
4633 } finally {
4634 Binder.restoreCallingIdentity(origId);
4635 }
4636 }
4637
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004638 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4639 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
4640 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
4641 deferResume, null /* result */);
4642 }
4643
4644 /**
4645 * Do either or both things: (1) change the current configuration, and (2)
4646 * make sure the given activity is running with the (now) current
4647 * configuration. Returns true if the activity has been left running, or
4648 * false if <var>starting</var> is being destroyed to match the new
4649 * configuration.
4650 *
4651 * @param userId is only used when persistent parameter is set to true to persist configuration
4652 * for that particular user
4653 */
4654 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4655 boolean initLocale, boolean persistent, int userId, boolean deferResume,
4656 ActivityTaskManagerService.UpdateConfigurationResult result) {
4657 int changes = 0;
4658 boolean kept = true;
4659
4660 if (mWindowManager != null) {
4661 mWindowManager.deferSurfaceLayout();
4662 }
4663 try {
4664 if (values != null) {
4665 changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
4666 deferResume);
4667 }
4668
4669 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4670 } finally {
4671 if (mWindowManager != null) {
4672 mWindowManager.continueSurfaceLayout();
4673 }
4674 }
4675
4676 if (result != null) {
4677 result.changes = changes;
4678 result.activityRelaunched = !kept;
4679 }
4680 return kept;
4681 }
4682
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004683 /** Update default (global) configuration and notify listeners about changes. */
4684 private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
4685 boolean persistent, int userId, boolean deferResume) {
4686 mTempConfig.setTo(getGlobalConfiguration());
4687 final int changes = mTempConfig.updateFrom(values);
4688 if (changes == 0) {
4689 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
4690 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
4691 // performDisplayOverrideConfigUpdate in order to send the new display configuration
4692 // (even if there are no actual changes) to unfreeze the window.
4693 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
4694 return 0;
4695 }
4696
4697 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
4698 "Updating global configuration to: " + values);
4699
4700 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
4701 StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
4702 values.colorMode,
4703 values.densityDpi,
4704 values.fontScale,
4705 values.hardKeyboardHidden,
4706 values.keyboard,
4707 values.keyboardHidden,
4708 values.mcc,
4709 values.mnc,
4710 values.navigation,
4711 values.navigationHidden,
4712 values.orientation,
4713 values.screenHeightDp,
4714 values.screenLayout,
4715 values.screenWidthDp,
4716 values.smallestScreenWidthDp,
4717 values.touchscreen,
4718 values.uiMode);
4719
4720
4721 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
4722 final LocaleList locales = values.getLocales();
4723 int bestLocaleIndex = 0;
4724 if (locales.size() > 1) {
4725 if (mSupportedSystemLocales == null) {
4726 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
4727 }
4728 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
4729 }
4730 SystemProperties.set("persist.sys.locale",
4731 locales.get(bestLocaleIndex).toLanguageTag());
4732 LocaleList.setDefault(locales, bestLocaleIndex);
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004733
4734 final Message m = PooledLambda.obtainMessage(
4735 ActivityTaskManagerService::sendLocaleToMountDaemonMsg, this,
4736 locales.get(bestLocaleIndex));
4737 mH.sendMessage(m);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004738 }
4739
Yunfan Chen75157d72018-07-27 14:47:21 +09004740 mTempConfig.seq = increaseConfigurationSeqLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004741
4742 // Update stored global config and notify everyone about the change.
4743 mStackSupervisor.onConfigurationChanged(mTempConfig);
4744
4745 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
4746 // TODO(multi-display): Update UsageEvents#Event to include displayId.
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004747 mUsageStatsInternal.reportConfigurationChange(mTempConfig, mAmInternal.getCurrentUserId());
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004748
4749 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
Wale Ogunwalef6733932018-06-27 05:14:34 -07004750 updateShouldShowDialogsLocked(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004751
4752 AttributeCache ac = AttributeCache.instance();
4753 if (ac != null) {
4754 ac.updateConfiguration(mTempConfig);
4755 }
4756
4757 // Make sure all resources in our process are updated right now, so that anyone who is going
4758 // to retrieve resource values after we return will be sure to get the new ones. This is
4759 // especially important during boot, where the first config change needs to guarantee all
4760 // resources have that config before following boot code is executed.
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004761 mSystemThread.applyConfigurationToResources(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004762
4763 // We need another copy of global config because we're scheduling some calls instead of
4764 // running them in place. We need to be sure that object we send will be handled unchanged.
4765 final Configuration configCopy = new Configuration(mTempConfig);
4766 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004767 final Message msg = PooledLambda.obtainMessage(
4768 ActivityTaskManagerService::sendPutConfigurationForUserMsg,
4769 this, userId, configCopy);
4770 mH.sendMessage(msg);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004771 }
4772
Yunfan Chen34fcc7a2018-10-11 16:26:09 -07004773 for (int i = mPidMap.size() - 1; i >= 0; i--) {
Yunfan Chen79b96062018-10-17 12:45:23 -07004774 final int pid = mPidMap.keyAt(i);
4775 final WindowProcessController app = mPidMap.get(pid);
Yunfan Chen34fcc7a2018-10-11 16:26:09 -07004776 if (DEBUG_CONFIGURATION) {
4777 Slog.v(TAG_CONFIGURATION, "Update process config of "
4778 + app.mName + " to new config " + configCopy);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004779 }
Yunfan Chen34fcc7a2018-10-11 16:26:09 -07004780 app.onConfigurationChanged(configCopy);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004781 }
4782
Wale Ogunwale2ea36d42018-10-18 10:27:31 -07004783 final Message msg = PooledLambda.obtainMessage(
4784 ActivityManagerInternal::broadcastGlobalConfigurationChanged,
4785 mAmInternal, changes, initLocale);
4786 mH.sendMessage(msg);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004787
4788 // Override configuration of the default display duplicates global config, so we need to
4789 // update it also. This will also notify WindowManager about changes.
4790 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
4791 DEFAULT_DISPLAY);
4792
4793 return changes;
4794 }
4795
4796 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
4797 boolean deferResume, int displayId) {
4798 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
4799 displayId, null /* result */);
4800 }
4801
4802 /**
4803 * Updates override configuration specific for the selected display. If no config is provided,
4804 * new one will be computed in WM based on current display info.
4805 */
4806 boolean updateDisplayOverrideConfigurationLocked(Configuration values,
4807 ActivityRecord starting, boolean deferResume, int displayId,
4808 ActivityTaskManagerService.UpdateConfigurationResult result) {
4809 int changes = 0;
4810 boolean kept = true;
4811
4812 if (mWindowManager != null) {
4813 mWindowManager.deferSurfaceLayout();
4814 }
4815 try {
4816 if (values != null) {
4817 if (displayId == DEFAULT_DISPLAY) {
4818 // Override configuration of the default display duplicates global config, so
4819 // we're calling global config update instead for default display. It will also
4820 // apply the correct override config.
4821 changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
4822 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
4823 } else {
4824 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
4825 }
4826 }
4827
4828 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4829 } finally {
4830 if (mWindowManager != null) {
4831 mWindowManager.continueSurfaceLayout();
4832 }
4833 }
4834
4835 if (result != null) {
4836 result.changes = changes;
4837 result.activityRelaunched = !kept;
4838 }
4839 return kept;
4840 }
4841
4842 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
4843 int displayId) {
4844 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
4845 final int changes = mTempConfig.updateFrom(values);
4846 if (changes != 0) {
4847 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
4848 + mTempConfig + " for displayId=" + displayId);
4849 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
4850
4851 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
4852 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004853 mAppWarnings.onDensityChanged();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004854
Wale Ogunwale5c918702018-10-18 11:06:33 -07004855 // Post message to start process to avoid possible deadlock of calling into AMS with
4856 // the ATMS lock held.
4857 final Message msg = PooledLambda.obtainMessage(
4858 ActivityManagerInternal::killAllBackgroundProcessesExcept, mAmInternal,
4859 N, ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
4860 mH.sendMessage(msg);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004861 }
4862 }
4863
4864 // Update the configuration with WM first and check if any of the stacks need to be resized
4865 // due to the configuration change. If so, resize the stacks now and do any relaunches if
4866 // necessary. This way we don't need to relaunch again afterwards in
4867 // ensureActivityConfiguration().
4868 if (mWindowManager != null) {
4869 final int[] resizedStacks =
4870 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
4871 if (resizedStacks != null) {
4872 for (int stackId : resizedStacks) {
4873 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
4874 }
4875 }
4876 }
4877
4878 return changes;
4879 }
4880
Wale Ogunwalef6733932018-06-27 05:14:34 -07004881 private void updateEventDispatchingLocked(boolean booted) {
4882 mWindowManager.setEventDispatching(booted && !mShuttingDown);
4883 }
4884
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004885 private void sendPutConfigurationForUserMsg(int userId, Configuration config) {
4886 final ContentResolver resolver = mContext.getContentResolver();
4887 Settings.System.putConfigurationForUser(resolver, config, userId);
4888 }
4889
4890 private void sendLocaleToMountDaemonMsg(Locale l) {
4891 try {
4892 IBinder service = ServiceManager.getService("mount");
4893 IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
4894 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
4895 storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
4896 } catch (RemoteException e) {
4897 Log.e(TAG, "Error storing locale for decryption UI", e);
4898 }
4899 }
4900
4901 boolean isActivityStartsLoggingEnabled() {
4902 return mAmInternal.isActivityStartsLoggingEnabled();
4903 }
4904
Wale Ogunwalef6733932018-06-27 05:14:34 -07004905 void enableScreenAfterBoot(boolean booted) {
4906 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4907 SystemClock.uptimeMillis());
4908 mWindowManager.enableScreenAfterBoot();
4909
4910 synchronized (mGlobalLock) {
4911 updateEventDispatchingLocked(booted);
4912 }
4913 }
4914
Wale Ogunwale906f9c62018-07-23 11:23:44 -07004915 static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
4916 if (r == null || !r.hasProcess()) {
4917 return KEY_DISPATCHING_TIMEOUT_MS;
4918 }
4919 return getInputDispatchingTimeoutLocked(r.app);
4920 }
4921
4922 private static long getInputDispatchingTimeoutLocked(WindowProcessController r) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07004923 return r != null ? r.getInputDispatchingTimeout() : KEY_DISPATCHING_TIMEOUT_MS;
Wale Ogunwale906f9c62018-07-23 11:23:44 -07004924 }
4925
Wale Ogunwalef6733932018-06-27 05:14:34 -07004926 /**
4927 * Decide based on the configuration whether we should show the ANR,
4928 * crash, etc dialogs. The idea is that if there is no affordance to
4929 * press the on-screen buttons, or the user experience would be more
4930 * greatly impacted than the crash itself, we shouldn't show the dialog.
4931 *
4932 * A thought: SystemUI might also want to get told about this, the Power
4933 * dialog / global actions also might want different behaviors.
4934 */
4935 private void updateShouldShowDialogsLocked(Configuration config) {
4936 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
4937 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
4938 && config.navigation == Configuration.NAVIGATION_NONAV);
4939 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
4940 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
4941 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
4942 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
4943 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
4944 final boolean hideDialogsSet = Settings.Global.getInt(mContext.getContentResolver(),
4945 HIDE_ERROR_DIALOGS, 0) != 0;
4946 mShowDialogs = inputMethodExists && uiModeSupportsDialogs && !hideDialogsSet;
4947 }
4948
4949 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
4950 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
4951 FONT_SCALE, 1.0f, userId);
4952
4953 synchronized (this) {
4954 if (getGlobalConfiguration().fontScale == scaleFactor) {
4955 return;
4956 }
4957
4958 final Configuration configuration
4959 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
4960 configuration.fontScale = scaleFactor;
4961 updatePersistentConfiguration(configuration, userId);
4962 }
4963 }
4964
4965 // Actually is sleeping or shutting down or whatever else in the future
4966 // is an inactive state.
4967 boolean isSleepingOrShuttingDownLocked() {
4968 return isSleepingLocked() || mShuttingDown;
4969 }
4970
4971 boolean isSleepingLocked() {
4972 return mSleeping;
4973 }
4974
Riddle Hsu16567132018-08-16 21:37:47 +08004975 /** Update AMS states when an activity is resumed. */
Wale Ogunwalef6733932018-06-27 05:14:34 -07004976 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
4977 final TaskRecord task = r.getTask();
4978 if (task.isActivityTypeStandard()) {
4979 if (mCurAppTimeTracker != r.appTimeTracker) {
4980 // We are switching app tracking. Complete the current one.
4981 if (mCurAppTimeTracker != null) {
4982 mCurAppTimeTracker.stop();
4983 mH.obtainMessage(
4984 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
4985 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
4986 mCurAppTimeTracker = null;
4987 }
4988 if (r.appTimeTracker != null) {
4989 mCurAppTimeTracker = r.appTimeTracker;
4990 startTimeTrackingFocusedActivityLocked();
4991 }
4992 } else {
4993 startTimeTrackingFocusedActivityLocked();
4994 }
4995 } else {
4996 r.appTimeTracker = null;
4997 }
4998 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
4999 // TODO: Probably not, because we don't want to resume voice on switching
5000 // back to this activity
5001 if (task.voiceInteractor != null) {
5002 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
5003 } else {
5004 finishRunningVoiceLocked();
5005
5006 if (mLastResumedActivity != null) {
5007 final IVoiceInteractionSession session;
5008
5009 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
5010 if (lastResumedActivityTask != null
5011 && lastResumedActivityTask.voiceSession != null) {
5012 session = lastResumedActivityTask.voiceSession;
5013 } else {
5014 session = mLastResumedActivity.voiceSession;
5015 }
5016
5017 if (session != null) {
5018 // We had been in a voice interaction session, but now focused has
5019 // move to something different. Just finish the session, we can't
5020 // return to it and retain the proper state and synchronization with
5021 // the voice interaction service.
5022 finishVoiceTask(session);
5023 }
5024 }
5025 }
5026
5027 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
5028 mAmInternal.sendForegroundProfileChanged(r.userId);
5029 }
5030 updateResumedAppTrace(r);
5031 mLastResumedActivity = r;
5032
Tiger Huang1e5b10a2018-07-30 20:19:51 +08005033 r.getDisplay().setFocusedApp(r, true);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005034
5035 applyUpdateLockStateLocked(r);
5036 applyUpdateVrModeLocked(r);
5037
5038 EventLogTags.writeAmSetResumedActivity(
5039 r == null ? -1 : r.userId,
5040 r == null ? "NULL" : r.shortComponentName,
5041 reason);
5042 }
5043
5044 ActivityTaskManagerInternal.SleepToken acquireSleepToken(String tag, int displayId) {
5045 synchronized (mGlobalLock) {
5046 final ActivityTaskManagerInternal.SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
5047 updateSleepIfNeededLocked();
5048 return token;
5049 }
5050 }
5051
5052 void updateSleepIfNeededLocked() {
5053 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
5054 final boolean wasSleeping = mSleeping;
5055 boolean updateOomAdj = false;
5056
5057 if (!shouldSleep) {
5058 // If wasSleeping is true, we need to wake up activity manager state from when
5059 // we started sleeping. In either case, we need to apply the sleep tokens, which
5060 // will wake up stacks or put them to sleep as appropriate.
5061 if (wasSleeping) {
5062 mSleeping = false;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07005063 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
5064 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__AWAKE);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005065 startTimeTrackingFocusedActivityLocked();
5066 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
5067 mStackSupervisor.comeOutOfSleepIfNeededLocked();
5068 }
5069 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
5070 if (wasSleeping) {
5071 updateOomAdj = true;
5072 }
5073 } else if (!mSleeping && shouldSleep) {
5074 mSleeping = true;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07005075 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
5076 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__ASLEEP);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005077 if (mCurAppTimeTracker != null) {
5078 mCurAppTimeTracker.stop();
5079 }
5080 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
5081 mStackSupervisor.goingToSleepLocked();
5082 updateResumedAppTrace(null /* resumed */);
5083 updateOomAdj = true;
5084 }
5085 if (updateOomAdj) {
5086 mH.post(mAmInternal::updateOomAdj);
5087 }
5088 }
5089
5090 void updateOomAdj() {
5091 mH.post(mAmInternal::updateOomAdj);
5092 }
5093
Wale Ogunwale53783742018-09-16 10:21:51 -07005094 void updateCpuStats() {
5095 mH.post(mAmInternal::updateCpuStats);
5096 }
5097
5098 void updateUsageStats(ActivityRecord component, boolean resumed) {
5099 final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::updateUsageStats,
5100 mAmInternal, component.realActivity, component.app.mUid, component.userId, resumed);
5101 mH.sendMessage(m);
5102 }
5103
5104 void setBooting(boolean booting) {
5105 mAmInternal.setBooting(booting);
5106 }
5107
5108 boolean isBooting() {
5109 return mAmInternal.isBooting();
5110 }
5111
5112 void setBooted(boolean booted) {
5113 mAmInternal.setBooted(booted);
5114 }
5115
5116 boolean isBooted() {
5117 return mAmInternal.isBooted();
5118 }
5119
5120 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
5121 mH.post(() -> {
5122 if (finishBooting) {
5123 mAmInternal.finishBooting();
5124 }
5125 if (enableScreen) {
5126 mInternal.enableScreenAfterBoot(isBooted());
5127 }
5128 });
5129 }
5130
5131 void setHeavyWeightProcess(ActivityRecord root) {
5132 mHeavyWeightProcess = root.app;
5133 final Message m = PooledLambda.obtainMessage(
5134 ActivityTaskManagerService::postHeavyWeightProcessNotification, this,
5135 root.app, root.intent, root.userId);
5136 mH.sendMessage(m);
5137 }
5138
5139 void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
5140 if (mHeavyWeightProcess == null || mHeavyWeightProcess != proc) {
5141 return;
5142 }
5143
5144 mHeavyWeightProcess = null;
5145 final Message m = PooledLambda.obtainMessage(
5146 ActivityTaskManagerService::cancelHeavyWeightProcessNotification, this,
5147 proc.mUserId);
5148 mH.sendMessage(m);
5149 }
5150
5151 private void cancelHeavyWeightProcessNotification(int userId) {
5152 final INotificationManager inm = NotificationManager.getService();
5153 if (inm == null) {
5154 return;
5155 }
5156 try {
5157 inm.cancelNotificationWithTag("android", null,
5158 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, userId);
5159 } catch (RuntimeException e) {
5160 Slog.w(TAG, "Error canceling notification for service", e);
5161 } catch (RemoteException e) {
5162 }
5163
5164 }
5165
5166 private void postHeavyWeightProcessNotification(
5167 WindowProcessController proc, Intent intent, int userId) {
5168 if (proc == null) {
5169 return;
5170 }
5171
5172 final INotificationManager inm = NotificationManager.getService();
5173 if (inm == null) {
5174 return;
5175 }
5176
5177 try {
5178 Context context = mContext.createPackageContext(proc.mInfo.packageName, 0);
5179 String text = mContext.getString(R.string.heavy_weight_notification,
5180 context.getApplicationInfo().loadLabel(context.getPackageManager()));
5181 Notification notification =
5182 new Notification.Builder(context,
5183 SystemNotificationChannels.HEAVY_WEIGHT_APP)
5184 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
5185 .setWhen(0)
5186 .setOngoing(true)
5187 .setTicker(text)
5188 .setColor(mContext.getColor(
5189 com.android.internal.R.color.system_notification_accent_color))
5190 .setContentTitle(text)
5191 .setContentText(
5192 mContext.getText(R.string.heavy_weight_notification_detail))
5193 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
5194 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
5195 new UserHandle(userId)))
5196 .build();
5197 try {
5198 inm.enqueueNotificationWithTag("android", "android", null,
5199 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, notification, userId);
5200 } catch (RuntimeException e) {
5201 Slog.w(TAG, "Error showing notification for heavy-weight app", e);
5202 } catch (RemoteException e) {
5203 }
5204 } catch (PackageManager.NameNotFoundException e) {
5205 Slog.w(TAG, "Unable to create context for heavy notification", e);
5206 }
5207
5208 }
5209
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07005210 IIntentSender getIntentSenderLocked(int type, String packageName, int callingUid, int userId,
5211 IBinder token, String resultWho, int requestCode, Intent[] intents,
5212 String[] resolvedTypes, int flags, Bundle bOptions) {
5213
5214 ActivityRecord activity = null;
5215 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5216 activity = ActivityRecord.isInStackLocked(token);
5217 if (activity == null) {
5218 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
5219 return null;
5220 }
5221 if (activity.finishing) {
5222 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
5223 return null;
5224 }
5225 }
5226
5227 final PendingIntentRecord rec = mPendingIntentController.getIntentSender(type, packageName,
5228 callingUid, userId, token, resultWho, requestCode, intents, resolvedTypes, flags,
5229 bOptions);
5230 final boolean noCreate = (flags & PendingIntent.FLAG_NO_CREATE) != 0;
5231 if (noCreate) {
5232 return rec;
5233 }
5234 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5235 if (activity.pendingResults == null) {
5236 activity.pendingResults = new HashSet<>();
5237 }
5238 activity.pendingResults.add(rec.ref);
5239 }
5240 return rec;
5241 }
5242
Andrii Kulian52d255c2018-07-13 11:32:19 -07005243 // TODO(b/111541062): Update app time tracking to make it aware of multiple resumed activities
Wale Ogunwalef6733932018-06-27 05:14:34 -07005244 private void startTimeTrackingFocusedActivityLocked() {
Andrii Kulian52d255c2018-07-13 11:32:19 -07005245 final ActivityRecord resumedActivity = mStackSupervisor.getTopResumedActivity();
Wale Ogunwalef6733932018-06-27 05:14:34 -07005246 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
5247 mCurAppTimeTracker.start(resumedActivity.packageName);
5248 }
5249 }
5250
5251 private void updateResumedAppTrace(@Nullable ActivityRecord resumed) {
5252 if (mTracedResumedActivity != null) {
5253 Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER,
5254 constructResumedTraceName(mTracedResumedActivity.packageName), 0);
5255 }
5256 if (resumed != null) {
5257 Trace.asyncTraceBegin(TRACE_TAG_ACTIVITY_MANAGER,
5258 constructResumedTraceName(resumed.packageName), 0);
5259 }
5260 mTracedResumedActivity = resumed;
5261 }
5262
5263 private String constructResumedTraceName(String packageName) {
5264 return "focused app: " + packageName;
5265 }
5266
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005267 /** Helper method that requests bounds from WM and applies them to stack. */
5268 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
5269 final Rect newStackBounds = new Rect();
5270 final ActivityStack stack = mStackSupervisor.getStack(stackId);
5271
5272 // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
5273 if (stack == null) {
5274 final StringWriter writer = new StringWriter();
5275 final PrintWriter printWriter = new PrintWriter(writer);
5276 mStackSupervisor.dumpDisplays(printWriter);
5277 printWriter.flush();
5278
5279 Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
5280 }
5281
5282 stack.getBoundsForNewConfiguration(newStackBounds);
5283 mStackSupervisor.resizeStackLocked(
5284 stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
5285 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
5286 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
5287 }
5288
5289 /** Applies latest configuration and/or visibility updates if needed. */
5290 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
5291 boolean kept = true;
Andrii Kulian5f750bc2018-07-17 08:57:23 -07005292 final ActivityStack mainStack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005293 // mainStack is null during startup.
5294 if (mainStack != null) {
5295 if (changes != 0 && starting == null) {
5296 // If the configuration changed, and the caller is not already
5297 // in the process of starting an activity, then find the top
5298 // activity to check if its configuration needs to change.
5299 starting = mainStack.topRunningActivityLocked();
5300 }
5301
5302 if (starting != null) {
5303 kept = starting.ensureActivityConfiguration(changes,
5304 false /* preserveWindow */);
5305 // And we need to make sure at this point that all other activities
5306 // are made visible with the correct configuration.
5307 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
5308 !PRESERVE_WINDOWS);
5309 }
5310 }
5311
5312 return kept;
5313 }
5314
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005315 void scheduleAppGcsLocked() {
5316 mH.post(() -> mAmInternal.scheduleAppGcs());
5317 }
5318
Wale Ogunwale53783742018-09-16 10:21:51 -07005319 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
5320 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
5321 }
5322
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005323 /**
5324 * Returns the PackageManager. Used by classes hosted by {@link ActivityTaskManagerService}. The
5325 * PackageManager could be unavailable at construction time and therefore needs to be accessed
5326 * on demand.
5327 */
5328 IPackageManager getPackageManager() {
5329 return AppGlobals.getPackageManager();
5330 }
5331
5332 PackageManagerInternal getPackageManagerInternalLocked() {
5333 if (mPmInternal == null) {
5334 mPmInternal = LocalServices.getService(PackageManagerInternal.class);
5335 }
5336 return mPmInternal;
5337 }
5338
Wale Ogunwale008163e2018-07-23 23:11:08 -07005339 AppWarnings getAppWarningsLocked() {
5340 return mAppWarnings;
5341 }
5342
Wale Ogunwale214f3482018-10-04 11:00:47 -07005343 Intent getHomeIntent() {
5344 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
5345 intent.setComponent(mTopComponent);
5346 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
5347 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5348 intent.addCategory(Intent.CATEGORY_HOME);
5349 }
5350 return intent;
5351 }
5352
Wale Ogunwale214f3482018-10-04 11:00:47 -07005353 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
5354 if (info == null) return null;
5355 ApplicationInfo newInfo = new ApplicationInfo(info);
5356 newInfo.initForUser(userId);
5357 return newInfo;
5358 }
5359
Wale Ogunwale9c103022018-10-18 07:44:54 -07005360 WindowProcessController getProcessController(String processName, int uid) {
Wale Ogunwale214f3482018-10-04 11:00:47 -07005361 if (uid == SYSTEM_UID) {
5362 // The system gets to run in any process. If there are multiple processes with the same
5363 // uid, just pick the first (this should never happen).
5364 final SparseArray<WindowProcessController> procs =
5365 mProcessNames.getMap().get(processName);
5366 if (procs == null) return null;
5367 final int procCount = procs.size();
5368 for (int i = 0; i < procCount; i++) {
5369 final int procUid = procs.keyAt(i);
5370 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
5371 // Don't use an app process or different user process for system component.
5372 continue;
5373 }
5374 return procs.valueAt(i);
5375 }
5376 }
5377
5378 return mProcessNames.get(processName, uid);
5379 }
5380
Wale Ogunwale342fbe92018-10-09 08:44:10 -07005381 WindowProcessController getProcessController(IApplicationThread thread) {
5382 if (thread == null) {
5383 return null;
5384 }
5385
5386 final IBinder threadBinder = thread.asBinder();
5387 final ArrayMap<String, SparseArray<WindowProcessController>> pmap = mProcessNames.getMap();
5388 for (int i = pmap.size()-1; i >= 0; i--) {
5389 final SparseArray<WindowProcessController> procs = pmap.valueAt(i);
5390 for (int j = procs.size() - 1; j >= 0; j--) {
5391 final WindowProcessController proc = procs.valueAt(j);
5392 if (proc.hasThread() && proc.getThread().asBinder() == threadBinder) {
5393 return proc;
5394 }
5395 }
5396 }
5397
5398 return null;
5399 }
5400
Wale Ogunwalebff2df42018-10-18 17:09:19 -07005401 int getUidStateLocked(int uid) {
5402 return mActiveUids.get(uid, PROCESS_STATE_NONEXISTENT);
5403 }
5404
Wale Ogunwale9de19442018-10-18 19:05:03 -07005405 /**
5406 * @return whitelist tag for a uid from mPendingTempWhitelist, null if not currently on
5407 * the whitelist
5408 */
5409 String getPendingTempWhitelistTagForUidLocked(int uid) {
5410 return mPendingTempWhitelist.get(uid);
5411 }
5412
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005413 void logAppTooSlow(WindowProcessController app, long startTime, String msg) {
5414 if (true || Build.IS_USER) {
5415 return;
5416 }
5417
5418 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5419 StrictMode.allowThreadDiskWrites();
5420 try {
5421 File tracesDir = new File("/data/anr");
5422 File tracesFile = null;
5423 try {
5424 tracesFile = File.createTempFile("app_slow", null, tracesDir);
5425
5426 StringBuilder sb = new StringBuilder();
5427 Time tobj = new Time();
5428 tobj.set(System.currentTimeMillis());
5429 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5430 sb.append(": ");
5431 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5432 sb.append(" since ");
5433 sb.append(msg);
5434 FileOutputStream fos = new FileOutputStream(tracesFile);
5435 fos.write(sb.toString().getBytes());
5436 if (app == null) {
5437 fos.write("\n*** No application process!".getBytes());
5438 }
5439 fos.close();
5440 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5441 } catch (IOException e) {
5442 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesFile, e);
5443 return;
5444 }
5445
5446 if (app != null && app.getPid() > 0) {
5447 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5448 firstPids.add(app.getPid());
5449 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, null, null);
5450 }
5451
5452 File lastTracesFile = null;
5453 File curTracesFile = null;
5454 for (int i=9; i>=0; i--) {
5455 String name = String.format(Locale.US, "slow%02d.txt", i);
5456 curTracesFile = new File(tracesDir, name);
5457 if (curTracesFile.exists()) {
5458 if (lastTracesFile != null) {
5459 curTracesFile.renameTo(lastTracesFile);
5460 } else {
5461 curTracesFile.delete();
5462 }
5463 }
5464 lastTracesFile = curTracesFile;
5465 }
5466 tracesFile.renameTo(curTracesFile);
5467 } finally {
5468 StrictMode.setThreadPolicy(oldPolicy);
5469 }
5470 }
5471
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005472 final class H extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005473 static final int REPORT_TIME_TRACKER_MSG = 1;
Wale Ogunwale98875612018-10-12 07:53:02 -07005474 static final int FIRST_ACTIVITY_STACK_MSG = 100;
5475 static final int FIRST_SUPERVISOR_STACK_MSG = 200;
Wale Ogunwalef6733932018-06-27 05:14:34 -07005476
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005477 public H(Looper looper) {
5478 super(looper, null, true);
5479 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005480
5481 @Override
5482 public void handleMessage(Message msg) {
5483 switch (msg.what) {
5484 case REPORT_TIME_TRACKER_MSG: {
5485 AppTimeTracker tracker = (AppTimeTracker) msg.obj;
5486 tracker.deliverResult(mContext);
5487 } break;
5488 }
5489 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005490 }
5491
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005492 final class UiHandler extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005493 static final int DISMISS_DIALOG_UI_MSG = 1;
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005494
5495 public UiHandler() {
5496 super(com.android.server.UiThread.get().getLooper(), null, true);
5497 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005498
5499 @Override
5500 public void handleMessage(Message msg) {
5501 switch (msg.what) {
5502 case DISMISS_DIALOG_UI_MSG: {
5503 final Dialog d = (Dialog) msg.obj;
5504 d.dismiss();
5505 break;
5506 }
5507 }
5508 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005509 }
5510
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005511 final class LocalService extends ActivityTaskManagerInternal {
5512 @Override
5513 public SleepToken acquireSleepToken(String tag, int displayId) {
5514 Preconditions.checkNotNull(tag);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005515 return ActivityTaskManagerService.this.acquireSleepToken(tag, displayId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005516 }
5517
5518 @Override
5519 public ComponentName getHomeActivityForUser(int userId) {
5520 synchronized (mGlobalLock) {
Louis Changbd48dca2018-08-29 17:44:34 +08005521 ActivityRecord homeActivity =
5522 mStackSupervisor.getDefaultDisplayHomeActivityForUser(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005523 return homeActivity == null ? null : homeActivity.realActivity;
5524 }
5525 }
5526
5527 @Override
5528 public void onLocalVoiceInteractionStarted(IBinder activity,
5529 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
5530 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005531 onLocalVoiceInteractionStartedLocked(activity, voiceSession, voiceInteractor);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005532 }
5533 }
5534
5535 @Override
5536 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
5537 synchronized (mGlobalLock) {
5538 mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
5539 reasons, timestamp);
5540 }
5541 }
5542
5543 @Override
5544 public void notifyAppTransitionFinished() {
5545 synchronized (mGlobalLock) {
5546 mStackSupervisor.notifyAppTransitionDone();
5547 }
5548 }
5549
5550 @Override
5551 public void notifyAppTransitionCancelled() {
5552 synchronized (mGlobalLock) {
5553 mStackSupervisor.notifyAppTransitionDone();
5554 }
5555 }
5556
5557 @Override
5558 public List<IBinder> getTopVisibleActivities() {
5559 synchronized (mGlobalLock) {
5560 return mStackSupervisor.getTopVisibleActivities();
5561 }
5562 }
5563
5564 @Override
5565 public void notifyDockedStackMinimizedChanged(boolean minimized) {
5566 synchronized (mGlobalLock) {
5567 mStackSupervisor.setDockedStackMinimized(minimized);
5568 }
5569 }
5570
5571 @Override
5572 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
5573 Bundle bOptions) {
5574 Preconditions.checkNotNull(intents, "intents");
5575 final String[] resolvedTypes = new String[intents.length];
5576
5577 // UID of the package on user userId.
5578 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
5579 // packageUid may not be initialized.
5580 int packageUid = 0;
5581 final long ident = Binder.clearCallingIdentity();
5582
5583 try {
5584 for (int i = 0; i < intents.length; i++) {
5585 resolvedTypes[i] =
5586 intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
5587 }
5588
5589 packageUid = AppGlobals.getPackageManager().getPackageUid(
5590 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
5591 } catch (RemoteException e) {
5592 // Shouldn't happen.
5593 } finally {
5594 Binder.restoreCallingIdentity(ident);
5595 }
5596
5597 synchronized (mGlobalLock) {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07005598 return getActivityStartController().startActivitiesInPackage(
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005599 packageUid, packageName,
5600 intents, resolvedTypes, null /* resultTo */,
5601 SafeActivityOptions.fromBundle(bOptions), userId,
Michal Karpinski201bc0c2018-07-20 15:32:00 +01005602 false /* validateIncomingUser */, null /* originatingPendingIntent */);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005603 }
5604 }
5605
5606 @Override
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07005607 public int startActivitiesInPackage(int uid, String callingPackage, Intent[] intents,
5608 String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, int userId,
5609 boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent) {
5610 synchronized (mGlobalLock) {
5611 return getActivityStartController().startActivitiesInPackage(uid, callingPackage,
5612 intents, resolvedTypes, resultTo, options, userId, validateIncomingUser,
5613 originatingPendingIntent);
5614 }
5615 }
5616
5617 @Override
5618 public int startActivityInPackage(int uid, int realCallingPid, int realCallingUid,
5619 String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
5620 String resultWho, int requestCode, int startFlags, SafeActivityOptions options,
5621 int userId, TaskRecord inTask, String reason, boolean validateIncomingUser,
5622 PendingIntentRecord originatingPendingIntent) {
5623 synchronized (mGlobalLock) {
5624 return getActivityStartController().startActivityInPackage(uid, realCallingPid,
5625 realCallingUid, callingPackage, intent, resolvedType, resultTo, resultWho,
5626 requestCode, startFlags, options, userId, inTask, reason,
5627 validateIncomingUser, originatingPendingIntent);
5628 }
5629 }
5630
5631 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005632 public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
5633 Intent intent, Bundle options, int userId) {
5634 return ActivityTaskManagerService.this.startActivityAsUser(
5635 caller, callerPacakge, intent,
5636 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
5637 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
5638 false /*validateIncomingUser*/);
5639 }
5640
5641 @Override
5642 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
5643 synchronized (mGlobalLock) {
5644
5645 // We might change the visibilities here, so prepare an empty app transition which
5646 // might be overridden later if we actually change visibilities.
5647 final boolean wasTransitionSet =
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005648 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005649 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005650 mWindowManager.prepareAppTransition(TRANSIT_NONE,
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005651 false /* alwaysKeepCurrent */);
5652 }
5653 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5654
5655 // If there was a transition set already we don't want to interfere with it as we
5656 // might be starting it too early.
5657 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005658 mWindowManager.executeAppTransition();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005659 }
5660 }
5661 if (callback != null) {
5662 callback.run();
5663 }
5664 }
5665
5666 @Override
5667 public void notifyKeyguardTrustedChanged() {
5668 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005669 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005670 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5671 }
5672 }
5673 }
5674
5675 /**
5676 * Called after virtual display Id is updated by
5677 * {@link com.android.server.vr.Vr2dDisplay} with a specific
5678 * {@param vrVr2dDisplayId}.
5679 */
5680 @Override
5681 public void setVr2dDisplayId(int vr2dDisplayId) {
5682 if (DEBUG_STACK) Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
5683 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005684 mVr2dDisplayId = vr2dDisplayId;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005685 }
5686 }
5687
5688 @Override
5689 public void setFocusedActivity(IBinder token) {
5690 synchronized (mGlobalLock) {
5691 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
5692 if (r == null) {
5693 throw new IllegalArgumentException(
5694 "setFocusedActivity: No activity record matching token=" + token);
5695 }
Louis Chang19443452018-10-09 12:10:21 +08005696 if (r.moveFocusableActivityToTop("setFocusedActivity")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08005697 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005698 }
5699 }
5700 }
5701
5702 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005703 public void registerScreenObserver(ScreenObserver observer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005704 mScreenObservers.add(observer);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005705 }
5706
5707 @Override
5708 public boolean isCallerRecents(int callingUid) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005709 return getRecentTasks().isCallerRecents(callingUid);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005710 }
5711
5712 @Override
5713 public boolean isRecentsComponentHomeActivity(int userId) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005714 return getRecentTasks().isRecentsComponentHomeActivity(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005715 }
5716
5717 @Override
5718 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
5719 ActivityTaskManagerService.this.cancelRecentsAnimation(restoreHomeStackPosition);
5720 }
5721
5722 @Override
5723 public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005724 ActivityTaskManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005725 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005726
5727 @Override
5728 public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
5729 synchronized (mGlobalLock) {
5730 mActiveVoiceInteractionServiceComponent = component;
5731 }
5732 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005733
5734 @Override
5735 public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
5736 if (!mAmInternal.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
5737 return;
5738 }
5739 synchronized (mGlobalLock) {
5740 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
5741 if (types == null) {
5742 if (uid < 0) {
5743 return;
5744 }
5745 types = new ArrayMap<>();
5746 mAllowAppSwitchUids.put(userId, types);
5747 }
5748 if (uid < 0) {
5749 types.remove(type);
5750 } else {
5751 types.put(type, uid);
5752 }
5753 }
5754 }
5755
5756 @Override
5757 public void onUserStopped(int userId) {
5758 synchronized (mGlobalLock) {
5759 getRecentTasks().unloadUserDataFromMemoryLocked(userId);
5760 mAllowAppSwitchUids.remove(userId);
5761 }
5762 }
5763
5764 @Override
5765 public boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
5766 synchronized (mGlobalLock) {
5767 return ActivityTaskManagerService.this.isGetTasksAllowed(
5768 caller, callingPid, callingUid);
5769 }
5770 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005771
5772 @Override
5773 public void onProcessAdded(WindowProcessController proc) {
5774 synchronized (mGlobalLock) {
5775 mProcessNames.put(proc.mName, proc.mUid, proc);
5776 }
5777 }
5778
5779 @Override
5780 public void onProcessRemoved(String name, int uid) {
5781 synchronized (mGlobalLock) {
5782 mProcessNames.remove(name, uid);
5783 }
5784 }
5785
5786 @Override
5787 public void onCleanUpApplicationRecord(WindowProcessController proc) {
5788 synchronized (mGlobalLock) {
5789 if (proc == mHomeProcess) {
5790 mHomeProcess = null;
5791 }
5792 if (proc == mPreviousProcess) {
5793 mPreviousProcess = null;
5794 }
5795 }
5796 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005797
5798 @Override
5799 public int getTopProcessState() {
5800 synchronized (mGlobalLock) {
5801 return mTopProcessState;
5802 }
5803 }
5804
5805 @Override
Wale Ogunwale53783742018-09-16 10:21:51 -07005806 public boolean isHeavyWeightProcess(WindowProcessController proc) {
5807 synchronized (mGlobalLock) {
5808 return proc == mHeavyWeightProcess;
5809 }
5810 }
5811
5812 @Override
5813 public void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
5814 synchronized (mGlobalLock) {
5815 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(proc);
5816 }
5817 }
5818
5819 @Override
5820 public void finishHeavyWeightApp() {
5821 synchronized (mGlobalLock) {
Sudheer Shankaee1da272018-10-20 20:11:44 -07005822 if (mHeavyWeightProcess != null) {
5823 mHeavyWeightProcess.finishActivities();
5824 }
Wale Ogunwale53783742018-09-16 10:21:51 -07005825 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(
5826 mHeavyWeightProcess);
5827 }
5828 }
5829
5830 @Override
Wale Ogunwalef6733932018-06-27 05:14:34 -07005831 public boolean isSleeping() {
5832 synchronized (mGlobalLock) {
5833 return isSleepingLocked();
5834 }
5835 }
5836
5837 @Override
5838 public boolean isShuttingDown() {
5839 synchronized (mGlobalLock) {
5840 return mShuttingDown;
5841 }
5842 }
5843
5844 @Override
5845 public boolean shuttingDown(boolean booted, int timeout) {
5846 synchronized (mGlobalLock) {
5847 mShuttingDown = true;
5848 mStackSupervisor.prepareForShutdownLocked();
5849 updateEventDispatchingLocked(booted);
Wale Ogunwaled4d67d02018-10-25 18:09:39 -07005850 notifyTaskPersisterLocked(null, true);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005851 return mStackSupervisor.shutdownLocked(timeout);
5852 }
5853 }
5854
5855 @Override
5856 public void enableScreenAfterBoot(boolean booted) {
5857 synchronized (mGlobalLock) {
5858 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5859 SystemClock.uptimeMillis());
5860 mWindowManager.enableScreenAfterBoot();
5861 updateEventDispatchingLocked(booted);
5862 }
5863 }
5864
5865 @Override
5866 public boolean showStrictModeViolationDialog() {
5867 synchronized (mGlobalLock) {
5868 return mShowDialogs && !mSleeping && !mShuttingDown;
5869 }
5870 }
5871
5872 @Override
5873 public void showSystemReadyErrorDialogsIfNeeded() {
5874 synchronized (mGlobalLock) {
5875 try {
5876 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
5877 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
5878 + " data partition or your device will be unstable.");
5879 mUiHandler.post(() -> {
5880 if (mShowDialogs) {
5881 AlertDialog d = new BaseErrorDialog(mUiContext);
5882 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5883 d.setCancelable(false);
5884 d.setTitle(mUiContext.getText(R.string.android_system_label));
5885 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
5886 d.setButton(DialogInterface.BUTTON_POSITIVE,
5887 mUiContext.getText(R.string.ok),
5888 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5889 d.show();
5890 }
5891 });
5892 }
5893 } catch (RemoteException e) {
5894 }
5895
5896 if (!Build.isBuildConsistent()) {
5897 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
5898 mUiHandler.post(() -> {
5899 if (mShowDialogs) {
5900 AlertDialog d = new BaseErrorDialog(mUiContext);
5901 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5902 d.setCancelable(false);
5903 d.setTitle(mUiContext.getText(R.string.android_system_label));
5904 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
5905 d.setButton(DialogInterface.BUTTON_POSITIVE,
5906 mUiContext.getText(R.string.ok),
5907 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5908 d.show();
5909 }
5910 });
5911 }
5912 }
5913 }
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005914
5915 @Override
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005916 public void onProcessMapped(int pid, WindowProcessController proc) {
5917 synchronized (mGlobalLock) {
5918 mPidMap.put(pid, proc);
5919 }
5920 }
5921
5922 @Override
5923 public void onProcessUnMapped(int pid) {
5924 synchronized (mGlobalLock) {
5925 mPidMap.remove(pid);
5926 }
5927 }
Wale Ogunwale008163e2018-07-23 23:11:08 -07005928
5929 @Override
5930 public void onPackageDataCleared(String name) {
5931 synchronized (mGlobalLock) {
Wale Ogunwale53783742018-09-16 10:21:51 -07005932 mCompatModePackages.handlePackageDataClearedLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07005933 mAppWarnings.onPackageDataCleared(name);
5934 }
5935 }
5936
5937 @Override
5938 public void onPackageUninstalled(String name) {
5939 synchronized (mGlobalLock) {
5940 mAppWarnings.onPackageUninstalled(name);
Wale Ogunwale53783742018-09-16 10:21:51 -07005941 mCompatModePackages.handlePackageUninstalledLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07005942 }
5943 }
Wale Ogunwale53783742018-09-16 10:21:51 -07005944
5945 @Override
5946 public void onPackageAdded(String name, boolean replacing) {
5947 synchronized (mGlobalLock) {
5948 mCompatModePackages.handlePackageAddedLocked(name, replacing);
5949 }
5950 }
5951
5952 @Override
Wale Ogunwale31913b52018-10-13 08:29:31 -07005953 public void onPackageReplaced(ApplicationInfo aInfo) {
5954 synchronized (mGlobalLock) {
5955 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
5956 }
5957 }
5958
5959 @Override
Wale Ogunwale53783742018-09-16 10:21:51 -07005960 public CompatibilityInfo compatibilityInfoForPackage(ApplicationInfo ai) {
5961 synchronized (mGlobalLock) {
5962 return compatibilityInfoForPackageLocked(ai);
5963 }
5964 }
5965
Yunfan Chen75157d72018-07-27 14:47:21 +09005966 /**
5967 * Set the corresponding display information for the process global configuration. To be
5968 * called when we need to show IME on a different display.
5969 *
5970 * @param pid The process id associated with the IME window.
5971 * @param displayId The ID of the display showing the IME.
5972 */
5973 @Override
Yunfan Chen79b96062018-10-17 12:45:23 -07005974 public void onImeWindowSetOnDisplay(final int pid, final int displayId) {
Yunfan Chen75157d72018-07-27 14:47:21 +09005975 if (pid == MY_PID || pid < 0) {
5976 if (DEBUG_CONFIGURATION) {
5977 Slog.w(TAG,
5978 "Trying to update display configuration for system/invalid process.");
5979 }
5980 return;
5981 }
5982 mH.post(() -> {
5983 synchronized (mGlobalLock) {
Yunfan Chen79b96062018-10-17 12:45:23 -07005984 final ActivityDisplay activityDisplay =
5985 mStackSupervisor.getActivityDisplay(displayId);
5986 if (activityDisplay == null) {
5987 // Call might come when display is not yet added or has been removed.
Yunfan Chen75157d72018-07-27 14:47:21 +09005988 if (DEBUG_CONFIGURATION) {
5989 Slog.w(TAG, "Trying to update display configuration for non-existing "
Yunfan Chen79b96062018-10-17 12:45:23 -07005990 + "displayId=" + displayId);
Yunfan Chen75157d72018-07-27 14:47:21 +09005991 }
5992 return;
5993 }
Yunfan Chen79b96062018-10-17 12:45:23 -07005994 final WindowProcessController process = mPidMap.get(pid);
5995 if (process == null) {
Yunfan Chen75157d72018-07-27 14:47:21 +09005996 if (DEBUG_CONFIGURATION) {
Yunfan Chen79b96062018-10-17 12:45:23 -07005997 Slog.w(TAG, "Trying to update display configuration for invalid "
5998 + "process, pid=" + pid);
Yunfan Chen75157d72018-07-27 14:47:21 +09005999 }
6000 return;
6001 }
Yunfan Chen79b96062018-10-17 12:45:23 -07006002 process.registerDisplayConfigurationListenerLocked(activityDisplay);
Yunfan Chen75157d72018-07-27 14:47:21 +09006003 }
6004 });
Yunfan Chen79b96062018-10-17 12:45:23 -07006005
Yunfan Chen75157d72018-07-27 14:47:21 +09006006 }
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07006007
6008 @Override
6009 public void sendActivityResult(int callingUid, IBinder activityToken, String resultWho,
6010 int requestCode, int resultCode, Intent data) {
6011 synchronized (mGlobalLock) {
6012 final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
6013 if (r != null && r.getStack() != null) {
6014 r.getStack().sendActivityResultLocked(callingUid, r, resultWho, requestCode,
6015 resultCode, data);
6016 }
6017 }
6018 }
6019
6020 @Override
6021 public void clearPendingResultForActivity(IBinder activityToken,
6022 WeakReference<PendingIntentRecord> pir) {
6023 synchronized (mGlobalLock) {
6024 final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
6025 if (r != null && r.pendingResults != null) {
6026 r.pendingResults.remove(pir);
6027 }
6028 }
6029 }
6030
6031 @Override
6032 public IIntentSender getIntentSender(int type, String packageName,
6033 int callingUid, int userId, IBinder token, String resultWho,
6034 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6035 Bundle bOptions) {
6036 synchronized (mGlobalLock) {
6037 return getIntentSenderLocked(type, packageName, callingUid, userId, token,
6038 resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6039 }
6040 }
Wale Ogunwalec4e63a42018-10-02 13:19:54 -07006041
6042 @Override
6043 public ActivityServiceConnectionsHolder getServiceConnectionsHolder(IBinder token) {
6044 synchronized (mGlobalLock) {
6045 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
6046 if (r == null) {
6047 return null;
6048 }
6049 if (r.mServiceConnectionsHolder == null) {
6050 r.mServiceConnectionsHolder = new ActivityServiceConnectionsHolder(
6051 ActivityTaskManagerService.this, r);
6052 }
6053
6054 return r.mServiceConnectionsHolder;
6055 }
6056 }
Wale Ogunwale214f3482018-10-04 11:00:47 -07006057
6058 @Override
6059 public Intent getHomeIntent() {
6060 synchronized (mGlobalLock) {
6061 return ActivityTaskManagerService.this.getHomeIntent();
6062 }
6063 }
6064
6065 @Override
6066 public boolean startHomeActivity(int userId, String reason) {
6067 synchronized (mGlobalLock) {
Louis Chang89f43fc2018-10-05 10:59:14 +08006068 return mStackSupervisor.startHomeOnDisplay(userId, reason, DEFAULT_DISPLAY);
6069 }
6070 }
6071
6072 @Override
6073 public boolean startHomeOnAllDisplays(int userId, String reason) {
6074 synchronized (mGlobalLock) {
6075 return mStackSupervisor.startHomeOnAllDisplays(userId, reason);
Wale Ogunwale214f3482018-10-04 11:00:47 -07006076 }
6077 }
6078
6079 @Override
6080 public boolean isFactoryTestProcess(WindowProcessController wpc) {
6081 synchronized (mGlobalLock) {
6082 if (mFactoryTest == FACTORY_TEST_OFF) {
6083 return false;
6084 }
6085 if (mFactoryTest == FACTORY_TEST_LOW_LEVEL && mTopComponent != null
6086 && wpc.mName.equals(mTopComponent.getPackageName())) {
6087 return true;
6088 }
6089 return mFactoryTest == FACTORY_TEST_HIGH_LEVEL
6090 && (wpc.mInfo.flags & FLAG_FACTORY_TEST) != 0;
6091 }
6092 }
6093
6094 @Override
6095 public void updateTopComponentForFactoryTest() {
6096 synchronized (mGlobalLock) {
6097 if (mFactoryTest != FACTORY_TEST_LOW_LEVEL) {
6098 return;
6099 }
6100 final ResolveInfo ri = mContext.getPackageManager()
6101 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), STOCK_PM_FLAGS);
6102 final CharSequence errorMsg;
6103 if (ri != null) {
6104 final ActivityInfo ai = ri.activityInfo;
6105 final ApplicationInfo app = ai.applicationInfo;
6106 if ((app.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
6107 mTopAction = Intent.ACTION_FACTORY_TEST;
6108 mTopData = null;
6109 mTopComponent = new ComponentName(app.packageName, ai.name);
6110 errorMsg = null;
6111 } else {
6112 errorMsg = mContext.getResources().getText(
6113 com.android.internal.R.string.factorytest_not_system);
6114 }
6115 } else {
6116 errorMsg = mContext.getResources().getText(
6117 com.android.internal.R.string.factorytest_no_action);
6118 }
6119 if (errorMsg == null) {
6120 return;
6121 }
6122
6123 mTopAction = null;
6124 mTopData = null;
6125 mTopComponent = null;
6126 mUiHandler.post(() -> {
6127 Dialog d = new FactoryErrorDialog(mUiContext, errorMsg);
6128 d.show();
Wale Ogunwale342fbe92018-10-09 08:44:10 -07006129 mAmInternal.ensureBootCompleted();
Wale Ogunwale214f3482018-10-04 11:00:47 -07006130 });
6131 }
6132 }
Wale Ogunwale31913b52018-10-13 08:29:31 -07006133
6134 @Override
6135 public void handleAppDied(WindowProcessController wpc, boolean restarting,
6136 Runnable finishInstrumentationCallback) {
6137 synchronized (mGlobalLock) {
6138 // Remove this application's activities from active lists.
6139 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(wpc);
6140
6141 wpc.clearRecentTasks();
6142 wpc.clearActivities();
6143
6144 if (wpc.isInstrumenting()) {
6145 finishInstrumentationCallback.run();
6146 }
6147
6148 mWindowManager.deferSurfaceLayout();
6149 try {
6150 if (!restarting && hasVisibleActivities
6151 && !mStackSupervisor.resumeFocusedStacksTopActivitiesLocked()) {
6152 // If there was nothing to resume, and we are not already restarting this
6153 // process, but there is a visible activity that is hosted by the process...
6154 // then make sure all visible activities are running, taking care of
6155 // restarting this process.
6156 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6157 }
6158 } finally {
6159 mWindowManager.continueSurfaceLayout();
6160 }
6161 }
6162 }
6163
6164 @Override
6165 public void closeSystemDialogs(String reason) {
6166 enforceNotIsolatedCaller("closeSystemDialogs");
6167
6168 final int pid = Binder.getCallingPid();
6169 final int uid = Binder.getCallingUid();
6170 final long origId = Binder.clearCallingIdentity();
6171 try {
6172 synchronized (mGlobalLock) {
6173 // Only allow this from foreground processes, so that background
6174 // applications can't abuse it to prevent system UI from being shown.
6175 if (uid >= FIRST_APPLICATION_UID) {
6176 final WindowProcessController proc = mPidMap.get(pid);
6177 if (!proc.isPerceptible()) {
6178 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6179 + " from background process " + proc);
6180 return;
6181 }
6182 }
Wale Ogunwale31913b52018-10-13 08:29:31 -07006183 mWindowManager.closeSystemDialogs(reason);
6184
6185 mStackSupervisor.closeSystemDialogsLocked();
Wale Ogunwale31913b52018-10-13 08:29:31 -07006186 }
Wale Ogunwale2ea36d42018-10-18 10:27:31 -07006187 // Call into AM outside the synchronized block.
6188 mAmInternal.broadcastCloseSystemDialogs(reason);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006189 } finally {
6190 Binder.restoreCallingIdentity(origId);
6191 }
6192 }
6193
6194 @Override
6195 public void cleanupDisabledPackageComponents(
6196 String packageName, Set<String> disabledClasses, int userId, boolean booted) {
6197 synchronized (mGlobalLock) {
6198 // Clean-up disabled activities.
6199 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6200 packageName, disabledClasses, true, false, userId) && booted) {
6201 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
6202 mStackSupervisor.scheduleIdleLocked();
6203 }
6204
6205 // Clean-up disabled tasks
6206 getRecentTasks().cleanupDisabledPackageTasksLocked(
6207 packageName, disabledClasses, userId);
6208 }
6209 }
6210
6211 @Override
6212 public boolean onForceStopPackage(String packageName, boolean doit, boolean evenPersistent,
6213 int userId) {
6214 synchronized (mGlobalLock) {
6215
6216 boolean didSomething =
6217 getActivityStartController().clearPendingActivityLaunches(packageName);
6218 didSomething |= mStackSupervisor.finishDisabledPackageActivitiesLocked(packageName,
6219 null, doit, evenPersistent, userId);
6220 return didSomething;
6221 }
6222 }
6223
6224 @Override
6225 public void resumeTopActivities(boolean scheduleIdle) {
6226 synchronized (mGlobalLock) {
6227 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
6228 if (scheduleIdle) {
6229 mStackSupervisor.scheduleIdleLocked();
6230 }
6231 }
6232 }
6233
6234 @Override
6235 public void preBindApplication(WindowProcessController wpc) {
6236 synchronized (mGlobalLock) {
6237 mStackSupervisor.getActivityMetricsLogger().notifyBindApplication(wpc.mInfo);
6238 }
6239 }
6240
6241 @Override
6242 public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
6243 synchronized (mGlobalLock) {
6244 return mStackSupervisor.attachApplicationLocked(wpc);
6245 }
6246 }
6247
6248 @Override
6249 public void notifyLockedProfile(@UserIdInt int userId, int currentUserId) {
6250 try {
6251 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
6252 throw new SecurityException("Only privileged app can call notifyLockedProfile");
6253 }
6254 } catch (RemoteException ex) {
6255 throw new SecurityException("Fail to check is caller a privileged app", ex);
6256 }
6257
6258 synchronized (mGlobalLock) {
6259 final long ident = Binder.clearCallingIdentity();
6260 try {
6261 if (mAmInternal.shouldConfirmCredentials(userId)) {
6262 if (mKeyguardController.isKeyguardLocked()) {
6263 // Showing launcher to avoid user entering credential twice.
6264 startHomeActivity(currentUserId, "notifyLockedProfile");
6265 }
6266 mStackSupervisor.lockAllProfileTasks(userId);
6267 }
6268 } finally {
6269 Binder.restoreCallingIdentity(ident);
6270 }
6271 }
6272 }
6273
6274 @Override
6275 public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
6276 mAmInternal.enforceCallingPermission(
6277 MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
6278
6279 synchronized (mGlobalLock) {
6280 final long ident = Binder.clearCallingIdentity();
6281 try {
6282 intent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
6283 FLAG_ACTIVITY_TASK_ON_HOME);
6284 ActivityOptions activityOptions = options != null
6285 ? new ActivityOptions(options) : ActivityOptions.makeBasic();
6286 activityOptions.setLaunchTaskId(
6287 mStackSupervisor.getDefaultDisplayHomeActivity().getTask().taskId);
6288 mContext.startActivityAsUser(intent, activityOptions.toBundle(),
6289 UserHandle.CURRENT);
6290 } finally {
6291 Binder.restoreCallingIdentity(ident);
6292 }
6293 }
6294 }
6295
6296 @Override
6297 public void writeActivitiesToProto(ProtoOutputStream proto) {
6298 synchronized (mGlobalLock) {
6299 // The output proto of "activity --proto activities"
6300 // is ActivityManagerServiceDumpActivitiesProto
6301 mStackSupervisor.writeToProto(proto,
6302 ActivityManagerServiceDumpActivitiesProto.ACTIVITY_STACK_SUPERVISOR);
6303 }
6304 }
6305
6306 @Override
6307 public void saveANRState(String reason) {
6308 synchronized (mGlobalLock) {
6309 final StringWriter sw = new StringWriter();
6310 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
6311 pw.println(" ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
6312 if (reason != null) {
6313 pw.println(" Reason: " + reason);
6314 }
6315 pw.println();
6316 getActivityStartController().dump(pw, " ", null);
6317 pw.println();
6318 pw.println("-------------------------------------------------------------------------------");
6319 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
6320 true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
6321 "" /* header */);
6322 pw.println();
6323 pw.close();
6324
6325 mLastANRState = sw.toString();
6326 }
6327 }
6328
6329 @Override
6330 public void clearSavedANRState() {
6331 synchronized (mGlobalLock) {
6332 mLastANRState = null;
6333 }
6334 }
6335
6336 @Override
6337 public void dump(String cmd, FileDescriptor fd, PrintWriter pw, String[] args, int opti,
6338 boolean dumpAll, boolean dumpClient, String dumpPackage) {
6339 synchronized (mGlobalLock) {
6340 if (DUMP_ACTIVITIES_CMD.equals(cmd) || DUMP_ACTIVITIES_SHORT_CMD.equals(cmd)) {
6341 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
6342 } else if (DUMP_LASTANR_CMD.equals(cmd)) {
6343 dumpLastANRLocked(pw);
6344 } else if (DUMP_LASTANR_TRACES_CMD.equals(cmd)) {
6345 dumpLastANRTracesLocked(pw);
6346 } else if (DUMP_STARTER_CMD.equals(cmd)) {
6347 dumpActivityStarterLocked(pw, dumpPackage);
6348 } else if (DUMP_CONTAINERS_CMD.equals(cmd)) {
6349 dumpActivityContainersLocked(pw);
6350 } else if (DUMP_RECENTS_CMD.equals(cmd) || DUMP_RECENTS_SHORT_CMD.equals(cmd)) {
6351 if (getRecentTasks() != null) {
6352 getRecentTasks().dump(pw, dumpAll, dumpPackage);
6353 }
6354 }
6355 }
6356 }
6357
6358 @Override
6359 public boolean dumpForProcesses(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
6360 String dumpPackage, int dumpAppId, boolean needSep, boolean testPssMode,
6361 int wakefulness) {
6362 synchronized (mGlobalLock) {
6363 if (mHomeProcess != null && (dumpPackage == null
6364 || mHomeProcess.mPkgList.contains(dumpPackage))) {
6365 if (needSep) {
6366 pw.println();
6367 needSep = false;
6368 }
6369 pw.println(" mHomeProcess: " + mHomeProcess);
6370 }
6371 if (mPreviousProcess != null && (dumpPackage == null
6372 || mPreviousProcess.mPkgList.contains(dumpPackage))) {
6373 if (needSep) {
6374 pw.println();
6375 needSep = false;
6376 }
6377 pw.println(" mPreviousProcess: " + mPreviousProcess);
6378 }
6379 if (dumpAll && (mPreviousProcess == null || dumpPackage == null
6380 || mPreviousProcess.mPkgList.contains(dumpPackage))) {
6381 StringBuilder sb = new StringBuilder(128);
6382 sb.append(" mPreviousProcessVisibleTime: ");
6383 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
6384 pw.println(sb);
6385 }
6386 if (mHeavyWeightProcess != null && (dumpPackage == null
6387 || mHeavyWeightProcess.mPkgList.contains(dumpPackage))) {
6388 if (needSep) {
6389 pw.println();
6390 needSep = false;
6391 }
6392 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
6393 }
6394 if (dumpPackage == null) {
6395 pw.println(" mGlobalConfiguration: " + getGlobalConfiguration());
6396 mStackSupervisor.dumpDisplayConfigs(pw, " ");
6397 }
6398 if (dumpAll) {
6399 if (dumpPackage == null) {
6400 pw.println(" mConfigWillChange: "
6401 + getTopDisplayFocusedStack().mConfigWillChange);
6402 }
6403 if (mCompatModePackages.getPackages().size() > 0) {
6404 boolean printed = false;
6405 for (Map.Entry<String, Integer> entry
6406 : mCompatModePackages.getPackages().entrySet()) {
6407 String pkg = entry.getKey();
6408 int mode = entry.getValue();
6409 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
6410 continue;
6411 }
6412 if (!printed) {
6413 pw.println(" mScreenCompatPackages:");
6414 printed = true;
6415 }
6416 pw.println(" " + pkg + ": " + mode);
6417 }
6418 }
6419 }
6420
6421 if (dumpPackage == null) {
6422 pw.println(" mWakefulness="
6423 + PowerManagerInternal.wakefulnessToString(wakefulness));
6424 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
6425 if (mRunningVoice != null) {
6426 pw.println(" mRunningVoice=" + mRunningVoice);
6427 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
6428 }
6429 pw.println(" mSleeping=" + mSleeping);
6430 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + testPssMode);
6431 pw.println(" mVrController=" + mVrController);
6432 }
6433 if (mCurAppTimeTracker != null) {
6434 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
6435 }
6436 if (mAllowAppSwitchUids.size() > 0) {
6437 boolean printed = false;
6438 for (int i = 0; i < mAllowAppSwitchUids.size(); i++) {
6439 ArrayMap<String, Integer> types = mAllowAppSwitchUids.valueAt(i);
6440 for (int j = 0; j < types.size(); j++) {
6441 if (dumpPackage == null ||
6442 UserHandle.getAppId(types.valueAt(j).intValue()) == dumpAppId) {
6443 if (needSep) {
6444 pw.println();
6445 needSep = false;
6446 }
6447 if (!printed) {
6448 pw.println(" mAllowAppSwitchUids:");
6449 printed = true;
6450 }
6451 pw.print(" User ");
6452 pw.print(mAllowAppSwitchUids.keyAt(i));
6453 pw.print(": Type ");
6454 pw.print(types.keyAt(j));
6455 pw.print(" = ");
6456 UserHandle.formatUid(pw, types.valueAt(j).intValue());
6457 pw.println();
6458 }
6459 }
6460 }
6461 }
6462 if (dumpPackage == null) {
6463 if (mController != null) {
6464 pw.println(" mController=" + mController
6465 + " mControllerIsAMonkey=" + mControllerIsAMonkey);
6466 }
6467 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
6468 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
6469 }
6470
6471 return needSep;
6472 }
6473 }
6474
6475 @Override
6476 public void writeProcessesToProto(ProtoOutputStream proto, String dumpPackage) {
6477 synchronized (mGlobalLock) {
6478 if (dumpPackage == null) {
6479 getGlobalConfiguration().writeToProto(proto, GLOBAL_CONFIGURATION);
6480 proto.write(CONFIG_WILL_CHANGE, getTopDisplayFocusedStack().mConfigWillChange);
6481 writeSleepStateToProto(proto);
6482 if (mController != null) {
6483 final long token = proto.start(CONTROLLER);
6484 proto.write(CONTROLLER, mController.toString());
6485 proto.write(IS_A_MONKEY, mControllerIsAMonkey);
6486 proto.end(token);
6487 }
6488 mStackSupervisor.mGoingToSleep.writeToProto(proto, GOING_TO_SLEEP);
6489 mStackSupervisor.mLaunchingActivity.writeToProto(proto, LAUNCHING_ACTIVITY);
6490 }
6491
6492 if (mHomeProcess != null && (dumpPackage == null
6493 || mHomeProcess.mPkgList.contains(dumpPackage))) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07006494 mHomeProcess.writeToProto(proto, HOME_PROC);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006495 }
6496
6497 if (mPreviousProcess != null && (dumpPackage == null
6498 || mPreviousProcess.mPkgList.contains(dumpPackage))) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07006499 mPreviousProcess.writeToProto(proto, PREVIOUS_PROC);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006500 proto.write(PREVIOUS_PROC_VISIBLE_TIME_MS, mPreviousProcessVisibleTime);
6501 }
6502
6503 if (mHeavyWeightProcess != null && (dumpPackage == null
6504 || mHeavyWeightProcess.mPkgList.contains(dumpPackage))) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07006505 mHeavyWeightProcess.writeToProto(proto, HEAVY_WEIGHT_PROC);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006506 }
6507
6508 for (Map.Entry<String, Integer> entry
6509 : mCompatModePackages.getPackages().entrySet()) {
6510 String pkg = entry.getKey();
6511 int mode = entry.getValue();
6512 if (dumpPackage == null || dumpPackage.equals(pkg)) {
6513 long compatToken = proto.start(SCREEN_COMPAT_PACKAGES);
6514 proto.write(PACKAGE, pkg);
6515 proto.write(MODE, mode);
6516 proto.end(compatToken);
6517 }
6518 }
6519
6520 if (mCurAppTimeTracker != null) {
6521 mCurAppTimeTracker.writeToProto(proto, CURRENT_TRACKER, true);
6522 }
6523
6524 }
6525 }
6526
6527 @Override
6528 public boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name,
6529 String[] args, int opti, boolean dumpAll, boolean dumpVisibleStacksOnly,
6530 boolean dumpFocusedStackOnly) {
6531 synchronized (mGlobalLock) {
6532 return ActivityTaskManagerService.this.dumpActivity(fd, pw, name, args, opti,
6533 dumpAll, dumpVisibleStacksOnly, dumpFocusedStackOnly);
6534 }
6535 }
6536
6537 @Override
Wale Ogunwaled4d67d02018-10-25 18:09:39 -07006538 public void dumpForOom(PrintWriter pw) {
6539 synchronized (mGlobalLock) {
6540 pw.println(" mHomeProcess: " + mHomeProcess);
6541 pw.println(" mPreviousProcess: " + mPreviousProcess);
6542 if (mHeavyWeightProcess != null) {
6543 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
6544 }
6545 }
6546 }
6547
6548 @Override
Wale Ogunwale31913b52018-10-13 08:29:31 -07006549 public boolean canGcNow() {
6550 synchronized (mGlobalLock) {
6551 return isSleeping() || mStackSupervisor.allResumedActivitiesIdle();
6552 }
6553 }
6554
6555 @Override
6556 public WindowProcessController getTopApp() {
6557 synchronized (mGlobalLock) {
6558 final ActivityRecord top = mStackSupervisor.getTopResumedActivity();
6559 return top != null ? top.app : null;
6560 }
6561 }
6562
6563 @Override
6564 public void rankTaskLayersIfNeeded() {
6565 synchronized (mGlobalLock) {
6566 if (mStackSupervisor != null) {
6567 mStackSupervisor.rankTaskLayersIfNeeded();
6568 }
6569 }
6570 }
6571
6572 @Override
6573 public void scheduleDestroyAllActivities(String reason) {
6574 synchronized (mGlobalLock) {
6575 mStackSupervisor.scheduleDestroyAllActivities(null, reason);
6576 }
6577 }
6578
6579 @Override
6580 public void removeUser(int userId) {
6581 synchronized (mGlobalLock) {
6582 mStackSupervisor.removeUserLocked(userId);
6583 }
6584 }
6585
6586 @Override
6587 public boolean switchUser(int userId, UserState userState) {
6588 synchronized (mGlobalLock) {
6589 return mStackSupervisor.switchUserLocked(userId, userState);
6590 }
6591 }
6592
6593 @Override
6594 public void onHandleAppCrash(WindowProcessController wpc) {
6595 synchronized (mGlobalLock) {
6596 mStackSupervisor.handleAppCrashLocked(wpc);
6597 }
6598 }
Wale Ogunwale64258362018-10-16 15:13:37 -07006599
6600 @Override
6601 public int finishTopCrashedActivities(WindowProcessController crashedApp, String reason) {
6602 synchronized (mGlobalLock) {
6603 return mStackSupervisor.finishTopCrashedActivitiesLocked(crashedApp, reason);
6604 }
6605 }
Wale Ogunwalebff2df42018-10-18 17:09:19 -07006606
6607 @Override
6608 public void onUidActive(int uid, int procState) {
6609 synchronized (mGlobalLock) {
6610 mActiveUids.put(uid, procState);
6611 }
6612 }
6613
6614 @Override
6615 public void onUidInactive(int uid) {
6616 synchronized (mGlobalLock) {
6617 mActiveUids.remove(uid);
6618 }
6619 }
6620
6621 @Override
6622 public void onActiveUidsCleared() {
6623 synchronized (mGlobalLock) {
6624 mActiveUids.clear();
6625 }
6626 }
6627
6628 @Override
6629 public void onUidProcStateChanged(int uid, int procState) {
6630 synchronized (mGlobalLock) {
6631 if (mActiveUids.get(uid) != null) {
6632 mActiveUids.put(uid, procState);
6633 }
6634 }
6635 }
Wale Ogunwale9de19442018-10-18 19:05:03 -07006636
6637 @Override
6638 public void onUidAddedToPendingTempWhitelist(int uid, String tag) {
6639 synchronized (mGlobalLock) {
6640 mPendingTempWhitelist.put(uid, tag);
6641 }
6642 }
6643
6644 @Override
6645 public void onUidRemovedFromPendingTempWhitelist(int uid) {
6646 synchronized (mGlobalLock) {
6647 mPendingTempWhitelist.remove(uid);
6648 }
6649 }
Wale Ogunwalee2172292018-10-25 10:11:10 -07006650
6651 @Override
6652 public boolean handleAppCrashInActivityController(String processName, int pid,
6653 String shortMsg, String longMsg, long timeMillis, String stackTrace,
6654 Runnable killCrashingAppCallback) {
6655 synchronized (mGlobalLock) {
6656 if (mController == null) {
6657 return false;
6658 }
6659
6660 try {
6661 if (!mController.appCrashed(processName, pid, shortMsg, longMsg, timeMillis,
6662 stackTrace)) {
6663 killCrashingAppCallback.run();
6664 return true;
6665 }
6666 } catch (RemoteException e) {
6667 mController = null;
6668 Watchdog.getInstance().setActivityController(null);
6669 }
6670 return false;
6671 }
6672 }
Wale Ogunwaled7889f52018-10-25 11:03:20 -07006673
6674 @Override
6675 public void removeRecentTasksByPackageName(String packageName, int userId) {
6676 synchronized (mGlobalLock) {
6677 mRecentTasks.removeTasksByPackageName(packageName, userId);
6678 }
6679 }
6680
6681 @Override
6682 public void cleanupRecentTasksForUser(int userId) {
6683 synchronized (mGlobalLock) {
6684 mRecentTasks.cleanupLocked(userId);
6685 }
6686 }
6687
6688 @Override
6689 public void loadRecentTasksForUser(int userId) {
6690 synchronized (mGlobalLock) {
6691 mRecentTasks.loadUserRecentsLocked(userId);
6692 }
6693 }
6694
6695 @Override
6696 public void onPackagesSuspendedChanged(String[] packages, boolean suspended, int userId) {
6697 synchronized (mGlobalLock) {
6698 mRecentTasks.onPackagesSuspendedChanged(packages, suspended, userId);
6699 }
6700 }
6701
6702 @Override
6703 public void flushRecentTasks() {
6704 mRecentTasks.flush();
6705 }
Wale Ogunwaled4d67d02018-10-25 18:09:39 -07006706
6707 @Override
6708 public WindowProcessController getHomeProcess() {
6709 synchronized (mGlobalLock) {
6710 return mHomeProcess;
6711 }
6712 }
6713
6714 @Override
6715 public WindowProcessController getPreviousProcess() {
6716 synchronized (mGlobalLock) {
6717 return mPreviousProcess;
6718 }
6719 }
Wale Ogunwale27c48ae2018-10-25 19:01:01 -07006720
6721 @Override
6722 public void clearLockedTasks(String reason) {
6723 synchronized (mGlobalLock) {
6724 getLockTaskController().clearLockedTasks(reason);
6725 }
6726 }
6727
6728 @Override
6729 public void updateUserConfiguration() {
6730 synchronized (mGlobalLock) {
6731 final Configuration configuration = new Configuration(getGlobalConfiguration());
6732 final int currentUserId = mAmInternal.getCurrentUserId();
6733 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(),
6734 configuration, currentUserId, Settings.System.canWrite(mContext));
6735 updateConfigurationLocked(configuration, null /* starting */,
6736 false /* initLocale */, false /* persistent */, currentUserId,
6737 false /* deferResume */);
6738 }
6739 }
Wale Ogunwale387b34c2018-10-25 19:59:40 -07006740
6741 @Override
6742 public boolean canShowErrorDialogs() {
6743 synchronized (mGlobalLock) {
6744 return mShowDialogs && !mSleeping && !mShuttingDown
6745 && !mKeyguardController.isKeyguardOrAodShowing(DEFAULT_DISPLAY)
6746 && !hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
6747 mAmInternal.getCurrentUserId())
6748 && !(UserManager.isDeviceInDemoMode(mContext)
6749 && mAmInternal.getCurrentUser().isDemo());
6750 }
6751 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07006752 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07006753}