blob: fa3039f63b6da7e26d50bf1f6ef2ed6de4f49a96 [file] [log] [blame]
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.server.am;
18
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070019import static android.Manifest.permission.BIND_VOICE_INTERACTION;
20import static android.Manifest.permission.CHANGE_CONFIGURATION;
21import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
Wale Ogunwale906f9c62018-07-23 11:23:44 -070022import static android.Manifest.permission.FILTER_EVENTS;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070023import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070024import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070025import static android.Manifest.permission.READ_FRAME_BUFFER;
26import static android.Manifest.permission.REMOVE_TASKS;
27import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070028import static android.Manifest.permission.STOP_APP_SWITCHES;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070029import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
Wale Ogunwalebff2df42018-10-18 17:09:19 -070030import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
Evan Rosky4505b352018-09-06 11:20:40 -070031import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
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;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070034import static android.app.AppOpsManager.OP_NONE;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070035import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070036import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
37import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070038import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
39import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070040import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070041import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Wale Ogunwale31913b52018-10-13 08:29:31 -070042import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070043import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
Wale Ogunwale31913b52018-10-13 08:29:31 -070044import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
Wale Ogunwale214f3482018-10-04 11:00:47 -070045import static android.content.pm.ApplicationInfo.FLAG_FACTORY_TEST;
Wale Ogunwale342fbe92018-10-09 08:44:10 -070046import static android.content.pm.ConfigurationInfo.GL_ES_VERSION_UNDEFINED;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070047import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
48import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
Evan Rosky4505b352018-09-06 11:20:40 -070049import static android.content.pm.PackageManager.FEATURE_PC;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070050import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070051import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070052import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
53import static android.os.Build.VERSION_CODES.N;
Wale Ogunwale214f3482018-10-04 11:00:47 -070054import static android.os.FactoryTest.FACTORY_TEST_HIGH_LEVEL;
55import static android.os.FactoryTest.FACTORY_TEST_LOW_LEVEL;
56import static android.os.FactoryTest.FACTORY_TEST_OFF;
Wale Ogunwale31913b52018-10-13 08:29:31 -070057import static android.os.Process.FIRST_APPLICATION_UID;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070058import static android.os.Process.SYSTEM_UID;
Evan Rosky4505b352018-09-06 11:20:40 -070059import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070060import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
61import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
62import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
63import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
Evan Rosky4505b352018-09-06 11:20:40 -070064import static android.provider.Settings.Global.HIDE_ERROR_DIALOGS;
65import static android.provider.Settings.System.FONT_SCALE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070066import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
67import static android.view.Display.DEFAULT_DISPLAY;
68import static android.view.Display.INVALID_DISPLAY;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070069import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
Wale Ogunwale6767eae2018-05-03 15:52:51 -070070import static android.view.WindowManager.TRANSIT_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070071import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070072import static android.view.WindowManager.TRANSIT_TASK_OPEN;
73import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
Evan Rosky4505b352018-09-06 11:20:40 -070074
Wale Ogunwale31913b52018-10-13 08:29:31 -070075import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.CONFIG_WILL_CHANGE;
76import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.CONTROLLER;
77import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.CURRENT_TRACKER;
78import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.Controller.IS_A_MONKEY;
79import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.GLOBAL_CONFIGURATION;
80import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.GOING_TO_SLEEP;
81import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.HEAVY_WEIGHT_PROC;
82import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.HOME_PROC;
83import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.LAUNCHING_ACTIVITY;
84import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC;
85import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC_VISIBLE_TIME_MS;
86import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.SCREEN_COMPAT_PACKAGES;
87import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.MODE;
88import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.PACKAGE;
Wale Ogunwale98875612018-10-12 07:53:02 -070089import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_ALL;
Wale Ogunwale31913b52018-10-13 08:29:31 -070090import static com.android.server.am.ActivityManagerService.ANR_TRACE_DIR;
Wale Ogunwale98875612018-10-12 07:53:02 -070091import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
92import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_FOCUS;
93import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_IMMERSIVE;
94import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_LOCKTASK;
95import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_STACK;
96import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
97import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
98import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_VISIBILITY;
99import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
100import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS;
101import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_IMMERSIVE;
102import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_LOCKTASK;
103import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_STACK;
104import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH;
105import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_VISIBILITY;
106import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_ATM;
107import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700108import static com.android.server.am.ActivityManagerService.MY_PID;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700109import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS;
Evan Rosky4505b352018-09-06 11:20:40 -0700110import static com.android.server.am.ActivityManagerService.dumpStackTraces;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700111import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700112import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700113import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
114import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
115import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
116import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
117import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
Evan Rosky4505b352018-09-06 11:20:40 -0700118import static com.android.server.am.ActivityTaskManagerService.H.REPORT_TIME_TRACKER_MSG;
119import static com.android.server.am.ActivityTaskManagerService.UiHandler.DISMISS_DIALOG_UI_MSG;
Wale Ogunwale98875612018-10-12 07:53:02 -0700120import static android.app.ActivityTaskManager.INVALID_TASK_ID;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700121import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700122import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700123import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
Evan Rosky4505b352018-09-06 11:20:40 -0700124import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT;
125import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_DATA;
126import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
127import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700128import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
129import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700130
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700131import android.Manifest;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700132import android.annotation.NonNull;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700133import android.annotation.Nullable;
134import android.annotation.UserIdInt;
135import android.app.Activity;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700136import android.app.ActivityManager;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700137import android.app.ActivityManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700138import android.app.ActivityOptions;
139import android.app.ActivityTaskManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700140import android.app.ActivityThread;
141import android.app.AlertDialog;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700142import android.app.AppGlobals;
Evan Rosky4505b352018-09-06 11:20:40 -0700143import android.app.Dialog;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700144import android.app.IActivityController;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700145import android.app.IActivityTaskManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700146import android.app.IApplicationThread;
147import android.app.IAssistDataReceiver;
Wale Ogunwale53783742018-09-16 10:21:51 -0700148import android.app.INotificationManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700149import android.app.ITaskStackListener;
Wale Ogunwale53783742018-09-16 10:21:51 -0700150import android.app.Notification;
151import android.app.NotificationManager;
152import android.app.PendingIntent;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700153import android.app.PictureInPictureParams;
154import android.app.ProfilerInfo;
155import android.app.RemoteAction;
156import android.app.WaitResult;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700157import android.app.WindowConfiguration;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700158import android.app.admin.DevicePolicyCache;
159import android.app.assist.AssistContent;
160import android.app.assist.AssistStructure;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700161import android.app.usage.UsageStatsManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700162import android.content.ActivityNotFoundException;
163import android.content.ComponentName;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700164import android.content.ContentResolver;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700165import android.content.Context;
Evan Rosky4505b352018-09-06 11:20:40 -0700166import android.content.DialogInterface;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700167import android.content.IIntentSender;
168import android.content.Intent;
169import android.content.pm.ActivityInfo;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700170import android.content.pm.ApplicationInfo;
Yunfan Chen75157d72018-07-27 14:47:21 +0900171import android.content.pm.ConfigurationInfo;
Evan Rosky4505b352018-09-06 11:20:40 -0700172import android.content.pm.IPackageManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700173import android.content.pm.PackageManager;
Evan Rosky4505b352018-09-06 11:20:40 -0700174import android.content.pm.PackageManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700175import android.content.pm.ParceledListSlice;
176import android.content.pm.ResolveInfo;
Wale Ogunwale53783742018-09-16 10:21:51 -0700177import android.content.res.CompatibilityInfo;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700178import android.content.res.Configuration;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700179import android.content.res.Resources;
Evan Rosky4505b352018-09-06 11:20:40 -0700180import android.database.ContentObserver;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700181import android.graphics.Bitmap;
182import android.graphics.Point;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700183import android.graphics.Rect;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700184import android.metrics.LogMaker;
185import android.net.Uri;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700186import android.os.Binder;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700187import android.os.Build;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700188import android.os.Bundle;
Wale Ogunwale214f3482018-10-04 11:00:47 -0700189import android.os.FactoryTest;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700190import android.os.FileUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700191import android.os.Handler;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700192import android.os.IBinder;
Evan Rosky4505b352018-09-06 11:20:40 -0700193import android.os.IUserManager;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700194import android.os.LocaleList;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700195import android.os.Looper;
196import android.os.Message;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700197import android.os.PersistableBundle;
Evan Rosky4505b352018-09-06 11:20:40 -0700198import android.os.PowerManager;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700199import android.os.PowerManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700200import android.os.RemoteException;
Evan Rosky4505b352018-09-06 11:20:40 -0700201import android.os.ServiceManager;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700202import android.os.StrictMode;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700203import android.os.SystemClock;
204import android.os.SystemProperties;
Evan Rosky4505b352018-09-06 11:20:40 -0700205import android.os.Trace;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700206import android.os.UpdateLock;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700207import android.os.UserHandle;
Evan Rosky4505b352018-09-06 11:20:40 -0700208import android.os.UserManager;
209import android.os.WorkSource;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700210import android.os.storage.IStorageManager;
211import android.os.storage.StorageManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700212import android.provider.Settings;
213import android.service.voice.IVoiceInteractionSession;
214import android.service.voice.VoiceInteractionManagerInternal;
215import android.telecom.TelecomManager;
216import android.text.TextUtils;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700217import android.text.format.Time;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700218import android.util.ArrayMap;
219import android.util.EventLog;
220import android.util.Log;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700221import android.util.Slog;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700222import android.util.SparseArray;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700223import android.util.SparseIntArray;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700224import android.util.StatsLog;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700225import android.util.TimeUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700226import android.util.proto.ProtoOutputStream;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700227import android.view.IRecentsAnimationRunner;
228import android.view.RemoteAnimationAdapter;
229import android.view.RemoteAnimationDefinition;
Evan Rosky4505b352018-09-06 11:20:40 -0700230import android.view.WindowManager;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700231
Evan Rosky4505b352018-09-06 11:20:40 -0700232import com.android.internal.R;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700233import com.android.internal.annotations.VisibleForTesting;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700234import com.android.internal.app.AssistUtils;
Evan Rosky4505b352018-09-06 11:20:40 -0700235import com.android.internal.app.IAppOpsService;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700236import com.android.internal.app.IVoiceInteractor;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700237import com.android.internal.app.ProcessMap;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700238import com.android.internal.logging.MetricsLogger;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700239import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Wale Ogunwale53783742018-09-16 10:21:51 -0700240import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
241import com.android.internal.notification.SystemNotificationChannels;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700242import com.android.internal.os.TransferPipe;
Evan Rosky4505b352018-09-06 11:20:40 -0700243import com.android.internal.os.logging.MetricsLoggerWrapper;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700244import com.android.internal.policy.IKeyguardDismissCallback;
245import com.android.internal.policy.KeyguardDismissCallback;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700246import com.android.internal.util.ArrayUtils;
247import com.android.internal.util.FastPrintWriter;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700248import com.android.internal.util.Preconditions;
Wale Ogunwale53783742018-09-16 10:21:51 -0700249import com.android.internal.util.function.pooled.PooledLambda;
Evan Rosky4505b352018-09-06 11:20:40 -0700250import com.android.server.AppOpsService;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700251import com.android.server.AttributeCache;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700252import com.android.server.LocalServices;
253import com.android.server.SystemService;
Evan Rosky4505b352018-09-06 11:20:40 -0700254import com.android.server.SystemServiceManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700255import com.android.server.Watchdog;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700256import com.android.server.firewall.IntentFirewall;
Evan Rosky4505b352018-09-06 11:20:40 -0700257import com.android.server.pm.UserManagerService;
258import com.android.server.uri.UriGrantsManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700259import com.android.server.vr.VrManagerInternal;
Evan Rosky4505b352018-09-06 11:20:40 -0700260import com.android.server.wm.ActivityTaskManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700261import com.android.server.wm.PinnedStackWindowController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700262import com.android.server.wm.WindowManagerService;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700263
Wale Ogunwale31913b52018-10-13 08:29:31 -0700264import java.io.BufferedReader;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700265import java.io.File;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700266import java.io.FileDescriptor;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700267import java.io.FileOutputStream;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700268import java.io.FileReader;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700269import java.io.IOException;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700270import java.io.PrintWriter;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700271import java.io.StringWriter;
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700272import java.lang.ref.WeakReference;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700273import java.text.DateFormat;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700274import java.util.ArrayList;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700275import java.util.Date;
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700276import java.util.HashSet;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700277import java.util.List;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700278import java.util.Locale;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700279import java.util.Map;
280import java.util.Set;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700281
282/**
283 * System service for managing activities and their containers (task, stacks, displays,... ).
284 *
285 * {@hide}
286 */
287public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
Wale Ogunwale98875612018-10-12 07:53:02 -0700288 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityTaskManagerService" : TAG_ATM;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700289 private static final String TAG_STACK = TAG + POSTFIX_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700290 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
291 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
292 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
293 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
294 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700295 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700296
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700297 // How long we wait until we timeout on key dispatching.
Wale Ogunwale51cc98a2018-10-15 10:41:05 -0700298 public static final int KEY_DISPATCHING_TIMEOUT_MS = 5 * 1000;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700299 // How long we wait until we timeout on key dispatching during instrumentation.
Wale Ogunwale51cc98a2018-10-15 10:41:05 -0700300 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS = 60 * 1000;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700301
Wale Ogunwale98875612018-10-12 07:53:02 -0700302 /** Used to indicate that an app transition should be animated. */
303 static final boolean ANIMATE = true;
304
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700305 /** Hardware-reported OpenGLES version. */
306 final int GL_ES_VERSION;
307
Wale Ogunwale31913b52018-10-13 08:29:31 -0700308 public static final String DUMP_ACTIVITIES_CMD = "activities" ;
309 public static final String DUMP_ACTIVITIES_SHORT_CMD = "a" ;
310 public static final String DUMP_LASTANR_CMD = "lastanr" ;
311 public static final String DUMP_LASTANR_TRACES_CMD = "lastanr-traces" ;
312 public static final String DUMP_STARTER_CMD = "starter" ;
313 public static final String DUMP_CONTAINERS_CMD = "containers" ;
314 public static final String DUMP_RECENTS_CMD = "recents" ;
315 public static final String DUMP_RECENTS_SHORT_CMD = "r" ;
316
Wale Ogunwale64258362018-10-16 15:13:37 -0700317 /** This activity is not being relaunched, or being relaunched for a non-resize reason. */
318 public static final int RELAUNCH_REASON_NONE = 0;
319 /** This activity is being relaunched due to windowing mode change. */
320 public static final int RELAUNCH_REASON_WINDOWING_MODE_RESIZE = 1;
321 /** This activity is being relaunched due to a free-resize operation. */
322 public static final int RELAUNCH_REASON_FREE_RESIZE = 2;
323
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700324 Context mContext;
Wale Ogunwale64258362018-10-16 15:13:37 -0700325
Wale Ogunwalef6733932018-06-27 05:14:34 -0700326 /**
327 * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
328 * change at runtime. Use mContext for non-UI purposes.
329 */
330 final Context mUiContext;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700331 final ActivityThread mSystemThread;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700332 H mH;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700333 UiHandler mUiHandler;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700334 ActivityManagerService mAm;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700335 ActivityManagerInternal mAmInternal;
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700336 UriGrantsManagerInternal mUgmInternal;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700337 private PackageManagerInternal mPmInternal;
Wale Ogunwale53783742018-09-16 10:21:51 -0700338 private ActivityTaskManagerInternal mInternal;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700339 PowerManagerInternal mPowerManagerInternal;
340 private UsageStatsManagerInternal mUsageStatsInternal;
341
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700342 PendingIntentController mPendingIntentController;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700343 IntentFirewall mIntentFirewall;
344
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700345 /* Global service lock used by the package the owns this service. */
346 Object mGlobalLock;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700347 ActivityStackSupervisor mStackSupervisor;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700348 WindowManagerService mWindowManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700349 private UserManagerService mUserManager;
350 private AppOpsService mAppOpsService;
Wale Ogunwalebff2df42018-10-18 17:09:19 -0700351 /** All active uids in the system. */
352 final SparseArray<Integer> mActiveUids = new SparseArray<>();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700353 /** All processes currently running that might have a window organized by name. */
354 final ProcessMap<WindowProcessController> mProcessNames = new ProcessMap<>();
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700355 /** All processes we currently have running mapped by pid */
356 final SparseArray<WindowProcessController> mPidMap = new SparseArray<>();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700357 /** This is the process holding what we currently consider to be the "home" activity. */
358 WindowProcessController mHomeProcess;
Wale Ogunwale53783742018-09-16 10:21:51 -0700359 /** The currently running heavy-weight process, if any. */
360 WindowProcessController mHeavyWeightProcess = null;
Wale Ogunwale214f3482018-10-04 11:00:47 -0700361 boolean mHasHeavyWeightFeature;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700362 /**
363 * This is the process holding the activity the user last visited that is in a different process
364 * from the one they are currently in.
365 */
366 WindowProcessController mPreviousProcess;
367 /** The time at which the previous process was last visible. */
368 long mPreviousProcessVisibleTime;
369
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700370 /** List of intents that were used to start the most recent tasks. */
371 private RecentTasks mRecentTasks;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700372 /** State of external calls telling us if the device is awake or asleep. */
373 private boolean mKeyguardShown = false;
374
375 // Wrapper around VoiceInteractionServiceManager
376 private AssistUtils mAssistUtils;
377
378 // VoiceInteraction session ID that changes for each new request except when
379 // being called for multi-window assist in a single session.
380 private int mViSessionId = 1000;
381
382 // How long to wait in getAssistContextExtras for the activity and foreground services
383 // to respond with the result.
384 private static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
385
386 // How long top wait when going through the modern assist (which doesn't need to block
387 // on getting this result before starting to launch its UI).
388 private static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
389
390 // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
391 private static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
392
393 private final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
394
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700395 // Keeps track of the active voice interaction service component, notified from
396 // VoiceInteractionManagerService
397 ComponentName mActiveVoiceInteractionServiceComponent;
398
399 private VrController mVrController;
400 KeyguardController mKeyguardController;
401 private final ClientLifecycleManager mLifecycleManager;
402 private TaskChangeNotificationController mTaskChangeNotificationController;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700403 /** The controller for all operations related to locktask. */
404 private LockTaskController mLockTaskController;
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700405 private ActivityStartController mActivityStartController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700406
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700407 boolean mSuppressResizeConfigChanges;
408
409 private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
410 new UpdateConfigurationResult();
411
412 static final class UpdateConfigurationResult {
413 // Configuration changes that were updated.
414 int changes;
415 // If the activity was relaunched to match the new configuration.
416 boolean activityRelaunched;
417
418 void reset() {
419 changes = 0;
420 activityRelaunched = false;
421 }
422 }
423
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700424 /** Current sequencing integer of the configuration, for skipping old configurations. */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700425 private int mConfigurationSeq;
426 // To cache the list of supported system locales
427 private String[] mSupportedSystemLocales = null;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700428
429 /**
430 * Temp object used when global and/or display override configuration is updated. It is also
431 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
432 * anyone...
433 */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700434 private Configuration mTempConfig = new Configuration();
435
Wale Ogunwalef6733932018-06-27 05:14:34 -0700436 /** Temporary to avoid allocations. */
437 final StringBuilder mStringBuilder = new StringBuilder(256);
438
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700439 // Amount of time after a call to stopAppSwitches() during which we will
440 // prevent further untrusted switches from happening.
441 private static final long APP_SWITCH_DELAY_TIME = 5 * 1000;
442
443 /**
444 * The time at which we will allow normal application switches again,
445 * after a call to {@link #stopAppSwitches()}.
446 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700447 private long mAppSwitchesAllowedTime;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700448 /**
449 * This is set to true after the first switch after mAppSwitchesAllowedTime
450 * is set; any switches after that will clear the time.
451 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700452 private boolean mDidAppSwitch;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700453
454 IActivityController mController = null;
455 boolean mControllerIsAMonkey = false;
456
Wale Ogunwale214f3482018-10-04 11:00:47 -0700457 final int mFactoryTest;
458
459 /** Used to control how we initialize the service. */
460 ComponentName mTopComponent;
461 String mTopAction = Intent.ACTION_MAIN;
462 String mTopData;
463
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700464 /**
Wale Ogunwale31913b52018-10-13 08:29:31 -0700465 * Dump of the activity state at the time of the last ANR. Cleared after
466 * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
467 */
468 String mLastANRState;
469
470 /**
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700471 * Used to retain an update lock when the foreground activity is in
472 * immersive mode.
473 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700474 private final UpdateLock mUpdateLock = new UpdateLock("immersive");
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700475
476 /**
477 * Packages that are being allowed to perform unrestricted app switches. Mapping is
478 * User -> Type -> uid.
479 */
480 final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
481
482 /** The dimensions of the thumbnails in the Recents UI. */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700483 private int mThumbnailWidth;
484 private int mThumbnailHeight;
485 private float mFullscreenThumbnailScale;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700486
487 /**
488 * Flag that indicates if multi-window is enabled.
489 *
490 * For any particular form of multi-window to be enabled, generic multi-window must be enabled
491 * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
492 * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
493 * At least one of the forms of multi-window must be enabled in order for this flag to be
494 * initialized to 'true'.
495 *
496 * @see #mSupportsSplitScreenMultiWindow
497 * @see #mSupportsFreeformWindowManagement
498 * @see #mSupportsPictureInPicture
499 * @see #mSupportsMultiDisplay
500 */
501 boolean mSupportsMultiWindow;
502 boolean mSupportsSplitScreenMultiWindow;
503 boolean mSupportsFreeformWindowManagement;
504 boolean mSupportsPictureInPicture;
505 boolean mSupportsMultiDisplay;
506 boolean mForceResizableActivities;
507
508 final List<ActivityTaskManagerInternal.ScreenObserver> mScreenObservers = new ArrayList<>();
509
510 // VR Vr2d Display Id.
511 int mVr2dDisplayId = INVALID_DISPLAY;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700512
Wale Ogunwalef6733932018-06-27 05:14:34 -0700513 /**
514 * Set while we are wanting to sleep, to prevent any
515 * activities from being started/resumed.
516 *
517 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
518 *
519 * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
520 * while in the sleep state until there is a pending transition out of sleep, in which case
521 * mSleeping is set to false, and remains false while awake.
522 *
523 * Whether mSleeping can quickly toggled between true/false without the device actually
524 * display changing states is undefined.
525 */
526 private boolean mSleeping = false;
527
528 /**
529 * The process state used for processes that are running the top activities.
530 * This changes between TOP and TOP_SLEEPING to following mSleeping.
531 */
532 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
533
534 // Whether we should show our dialogs (ANR, crash, etc) or just perform their default action
535 // automatically. Important for devices without direct input devices.
536 private boolean mShowDialogs = true;
537
538 /** Set if we are shutting down the system, similar to sleeping. */
539 boolean mShuttingDown = false;
540
541 /**
542 * We want to hold a wake lock while running a voice interaction session, since
543 * this may happen with the screen off and we need to keep the CPU running to
544 * be able to continue to interact with the user.
545 */
546 PowerManager.WakeLock mVoiceWakeLock;
547
548 /**
549 * Set while we are running a voice interaction. This overrides sleeping while it is active.
550 */
551 IVoiceInteractionSession mRunningVoice;
552
553 /**
554 * The last resumed activity. This is identical to the current resumed activity most
555 * of the time but could be different when we're pausing one activity before we resume
556 * another activity.
557 */
558 ActivityRecord mLastResumedActivity;
559
560 /**
561 * The activity that is currently being traced as the active resumed activity.
562 *
563 * @see #updateResumedAppTrace
564 */
565 private @Nullable ActivityRecord mTracedResumedActivity;
566
567 /** If non-null, we are tracking the time the user spends in the currently focused app. */
568 AppTimeTracker mCurAppTimeTracker;
569
Wale Ogunwale008163e2018-07-23 23:11:08 -0700570 private AppWarnings mAppWarnings;
571
Wale Ogunwale53783742018-09-16 10:21:51 -0700572 /**
573 * Packages that the user has asked to have run in screen size
574 * compatibility mode instead of filling the screen.
575 */
576 CompatModePackages mCompatModePackages;
577
Wale Ogunwalef6733932018-06-27 05:14:34 -0700578 private FontScaleSettingObserver mFontScaleSettingObserver;
579
580 private final class FontScaleSettingObserver extends ContentObserver {
581 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
582 private final Uri mHideErrorDialogsUri = Settings.Global.getUriFor(HIDE_ERROR_DIALOGS);
583
584 public FontScaleSettingObserver() {
585 super(mH);
586 final ContentResolver resolver = mContext.getContentResolver();
587 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
588 resolver.registerContentObserver(mHideErrorDialogsUri, false, this,
589 UserHandle.USER_ALL);
590 }
591
592 @Override
593 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
594 if (mFontScaleUri.equals(uri)) {
595 updateFontScaleIfNeeded(userId);
596 } else if (mHideErrorDialogsUri.equals(uri)) {
597 synchronized (mGlobalLock) {
598 updateShouldShowDialogsLocked(getGlobalConfiguration());
599 }
600 }
601 }
602 }
603
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700604 ActivityTaskManagerService(Context context) {
605 mContext = context;
Wale Ogunwale214f3482018-10-04 11:00:47 -0700606 mFactoryTest = FactoryTest.getMode();
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700607 mSystemThread = ActivityThread.currentActivityThread();
608 mUiContext = mSystemThread.getSystemUiContext();
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700609 mLifecycleManager = new ClientLifecycleManager();
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700610 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", GL_ES_VERSION_UNDEFINED);
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700611 }
612
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700613 void onSystemReady() {
Wale Ogunwale214f3482018-10-04 11:00:47 -0700614 mHasHeavyWeightFeature = mContext.getPackageManager().hasSystemFeature(
615 PackageManager.FEATURE_CANT_SAVE_STATE);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700616 mAssistUtils = new AssistUtils(mContext);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700617 mVrController.onSystemReady();
618 mRecentTasks.onSystemReadyLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700619 }
620
Wale Ogunwalef6733932018-06-27 05:14:34 -0700621 void onInitPowerManagement() {
622 mStackSupervisor.initPowerManagement();
623 final PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700624 mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
Wale Ogunwalef6733932018-06-27 05:14:34 -0700625 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
626 mVoiceWakeLock.setReferenceCounted(false);
627 }
628
629 void installSystemProviders() {
630 mFontScaleSettingObserver = new FontScaleSettingObserver();
631 }
632
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700633 void retrieveSettings(ContentResolver resolver) {
634 final boolean freeformWindowManagement =
635 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
636 || Settings.Global.getInt(
637 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
638
639 final boolean supportsMultiWindow = ActivityTaskManager.supportsMultiWindow(mContext);
640 final boolean supportsPictureInPicture = supportsMultiWindow &&
641 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
642 final boolean supportsSplitScreenMultiWindow =
643 ActivityTaskManager.supportsSplitScreenMultiWindow(mContext);
644 final boolean supportsMultiDisplay = mContext.getPackageManager()
645 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
646 final boolean alwaysFinishActivities =
647 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
648 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
649 final boolean forceResizable = Settings.Global.getInt(
650 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
Garfield Tane0846042018-07-26 13:42:04 -0700651 final boolean isPc = mContext.getPackageManager().hasSystemFeature(FEATURE_PC);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700652
653 // Transfer any global setting for forcing RTL layout, into a System Property
654 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
655
656 final Configuration configuration = new Configuration();
657 Settings.System.getConfiguration(resolver, configuration);
658 if (forceRtl) {
659 // This will take care of setting the correct layout direction flags
660 configuration.setLayoutDirection(configuration.locale);
661 }
662
663 synchronized (mGlobalLock) {
664 mForceResizableActivities = forceResizable;
665 final boolean multiWindowFormEnabled = freeformWindowManagement
666 || supportsSplitScreenMultiWindow
667 || supportsPictureInPicture
668 || supportsMultiDisplay;
669 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
670 mSupportsMultiWindow = true;
671 mSupportsFreeformWindowManagement = freeformWindowManagement;
672 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
673 mSupportsPictureInPicture = supportsPictureInPicture;
674 mSupportsMultiDisplay = supportsMultiDisplay;
675 } else {
676 mSupportsMultiWindow = false;
677 mSupportsFreeformWindowManagement = false;
678 mSupportsSplitScreenMultiWindow = false;
679 mSupportsPictureInPicture = false;
680 mSupportsMultiDisplay = false;
681 }
682 mWindowManager.setForceResizableTasks(mForceResizableActivities);
683 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
Garfield Tane0846042018-07-26 13:42:04 -0700684 mWindowManager.setSupportsFreeformWindowManagement(mSupportsFreeformWindowManagement);
685 mWindowManager.setIsPc(isPc);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700686 // This happens before any activities are started, so we can change global configuration
687 // in-place.
688 updateConfigurationLocked(configuration, null, true);
689 final Configuration globalConfig = getGlobalConfiguration();
690 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
691
692 // Load resources only after the current configuration has been set.
693 final Resources res = mContext.getResources();
694 mThumbnailWidth = res.getDimensionPixelSize(
695 com.android.internal.R.dimen.thumbnail_width);
696 mThumbnailHeight = res.getDimensionPixelSize(
697 com.android.internal.R.dimen.thumbnail_height);
698
699 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
700 mFullscreenThumbnailScale = (float) res
701 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
702 (float) globalConfig.screenWidthDp;
703 } else {
704 mFullscreenThumbnailScale = res.getFraction(
705 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
706 }
707 }
708 }
709
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700710 // TODO: Will be converted to WM lock once transition is complete.
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700711 void setActivityManagerService(ActivityManagerService am, Looper looper,
712 IntentFirewall intentFirewall, PendingIntentController intentController) {
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700713 mAm = am;
714 mGlobalLock = mAm;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700715 mH = new H(looper);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700716 mUiHandler = new UiHandler();
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700717 mIntentFirewall = intentFirewall;
Wale Ogunwale53783742018-09-16 10:21:51 -0700718 final File systemDir = SystemServiceManager.ensureSystemDir();
719 mAppWarnings = new AppWarnings(this, mUiContext, mH, mUiHandler, systemDir);
720 mCompatModePackages = new CompatModePackages(this, systemDir, mH);
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700721 mPendingIntentController = intentController;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700722
723 mTempConfig.setToDefaults();
724 mTempConfig.setLocales(LocaleList.getDefault());
725 mConfigurationSeq = mTempConfig.seq = 1;
726 mStackSupervisor = createStackSupervisor();
727 mStackSupervisor.onConfigurationChanged(mTempConfig);
728
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700729 mTaskChangeNotificationController =
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700730 new TaskChangeNotificationController(mGlobalLock, mStackSupervisor, mH);
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700731 mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mH);
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700732 mActivityStartController = new ActivityStartController(this);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700733 mRecentTasks = createRecentTasks();
734 mStackSupervisor.setRecentTasks(mRecentTasks);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700735 mVrController = new VrController(mGlobalLock);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700736 mKeyguardController = mStackSupervisor.getKeyguardController();
737 }
738
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700739 void onActivityManagerInternalAdded() {
740 mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700741 mUgmInternal = LocalServices.getService(UriGrantsManagerInternal.class);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700742 }
743
Yunfan Chen75157d72018-07-27 14:47:21 +0900744 int increaseConfigurationSeqLocked() {
745 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
746 return mConfigurationSeq;
747 }
748
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700749 protected ActivityStackSupervisor createStackSupervisor() {
750 final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mH.getLooper());
751 supervisor.initialize();
752 return supervisor;
753 }
754
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700755 void setWindowManager(WindowManagerService wm) {
756 mWindowManager = wm;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700757 mLockTaskController.setWindowManager(wm);
Wale Ogunwale31913b52018-10-13 08:29:31 -0700758 mStackSupervisor.setWindowManager(wm);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700759 }
760
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700761 void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
762 mUsageStatsInternal = usageStatsManager;
763 }
764
Wale Ogunwalef6733932018-06-27 05:14:34 -0700765 UserManagerService getUserManager() {
766 if (mUserManager == null) {
767 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
768 mUserManager = (UserManagerService) IUserManager.Stub.asInterface(b);
769 }
770 return mUserManager;
771 }
772
773 AppOpsService getAppOpsService() {
774 if (mAppOpsService == null) {
775 IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
776 mAppOpsService = (AppOpsService) IAppOpsService.Stub.asInterface(b);
777 }
778 return mAppOpsService;
779 }
780
781 boolean hasUserRestriction(String restriction, int userId) {
782 return getUserManager().hasUserRestriction(restriction, userId);
783 }
784
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700785 protected RecentTasks createRecentTasks() {
786 return new RecentTasks(this, mStackSupervisor);
787 }
788
789 RecentTasks getRecentTasks() {
790 return mRecentTasks;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700791 }
792
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700793 ClientLifecycleManager getLifecycleManager() {
794 return mLifecycleManager;
795 }
796
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700797 ActivityStartController getActivityStartController() {
798 return mActivityStartController;
799 }
800
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700801 TaskChangeNotificationController getTaskChangeNotificationController() {
802 return mTaskChangeNotificationController;
803 }
804
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700805 LockTaskController getLockTaskController() {
806 return mLockTaskController;
807 }
808
Yunfan Chen75157d72018-07-27 14:47:21 +0900809 /**
810 * Return the global configuration used by the process corresponding to the input pid. This is
811 * usually the global configuration with some overrides specific to that process.
812 */
813 Configuration getGlobalConfigurationForCallingPid() {
814 final int pid = Binder.getCallingPid();
815 if (pid == MY_PID || pid < 0) {
816 return getGlobalConfiguration();
817 }
818 synchronized (mGlobalLock) {
819 final WindowProcessController app = mPidMap.get(pid);
820 return app != null ? app.getConfiguration() : getGlobalConfiguration();
821 }
822 }
823
824 /**
825 * Return the device configuration info used by the process corresponding to the input pid.
826 * The value is consistent with the global configuration for the process.
827 */
828 @Override
829 public ConfigurationInfo getDeviceConfigurationInfo() {
830 ConfigurationInfo config = new ConfigurationInfo();
831 synchronized (mGlobalLock) {
832 final Configuration globalConfig = getGlobalConfigurationForCallingPid();
833 config.reqTouchScreen = globalConfig.touchscreen;
834 config.reqKeyboardType = globalConfig.keyboard;
835 config.reqNavigation = globalConfig.navigation;
836 if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
837 || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
838 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
839 }
840 if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
841 && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
842 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
843 }
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700844 config.reqGlEsVersion = GL_ES_VERSION;
Yunfan Chen75157d72018-07-27 14:47:21 +0900845 }
846 return config;
847 }
848
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700849 private void start() {
Wale Ogunwale53783742018-09-16 10:21:51 -0700850 mInternal = new LocalService();
851 LocalServices.addService(ActivityTaskManagerInternal.class, mInternal);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700852 }
853
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700854 public static final class Lifecycle extends SystemService {
855 private final ActivityTaskManagerService mService;
856
857 public Lifecycle(Context context) {
858 super(context);
859 mService = new ActivityTaskManagerService(context);
860 }
861
862 @Override
863 public void onStart() {
864 publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700865 mService.start();
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700866 }
867
868 public ActivityTaskManagerService getService() {
869 return mService;
870 }
871 }
872
873 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700874 public final int startActivity(IApplicationThread caller, String callingPackage,
875 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
876 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
877 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
878 resultWho, requestCode, startFlags, profilerInfo, bOptions,
879 UserHandle.getCallingUserId());
880 }
881
882 @Override
883 public final int startActivities(IApplicationThread caller, String callingPackage,
884 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
885 int userId) {
886 final String reason = "startActivities";
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700887 enforceNotIsolatedCaller(reason);
888 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, reason);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700889 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700890 return getActivityStartController().startActivities(caller, -1, callingPackage, intents,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100891 resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId, reason,
892 null /* originatingPendingIntent */);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700893 }
894
895 @Override
896 public int startActivityAsUser(IApplicationThread caller, String callingPackage,
897 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
898 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
899 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
900 resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
901 true /*validateIncomingUser*/);
902 }
903
904 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 boolean validateIncomingUser) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700908 enforceNotIsolatedCaller("startActivityAsUser");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700909
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700910 userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700911 Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
912
913 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700914 return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700915 .setCaller(caller)
916 .setCallingPackage(callingPackage)
917 .setResolvedType(resolvedType)
918 .setResultTo(resultTo)
919 .setResultWho(resultWho)
920 .setRequestCode(requestCode)
921 .setStartFlags(startFlags)
922 .setProfilerInfo(profilerInfo)
923 .setActivityOptions(bOptions)
924 .setMayWait(userId)
925 .execute();
926
927 }
928
929 @Override
930 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
931 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700932 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions) {
933 enforceNotIsolatedCaller("startActivityIntentSender");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700934 // Refuse possible leaked file descriptors
935 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
936 throw new IllegalArgumentException("File descriptors passed in Intent");
937 }
938
939 if (!(target instanceof PendingIntentRecord)) {
940 throw new IllegalArgumentException("Bad PendingIntent object");
941 }
942
943 PendingIntentRecord pir = (PendingIntentRecord)target;
944
945 synchronized (mGlobalLock) {
946 // If this is coming from the currently resumed activity, it is
947 // effectively saying that app switches are allowed at this point.
Andrii Kulian5f750bc2018-07-17 08:57:23 -0700948 final ActivityStack stack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700949 if (stack.mResumedActivity != null &&
950 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700951 mAppSwitchesAllowedTime = 0;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700952 }
953 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700954 return pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700955 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700956 }
957
958 @Override
959 public boolean startNextMatchingActivity(IBinder callingActivity, Intent intent,
960 Bundle bOptions) {
961 // Refuse possible leaked file descriptors
962 if (intent != null && intent.hasFileDescriptors()) {
963 throw new IllegalArgumentException("File descriptors passed in Intent");
964 }
965 SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
966
967 synchronized (mGlobalLock) {
968 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
969 if (r == null) {
970 SafeActivityOptions.abort(options);
971 return false;
972 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700973 if (!r.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700974 // The caller is not running... d'oh!
975 SafeActivityOptions.abort(options);
976 return false;
977 }
978 intent = new Intent(intent);
979 // The caller is not allowed to change the data.
980 intent.setDataAndType(r.intent.getData(), r.intent.getType());
981 // And we are resetting to find the next component...
982 intent.setComponent(null);
983
984 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
985
986 ActivityInfo aInfo = null;
987 try {
988 List<ResolveInfo> resolves =
989 AppGlobals.getPackageManager().queryIntentActivities(
990 intent, r.resolvedType,
991 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
992 UserHandle.getCallingUserId()).getList();
993
994 // Look for the original activity in the list...
995 final int N = resolves != null ? resolves.size() : 0;
996 for (int i=0; i<N; i++) {
997 ResolveInfo rInfo = resolves.get(i);
998 if (rInfo.activityInfo.packageName.equals(r.packageName)
999 && rInfo.activityInfo.name.equals(r.info.name)) {
1000 // We found the current one... the next matching is
1001 // after it.
1002 i++;
1003 if (i<N) {
1004 aInfo = resolves.get(i).activityInfo;
1005 }
1006 if (debug) {
1007 Slog.v(TAG, "Next matching activity: found current " + r.packageName
1008 + "/" + r.info.name);
1009 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
1010 ? "null" : aInfo.packageName + "/" + aInfo.name));
1011 }
1012 break;
1013 }
1014 }
1015 } catch (RemoteException e) {
1016 }
1017
1018 if (aInfo == null) {
1019 // Nobody who is next!
1020 SafeActivityOptions.abort(options);
1021 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
1022 return false;
1023 }
1024
1025 intent.setComponent(new ComponentName(
1026 aInfo.applicationInfo.packageName, aInfo.name));
1027 intent.setFlags(intent.getFlags()&~(
1028 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
1029 Intent.FLAG_ACTIVITY_CLEAR_TOP|
1030 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
1031 FLAG_ACTIVITY_NEW_TASK));
1032
1033 // Okay now we need to start the new activity, replacing the currently running activity.
1034 // This is a little tricky because we want to start the new one as if the current one is
1035 // finished, but not finish the current one first so that there is no flicker.
1036 // And thus...
1037 final boolean wasFinishing = r.finishing;
1038 r.finishing = true;
1039
1040 // Propagate reply information over to the new activity.
1041 final ActivityRecord resultTo = r.resultTo;
1042 final String resultWho = r.resultWho;
1043 final int requestCode = r.requestCode;
1044 r.resultTo = null;
1045 if (resultTo != null) {
1046 resultTo.removeResultsLocked(r, resultWho, requestCode);
1047 }
1048
1049 final long origId = Binder.clearCallingIdentity();
1050 // TODO(b/64750076): Check if calling pid should really be -1.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001051 final int res = getActivityStartController()
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001052 .obtainStarter(intent, "startNextMatchingActivity")
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001053 .setCaller(r.app.getThread())
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001054 .setResolvedType(r.resolvedType)
1055 .setActivityInfo(aInfo)
1056 .setResultTo(resultTo != null ? resultTo.appToken : null)
1057 .setResultWho(resultWho)
1058 .setRequestCode(requestCode)
1059 .setCallingPid(-1)
1060 .setCallingUid(r.launchedFromUid)
1061 .setCallingPackage(r.launchedFromPackage)
1062 .setRealCallingPid(-1)
1063 .setRealCallingUid(r.launchedFromUid)
1064 .setActivityOptions(options)
1065 .execute();
1066 Binder.restoreCallingIdentity(origId);
1067
1068 r.finishing = wasFinishing;
1069 if (res != ActivityManager.START_SUCCESS) {
1070 return false;
1071 }
1072 return true;
1073 }
1074 }
1075
1076 @Override
1077 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
1078 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1079 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
1080 final WaitResult res = new WaitResult();
1081 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001082 enforceNotIsolatedCaller("startActivityAndWait");
1083 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
1084 userId, "startActivityAndWait");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001085 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001086 getActivityStartController().obtainStarter(intent, "startActivityAndWait")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001087 .setCaller(caller)
1088 .setCallingPackage(callingPackage)
1089 .setResolvedType(resolvedType)
1090 .setResultTo(resultTo)
1091 .setResultWho(resultWho)
1092 .setRequestCode(requestCode)
1093 .setStartFlags(startFlags)
1094 .setActivityOptions(bOptions)
1095 .setMayWait(userId)
1096 .setProfilerInfo(profilerInfo)
1097 .setWaitResult(res)
1098 .execute();
1099 }
1100 return res;
1101 }
1102
1103 @Override
1104 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
1105 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1106 int startFlags, Configuration config, Bundle bOptions, int userId) {
1107 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001108 enforceNotIsolatedCaller("startActivityWithConfig");
1109 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
1110 "startActivityWithConfig");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001111 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001112 return getActivityStartController().obtainStarter(intent, "startActivityWithConfig")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001113 .setCaller(caller)
1114 .setCallingPackage(callingPackage)
1115 .setResolvedType(resolvedType)
1116 .setResultTo(resultTo)
1117 .setResultWho(resultWho)
1118 .setRequestCode(requestCode)
1119 .setStartFlags(startFlags)
1120 .setGlobalConfiguration(config)
1121 .setActivityOptions(bOptions)
1122 .setMayWait(userId)
1123 .execute();
1124 }
1125 }
1126
1127 @Override
1128 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
1129 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1130 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
1131 int userId) {
1132
1133 // This is very dangerous -- it allows you to perform a start activity (including
1134 // permission grants) as any app that may launch one of your own activities. So
1135 // we will only allow this to be done from activities that are part of the core framework,
1136 // and then only when they are running as the system.
1137 final ActivityRecord sourceRecord;
1138 final int targetUid;
1139 final String targetPackage;
1140 final boolean isResolver;
1141 synchronized (mGlobalLock) {
1142 if (resultTo == null) {
1143 throw new SecurityException("Must be called from an activity");
1144 }
1145 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
1146 if (sourceRecord == null) {
1147 throw new SecurityException("Called with bad activity token: " + resultTo);
1148 }
1149 if (!sourceRecord.info.packageName.equals("android")) {
1150 throw new SecurityException(
1151 "Must be called from an activity that is declared in the android package");
1152 }
1153 if (sourceRecord.app == null) {
1154 throw new SecurityException("Called without a process attached to activity");
1155 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001156 if (UserHandle.getAppId(sourceRecord.app.mUid) != SYSTEM_UID) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001157 // This is still okay, as long as this activity is running under the
1158 // uid of the original calling activity.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001159 if (sourceRecord.app.mUid != sourceRecord.launchedFromUid) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001160 throw new SecurityException(
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001161 "Calling activity in uid " + sourceRecord.app.mUid
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001162 + " must be system uid or original calling uid "
1163 + sourceRecord.launchedFromUid);
1164 }
1165 }
1166 if (ignoreTargetSecurity) {
1167 if (intent.getComponent() == null) {
1168 throw new SecurityException(
1169 "Component must be specified with ignoreTargetSecurity");
1170 }
1171 if (intent.getSelector() != null) {
1172 throw new SecurityException(
1173 "Selector not allowed with ignoreTargetSecurity");
1174 }
1175 }
1176 targetUid = sourceRecord.launchedFromUid;
1177 targetPackage = sourceRecord.launchedFromPackage;
1178 isResolver = sourceRecord.isResolverOrChildActivity();
1179 }
1180
1181 if (userId == UserHandle.USER_NULL) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001182 userId = UserHandle.getUserId(sourceRecord.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001183 }
1184
1185 // TODO: Switch to user app stacks here.
1186 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001187 return getActivityStartController().obtainStarter(intent, "startActivityAsCaller")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001188 .setCallingUid(targetUid)
1189 .setCallingPackage(targetPackage)
1190 .setResolvedType(resolvedType)
1191 .setResultTo(resultTo)
1192 .setResultWho(resultWho)
1193 .setRequestCode(requestCode)
1194 .setStartFlags(startFlags)
1195 .setActivityOptions(bOptions)
1196 .setMayWait(userId)
1197 .setIgnoreTargetSecurity(ignoreTargetSecurity)
1198 .setFilterCallingUid(isResolver ? 0 /* system */ : targetUid)
1199 .execute();
1200 } catch (SecurityException e) {
1201 // XXX need to figure out how to propagate to original app.
1202 // A SecurityException here is generally actually a fault of the original
1203 // calling activity (such as a fairly granting permissions), so propagate it
1204 // back to them.
1205 /*
1206 StringBuilder msg = new StringBuilder();
1207 msg.append("While launching");
1208 msg.append(intent.toString());
1209 msg.append(": ");
1210 msg.append(e.getMessage());
1211 */
1212 throw e;
1213 }
1214 }
1215
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001216 int handleIncomingUser(int callingPid, int callingUid, int userId, String name) {
1217 return mAmInternal.handleIncomingUser(callingPid, callingUid, userId, false /* allowAll */,
1218 ALLOW_FULL_ONLY, name, null /* callerPackage */);
1219 }
1220
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001221 @Override
1222 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
1223 Intent intent, String resolvedType, IVoiceInteractionSession session,
1224 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
1225 Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001226 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001227 if (session == null || interactor == null) {
1228 throw new NullPointerException("null session or interactor");
1229 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001230 userId = handleIncomingUser(callingPid, callingUid, userId, "startVoiceActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001231 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001232 return getActivityStartController().obtainStarter(intent, "startVoiceActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001233 .setCallingUid(callingUid)
1234 .setCallingPackage(callingPackage)
1235 .setResolvedType(resolvedType)
1236 .setVoiceSession(session)
1237 .setVoiceInteractor(interactor)
1238 .setStartFlags(startFlags)
1239 .setProfilerInfo(profilerInfo)
1240 .setActivityOptions(bOptions)
1241 .setMayWait(userId)
1242 .execute();
1243 }
1244
1245 @Override
1246 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
1247 Intent intent, String resolvedType, Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001248 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
1249 userId = handleIncomingUser(callingPid, callingUid, userId, "startAssistantActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001250
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001251 return getActivityStartController().obtainStarter(intent, "startAssistantActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001252 .setCallingUid(callingUid)
1253 .setCallingPackage(callingPackage)
1254 .setResolvedType(resolvedType)
1255 .setActivityOptions(bOptions)
1256 .setMayWait(userId)
1257 .execute();
1258 }
1259
1260 @Override
1261 public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
1262 IRecentsAnimationRunner recentsAnimationRunner) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001263 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001264 final int callingPid = Binder.getCallingPid();
1265 final long origId = Binder.clearCallingIdentity();
1266 try {
1267 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07001268 final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
1269 final int recentsUid = mRecentTasks.getRecentsComponentUid();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001270
1271 // Start a new recents animation
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001272 final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
1273 getActivityStartController(), mWindowManager, callingPid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001274 anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
1275 recentsUid, assistDataReceiver);
1276 }
1277 } finally {
1278 Binder.restoreCallingIdentity(origId);
1279 }
1280 }
1281
1282 @Override
1283 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001284 enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001285 "startActivityFromRecents()");
1286
1287 final int callingPid = Binder.getCallingPid();
1288 final int callingUid = Binder.getCallingUid();
1289 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(bOptions);
1290 final long origId = Binder.clearCallingIdentity();
1291 try {
1292 synchronized (mGlobalLock) {
1293 return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
1294 safeOptions);
1295 }
1296 } finally {
1297 Binder.restoreCallingIdentity(origId);
1298 }
1299 }
1300
1301 /**
1302 * This is the internal entry point for handling Activity.finish().
1303 *
1304 * @param token The Binder token referencing the Activity we want to finish.
1305 * @param resultCode Result code, if any, from this Activity.
1306 * @param resultData Result data (Intent), if any, from this Activity.
1307 * @param finishTask Whether to finish the task associated with this Activity.
1308 *
1309 * @return Returns true if the activity successfully finished, or false if it is still running.
1310 */
1311 @Override
1312 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
1313 int finishTask) {
1314 // Refuse possible leaked file descriptors
1315 if (resultData != null && resultData.hasFileDescriptors()) {
1316 throw new IllegalArgumentException("File descriptors passed in Intent");
1317 }
1318
1319 synchronized (mGlobalLock) {
1320 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1321 if (r == null) {
1322 return true;
1323 }
1324 // Keep track of the root activity of the task before we finish it
1325 TaskRecord tr = r.getTask();
1326 ActivityRecord rootR = tr.getRootActivity();
1327 if (rootR == null) {
1328 Slog.w(TAG, "Finishing task with all activities already finished");
1329 }
1330 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
1331 // finish.
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001332 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001333 return false;
1334 }
1335
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001336 // TODO: There is a dup. of this block of code in ActivityStack.navigateUpToLocked
1337 // We should consolidate.
1338 if (mController != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001339 // Find the first activity that is not finishing.
1340 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
1341 if (next != null) {
1342 // ask watcher if this is allowed
1343 boolean resumeOK = true;
1344 try {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001345 resumeOK = mController.activityResuming(next.packageName);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001346 } catch (RemoteException e) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001347 mController = null;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001348 Watchdog.getInstance().setActivityController(null);
1349 }
1350
1351 if (!resumeOK) {
1352 Slog.i(TAG, "Not finishing activity because controller resumed");
1353 return false;
1354 }
1355 }
1356 }
1357 final long origId = Binder.clearCallingIdentity();
1358 try {
1359 boolean res;
1360 final boolean finishWithRootActivity =
1361 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
1362 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
1363 || (finishWithRootActivity && r == rootR)) {
1364 // If requested, remove the task that is associated to this activity only if it
1365 // was the root activity in the task. The result code and data is ignored
1366 // because we don't support returning them across task boundaries. Also, to
1367 // keep backwards compatibility we remove the task from recents when finishing
1368 // task with root activity.
1369 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
1370 finishWithRootActivity, "finish-activity");
1371 if (!res) {
1372 Slog.i(TAG, "Removing task failed to finish activity");
1373 }
Garfield Tan2746ab52018-07-25 12:33:01 -07001374 // Explicitly dismissing the activity so reset its relaunch flag.
Wale Ogunwale64258362018-10-16 15:13:37 -07001375 r.mRelaunchReason = RELAUNCH_REASON_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001376 } else {
1377 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
1378 resultData, "app-request", true);
1379 if (!res) {
1380 Slog.i(TAG, "Failed to finish by app-request");
1381 }
1382 }
1383 return res;
1384 } finally {
1385 Binder.restoreCallingIdentity(origId);
1386 }
1387 }
1388 }
1389
1390 @Override
1391 public boolean finishActivityAffinity(IBinder token) {
1392 synchronized (mGlobalLock) {
1393 final long origId = Binder.clearCallingIdentity();
1394 try {
1395 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1396 if (r == null) {
1397 return false;
1398 }
1399
1400 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
1401 // can finish.
1402 final TaskRecord task = r.getTask();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001403 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001404 return false;
1405 }
1406 return task.getStack().finishActivityAffinityLocked(r);
1407 } finally {
1408 Binder.restoreCallingIdentity(origId);
1409 }
1410 }
1411 }
1412
1413 @Override
1414 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
1415 final long origId = Binder.clearCallingIdentity();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001416 try {
1417 WindowProcessController proc = null;
1418 synchronized (mGlobalLock) {
1419 ActivityStack stack = ActivityRecord.getStackLocked(token);
1420 if (stack == null) {
1421 return;
1422 }
1423 final ActivityRecord r = mStackSupervisor.activityIdleInternalLocked(token,
1424 false /* fromTimeout */, false /* processPausingActivities */, config);
1425 if (r != null) {
1426 proc = r.app;
1427 }
1428 if (stopProfiling && proc != null) {
1429 proc.clearProfilerIfNeeded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001430 }
1431 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001432 } finally {
1433 Binder.restoreCallingIdentity(origId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001434 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001435 }
1436
1437 @Override
1438 public final void activityResumed(IBinder token) {
1439 final long origId = Binder.clearCallingIdentity();
1440 synchronized (mGlobalLock) {
1441 ActivityRecord.activityResumedLocked(token);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001442 mWindowManager.notifyAppResumedFinished(token);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001443 }
1444 Binder.restoreCallingIdentity(origId);
1445 }
1446
1447 @Override
1448 public final void activityPaused(IBinder token) {
1449 final long origId = Binder.clearCallingIdentity();
1450 synchronized (mGlobalLock) {
1451 ActivityStack stack = ActivityRecord.getStackLocked(token);
1452 if (stack != null) {
1453 stack.activityPausedLocked(token, false);
1454 }
1455 }
1456 Binder.restoreCallingIdentity(origId);
1457 }
1458
1459 @Override
1460 public final void activityStopped(IBinder token, Bundle icicle,
1461 PersistableBundle persistentState, CharSequence description) {
1462 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
1463
1464 // Refuse possible leaked file descriptors
1465 if (icicle != null && icicle.hasFileDescriptors()) {
1466 throw new IllegalArgumentException("File descriptors passed in Bundle");
1467 }
1468
1469 final long origId = Binder.clearCallingIdentity();
1470
1471 synchronized (mGlobalLock) {
1472 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1473 if (r != null) {
1474 r.activityStoppedLocked(icicle, persistentState, description);
1475 }
1476 }
1477
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001478 mAmInternal.trimApplications();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001479
1480 Binder.restoreCallingIdentity(origId);
1481 }
1482
1483 @Override
1484 public final void activityDestroyed(IBinder token) {
1485 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
1486 synchronized (mGlobalLock) {
1487 ActivityStack stack = ActivityRecord.getStackLocked(token);
1488 if (stack != null) {
1489 stack.activityDestroyedLocked(token, "activityDestroyed");
1490 }
1491 }
1492 }
1493
1494 @Override
1495 public final void activityRelaunched(IBinder token) {
1496 final long origId = Binder.clearCallingIdentity();
1497 synchronized (mGlobalLock) {
1498 mStackSupervisor.activityRelaunchedLocked(token);
1499 }
1500 Binder.restoreCallingIdentity(origId);
1501 }
1502
1503 public final void activitySlept(IBinder token) {
1504 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
1505
1506 final long origId = Binder.clearCallingIdentity();
1507
1508 synchronized (mGlobalLock) {
1509 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1510 if (r != null) {
1511 mStackSupervisor.activitySleptLocked(r);
1512 }
1513 }
1514
1515 Binder.restoreCallingIdentity(origId);
1516 }
1517
1518 @Override
1519 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
1520 synchronized (mGlobalLock) {
1521 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1522 if (r == null) {
1523 return;
1524 }
1525 final long origId = Binder.clearCallingIdentity();
1526 try {
1527 r.setRequestedOrientation(requestedOrientation);
1528 } finally {
1529 Binder.restoreCallingIdentity(origId);
1530 }
1531 }
1532 }
1533
1534 @Override
1535 public int getRequestedOrientation(IBinder token) {
1536 synchronized (mGlobalLock) {
1537 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1538 if (r == null) {
1539 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
1540 }
1541 return r.getRequestedOrientation();
1542 }
1543 }
1544
1545 @Override
1546 public void setImmersive(IBinder token, boolean immersive) {
1547 synchronized (mGlobalLock) {
1548 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1549 if (r == null) {
1550 throw new IllegalArgumentException();
1551 }
1552 r.immersive = immersive;
1553
1554 // update associated state if we're frontmost
Andrii Kulian52d255c2018-07-13 11:32:19 -07001555 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001556 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001557 applyUpdateLockStateLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001558 }
1559 }
1560 }
1561
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001562 void applyUpdateLockStateLocked(ActivityRecord r) {
1563 // Modifications to the UpdateLock state are done on our handler, outside
1564 // the activity manager's locks. The new state is determined based on the
1565 // state *now* of the relevant activity record. The object is passed to
1566 // the handler solely for logging detail, not to be consulted/modified.
1567 final boolean nextState = r != null && r.immersive;
1568 mH.post(() -> {
1569 if (mUpdateLock.isHeld() != nextState) {
1570 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1571 "Applying new update lock state '" + nextState + "' for " + r);
1572 if (nextState) {
1573 mUpdateLock.acquire();
1574 } else {
1575 mUpdateLock.release();
1576 }
1577 }
1578 });
1579 }
1580
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001581 @Override
1582 public boolean isImmersive(IBinder token) {
1583 synchronized (mGlobalLock) {
1584 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1585 if (r == null) {
1586 throw new IllegalArgumentException();
1587 }
1588 return r.immersive;
1589 }
1590 }
1591
1592 @Override
1593 public boolean isTopActivityImmersive() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001594 enforceNotIsolatedCaller("isTopActivityImmersive");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001595 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001596 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001597 return (r != null) ? r.immersive : false;
1598 }
1599 }
1600
1601 @Override
1602 public void overridePendingTransition(IBinder token, String packageName,
1603 int enterAnim, int exitAnim) {
1604 synchronized (mGlobalLock) {
1605 ActivityRecord self = ActivityRecord.isInStackLocked(token);
1606 if (self == null) {
1607 return;
1608 }
1609
1610 final long origId = Binder.clearCallingIdentity();
1611
1612 if (self.isState(
1613 ActivityStack.ActivityState.RESUMED, ActivityStack.ActivityState.PAUSING)) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001614 mWindowManager.overridePendingAppTransition(packageName,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001615 enterAnim, exitAnim, null);
1616 }
1617
1618 Binder.restoreCallingIdentity(origId);
1619 }
1620 }
1621
1622 @Override
1623 public int getFrontActivityScreenCompatMode() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001624 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001625 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001626 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001627 if (r == null) {
1628 return ActivityManager.COMPAT_MODE_UNKNOWN;
1629 }
Wale Ogunwale53783742018-09-16 10:21:51 -07001630 return mCompatModePackages.computeCompatModeLocked(r.info.applicationInfo);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001631 }
1632 }
1633
1634 @Override
1635 public void setFrontActivityScreenCompatMode(int mode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001636 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001637 "setFrontActivityScreenCompatMode");
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001638 ApplicationInfo ai;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001639 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001640 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001641 if (r == null) {
1642 Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity");
1643 return;
1644 }
1645 ai = r.info.applicationInfo;
Wale Ogunwale53783742018-09-16 10:21:51 -07001646 mCompatModePackages.setPackageScreenCompatModeLocked(ai, mode);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001647 }
1648 }
1649
1650 @Override
1651 public int getLaunchedFromUid(IBinder activityToken) {
1652 ActivityRecord srec;
1653 synchronized (mGlobalLock) {
1654 srec = ActivityRecord.forTokenLocked(activityToken);
1655 }
1656 if (srec == null) {
1657 return -1;
1658 }
1659 return srec.launchedFromUid;
1660 }
1661
1662 @Override
1663 public String getLaunchedFromPackage(IBinder activityToken) {
1664 ActivityRecord srec;
1665 synchronized (mGlobalLock) {
1666 srec = ActivityRecord.forTokenLocked(activityToken);
1667 }
1668 if (srec == null) {
1669 return null;
1670 }
1671 return srec.launchedFromPackage;
1672 }
1673
1674 @Override
1675 public boolean convertFromTranslucent(IBinder token) {
1676 final long origId = Binder.clearCallingIdentity();
1677 try {
1678 synchronized (mGlobalLock) {
1679 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1680 if (r == null) {
1681 return false;
1682 }
1683 final boolean translucentChanged = r.changeWindowTranslucency(true);
1684 if (translucentChanged) {
1685 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
1686 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001687 mWindowManager.setAppFullscreen(token, true);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001688 return translucentChanged;
1689 }
1690 } finally {
1691 Binder.restoreCallingIdentity(origId);
1692 }
1693 }
1694
1695 @Override
1696 public boolean convertToTranslucent(IBinder token, Bundle options) {
1697 SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
1698 final long origId = Binder.clearCallingIdentity();
1699 try {
1700 synchronized (mGlobalLock) {
1701 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1702 if (r == null) {
1703 return false;
1704 }
1705 final TaskRecord task = r.getTask();
1706 int index = task.mActivities.lastIndexOf(r);
1707 if (index > 0) {
1708 ActivityRecord under = task.mActivities.get(index - 1);
1709 under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
1710 }
1711 final boolean translucentChanged = r.changeWindowTranslucency(false);
1712 if (translucentChanged) {
1713 r.getStack().convertActivityToTranslucent(r);
1714 }
1715 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001716 mWindowManager.setAppFullscreen(token, false);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001717 return translucentChanged;
1718 }
1719 } finally {
1720 Binder.restoreCallingIdentity(origId);
1721 }
1722 }
1723
1724 @Override
1725 public void notifyActivityDrawn(IBinder token) {
1726 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
1727 synchronized (mGlobalLock) {
1728 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
1729 if (r != null) {
1730 r.getStack().notifyActivityDrawnLocked(r);
1731 }
1732 }
1733 }
1734
1735 @Override
1736 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
1737 synchronized (mGlobalLock) {
1738 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1739 if (r == null) {
1740 return;
1741 }
1742 r.reportFullyDrawnLocked(restoredFromBundle);
1743 }
1744 }
1745
1746 @Override
1747 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
1748 synchronized (mGlobalLock) {
1749 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
1750 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
1751 return stack.mDisplayId;
1752 }
1753 return DEFAULT_DISPLAY;
1754 }
1755 }
1756
1757 @Override
1758 public ActivityManager.StackInfo getFocusedStackInfo() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001759 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001760 long ident = Binder.clearCallingIdentity();
1761 try {
1762 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001763 ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001764 if (focusedStack != null) {
1765 return mStackSupervisor.getStackInfo(focusedStack.mStackId);
1766 }
1767 return null;
1768 }
1769 } finally {
1770 Binder.restoreCallingIdentity(ident);
1771 }
1772 }
1773
1774 @Override
1775 public void setFocusedStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001776 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001777 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
1778 final long callingId = Binder.clearCallingIdentity();
1779 try {
1780 synchronized (mGlobalLock) {
1781 final ActivityStack stack = mStackSupervisor.getStack(stackId);
1782 if (stack == null) {
1783 Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
1784 return;
1785 }
1786 final ActivityRecord r = stack.topRunningActivityLocked();
Louis Chang19443452018-10-09 12:10:21 +08001787 if (r != null && r.moveFocusableActivityToTop("setFocusedStack")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08001788 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001789 }
1790 }
1791 } finally {
1792 Binder.restoreCallingIdentity(callingId);
1793 }
1794 }
1795
1796 @Override
1797 public void setFocusedTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001798 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001799 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
1800 final long callingId = Binder.clearCallingIdentity();
1801 try {
1802 synchronized (mGlobalLock) {
1803 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1804 if (task == null) {
1805 return;
1806 }
1807 final ActivityRecord r = task.topRunningActivityLocked();
Louis Chang19443452018-10-09 12:10:21 +08001808 if (r != null && r.moveFocusableActivityToTop("setFocusedTask")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08001809 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001810 }
1811 }
1812 } finally {
1813 Binder.restoreCallingIdentity(callingId);
1814 }
1815 }
1816
1817 @Override
1818 public boolean removeTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001819 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001820 synchronized (mGlobalLock) {
1821 final long ident = Binder.clearCallingIdentity();
1822 try {
1823 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
1824 "remove-task");
1825 } finally {
1826 Binder.restoreCallingIdentity(ident);
1827 }
1828 }
1829 }
1830
1831 @Override
Winson Chunge6439102018-07-30 15:48:01 -07001832 public void removeAllVisibleRecentTasks() {
1833 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeAllVisibleRecentTasks()");
1834 synchronized (mGlobalLock) {
1835 final long ident = Binder.clearCallingIdentity();
1836 try {
1837 getRecentTasks().removeAllVisibleTasks();
1838 } finally {
1839 Binder.restoreCallingIdentity(ident);
1840 }
1841 }
1842 }
1843
1844 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001845 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
1846 synchronized (mGlobalLock) {
1847 final ActivityRecord srec = ActivityRecord.forTokenLocked(token);
1848 if (srec != null) {
1849 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
1850 }
1851 }
1852 return false;
1853 }
1854
1855 @Override
1856 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
1857 Intent resultData) {
1858
1859 synchronized (mGlobalLock) {
1860 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
1861 if (r != null) {
1862 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
1863 }
1864 return false;
1865 }
1866 }
1867
1868 /**
1869 * Attempts to move a task backwards in z-order (the order of activities within the task is
1870 * unchanged).
1871 *
1872 * There are several possible results of this call:
1873 * - if the task is locked, then we will show the lock toast
1874 * - if there is a task behind the provided task, then that task is made visible and resumed as
1875 * this task is moved to the back
1876 * - otherwise, if there are no other tasks in the stack:
1877 * - if this task is in the pinned stack, then we remove the stack completely, which will
1878 * have the effect of moving the task to the top or bottom of the fullscreen stack
1879 * (depending on whether it is visible)
1880 * - otherwise, we simply return home and hide this task
1881 *
1882 * @param token A reference to the activity we wish to move
1883 * @param nonRoot If false then this only works if the activity is the root
1884 * of a task; if true it will work for any activity in a task.
1885 * @return Returns true if the move completed, false if not.
1886 */
1887 @Override
1888 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001889 enforceNotIsolatedCaller("moveActivityTaskToBack");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001890 synchronized (mGlobalLock) {
1891 final long origId = Binder.clearCallingIdentity();
1892 try {
1893 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
1894 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1895 if (task != null) {
1896 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
1897 }
1898 } finally {
1899 Binder.restoreCallingIdentity(origId);
1900 }
1901 }
1902 return false;
1903 }
1904
1905 @Override
1906 public Rect getTaskBounds(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001907 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001908 long ident = Binder.clearCallingIdentity();
1909 Rect rect = new Rect();
1910 try {
1911 synchronized (mGlobalLock) {
1912 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
1913 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1914 if (task == null) {
1915 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
1916 return rect;
1917 }
1918 if (task.getStack() != null) {
1919 // Return the bounds from window manager since it will be adjusted for various
1920 // things like the presense of a docked stack for tasks that aren't resizeable.
1921 task.getWindowContainerBounds(rect);
1922 } else {
1923 // Task isn't in window manager yet since it isn't associated with a stack.
1924 // Return the persist value from activity manager
1925 if (!task.matchParentBounds()) {
1926 rect.set(task.getBounds());
1927 } else if (task.mLastNonFullscreenBounds != null) {
1928 rect.set(task.mLastNonFullscreenBounds);
1929 }
1930 }
1931 }
1932 } finally {
1933 Binder.restoreCallingIdentity(ident);
1934 }
1935 return rect;
1936 }
1937
1938 @Override
1939 public ActivityManager.TaskDescription getTaskDescription(int id) {
1940 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001941 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001942 MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
1943 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
1944 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1945 if (tr != null) {
1946 return tr.lastTaskDescription;
1947 }
1948 }
1949 return null;
1950 }
1951
1952 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001953 public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
1954 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
1955 setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
1956 toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
1957 return;
1958 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001959 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001960 synchronized (mGlobalLock) {
1961 final long ident = Binder.clearCallingIdentity();
1962 try {
1963 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1964 if (task == null) {
1965 Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
1966 return;
1967 }
1968
1969 if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
1970 + " to windowingMode=" + windowingMode + " toTop=" + toTop);
1971
1972 if (!task.isActivityTypeStandardOrUndefined()) {
1973 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
1974 + " non-standard task " + taskId + " to windowing mode="
1975 + windowingMode);
1976 }
1977
1978 final ActivityStack stack = task.getStack();
1979 if (toTop) {
1980 stack.moveToFront("setTaskWindowingMode", task);
1981 }
1982 stack.setWindowingMode(windowingMode);
1983 } finally {
1984 Binder.restoreCallingIdentity(ident);
1985 }
1986 }
1987 }
1988
1989 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001990 public String getCallingPackage(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001991 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001992 ActivityRecord r = getCallingRecordLocked(token);
1993 return r != null ? r.info.packageName : null;
1994 }
1995 }
1996
1997 @Override
1998 public ComponentName getCallingActivity(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.intent.getComponent() : null;
2002 }
2003 }
2004
2005 private ActivityRecord getCallingRecordLocked(IBinder token) {
2006 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2007 if (r == null) {
2008 return null;
2009 }
2010 return r.resultTo;
2011 }
2012
2013 @Override
2014 public void unhandledBack() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002015 mAmInternal.enforceCallingPermission(android.Manifest.permission.FORCE_BACK, "unhandledBack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002016
2017 synchronized (mGlobalLock) {
2018 final long origId = Binder.clearCallingIdentity();
2019 try {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002020 getTopDisplayFocusedStack().unhandledBackLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002021 } finally {
2022 Binder.restoreCallingIdentity(origId);
2023 }
2024 }
2025 }
2026
2027 /**
2028 * TODO: Add mController hook
2029 */
2030 @Override
2031 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002032 mAmInternal.enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002033
2034 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
2035 synchronized (mGlobalLock) {
2036 moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
2037 false /* fromRecents */);
2038 }
2039 }
2040
2041 void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
2042 boolean fromRecents) {
2043
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002044 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002045 Binder.getCallingUid(), -1, -1, "Task to front")) {
2046 SafeActivityOptions.abort(options);
2047 return;
2048 }
2049 final long origId = Binder.clearCallingIdentity();
2050 try {
2051 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2052 if (task == null) {
2053 Slog.d(TAG, "Could not find task for id: "+ taskId);
Winson Chungd0243682018-09-25 18:11:54 -07002054 SafeActivityOptions.abort(options);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002055 return;
2056 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002057 if (getLockTaskController().isLockTaskModeViolation(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002058 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
Winson Chungd0243682018-09-25 18:11:54 -07002059 SafeActivityOptions.abort(options);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002060 return;
2061 }
2062 ActivityOptions realOptions = options != null
2063 ? options.getOptions(mStackSupervisor)
2064 : null;
2065 mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
2066 false /* forceNonResizable */);
2067
2068 final ActivityRecord topActivity = task.getTopActivity();
2069 if (topActivity != null) {
2070
2071 // We are reshowing a task, use a starting window to hide the initial draw delay
2072 // so the transition can start earlier.
2073 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
2074 true /* taskSwitch */, fromRecents);
2075 }
2076 } finally {
2077 Binder.restoreCallingIdentity(origId);
2078 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002079 }
2080
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002081 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
2082 int callingPid, int callingUid, String name) {
2083 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
2084 return true;
2085 }
2086
2087 if (getRecentTasks().isCallerRecents(sourceUid)) {
2088 return true;
2089 }
2090
2091 int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
2092 if (perm == PackageManager.PERMISSION_GRANTED) {
2093 return true;
2094 }
2095 if (checkAllowAppSwitchUid(sourceUid)) {
2096 return true;
2097 }
2098
2099 // If the actual IPC caller is different from the logical source, then
2100 // also see if they are allowed to control app switches.
2101 if (callingUid != -1 && callingUid != sourceUid) {
2102 perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
2103 if (perm == PackageManager.PERMISSION_GRANTED) {
2104 return true;
2105 }
2106 if (checkAllowAppSwitchUid(callingUid)) {
2107 return true;
2108 }
2109 }
2110
2111 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
2112 return false;
2113 }
2114
2115 private boolean checkAllowAppSwitchUid(int uid) {
2116 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
2117 if (types != null) {
2118 for (int i = types.size() - 1; i >= 0; i--) {
2119 if (types.valueAt(i).intValue() == uid) {
2120 return true;
2121 }
2122 }
2123 }
2124 return false;
2125 }
2126
2127 @Override
2128 public void setActivityController(IActivityController controller, boolean imAMonkey) {
2129 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
2130 "setActivityController()");
2131 synchronized (mGlobalLock) {
2132 mController = controller;
2133 mControllerIsAMonkey = imAMonkey;
2134 Watchdog.getInstance().setActivityController(controller);
2135 }
2136 }
2137
2138 boolean isControllerAMonkey() {
2139 synchronized (mGlobalLock) {
2140 return mController != null && mControllerIsAMonkey;
2141 }
2142 }
2143
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002144 @Override
2145 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
2146 synchronized (mGlobalLock) {
2147 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
2148 }
2149 }
2150
2151 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002152 public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum) {
2153 return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
2154 }
2155
2156 @Override
2157 public List<ActivityManager.RunningTaskInfo> getFilteredTasks(int maxNum,
2158 @WindowConfiguration.ActivityType int ignoreActivityType,
2159 @WindowConfiguration.WindowingMode int ignoreWindowingMode) {
2160 final int callingUid = Binder.getCallingUid();
2161 ArrayList<ActivityManager.RunningTaskInfo> list = new ArrayList<>();
2162
2163 synchronized (mGlobalLock) {
2164 if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
2165
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002166 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002167 callingUid);
2168 mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
2169 ignoreWindowingMode, callingUid, allowed);
2170 }
2171
2172 return list;
2173 }
2174
2175 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002176 public final void finishSubActivity(IBinder token, String resultWho, int requestCode) {
2177 synchronized (mGlobalLock) {
2178 final long origId = Binder.clearCallingIdentity();
2179 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2180 if (r != null) {
2181 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
2182 }
2183 Binder.restoreCallingIdentity(origId);
2184 }
2185 }
2186
2187 @Override
2188 public boolean willActivityBeVisible(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002189 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002190 ActivityStack stack = ActivityRecord.getStackLocked(token);
2191 if (stack != null) {
2192 return stack.willActivityBeVisibleLocked(token);
2193 }
2194 return false;
2195 }
2196 }
2197
2198 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002199 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002200 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002201 synchronized (mGlobalLock) {
2202 final long ident = Binder.clearCallingIdentity();
2203 try {
2204 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2205 if (task == null) {
2206 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
2207 return;
2208 }
2209
2210 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
2211 + " to stackId=" + stackId + " toTop=" + toTop);
2212
2213 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2214 if (stack == null) {
2215 throw new IllegalStateException(
2216 "moveTaskToStack: No stack for stackId=" + stackId);
2217 }
2218 if (!stack.isActivityTypeStandardOrUndefined()) {
2219 throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
2220 + taskId + " to stack " + stackId);
2221 }
2222 if (stack.inSplitScreenPrimaryWindowingMode()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002223 mWindowManager.setDockedStackCreateState(
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002224 SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
2225 }
2226 task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
2227 "moveTaskToStack");
2228 } finally {
2229 Binder.restoreCallingIdentity(ident);
2230 }
2231 }
2232 }
2233
2234 @Override
2235 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
2236 boolean preserveWindows, boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002237 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002238
2239 final long ident = Binder.clearCallingIdentity();
2240 try {
2241 synchronized (mGlobalLock) {
2242 if (animate) {
2243 final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
2244 if (stack == null) {
2245 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2246 return;
2247 }
2248 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
2249 throw new IllegalArgumentException("Stack: " + stackId
2250 + " doesn't support animated resize.");
2251 }
2252 stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
2253 animationDuration, false /* fromFullscreen */);
2254 } else {
2255 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2256 if (stack == null) {
2257 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2258 return;
2259 }
2260 mStackSupervisor.resizeStackLocked(stack, destBounds,
2261 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
2262 preserveWindows, allowResizeInDockedMode, !DEFER_RESUME);
2263 }
2264 }
2265 } finally {
2266 Binder.restoreCallingIdentity(ident);
2267 }
2268 }
2269
2270 /**
2271 * Moves the specified task to the primary-split-screen stack.
2272 *
2273 * @param taskId Id of task to move.
2274 * @param createMode The mode the primary split screen stack should be created in if it doesn't
2275 * exist already. See
2276 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
2277 * and
2278 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
2279 * @param toTop If the task and stack should be moved to the top.
2280 * @param animate Whether we should play an animation for the moving the task.
2281 * @param initialBounds If the primary stack gets created, it will use these bounds for the
2282 * stack. Pass {@code null} to use default bounds.
2283 * @param showRecents If the recents activity should be shown on the other side of the task
2284 * going into split-screen mode.
2285 */
2286 @Override
2287 public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode,
2288 boolean toTop, boolean animate, Rect initialBounds, boolean showRecents) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002289 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002290 "setTaskWindowingModeSplitScreenPrimary()");
2291 synchronized (mGlobalLock) {
2292 final long ident = Binder.clearCallingIdentity();
2293 try {
2294 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2295 if (task == null) {
2296 Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
2297 return false;
2298 }
2299 if (DEBUG_STACK) Slog.d(TAG_STACK,
2300 "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
2301 + " to createMode=" + createMode + " toTop=" + toTop);
2302 if (!task.isActivityTypeStandardOrUndefined()) {
2303 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
2304 + " non-standard task " + taskId + " to split-screen windowing mode");
2305 }
2306
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002307 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002308 final int windowingMode = task.getWindowingMode();
2309 final ActivityStack stack = task.getStack();
2310 if (toTop) {
2311 stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
2312 }
2313 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
2314 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */);
2315 return windowingMode != task.getWindowingMode();
2316 } finally {
2317 Binder.restoreCallingIdentity(ident);
2318 }
2319 }
2320 }
2321
2322 /**
2323 * Removes stacks in the input windowing modes from the system if they are of activity type
2324 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
2325 */
2326 @Override
2327 public void removeStacksInWindowingModes(int[] windowingModes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002328 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002329 "removeStacksInWindowingModes()");
2330
2331 synchronized (mGlobalLock) {
2332 final long ident = Binder.clearCallingIdentity();
2333 try {
2334 mStackSupervisor.removeStacksInWindowingModes(windowingModes);
2335 } finally {
2336 Binder.restoreCallingIdentity(ident);
2337 }
2338 }
2339 }
2340
2341 @Override
2342 public void removeStacksWithActivityTypes(int[] activityTypes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002343 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002344 "removeStacksWithActivityTypes()");
2345
2346 synchronized (mGlobalLock) {
2347 final long ident = Binder.clearCallingIdentity();
2348 try {
2349 mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
2350 } finally {
2351 Binder.restoreCallingIdentity(ident);
2352 }
2353 }
2354 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002355
2356 @Override
2357 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
2358 int userId) {
2359 final int callingUid = Binder.getCallingUid();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002360 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, "getRecentTasks");
2361 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002362 callingUid);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002363 final boolean detailed = checkGetTasksPermission(
2364 android.Manifest.permission.GET_DETAILED_TASKS, Binder.getCallingPid(),
2365 UserHandle.getAppId(callingUid))
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002366 == PackageManager.PERMISSION_GRANTED;
2367
2368 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002369 return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002370 callingUid);
2371 }
2372 }
2373
2374 @Override
2375 public List<ActivityManager.StackInfo> getAllStackInfos() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002376 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002377 long ident = Binder.clearCallingIdentity();
2378 try {
2379 synchronized (mGlobalLock) {
2380 return mStackSupervisor.getAllStackInfosLocked();
2381 }
2382 } finally {
2383 Binder.restoreCallingIdentity(ident);
2384 }
2385 }
2386
2387 @Override
2388 public ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002389 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002390 long ident = Binder.clearCallingIdentity();
2391 try {
2392 synchronized (mGlobalLock) {
2393 return mStackSupervisor.getStackInfo(windowingMode, activityType);
2394 }
2395 } finally {
2396 Binder.restoreCallingIdentity(ident);
2397 }
2398 }
2399
2400 @Override
2401 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002402 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002403 final long callingUid = Binder.getCallingUid();
2404 final long origId = Binder.clearCallingIdentity();
2405 try {
2406 synchronized (mGlobalLock) {
2407 // Cancel the recents animation synchronously (do not hold the WM lock)
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002408 mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002409 ? REORDER_MOVE_TO_ORIGINAL_POSITION
2410 : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
2411 }
2412 } finally {
2413 Binder.restoreCallingIdentity(origId);
2414 }
2415 }
2416
2417 @Override
2418 public void startLockTaskModeByToken(IBinder token) {
2419 synchronized (mGlobalLock) {
2420 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2421 if (r == null) {
2422 return;
2423 }
2424 startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
2425 }
2426 }
2427
2428 @Override
2429 public void startSystemLockTaskMode(int taskId) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002430 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002431 // This makes inner call to look as if it was initiated by system.
2432 long ident = Binder.clearCallingIdentity();
2433 try {
2434 synchronized (mGlobalLock) {
2435 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2436
2437 // When starting lock task mode the stack must be in front and focused
2438 task.getStack().moveToFront("startSystemLockTaskMode");
2439 startLockTaskModeLocked(task, true /* isSystemCaller */);
2440 }
2441 } finally {
2442 Binder.restoreCallingIdentity(ident);
2443 }
2444 }
2445
2446 @Override
2447 public void stopLockTaskModeByToken(IBinder token) {
2448 synchronized (mGlobalLock) {
2449 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2450 if (r == null) {
2451 return;
2452 }
2453 stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
2454 }
2455 }
2456
2457 /**
2458 * This API should be called by SystemUI only when user perform certain action to dismiss
2459 * lock task mode. We should only dismiss pinned lock task mode in this case.
2460 */
2461 @Override
2462 public void stopSystemLockTaskMode() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002463 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002464 stopLockTaskModeInternal(null, true /* isSystemCaller */);
2465 }
2466
2467 private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
2468 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
2469 if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
2470 return;
2471 }
2472
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002473 final ActivityStack stack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002474 if (stack == null || task != stack.topTask()) {
2475 throw new IllegalArgumentException("Invalid task, not in foreground");
2476 }
2477
2478 // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
2479 // system or a specific app.
2480 // * System-initiated requests will only start the pinned mode (screen pinning)
2481 // * App-initiated requests
2482 // - will put the device in fully locked mode (LockTask), if the app is whitelisted
2483 // - will start the pinned mode, otherwise
2484 final int callingUid = Binder.getCallingUid();
2485 long ident = Binder.clearCallingIdentity();
2486 try {
2487 // When a task is locked, dismiss the pinned stack if it exists
2488 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2489
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002490 getLockTaskController().startLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002491 } finally {
2492 Binder.restoreCallingIdentity(ident);
2493 }
2494 }
2495
2496 private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
2497 final int callingUid = Binder.getCallingUid();
2498 long ident = Binder.clearCallingIdentity();
2499 try {
2500 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002501 getLockTaskController().stopLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002502 }
2503 // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
2504 // task and jumping straight into a call in the case of emergency call back.
2505 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
2506 if (tm != null) {
2507 tm.showInCallScreen(false);
2508 }
2509 } finally {
2510 Binder.restoreCallingIdentity(ident);
2511 }
2512 }
2513
2514 @Override
2515 public boolean isInLockTaskMode() {
2516 return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
2517 }
2518
2519 @Override
2520 public int getLockTaskModeState() {
2521 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002522 return getLockTaskController().getLockTaskModeState();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002523 }
2524 }
2525
2526 @Override
2527 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
2528 synchronized (mGlobalLock) {
2529 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2530 if (r != null) {
2531 r.setTaskDescription(td);
2532 final TaskRecord task = r.getTask();
2533 task.updateTaskDescription();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002534 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002535 }
2536 }
2537 }
2538
2539 @Override
2540 public Bundle getActivityOptions(IBinder token) {
2541 final long origId = Binder.clearCallingIdentity();
2542 try {
2543 synchronized (mGlobalLock) {
2544 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
2545 if (r != null) {
2546 final ActivityOptions activityOptions = r.takeOptionsLocked();
2547 return activityOptions == null ? null : activityOptions.toBundle();
2548 }
2549 return null;
2550 }
2551 } finally {
2552 Binder.restoreCallingIdentity(origId);
2553 }
2554 }
2555
2556 @Override
2557 public List<IBinder> getAppTasks(String callingPackage) {
2558 int callingUid = Binder.getCallingUid();
2559 long ident = Binder.clearCallingIdentity();
2560 try {
2561 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002562 return mRecentTasks.getAppTasksList(callingUid, callingPackage);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002563 }
2564 } finally {
2565 Binder.restoreCallingIdentity(ident);
2566 }
2567 }
2568
2569 @Override
2570 public void finishVoiceTask(IVoiceInteractionSession session) {
2571 synchronized (mGlobalLock) {
2572 final long origId = Binder.clearCallingIdentity();
2573 try {
2574 // TODO: VI Consider treating local voice interactions and voice tasks
2575 // differently here
2576 mStackSupervisor.finishVoiceTask(session);
2577 } finally {
2578 Binder.restoreCallingIdentity(origId);
2579 }
2580 }
2581
2582 }
2583
2584 @Override
2585 public boolean isTopOfTask(IBinder token) {
2586 synchronized (mGlobalLock) {
2587 ActivityRecord r = ActivityRecord.isInStackLocked(token);
Riddle Hsu66b74a82018-07-26 00:20:12 +08002588 return r != null && r.getTask().getTopActivity() == r;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002589 }
2590 }
2591
2592 @Override
2593 public void notifyLaunchTaskBehindComplete(IBinder token) {
2594 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
2595 }
2596
2597 @Override
2598 public void notifyEnterAnimationComplete(IBinder token) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002599 mH.post(() -> {
2600 synchronized (mGlobalLock) {
2601 ActivityRecord r = ActivityRecord.forTokenLocked(token);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002602 if (r != null && r.attachedToProcess()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002603 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002604 r.app.getThread().scheduleEnterAnimationComplete(r.appToken);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002605 } catch (RemoteException e) {
2606 }
2607 }
2608 }
2609
2610 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002611 }
2612
2613 /** Called from an app when assist data is ready. */
2614 @Override
2615 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
2616 AssistContent content, Uri referrer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002617 PendingAssistExtras pae = (PendingAssistExtras) token;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002618 synchronized (pae) {
2619 pae.result = extras;
2620 pae.structure = structure;
2621 pae.content = content;
2622 if (referrer != null) {
2623 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
2624 }
2625 if (structure != null) {
2626 structure.setHomeActivity(pae.isHome);
2627 }
2628 pae.haveResult = true;
2629 pae.notifyAll();
2630 if (pae.intent == null && pae.receiver == null) {
2631 // Caller is just waiting for the result.
2632 return;
2633 }
2634 }
2635 // We are now ready to launch the assist activity.
2636 IAssistDataReceiver sendReceiver = null;
2637 Bundle sendBundle = null;
2638 synchronized (mGlobalLock) {
2639 buildAssistBundleLocked(pae, extras);
2640 boolean exists = mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002641 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002642 if (!exists) {
2643 // Timed out.
2644 return;
2645 }
2646
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002647 if ((sendReceiver = pae.receiver) != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002648 // Caller wants result sent back to them.
2649 sendBundle = new Bundle();
2650 sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
2651 sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
2652 sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
2653 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
2654 }
2655 }
2656 if (sendReceiver != null) {
2657 try {
2658 sendReceiver.onHandleAssistData(sendBundle);
2659 } catch (RemoteException e) {
2660 }
2661 return;
2662 }
2663
2664 final long ident = Binder.clearCallingIdentity();
2665 try {
2666 if (TextUtils.equals(pae.intent.getAction(),
2667 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
2668 pae.intent.putExtras(pae.extras);
2669 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
2670 } else {
2671 pae.intent.replaceExtras(pae.extras);
2672 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
2673 | Intent.FLAG_ACTIVITY_SINGLE_TOP
2674 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Wale Ogunwale31913b52018-10-13 08:29:31 -07002675 mInternal.closeSystemDialogs("assist");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002676
2677 try {
2678 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
2679 } catch (ActivityNotFoundException e) {
2680 Slog.w(TAG, "No activity to handle assist action.", e);
2681 }
2682 }
2683 } finally {
2684 Binder.restoreCallingIdentity(ident);
2685 }
2686 }
2687
2688 @Override
2689 public int addAppTask(IBinder activityToken, Intent intent,
2690 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
2691 final int callingUid = Binder.getCallingUid();
2692 final long callingIdent = Binder.clearCallingIdentity();
2693
2694 try {
2695 synchronized (mGlobalLock) {
2696 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
2697 if (r == null) {
2698 throw new IllegalArgumentException("Activity does not exist; token="
2699 + activityToken);
2700 }
2701 ComponentName comp = intent.getComponent();
2702 if (comp == null) {
2703 throw new IllegalArgumentException("Intent " + intent
2704 + " must specify explicit component");
2705 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002706 if (thumbnail.getWidth() != mThumbnailWidth
2707 || thumbnail.getHeight() != mThumbnailHeight) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002708 throw new IllegalArgumentException("Bad thumbnail size: got "
2709 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002710 + mThumbnailWidth + "x" + mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002711 }
2712 if (intent.getSelector() != null) {
2713 intent.setSelector(null);
2714 }
2715 if (intent.getSourceBounds() != null) {
2716 intent.setSourceBounds(null);
2717 }
2718 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
2719 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
2720 // The caller has added this as an auto-remove task... that makes no
2721 // sense, so turn off auto-remove.
2722 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
2723 }
2724 }
2725 final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
2726 STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
2727 if (ainfo.applicationInfo.uid != callingUid) {
2728 throw new SecurityException(
2729 "Can't add task for another application: target uid="
2730 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
2731 }
2732
2733 final ActivityStack stack = r.getStack();
2734 final TaskRecord task = stack.createTaskRecord(
2735 mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent,
2736 null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002737 if (!mRecentTasks.addToBottom(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002738 // The app has too many tasks already and we can't add any more
2739 stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
2740 return INVALID_TASK_ID;
2741 }
2742 task.lastTaskDescription.copyFrom(description);
2743
2744 // TODO: Send the thumbnail to WM to store it.
2745
2746 return task.taskId;
2747 }
2748 } finally {
2749 Binder.restoreCallingIdentity(callingIdent);
2750 }
2751 }
2752
2753 @Override
2754 public Point getAppTaskThumbnailSize() {
2755 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002756 return new Point(mThumbnailWidth, mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002757 }
2758 }
2759
2760 @Override
2761 public void setTaskResizeable(int taskId, int resizeableMode) {
2762 synchronized (mGlobalLock) {
2763 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
2764 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
2765 if (task == null) {
2766 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
2767 return;
2768 }
2769 task.setResizeMode(resizeableMode);
2770 }
2771 }
2772
2773 @Override
2774 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002775 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002776 long ident = Binder.clearCallingIdentity();
2777 try {
2778 synchronized (mGlobalLock) {
2779 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2780 if (task == null) {
2781 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
2782 return;
2783 }
2784 // Place the task in the right stack if it isn't there already based on
2785 // the requested bounds.
2786 // The stack transition logic is:
2787 // - a null bounds on a freeform task moves that task to fullscreen
2788 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
2789 // that task to freeform
2790 // - otherwise the task is not moved
2791 ActivityStack stack = task.getStack();
2792 if (!task.getWindowConfiguration().canResizeTask()) {
2793 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
2794 }
2795 if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
2796 stack = stack.getDisplay().getOrCreateStack(
2797 WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
2798 } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
2799 stack = stack.getDisplay().getOrCreateStack(
2800 WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
2801 }
2802
2803 // Reparent the task to the right stack if necessary
2804 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
2805 if (stack != task.getStack()) {
2806 // Defer resume until the task is resized below
2807 task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
2808 DEFER_RESUME, "resizeTask");
2809 preserveWindow = false;
2810 }
2811
2812 // After reparenting (which only resizes the task to the stack bounds), resize the
2813 // task to the actual bounds provided
2814 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
2815 }
2816 } finally {
2817 Binder.restoreCallingIdentity(ident);
2818 }
2819 }
2820
2821 @Override
2822 public boolean releaseActivityInstance(IBinder token) {
2823 synchronized (mGlobalLock) {
2824 final long origId = Binder.clearCallingIdentity();
2825 try {
2826 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2827 if (r == null) {
2828 return false;
2829 }
2830 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
2831 } finally {
2832 Binder.restoreCallingIdentity(origId);
2833 }
2834 }
2835 }
2836
2837 @Override
2838 public void releaseSomeActivities(IApplicationThread appInt) {
2839 synchronized (mGlobalLock) {
2840 final long origId = Binder.clearCallingIdentity();
2841 try {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07002842 final WindowProcessController app = getProcessController(appInt);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002843 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
2844 } finally {
2845 Binder.restoreCallingIdentity(origId);
2846 }
2847 }
2848 }
2849
2850 @Override
2851 public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
2852 int secondaryDisplayShowing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002853 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002854 != PackageManager.PERMISSION_GRANTED) {
2855 throw new SecurityException("Requires permission "
2856 + android.Manifest.permission.DEVICE_POWER);
2857 }
2858
2859 synchronized (mGlobalLock) {
2860 long ident = Binder.clearCallingIdentity();
2861 if (mKeyguardShown != keyguardShowing) {
2862 mKeyguardShown = keyguardShowing;
Wale Ogunwale342fbe92018-10-09 08:44:10 -07002863 final Message msg = PooledLambda.obtainMessage(
2864 ActivityManagerInternal::reportCurKeyguardUsageEvent, mAmInternal,
2865 keyguardShowing);
2866 mH.sendMessage(msg);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002867 }
2868 try {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002869 mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002870 secondaryDisplayShowing);
2871 } finally {
2872 Binder.restoreCallingIdentity(ident);
2873 }
2874 }
2875
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002876 mH.post(() -> {
2877 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2878 mScreenObservers.get(i).onKeyguardStateChanged(keyguardShowing);
2879 }
2880 });
2881 }
2882
2883 void onScreenAwakeChanged(boolean isAwake) {
2884 mH.post(() -> {
2885 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2886 mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2887 }
2888 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002889 }
2890
2891 @Override
2892 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002893 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
2894 userId, "getTaskDescriptionIcon");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002895
2896 final File passedIconFile = new File(filePath);
2897 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
2898 passedIconFile.getName());
2899 if (!legitIconFile.getPath().equals(filePath)
2900 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
2901 throw new IllegalArgumentException("Bad file path: " + filePath
2902 + " passed for userId " + userId);
2903 }
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002904 return mRecentTasks.getTaskDescriptionIcon(filePath);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002905 }
2906
2907 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002908 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002909 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
2910 final ActivityOptions activityOptions = safeOptions != null
2911 ? safeOptions.getOptions(mStackSupervisor)
2912 : null;
2913 if (activityOptions == null
2914 || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
2915 || activityOptions.getCustomInPlaceResId() == 0) {
2916 throw new IllegalArgumentException("Expected in-place ActivityOption " +
2917 "with valid animation");
2918 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002919 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
2920 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002921 activityOptions.getCustomInPlaceResId());
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002922 mWindowManager.executeAppTransition();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002923 }
2924
2925 @Override
2926 public void removeStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002927 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002928 synchronized (mGlobalLock) {
2929 final long ident = Binder.clearCallingIdentity();
2930 try {
2931 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2932 if (stack == null) {
2933 Slog.w(TAG, "removeStack: No stack with id=" + stackId);
2934 return;
2935 }
2936 if (!stack.isActivityTypeStandardOrUndefined()) {
2937 throw new IllegalArgumentException(
2938 "Removing non-standard stack is not allowed.");
2939 }
2940 mStackSupervisor.removeStack(stack);
2941 } finally {
2942 Binder.restoreCallingIdentity(ident);
2943 }
2944 }
2945 }
2946
2947 @Override
2948 public void moveStackToDisplay(int stackId, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002949 mAmInternal.enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002950
2951 synchronized (mGlobalLock) {
2952 final long ident = Binder.clearCallingIdentity();
2953 try {
2954 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
2955 + " to displayId=" + displayId);
2956 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
2957 } finally {
2958 Binder.restoreCallingIdentity(ident);
2959 }
2960 }
2961 }
2962
2963 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002964 public void exitFreeformMode(IBinder token) {
2965 synchronized (mGlobalLock) {
2966 long ident = Binder.clearCallingIdentity();
2967 try {
2968 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2969 if (r == null) {
2970 throw new IllegalArgumentException(
2971 "exitFreeformMode: No activity record matching token=" + token);
2972 }
2973
2974 final ActivityStack stack = r.getStack();
2975 if (stack == null || !stack.inFreeformWindowingMode()) {
2976 throw new IllegalStateException(
2977 "exitFreeformMode: You can only go fullscreen from freeform.");
2978 }
2979
2980 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
2981 } finally {
2982 Binder.restoreCallingIdentity(ident);
2983 }
2984 }
2985 }
2986
2987 /** Sets the task stack listener that gets callbacks when a task stack changes. */
2988 @Override
2989 public void registerTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002990 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002991 "registerTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002992 mTaskChangeNotificationController.registerTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002993 }
2994
2995 /** Unregister a task stack listener so that it stops receiving callbacks. */
2996 @Override
2997 public void unregisterTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002998 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002999 "unregisterTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003000 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003001 }
3002
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003003 @Override
3004 public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
3005 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
3006 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
3007 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
3008 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
3009 }
3010
3011 @Override
3012 public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
3013 IBinder activityToken, int flags) {
3014 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
3015 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
3016 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
3017 }
3018
3019 @Override
3020 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
3021 Bundle args) {
3022 return enqueueAssistContext(requestType, intent, hint, null, null, null,
3023 true /* focused */, true /* newSessionId */, userHandle, args,
3024 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
3025 }
3026
3027 @Override
3028 public Bundle getAssistContextExtras(int requestType) {
3029 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
3030 null, null, true /* focused */, true /* newSessionId */,
3031 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
3032 if (pae == null) {
3033 return null;
3034 }
3035 synchronized (pae) {
3036 while (!pae.haveResult) {
3037 try {
3038 pae.wait();
3039 } catch (InterruptedException e) {
3040 }
3041 }
3042 }
3043 synchronized (mGlobalLock) {
3044 buildAssistBundleLocked(pae, pae.result);
3045 mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003046 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003047 }
3048 return pae.extras;
3049 }
3050
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003051 /**
3052 * Binder IPC calls go through the public entry point.
3053 * This can be called with or without the global lock held.
3054 */
3055 private static int checkCallingPermission(String permission) {
3056 return checkPermission(
3057 permission, Binder.getCallingPid(), UserHandle.getAppId(Binder.getCallingUid()));
3058 }
3059
3060 /** This can be called with or without the global lock held. */
Wale Ogunwale214f3482018-10-04 11:00:47 -07003061 private void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003062 if (!getRecentTasks().isCallerRecents(Binder.getCallingUid())) {
3063 mAmInternal.enforceCallingPermission(permission, func);
3064 }
3065 }
3066
3067 @VisibleForTesting
3068 int checkGetTasksPermission(String permission, int pid, int uid) {
3069 return checkPermission(permission, pid, uid);
3070 }
3071
3072 static int checkPermission(String permission, int pid, int uid) {
3073 if (permission == null) {
3074 return PackageManager.PERMISSION_DENIED;
3075 }
3076 return checkComponentPermission(permission, pid, uid, -1, true);
3077 }
3078
Wale Ogunwale214f3482018-10-04 11:00:47 -07003079 public static int checkComponentPermission(String permission, int pid, int uid,
3080 int owningUid, boolean exported) {
3081 return ActivityManagerService.checkComponentPermission(
3082 permission, pid, uid, owningUid, exported);
3083 }
3084
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003085 boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
3086 if (getRecentTasks().isCallerRecents(callingUid)) {
3087 // Always allow the recents component to get tasks
3088 return true;
3089 }
3090
3091 boolean allowed = checkGetTasksPermission(android.Manifest.permission.REAL_GET_TASKS,
3092 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
3093 if (!allowed) {
3094 if (checkGetTasksPermission(android.Manifest.permission.GET_TASKS,
3095 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
3096 // Temporary compatibility: some existing apps on the system image may
3097 // still be requesting the old permission and not switched to the new
3098 // one; if so, we'll still allow them full access. This means we need
3099 // to see if they are holding the old permission and are a system app.
3100 try {
3101 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
3102 allowed = true;
3103 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
3104 + " is using old GET_TASKS but privileged; allowing");
3105 }
3106 } catch (RemoteException e) {
3107 }
3108 }
3109 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
3110 + " does not hold REAL_GET_TASKS; limiting output");
3111 }
3112 return allowed;
3113 }
3114
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003115 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
3116 IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
3117 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
3118 int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003119 mAmInternal.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003120 "enqueueAssistContext()");
3121
3122 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003123 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003124 if (activity == null) {
3125 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
3126 return null;
3127 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003128 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003129 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
3130 return null;
3131 }
3132 if (focused) {
3133 if (activityToken != null) {
3134 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
3135 if (activity != caller) {
3136 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
3137 + " is not current top " + activity);
3138 return null;
3139 }
3140 }
3141 } else {
3142 activity = ActivityRecord.forTokenLocked(activityToken);
3143 if (activity == null) {
3144 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
3145 + " couldn't be found");
3146 return null;
3147 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003148 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003149 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
3150 return null;
3151 }
3152 }
3153
3154 PendingAssistExtras pae;
3155 Bundle extras = new Bundle();
3156 if (args != null) {
3157 extras.putAll(args);
3158 }
3159 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003160 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003161
3162 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
3163 userHandle);
3164 pae.isHome = activity.isActivityTypeHome();
3165
3166 // Increment the sessionId if necessary
3167 if (newSessionId) {
3168 mViSessionId++;
3169 }
3170 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003171 activity.app.getThread().requestAssistContextExtras(activity.appToken, pae,
3172 requestType, mViSessionId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003173 mPendingAssistExtras.add(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003174 mUiHandler.postDelayed(pae, timeout);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003175 } catch (RemoteException e) {
3176 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
3177 return null;
3178 }
3179 return pae;
3180 }
3181 }
3182
3183 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
3184 if (result != null) {
3185 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
3186 }
3187 if (pae.hint != null) {
3188 pae.extras.putBoolean(pae.hint, true);
3189 }
3190 }
3191
3192 private void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
3193 IAssistDataReceiver receiver;
3194 synchronized (mGlobalLock) {
3195 mPendingAssistExtras.remove(pae);
3196 receiver = pae.receiver;
3197 }
3198 if (receiver != null) {
3199 // Caller wants result sent back to them.
3200 Bundle sendBundle = new Bundle();
3201 // At least return the receiver extras
3202 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
3203 try {
3204 pae.receiver.onHandleAssistData(sendBundle);
3205 } catch (RemoteException e) {
3206 }
3207 }
3208 }
3209
3210 public class PendingAssistExtras extends Binder implements Runnable {
3211 public final ActivityRecord activity;
3212 public boolean isHome;
3213 public final Bundle extras;
3214 public final Intent intent;
3215 public final String hint;
3216 public final IAssistDataReceiver receiver;
3217 public final int userHandle;
3218 public boolean haveResult = false;
3219 public Bundle result = null;
3220 public AssistStructure structure = null;
3221 public AssistContent content = null;
3222 public Bundle receiverExtras;
3223
3224 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
3225 String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
3226 int _userHandle) {
3227 activity = _activity;
3228 extras = _extras;
3229 intent = _intent;
3230 hint = _hint;
3231 receiver = _receiver;
3232 receiverExtras = _receiverExtras;
3233 userHandle = _userHandle;
3234 }
3235
3236 @Override
3237 public void run() {
3238 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
3239 synchronized (this) {
3240 haveResult = true;
3241 notifyAll();
3242 }
3243 pendingAssistExtrasTimedOut(this);
3244 }
3245 }
3246
3247 @Override
3248 public boolean isAssistDataAllowedOnCurrentActivity() {
3249 int userId;
3250 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003251 final ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003252 if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
3253 return false;
3254 }
3255
3256 final ActivityRecord activity = focusedStack.getTopActivity();
3257 if (activity == null) {
3258 return false;
3259 }
3260 userId = activity.userId;
3261 }
3262 return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
3263 }
3264
3265 @Override
3266 public boolean showAssistFromActivity(IBinder token, Bundle args) {
3267 long ident = Binder.clearCallingIdentity();
3268 try {
3269 synchronized (mGlobalLock) {
3270 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003271 ActivityRecord top = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003272 if (top != caller) {
3273 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3274 + " is not current top " + top);
3275 return false;
3276 }
3277 if (!top.nowVisible) {
3278 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3279 + " is not visible");
3280 return false;
3281 }
3282 }
3283 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
3284 token);
3285 } finally {
3286 Binder.restoreCallingIdentity(ident);
3287 }
3288 }
3289
3290 @Override
3291 public boolean isRootVoiceInteraction(IBinder token) {
3292 synchronized (mGlobalLock) {
3293 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3294 if (r == null) {
3295 return false;
3296 }
3297 return r.rootVoiceInteraction;
3298 }
3299 }
3300
Wale Ogunwalef6733932018-06-27 05:14:34 -07003301 private void onLocalVoiceInteractionStartedLocked(IBinder activity,
3302 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
3303 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
3304 if (activityToCallback == null) return;
3305 activityToCallback.setVoiceSessionLocked(voiceSession);
3306
3307 // Inform the activity
3308 try {
3309 activityToCallback.app.getThread().scheduleLocalVoiceInteractionStarted(activity,
3310 voiceInteractor);
3311 long token = Binder.clearCallingIdentity();
3312 try {
3313 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
3314 } finally {
3315 Binder.restoreCallingIdentity(token);
3316 }
3317 // TODO: VI Should we cache the activity so that it's easier to find later
3318 // rather than scan through all the stacks and activities?
3319 } catch (RemoteException re) {
3320 activityToCallback.clearVoiceSessionLocked();
3321 // TODO: VI Should this terminate the voice session?
3322 }
3323 }
3324
3325 private void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
3326 Slog.d(TAG, "<<< startRunningVoiceLocked()");
3327 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
3328 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
3329 boolean wasRunningVoice = mRunningVoice != null;
3330 mRunningVoice = session;
3331 if (!wasRunningVoice) {
3332 mVoiceWakeLock.acquire();
3333 updateSleepIfNeededLocked();
3334 }
3335 }
3336 }
3337
3338 void finishRunningVoiceLocked() {
3339 if (mRunningVoice != null) {
3340 mRunningVoice = null;
3341 mVoiceWakeLock.release();
3342 updateSleepIfNeededLocked();
3343 }
3344 }
3345
3346 @Override
3347 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3348 synchronized (mGlobalLock) {
3349 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3350 if (keepAwake) {
3351 mVoiceWakeLock.acquire();
3352 } else {
3353 mVoiceWakeLock.release();
3354 }
3355 }
3356 }
3357 }
3358
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003359 @Override
3360 public ComponentName getActivityClassForToken(IBinder token) {
3361 synchronized (mGlobalLock) {
3362 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3363 if (r == null) {
3364 return null;
3365 }
3366 return r.intent.getComponent();
3367 }
3368 }
3369
3370 @Override
3371 public String getPackageForToken(IBinder token) {
3372 synchronized (mGlobalLock) {
3373 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3374 if (r == null) {
3375 return null;
3376 }
3377 return r.packageName;
3378 }
3379 }
3380
3381 @Override
3382 public void showLockTaskEscapeMessage(IBinder token) {
3383 synchronized (mGlobalLock) {
3384 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3385 if (r == null) {
3386 return;
3387 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003388 getLockTaskController().showLockTaskToast();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003389 }
3390 }
3391
3392 @Override
3393 public void keyguardGoingAway(int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003394 enforceNotIsolatedCaller("keyguardGoingAway");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003395 final long token = Binder.clearCallingIdentity();
3396 try {
3397 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003398 mKeyguardController.keyguardGoingAway(flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003399 }
3400 } finally {
3401 Binder.restoreCallingIdentity(token);
3402 }
3403 }
3404
3405 /**
3406 * Try to place task to provided position. The final position might be different depending on
3407 * current user and stacks state. The task will be moved to target stack if it's currently in
3408 * different stack.
3409 */
3410 @Override
3411 public void positionTaskInStack(int taskId, int stackId, int position) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003412 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003413 synchronized (mGlobalLock) {
3414 long ident = Binder.clearCallingIdentity();
3415 try {
3416 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
3417 + taskId + " in stackId=" + stackId + " at position=" + position);
3418 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3419 if (task == null) {
3420 throw new IllegalArgumentException("positionTaskInStack: no task for id="
3421 + taskId);
3422 }
3423
3424 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3425
3426 if (stack == null) {
3427 throw new IllegalArgumentException("positionTaskInStack: no stack for id="
3428 + stackId);
3429 }
3430 if (!stack.isActivityTypeStandardOrUndefined()) {
3431 throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
3432 + " the position of task " + taskId + " in/to non-standard stack");
3433 }
3434
3435 // TODO: Have the callers of this API call a separate reparent method if that is
3436 // what they intended to do vs. having this method also do reparenting.
3437 if (task.getStack() == stack) {
3438 // Change position in current stack.
3439 stack.positionChildAt(task, position);
3440 } else {
3441 // Reparent to new stack.
3442 task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
3443 !DEFER_RESUME, "positionTaskInStack");
3444 }
3445 } finally {
3446 Binder.restoreCallingIdentity(ident);
3447 }
3448 }
3449 }
3450
3451 @Override
3452 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
3453 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
3454 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
3455 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
3456 synchronized (mGlobalLock) {
3457 ActivityRecord record = ActivityRecord.isInStackLocked(token);
3458 if (record == null) {
3459 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
3460 + "found for: " + token);
3461 }
3462 record.setSizeConfigurations(horizontalSizeConfiguration,
3463 verticalSizeConfigurations, smallestSizeConfigurations);
3464 }
3465 }
3466
3467 /**
3468 * Dismisses split-screen multi-window mode.
3469 * @param toTop If true the current primary split-screen stack will be placed or left on top.
3470 */
3471 @Override
3472 public void dismissSplitScreenMode(boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003473 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003474 MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
3475 final long ident = Binder.clearCallingIdentity();
3476 try {
3477 synchronized (mGlobalLock) {
3478 final ActivityStack stack =
3479 mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
3480 if (stack == null) {
3481 Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
3482 return;
3483 }
3484
3485 if (toTop) {
3486 // Caller wants the current split-screen primary stack to be the top stack after
3487 // it goes fullscreen, so move it to the front.
3488 stack.moveToFront("dismissSplitScreenMode");
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003489 } else if (mStackSupervisor.isTopDisplayFocusedStack(stack)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003490 // In this case the current split-screen primary stack shouldn't be the top
3491 // stack after it goes fullscreen, but it current has focus, so we move the
3492 // focus to the top-most split-screen secondary stack next to it.
3493 final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
3494 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
3495 if (otherStack != null) {
3496 otherStack.moveToFront("dismissSplitScreenMode_other");
3497 }
3498 }
3499
Evan Rosky10475742018-09-05 19:02:48 -07003500 stack.setWindowingMode(WINDOWING_MODE_UNDEFINED);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003501 }
3502 } finally {
3503 Binder.restoreCallingIdentity(ident);
3504 }
3505 }
3506
3507 /**
3508 * Dismisses Pip
3509 * @param animate True if the dismissal should be animated.
3510 * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
3511 * default animation duration should be used.
3512 */
3513 @Override
3514 public void dismissPip(boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003515 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003516 final long ident = Binder.clearCallingIdentity();
3517 try {
3518 synchronized (mGlobalLock) {
3519 final PinnedActivityStack stack =
3520 mStackSupervisor.getDefaultDisplay().getPinnedStack();
3521 if (stack == null) {
3522 Slog.w(TAG, "dismissPip: pinned stack not found.");
3523 return;
3524 }
3525 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
3526 throw new IllegalArgumentException("Stack: " + stack
3527 + " doesn't support animated resize.");
3528 }
3529 if (animate) {
3530 stack.animateResizePinnedStack(null /* sourceHintBounds */,
3531 null /* destBounds */, animationDuration, false /* fromFullscreen */);
3532 } else {
3533 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
3534 }
3535 }
3536 } finally {
3537 Binder.restoreCallingIdentity(ident);
3538 }
3539 }
3540
3541 @Override
3542 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003543 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003544 synchronized (mGlobalLock) {
3545 mSuppressResizeConfigChanges = suppress;
3546 }
3547 }
3548
3549 /**
3550 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
3551 * animated the stack to the fullscreen, but can also be called if we are relaunching an
3552 * activity and clearing the task at the same time.
3553 */
3554 @Override
3555 // TODO: API should just be about changing windowing modes...
3556 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003557 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003558 "moveTasksToFullscreenStack()");
3559 synchronized (mGlobalLock) {
3560 final long origId = Binder.clearCallingIdentity();
3561 try {
3562 final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
3563 if (stack != null){
3564 if (!stack.isActivityTypeStandardOrUndefined()) {
3565 throw new IllegalArgumentException(
3566 "You can't move tasks from non-standard stacks.");
3567 }
3568 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
3569 }
3570 } finally {
3571 Binder.restoreCallingIdentity(origId);
3572 }
3573 }
3574 }
3575
3576 /**
3577 * Moves the top activity in the input stackId to the pinned stack.
3578 *
3579 * @param stackId Id of stack to move the top activity to pinned stack.
3580 * @param bounds Bounds to use for pinned stack.
3581 *
3582 * @return True if the top activity of the input stack was successfully moved to the pinned
3583 * stack.
3584 */
3585 @Override
3586 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003587 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003588 "moveTopActivityToPinnedStack()");
3589 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003590 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003591 throw new IllegalStateException("moveTopActivityToPinnedStack:"
3592 + "Device doesn't support picture-in-picture mode");
3593 }
3594
3595 long ident = Binder.clearCallingIdentity();
3596 try {
3597 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
3598 } finally {
3599 Binder.restoreCallingIdentity(ident);
3600 }
3601 }
3602 }
3603
3604 @Override
3605 public boolean isInMultiWindowMode(IBinder token) {
3606 final long origId = Binder.clearCallingIdentity();
3607 try {
3608 synchronized (mGlobalLock) {
3609 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3610 if (r == null) {
3611 return false;
3612 }
3613 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
3614 return r.inMultiWindowMode();
3615 }
3616 } finally {
3617 Binder.restoreCallingIdentity(origId);
3618 }
3619 }
3620
3621 @Override
3622 public boolean isInPictureInPictureMode(IBinder token) {
3623 final long origId = Binder.clearCallingIdentity();
3624 try {
3625 synchronized (mGlobalLock) {
3626 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
3627 }
3628 } finally {
3629 Binder.restoreCallingIdentity(origId);
3630 }
3631 }
3632
3633 private boolean isInPictureInPictureMode(ActivityRecord r) {
3634 if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
3635 || r.getStack().isInStackLocked(r) == null) {
3636 return false;
3637 }
3638
3639 // If we are animating to fullscreen then we have already dispatched the PIP mode
3640 // changed, so we should reflect that check here as well.
3641 final PinnedActivityStack stack = r.getStack();
3642 final PinnedStackWindowController windowController = stack.getWindowContainerController();
3643 return !windowController.isAnimatingBoundsToFullscreen();
3644 }
3645
3646 @Override
3647 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
3648 final long origId = Binder.clearCallingIdentity();
3649 try {
3650 synchronized (mGlobalLock) {
3651 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3652 "enterPictureInPictureMode", token, params);
3653
3654 // If the activity is already in picture in picture mode, then just return early
3655 if (isInPictureInPictureMode(r)) {
3656 return true;
3657 }
3658
3659 // Activity supports picture-in-picture, now check that we can enter PiP at this
3660 // point, if it is
3661 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
3662 false /* beforeStopping */)) {
3663 return false;
3664 }
3665
3666 final Runnable enterPipRunnable = () -> {
Wale Ogunwalef276a6f2018-06-15 08:26:07 -07003667 synchronized (mGlobalLock) {
3668 // Only update the saved args from the args that are set
3669 r.pictureInPictureArgs.copyOnlySet(params);
3670 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
3671 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
3672 // Adjust the source bounds by the insets for the transition down
3673 final Rect sourceBounds = new Rect(
3674 r.pictureInPictureArgs.getSourceRectHint());
3675 mStackSupervisor.moveActivityToPinnedStackLocked(
3676 r, sourceBounds, aspectRatio, "enterPictureInPictureMode");
3677 final PinnedActivityStack stack = r.getStack();
3678 stack.setPictureInPictureAspectRatio(aspectRatio);
3679 stack.setPictureInPictureActions(actions);
3680 MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
3681 r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
3682 logPictureInPictureArgs(params);
3683 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003684 };
3685
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003686 if (isKeyguardLocked()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003687 // If the keyguard is showing or occluded, then try and dismiss it before
3688 // entering picture-in-picture (this will prompt the user to authenticate if the
3689 // device is currently locked).
3690 dismissKeyguard(token, new KeyguardDismissCallback() {
3691 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003692 public void onDismissSucceeded() {
3693 mH.post(enterPipRunnable);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003694 }
3695 }, null /* message */);
3696 } else {
3697 // Enter picture in picture immediately otherwise
3698 enterPipRunnable.run();
3699 }
3700 return true;
3701 }
3702 } finally {
3703 Binder.restoreCallingIdentity(origId);
3704 }
3705 }
3706
3707 @Override
3708 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
3709 final long origId = Binder.clearCallingIdentity();
3710 try {
3711 synchronized (mGlobalLock) {
3712 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3713 "setPictureInPictureParams", token, params);
3714
3715 // Only update the saved args from the args that are set
3716 r.pictureInPictureArgs.copyOnlySet(params);
3717 if (r.inPinnedWindowingMode()) {
3718 // If the activity is already in picture-in-picture, update the pinned stack now
3719 // if it is not already expanding to fullscreen. Otherwise, the arguments will
3720 // be used the next time the activity enters PiP
3721 final PinnedActivityStack stack = r.getStack();
3722 if (!stack.isAnimatingBoundsToFullscreen()) {
3723 stack.setPictureInPictureAspectRatio(
3724 r.pictureInPictureArgs.getAspectRatio());
3725 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
3726 }
3727 }
3728 logPictureInPictureArgs(params);
3729 }
3730 } finally {
3731 Binder.restoreCallingIdentity(origId);
3732 }
3733 }
3734
3735 @Override
3736 public int getMaxNumPictureInPictureActions(IBinder token) {
3737 // Currently, this is a static constant, but later, we may change this to be dependent on
3738 // the context of the activity
3739 return 3;
3740 }
3741
3742 private void logPictureInPictureArgs(PictureInPictureParams params) {
3743 if (params.hasSetActions()) {
3744 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
3745 params.getActions().size());
3746 }
3747 if (params.hasSetAspectRatio()) {
3748 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
3749 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
3750 MetricsLogger.action(lm);
3751 }
3752 }
3753
3754 /**
3755 * Checks the state of the system and the activity associated with the given {@param token} to
3756 * verify that picture-in-picture is supported for that activity.
3757 *
3758 * @return the activity record for the given {@param token} if all the checks pass.
3759 */
3760 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
3761 IBinder token, PictureInPictureParams params) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003762 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003763 throw new IllegalStateException(caller
3764 + ": Device doesn't support picture-in-picture mode.");
3765 }
3766
3767 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3768 if (r == null) {
3769 throw new IllegalStateException(caller
3770 + ": Can't find activity for token=" + token);
3771 }
3772
3773 if (!r.supportsPictureInPicture()) {
3774 throw new IllegalStateException(caller
3775 + ": Current activity does not support picture-in-picture.");
3776 }
3777
3778 if (params.hasSetAspectRatio()
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003779 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003780 params.getAspectRatio())) {
3781 final float minAspectRatio = mContext.getResources().getFloat(
3782 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
3783 final float maxAspectRatio = mContext.getResources().getFloat(
3784 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
3785 throw new IllegalArgumentException(String.format(caller
3786 + ": Aspect ratio is too extreme (must be between %f and %f).",
3787 minAspectRatio, maxAspectRatio));
3788 }
3789
3790 // Truncate the number of actions if necessary
3791 params.truncateActions(getMaxNumPictureInPictureActions(token));
3792
3793 return r;
3794 }
3795
3796 @Override
3797 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003798 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003799 synchronized (mGlobalLock) {
3800 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
3801 if (r == null) {
3802 throw new IllegalArgumentException("Activity does not exist; token="
3803 + activityToken);
3804 }
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07003805 return r.getUriPermissionsLocked().getExternalToken();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003806 }
3807 }
3808
3809 @Override
3810 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
3811 Rect tempDockedTaskInsetBounds,
3812 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003813 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003814 long ident = Binder.clearCallingIdentity();
3815 try {
3816 synchronized (mGlobalLock) {
3817 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
3818 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
3819 PRESERVE_WINDOWS);
3820 }
3821 } finally {
3822 Binder.restoreCallingIdentity(ident);
3823 }
3824 }
3825
3826 @Override
3827 public void setSplitScreenResizing(boolean resizing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003828 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003829 final long ident = Binder.clearCallingIdentity();
3830 try {
3831 synchronized (mGlobalLock) {
3832 mStackSupervisor.setSplitScreenResizing(resizing);
3833 }
3834 } finally {
3835 Binder.restoreCallingIdentity(ident);
3836 }
3837 }
3838
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003839 /**
3840 * Check that we have the features required for VR-related API calls, and throw an exception if
3841 * not.
3842 */
3843 void enforceSystemHasVrFeature() {
3844 if (!mContext.getPackageManager().hasSystemFeature(
3845 PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
3846 throw new UnsupportedOperationException("VR mode not supported on this device!");
3847 }
3848 }
3849
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003850 @Override
3851 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003852 enforceSystemHasVrFeature();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003853
3854 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3855
3856 ActivityRecord r;
3857 synchronized (mGlobalLock) {
3858 r = ActivityRecord.isInStackLocked(token);
3859 }
3860
3861 if (r == null) {
3862 throw new IllegalArgumentException();
3863 }
3864
3865 int err;
3866 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
3867 VrManagerInternal.NO_ERROR) {
3868 return err;
3869 }
3870
3871 // Clear the binder calling uid since this path may call moveToTask().
3872 final long callingId = Binder.clearCallingIdentity();
3873 try {
3874 synchronized (mGlobalLock) {
3875 r.requestedVrComponent = (enabled) ? packageName : null;
3876
3877 // Update associated state if this activity is currently focused
Andrii Kulian52d255c2018-07-13 11:32:19 -07003878 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003879 applyUpdateVrModeLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003880 }
3881 return 0;
3882 }
3883 } finally {
3884 Binder.restoreCallingIdentity(callingId);
3885 }
3886 }
3887
3888 @Override
3889 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
3890 Slog.i(TAG, "Activity tried to startLocalVoiceInteraction");
3891 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003892 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003893 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
3894 throw new SecurityException("Only focused activity can call startVoiceInteraction");
3895 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07003896 if (mRunningVoice != null || activity.getTask().voiceSession != null
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003897 || activity.voiceSession != null) {
3898 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
3899 return;
3900 }
3901 if (activity.pendingVoiceInteractionStart) {
3902 Slog.w(TAG, "Pending start of voice interaction already.");
3903 return;
3904 }
3905 activity.pendingVoiceInteractionStart = true;
3906 }
3907 LocalServices.getService(VoiceInteractionManagerInternal.class)
3908 .startLocalVoiceInteraction(callingActivity, options);
3909 }
3910
3911 @Override
3912 public void stopLocalVoiceInteraction(IBinder callingActivity) {
3913 LocalServices.getService(VoiceInteractionManagerInternal.class)
3914 .stopLocalVoiceInteraction(callingActivity);
3915 }
3916
3917 @Override
3918 public boolean supportsLocalVoiceInteraction() {
3919 return LocalServices.getService(VoiceInteractionManagerInternal.class)
3920 .supportsLocalVoiceInteraction();
3921 }
3922
3923 /** Notifies all listeners when the pinned stack animation starts. */
3924 @Override
3925 public void notifyPinnedStackAnimationStarted() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003926 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003927 }
3928
3929 /** Notifies all listeners when the pinned stack animation ends. */
3930 @Override
3931 public void notifyPinnedStackAnimationEnded() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003932 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003933 }
3934
3935 @Override
3936 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003937 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003938 final long ident = Binder.clearCallingIdentity();
3939 try {
3940 synchronized (mGlobalLock) {
3941 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
3942 }
3943 } finally {
3944 Binder.restoreCallingIdentity(ident);
3945 }
3946 }
3947
3948 @Override
3949 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003950 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003951
3952 synchronized (mGlobalLock) {
3953 // Check if display is initialized in AM.
3954 if (!mStackSupervisor.isDisplayAdded(displayId)) {
3955 // Call might come when display is not yet added or has already been removed.
3956 if (DEBUG_CONFIGURATION) {
3957 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
3958 + displayId);
3959 }
3960 return false;
3961 }
3962
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003963 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003964 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003965 values = mWindowManager.computeNewConfiguration(displayId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003966 }
3967
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003968 if (mWindowManager != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07003969 final Message msg = PooledLambda.obtainMessage(
3970 ActivityManagerInternal::updateOomLevelsForDisplay, mAmInternal, displayId);
3971 mH.sendMessage(msg);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003972 }
3973
3974 final long origId = Binder.clearCallingIdentity();
3975 try {
3976 if (values != null) {
3977 Settings.System.clearConfiguration(values);
3978 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003979 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003980 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
3981 return mTmpUpdateConfigurationResult.changes != 0;
3982 } finally {
3983 Binder.restoreCallingIdentity(origId);
3984 }
3985 }
3986 }
3987
3988 @Override
3989 public boolean updateConfiguration(Configuration values) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003990 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003991
3992 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003993 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003994 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003995 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003996 }
3997
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003998 if (mWindowManager != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07003999 final Message msg = PooledLambda.obtainMessage(
4000 ActivityManagerInternal::updateOomLevelsForDisplay, mAmInternal,
4001 DEFAULT_DISPLAY);
4002 mH.sendMessage(msg);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004003 }
4004
4005 final long origId = Binder.clearCallingIdentity();
4006 try {
4007 if (values != null) {
4008 Settings.System.clearConfiguration(values);
4009 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004010 updateConfigurationLocked(values, null, false, false /* persistent */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004011 UserHandle.USER_NULL, false /* deferResume */,
4012 mTmpUpdateConfigurationResult);
4013 return mTmpUpdateConfigurationResult.changes != 0;
4014 } finally {
4015 Binder.restoreCallingIdentity(origId);
4016 }
4017 }
4018 }
4019
4020 @Override
4021 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
4022 CharSequence message) {
4023 if (message != null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004024 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004025 Manifest.permission.SHOW_KEYGUARD_MESSAGE, "dismissKeyguard()");
4026 }
4027 final long callingId = Binder.clearCallingIdentity();
4028 try {
4029 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004030 mKeyguardController.dismissKeyguard(token, callback, message);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004031 }
4032 } finally {
4033 Binder.restoreCallingIdentity(callingId);
4034 }
4035 }
4036
4037 @Override
4038 public void cancelTaskWindowTransition(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004039 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004040 "cancelTaskWindowTransition()");
4041 final long ident = Binder.clearCallingIdentity();
4042 try {
4043 synchronized (mGlobalLock) {
4044 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
4045 MATCH_TASK_IN_STACKS_ONLY);
4046 if (task == null) {
4047 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
4048 return;
4049 }
4050 task.cancelWindowTransition();
4051 }
4052 } finally {
4053 Binder.restoreCallingIdentity(ident);
4054 }
4055 }
4056
4057 @Override
4058 public ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004059 enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004060 final long ident = Binder.clearCallingIdentity();
4061 try {
4062 final TaskRecord task;
4063 synchronized (mGlobalLock) {
4064 task = mStackSupervisor.anyTaskForIdLocked(taskId,
4065 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
4066 if (task == null) {
4067 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
4068 return null;
4069 }
4070 }
4071 // Don't call this while holding the lock as this operation might hit the disk.
4072 return task.getSnapshot(reducedResolution);
4073 } finally {
4074 Binder.restoreCallingIdentity(ident);
4075 }
4076 }
4077
4078 @Override
4079 public void setDisablePreviewScreenshots(IBinder token, boolean disable) {
4080 synchronized (mGlobalLock) {
4081 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4082 if (r == null) {
4083 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
4084 + token);
4085 return;
4086 }
4087 final long origId = Binder.clearCallingIdentity();
4088 try {
4089 r.setDisablePreviewScreenshots(disable);
4090 } finally {
4091 Binder.restoreCallingIdentity(origId);
4092 }
4093 }
4094 }
4095
4096 /** Return the user id of the last resumed activity. */
4097 @Override
4098 public @UserIdInt
4099 int getLastResumedActivityUserId() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004100 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004101 Manifest.permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
4102 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07004103 if (mLastResumedActivity == null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004104 return getCurrentUserId();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004105 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004106 return mLastResumedActivity.userId;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004107 }
4108 }
4109
4110 @Override
4111 public void updateLockTaskFeatures(int userId, int flags) {
4112 final int callingUid = Binder.getCallingUid();
4113 if (callingUid != 0 && callingUid != SYSTEM_UID) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004114 mAmInternal.enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004115 "updateLockTaskFeatures()");
4116 }
4117 synchronized (mGlobalLock) {
4118 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
4119 Integer.toHexString(flags));
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07004120 getLockTaskController().updateLockTaskFeatures(userId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004121 }
4122 }
4123
4124 @Override
4125 public void setShowWhenLocked(IBinder token, boolean showWhenLocked) {
4126 synchronized (mGlobalLock) {
4127 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4128 if (r == null) {
4129 return;
4130 }
4131 final long origId = Binder.clearCallingIdentity();
4132 try {
4133 r.setShowWhenLocked(showWhenLocked);
4134 } finally {
4135 Binder.restoreCallingIdentity(origId);
4136 }
4137 }
4138 }
4139
4140 @Override
4141 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) {
4142 synchronized (mGlobalLock) {
4143 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4144 if (r == null) {
4145 return;
4146 }
4147 final long origId = Binder.clearCallingIdentity();
4148 try {
4149 r.setTurnScreenOn(turnScreenOn);
4150 } finally {
4151 Binder.restoreCallingIdentity(origId);
4152 }
4153 }
4154 }
4155
4156 @Override
4157 public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004158 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004159 "registerRemoteAnimations");
4160 definition.setCallingPid(Binder.getCallingPid());
4161 synchronized (mGlobalLock) {
4162 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4163 if (r == null) {
4164 return;
4165 }
4166 final long origId = Binder.clearCallingIdentity();
4167 try {
4168 r.registerRemoteAnimations(definition);
4169 } finally {
4170 Binder.restoreCallingIdentity(origId);
4171 }
4172 }
4173 }
4174
4175 @Override
4176 public void registerRemoteAnimationForNextActivityStart(String packageName,
4177 RemoteAnimationAdapter adapter) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004178 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004179 "registerRemoteAnimationForNextActivityStart");
4180 adapter.setCallingPid(Binder.getCallingPid());
4181 synchronized (mGlobalLock) {
4182 final long origId = Binder.clearCallingIdentity();
4183 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07004184 getActivityStartController().registerRemoteAnimationForNextActivityStart(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004185 packageName, adapter);
4186 } finally {
4187 Binder.restoreCallingIdentity(origId);
4188 }
4189 }
4190 }
4191
4192 /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
4193 @Override
4194 public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
4195 synchronized (mGlobalLock) {
4196 final long origId = Binder.clearCallingIdentity();
4197 try {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004198 mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004199 } finally {
4200 Binder.restoreCallingIdentity(origId);
4201 }
4202 }
4203 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004204
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004205 @Override
4206 public void setVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004207 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004208 synchronized (mGlobalLock) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004209 final int pid = Binder.getCallingPid();
4210 final WindowProcessController wpc = mPidMap.get(pid);
4211 mVrController.setVrThreadLocked(tid, pid, wpc);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004212 }
4213 }
4214
4215 @Override
4216 public void setPersistentVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004217 if (checkCallingPermission(Manifest.permission.RESTRICTED_VR_ACCESS)
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004218 != PERMISSION_GRANTED) {
4219 final String msg = "Permission Denial: setPersistentVrThread() from pid="
4220 + Binder.getCallingPid()
4221 + ", uid=" + Binder.getCallingUid()
4222 + " requires " + Manifest.permission.RESTRICTED_VR_ACCESS;
4223 Slog.w(TAG, msg);
4224 throw new SecurityException(msg);
4225 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004226 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004227 synchronized (mGlobalLock) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004228 final int pid = Binder.getCallingPid();
4229 final WindowProcessController proc = mPidMap.get(pid);
4230 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004231 }
4232 }
4233
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004234 @Override
4235 public void stopAppSwitches() {
4236 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
4237 synchronized (mGlobalLock) {
4238 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME;
4239 mDidAppSwitch = false;
4240 getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
4241 }
4242 }
4243
4244 @Override
4245 public void resumeAppSwitches() {
4246 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
4247 synchronized (mGlobalLock) {
4248 // Note that we don't execute any pending app switches... we will
4249 // let those wait until either the timeout, or the next start
4250 // activity request.
4251 mAppSwitchesAllowedTime = 0;
4252 }
4253 }
4254
4255 void onStartActivitySetDidAppSwitch() {
4256 if (mDidAppSwitch) {
4257 // This is the second allowed switch since we stopped switches, so now just generally
4258 // allow switches. Use case:
4259 // - user presses home (switches disabled, switch to home, mDidAppSwitch now true);
4260 // - user taps a home icon (coming from home so allowed, we hit here and now allow
4261 // anyone to switch again).
4262 mAppSwitchesAllowedTime = 0;
4263 } else {
4264 mDidAppSwitch = true;
4265 }
4266 }
4267
4268 /** @return whether the system should disable UI modes incompatible with VR mode. */
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004269 boolean shouldDisableNonVrUiLocked() {
4270 return mVrController.shouldDisableNonVrUiLocked();
4271 }
4272
Wale Ogunwale53783742018-09-16 10:21:51 -07004273 private void applyUpdateVrModeLocked(ActivityRecord r) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004274 // VR apps are expected to run in a main display. If an app is turning on VR for
4275 // itself, but lives in a dynamic stack, then make sure that it is moved to the main
4276 // fullscreen stack before enabling VR Mode.
4277 // TODO: The goal of this code is to keep the VR app on the main display. When the
4278 // stack implementation changes in the future, keep in mind that the use of the fullscreen
4279 // stack is a means to move the activity to the main display and a moveActivityToDisplay()
4280 // option would be a better choice here.
4281 if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
4282 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
4283 + " to main stack for VR");
4284 final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
4285 WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
4286 moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
4287 }
4288 mH.post(() -> {
4289 if (!mVrController.onVrModeChanged(r)) {
4290 return;
4291 }
4292 synchronized (mGlobalLock) {
4293 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
4294 mWindowManager.disableNonVrUi(disableNonVrUi);
4295 if (disableNonVrUi) {
4296 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
4297 // then remove the pinned stack.
4298 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
4299 }
4300 }
4301 });
4302 }
4303
Wale Ogunwale53783742018-09-16 10:21:51 -07004304 @Override
4305 public int getPackageScreenCompatMode(String packageName) {
4306 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4307 synchronized (mGlobalLock) {
4308 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4309 }
4310 }
4311
4312 @Override
4313 public void setPackageScreenCompatMode(String packageName, int mode) {
4314 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4315 "setPackageScreenCompatMode");
4316 synchronized (mGlobalLock) {
4317 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4318 }
4319 }
4320
4321 @Override
4322 public boolean getPackageAskScreenCompat(String packageName) {
4323 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4324 synchronized (mGlobalLock) {
4325 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4326 }
4327 }
4328
4329 @Override
4330 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4331 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4332 "setPackageAskScreenCompat");
4333 synchronized (mGlobalLock) {
4334 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4335 }
4336 }
4337
Wale Ogunwale64258362018-10-16 15:13:37 -07004338 public static String relaunchReasonToString(int relaunchReason) {
4339 switch (relaunchReason) {
4340 case RELAUNCH_REASON_WINDOWING_MODE_RESIZE:
4341 return "window_resize";
4342 case RELAUNCH_REASON_FREE_RESIZE:
4343 return "free_resize";
4344 default:
4345 return null;
4346 }
4347 }
4348
Andrii Kulian5f750bc2018-07-17 08:57:23 -07004349 ActivityStack getTopDisplayFocusedStack() {
4350 return mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004351 }
4352
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004353 /** Pokes the task persister. */
4354 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
4355 mRecentTasks.notifyTaskPersisterLocked(task, flush);
4356 }
4357
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004358 void onTopProcChangedLocked(WindowProcessController proc) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004359 mVrController.onTopProcChangedLocked(proc);
4360 }
4361
4362 boolean isKeyguardLocked() {
4363 return mKeyguardController.isKeyguardLocked();
4364 }
4365
4366 boolean isNextTransitionForward() {
4367 int transit = mWindowManager.getPendingAppTransition();
4368 return transit == TRANSIT_ACTIVITY_OPEN
4369 || transit == TRANSIT_TASK_OPEN
4370 || transit == TRANSIT_TASK_TO_FRONT;
4371 }
4372
Wale Ogunwale31913b52018-10-13 08:29:31 -07004373 void dumpLastANRLocked(PrintWriter pw) {
4374 pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
4375 if (mLastANRState == null) {
4376 pw.println(" <no ANR has occurred since boot>");
4377 } else {
4378 pw.println(mLastANRState);
4379 }
4380 }
4381
4382 void dumpLastANRTracesLocked(PrintWriter pw) {
4383 pw.println("ACTIVITY MANAGER LAST ANR TRACES (dumpsys activity lastanr-traces)");
4384
4385 final File[] files = new File(ANR_TRACE_DIR).listFiles();
4386 if (ArrayUtils.isEmpty(files)) {
4387 pw.println(" <no ANR has occurred since boot>");
4388 return;
4389 }
4390 // Find the latest file.
4391 File latest = null;
4392 for (File f : files) {
4393 if ((latest == null) || (latest.lastModified() < f.lastModified())) {
4394 latest = f;
Wale Ogunwalef6733932018-06-27 05:14:34 -07004395 }
Wale Ogunwale31913b52018-10-13 08:29:31 -07004396 }
4397 pw.print("File: ");
4398 pw.print(latest.getName());
4399 pw.println();
4400 try (BufferedReader in = new BufferedReader(new FileReader(latest))) {
4401 String line;
4402 while ((line = in.readLine()) != null) {
4403 pw.println(line);
4404 }
4405 } catch (IOException e) {
4406 pw.print("Unable to read: ");
4407 pw.print(e);
4408 pw.println();
4409 }
4410 }
4411
4412 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
4413 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
4414 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
4415 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
4416 }
4417
4418 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
4419 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
4420 pw.println(header);
4421
4422 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
4423 dumpPackage);
4424 boolean needSep = printedAnything;
4425
4426 boolean printed = ActivityStackSupervisor.printThisActivity(pw,
4427 mStackSupervisor.getTopResumedActivity(), dumpPackage, needSep,
4428 " ResumedActivity: ");
4429 if (printed) {
4430 printedAnything = true;
4431 needSep = false;
4432 }
4433
4434 if (dumpPackage == null) {
4435 if (needSep) {
4436 pw.println();
4437 }
4438 printedAnything = true;
4439 mStackSupervisor.dump(pw, " ");
4440 }
4441
4442 if (!printedAnything) {
4443 pw.println(" (nothing)");
4444 }
4445 }
4446
4447 void dumpActivityContainersLocked(PrintWriter pw) {
4448 pw.println("ACTIVITY MANAGER STARTER (dumpsys activity containers)");
4449 mStackSupervisor.dumpChildrenNames(pw, " ");
4450 pw.println(" ");
4451 }
4452
4453 void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
4454 pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
4455 getActivityStartController().dump(pw, "", dumpPackage);
4456 }
4457
4458 /**
4459 * There are three things that cmd can be:
4460 * - a flattened component name that matches an existing activity
4461 * - the cmd arg isn't the flattened component name of an existing activity:
4462 * dump all activity whose component contains the cmd as a substring
4463 * - A hex number of the ActivityRecord object instance.
4464 *
4465 * @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
4466 * @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
4467 */
4468 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
4469 int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
4470 ArrayList<ActivityRecord> activities;
4471
4472 synchronized (mGlobalLock) {
4473 activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
4474 dumpFocusedStackOnly);
4475 }
4476
4477 if (activities.size() <= 0) {
4478 return false;
4479 }
4480
4481 String[] newArgs = new String[args.length - opti];
4482 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
4483
4484 TaskRecord lastTask = null;
4485 boolean needSep = false;
4486 for (int i = activities.size() - 1; i >= 0; i--) {
4487 ActivityRecord r = activities.get(i);
4488 if (needSep) {
4489 pw.println();
4490 }
4491 needSep = true;
4492 synchronized (mGlobalLock) {
4493 final TaskRecord task = r.getTask();
4494 if (lastTask != task) {
4495 lastTask = task;
4496 pw.print("TASK "); pw.print(lastTask.affinity);
4497 pw.print(" id="); pw.print(lastTask.taskId);
4498 pw.print(" userId="); pw.println(lastTask.userId);
4499 if (dumpAll) {
4500 lastTask.dump(pw, " ");
4501 }
4502 }
4503 }
4504 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
4505 }
4506 return true;
4507 }
4508
4509 /**
4510 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
4511 * there is a thread associated with the activity.
4512 */
4513 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
4514 final ActivityRecord r, String[] args, boolean dumpAll) {
4515 String innerPrefix = prefix + " ";
4516 synchronized (mGlobalLock) {
4517 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
4518 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
4519 pw.print(" pid=");
4520 if (r.hasProcess()) pw.println(r.app.getPid());
4521 else pw.println("(not running)");
4522 if (dumpAll) {
4523 r.dump(pw, innerPrefix);
4524 }
4525 }
4526 if (r.attachedToProcess()) {
4527 // flush anything that is already in the PrintWriter since the thread is going
4528 // to write to the file descriptor directly
4529 pw.flush();
4530 try {
4531 TransferPipe tp = new TransferPipe();
4532 try {
4533 r.app.getThread().dumpActivity(tp.getWriteFd(),
4534 r.appToken, innerPrefix, args);
4535 tp.go(fd);
4536 } finally {
4537 tp.kill();
4538 }
4539 } catch (IOException e) {
4540 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
4541 } catch (RemoteException e) {
4542 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
4543 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004544 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004545 }
4546
Wale Ogunwalef6733932018-06-27 05:14:34 -07004547 void writeSleepStateToProto(ProtoOutputStream proto) {
4548 for (ActivityTaskManagerInternal.SleepToken st : mStackSupervisor.mSleepTokens) {
4549 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS,
4550 st.toString());
4551 }
4552
4553 if (mRunningVoice != null) {
4554 final long vrToken = proto.start(
4555 ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
4556 proto.write(ActivityManagerServiceDumpProcessesProto.Voice.SESSION,
4557 mRunningVoice.toString());
4558 mVoiceWakeLock.writeToProto(
4559 proto, ActivityManagerServiceDumpProcessesProto.Voice.WAKELOCK);
4560 proto.end(vrToken);
4561 }
4562
4563 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
4564 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN,
4565 mShuttingDown);
4566 mVrController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004567 }
4568
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004569 int getCurrentUserId() {
4570 return mAmInternal.getCurrentUserId();
4571 }
4572
4573 private void enforceNotIsolatedCaller(String caller) {
4574 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4575 throw new SecurityException("Isolated process not allowed to call " + caller);
4576 }
4577 }
4578
Wale Ogunwalef6733932018-06-27 05:14:34 -07004579 public Configuration getConfiguration() {
4580 Configuration ci;
4581 synchronized(mGlobalLock) {
Yunfan Chen75157d72018-07-27 14:47:21 +09004582 ci = new Configuration(getGlobalConfigurationForCallingPid());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004583 ci.userSetLocale = false;
4584 }
4585 return ci;
4586 }
4587
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004588 /**
4589 * Current global configuration information. Contains general settings for the entire system,
4590 * also corresponds to the merged configuration of the default display.
4591 */
4592 Configuration getGlobalConfiguration() {
4593 return mStackSupervisor.getConfiguration();
4594 }
4595
4596 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4597 boolean initLocale) {
4598 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
4599 }
4600
4601 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4602 boolean initLocale, boolean deferResume) {
4603 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
4604 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
4605 UserHandle.USER_NULL, deferResume);
4606 }
4607
4608 void updatePersistentConfiguration(Configuration values, @UserIdInt int userId) {
4609 final long origId = Binder.clearCallingIdentity();
4610 try {
4611 synchronized (mGlobalLock) {
4612 updateConfigurationLocked(values, null, false, true, userId,
4613 false /* deferResume */);
4614 }
4615 } finally {
4616 Binder.restoreCallingIdentity(origId);
4617 }
4618 }
4619
4620 void updateUserConfiguration() {
4621 synchronized (mGlobalLock) {
4622 final Configuration configuration = new Configuration(getGlobalConfiguration());
4623 final int currentUserId = mAmInternal.getCurrentUserId();
4624 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
4625 currentUserId, Settings.System.canWrite(mContext));
4626 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
4627 false /* persistent */, currentUserId, false /* deferResume */);
4628 }
4629 }
4630
4631 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4632 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
4633 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
4634 deferResume, null /* result */);
4635 }
4636
4637 /**
4638 * Do either or both things: (1) change the current configuration, and (2)
4639 * make sure the given activity is running with the (now) current
4640 * configuration. Returns true if the activity has been left running, or
4641 * false if <var>starting</var> is being destroyed to match the new
4642 * configuration.
4643 *
4644 * @param userId is only used when persistent parameter is set to true to persist configuration
4645 * for that particular user
4646 */
4647 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4648 boolean initLocale, boolean persistent, int userId, boolean deferResume,
4649 ActivityTaskManagerService.UpdateConfigurationResult result) {
4650 int changes = 0;
4651 boolean kept = true;
4652
4653 if (mWindowManager != null) {
4654 mWindowManager.deferSurfaceLayout();
4655 }
4656 try {
4657 if (values != null) {
4658 changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
4659 deferResume);
4660 }
4661
4662 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4663 } finally {
4664 if (mWindowManager != null) {
4665 mWindowManager.continueSurfaceLayout();
4666 }
4667 }
4668
4669 if (result != null) {
4670 result.changes = changes;
4671 result.activityRelaunched = !kept;
4672 }
4673 return kept;
4674 }
4675
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004676 /** Update default (global) configuration and notify listeners about changes. */
4677 private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
4678 boolean persistent, int userId, boolean deferResume) {
4679 mTempConfig.setTo(getGlobalConfiguration());
4680 final int changes = mTempConfig.updateFrom(values);
4681 if (changes == 0) {
4682 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
4683 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
4684 // performDisplayOverrideConfigUpdate in order to send the new display configuration
4685 // (even if there are no actual changes) to unfreeze the window.
4686 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
4687 return 0;
4688 }
4689
4690 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
4691 "Updating global configuration to: " + values);
4692
4693 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
4694 StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
4695 values.colorMode,
4696 values.densityDpi,
4697 values.fontScale,
4698 values.hardKeyboardHidden,
4699 values.keyboard,
4700 values.keyboardHidden,
4701 values.mcc,
4702 values.mnc,
4703 values.navigation,
4704 values.navigationHidden,
4705 values.orientation,
4706 values.screenHeightDp,
4707 values.screenLayout,
4708 values.screenWidthDp,
4709 values.smallestScreenWidthDp,
4710 values.touchscreen,
4711 values.uiMode);
4712
4713
4714 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
4715 final LocaleList locales = values.getLocales();
4716 int bestLocaleIndex = 0;
4717 if (locales.size() > 1) {
4718 if (mSupportedSystemLocales == null) {
4719 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
4720 }
4721 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
4722 }
4723 SystemProperties.set("persist.sys.locale",
4724 locales.get(bestLocaleIndex).toLanguageTag());
4725 LocaleList.setDefault(locales, bestLocaleIndex);
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004726
4727 final Message m = PooledLambda.obtainMessage(
4728 ActivityTaskManagerService::sendLocaleToMountDaemonMsg, this,
4729 locales.get(bestLocaleIndex));
4730 mH.sendMessage(m);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004731 }
4732
Yunfan Chen75157d72018-07-27 14:47:21 +09004733 mTempConfig.seq = increaseConfigurationSeqLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004734
4735 // Update stored global config and notify everyone about the change.
4736 mStackSupervisor.onConfigurationChanged(mTempConfig);
4737
4738 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
4739 // TODO(multi-display): Update UsageEvents#Event to include displayId.
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004740 mUsageStatsInternal.reportConfigurationChange(mTempConfig, mAmInternal.getCurrentUserId());
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004741
4742 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
Wale Ogunwalef6733932018-06-27 05:14:34 -07004743 updateShouldShowDialogsLocked(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004744
4745 AttributeCache ac = AttributeCache.instance();
4746 if (ac != null) {
4747 ac.updateConfiguration(mTempConfig);
4748 }
4749
4750 // Make sure all resources in our process are updated right now, so that anyone who is going
4751 // to retrieve resource values after we return will be sure to get the new ones. This is
4752 // especially important during boot, where the first config change needs to guarantee all
4753 // resources have that config before following boot code is executed.
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004754 mSystemThread.applyConfigurationToResources(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004755
4756 // We need another copy of global config because we're scheduling some calls instead of
4757 // running them in place. We need to be sure that object we send will be handled unchanged.
4758 final Configuration configCopy = new Configuration(mTempConfig);
4759 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004760 final Message msg = PooledLambda.obtainMessage(
4761 ActivityTaskManagerService::sendPutConfigurationForUserMsg,
4762 this, userId, configCopy);
4763 mH.sendMessage(msg);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004764 }
4765
Yunfan Chen34fcc7a2018-10-11 16:26:09 -07004766 for (int i = mPidMap.size() - 1; i >= 0; i--) {
4767 WindowProcessController app = mPidMap.get(mPidMap.keyAt(i));
4768 if (DEBUG_CONFIGURATION) {
4769 Slog.v(TAG_CONFIGURATION, "Update process config of "
4770 + app.mName + " to new config " + configCopy);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004771 }
Yunfan Chen34fcc7a2018-10-11 16:26:09 -07004772 app.onConfigurationChanged(configCopy);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004773 }
4774
Wale Ogunwale2ea36d42018-10-18 10:27:31 -07004775 final Message msg = PooledLambda.obtainMessage(
4776 ActivityManagerInternal::broadcastGlobalConfigurationChanged,
4777 mAmInternal, changes, initLocale);
4778 mH.sendMessage(msg);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004779
4780 // Override configuration of the default display duplicates global config, so we need to
4781 // update it also. This will also notify WindowManager about changes.
4782 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
4783 DEFAULT_DISPLAY);
4784
4785 return changes;
4786 }
4787
4788 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
4789 boolean deferResume, int displayId) {
4790 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
4791 displayId, null /* result */);
4792 }
4793
4794 /**
4795 * Updates override configuration specific for the selected display. If no config is provided,
4796 * new one will be computed in WM based on current display info.
4797 */
4798 boolean updateDisplayOverrideConfigurationLocked(Configuration values,
4799 ActivityRecord starting, boolean deferResume, int displayId,
4800 ActivityTaskManagerService.UpdateConfigurationResult result) {
4801 int changes = 0;
4802 boolean kept = true;
4803
4804 if (mWindowManager != null) {
4805 mWindowManager.deferSurfaceLayout();
4806 }
4807 try {
4808 if (values != null) {
4809 if (displayId == DEFAULT_DISPLAY) {
4810 // Override configuration of the default display duplicates global config, so
4811 // we're calling global config update instead for default display. It will also
4812 // apply the correct override config.
4813 changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
4814 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
4815 } else {
4816 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
4817 }
4818 }
4819
4820 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4821 } finally {
4822 if (mWindowManager != null) {
4823 mWindowManager.continueSurfaceLayout();
4824 }
4825 }
4826
4827 if (result != null) {
4828 result.changes = changes;
4829 result.activityRelaunched = !kept;
4830 }
4831 return kept;
4832 }
4833
4834 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
4835 int displayId) {
4836 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
4837 final int changes = mTempConfig.updateFrom(values);
4838 if (changes != 0) {
4839 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
4840 + mTempConfig + " for displayId=" + displayId);
4841 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
4842
4843 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
4844 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004845 mAppWarnings.onDensityChanged();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004846
Wale Ogunwale5c918702018-10-18 11:06:33 -07004847 // Post message to start process to avoid possible deadlock of calling into AMS with
4848 // the ATMS lock held.
4849 final Message msg = PooledLambda.obtainMessage(
4850 ActivityManagerInternal::killAllBackgroundProcessesExcept, mAmInternal,
4851 N, ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
4852 mH.sendMessage(msg);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004853 }
4854 }
4855
4856 // Update the configuration with WM first and check if any of the stacks need to be resized
4857 // due to the configuration change. If so, resize the stacks now and do any relaunches if
4858 // necessary. This way we don't need to relaunch again afterwards in
4859 // ensureActivityConfiguration().
4860 if (mWindowManager != null) {
4861 final int[] resizedStacks =
4862 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
4863 if (resizedStacks != null) {
4864 for (int stackId : resizedStacks) {
4865 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
4866 }
4867 }
4868 }
4869
4870 return changes;
4871 }
4872
Wale Ogunwalef6733932018-06-27 05:14:34 -07004873 private void updateEventDispatchingLocked(boolean booted) {
4874 mWindowManager.setEventDispatching(booted && !mShuttingDown);
4875 }
4876
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004877 private void sendPutConfigurationForUserMsg(int userId, Configuration config) {
4878 final ContentResolver resolver = mContext.getContentResolver();
4879 Settings.System.putConfigurationForUser(resolver, config, userId);
4880 }
4881
4882 private void sendLocaleToMountDaemonMsg(Locale l) {
4883 try {
4884 IBinder service = ServiceManager.getService("mount");
4885 IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
4886 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
4887 storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
4888 } catch (RemoteException e) {
4889 Log.e(TAG, "Error storing locale for decryption UI", e);
4890 }
4891 }
4892
4893 boolean isActivityStartsLoggingEnabled() {
4894 return mAmInternal.isActivityStartsLoggingEnabled();
4895 }
4896
Wale Ogunwalef6733932018-06-27 05:14:34 -07004897 void enableScreenAfterBoot(boolean booted) {
4898 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4899 SystemClock.uptimeMillis());
4900 mWindowManager.enableScreenAfterBoot();
4901
4902 synchronized (mGlobalLock) {
4903 updateEventDispatchingLocked(booted);
4904 }
4905 }
4906
4907 boolean canShowErrorDialogs() {
4908 return mShowDialogs && !mSleeping && !mShuttingDown
4909 && !mKeyguardController.isKeyguardOrAodShowing(DEFAULT_DISPLAY)
4910 && !hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
Wale Ogunwale86b74462018-07-02 08:42:43 -07004911 mAmInternal.getCurrentUserId())
Wale Ogunwalef6733932018-06-27 05:14:34 -07004912 && !(UserManager.isDeviceInDemoMode(mContext)
Wale Ogunwale86b74462018-07-02 08:42:43 -07004913 && mAmInternal.getCurrentUser().isDemo());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004914 }
4915
Wale Ogunwale906f9c62018-07-23 11:23:44 -07004916 static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
4917 if (r == null || !r.hasProcess()) {
4918 return KEY_DISPATCHING_TIMEOUT_MS;
4919 }
4920 return getInputDispatchingTimeoutLocked(r.app);
4921 }
4922
4923 private static long getInputDispatchingTimeoutLocked(WindowProcessController r) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07004924 return r != null ? r.getInputDispatchingTimeout() : KEY_DISPATCHING_TIMEOUT_MS;
Wale Ogunwale906f9c62018-07-23 11:23:44 -07004925 }
4926
Wale Ogunwalef6733932018-06-27 05:14:34 -07004927 /**
4928 * Decide based on the configuration whether we should show the ANR,
4929 * crash, etc dialogs. The idea is that if there is no affordance to
4930 * press the on-screen buttons, or the user experience would be more
4931 * greatly impacted than the crash itself, we shouldn't show the dialog.
4932 *
4933 * A thought: SystemUI might also want to get told about this, the Power
4934 * dialog / global actions also might want different behaviors.
4935 */
4936 private void updateShouldShowDialogsLocked(Configuration config) {
4937 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
4938 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
4939 && config.navigation == Configuration.NAVIGATION_NONAV);
4940 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
4941 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
4942 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
4943 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
4944 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
4945 final boolean hideDialogsSet = Settings.Global.getInt(mContext.getContentResolver(),
4946 HIDE_ERROR_DIALOGS, 0) != 0;
4947 mShowDialogs = inputMethodExists && uiModeSupportsDialogs && !hideDialogsSet;
4948 }
4949
4950 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
4951 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
4952 FONT_SCALE, 1.0f, userId);
4953
4954 synchronized (this) {
4955 if (getGlobalConfiguration().fontScale == scaleFactor) {
4956 return;
4957 }
4958
4959 final Configuration configuration
4960 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
4961 configuration.fontScale = scaleFactor;
4962 updatePersistentConfiguration(configuration, userId);
4963 }
4964 }
4965
4966 // Actually is sleeping or shutting down or whatever else in the future
4967 // is an inactive state.
4968 boolean isSleepingOrShuttingDownLocked() {
4969 return isSleepingLocked() || mShuttingDown;
4970 }
4971
4972 boolean isSleepingLocked() {
4973 return mSleeping;
4974 }
4975
Riddle Hsu16567132018-08-16 21:37:47 +08004976 /** Update AMS states when an activity is resumed. */
Wale Ogunwalef6733932018-06-27 05:14:34 -07004977 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
4978 final TaskRecord task = r.getTask();
4979 if (task.isActivityTypeStandard()) {
4980 if (mCurAppTimeTracker != r.appTimeTracker) {
4981 // We are switching app tracking. Complete the current one.
4982 if (mCurAppTimeTracker != null) {
4983 mCurAppTimeTracker.stop();
4984 mH.obtainMessage(
4985 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
4986 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
4987 mCurAppTimeTracker = null;
4988 }
4989 if (r.appTimeTracker != null) {
4990 mCurAppTimeTracker = r.appTimeTracker;
4991 startTimeTrackingFocusedActivityLocked();
4992 }
4993 } else {
4994 startTimeTrackingFocusedActivityLocked();
4995 }
4996 } else {
4997 r.appTimeTracker = null;
4998 }
4999 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
5000 // TODO: Probably not, because we don't want to resume voice on switching
5001 // back to this activity
5002 if (task.voiceInteractor != null) {
5003 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
5004 } else {
5005 finishRunningVoiceLocked();
5006
5007 if (mLastResumedActivity != null) {
5008 final IVoiceInteractionSession session;
5009
5010 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
5011 if (lastResumedActivityTask != null
5012 && lastResumedActivityTask.voiceSession != null) {
5013 session = lastResumedActivityTask.voiceSession;
5014 } else {
5015 session = mLastResumedActivity.voiceSession;
5016 }
5017
5018 if (session != null) {
5019 // We had been in a voice interaction session, but now focused has
5020 // move to something different. Just finish the session, we can't
5021 // return to it and retain the proper state and synchronization with
5022 // the voice interaction service.
5023 finishVoiceTask(session);
5024 }
5025 }
5026 }
5027
5028 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
5029 mAmInternal.sendForegroundProfileChanged(r.userId);
5030 }
5031 updateResumedAppTrace(r);
5032 mLastResumedActivity = r;
5033
Tiger Huang1e5b10a2018-07-30 20:19:51 +08005034 r.getDisplay().setFocusedApp(r, true);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005035
5036 applyUpdateLockStateLocked(r);
5037 applyUpdateVrModeLocked(r);
5038
5039 EventLogTags.writeAmSetResumedActivity(
5040 r == null ? -1 : r.userId,
5041 r == null ? "NULL" : r.shortComponentName,
5042 reason);
5043 }
5044
5045 ActivityTaskManagerInternal.SleepToken acquireSleepToken(String tag, int displayId) {
5046 synchronized (mGlobalLock) {
5047 final ActivityTaskManagerInternal.SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
5048 updateSleepIfNeededLocked();
5049 return token;
5050 }
5051 }
5052
5053 void updateSleepIfNeededLocked() {
5054 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
5055 final boolean wasSleeping = mSleeping;
5056 boolean updateOomAdj = false;
5057
5058 if (!shouldSleep) {
5059 // If wasSleeping is true, we need to wake up activity manager state from when
5060 // we started sleeping. In either case, we need to apply the sleep tokens, which
5061 // will wake up stacks or put them to sleep as appropriate.
5062 if (wasSleeping) {
5063 mSleeping = false;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07005064 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
5065 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__AWAKE);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005066 startTimeTrackingFocusedActivityLocked();
5067 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
5068 mStackSupervisor.comeOutOfSleepIfNeededLocked();
5069 }
5070 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
5071 if (wasSleeping) {
5072 updateOomAdj = true;
5073 }
5074 } else if (!mSleeping && shouldSleep) {
5075 mSleeping = true;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07005076 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
5077 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__ASLEEP);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005078 if (mCurAppTimeTracker != null) {
5079 mCurAppTimeTracker.stop();
5080 }
5081 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
5082 mStackSupervisor.goingToSleepLocked();
5083 updateResumedAppTrace(null /* resumed */);
5084 updateOomAdj = true;
5085 }
5086 if (updateOomAdj) {
5087 mH.post(mAmInternal::updateOomAdj);
5088 }
5089 }
5090
5091 void updateOomAdj() {
5092 mH.post(mAmInternal::updateOomAdj);
5093 }
5094
Wale Ogunwale53783742018-09-16 10:21:51 -07005095 void updateCpuStats() {
5096 mH.post(mAmInternal::updateCpuStats);
5097 }
5098
5099 void updateUsageStats(ActivityRecord component, boolean resumed) {
5100 final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::updateUsageStats,
5101 mAmInternal, component.realActivity, component.app.mUid, component.userId, resumed);
5102 mH.sendMessage(m);
5103 }
5104
5105 void setBooting(boolean booting) {
5106 mAmInternal.setBooting(booting);
5107 }
5108
5109 boolean isBooting() {
5110 return mAmInternal.isBooting();
5111 }
5112
5113 void setBooted(boolean booted) {
5114 mAmInternal.setBooted(booted);
5115 }
5116
5117 boolean isBooted() {
5118 return mAmInternal.isBooted();
5119 }
5120
5121 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
5122 mH.post(() -> {
5123 if (finishBooting) {
5124 mAmInternal.finishBooting();
5125 }
5126 if (enableScreen) {
5127 mInternal.enableScreenAfterBoot(isBooted());
5128 }
5129 });
5130 }
5131
5132 void setHeavyWeightProcess(ActivityRecord root) {
5133 mHeavyWeightProcess = root.app;
5134 final Message m = PooledLambda.obtainMessage(
5135 ActivityTaskManagerService::postHeavyWeightProcessNotification, this,
5136 root.app, root.intent, root.userId);
5137 mH.sendMessage(m);
5138 }
5139
5140 void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
5141 if (mHeavyWeightProcess == null || mHeavyWeightProcess != proc) {
5142 return;
5143 }
5144
5145 mHeavyWeightProcess = null;
5146 final Message m = PooledLambda.obtainMessage(
5147 ActivityTaskManagerService::cancelHeavyWeightProcessNotification, this,
5148 proc.mUserId);
5149 mH.sendMessage(m);
5150 }
5151
5152 private void cancelHeavyWeightProcessNotification(int userId) {
5153 final INotificationManager inm = NotificationManager.getService();
5154 if (inm == null) {
5155 return;
5156 }
5157 try {
5158 inm.cancelNotificationWithTag("android", null,
5159 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, userId);
5160 } catch (RuntimeException e) {
5161 Slog.w(TAG, "Error canceling notification for service", e);
5162 } catch (RemoteException e) {
5163 }
5164
5165 }
5166
5167 private void postHeavyWeightProcessNotification(
5168 WindowProcessController proc, Intent intent, int userId) {
5169 if (proc == null) {
5170 return;
5171 }
5172
5173 final INotificationManager inm = NotificationManager.getService();
5174 if (inm == null) {
5175 return;
5176 }
5177
5178 try {
5179 Context context = mContext.createPackageContext(proc.mInfo.packageName, 0);
5180 String text = mContext.getString(R.string.heavy_weight_notification,
5181 context.getApplicationInfo().loadLabel(context.getPackageManager()));
5182 Notification notification =
5183 new Notification.Builder(context,
5184 SystemNotificationChannels.HEAVY_WEIGHT_APP)
5185 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
5186 .setWhen(0)
5187 .setOngoing(true)
5188 .setTicker(text)
5189 .setColor(mContext.getColor(
5190 com.android.internal.R.color.system_notification_accent_color))
5191 .setContentTitle(text)
5192 .setContentText(
5193 mContext.getText(R.string.heavy_weight_notification_detail))
5194 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
5195 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
5196 new UserHandle(userId)))
5197 .build();
5198 try {
5199 inm.enqueueNotificationWithTag("android", "android", null,
5200 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, notification, userId);
5201 } catch (RuntimeException e) {
5202 Slog.w(TAG, "Error showing notification for heavy-weight app", e);
5203 } catch (RemoteException e) {
5204 }
5205 } catch (PackageManager.NameNotFoundException e) {
5206 Slog.w(TAG, "Unable to create context for heavy notification", e);
5207 }
5208
5209 }
5210
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07005211 IIntentSender getIntentSenderLocked(int type, String packageName, int callingUid, int userId,
5212 IBinder token, String resultWho, int requestCode, Intent[] intents,
5213 String[] resolvedTypes, int flags, Bundle bOptions) {
5214
5215 ActivityRecord activity = null;
5216 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5217 activity = ActivityRecord.isInStackLocked(token);
5218 if (activity == null) {
5219 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
5220 return null;
5221 }
5222 if (activity.finishing) {
5223 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
5224 return null;
5225 }
5226 }
5227
5228 final PendingIntentRecord rec = mPendingIntentController.getIntentSender(type, packageName,
5229 callingUid, userId, token, resultWho, requestCode, intents, resolvedTypes, flags,
5230 bOptions);
5231 final boolean noCreate = (flags & PendingIntent.FLAG_NO_CREATE) != 0;
5232 if (noCreate) {
5233 return rec;
5234 }
5235 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5236 if (activity.pendingResults == null) {
5237 activity.pendingResults = new HashSet<>();
5238 }
5239 activity.pendingResults.add(rec.ref);
5240 }
5241 return rec;
5242 }
5243
Andrii Kulian52d255c2018-07-13 11:32:19 -07005244 // TODO(b/111541062): Update app time tracking to make it aware of multiple resumed activities
Wale Ogunwalef6733932018-06-27 05:14:34 -07005245 private void startTimeTrackingFocusedActivityLocked() {
Andrii Kulian52d255c2018-07-13 11:32:19 -07005246 final ActivityRecord resumedActivity = mStackSupervisor.getTopResumedActivity();
Wale Ogunwalef6733932018-06-27 05:14:34 -07005247 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
5248 mCurAppTimeTracker.start(resumedActivity.packageName);
5249 }
5250 }
5251
5252 private void updateResumedAppTrace(@Nullable ActivityRecord resumed) {
5253 if (mTracedResumedActivity != null) {
5254 Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER,
5255 constructResumedTraceName(mTracedResumedActivity.packageName), 0);
5256 }
5257 if (resumed != null) {
5258 Trace.asyncTraceBegin(TRACE_TAG_ACTIVITY_MANAGER,
5259 constructResumedTraceName(resumed.packageName), 0);
5260 }
5261 mTracedResumedActivity = resumed;
5262 }
5263
5264 private String constructResumedTraceName(String packageName) {
5265 return "focused app: " + packageName;
5266 }
5267
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005268 /** Helper method that requests bounds from WM and applies them to stack. */
5269 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
5270 final Rect newStackBounds = new Rect();
5271 final ActivityStack stack = mStackSupervisor.getStack(stackId);
5272
5273 // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
5274 if (stack == null) {
5275 final StringWriter writer = new StringWriter();
5276 final PrintWriter printWriter = new PrintWriter(writer);
5277 mStackSupervisor.dumpDisplays(printWriter);
5278 printWriter.flush();
5279
5280 Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
5281 }
5282
5283 stack.getBoundsForNewConfiguration(newStackBounds);
5284 mStackSupervisor.resizeStackLocked(
5285 stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
5286 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
5287 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
5288 }
5289
5290 /** Applies latest configuration and/or visibility updates if needed. */
5291 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
5292 boolean kept = true;
Andrii Kulian5f750bc2018-07-17 08:57:23 -07005293 final ActivityStack mainStack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005294 // mainStack is null during startup.
5295 if (mainStack != null) {
5296 if (changes != 0 && starting == null) {
5297 // If the configuration changed, and the caller is not already
5298 // in the process of starting an activity, then find the top
5299 // activity to check if its configuration needs to change.
5300 starting = mainStack.topRunningActivityLocked();
5301 }
5302
5303 if (starting != null) {
5304 kept = starting.ensureActivityConfiguration(changes,
5305 false /* preserveWindow */);
5306 // And we need to make sure at this point that all other activities
5307 // are made visible with the correct configuration.
5308 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
5309 !PRESERVE_WINDOWS);
5310 }
5311 }
5312
5313 return kept;
5314 }
5315
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005316 void scheduleAppGcsLocked() {
5317 mH.post(() -> mAmInternal.scheduleAppGcs());
5318 }
5319
Wale Ogunwale53783742018-09-16 10:21:51 -07005320 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
5321 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
5322 }
5323
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005324 /**
5325 * Returns the PackageManager. Used by classes hosted by {@link ActivityTaskManagerService}. The
5326 * PackageManager could be unavailable at construction time and therefore needs to be accessed
5327 * on demand.
5328 */
5329 IPackageManager getPackageManager() {
5330 return AppGlobals.getPackageManager();
5331 }
5332
5333 PackageManagerInternal getPackageManagerInternalLocked() {
5334 if (mPmInternal == null) {
5335 mPmInternal = LocalServices.getService(PackageManagerInternal.class);
5336 }
5337 return mPmInternal;
5338 }
5339
Wale Ogunwale008163e2018-07-23 23:11:08 -07005340 AppWarnings getAppWarningsLocked() {
5341 return mAppWarnings;
5342 }
5343
Wale Ogunwale214f3482018-10-04 11:00:47 -07005344 Intent getHomeIntent() {
5345 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
5346 intent.setComponent(mTopComponent);
5347 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
5348 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5349 intent.addCategory(Intent.CATEGORY_HOME);
5350 }
5351 return intent;
5352 }
5353
5354 /**
5355 * This starts home activity on displays that can have system decorations and only if the
5356 * home activity can have multiple instances.
5357 */
5358 boolean startHomeActivityLocked(int userId, String reason, int displayId) {
5359 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL && mTopAction == null) {
5360 // We are running in factory test mode, but unable to find the factory test app, so just
5361 // sit around displaying the error message and don't try to start anything.
5362 return false;
5363 }
5364
5365 final Intent intent = getHomeIntent();
5366 ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
5367 if (aInfo != null) {
5368 intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
5369 // Don't do this if the home app is currently being instrumented.
5370 aInfo = new ActivityInfo(aInfo);
5371 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
5372 WindowProcessController app =
5373 getProcessController(aInfo.processName, aInfo.applicationInfo.uid);
5374 if (app == null || !app.isInstrumenting()) {
5375 intent.setFlags(intent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
5376 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
5377 // For ANR debugging to verify if the user activity is the one that actually
5378 // launched.
5379 final String myReason = reason + ":" + userId + ":" + resolvedUserId;
5380 getActivityStartController().startHomeActivity(intent, aInfo, myReason, displayId);
5381 }
5382 } else {
5383 Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
5384 }
5385
5386 return true;
5387 }
5388
5389 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
5390 ActivityInfo ai = null;
5391 final ComponentName comp = intent.getComponent();
5392 try {
5393 if (comp != null) {
5394 // Factory test.
5395 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
5396 } else {
5397 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
5398 intent,
5399 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
5400 flags, userId);
5401
5402 if (info != null) {
5403 ai = info.activityInfo;
5404 }
5405 }
5406 } catch (RemoteException e) {
5407 // ignore
5408 }
5409
5410 return ai;
5411 }
5412
5413 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
5414 if (info == null) return null;
5415 ApplicationInfo newInfo = new ApplicationInfo(info);
5416 newInfo.initForUser(userId);
5417 return newInfo;
5418 }
5419
Wale Ogunwale9c103022018-10-18 07:44:54 -07005420 WindowProcessController getProcessController(String processName, int uid) {
Wale Ogunwale214f3482018-10-04 11:00:47 -07005421 if (uid == SYSTEM_UID) {
5422 // The system gets to run in any process. If there are multiple processes with the same
5423 // uid, just pick the first (this should never happen).
5424 final SparseArray<WindowProcessController> procs =
5425 mProcessNames.getMap().get(processName);
5426 if (procs == null) return null;
5427 final int procCount = procs.size();
5428 for (int i = 0; i < procCount; i++) {
5429 final int procUid = procs.keyAt(i);
5430 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
5431 // Don't use an app process or different user process for system component.
5432 continue;
5433 }
5434 return procs.valueAt(i);
5435 }
5436 }
5437
5438 return mProcessNames.get(processName, uid);
5439 }
5440
Wale Ogunwale342fbe92018-10-09 08:44:10 -07005441 WindowProcessController getProcessController(IApplicationThread thread) {
5442 if (thread == null) {
5443 return null;
5444 }
5445
5446 final IBinder threadBinder = thread.asBinder();
5447 final ArrayMap<String, SparseArray<WindowProcessController>> pmap = mProcessNames.getMap();
5448 for (int i = pmap.size()-1; i >= 0; i--) {
5449 final SparseArray<WindowProcessController> procs = pmap.valueAt(i);
5450 for (int j = procs.size() - 1; j >= 0; j--) {
5451 final WindowProcessController proc = procs.valueAt(j);
5452 if (proc.hasThread() && proc.getThread().asBinder() == threadBinder) {
5453 return proc;
5454 }
5455 }
5456 }
5457
5458 return null;
5459 }
5460
Wale Ogunwalebff2df42018-10-18 17:09:19 -07005461 int getUidStateLocked(int uid) {
5462 return mActiveUids.get(uid, PROCESS_STATE_NONEXISTENT);
5463 }
5464
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005465 void logAppTooSlow(WindowProcessController app, long startTime, String msg) {
5466 if (true || Build.IS_USER) {
5467 return;
5468 }
5469
5470 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5471 StrictMode.allowThreadDiskWrites();
5472 try {
5473 File tracesDir = new File("/data/anr");
5474 File tracesFile = null;
5475 try {
5476 tracesFile = File.createTempFile("app_slow", null, tracesDir);
5477
5478 StringBuilder sb = new StringBuilder();
5479 Time tobj = new Time();
5480 tobj.set(System.currentTimeMillis());
5481 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5482 sb.append(": ");
5483 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5484 sb.append(" since ");
5485 sb.append(msg);
5486 FileOutputStream fos = new FileOutputStream(tracesFile);
5487 fos.write(sb.toString().getBytes());
5488 if (app == null) {
5489 fos.write("\n*** No application process!".getBytes());
5490 }
5491 fos.close();
5492 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5493 } catch (IOException e) {
5494 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesFile, e);
5495 return;
5496 }
5497
5498 if (app != null && app.getPid() > 0) {
5499 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5500 firstPids.add(app.getPid());
5501 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, null, null);
5502 }
5503
5504 File lastTracesFile = null;
5505 File curTracesFile = null;
5506 for (int i=9; i>=0; i--) {
5507 String name = String.format(Locale.US, "slow%02d.txt", i);
5508 curTracesFile = new File(tracesDir, name);
5509 if (curTracesFile.exists()) {
5510 if (lastTracesFile != null) {
5511 curTracesFile.renameTo(lastTracesFile);
5512 } else {
5513 curTracesFile.delete();
5514 }
5515 }
5516 lastTracesFile = curTracesFile;
5517 }
5518 tracesFile.renameTo(curTracesFile);
5519 } finally {
5520 StrictMode.setThreadPolicy(oldPolicy);
5521 }
5522 }
5523
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005524 final class H extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005525 static final int REPORT_TIME_TRACKER_MSG = 1;
Wale Ogunwale98875612018-10-12 07:53:02 -07005526 static final int FIRST_ACTIVITY_STACK_MSG = 100;
5527 static final int FIRST_SUPERVISOR_STACK_MSG = 200;
Wale Ogunwalef6733932018-06-27 05:14:34 -07005528
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005529 public H(Looper looper) {
5530 super(looper, null, true);
5531 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005532
5533 @Override
5534 public void handleMessage(Message msg) {
5535 switch (msg.what) {
5536 case REPORT_TIME_TRACKER_MSG: {
5537 AppTimeTracker tracker = (AppTimeTracker) msg.obj;
5538 tracker.deliverResult(mContext);
5539 } break;
5540 }
5541 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005542 }
5543
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005544 final class UiHandler extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005545 static final int DISMISS_DIALOG_UI_MSG = 1;
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005546
5547 public UiHandler() {
5548 super(com.android.server.UiThread.get().getLooper(), null, true);
5549 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005550
5551 @Override
5552 public void handleMessage(Message msg) {
5553 switch (msg.what) {
5554 case DISMISS_DIALOG_UI_MSG: {
5555 final Dialog d = (Dialog) msg.obj;
5556 d.dismiss();
5557 break;
5558 }
5559 }
5560 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005561 }
5562
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005563 final class LocalService extends ActivityTaskManagerInternal {
5564 @Override
5565 public SleepToken acquireSleepToken(String tag, int displayId) {
5566 Preconditions.checkNotNull(tag);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005567 return ActivityTaskManagerService.this.acquireSleepToken(tag, displayId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005568 }
5569
5570 @Override
5571 public ComponentName getHomeActivityForUser(int userId) {
5572 synchronized (mGlobalLock) {
Louis Changbd48dca2018-08-29 17:44:34 +08005573 ActivityRecord homeActivity =
5574 mStackSupervisor.getDefaultDisplayHomeActivityForUser(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005575 return homeActivity == null ? null : homeActivity.realActivity;
5576 }
5577 }
5578
5579 @Override
5580 public void onLocalVoiceInteractionStarted(IBinder activity,
5581 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
5582 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005583 onLocalVoiceInteractionStartedLocked(activity, voiceSession, voiceInteractor);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005584 }
5585 }
5586
5587 @Override
5588 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
5589 synchronized (mGlobalLock) {
5590 mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
5591 reasons, timestamp);
5592 }
5593 }
5594
5595 @Override
5596 public void notifyAppTransitionFinished() {
5597 synchronized (mGlobalLock) {
5598 mStackSupervisor.notifyAppTransitionDone();
5599 }
5600 }
5601
5602 @Override
5603 public void notifyAppTransitionCancelled() {
5604 synchronized (mGlobalLock) {
5605 mStackSupervisor.notifyAppTransitionDone();
5606 }
5607 }
5608
5609 @Override
5610 public List<IBinder> getTopVisibleActivities() {
5611 synchronized (mGlobalLock) {
5612 return mStackSupervisor.getTopVisibleActivities();
5613 }
5614 }
5615
5616 @Override
5617 public void notifyDockedStackMinimizedChanged(boolean minimized) {
5618 synchronized (mGlobalLock) {
5619 mStackSupervisor.setDockedStackMinimized(minimized);
5620 }
5621 }
5622
5623 @Override
5624 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
5625 Bundle bOptions) {
5626 Preconditions.checkNotNull(intents, "intents");
5627 final String[] resolvedTypes = new String[intents.length];
5628
5629 // UID of the package on user userId.
5630 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
5631 // packageUid may not be initialized.
5632 int packageUid = 0;
5633 final long ident = Binder.clearCallingIdentity();
5634
5635 try {
5636 for (int i = 0; i < intents.length; i++) {
5637 resolvedTypes[i] =
5638 intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
5639 }
5640
5641 packageUid = AppGlobals.getPackageManager().getPackageUid(
5642 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
5643 } catch (RemoteException e) {
5644 // Shouldn't happen.
5645 } finally {
5646 Binder.restoreCallingIdentity(ident);
5647 }
5648
5649 synchronized (mGlobalLock) {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07005650 return getActivityStartController().startActivitiesInPackage(
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005651 packageUid, packageName,
5652 intents, resolvedTypes, null /* resultTo */,
5653 SafeActivityOptions.fromBundle(bOptions), userId,
Michal Karpinski201bc0c2018-07-20 15:32:00 +01005654 false /* validateIncomingUser */, null /* originatingPendingIntent */);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005655 }
5656 }
5657
5658 @Override
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07005659 public int startActivitiesInPackage(int uid, String callingPackage, Intent[] intents,
5660 String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, int userId,
5661 boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent) {
5662 synchronized (mGlobalLock) {
5663 return getActivityStartController().startActivitiesInPackage(uid, callingPackage,
5664 intents, resolvedTypes, resultTo, options, userId, validateIncomingUser,
5665 originatingPendingIntent);
5666 }
5667 }
5668
5669 @Override
5670 public int startActivityInPackage(int uid, int realCallingPid, int realCallingUid,
5671 String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
5672 String resultWho, int requestCode, int startFlags, SafeActivityOptions options,
5673 int userId, TaskRecord inTask, String reason, boolean validateIncomingUser,
5674 PendingIntentRecord originatingPendingIntent) {
5675 synchronized (mGlobalLock) {
5676 return getActivityStartController().startActivityInPackage(uid, realCallingPid,
5677 realCallingUid, callingPackage, intent, resolvedType, resultTo, resultWho,
5678 requestCode, startFlags, options, userId, inTask, reason,
5679 validateIncomingUser, originatingPendingIntent);
5680 }
5681 }
5682
5683 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005684 public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
5685 Intent intent, Bundle options, int userId) {
5686 return ActivityTaskManagerService.this.startActivityAsUser(
5687 caller, callerPacakge, intent,
5688 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
5689 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
5690 false /*validateIncomingUser*/);
5691 }
5692
5693 @Override
5694 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
5695 synchronized (mGlobalLock) {
5696
5697 // We might change the visibilities here, so prepare an empty app transition which
5698 // might be overridden later if we actually change visibilities.
5699 final boolean wasTransitionSet =
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005700 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005701 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005702 mWindowManager.prepareAppTransition(TRANSIT_NONE,
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005703 false /* alwaysKeepCurrent */);
5704 }
5705 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5706
5707 // If there was a transition set already we don't want to interfere with it as we
5708 // might be starting it too early.
5709 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005710 mWindowManager.executeAppTransition();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005711 }
5712 }
5713 if (callback != null) {
5714 callback.run();
5715 }
5716 }
5717
5718 @Override
5719 public void notifyKeyguardTrustedChanged() {
5720 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005721 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005722 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5723 }
5724 }
5725 }
5726
5727 /**
5728 * Called after virtual display Id is updated by
5729 * {@link com.android.server.vr.Vr2dDisplay} with a specific
5730 * {@param vrVr2dDisplayId}.
5731 */
5732 @Override
5733 public void setVr2dDisplayId(int vr2dDisplayId) {
5734 if (DEBUG_STACK) Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
5735 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005736 mVr2dDisplayId = vr2dDisplayId;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005737 }
5738 }
5739
5740 @Override
5741 public void setFocusedActivity(IBinder token) {
5742 synchronized (mGlobalLock) {
5743 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
5744 if (r == null) {
5745 throw new IllegalArgumentException(
5746 "setFocusedActivity: No activity record matching token=" + token);
5747 }
Louis Chang19443452018-10-09 12:10:21 +08005748 if (r.moveFocusableActivityToTop("setFocusedActivity")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08005749 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005750 }
5751 }
5752 }
5753
5754 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005755 public void registerScreenObserver(ScreenObserver observer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005756 mScreenObservers.add(observer);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005757 }
5758
5759 @Override
5760 public boolean isCallerRecents(int callingUid) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005761 return getRecentTasks().isCallerRecents(callingUid);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005762 }
5763
5764 @Override
5765 public boolean isRecentsComponentHomeActivity(int userId) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005766 return getRecentTasks().isRecentsComponentHomeActivity(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005767 }
5768
5769 @Override
5770 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
5771 ActivityTaskManagerService.this.cancelRecentsAnimation(restoreHomeStackPosition);
5772 }
5773
5774 @Override
5775 public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005776 ActivityTaskManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005777 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005778
5779 @Override
5780 public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
5781 synchronized (mGlobalLock) {
5782 mActiveVoiceInteractionServiceComponent = component;
5783 }
5784 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005785
5786 @Override
5787 public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
5788 if (!mAmInternal.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
5789 return;
5790 }
5791 synchronized (mGlobalLock) {
5792 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
5793 if (types == null) {
5794 if (uid < 0) {
5795 return;
5796 }
5797 types = new ArrayMap<>();
5798 mAllowAppSwitchUids.put(userId, types);
5799 }
5800 if (uid < 0) {
5801 types.remove(type);
5802 } else {
5803 types.put(type, uid);
5804 }
5805 }
5806 }
5807
5808 @Override
5809 public void onUserStopped(int userId) {
5810 synchronized (mGlobalLock) {
5811 getRecentTasks().unloadUserDataFromMemoryLocked(userId);
5812 mAllowAppSwitchUids.remove(userId);
5813 }
5814 }
5815
5816 @Override
5817 public boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
5818 synchronized (mGlobalLock) {
5819 return ActivityTaskManagerService.this.isGetTasksAllowed(
5820 caller, callingPid, callingUid);
5821 }
5822 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005823
5824 @Override
5825 public void onProcessAdded(WindowProcessController proc) {
5826 synchronized (mGlobalLock) {
5827 mProcessNames.put(proc.mName, proc.mUid, proc);
5828 }
5829 }
5830
5831 @Override
5832 public void onProcessRemoved(String name, int uid) {
5833 synchronized (mGlobalLock) {
5834 mProcessNames.remove(name, uid);
5835 }
5836 }
5837
5838 @Override
5839 public void onCleanUpApplicationRecord(WindowProcessController proc) {
5840 synchronized (mGlobalLock) {
5841 if (proc == mHomeProcess) {
5842 mHomeProcess = null;
5843 }
5844 if (proc == mPreviousProcess) {
5845 mPreviousProcess = null;
5846 }
5847 }
5848 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005849
5850 @Override
5851 public int getTopProcessState() {
5852 synchronized (mGlobalLock) {
5853 return mTopProcessState;
5854 }
5855 }
5856
5857 @Override
Wale Ogunwale53783742018-09-16 10:21:51 -07005858 public boolean isHeavyWeightProcess(WindowProcessController proc) {
5859 synchronized (mGlobalLock) {
5860 return proc == mHeavyWeightProcess;
5861 }
5862 }
5863
5864 @Override
5865 public void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
5866 synchronized (mGlobalLock) {
5867 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(proc);
5868 }
5869 }
5870
5871 @Override
5872 public void finishHeavyWeightApp() {
5873 synchronized (mGlobalLock) {
5874 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(
5875 mHeavyWeightProcess);
5876 }
5877 }
5878
5879 @Override
Wale Ogunwalef6733932018-06-27 05:14:34 -07005880 public boolean isSleeping() {
5881 synchronized (mGlobalLock) {
5882 return isSleepingLocked();
5883 }
5884 }
5885
5886 @Override
5887 public boolean isShuttingDown() {
5888 synchronized (mGlobalLock) {
5889 return mShuttingDown;
5890 }
5891 }
5892
5893 @Override
5894 public boolean shuttingDown(boolean booted, int timeout) {
5895 synchronized (mGlobalLock) {
5896 mShuttingDown = true;
5897 mStackSupervisor.prepareForShutdownLocked();
5898 updateEventDispatchingLocked(booted);
5899 return mStackSupervisor.shutdownLocked(timeout);
5900 }
5901 }
5902
5903 @Override
5904 public void enableScreenAfterBoot(boolean booted) {
5905 synchronized (mGlobalLock) {
5906 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5907 SystemClock.uptimeMillis());
5908 mWindowManager.enableScreenAfterBoot();
5909 updateEventDispatchingLocked(booted);
5910 }
5911 }
5912
5913 @Override
5914 public boolean showStrictModeViolationDialog() {
5915 synchronized (mGlobalLock) {
5916 return mShowDialogs && !mSleeping && !mShuttingDown;
5917 }
5918 }
5919
5920 @Override
5921 public void showSystemReadyErrorDialogsIfNeeded() {
5922 synchronized (mGlobalLock) {
5923 try {
5924 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
5925 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
5926 + " data partition or your device will be unstable.");
5927 mUiHandler.post(() -> {
5928 if (mShowDialogs) {
5929 AlertDialog d = new BaseErrorDialog(mUiContext);
5930 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5931 d.setCancelable(false);
5932 d.setTitle(mUiContext.getText(R.string.android_system_label));
5933 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
5934 d.setButton(DialogInterface.BUTTON_POSITIVE,
5935 mUiContext.getText(R.string.ok),
5936 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5937 d.show();
5938 }
5939 });
5940 }
5941 } catch (RemoteException e) {
5942 }
5943
5944 if (!Build.isBuildConsistent()) {
5945 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
5946 mUiHandler.post(() -> {
5947 if (mShowDialogs) {
5948 AlertDialog d = new BaseErrorDialog(mUiContext);
5949 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5950 d.setCancelable(false);
5951 d.setTitle(mUiContext.getText(R.string.android_system_label));
5952 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
5953 d.setButton(DialogInterface.BUTTON_POSITIVE,
5954 mUiContext.getText(R.string.ok),
5955 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5956 d.show();
5957 }
5958 });
5959 }
5960 }
5961 }
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005962
5963 @Override
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005964 public void onProcessMapped(int pid, WindowProcessController proc) {
5965 synchronized (mGlobalLock) {
5966 mPidMap.put(pid, proc);
5967 }
5968 }
5969
5970 @Override
5971 public void onProcessUnMapped(int pid) {
5972 synchronized (mGlobalLock) {
5973 mPidMap.remove(pid);
5974 }
5975 }
Wale Ogunwale008163e2018-07-23 23:11:08 -07005976
5977 @Override
5978 public void onPackageDataCleared(String name) {
5979 synchronized (mGlobalLock) {
Wale Ogunwale53783742018-09-16 10:21:51 -07005980 mCompatModePackages.handlePackageDataClearedLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07005981 mAppWarnings.onPackageDataCleared(name);
5982 }
5983 }
5984
5985 @Override
5986 public void onPackageUninstalled(String name) {
5987 synchronized (mGlobalLock) {
5988 mAppWarnings.onPackageUninstalled(name);
Wale Ogunwale53783742018-09-16 10:21:51 -07005989 mCompatModePackages.handlePackageUninstalledLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07005990 }
5991 }
Wale Ogunwale53783742018-09-16 10:21:51 -07005992
5993 @Override
5994 public void onPackageAdded(String name, boolean replacing) {
5995 synchronized (mGlobalLock) {
5996 mCompatModePackages.handlePackageAddedLocked(name, replacing);
5997 }
5998 }
5999
6000 @Override
Wale Ogunwale31913b52018-10-13 08:29:31 -07006001 public void onPackageReplaced(ApplicationInfo aInfo) {
6002 synchronized (mGlobalLock) {
6003 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
6004 }
6005 }
6006
6007 @Override
Wale Ogunwale53783742018-09-16 10:21:51 -07006008 public CompatibilityInfo compatibilityInfoForPackage(ApplicationInfo ai) {
6009 synchronized (mGlobalLock) {
6010 return compatibilityInfoForPackageLocked(ai);
6011 }
6012 }
6013
Yunfan Chen75157d72018-07-27 14:47:21 +09006014 /**
6015 * Set the corresponding display information for the process global configuration. To be
6016 * called when we need to show IME on a different display.
6017 *
6018 * @param pid The process id associated with the IME window.
6019 * @param displayId The ID of the display showing the IME.
6020 */
6021 @Override
6022 public void onImeWindowSetOnDisplay(int pid, int displayId) {
6023 if (pid == MY_PID || pid < 0) {
6024 if (DEBUG_CONFIGURATION) {
6025 Slog.w(TAG,
6026 "Trying to update display configuration for system/invalid process.");
6027 }
6028 return;
6029 }
6030 mH.post(() -> {
6031 synchronized (mGlobalLock) {
6032 // Check if display is initialized in AM.
6033 if (!mStackSupervisor.isDisplayAdded(displayId)) {
6034 // Call come when display is not yet added or has already been removed.
6035 if (DEBUG_CONFIGURATION) {
6036 Slog.w(TAG, "Trying to update display configuration for non-existing "
6037 + "displayId=" + displayId);
6038 }
6039 return;
6040 }
6041 final WindowProcessController imeProcess = mPidMap.get(pid);
6042 if (imeProcess == null) {
6043 if (DEBUG_CONFIGURATION) {
6044 Slog.w(TAG, "Trying to update display configuration for invalid pid: "
6045 + pid);
6046 }
6047 return;
6048 }
6049 // Fetch the current override configuration of the display and set it to the
6050 // process global configuration.
6051 imeProcess.onConfigurationChanged(
6052 mStackSupervisor.getDisplayOverrideConfiguration(displayId));
6053 }
6054 });
6055 }
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07006056
6057 @Override
6058 public void sendActivityResult(int callingUid, IBinder activityToken, String resultWho,
6059 int requestCode, int resultCode, Intent data) {
6060 synchronized (mGlobalLock) {
6061 final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
6062 if (r != null && r.getStack() != null) {
6063 r.getStack().sendActivityResultLocked(callingUid, r, resultWho, requestCode,
6064 resultCode, data);
6065 }
6066 }
6067 }
6068
6069 @Override
6070 public void clearPendingResultForActivity(IBinder activityToken,
6071 WeakReference<PendingIntentRecord> pir) {
6072 synchronized (mGlobalLock) {
6073 final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
6074 if (r != null && r.pendingResults != null) {
6075 r.pendingResults.remove(pir);
6076 }
6077 }
6078 }
6079
6080 @Override
6081 public IIntentSender getIntentSender(int type, String packageName,
6082 int callingUid, int userId, IBinder token, String resultWho,
6083 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6084 Bundle bOptions) {
6085 synchronized (mGlobalLock) {
6086 return getIntentSenderLocked(type, packageName, callingUid, userId, token,
6087 resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6088 }
6089 }
Wale Ogunwalec4e63a42018-10-02 13:19:54 -07006090
6091 @Override
6092 public ActivityServiceConnectionsHolder getServiceConnectionsHolder(IBinder token) {
6093 synchronized (mGlobalLock) {
6094 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
6095 if (r == null) {
6096 return null;
6097 }
6098 if (r.mServiceConnectionsHolder == null) {
6099 r.mServiceConnectionsHolder = new ActivityServiceConnectionsHolder(
6100 ActivityTaskManagerService.this, r);
6101 }
6102
6103 return r.mServiceConnectionsHolder;
6104 }
6105 }
Wale Ogunwale214f3482018-10-04 11:00:47 -07006106
6107 @Override
6108 public Intent getHomeIntent() {
6109 synchronized (mGlobalLock) {
6110 return ActivityTaskManagerService.this.getHomeIntent();
6111 }
6112 }
6113
6114 @Override
6115 public boolean startHomeActivity(int userId, String reason) {
6116 synchronized (mGlobalLock) {
6117 return startHomeActivityLocked(userId, reason, DEFAULT_DISPLAY);
6118 }
6119 }
6120
6121 @Override
6122 public boolean isFactoryTestProcess(WindowProcessController wpc) {
6123 synchronized (mGlobalLock) {
6124 if (mFactoryTest == FACTORY_TEST_OFF) {
6125 return false;
6126 }
6127 if (mFactoryTest == FACTORY_TEST_LOW_LEVEL && mTopComponent != null
6128 && wpc.mName.equals(mTopComponent.getPackageName())) {
6129 return true;
6130 }
6131 return mFactoryTest == FACTORY_TEST_HIGH_LEVEL
6132 && (wpc.mInfo.flags & FLAG_FACTORY_TEST) != 0;
6133 }
6134 }
6135
6136 @Override
6137 public void updateTopComponentForFactoryTest() {
6138 synchronized (mGlobalLock) {
6139 if (mFactoryTest != FACTORY_TEST_LOW_LEVEL) {
6140 return;
6141 }
6142 final ResolveInfo ri = mContext.getPackageManager()
6143 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), STOCK_PM_FLAGS);
6144 final CharSequence errorMsg;
6145 if (ri != null) {
6146 final ActivityInfo ai = ri.activityInfo;
6147 final ApplicationInfo app = ai.applicationInfo;
6148 if ((app.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
6149 mTopAction = Intent.ACTION_FACTORY_TEST;
6150 mTopData = null;
6151 mTopComponent = new ComponentName(app.packageName, ai.name);
6152 errorMsg = null;
6153 } else {
6154 errorMsg = mContext.getResources().getText(
6155 com.android.internal.R.string.factorytest_not_system);
6156 }
6157 } else {
6158 errorMsg = mContext.getResources().getText(
6159 com.android.internal.R.string.factorytest_no_action);
6160 }
6161 if (errorMsg == null) {
6162 return;
6163 }
6164
6165 mTopAction = null;
6166 mTopData = null;
6167 mTopComponent = null;
6168 mUiHandler.post(() -> {
6169 Dialog d = new FactoryErrorDialog(mUiContext, errorMsg);
6170 d.show();
Wale Ogunwale342fbe92018-10-09 08:44:10 -07006171 mAmInternal.ensureBootCompleted();
Wale Ogunwale214f3482018-10-04 11:00:47 -07006172 });
6173 }
6174 }
Wale Ogunwale31913b52018-10-13 08:29:31 -07006175
6176 @Override
6177 public void handleAppDied(WindowProcessController wpc, boolean restarting,
6178 Runnable finishInstrumentationCallback) {
6179 synchronized (mGlobalLock) {
6180 // Remove this application's activities from active lists.
6181 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(wpc);
6182
6183 wpc.clearRecentTasks();
6184 wpc.clearActivities();
6185
6186 if (wpc.isInstrumenting()) {
6187 finishInstrumentationCallback.run();
6188 }
6189
6190 mWindowManager.deferSurfaceLayout();
6191 try {
6192 if (!restarting && hasVisibleActivities
6193 && !mStackSupervisor.resumeFocusedStacksTopActivitiesLocked()) {
6194 // If there was nothing to resume, and we are not already restarting this
6195 // process, but there is a visible activity that is hosted by the process...
6196 // then make sure all visible activities are running, taking care of
6197 // restarting this process.
6198 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6199 }
6200 } finally {
6201 mWindowManager.continueSurfaceLayout();
6202 }
6203 }
6204 }
6205
6206 @Override
6207 public void closeSystemDialogs(String reason) {
6208 enforceNotIsolatedCaller("closeSystemDialogs");
6209
6210 final int pid = Binder.getCallingPid();
6211 final int uid = Binder.getCallingUid();
6212 final long origId = Binder.clearCallingIdentity();
6213 try {
6214 synchronized (mGlobalLock) {
6215 // Only allow this from foreground processes, so that background
6216 // applications can't abuse it to prevent system UI from being shown.
6217 if (uid >= FIRST_APPLICATION_UID) {
6218 final WindowProcessController proc = mPidMap.get(pid);
6219 if (!proc.isPerceptible()) {
6220 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6221 + " from background process " + proc);
6222 return;
6223 }
6224 }
Wale Ogunwale31913b52018-10-13 08:29:31 -07006225 mWindowManager.closeSystemDialogs(reason);
6226
6227 mStackSupervisor.closeSystemDialogsLocked();
Wale Ogunwale31913b52018-10-13 08:29:31 -07006228 }
Wale Ogunwale2ea36d42018-10-18 10:27:31 -07006229 // Call into AM outside the synchronized block.
6230 mAmInternal.broadcastCloseSystemDialogs(reason);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006231 } finally {
6232 Binder.restoreCallingIdentity(origId);
6233 }
6234 }
6235
6236 @Override
6237 public void cleanupDisabledPackageComponents(
6238 String packageName, Set<String> disabledClasses, int userId, boolean booted) {
6239 synchronized (mGlobalLock) {
6240 // Clean-up disabled activities.
6241 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6242 packageName, disabledClasses, true, false, userId) && booted) {
6243 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
6244 mStackSupervisor.scheduleIdleLocked();
6245 }
6246
6247 // Clean-up disabled tasks
6248 getRecentTasks().cleanupDisabledPackageTasksLocked(
6249 packageName, disabledClasses, userId);
6250 }
6251 }
6252
6253 @Override
6254 public boolean onForceStopPackage(String packageName, boolean doit, boolean evenPersistent,
6255 int userId) {
6256 synchronized (mGlobalLock) {
6257
6258 boolean didSomething =
6259 getActivityStartController().clearPendingActivityLaunches(packageName);
6260 didSomething |= mStackSupervisor.finishDisabledPackageActivitiesLocked(packageName,
6261 null, doit, evenPersistent, userId);
6262 return didSomething;
6263 }
6264 }
6265
6266 @Override
6267 public void resumeTopActivities(boolean scheduleIdle) {
6268 synchronized (mGlobalLock) {
6269 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
6270 if (scheduleIdle) {
6271 mStackSupervisor.scheduleIdleLocked();
6272 }
6273 }
6274 }
6275
6276 @Override
6277 public void preBindApplication(WindowProcessController wpc) {
6278 synchronized (mGlobalLock) {
6279 mStackSupervisor.getActivityMetricsLogger().notifyBindApplication(wpc.mInfo);
6280 }
6281 }
6282
6283 @Override
6284 public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
6285 synchronized (mGlobalLock) {
6286 return mStackSupervisor.attachApplicationLocked(wpc);
6287 }
6288 }
6289
6290 @Override
6291 public void notifyLockedProfile(@UserIdInt int userId, int currentUserId) {
6292 try {
6293 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
6294 throw new SecurityException("Only privileged app can call notifyLockedProfile");
6295 }
6296 } catch (RemoteException ex) {
6297 throw new SecurityException("Fail to check is caller a privileged app", ex);
6298 }
6299
6300 synchronized (mGlobalLock) {
6301 final long ident = Binder.clearCallingIdentity();
6302 try {
6303 if (mAmInternal.shouldConfirmCredentials(userId)) {
6304 if (mKeyguardController.isKeyguardLocked()) {
6305 // Showing launcher to avoid user entering credential twice.
6306 startHomeActivity(currentUserId, "notifyLockedProfile");
6307 }
6308 mStackSupervisor.lockAllProfileTasks(userId);
6309 }
6310 } finally {
6311 Binder.restoreCallingIdentity(ident);
6312 }
6313 }
6314 }
6315
6316 @Override
6317 public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
6318 mAmInternal.enforceCallingPermission(
6319 MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
6320
6321 synchronized (mGlobalLock) {
6322 final long ident = Binder.clearCallingIdentity();
6323 try {
6324 intent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
6325 FLAG_ACTIVITY_TASK_ON_HOME);
6326 ActivityOptions activityOptions = options != null
6327 ? new ActivityOptions(options) : ActivityOptions.makeBasic();
6328 activityOptions.setLaunchTaskId(
6329 mStackSupervisor.getDefaultDisplayHomeActivity().getTask().taskId);
6330 mContext.startActivityAsUser(intent, activityOptions.toBundle(),
6331 UserHandle.CURRENT);
6332 } finally {
6333 Binder.restoreCallingIdentity(ident);
6334 }
6335 }
6336 }
6337
6338 @Override
6339 public void writeActivitiesToProto(ProtoOutputStream proto) {
6340 synchronized (mGlobalLock) {
6341 // The output proto of "activity --proto activities"
6342 // is ActivityManagerServiceDumpActivitiesProto
6343 mStackSupervisor.writeToProto(proto,
6344 ActivityManagerServiceDumpActivitiesProto.ACTIVITY_STACK_SUPERVISOR);
6345 }
6346 }
6347
6348 @Override
6349 public void saveANRState(String reason) {
6350 synchronized (mGlobalLock) {
6351 final StringWriter sw = new StringWriter();
6352 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
6353 pw.println(" ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
6354 if (reason != null) {
6355 pw.println(" Reason: " + reason);
6356 }
6357 pw.println();
6358 getActivityStartController().dump(pw, " ", null);
6359 pw.println();
6360 pw.println("-------------------------------------------------------------------------------");
6361 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
6362 true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
6363 "" /* header */);
6364 pw.println();
6365 pw.close();
6366
6367 mLastANRState = sw.toString();
6368 }
6369 }
6370
6371 @Override
6372 public void clearSavedANRState() {
6373 synchronized (mGlobalLock) {
6374 mLastANRState = null;
6375 }
6376 }
6377
6378 @Override
6379 public void dump(String cmd, FileDescriptor fd, PrintWriter pw, String[] args, int opti,
6380 boolean dumpAll, boolean dumpClient, String dumpPackage) {
6381 synchronized (mGlobalLock) {
6382 if (DUMP_ACTIVITIES_CMD.equals(cmd) || DUMP_ACTIVITIES_SHORT_CMD.equals(cmd)) {
6383 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
6384 } else if (DUMP_LASTANR_CMD.equals(cmd)) {
6385 dumpLastANRLocked(pw);
6386 } else if (DUMP_LASTANR_TRACES_CMD.equals(cmd)) {
6387 dumpLastANRTracesLocked(pw);
6388 } else if (DUMP_STARTER_CMD.equals(cmd)) {
6389 dumpActivityStarterLocked(pw, dumpPackage);
6390 } else if (DUMP_CONTAINERS_CMD.equals(cmd)) {
6391 dumpActivityContainersLocked(pw);
6392 } else if (DUMP_RECENTS_CMD.equals(cmd) || DUMP_RECENTS_SHORT_CMD.equals(cmd)) {
6393 if (getRecentTasks() != null) {
6394 getRecentTasks().dump(pw, dumpAll, dumpPackage);
6395 }
6396 }
6397 }
6398 }
6399
6400 @Override
6401 public boolean dumpForProcesses(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
6402 String dumpPackage, int dumpAppId, boolean needSep, boolean testPssMode,
6403 int wakefulness) {
6404 synchronized (mGlobalLock) {
6405 if (mHomeProcess != null && (dumpPackage == null
6406 || mHomeProcess.mPkgList.contains(dumpPackage))) {
6407 if (needSep) {
6408 pw.println();
6409 needSep = false;
6410 }
6411 pw.println(" mHomeProcess: " + mHomeProcess);
6412 }
6413 if (mPreviousProcess != null && (dumpPackage == null
6414 || mPreviousProcess.mPkgList.contains(dumpPackage))) {
6415 if (needSep) {
6416 pw.println();
6417 needSep = false;
6418 }
6419 pw.println(" mPreviousProcess: " + mPreviousProcess);
6420 }
6421 if (dumpAll && (mPreviousProcess == null || dumpPackage == null
6422 || mPreviousProcess.mPkgList.contains(dumpPackage))) {
6423 StringBuilder sb = new StringBuilder(128);
6424 sb.append(" mPreviousProcessVisibleTime: ");
6425 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
6426 pw.println(sb);
6427 }
6428 if (mHeavyWeightProcess != null && (dumpPackage == null
6429 || mHeavyWeightProcess.mPkgList.contains(dumpPackage))) {
6430 if (needSep) {
6431 pw.println();
6432 needSep = false;
6433 }
6434 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
6435 }
6436 if (dumpPackage == null) {
6437 pw.println(" mGlobalConfiguration: " + getGlobalConfiguration());
6438 mStackSupervisor.dumpDisplayConfigs(pw, " ");
6439 }
6440 if (dumpAll) {
6441 if (dumpPackage == null) {
6442 pw.println(" mConfigWillChange: "
6443 + getTopDisplayFocusedStack().mConfigWillChange);
6444 }
6445 if (mCompatModePackages.getPackages().size() > 0) {
6446 boolean printed = false;
6447 for (Map.Entry<String, Integer> entry
6448 : mCompatModePackages.getPackages().entrySet()) {
6449 String pkg = entry.getKey();
6450 int mode = entry.getValue();
6451 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
6452 continue;
6453 }
6454 if (!printed) {
6455 pw.println(" mScreenCompatPackages:");
6456 printed = true;
6457 }
6458 pw.println(" " + pkg + ": " + mode);
6459 }
6460 }
6461 }
6462
6463 if (dumpPackage == null) {
6464 pw.println(" mWakefulness="
6465 + PowerManagerInternal.wakefulnessToString(wakefulness));
6466 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
6467 if (mRunningVoice != null) {
6468 pw.println(" mRunningVoice=" + mRunningVoice);
6469 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
6470 }
6471 pw.println(" mSleeping=" + mSleeping);
6472 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + testPssMode);
6473 pw.println(" mVrController=" + mVrController);
6474 }
6475 if (mCurAppTimeTracker != null) {
6476 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
6477 }
6478 if (mAllowAppSwitchUids.size() > 0) {
6479 boolean printed = false;
6480 for (int i = 0; i < mAllowAppSwitchUids.size(); i++) {
6481 ArrayMap<String, Integer> types = mAllowAppSwitchUids.valueAt(i);
6482 for (int j = 0; j < types.size(); j++) {
6483 if (dumpPackage == null ||
6484 UserHandle.getAppId(types.valueAt(j).intValue()) == dumpAppId) {
6485 if (needSep) {
6486 pw.println();
6487 needSep = false;
6488 }
6489 if (!printed) {
6490 pw.println(" mAllowAppSwitchUids:");
6491 printed = true;
6492 }
6493 pw.print(" User ");
6494 pw.print(mAllowAppSwitchUids.keyAt(i));
6495 pw.print(": Type ");
6496 pw.print(types.keyAt(j));
6497 pw.print(" = ");
6498 UserHandle.formatUid(pw, types.valueAt(j).intValue());
6499 pw.println();
6500 }
6501 }
6502 }
6503 }
6504 if (dumpPackage == null) {
6505 if (mController != null) {
6506 pw.println(" mController=" + mController
6507 + " mControllerIsAMonkey=" + mControllerIsAMonkey);
6508 }
6509 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
6510 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
6511 }
6512
6513 return needSep;
6514 }
6515 }
6516
6517 @Override
6518 public void writeProcessesToProto(ProtoOutputStream proto, String dumpPackage) {
6519 synchronized (mGlobalLock) {
6520 if (dumpPackage == null) {
6521 getGlobalConfiguration().writeToProto(proto, GLOBAL_CONFIGURATION);
6522 proto.write(CONFIG_WILL_CHANGE, getTopDisplayFocusedStack().mConfigWillChange);
6523 writeSleepStateToProto(proto);
6524 if (mController != null) {
6525 final long token = proto.start(CONTROLLER);
6526 proto.write(CONTROLLER, mController.toString());
6527 proto.write(IS_A_MONKEY, mControllerIsAMonkey);
6528 proto.end(token);
6529 }
6530 mStackSupervisor.mGoingToSleep.writeToProto(proto, GOING_TO_SLEEP);
6531 mStackSupervisor.mLaunchingActivity.writeToProto(proto, LAUNCHING_ACTIVITY);
6532 }
6533
6534 if (mHomeProcess != null && (dumpPackage == null
6535 || mHomeProcess.mPkgList.contains(dumpPackage))) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07006536 mHomeProcess.writeToProto(proto, HOME_PROC);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006537 }
6538
6539 if (mPreviousProcess != null && (dumpPackage == null
6540 || mPreviousProcess.mPkgList.contains(dumpPackage))) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07006541 mPreviousProcess.writeToProto(proto, PREVIOUS_PROC);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006542 proto.write(PREVIOUS_PROC_VISIBLE_TIME_MS, mPreviousProcessVisibleTime);
6543 }
6544
6545 if (mHeavyWeightProcess != null && (dumpPackage == null
6546 || mHeavyWeightProcess.mPkgList.contains(dumpPackage))) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07006547 mHeavyWeightProcess.writeToProto(proto, HEAVY_WEIGHT_PROC);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006548 }
6549
6550 for (Map.Entry<String, Integer> entry
6551 : mCompatModePackages.getPackages().entrySet()) {
6552 String pkg = entry.getKey();
6553 int mode = entry.getValue();
6554 if (dumpPackage == null || dumpPackage.equals(pkg)) {
6555 long compatToken = proto.start(SCREEN_COMPAT_PACKAGES);
6556 proto.write(PACKAGE, pkg);
6557 proto.write(MODE, mode);
6558 proto.end(compatToken);
6559 }
6560 }
6561
6562 if (mCurAppTimeTracker != null) {
6563 mCurAppTimeTracker.writeToProto(proto, CURRENT_TRACKER, true);
6564 }
6565
6566 }
6567 }
6568
6569 @Override
6570 public boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name,
6571 String[] args, int opti, boolean dumpAll, boolean dumpVisibleStacksOnly,
6572 boolean dumpFocusedStackOnly) {
6573 synchronized (mGlobalLock) {
6574 return ActivityTaskManagerService.this.dumpActivity(fd, pw, name, args, opti,
6575 dumpAll, dumpVisibleStacksOnly, dumpFocusedStackOnly);
6576 }
6577 }
6578
6579 @Override
6580 public boolean canGcNow() {
6581 synchronized (mGlobalLock) {
6582 return isSleeping() || mStackSupervisor.allResumedActivitiesIdle();
6583 }
6584 }
6585
6586 @Override
6587 public WindowProcessController getTopApp() {
6588 synchronized (mGlobalLock) {
6589 final ActivityRecord top = mStackSupervisor.getTopResumedActivity();
6590 return top != null ? top.app : null;
6591 }
6592 }
6593
6594 @Override
6595 public void rankTaskLayersIfNeeded() {
6596 synchronized (mGlobalLock) {
6597 if (mStackSupervisor != null) {
6598 mStackSupervisor.rankTaskLayersIfNeeded();
6599 }
6600 }
6601 }
6602
6603 @Override
6604 public void scheduleDestroyAllActivities(String reason) {
6605 synchronized (mGlobalLock) {
6606 mStackSupervisor.scheduleDestroyAllActivities(null, reason);
6607 }
6608 }
6609
6610 @Override
6611 public void removeUser(int userId) {
6612 synchronized (mGlobalLock) {
6613 mStackSupervisor.removeUserLocked(userId);
6614 }
6615 }
6616
6617 @Override
6618 public boolean switchUser(int userId, UserState userState) {
6619 synchronized (mGlobalLock) {
6620 return mStackSupervisor.switchUserLocked(userId, userState);
6621 }
6622 }
6623
6624 @Override
6625 public void onHandleAppCrash(WindowProcessController wpc) {
6626 synchronized (mGlobalLock) {
6627 mStackSupervisor.handleAppCrashLocked(wpc);
6628 }
6629 }
Wale Ogunwale64258362018-10-16 15:13:37 -07006630
6631 @Override
6632 public int finishTopCrashedActivities(WindowProcessController crashedApp, String reason) {
6633 synchronized (mGlobalLock) {
6634 return mStackSupervisor.finishTopCrashedActivitiesLocked(crashedApp, reason);
6635 }
6636 }
Wale Ogunwalebff2df42018-10-18 17:09:19 -07006637
6638 @Override
6639 public void onUidActive(int uid, int procState) {
6640 synchronized (mGlobalLock) {
6641 mActiveUids.put(uid, procState);
6642 }
6643 }
6644
6645 @Override
6646 public void onUidInactive(int uid) {
6647 synchronized (mGlobalLock) {
6648 mActiveUids.remove(uid);
6649 }
6650 }
6651
6652 @Override
6653 public void onActiveUidsCleared() {
6654 synchronized (mGlobalLock) {
6655 mActiveUids.clear();
6656 }
6657 }
6658
6659 @Override
6660 public void onUidProcStateChanged(int uid, int procState) {
6661 synchronized (mGlobalLock) {
6662 if (mActiveUids.get(uid) != null) {
6663 mActiveUids.put(uid, procState);
6664 }
6665 }
6666 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07006667 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07006668}