blob: 5b0a4a9b05963762bd204677348244a242726f82 [file] [log] [blame]
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.server.am;
18
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070019import static android.Manifest.permission.BIND_VOICE_INTERACTION;
20import static android.Manifest.permission.CHANGE_CONFIGURATION;
21import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
22import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070023import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070024import static android.Manifest.permission.READ_FRAME_BUFFER;
25import static android.Manifest.permission.REMOVE_TASKS;
26import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070027import static android.Manifest.permission.STOP_APP_SWITCHES;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070028import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
Wale Ogunwalebff2df42018-10-18 17:09:19 -070029import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
Evan Rosky4505b352018-09-06 11:20:40 -070030import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
Yunfan Chen79b96062018-10-17 12:45:23 -070031import static android.app.ActivityTaskManager.INVALID_TASK_ID;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070032import static android.app.ActivityTaskManager.RESIZE_MODE_PRESERVE_WINDOW;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070033import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
34import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070035import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
36import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070037import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
38import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070039import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070040import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Wale Ogunwale31913b52018-10-13 08:29:31 -070041import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070042import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
Wale Ogunwale31913b52018-10-13 08:29:31 -070043import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
Wale Ogunwale214f3482018-10-04 11:00:47 -070044import static android.content.pm.ApplicationInfo.FLAG_FACTORY_TEST;
Wale Ogunwale342fbe92018-10-09 08:44:10 -070045import static android.content.pm.ConfigurationInfo.GL_ES_VERSION_UNDEFINED;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070046import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
47import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
Evan Rosky4505b352018-09-06 11:20:40 -070048import static android.content.pm.PackageManager.FEATURE_PC;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070049import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070050import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070051import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
52import static android.os.Build.VERSION_CODES.N;
Wale Ogunwale214f3482018-10-04 11:00:47 -070053import static android.os.FactoryTest.FACTORY_TEST_HIGH_LEVEL;
54import static android.os.FactoryTest.FACTORY_TEST_LOW_LEVEL;
55import static android.os.FactoryTest.FACTORY_TEST_OFF;
Wale Ogunwale31913b52018-10-13 08:29:31 -070056import static android.os.Process.FIRST_APPLICATION_UID;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070057import static android.os.Process.SYSTEM_UID;
Evan Rosky4505b352018-09-06 11:20:40 -070058import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070059import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
60import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
61import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
62import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
Evan Rosky4505b352018-09-06 11:20:40 -070063import static android.provider.Settings.Global.HIDE_ERROR_DIALOGS;
64import static android.provider.Settings.System.FONT_SCALE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070065import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
66import static android.view.Display.DEFAULT_DISPLAY;
67import static android.view.Display.INVALID_DISPLAY;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070068import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
Wale Ogunwale6767eae2018-05-03 15:52:51 -070069import static android.view.WindowManager.TRANSIT_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070070import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070071import static android.view.WindowManager.TRANSIT_TASK_OPEN;
72import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
Evan Rosky4505b352018-09-06 11:20:40 -070073
Yunfan Chen79b96062018-10-17 12:45:23 -070074import static com.android.server.am.ActivityManagerService.ANR_TRACE_DIR;
75import static com.android.server.am.ActivityManagerService.MY_PID;
76import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS;
77import static com.android.server.am.ActivityManagerService.dumpStackTraces;
Wale Ogunwale31913b52018-10-13 08:29:31 -070078import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.CONFIG_WILL_CHANGE;
79import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.CONTROLLER;
80import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.CURRENT_TRACKER;
81import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.Controller.IS_A_MONKEY;
82import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.GLOBAL_CONFIGURATION;
83import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.GOING_TO_SLEEP;
84import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.HEAVY_WEIGHT_PROC;
85import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.HOME_PROC;
86import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.LAUNCHING_ACTIVITY;
87import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC;
Yunfan Chen79b96062018-10-17 12:45:23 -070088import static com.android.server.am.ActivityManagerServiceDumpProcessesProto
89 .PREVIOUS_PROC_VISIBLE_TIME_MS;
Wale Ogunwale31913b52018-10-13 08:29:31 -070090import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.SCREEN_COMPAT_PACKAGES;
Yunfan Chen79b96062018-10-17 12:45:23 -070091import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage
92 .MODE;
93import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage
94 .PACKAGE;
95import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
96import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
97import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
98import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
99import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
100import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
101import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
Wale Ogunwale98875612018-10-12 07:53:02 -0700102import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_ALL;
103import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
104import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_FOCUS;
105import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_IMMERSIVE;
106import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_LOCKTASK;
107import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_STACK;
108import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
109import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
110import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_VISIBILITY;
111import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
112import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS;
113import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_IMMERSIVE;
114import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_LOCKTASK;
115import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_STACK;
116import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH;
117import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_VISIBILITY;
118import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_ATM;
119import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
Evan Rosky4505b352018-09-06 11:20:40 -0700120import static com.android.server.am.ActivityTaskManagerService.H.REPORT_TIME_TRACKER_MSG;
121import static com.android.server.am.ActivityTaskManagerService.UiHandler.DISMISS_DIALOG_UI_MSG;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700122import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700123import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700124import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
Evan Rosky4505b352018-09-06 11:20:40 -0700125import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT;
126import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_DATA;
127import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
128import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700129import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
130import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700131
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700132import android.Manifest;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700133import android.annotation.NonNull;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700134import android.annotation.Nullable;
135import android.annotation.UserIdInt;
136import android.app.Activity;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700137import android.app.ActivityManager;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700138import android.app.ActivityManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700139import android.app.ActivityOptions;
140import android.app.ActivityTaskManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700141import android.app.ActivityThread;
142import android.app.AlertDialog;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700143import android.app.AppGlobals;
Evan Rosky4505b352018-09-06 11:20:40 -0700144import android.app.Dialog;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700145import android.app.IActivityController;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700146import android.app.IActivityTaskManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700147import android.app.IApplicationThread;
148import android.app.IAssistDataReceiver;
Wale Ogunwale53783742018-09-16 10:21:51 -0700149import android.app.INotificationManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700150import android.app.ITaskStackListener;
Wale Ogunwale53783742018-09-16 10:21:51 -0700151import android.app.Notification;
152import android.app.NotificationManager;
153import android.app.PendingIntent;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700154import android.app.PictureInPictureParams;
155import android.app.ProfilerInfo;
156import android.app.RemoteAction;
157import android.app.WaitResult;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700158import android.app.WindowConfiguration;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700159import android.app.admin.DevicePolicyCache;
160import android.app.assist.AssistContent;
161import android.app.assist.AssistStructure;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700162import android.app.usage.UsageStatsManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700163import android.content.ActivityNotFoundException;
164import android.content.ComponentName;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700165import android.content.ContentResolver;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700166import android.content.Context;
Evan Rosky4505b352018-09-06 11:20:40 -0700167import android.content.DialogInterface;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700168import android.content.IIntentSender;
169import android.content.Intent;
170import android.content.pm.ActivityInfo;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700171import android.content.pm.ApplicationInfo;
Yunfan Chen75157d72018-07-27 14:47:21 +0900172import android.content.pm.ConfigurationInfo;
Evan Rosky4505b352018-09-06 11:20:40 -0700173import android.content.pm.IPackageManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700174import android.content.pm.PackageManager;
Evan Rosky4505b352018-09-06 11:20:40 -0700175import android.content.pm.PackageManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700176import android.content.pm.ParceledListSlice;
177import android.content.pm.ResolveInfo;
Wale Ogunwale53783742018-09-16 10:21:51 -0700178import android.content.res.CompatibilityInfo;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700179import android.content.res.Configuration;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700180import android.content.res.Resources;
Evan Rosky4505b352018-09-06 11:20:40 -0700181import android.database.ContentObserver;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700182import android.graphics.Bitmap;
183import android.graphics.Point;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700184import android.graphics.Rect;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700185import android.metrics.LogMaker;
186import android.net.Uri;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700187import android.os.Binder;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700188import android.os.Build;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700189import android.os.Bundle;
Wale Ogunwale214f3482018-10-04 11:00:47 -0700190import android.os.FactoryTest;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700191import android.os.FileUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700192import android.os.Handler;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700193import android.os.IBinder;
Evan Rosky4505b352018-09-06 11:20:40 -0700194import android.os.IUserManager;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700195import android.os.LocaleList;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700196import android.os.Looper;
197import android.os.Message;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700198import android.os.PersistableBundle;
Evan Rosky4505b352018-09-06 11:20:40 -0700199import android.os.PowerManager;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700200import android.os.PowerManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700201import android.os.RemoteException;
Evan Rosky4505b352018-09-06 11:20:40 -0700202import android.os.ServiceManager;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700203import android.os.StrictMode;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700204import android.os.SystemClock;
205import android.os.SystemProperties;
Evan Rosky4505b352018-09-06 11:20:40 -0700206import android.os.Trace;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700207import android.os.UpdateLock;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700208import android.os.UserHandle;
Evan Rosky4505b352018-09-06 11:20:40 -0700209import android.os.UserManager;
210import android.os.WorkSource;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700211import android.os.storage.IStorageManager;
212import android.os.storage.StorageManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700213import android.provider.Settings;
214import android.service.voice.IVoiceInteractionSession;
215import android.service.voice.VoiceInteractionManagerInternal;
216import android.telecom.TelecomManager;
217import android.text.TextUtils;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700218import android.text.format.Time;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700219import android.util.ArrayMap;
220import android.util.EventLog;
221import android.util.Log;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700222import android.util.Slog;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700223import android.util.SparseArray;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700224import android.util.SparseIntArray;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700225import android.util.StatsLog;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700226import android.util.TimeUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700227import android.util.proto.ProtoOutputStream;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700228import android.view.IRecentsAnimationRunner;
229import android.view.RemoteAnimationAdapter;
230import android.view.RemoteAnimationDefinition;
Evan Rosky4505b352018-09-06 11:20:40 -0700231import android.view.WindowManager;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700232
Evan Rosky4505b352018-09-06 11:20:40 -0700233import com.android.internal.R;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700234import com.android.internal.annotations.VisibleForTesting;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700235import com.android.internal.app.AssistUtils;
Evan Rosky4505b352018-09-06 11:20:40 -0700236import com.android.internal.app.IAppOpsService;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700237import com.android.internal.app.IVoiceInteractor;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700238import com.android.internal.app.ProcessMap;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700239import com.android.internal.logging.MetricsLogger;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700240import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Wale Ogunwale53783742018-09-16 10:21:51 -0700241import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
242import com.android.internal.notification.SystemNotificationChannels;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700243import com.android.internal.os.TransferPipe;
Evan Rosky4505b352018-09-06 11:20:40 -0700244import com.android.internal.os.logging.MetricsLoggerWrapper;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700245import com.android.internal.policy.IKeyguardDismissCallback;
246import com.android.internal.policy.KeyguardDismissCallback;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700247import com.android.internal.util.ArrayUtils;
248import com.android.internal.util.FastPrintWriter;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700249import com.android.internal.util.Preconditions;
Wale Ogunwale53783742018-09-16 10:21:51 -0700250import com.android.internal.util.function.pooled.PooledLambda;
Evan Rosky4505b352018-09-06 11:20:40 -0700251import com.android.server.AppOpsService;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700252import com.android.server.AttributeCache;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700253import com.android.server.LocalServices;
254import com.android.server.SystemService;
Evan Rosky4505b352018-09-06 11:20:40 -0700255import com.android.server.SystemServiceManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700256import com.android.server.Watchdog;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700257import com.android.server.firewall.IntentFirewall;
Evan Rosky4505b352018-09-06 11:20:40 -0700258import com.android.server.pm.UserManagerService;
259import com.android.server.uri.UriGrantsManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700260import com.android.server.vr.VrManagerInternal;
Evan Rosky4505b352018-09-06 11:20:40 -0700261import com.android.server.wm.ActivityTaskManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700262import com.android.server.wm.PinnedStackWindowController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700263import com.android.server.wm.WindowManagerService;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700264
Wale Ogunwale31913b52018-10-13 08:29:31 -0700265import java.io.BufferedReader;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700266import java.io.File;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700267import java.io.FileDescriptor;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700268import java.io.FileOutputStream;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700269import java.io.FileReader;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700270import java.io.IOException;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700271import java.io.PrintWriter;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700272import java.io.StringWriter;
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700273import java.lang.ref.WeakReference;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700274import java.text.DateFormat;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700275import java.util.ArrayList;
Wale Ogunwale27c48ae2018-10-25 19:01:01 -0700276import java.util.Arrays;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700277import java.util.Date;
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700278import java.util.HashSet;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700279import java.util.List;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700280import java.util.Locale;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700281import java.util.Map;
282import java.util.Set;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700283
284/**
285 * System service for managing activities and their containers (task, stacks, displays,... ).
286 *
287 * {@hide}
288 */
289public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
Wale Ogunwale98875612018-10-12 07:53:02 -0700290 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityTaskManagerService" : TAG_ATM;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700291 private static final String TAG_STACK = TAG + POSTFIX_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700292 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
293 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
294 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
295 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
296 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700297 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700298
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700299 // How long we wait until we timeout on key dispatching.
Wale Ogunwale51cc98a2018-10-15 10:41:05 -0700300 public static final int KEY_DISPATCHING_TIMEOUT_MS = 5 * 1000;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700301 // How long we wait until we timeout on key dispatching during instrumentation.
Wale Ogunwale51cc98a2018-10-15 10:41:05 -0700302 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS = 60 * 1000;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700303
Wale Ogunwale98875612018-10-12 07:53:02 -0700304 /** Used to indicate that an app transition should be animated. */
305 static final boolean ANIMATE = true;
306
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700307 /** Hardware-reported OpenGLES version. */
308 final int GL_ES_VERSION;
309
Wale Ogunwale31913b52018-10-13 08:29:31 -0700310 public static final String DUMP_ACTIVITIES_CMD = "activities" ;
311 public static final String DUMP_ACTIVITIES_SHORT_CMD = "a" ;
312 public static final String DUMP_LASTANR_CMD = "lastanr" ;
313 public static final String DUMP_LASTANR_TRACES_CMD = "lastanr-traces" ;
314 public static final String DUMP_STARTER_CMD = "starter" ;
315 public static final String DUMP_CONTAINERS_CMD = "containers" ;
316 public static final String DUMP_RECENTS_CMD = "recents" ;
317 public static final String DUMP_RECENTS_SHORT_CMD = "r" ;
318
Wale Ogunwale64258362018-10-16 15:13:37 -0700319 /** This activity is not being relaunched, or being relaunched for a non-resize reason. */
320 public static final int RELAUNCH_REASON_NONE = 0;
321 /** This activity is being relaunched due to windowing mode change. */
322 public static final int RELAUNCH_REASON_WINDOWING_MODE_RESIZE = 1;
323 /** This activity is being relaunched due to a free-resize operation. */
324 public static final int RELAUNCH_REASON_FREE_RESIZE = 2;
325
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700326 Context mContext;
Wale Ogunwale64258362018-10-16 15:13:37 -0700327
Wale Ogunwalef6733932018-06-27 05:14:34 -0700328 /**
329 * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
330 * change at runtime. Use mContext for non-UI purposes.
331 */
332 final Context mUiContext;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700333 final ActivityThread mSystemThread;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700334 H mH;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700335 UiHandler mUiHandler;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700336 ActivityManagerInternal mAmInternal;
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700337 UriGrantsManagerInternal mUgmInternal;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700338 private PackageManagerInternal mPmInternal;
Wale Ogunwale53783742018-09-16 10:21:51 -0700339 private ActivityTaskManagerInternal mInternal;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700340 PowerManagerInternal mPowerManagerInternal;
341 private UsageStatsManagerInternal mUsageStatsInternal;
342
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700343 PendingIntentController mPendingIntentController;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700344 IntentFirewall mIntentFirewall;
345
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700346 /* Global service lock used by the package the owns this service. */
347 Object mGlobalLock;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700348 ActivityStackSupervisor mStackSupervisor;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700349 WindowManagerService mWindowManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700350 private UserManagerService mUserManager;
351 private AppOpsService mAppOpsService;
Wale Ogunwalebff2df42018-10-18 17:09:19 -0700352 /** All active uids in the system. */
Wale Ogunwale9de19442018-10-18 19:05:03 -0700353 private final SparseArray<Integer> mActiveUids = new SparseArray<>();
354 private final SparseArray<String> mPendingTempWhitelist = new SparseArray<>();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700355 /** All processes currently running that might have a window organized by name. */
356 final ProcessMap<WindowProcessController> mProcessNames = new ProcessMap<>();
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700357 /** All processes we currently have running mapped by pid */
358 final SparseArray<WindowProcessController> mPidMap = new SparseArray<>();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700359 /** This is the process holding what we currently consider to be the "home" activity. */
360 WindowProcessController mHomeProcess;
Wale Ogunwale53783742018-09-16 10:21:51 -0700361 /** The currently running heavy-weight process, if any. */
362 WindowProcessController mHeavyWeightProcess = null;
Wale Ogunwale214f3482018-10-04 11:00:47 -0700363 boolean mHasHeavyWeightFeature;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700364 /**
365 * This is the process holding the activity the user last visited that is in a different process
366 * from the one they are currently in.
367 */
368 WindowProcessController mPreviousProcess;
369 /** The time at which the previous process was last visible. */
370 long mPreviousProcessVisibleTime;
371
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700372 /** List of intents that were used to start the most recent tasks. */
373 private RecentTasks mRecentTasks;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700374 /** State of external calls telling us if the device is awake or asleep. */
375 private boolean mKeyguardShown = false;
376
377 // Wrapper around VoiceInteractionServiceManager
378 private AssistUtils mAssistUtils;
379
380 // VoiceInteraction session ID that changes for each new request except when
381 // being called for multi-window assist in a single session.
382 private int mViSessionId = 1000;
383
384 // How long to wait in getAssistContextExtras for the activity and foreground services
385 // to respond with the result.
386 private static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
387
388 // How long top wait when going through the modern assist (which doesn't need to block
389 // on getting this result before starting to launch its UI).
390 private static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
391
392 // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
393 private static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
394
395 private final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
396
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700397 // Keeps track of the active voice interaction service component, notified from
398 // VoiceInteractionManagerService
399 ComponentName mActiveVoiceInteractionServiceComponent;
400
Wale Ogunwalee2172292018-10-25 10:11:10 -0700401 VrController mVrController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700402 KeyguardController mKeyguardController;
403 private final ClientLifecycleManager mLifecycleManager;
404 private TaskChangeNotificationController mTaskChangeNotificationController;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700405 /** The controller for all operations related to locktask. */
406 private LockTaskController mLockTaskController;
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700407 private ActivityStartController mActivityStartController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700408
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700409 boolean mSuppressResizeConfigChanges;
410
411 private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
412 new UpdateConfigurationResult();
413
414 static final class UpdateConfigurationResult {
415 // Configuration changes that were updated.
416 int changes;
417 // If the activity was relaunched to match the new configuration.
418 boolean activityRelaunched;
419
420 void reset() {
421 changes = 0;
422 activityRelaunched = false;
423 }
424 }
425
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700426 /** Current sequencing integer of the configuration, for skipping old configurations. */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700427 private int mConfigurationSeq;
428 // To cache the list of supported system locales
429 private String[] mSupportedSystemLocales = null;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700430
431 /**
432 * Temp object used when global and/or display override configuration is updated. It is also
433 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
434 * anyone...
435 */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700436 private Configuration mTempConfig = new Configuration();
437
Wale Ogunwalef6733932018-06-27 05:14:34 -0700438 /** Temporary to avoid allocations. */
439 final StringBuilder mStringBuilder = new StringBuilder(256);
440
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700441 // Amount of time after a call to stopAppSwitches() during which we will
442 // prevent further untrusted switches from happening.
443 private static final long APP_SWITCH_DELAY_TIME = 5 * 1000;
444
445 /**
446 * The time at which we will allow normal application switches again,
447 * after a call to {@link #stopAppSwitches()}.
448 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700449 private long mAppSwitchesAllowedTime;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700450 /**
451 * This is set to true after the first switch after mAppSwitchesAllowedTime
452 * is set; any switches after that will clear the time.
453 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700454 private boolean mDidAppSwitch;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700455
456 IActivityController mController = null;
457 boolean mControllerIsAMonkey = false;
458
Wale Ogunwale214f3482018-10-04 11:00:47 -0700459 final int mFactoryTest;
460
461 /** Used to control how we initialize the service. */
462 ComponentName mTopComponent;
463 String mTopAction = Intent.ACTION_MAIN;
464 String mTopData;
465
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700466 /**
Wale Ogunwale31913b52018-10-13 08:29:31 -0700467 * Dump of the activity state at the time of the last ANR. Cleared after
468 * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
469 */
470 String mLastANRState;
471
472 /**
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700473 * Used to retain an update lock when the foreground activity is in
474 * immersive mode.
475 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700476 private final UpdateLock mUpdateLock = new UpdateLock("immersive");
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700477
478 /**
479 * Packages that are being allowed to perform unrestricted app switches. Mapping is
480 * User -> Type -> uid.
481 */
482 final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
483
484 /** The dimensions of the thumbnails in the Recents UI. */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700485 private int mThumbnailWidth;
486 private int mThumbnailHeight;
487 private float mFullscreenThumbnailScale;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700488
489 /**
490 * Flag that indicates if multi-window is enabled.
491 *
492 * For any particular form of multi-window to be enabled, generic multi-window must be enabled
493 * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
494 * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
495 * At least one of the forms of multi-window must be enabled in order for this flag to be
496 * initialized to 'true'.
497 *
498 * @see #mSupportsSplitScreenMultiWindow
499 * @see #mSupportsFreeformWindowManagement
500 * @see #mSupportsPictureInPicture
501 * @see #mSupportsMultiDisplay
502 */
503 boolean mSupportsMultiWindow;
504 boolean mSupportsSplitScreenMultiWindow;
505 boolean mSupportsFreeformWindowManagement;
506 boolean mSupportsPictureInPicture;
507 boolean mSupportsMultiDisplay;
508 boolean mForceResizableActivities;
509
510 final List<ActivityTaskManagerInternal.ScreenObserver> mScreenObservers = new ArrayList<>();
511
512 // VR Vr2d Display Id.
513 int mVr2dDisplayId = INVALID_DISPLAY;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700514
Wale Ogunwalef6733932018-06-27 05:14:34 -0700515 /**
516 * Set while we are wanting to sleep, to prevent any
517 * activities from being started/resumed.
518 *
519 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
520 *
521 * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
522 * while in the sleep state until there is a pending transition out of sleep, in which case
523 * mSleeping is set to false, and remains false while awake.
524 *
525 * Whether mSleeping can quickly toggled between true/false without the device actually
526 * display changing states is undefined.
527 */
528 private boolean mSleeping = false;
529
530 /**
531 * The process state used for processes that are running the top activities.
532 * This changes between TOP and TOP_SLEEPING to following mSleeping.
533 */
534 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
535
536 // Whether we should show our dialogs (ANR, crash, etc) or just perform their default action
537 // automatically. Important for devices without direct input devices.
538 private boolean mShowDialogs = true;
539
540 /** Set if we are shutting down the system, similar to sleeping. */
541 boolean mShuttingDown = false;
542
543 /**
544 * We want to hold a wake lock while running a voice interaction session, since
545 * this may happen with the screen off and we need to keep the CPU running to
546 * be able to continue to interact with the user.
547 */
548 PowerManager.WakeLock mVoiceWakeLock;
549
550 /**
551 * Set while we are running a voice interaction. This overrides sleeping while it is active.
552 */
553 IVoiceInteractionSession mRunningVoice;
554
555 /**
556 * The last resumed activity. This is identical to the current resumed activity most
557 * of the time but could be different when we're pausing one activity before we resume
558 * another activity.
559 */
560 ActivityRecord mLastResumedActivity;
561
562 /**
563 * The activity that is currently being traced as the active resumed activity.
564 *
565 * @see #updateResumedAppTrace
566 */
567 private @Nullable ActivityRecord mTracedResumedActivity;
568
569 /** If non-null, we are tracking the time the user spends in the currently focused app. */
570 AppTimeTracker mCurAppTimeTracker;
571
Wale Ogunwale008163e2018-07-23 23:11:08 -0700572 private AppWarnings mAppWarnings;
573
Wale Ogunwale53783742018-09-16 10:21:51 -0700574 /**
575 * Packages that the user has asked to have run in screen size
576 * compatibility mode instead of filling the screen.
577 */
578 CompatModePackages mCompatModePackages;
579
Wale Ogunwalef6733932018-06-27 05:14:34 -0700580 private FontScaleSettingObserver mFontScaleSettingObserver;
581
582 private final class FontScaleSettingObserver extends ContentObserver {
583 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
584 private final Uri mHideErrorDialogsUri = Settings.Global.getUriFor(HIDE_ERROR_DIALOGS);
585
586 public FontScaleSettingObserver() {
587 super(mH);
588 final ContentResolver resolver = mContext.getContentResolver();
589 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
590 resolver.registerContentObserver(mHideErrorDialogsUri, false, this,
591 UserHandle.USER_ALL);
592 }
593
594 @Override
595 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
596 if (mFontScaleUri.equals(uri)) {
597 updateFontScaleIfNeeded(userId);
598 } else if (mHideErrorDialogsUri.equals(uri)) {
599 synchronized (mGlobalLock) {
600 updateShouldShowDialogsLocked(getGlobalConfiguration());
601 }
602 }
603 }
604 }
605
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700606 ActivityTaskManagerService(Context context) {
607 mContext = context;
Wale Ogunwale214f3482018-10-04 11:00:47 -0700608 mFactoryTest = FactoryTest.getMode();
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700609 mSystemThread = ActivityThread.currentActivityThread();
610 mUiContext = mSystemThread.getSystemUiContext();
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700611 mLifecycleManager = new ClientLifecycleManager();
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700612 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", GL_ES_VERSION_UNDEFINED);
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700613 }
614
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700615 public void onSystemReady() {
616 synchronized (mGlobalLock) {
617 mHasHeavyWeightFeature = mContext.getPackageManager().hasSystemFeature(
618 PackageManager.FEATURE_CANT_SAVE_STATE);
619 mAssistUtils = new AssistUtils(mContext);
620 mVrController.onSystemReady();
621 mRecentTasks.onSystemReadyLocked();
622 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700623 }
624
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700625 public void onInitPowerManagement() {
626 synchronized (mGlobalLock) {
627 mStackSupervisor.initPowerManagement();
628 final PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
629 mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
630 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
631 mVoiceWakeLock.setReferenceCounted(false);
632 }
Wale Ogunwalef6733932018-06-27 05:14:34 -0700633 }
634
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700635 public void installSystemProviders() {
Wale Ogunwalef6733932018-06-27 05:14:34 -0700636 mFontScaleSettingObserver = new FontScaleSettingObserver();
637 }
638
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700639 void retrieveSettings(ContentResolver resolver) {
640 final boolean freeformWindowManagement =
641 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
642 || Settings.Global.getInt(
643 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
644
645 final boolean supportsMultiWindow = ActivityTaskManager.supportsMultiWindow(mContext);
646 final boolean supportsPictureInPicture = supportsMultiWindow &&
647 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
648 final boolean supportsSplitScreenMultiWindow =
649 ActivityTaskManager.supportsSplitScreenMultiWindow(mContext);
650 final boolean supportsMultiDisplay = mContext.getPackageManager()
651 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
652 final boolean alwaysFinishActivities =
653 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
654 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
655 final boolean forceResizable = Settings.Global.getInt(
656 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
Garfield Tane0846042018-07-26 13:42:04 -0700657 final boolean isPc = mContext.getPackageManager().hasSystemFeature(FEATURE_PC);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700658
659 // Transfer any global setting for forcing RTL layout, into a System Property
660 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
661
662 final Configuration configuration = new Configuration();
663 Settings.System.getConfiguration(resolver, configuration);
664 if (forceRtl) {
665 // This will take care of setting the correct layout direction flags
666 configuration.setLayoutDirection(configuration.locale);
667 }
668
669 synchronized (mGlobalLock) {
670 mForceResizableActivities = forceResizable;
671 final boolean multiWindowFormEnabled = freeformWindowManagement
672 || supportsSplitScreenMultiWindow
673 || supportsPictureInPicture
674 || supportsMultiDisplay;
675 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
676 mSupportsMultiWindow = true;
677 mSupportsFreeformWindowManagement = freeformWindowManagement;
678 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
679 mSupportsPictureInPicture = supportsPictureInPicture;
680 mSupportsMultiDisplay = supportsMultiDisplay;
681 } else {
682 mSupportsMultiWindow = false;
683 mSupportsFreeformWindowManagement = false;
684 mSupportsSplitScreenMultiWindow = false;
685 mSupportsPictureInPicture = false;
686 mSupportsMultiDisplay = false;
687 }
688 mWindowManager.setForceResizableTasks(mForceResizableActivities);
689 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
Garfield Tane0846042018-07-26 13:42:04 -0700690 mWindowManager.setSupportsFreeformWindowManagement(mSupportsFreeformWindowManagement);
691 mWindowManager.setIsPc(isPc);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700692 // This happens before any activities are started, so we can change global configuration
693 // in-place.
694 updateConfigurationLocked(configuration, null, true);
695 final Configuration globalConfig = getGlobalConfiguration();
696 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
697
698 // Load resources only after the current configuration has been set.
699 final Resources res = mContext.getResources();
700 mThumbnailWidth = res.getDimensionPixelSize(
701 com.android.internal.R.dimen.thumbnail_width);
702 mThumbnailHeight = res.getDimensionPixelSize(
703 com.android.internal.R.dimen.thumbnail_height);
704
705 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
706 mFullscreenThumbnailScale = (float) res
707 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
708 (float) globalConfig.screenWidthDp;
709 } else {
710 mFullscreenThumbnailScale = res.getFraction(
711 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
712 }
713 }
714 }
715
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700716 // TODO: Will be converted to WM lock once transition is complete.
Wale Ogunwale9de19442018-10-18 19:05:03 -0700717 void setActivityManagerService(Object globalLock, Looper looper,
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700718 IntentFirewall intentFirewall, PendingIntentController intentController) {
Wale Ogunwale9de19442018-10-18 19:05:03 -0700719 mGlobalLock = globalLock;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700720 mH = new H(looper);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700721 mUiHandler = new UiHandler();
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700722 mIntentFirewall = intentFirewall;
Wale Ogunwale53783742018-09-16 10:21:51 -0700723 final File systemDir = SystemServiceManager.ensureSystemDir();
724 mAppWarnings = new AppWarnings(this, mUiContext, mH, mUiHandler, systemDir);
725 mCompatModePackages = new CompatModePackages(this, systemDir, mH);
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700726 mPendingIntentController = intentController;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700727
728 mTempConfig.setToDefaults();
729 mTempConfig.setLocales(LocaleList.getDefault());
730 mConfigurationSeq = mTempConfig.seq = 1;
731 mStackSupervisor = createStackSupervisor();
732 mStackSupervisor.onConfigurationChanged(mTempConfig);
733
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700734 mTaskChangeNotificationController =
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700735 new TaskChangeNotificationController(mGlobalLock, mStackSupervisor, mH);
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700736 mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mH);
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700737 mActivityStartController = new ActivityStartController(this);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700738 mRecentTasks = createRecentTasks();
739 mStackSupervisor.setRecentTasks(mRecentTasks);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700740 mVrController = new VrController(mGlobalLock);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700741 mKeyguardController = mStackSupervisor.getKeyguardController();
742 }
743
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700744 public void onActivityManagerInternalAdded() {
745 synchronized (mGlobalLock) {
746 mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
747 mUgmInternal = LocalServices.getService(UriGrantsManagerInternal.class);
748 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700749 }
750
Yunfan Chen75157d72018-07-27 14:47:21 +0900751 int increaseConfigurationSeqLocked() {
752 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
753 return mConfigurationSeq;
754 }
755
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700756 protected ActivityStackSupervisor createStackSupervisor() {
757 final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mH.getLooper());
758 supervisor.initialize();
759 return supervisor;
760 }
761
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700762 public void setWindowManager(WindowManagerService wm) {
763 synchronized (mGlobalLock) {
764 mWindowManager = wm;
765 mLockTaskController.setWindowManager(wm);
766 mStackSupervisor.setWindowManager(wm);
767 }
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700768 }
769
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700770 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
771 synchronized (mGlobalLock) {
772 mUsageStatsInternal = usageStatsManager;
773 }
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700774 }
775
Wale Ogunwalef6733932018-06-27 05:14:34 -0700776 UserManagerService getUserManager() {
777 if (mUserManager == null) {
778 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
779 mUserManager = (UserManagerService) IUserManager.Stub.asInterface(b);
780 }
781 return mUserManager;
782 }
783
784 AppOpsService getAppOpsService() {
785 if (mAppOpsService == null) {
786 IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
787 mAppOpsService = (AppOpsService) IAppOpsService.Stub.asInterface(b);
788 }
789 return mAppOpsService;
790 }
791
792 boolean hasUserRestriction(String restriction, int userId) {
793 return getUserManager().hasUserRestriction(restriction, userId);
794 }
795
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700796 protected RecentTasks createRecentTasks() {
797 return new RecentTasks(this, mStackSupervisor);
798 }
799
800 RecentTasks getRecentTasks() {
801 return mRecentTasks;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700802 }
803
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700804 ClientLifecycleManager getLifecycleManager() {
805 return mLifecycleManager;
806 }
807
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700808 ActivityStartController getActivityStartController() {
809 return mActivityStartController;
810 }
811
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700812 TaskChangeNotificationController getTaskChangeNotificationController() {
813 return mTaskChangeNotificationController;
814 }
815
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700816 LockTaskController getLockTaskController() {
817 return mLockTaskController;
818 }
819
Yunfan Chen75157d72018-07-27 14:47:21 +0900820 /**
821 * Return the global configuration used by the process corresponding to the input pid. This is
822 * usually the global configuration with some overrides specific to that process.
823 */
824 Configuration getGlobalConfigurationForCallingPid() {
825 final int pid = Binder.getCallingPid();
826 if (pid == MY_PID || pid < 0) {
827 return getGlobalConfiguration();
828 }
829 synchronized (mGlobalLock) {
830 final WindowProcessController app = mPidMap.get(pid);
831 return app != null ? app.getConfiguration() : getGlobalConfiguration();
832 }
833 }
834
835 /**
836 * Return the device configuration info used by the process corresponding to the input pid.
837 * The value is consistent with the global configuration for the process.
838 */
839 @Override
840 public ConfigurationInfo getDeviceConfigurationInfo() {
841 ConfigurationInfo config = new ConfigurationInfo();
842 synchronized (mGlobalLock) {
843 final Configuration globalConfig = getGlobalConfigurationForCallingPid();
844 config.reqTouchScreen = globalConfig.touchscreen;
845 config.reqKeyboardType = globalConfig.keyboard;
846 config.reqNavigation = globalConfig.navigation;
847 if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
848 || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
849 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
850 }
851 if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
852 && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
853 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
854 }
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700855 config.reqGlEsVersion = GL_ES_VERSION;
Yunfan Chen75157d72018-07-27 14:47:21 +0900856 }
857 return config;
858 }
859
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700860 private void start() {
Wale Ogunwale53783742018-09-16 10:21:51 -0700861 mInternal = new LocalService();
862 LocalServices.addService(ActivityTaskManagerInternal.class, mInternal);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700863 }
864
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700865 public static final class Lifecycle extends SystemService {
866 private final ActivityTaskManagerService mService;
867
868 public Lifecycle(Context context) {
869 super(context);
870 mService = new ActivityTaskManagerService(context);
871 }
872
873 @Override
874 public void onStart() {
875 publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700876 mService.start();
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700877 }
878
879 public ActivityTaskManagerService getService() {
880 return mService;
881 }
882 }
883
884 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700885 public final int startActivity(IApplicationThread caller, String callingPackage,
886 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
887 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
888 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
889 resultWho, requestCode, startFlags, profilerInfo, bOptions,
890 UserHandle.getCallingUserId());
891 }
892
893 @Override
894 public final int startActivities(IApplicationThread caller, String callingPackage,
895 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
896 int userId) {
897 final String reason = "startActivities";
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700898 enforceNotIsolatedCaller(reason);
899 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, reason);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700900 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700901 return getActivityStartController().startActivities(caller, -1, callingPackage, intents,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100902 resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId, reason,
903 null /* originatingPendingIntent */);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700904 }
905
906 @Override
907 public int startActivityAsUser(IApplicationThread caller, String callingPackage,
908 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
909 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
910 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
911 resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
912 true /*validateIncomingUser*/);
913 }
914
915 int startActivityAsUser(IApplicationThread caller, String callingPackage,
916 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
917 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
918 boolean validateIncomingUser) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700919 enforceNotIsolatedCaller("startActivityAsUser");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700920
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700921 userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700922 Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
923
924 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700925 return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700926 .setCaller(caller)
927 .setCallingPackage(callingPackage)
928 .setResolvedType(resolvedType)
929 .setResultTo(resultTo)
930 .setResultWho(resultWho)
931 .setRequestCode(requestCode)
932 .setStartFlags(startFlags)
933 .setProfilerInfo(profilerInfo)
934 .setActivityOptions(bOptions)
935 .setMayWait(userId)
936 .execute();
937
938 }
939
940 @Override
941 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
942 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700943 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions) {
944 enforceNotIsolatedCaller("startActivityIntentSender");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700945 // Refuse possible leaked file descriptors
946 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
947 throw new IllegalArgumentException("File descriptors passed in Intent");
948 }
949
950 if (!(target instanceof PendingIntentRecord)) {
951 throw new IllegalArgumentException("Bad PendingIntent object");
952 }
953
954 PendingIntentRecord pir = (PendingIntentRecord)target;
955
956 synchronized (mGlobalLock) {
957 // If this is coming from the currently resumed activity, it is
958 // effectively saying that app switches are allowed at this point.
Andrii Kulian5f750bc2018-07-17 08:57:23 -0700959 final ActivityStack stack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700960 if (stack.mResumedActivity != null &&
961 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700962 mAppSwitchesAllowedTime = 0;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700963 }
964 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700965 return pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700966 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700967 }
968
969 @Override
970 public boolean startNextMatchingActivity(IBinder callingActivity, Intent intent,
971 Bundle bOptions) {
972 // Refuse possible leaked file descriptors
973 if (intent != null && intent.hasFileDescriptors()) {
974 throw new IllegalArgumentException("File descriptors passed in Intent");
975 }
976 SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
977
978 synchronized (mGlobalLock) {
979 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
980 if (r == null) {
981 SafeActivityOptions.abort(options);
982 return false;
983 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700984 if (!r.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700985 // The caller is not running... d'oh!
986 SafeActivityOptions.abort(options);
987 return false;
988 }
989 intent = new Intent(intent);
990 // The caller is not allowed to change the data.
991 intent.setDataAndType(r.intent.getData(), r.intent.getType());
992 // And we are resetting to find the next component...
993 intent.setComponent(null);
994
995 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
996
997 ActivityInfo aInfo = null;
998 try {
999 List<ResolveInfo> resolves =
1000 AppGlobals.getPackageManager().queryIntentActivities(
1001 intent, r.resolvedType,
1002 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
1003 UserHandle.getCallingUserId()).getList();
1004
1005 // Look for the original activity in the list...
1006 final int N = resolves != null ? resolves.size() : 0;
1007 for (int i=0; i<N; i++) {
1008 ResolveInfo rInfo = resolves.get(i);
1009 if (rInfo.activityInfo.packageName.equals(r.packageName)
1010 && rInfo.activityInfo.name.equals(r.info.name)) {
1011 // We found the current one... the next matching is
1012 // after it.
1013 i++;
1014 if (i<N) {
1015 aInfo = resolves.get(i).activityInfo;
1016 }
1017 if (debug) {
1018 Slog.v(TAG, "Next matching activity: found current " + r.packageName
1019 + "/" + r.info.name);
1020 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
1021 ? "null" : aInfo.packageName + "/" + aInfo.name));
1022 }
1023 break;
1024 }
1025 }
1026 } catch (RemoteException e) {
1027 }
1028
1029 if (aInfo == null) {
1030 // Nobody who is next!
1031 SafeActivityOptions.abort(options);
1032 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
1033 return false;
1034 }
1035
1036 intent.setComponent(new ComponentName(
1037 aInfo.applicationInfo.packageName, aInfo.name));
1038 intent.setFlags(intent.getFlags()&~(
1039 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
1040 Intent.FLAG_ACTIVITY_CLEAR_TOP|
1041 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
1042 FLAG_ACTIVITY_NEW_TASK));
1043
1044 // Okay now we need to start the new activity, replacing the currently running activity.
1045 // This is a little tricky because we want to start the new one as if the current one is
1046 // finished, but not finish the current one first so that there is no flicker.
1047 // And thus...
1048 final boolean wasFinishing = r.finishing;
1049 r.finishing = true;
1050
1051 // Propagate reply information over to the new activity.
1052 final ActivityRecord resultTo = r.resultTo;
1053 final String resultWho = r.resultWho;
1054 final int requestCode = r.requestCode;
1055 r.resultTo = null;
1056 if (resultTo != null) {
1057 resultTo.removeResultsLocked(r, resultWho, requestCode);
1058 }
1059
1060 final long origId = Binder.clearCallingIdentity();
1061 // TODO(b/64750076): Check if calling pid should really be -1.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001062 final int res = getActivityStartController()
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001063 .obtainStarter(intent, "startNextMatchingActivity")
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001064 .setCaller(r.app.getThread())
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001065 .setResolvedType(r.resolvedType)
1066 .setActivityInfo(aInfo)
1067 .setResultTo(resultTo != null ? resultTo.appToken : null)
1068 .setResultWho(resultWho)
1069 .setRequestCode(requestCode)
1070 .setCallingPid(-1)
1071 .setCallingUid(r.launchedFromUid)
1072 .setCallingPackage(r.launchedFromPackage)
1073 .setRealCallingPid(-1)
1074 .setRealCallingUid(r.launchedFromUid)
1075 .setActivityOptions(options)
1076 .execute();
1077 Binder.restoreCallingIdentity(origId);
1078
1079 r.finishing = wasFinishing;
1080 if (res != ActivityManager.START_SUCCESS) {
1081 return false;
1082 }
1083 return true;
1084 }
1085 }
1086
1087 @Override
1088 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
1089 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1090 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
1091 final WaitResult res = new WaitResult();
1092 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001093 enforceNotIsolatedCaller("startActivityAndWait");
1094 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
1095 userId, "startActivityAndWait");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001096 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001097 getActivityStartController().obtainStarter(intent, "startActivityAndWait")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001098 .setCaller(caller)
1099 .setCallingPackage(callingPackage)
1100 .setResolvedType(resolvedType)
1101 .setResultTo(resultTo)
1102 .setResultWho(resultWho)
1103 .setRequestCode(requestCode)
1104 .setStartFlags(startFlags)
1105 .setActivityOptions(bOptions)
1106 .setMayWait(userId)
1107 .setProfilerInfo(profilerInfo)
1108 .setWaitResult(res)
1109 .execute();
1110 }
1111 return res;
1112 }
1113
1114 @Override
1115 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
1116 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1117 int startFlags, Configuration config, Bundle bOptions, int userId) {
1118 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001119 enforceNotIsolatedCaller("startActivityWithConfig");
1120 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
1121 "startActivityWithConfig");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001122 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001123 return getActivityStartController().obtainStarter(intent, "startActivityWithConfig")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001124 .setCaller(caller)
1125 .setCallingPackage(callingPackage)
1126 .setResolvedType(resolvedType)
1127 .setResultTo(resultTo)
1128 .setResultWho(resultWho)
1129 .setRequestCode(requestCode)
1130 .setStartFlags(startFlags)
1131 .setGlobalConfiguration(config)
1132 .setActivityOptions(bOptions)
1133 .setMayWait(userId)
1134 .execute();
1135 }
1136 }
1137
1138 @Override
1139 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
1140 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1141 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
1142 int userId) {
1143
1144 // This is very dangerous -- it allows you to perform a start activity (including
1145 // permission grants) as any app that may launch one of your own activities. So
1146 // we will only allow this to be done from activities that are part of the core framework,
1147 // and then only when they are running as the system.
1148 final ActivityRecord sourceRecord;
1149 final int targetUid;
1150 final String targetPackage;
1151 final boolean isResolver;
1152 synchronized (mGlobalLock) {
1153 if (resultTo == null) {
1154 throw new SecurityException("Must be called from an activity");
1155 }
1156 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
1157 if (sourceRecord == null) {
1158 throw new SecurityException("Called with bad activity token: " + resultTo);
1159 }
1160 if (!sourceRecord.info.packageName.equals("android")) {
1161 throw new SecurityException(
1162 "Must be called from an activity that is declared in the android package");
1163 }
1164 if (sourceRecord.app == null) {
1165 throw new SecurityException("Called without a process attached to activity");
1166 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001167 if (UserHandle.getAppId(sourceRecord.app.mUid) != SYSTEM_UID) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001168 // This is still okay, as long as this activity is running under the
1169 // uid of the original calling activity.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001170 if (sourceRecord.app.mUid != sourceRecord.launchedFromUid) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001171 throw new SecurityException(
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001172 "Calling activity in uid " + sourceRecord.app.mUid
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001173 + " must be system uid or original calling uid "
1174 + sourceRecord.launchedFromUid);
1175 }
1176 }
1177 if (ignoreTargetSecurity) {
1178 if (intent.getComponent() == null) {
1179 throw new SecurityException(
1180 "Component must be specified with ignoreTargetSecurity");
1181 }
1182 if (intent.getSelector() != null) {
1183 throw new SecurityException(
1184 "Selector not allowed with ignoreTargetSecurity");
1185 }
1186 }
1187 targetUid = sourceRecord.launchedFromUid;
1188 targetPackage = sourceRecord.launchedFromPackage;
1189 isResolver = sourceRecord.isResolverOrChildActivity();
1190 }
1191
1192 if (userId == UserHandle.USER_NULL) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001193 userId = UserHandle.getUserId(sourceRecord.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001194 }
1195
1196 // TODO: Switch to user app stacks here.
1197 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001198 return getActivityStartController().obtainStarter(intent, "startActivityAsCaller")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001199 .setCallingUid(targetUid)
1200 .setCallingPackage(targetPackage)
1201 .setResolvedType(resolvedType)
1202 .setResultTo(resultTo)
1203 .setResultWho(resultWho)
1204 .setRequestCode(requestCode)
1205 .setStartFlags(startFlags)
1206 .setActivityOptions(bOptions)
1207 .setMayWait(userId)
1208 .setIgnoreTargetSecurity(ignoreTargetSecurity)
1209 .setFilterCallingUid(isResolver ? 0 /* system */ : targetUid)
1210 .execute();
1211 } catch (SecurityException e) {
1212 // XXX need to figure out how to propagate to original app.
1213 // A SecurityException here is generally actually a fault of the original
1214 // calling activity (such as a fairly granting permissions), so propagate it
1215 // back to them.
1216 /*
1217 StringBuilder msg = new StringBuilder();
1218 msg.append("While launching");
1219 msg.append(intent.toString());
1220 msg.append(": ");
1221 msg.append(e.getMessage());
1222 */
1223 throw e;
1224 }
1225 }
1226
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001227 int handleIncomingUser(int callingPid, int callingUid, int userId, String name) {
1228 return mAmInternal.handleIncomingUser(callingPid, callingUid, userId, false /* allowAll */,
1229 ALLOW_FULL_ONLY, name, null /* callerPackage */);
1230 }
1231
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001232 @Override
1233 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
1234 Intent intent, String resolvedType, IVoiceInteractionSession session,
1235 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
1236 Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001237 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001238 if (session == null || interactor == null) {
1239 throw new NullPointerException("null session or interactor");
1240 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001241 userId = handleIncomingUser(callingPid, callingUid, userId, "startVoiceActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001242 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001243 return getActivityStartController().obtainStarter(intent, "startVoiceActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001244 .setCallingUid(callingUid)
1245 .setCallingPackage(callingPackage)
1246 .setResolvedType(resolvedType)
1247 .setVoiceSession(session)
1248 .setVoiceInteractor(interactor)
1249 .setStartFlags(startFlags)
1250 .setProfilerInfo(profilerInfo)
1251 .setActivityOptions(bOptions)
1252 .setMayWait(userId)
1253 .execute();
1254 }
1255
1256 @Override
1257 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
1258 Intent intent, String resolvedType, Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001259 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
1260 userId = handleIncomingUser(callingPid, callingUid, userId, "startAssistantActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001261
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001262 return getActivityStartController().obtainStarter(intent, "startAssistantActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001263 .setCallingUid(callingUid)
1264 .setCallingPackage(callingPackage)
1265 .setResolvedType(resolvedType)
1266 .setActivityOptions(bOptions)
1267 .setMayWait(userId)
1268 .execute();
1269 }
1270
1271 @Override
1272 public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
1273 IRecentsAnimationRunner recentsAnimationRunner) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001274 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001275 final int callingPid = Binder.getCallingPid();
1276 final long origId = Binder.clearCallingIdentity();
1277 try {
1278 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07001279 final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
1280 final int recentsUid = mRecentTasks.getRecentsComponentUid();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001281
1282 // Start a new recents animation
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001283 final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
1284 getActivityStartController(), mWindowManager, callingPid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001285 anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
1286 recentsUid, assistDataReceiver);
1287 }
1288 } finally {
1289 Binder.restoreCallingIdentity(origId);
1290 }
1291 }
1292
1293 @Override
1294 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001295 enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001296 "startActivityFromRecents()");
1297
1298 final int callingPid = Binder.getCallingPid();
1299 final int callingUid = Binder.getCallingUid();
1300 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(bOptions);
1301 final long origId = Binder.clearCallingIdentity();
1302 try {
1303 synchronized (mGlobalLock) {
1304 return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
1305 safeOptions);
1306 }
1307 } finally {
1308 Binder.restoreCallingIdentity(origId);
1309 }
1310 }
1311
1312 /**
1313 * This is the internal entry point for handling Activity.finish().
1314 *
1315 * @param token The Binder token referencing the Activity we want to finish.
1316 * @param resultCode Result code, if any, from this Activity.
1317 * @param resultData Result data (Intent), if any, from this Activity.
1318 * @param finishTask Whether to finish the task associated with this Activity.
1319 *
1320 * @return Returns true if the activity successfully finished, or false if it is still running.
1321 */
1322 @Override
1323 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
1324 int finishTask) {
1325 // Refuse possible leaked file descriptors
1326 if (resultData != null && resultData.hasFileDescriptors()) {
1327 throw new IllegalArgumentException("File descriptors passed in Intent");
1328 }
1329
1330 synchronized (mGlobalLock) {
1331 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1332 if (r == null) {
1333 return true;
1334 }
1335 // Keep track of the root activity of the task before we finish it
1336 TaskRecord tr = r.getTask();
1337 ActivityRecord rootR = tr.getRootActivity();
1338 if (rootR == null) {
1339 Slog.w(TAG, "Finishing task with all activities already finished");
1340 }
1341 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
1342 // finish.
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001343 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001344 return false;
1345 }
1346
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001347 // TODO: There is a dup. of this block of code in ActivityStack.navigateUpToLocked
1348 // We should consolidate.
1349 if (mController != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001350 // Find the first activity that is not finishing.
1351 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
1352 if (next != null) {
1353 // ask watcher if this is allowed
1354 boolean resumeOK = true;
1355 try {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001356 resumeOK = mController.activityResuming(next.packageName);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001357 } catch (RemoteException e) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001358 mController = null;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001359 Watchdog.getInstance().setActivityController(null);
1360 }
1361
1362 if (!resumeOK) {
1363 Slog.i(TAG, "Not finishing activity because controller resumed");
1364 return false;
1365 }
1366 }
1367 }
1368 final long origId = Binder.clearCallingIdentity();
1369 try {
1370 boolean res;
1371 final boolean finishWithRootActivity =
1372 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
1373 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
1374 || (finishWithRootActivity && r == rootR)) {
1375 // If requested, remove the task that is associated to this activity only if it
1376 // was the root activity in the task. The result code and data is ignored
1377 // because we don't support returning them across task boundaries. Also, to
1378 // keep backwards compatibility we remove the task from recents when finishing
1379 // task with root activity.
1380 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
1381 finishWithRootActivity, "finish-activity");
1382 if (!res) {
1383 Slog.i(TAG, "Removing task failed to finish activity");
1384 }
Garfield Tan2746ab52018-07-25 12:33:01 -07001385 // Explicitly dismissing the activity so reset its relaunch flag.
Wale Ogunwale64258362018-10-16 15:13:37 -07001386 r.mRelaunchReason = RELAUNCH_REASON_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001387 } else {
1388 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
1389 resultData, "app-request", true);
1390 if (!res) {
1391 Slog.i(TAG, "Failed to finish by app-request");
1392 }
1393 }
1394 return res;
1395 } finally {
1396 Binder.restoreCallingIdentity(origId);
1397 }
1398 }
1399 }
1400
1401 @Override
1402 public boolean finishActivityAffinity(IBinder token) {
1403 synchronized (mGlobalLock) {
1404 final long origId = Binder.clearCallingIdentity();
1405 try {
1406 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1407 if (r == null) {
1408 return false;
1409 }
1410
1411 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
1412 // can finish.
1413 final TaskRecord task = r.getTask();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001414 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001415 return false;
1416 }
1417 return task.getStack().finishActivityAffinityLocked(r);
1418 } finally {
1419 Binder.restoreCallingIdentity(origId);
1420 }
1421 }
1422 }
1423
1424 @Override
1425 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
1426 final long origId = Binder.clearCallingIdentity();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001427 try {
1428 WindowProcessController proc = null;
1429 synchronized (mGlobalLock) {
1430 ActivityStack stack = ActivityRecord.getStackLocked(token);
1431 if (stack == null) {
1432 return;
1433 }
1434 final ActivityRecord r = mStackSupervisor.activityIdleInternalLocked(token,
1435 false /* fromTimeout */, false /* processPausingActivities */, config);
1436 if (r != null) {
1437 proc = r.app;
1438 }
1439 if (stopProfiling && proc != null) {
1440 proc.clearProfilerIfNeeded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001441 }
1442 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001443 } finally {
1444 Binder.restoreCallingIdentity(origId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001445 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001446 }
1447
1448 @Override
1449 public final void activityResumed(IBinder token) {
1450 final long origId = Binder.clearCallingIdentity();
1451 synchronized (mGlobalLock) {
1452 ActivityRecord.activityResumedLocked(token);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001453 mWindowManager.notifyAppResumedFinished(token);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001454 }
1455 Binder.restoreCallingIdentity(origId);
1456 }
1457
1458 @Override
1459 public final void activityPaused(IBinder token) {
1460 final long origId = Binder.clearCallingIdentity();
1461 synchronized (mGlobalLock) {
1462 ActivityStack stack = ActivityRecord.getStackLocked(token);
1463 if (stack != null) {
1464 stack.activityPausedLocked(token, false);
1465 }
1466 }
1467 Binder.restoreCallingIdentity(origId);
1468 }
1469
1470 @Override
1471 public final void activityStopped(IBinder token, Bundle icicle,
1472 PersistableBundle persistentState, CharSequence description) {
1473 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
1474
1475 // Refuse possible leaked file descriptors
1476 if (icicle != null && icicle.hasFileDescriptors()) {
1477 throw new IllegalArgumentException("File descriptors passed in Bundle");
1478 }
1479
1480 final long origId = Binder.clearCallingIdentity();
1481
1482 synchronized (mGlobalLock) {
1483 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1484 if (r != null) {
1485 r.activityStoppedLocked(icicle, persistentState, description);
1486 }
1487 }
1488
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001489 mAmInternal.trimApplications();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001490
1491 Binder.restoreCallingIdentity(origId);
1492 }
1493
1494 @Override
1495 public final void activityDestroyed(IBinder token) {
1496 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
1497 synchronized (mGlobalLock) {
1498 ActivityStack stack = ActivityRecord.getStackLocked(token);
1499 if (stack != null) {
1500 stack.activityDestroyedLocked(token, "activityDestroyed");
1501 }
1502 }
1503 }
1504
1505 @Override
1506 public final void activityRelaunched(IBinder token) {
1507 final long origId = Binder.clearCallingIdentity();
1508 synchronized (mGlobalLock) {
1509 mStackSupervisor.activityRelaunchedLocked(token);
1510 }
1511 Binder.restoreCallingIdentity(origId);
1512 }
1513
1514 public final void activitySlept(IBinder token) {
1515 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
1516
1517 final long origId = Binder.clearCallingIdentity();
1518
1519 synchronized (mGlobalLock) {
1520 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1521 if (r != null) {
1522 mStackSupervisor.activitySleptLocked(r);
1523 }
1524 }
1525
1526 Binder.restoreCallingIdentity(origId);
1527 }
1528
1529 @Override
1530 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
1531 synchronized (mGlobalLock) {
1532 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1533 if (r == null) {
1534 return;
1535 }
1536 final long origId = Binder.clearCallingIdentity();
1537 try {
1538 r.setRequestedOrientation(requestedOrientation);
1539 } finally {
1540 Binder.restoreCallingIdentity(origId);
1541 }
1542 }
1543 }
1544
1545 @Override
1546 public int getRequestedOrientation(IBinder token) {
1547 synchronized (mGlobalLock) {
1548 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1549 if (r == null) {
1550 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
1551 }
1552 return r.getRequestedOrientation();
1553 }
1554 }
1555
1556 @Override
1557 public void setImmersive(IBinder token, boolean immersive) {
1558 synchronized (mGlobalLock) {
1559 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1560 if (r == null) {
1561 throw new IllegalArgumentException();
1562 }
1563 r.immersive = immersive;
1564
1565 // update associated state if we're frontmost
Andrii Kulian52d255c2018-07-13 11:32:19 -07001566 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001567 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001568 applyUpdateLockStateLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001569 }
1570 }
1571 }
1572
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001573 void applyUpdateLockStateLocked(ActivityRecord r) {
1574 // Modifications to the UpdateLock state are done on our handler, outside
1575 // the activity manager's locks. The new state is determined based on the
1576 // state *now* of the relevant activity record. The object is passed to
1577 // the handler solely for logging detail, not to be consulted/modified.
1578 final boolean nextState = r != null && r.immersive;
1579 mH.post(() -> {
1580 if (mUpdateLock.isHeld() != nextState) {
1581 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1582 "Applying new update lock state '" + nextState + "' for " + r);
1583 if (nextState) {
1584 mUpdateLock.acquire();
1585 } else {
1586 mUpdateLock.release();
1587 }
1588 }
1589 });
1590 }
1591
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001592 @Override
1593 public boolean isImmersive(IBinder token) {
1594 synchronized (mGlobalLock) {
1595 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1596 if (r == null) {
1597 throw new IllegalArgumentException();
1598 }
1599 return r.immersive;
1600 }
1601 }
1602
1603 @Override
1604 public boolean isTopActivityImmersive() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001605 enforceNotIsolatedCaller("isTopActivityImmersive");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001606 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001607 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001608 return (r != null) ? r.immersive : false;
1609 }
1610 }
1611
1612 @Override
1613 public void overridePendingTransition(IBinder token, String packageName,
1614 int enterAnim, int exitAnim) {
1615 synchronized (mGlobalLock) {
1616 ActivityRecord self = ActivityRecord.isInStackLocked(token);
1617 if (self == null) {
1618 return;
1619 }
1620
1621 final long origId = Binder.clearCallingIdentity();
1622
1623 if (self.isState(
1624 ActivityStack.ActivityState.RESUMED, ActivityStack.ActivityState.PAUSING)) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001625 mWindowManager.overridePendingAppTransition(packageName,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001626 enterAnim, exitAnim, null);
1627 }
1628
1629 Binder.restoreCallingIdentity(origId);
1630 }
1631 }
1632
1633 @Override
1634 public int getFrontActivityScreenCompatMode() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001635 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001636 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001637 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001638 if (r == null) {
1639 return ActivityManager.COMPAT_MODE_UNKNOWN;
1640 }
Wale Ogunwale53783742018-09-16 10:21:51 -07001641 return mCompatModePackages.computeCompatModeLocked(r.info.applicationInfo);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001642 }
1643 }
1644
1645 @Override
1646 public void setFrontActivityScreenCompatMode(int mode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001647 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001648 "setFrontActivityScreenCompatMode");
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001649 ApplicationInfo ai;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001650 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001651 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001652 if (r == null) {
1653 Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity");
1654 return;
1655 }
1656 ai = r.info.applicationInfo;
Wale Ogunwale53783742018-09-16 10:21:51 -07001657 mCompatModePackages.setPackageScreenCompatModeLocked(ai, mode);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001658 }
1659 }
1660
1661 @Override
1662 public int getLaunchedFromUid(IBinder activityToken) {
1663 ActivityRecord srec;
1664 synchronized (mGlobalLock) {
1665 srec = ActivityRecord.forTokenLocked(activityToken);
1666 }
1667 if (srec == null) {
1668 return -1;
1669 }
1670 return srec.launchedFromUid;
1671 }
1672
1673 @Override
1674 public String getLaunchedFromPackage(IBinder activityToken) {
1675 ActivityRecord srec;
1676 synchronized (mGlobalLock) {
1677 srec = ActivityRecord.forTokenLocked(activityToken);
1678 }
1679 if (srec == null) {
1680 return null;
1681 }
1682 return srec.launchedFromPackage;
1683 }
1684
1685 @Override
1686 public boolean convertFromTranslucent(IBinder token) {
1687 final long origId = Binder.clearCallingIdentity();
1688 try {
1689 synchronized (mGlobalLock) {
1690 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1691 if (r == null) {
1692 return false;
1693 }
1694 final boolean translucentChanged = r.changeWindowTranslucency(true);
1695 if (translucentChanged) {
1696 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
1697 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001698 mWindowManager.setAppFullscreen(token, true);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001699 return translucentChanged;
1700 }
1701 } finally {
1702 Binder.restoreCallingIdentity(origId);
1703 }
1704 }
1705
1706 @Override
1707 public boolean convertToTranslucent(IBinder token, Bundle options) {
1708 SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
1709 final long origId = Binder.clearCallingIdentity();
1710 try {
1711 synchronized (mGlobalLock) {
1712 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1713 if (r == null) {
1714 return false;
1715 }
1716 final TaskRecord task = r.getTask();
1717 int index = task.mActivities.lastIndexOf(r);
1718 if (index > 0) {
1719 ActivityRecord under = task.mActivities.get(index - 1);
1720 under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
1721 }
1722 final boolean translucentChanged = r.changeWindowTranslucency(false);
1723 if (translucentChanged) {
1724 r.getStack().convertActivityToTranslucent(r);
1725 }
1726 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001727 mWindowManager.setAppFullscreen(token, false);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001728 return translucentChanged;
1729 }
1730 } finally {
1731 Binder.restoreCallingIdentity(origId);
1732 }
1733 }
1734
1735 @Override
1736 public void notifyActivityDrawn(IBinder token) {
1737 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
1738 synchronized (mGlobalLock) {
1739 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
1740 if (r != null) {
1741 r.getStack().notifyActivityDrawnLocked(r);
1742 }
1743 }
1744 }
1745
1746 @Override
1747 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
1748 synchronized (mGlobalLock) {
1749 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1750 if (r == null) {
1751 return;
1752 }
1753 r.reportFullyDrawnLocked(restoredFromBundle);
1754 }
1755 }
1756
1757 @Override
1758 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
1759 synchronized (mGlobalLock) {
1760 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
1761 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
1762 return stack.mDisplayId;
1763 }
1764 return DEFAULT_DISPLAY;
1765 }
1766 }
1767
1768 @Override
1769 public ActivityManager.StackInfo getFocusedStackInfo() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001770 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001771 long ident = Binder.clearCallingIdentity();
1772 try {
1773 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001774 ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001775 if (focusedStack != null) {
1776 return mStackSupervisor.getStackInfo(focusedStack.mStackId);
1777 }
1778 return null;
1779 }
1780 } finally {
1781 Binder.restoreCallingIdentity(ident);
1782 }
1783 }
1784
1785 @Override
1786 public void setFocusedStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001787 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001788 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
1789 final long callingId = Binder.clearCallingIdentity();
1790 try {
1791 synchronized (mGlobalLock) {
1792 final ActivityStack stack = mStackSupervisor.getStack(stackId);
1793 if (stack == null) {
1794 Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
1795 return;
1796 }
1797 final ActivityRecord r = stack.topRunningActivityLocked();
Louis Chang19443452018-10-09 12:10:21 +08001798 if (r != null && r.moveFocusableActivityToTop("setFocusedStack")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08001799 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001800 }
1801 }
1802 } finally {
1803 Binder.restoreCallingIdentity(callingId);
1804 }
1805 }
1806
1807 @Override
1808 public void setFocusedTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001809 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001810 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
1811 final long callingId = Binder.clearCallingIdentity();
1812 try {
1813 synchronized (mGlobalLock) {
1814 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1815 if (task == null) {
1816 return;
1817 }
1818 final ActivityRecord r = task.topRunningActivityLocked();
Louis Chang19443452018-10-09 12:10:21 +08001819 if (r != null && r.moveFocusableActivityToTop("setFocusedTask")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08001820 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001821 }
1822 }
1823 } finally {
1824 Binder.restoreCallingIdentity(callingId);
1825 }
1826 }
1827
1828 @Override
1829 public boolean removeTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001830 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001831 synchronized (mGlobalLock) {
1832 final long ident = Binder.clearCallingIdentity();
1833 try {
1834 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
1835 "remove-task");
1836 } finally {
1837 Binder.restoreCallingIdentity(ident);
1838 }
1839 }
1840 }
1841
1842 @Override
Winson Chunge6439102018-07-30 15:48:01 -07001843 public void removeAllVisibleRecentTasks() {
1844 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeAllVisibleRecentTasks()");
1845 synchronized (mGlobalLock) {
1846 final long ident = Binder.clearCallingIdentity();
1847 try {
1848 getRecentTasks().removeAllVisibleTasks();
1849 } finally {
1850 Binder.restoreCallingIdentity(ident);
1851 }
1852 }
1853 }
1854
1855 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001856 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
1857 synchronized (mGlobalLock) {
1858 final ActivityRecord srec = ActivityRecord.forTokenLocked(token);
1859 if (srec != null) {
1860 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
1861 }
1862 }
1863 return false;
1864 }
1865
1866 @Override
1867 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
1868 Intent resultData) {
1869
1870 synchronized (mGlobalLock) {
1871 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
1872 if (r != null) {
1873 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
1874 }
1875 return false;
1876 }
1877 }
1878
1879 /**
1880 * Attempts to move a task backwards in z-order (the order of activities within the task is
1881 * unchanged).
1882 *
1883 * There are several possible results of this call:
1884 * - if the task is locked, then we will show the lock toast
1885 * - if there is a task behind the provided task, then that task is made visible and resumed as
1886 * this task is moved to the back
1887 * - otherwise, if there are no other tasks in the stack:
1888 * - if this task is in the pinned stack, then we remove the stack completely, which will
1889 * have the effect of moving the task to the top or bottom of the fullscreen stack
1890 * (depending on whether it is visible)
1891 * - otherwise, we simply return home and hide this task
1892 *
1893 * @param token A reference to the activity we wish to move
1894 * @param nonRoot If false then this only works if the activity is the root
1895 * of a task; if true it will work for any activity in a task.
1896 * @return Returns true if the move completed, false if not.
1897 */
1898 @Override
1899 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001900 enforceNotIsolatedCaller("moveActivityTaskToBack");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001901 synchronized (mGlobalLock) {
1902 final long origId = Binder.clearCallingIdentity();
1903 try {
1904 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
1905 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1906 if (task != null) {
1907 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
1908 }
1909 } finally {
1910 Binder.restoreCallingIdentity(origId);
1911 }
1912 }
1913 return false;
1914 }
1915
1916 @Override
1917 public Rect getTaskBounds(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001918 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001919 long ident = Binder.clearCallingIdentity();
1920 Rect rect = new Rect();
1921 try {
1922 synchronized (mGlobalLock) {
1923 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
1924 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1925 if (task == null) {
1926 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
1927 return rect;
1928 }
1929 if (task.getStack() != null) {
1930 // Return the bounds from window manager since it will be adjusted for various
1931 // things like the presense of a docked stack for tasks that aren't resizeable.
1932 task.getWindowContainerBounds(rect);
1933 } else {
1934 // Task isn't in window manager yet since it isn't associated with a stack.
1935 // Return the persist value from activity manager
1936 if (!task.matchParentBounds()) {
1937 rect.set(task.getBounds());
1938 } else if (task.mLastNonFullscreenBounds != null) {
1939 rect.set(task.mLastNonFullscreenBounds);
1940 }
1941 }
1942 }
1943 } finally {
1944 Binder.restoreCallingIdentity(ident);
1945 }
1946 return rect;
1947 }
1948
1949 @Override
1950 public ActivityManager.TaskDescription getTaskDescription(int id) {
1951 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001952 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001953 MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
1954 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
1955 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1956 if (tr != null) {
1957 return tr.lastTaskDescription;
1958 }
1959 }
1960 return null;
1961 }
1962
1963 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001964 public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
1965 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
1966 setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
1967 toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
1968 return;
1969 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001970 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001971 synchronized (mGlobalLock) {
1972 final long ident = Binder.clearCallingIdentity();
1973 try {
1974 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1975 if (task == null) {
1976 Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
1977 return;
1978 }
1979
1980 if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
1981 + " to windowingMode=" + windowingMode + " toTop=" + toTop);
1982
1983 if (!task.isActivityTypeStandardOrUndefined()) {
1984 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
1985 + " non-standard task " + taskId + " to windowing mode="
1986 + windowingMode);
1987 }
1988
1989 final ActivityStack stack = task.getStack();
1990 if (toTop) {
1991 stack.moveToFront("setTaskWindowingMode", task);
1992 }
1993 stack.setWindowingMode(windowingMode);
1994 } finally {
1995 Binder.restoreCallingIdentity(ident);
1996 }
1997 }
1998 }
1999
2000 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002001 public String getCallingPackage(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002002 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002003 ActivityRecord r = getCallingRecordLocked(token);
2004 return r != null ? r.info.packageName : null;
2005 }
2006 }
2007
2008 @Override
2009 public ComponentName getCallingActivity(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002010 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002011 ActivityRecord r = getCallingRecordLocked(token);
2012 return r != null ? r.intent.getComponent() : null;
2013 }
2014 }
2015
2016 private ActivityRecord getCallingRecordLocked(IBinder token) {
2017 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2018 if (r == null) {
2019 return null;
2020 }
2021 return r.resultTo;
2022 }
2023
2024 @Override
2025 public void unhandledBack() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002026 mAmInternal.enforceCallingPermission(android.Manifest.permission.FORCE_BACK, "unhandledBack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002027
2028 synchronized (mGlobalLock) {
2029 final long origId = Binder.clearCallingIdentity();
2030 try {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002031 getTopDisplayFocusedStack().unhandledBackLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002032 } finally {
2033 Binder.restoreCallingIdentity(origId);
2034 }
2035 }
2036 }
2037
2038 /**
2039 * TODO: Add mController hook
2040 */
2041 @Override
2042 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002043 mAmInternal.enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002044
2045 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
2046 synchronized (mGlobalLock) {
2047 moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
2048 false /* fromRecents */);
2049 }
2050 }
2051
2052 void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
2053 boolean fromRecents) {
2054
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002055 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002056 Binder.getCallingUid(), -1, -1, "Task to front")) {
2057 SafeActivityOptions.abort(options);
2058 return;
2059 }
2060 final long origId = Binder.clearCallingIdentity();
2061 try {
2062 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2063 if (task == null) {
2064 Slog.d(TAG, "Could not find task for id: "+ taskId);
Winson Chungd0243682018-09-25 18:11:54 -07002065 SafeActivityOptions.abort(options);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002066 return;
2067 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002068 if (getLockTaskController().isLockTaskModeViolation(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002069 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
Winson Chungd0243682018-09-25 18:11:54 -07002070 SafeActivityOptions.abort(options);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002071 return;
2072 }
2073 ActivityOptions realOptions = options != null
2074 ? options.getOptions(mStackSupervisor)
2075 : null;
2076 mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
2077 false /* forceNonResizable */);
2078
2079 final ActivityRecord topActivity = task.getTopActivity();
2080 if (topActivity != null) {
2081
2082 // We are reshowing a task, use a starting window to hide the initial draw delay
2083 // so the transition can start earlier.
2084 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
2085 true /* taskSwitch */, fromRecents);
2086 }
2087 } finally {
2088 Binder.restoreCallingIdentity(origId);
2089 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002090 }
2091
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002092 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
2093 int callingPid, int callingUid, String name) {
2094 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
2095 return true;
2096 }
2097
2098 if (getRecentTasks().isCallerRecents(sourceUid)) {
2099 return true;
2100 }
2101
2102 int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
2103 if (perm == PackageManager.PERMISSION_GRANTED) {
2104 return true;
2105 }
2106 if (checkAllowAppSwitchUid(sourceUid)) {
2107 return true;
2108 }
2109
2110 // If the actual IPC caller is different from the logical source, then
2111 // also see if they are allowed to control app switches.
2112 if (callingUid != -1 && callingUid != sourceUid) {
2113 perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
2114 if (perm == PackageManager.PERMISSION_GRANTED) {
2115 return true;
2116 }
2117 if (checkAllowAppSwitchUid(callingUid)) {
2118 return true;
2119 }
2120 }
2121
2122 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
2123 return false;
2124 }
2125
2126 private boolean checkAllowAppSwitchUid(int uid) {
2127 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
2128 if (types != null) {
2129 for (int i = types.size() - 1; i >= 0; i--) {
2130 if (types.valueAt(i).intValue() == uid) {
2131 return true;
2132 }
2133 }
2134 }
2135 return false;
2136 }
2137
2138 @Override
2139 public void setActivityController(IActivityController controller, boolean imAMonkey) {
2140 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
2141 "setActivityController()");
2142 synchronized (mGlobalLock) {
2143 mController = controller;
2144 mControllerIsAMonkey = imAMonkey;
2145 Watchdog.getInstance().setActivityController(controller);
2146 }
2147 }
2148
Wale Ogunwale387b34c2018-10-25 19:59:40 -07002149 public boolean isControllerAMonkey() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002150 synchronized (mGlobalLock) {
2151 return mController != null && mControllerIsAMonkey;
2152 }
2153 }
2154
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002155 @Override
2156 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
2157 synchronized (mGlobalLock) {
2158 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
2159 }
2160 }
2161
2162 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002163 public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum) {
2164 return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
2165 }
2166
2167 @Override
2168 public List<ActivityManager.RunningTaskInfo> getFilteredTasks(int maxNum,
2169 @WindowConfiguration.ActivityType int ignoreActivityType,
2170 @WindowConfiguration.WindowingMode int ignoreWindowingMode) {
2171 final int callingUid = Binder.getCallingUid();
2172 ArrayList<ActivityManager.RunningTaskInfo> list = new ArrayList<>();
2173
2174 synchronized (mGlobalLock) {
2175 if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
2176
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002177 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002178 callingUid);
2179 mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
2180 ignoreWindowingMode, callingUid, allowed);
2181 }
2182
2183 return list;
2184 }
2185
2186 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002187 public final void finishSubActivity(IBinder token, String resultWho, int requestCode) {
2188 synchronized (mGlobalLock) {
2189 final long origId = Binder.clearCallingIdentity();
2190 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2191 if (r != null) {
2192 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
2193 }
2194 Binder.restoreCallingIdentity(origId);
2195 }
2196 }
2197
2198 @Override
2199 public boolean willActivityBeVisible(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002200 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002201 ActivityStack stack = ActivityRecord.getStackLocked(token);
2202 if (stack != null) {
2203 return stack.willActivityBeVisibleLocked(token);
2204 }
2205 return false;
2206 }
2207 }
2208
2209 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002210 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002211 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002212 synchronized (mGlobalLock) {
2213 final long ident = Binder.clearCallingIdentity();
2214 try {
2215 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2216 if (task == null) {
2217 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
2218 return;
2219 }
2220
2221 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
2222 + " to stackId=" + stackId + " toTop=" + toTop);
2223
2224 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2225 if (stack == null) {
2226 throw new IllegalStateException(
2227 "moveTaskToStack: No stack for stackId=" + stackId);
2228 }
2229 if (!stack.isActivityTypeStandardOrUndefined()) {
2230 throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
2231 + taskId + " to stack " + stackId);
2232 }
2233 if (stack.inSplitScreenPrimaryWindowingMode()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002234 mWindowManager.setDockedStackCreateState(
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002235 SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
2236 }
2237 task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
2238 "moveTaskToStack");
2239 } finally {
2240 Binder.restoreCallingIdentity(ident);
2241 }
2242 }
2243 }
2244
2245 @Override
2246 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
2247 boolean preserveWindows, boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002248 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002249
2250 final long ident = Binder.clearCallingIdentity();
2251 try {
2252 synchronized (mGlobalLock) {
2253 if (animate) {
2254 final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
2255 if (stack == null) {
2256 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2257 return;
2258 }
2259 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
2260 throw new IllegalArgumentException("Stack: " + stackId
2261 + " doesn't support animated resize.");
2262 }
2263 stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
2264 animationDuration, false /* fromFullscreen */);
2265 } else {
2266 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2267 if (stack == null) {
2268 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2269 return;
2270 }
2271 mStackSupervisor.resizeStackLocked(stack, destBounds,
2272 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
2273 preserveWindows, allowResizeInDockedMode, !DEFER_RESUME);
2274 }
2275 }
2276 } finally {
2277 Binder.restoreCallingIdentity(ident);
2278 }
2279 }
2280
2281 /**
2282 * Moves the specified task to the primary-split-screen stack.
2283 *
2284 * @param taskId Id of task to move.
2285 * @param createMode The mode the primary split screen stack should be created in if it doesn't
2286 * exist already. See
2287 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
2288 * and
2289 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
2290 * @param toTop If the task and stack should be moved to the top.
2291 * @param animate Whether we should play an animation for the moving the task.
2292 * @param initialBounds If the primary stack gets created, it will use these bounds for the
2293 * stack. Pass {@code null} to use default bounds.
2294 * @param showRecents If the recents activity should be shown on the other side of the task
2295 * going into split-screen mode.
2296 */
2297 @Override
2298 public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode,
2299 boolean toTop, boolean animate, Rect initialBounds, boolean showRecents) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002300 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002301 "setTaskWindowingModeSplitScreenPrimary()");
2302 synchronized (mGlobalLock) {
2303 final long ident = Binder.clearCallingIdentity();
2304 try {
2305 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2306 if (task == null) {
2307 Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
2308 return false;
2309 }
2310 if (DEBUG_STACK) Slog.d(TAG_STACK,
2311 "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
2312 + " to createMode=" + createMode + " toTop=" + toTop);
2313 if (!task.isActivityTypeStandardOrUndefined()) {
2314 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
2315 + " non-standard task " + taskId + " to split-screen windowing mode");
2316 }
2317
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002318 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002319 final int windowingMode = task.getWindowingMode();
2320 final ActivityStack stack = task.getStack();
2321 if (toTop) {
2322 stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
2323 }
2324 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
2325 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */);
2326 return windowingMode != task.getWindowingMode();
2327 } finally {
2328 Binder.restoreCallingIdentity(ident);
2329 }
2330 }
2331 }
2332
2333 /**
2334 * Removes stacks in the input windowing modes from the system if they are of activity type
2335 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
2336 */
2337 @Override
2338 public void removeStacksInWindowingModes(int[] windowingModes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002339 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002340 "removeStacksInWindowingModes()");
2341
2342 synchronized (mGlobalLock) {
2343 final long ident = Binder.clearCallingIdentity();
2344 try {
2345 mStackSupervisor.removeStacksInWindowingModes(windowingModes);
2346 } finally {
2347 Binder.restoreCallingIdentity(ident);
2348 }
2349 }
2350 }
2351
2352 @Override
2353 public void removeStacksWithActivityTypes(int[] activityTypes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002354 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002355 "removeStacksWithActivityTypes()");
2356
2357 synchronized (mGlobalLock) {
2358 final long ident = Binder.clearCallingIdentity();
2359 try {
2360 mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
2361 } finally {
2362 Binder.restoreCallingIdentity(ident);
2363 }
2364 }
2365 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002366
2367 @Override
2368 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
2369 int userId) {
2370 final int callingUid = Binder.getCallingUid();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002371 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, "getRecentTasks");
2372 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002373 callingUid);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002374 final boolean detailed = checkGetTasksPermission(
2375 android.Manifest.permission.GET_DETAILED_TASKS, Binder.getCallingPid(),
2376 UserHandle.getAppId(callingUid))
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002377 == PackageManager.PERMISSION_GRANTED;
2378
2379 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002380 return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002381 callingUid);
2382 }
2383 }
2384
2385 @Override
2386 public List<ActivityManager.StackInfo> getAllStackInfos() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002387 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002388 long ident = Binder.clearCallingIdentity();
2389 try {
2390 synchronized (mGlobalLock) {
2391 return mStackSupervisor.getAllStackInfosLocked();
2392 }
2393 } finally {
2394 Binder.restoreCallingIdentity(ident);
2395 }
2396 }
2397
2398 @Override
2399 public ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002400 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002401 long ident = Binder.clearCallingIdentity();
2402 try {
2403 synchronized (mGlobalLock) {
2404 return mStackSupervisor.getStackInfo(windowingMode, activityType);
2405 }
2406 } finally {
2407 Binder.restoreCallingIdentity(ident);
2408 }
2409 }
2410
2411 @Override
2412 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002413 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002414 final long callingUid = Binder.getCallingUid();
2415 final long origId = Binder.clearCallingIdentity();
2416 try {
2417 synchronized (mGlobalLock) {
2418 // Cancel the recents animation synchronously (do not hold the WM lock)
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002419 mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002420 ? REORDER_MOVE_TO_ORIGINAL_POSITION
2421 : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
2422 }
2423 } finally {
2424 Binder.restoreCallingIdentity(origId);
2425 }
2426 }
2427
2428 @Override
2429 public void startLockTaskModeByToken(IBinder token) {
2430 synchronized (mGlobalLock) {
2431 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2432 if (r == null) {
2433 return;
2434 }
2435 startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
2436 }
2437 }
2438
2439 @Override
2440 public void startSystemLockTaskMode(int taskId) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002441 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002442 // This makes inner call to look as if it was initiated by system.
2443 long ident = Binder.clearCallingIdentity();
2444 try {
2445 synchronized (mGlobalLock) {
2446 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2447
2448 // When starting lock task mode the stack must be in front and focused
2449 task.getStack().moveToFront("startSystemLockTaskMode");
2450 startLockTaskModeLocked(task, true /* isSystemCaller */);
2451 }
2452 } finally {
2453 Binder.restoreCallingIdentity(ident);
2454 }
2455 }
2456
2457 @Override
2458 public void stopLockTaskModeByToken(IBinder token) {
2459 synchronized (mGlobalLock) {
2460 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2461 if (r == null) {
2462 return;
2463 }
2464 stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
2465 }
2466 }
2467
2468 /**
2469 * This API should be called by SystemUI only when user perform certain action to dismiss
2470 * lock task mode. We should only dismiss pinned lock task mode in this case.
2471 */
2472 @Override
2473 public void stopSystemLockTaskMode() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002474 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002475 stopLockTaskModeInternal(null, true /* isSystemCaller */);
2476 }
2477
2478 private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
2479 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
2480 if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
2481 return;
2482 }
2483
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002484 final ActivityStack stack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002485 if (stack == null || task != stack.topTask()) {
2486 throw new IllegalArgumentException("Invalid task, not in foreground");
2487 }
2488
2489 // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
2490 // system or a specific app.
2491 // * System-initiated requests will only start the pinned mode (screen pinning)
2492 // * App-initiated requests
2493 // - will put the device in fully locked mode (LockTask), if the app is whitelisted
2494 // - will start the pinned mode, otherwise
2495 final int callingUid = Binder.getCallingUid();
2496 long ident = Binder.clearCallingIdentity();
2497 try {
2498 // When a task is locked, dismiss the pinned stack if it exists
2499 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2500
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002501 getLockTaskController().startLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002502 } finally {
2503 Binder.restoreCallingIdentity(ident);
2504 }
2505 }
2506
2507 private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
2508 final int callingUid = Binder.getCallingUid();
2509 long ident = Binder.clearCallingIdentity();
2510 try {
2511 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002512 getLockTaskController().stopLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002513 }
2514 // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
2515 // task and jumping straight into a call in the case of emergency call back.
2516 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
2517 if (tm != null) {
2518 tm.showInCallScreen(false);
2519 }
2520 } finally {
2521 Binder.restoreCallingIdentity(ident);
2522 }
2523 }
2524
2525 @Override
Wale Ogunwale27c48ae2018-10-25 19:01:01 -07002526 public void updateLockTaskPackages(int userId, String[] packages) {
2527 final int callingUid = Binder.getCallingUid();
2528 if (callingUid != 0 && callingUid != SYSTEM_UID) {
2529 mAmInternal.enforceCallingPermission(Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
2530 "updateLockTaskPackages()");
2531 }
2532 synchronized (this) {
2533 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":"
2534 + Arrays.toString(packages));
2535 getLockTaskController().updateLockTaskPackages(userId, packages);
2536 }
2537 }
2538
2539 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002540 public boolean isInLockTaskMode() {
2541 return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
2542 }
2543
2544 @Override
2545 public int getLockTaskModeState() {
2546 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002547 return getLockTaskController().getLockTaskModeState();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002548 }
2549 }
2550
2551 @Override
2552 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
2553 synchronized (mGlobalLock) {
2554 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2555 if (r != null) {
2556 r.setTaskDescription(td);
2557 final TaskRecord task = r.getTask();
2558 task.updateTaskDescription();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002559 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002560 }
2561 }
2562 }
2563
2564 @Override
2565 public Bundle getActivityOptions(IBinder token) {
2566 final long origId = Binder.clearCallingIdentity();
2567 try {
2568 synchronized (mGlobalLock) {
2569 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
2570 if (r != null) {
2571 final ActivityOptions activityOptions = r.takeOptionsLocked();
2572 return activityOptions == null ? null : activityOptions.toBundle();
2573 }
2574 return null;
2575 }
2576 } finally {
2577 Binder.restoreCallingIdentity(origId);
2578 }
2579 }
2580
2581 @Override
2582 public List<IBinder> getAppTasks(String callingPackage) {
2583 int callingUid = Binder.getCallingUid();
2584 long ident = Binder.clearCallingIdentity();
2585 try {
2586 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002587 return mRecentTasks.getAppTasksList(callingUid, callingPackage);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002588 }
2589 } finally {
2590 Binder.restoreCallingIdentity(ident);
2591 }
2592 }
2593
2594 @Override
2595 public void finishVoiceTask(IVoiceInteractionSession session) {
2596 synchronized (mGlobalLock) {
2597 final long origId = Binder.clearCallingIdentity();
2598 try {
2599 // TODO: VI Consider treating local voice interactions and voice tasks
2600 // differently here
2601 mStackSupervisor.finishVoiceTask(session);
2602 } finally {
2603 Binder.restoreCallingIdentity(origId);
2604 }
2605 }
2606
2607 }
2608
2609 @Override
2610 public boolean isTopOfTask(IBinder token) {
2611 synchronized (mGlobalLock) {
2612 ActivityRecord r = ActivityRecord.isInStackLocked(token);
Riddle Hsu66b74a82018-07-26 00:20:12 +08002613 return r != null && r.getTask().getTopActivity() == r;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002614 }
2615 }
2616
2617 @Override
2618 public void notifyLaunchTaskBehindComplete(IBinder token) {
2619 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
2620 }
2621
2622 @Override
2623 public void notifyEnterAnimationComplete(IBinder token) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002624 mH.post(() -> {
2625 synchronized (mGlobalLock) {
2626 ActivityRecord r = ActivityRecord.forTokenLocked(token);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002627 if (r != null && r.attachedToProcess()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002628 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002629 r.app.getThread().scheduleEnterAnimationComplete(r.appToken);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002630 } catch (RemoteException e) {
2631 }
2632 }
2633 }
2634
2635 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002636 }
2637
2638 /** Called from an app when assist data is ready. */
2639 @Override
2640 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
2641 AssistContent content, Uri referrer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002642 PendingAssistExtras pae = (PendingAssistExtras) token;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002643 synchronized (pae) {
2644 pae.result = extras;
2645 pae.structure = structure;
2646 pae.content = content;
2647 if (referrer != null) {
2648 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
2649 }
2650 if (structure != null) {
2651 structure.setHomeActivity(pae.isHome);
2652 }
2653 pae.haveResult = true;
2654 pae.notifyAll();
2655 if (pae.intent == null && pae.receiver == null) {
2656 // Caller is just waiting for the result.
2657 return;
2658 }
2659 }
2660 // We are now ready to launch the assist activity.
2661 IAssistDataReceiver sendReceiver = null;
2662 Bundle sendBundle = null;
2663 synchronized (mGlobalLock) {
2664 buildAssistBundleLocked(pae, extras);
2665 boolean exists = mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002666 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002667 if (!exists) {
2668 // Timed out.
2669 return;
2670 }
2671
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002672 if ((sendReceiver = pae.receiver) != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002673 // Caller wants result sent back to them.
2674 sendBundle = new Bundle();
2675 sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
2676 sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
2677 sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
2678 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
2679 }
2680 }
2681 if (sendReceiver != null) {
2682 try {
2683 sendReceiver.onHandleAssistData(sendBundle);
2684 } catch (RemoteException e) {
2685 }
2686 return;
2687 }
2688
2689 final long ident = Binder.clearCallingIdentity();
2690 try {
2691 if (TextUtils.equals(pae.intent.getAction(),
2692 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
2693 pae.intent.putExtras(pae.extras);
2694 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
2695 } else {
2696 pae.intent.replaceExtras(pae.extras);
2697 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
2698 | Intent.FLAG_ACTIVITY_SINGLE_TOP
2699 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Wale Ogunwale31913b52018-10-13 08:29:31 -07002700 mInternal.closeSystemDialogs("assist");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002701
2702 try {
2703 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
2704 } catch (ActivityNotFoundException e) {
2705 Slog.w(TAG, "No activity to handle assist action.", e);
2706 }
2707 }
2708 } finally {
2709 Binder.restoreCallingIdentity(ident);
2710 }
2711 }
2712
2713 @Override
2714 public int addAppTask(IBinder activityToken, Intent intent,
2715 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
2716 final int callingUid = Binder.getCallingUid();
2717 final long callingIdent = Binder.clearCallingIdentity();
2718
2719 try {
2720 synchronized (mGlobalLock) {
2721 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
2722 if (r == null) {
2723 throw new IllegalArgumentException("Activity does not exist; token="
2724 + activityToken);
2725 }
2726 ComponentName comp = intent.getComponent();
2727 if (comp == null) {
2728 throw new IllegalArgumentException("Intent " + intent
2729 + " must specify explicit component");
2730 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002731 if (thumbnail.getWidth() != mThumbnailWidth
2732 || thumbnail.getHeight() != mThumbnailHeight) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002733 throw new IllegalArgumentException("Bad thumbnail size: got "
2734 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002735 + mThumbnailWidth + "x" + mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002736 }
2737 if (intent.getSelector() != null) {
2738 intent.setSelector(null);
2739 }
2740 if (intent.getSourceBounds() != null) {
2741 intent.setSourceBounds(null);
2742 }
2743 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
2744 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
2745 // The caller has added this as an auto-remove task... that makes no
2746 // sense, so turn off auto-remove.
2747 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
2748 }
2749 }
2750 final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
2751 STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
2752 if (ainfo.applicationInfo.uid != callingUid) {
2753 throw new SecurityException(
2754 "Can't add task for another application: target uid="
2755 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
2756 }
2757
2758 final ActivityStack stack = r.getStack();
2759 final TaskRecord task = stack.createTaskRecord(
2760 mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent,
2761 null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002762 if (!mRecentTasks.addToBottom(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002763 // The app has too many tasks already and we can't add any more
2764 stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
2765 return INVALID_TASK_ID;
2766 }
2767 task.lastTaskDescription.copyFrom(description);
2768
2769 // TODO: Send the thumbnail to WM to store it.
2770
2771 return task.taskId;
2772 }
2773 } finally {
2774 Binder.restoreCallingIdentity(callingIdent);
2775 }
2776 }
2777
2778 @Override
2779 public Point getAppTaskThumbnailSize() {
2780 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002781 return new Point(mThumbnailWidth, mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002782 }
2783 }
2784
2785 @Override
2786 public void setTaskResizeable(int taskId, int resizeableMode) {
2787 synchronized (mGlobalLock) {
2788 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
2789 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
2790 if (task == null) {
2791 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
2792 return;
2793 }
2794 task.setResizeMode(resizeableMode);
2795 }
2796 }
2797
2798 @Override
2799 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002800 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002801 long ident = Binder.clearCallingIdentity();
2802 try {
2803 synchronized (mGlobalLock) {
2804 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2805 if (task == null) {
2806 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
2807 return;
2808 }
2809 // Place the task in the right stack if it isn't there already based on
2810 // the requested bounds.
2811 // The stack transition logic is:
2812 // - a null bounds on a freeform task moves that task to fullscreen
2813 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
2814 // that task to freeform
2815 // - otherwise the task is not moved
2816 ActivityStack stack = task.getStack();
2817 if (!task.getWindowConfiguration().canResizeTask()) {
2818 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
2819 }
2820 if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
2821 stack = stack.getDisplay().getOrCreateStack(
2822 WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
2823 } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
2824 stack = stack.getDisplay().getOrCreateStack(
2825 WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
2826 }
2827
2828 // Reparent the task to the right stack if necessary
2829 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
2830 if (stack != task.getStack()) {
2831 // Defer resume until the task is resized below
2832 task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
2833 DEFER_RESUME, "resizeTask");
2834 preserveWindow = false;
2835 }
2836
2837 // After reparenting (which only resizes the task to the stack bounds), resize the
2838 // task to the actual bounds provided
2839 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
2840 }
2841 } finally {
2842 Binder.restoreCallingIdentity(ident);
2843 }
2844 }
2845
2846 @Override
2847 public boolean releaseActivityInstance(IBinder token) {
2848 synchronized (mGlobalLock) {
2849 final long origId = Binder.clearCallingIdentity();
2850 try {
2851 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2852 if (r == null) {
2853 return false;
2854 }
2855 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
2856 } finally {
2857 Binder.restoreCallingIdentity(origId);
2858 }
2859 }
2860 }
2861
2862 @Override
2863 public void releaseSomeActivities(IApplicationThread appInt) {
2864 synchronized (mGlobalLock) {
2865 final long origId = Binder.clearCallingIdentity();
2866 try {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07002867 final WindowProcessController app = getProcessController(appInt);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002868 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
2869 } finally {
2870 Binder.restoreCallingIdentity(origId);
2871 }
2872 }
2873 }
2874
2875 @Override
2876 public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
2877 int secondaryDisplayShowing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002878 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002879 != PackageManager.PERMISSION_GRANTED) {
2880 throw new SecurityException("Requires permission "
2881 + android.Manifest.permission.DEVICE_POWER);
2882 }
2883
2884 synchronized (mGlobalLock) {
2885 long ident = Binder.clearCallingIdentity();
2886 if (mKeyguardShown != keyguardShowing) {
2887 mKeyguardShown = keyguardShowing;
Wale Ogunwale342fbe92018-10-09 08:44:10 -07002888 final Message msg = PooledLambda.obtainMessage(
2889 ActivityManagerInternal::reportCurKeyguardUsageEvent, mAmInternal,
2890 keyguardShowing);
2891 mH.sendMessage(msg);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002892 }
2893 try {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002894 mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002895 secondaryDisplayShowing);
2896 } finally {
2897 Binder.restoreCallingIdentity(ident);
2898 }
2899 }
2900
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002901 mH.post(() -> {
2902 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2903 mScreenObservers.get(i).onKeyguardStateChanged(keyguardShowing);
2904 }
2905 });
2906 }
2907
Wale Ogunwale387b34c2018-10-25 19:59:40 -07002908 public void onScreenAwakeChanged(boolean isAwake) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002909 mH.post(() -> {
2910 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2911 mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2912 }
2913 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002914 }
2915
2916 @Override
2917 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002918 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
2919 userId, "getTaskDescriptionIcon");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002920
2921 final File passedIconFile = new File(filePath);
2922 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
2923 passedIconFile.getName());
2924 if (!legitIconFile.getPath().equals(filePath)
2925 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
2926 throw new IllegalArgumentException("Bad file path: " + filePath
2927 + " passed for userId " + userId);
2928 }
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002929 return mRecentTasks.getTaskDescriptionIcon(filePath);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002930 }
2931
2932 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002933 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002934 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
2935 final ActivityOptions activityOptions = safeOptions != null
2936 ? safeOptions.getOptions(mStackSupervisor)
2937 : null;
2938 if (activityOptions == null
2939 || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
2940 || activityOptions.getCustomInPlaceResId() == 0) {
2941 throw new IllegalArgumentException("Expected in-place ActivityOption " +
2942 "with valid animation");
2943 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002944 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
2945 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002946 activityOptions.getCustomInPlaceResId());
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002947 mWindowManager.executeAppTransition();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002948 }
2949
2950 @Override
2951 public void removeStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002952 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002953 synchronized (mGlobalLock) {
2954 final long ident = Binder.clearCallingIdentity();
2955 try {
2956 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2957 if (stack == null) {
2958 Slog.w(TAG, "removeStack: No stack with id=" + stackId);
2959 return;
2960 }
2961 if (!stack.isActivityTypeStandardOrUndefined()) {
2962 throw new IllegalArgumentException(
2963 "Removing non-standard stack is not allowed.");
2964 }
2965 mStackSupervisor.removeStack(stack);
2966 } finally {
2967 Binder.restoreCallingIdentity(ident);
2968 }
2969 }
2970 }
2971
2972 @Override
2973 public void moveStackToDisplay(int stackId, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002974 mAmInternal.enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002975
2976 synchronized (mGlobalLock) {
2977 final long ident = Binder.clearCallingIdentity();
2978 try {
2979 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
2980 + " to displayId=" + displayId);
2981 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
2982 } finally {
2983 Binder.restoreCallingIdentity(ident);
2984 }
2985 }
2986 }
2987
2988 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002989 public void exitFreeformMode(IBinder token) {
2990 synchronized (mGlobalLock) {
2991 long ident = Binder.clearCallingIdentity();
2992 try {
2993 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2994 if (r == null) {
2995 throw new IllegalArgumentException(
2996 "exitFreeformMode: No activity record matching token=" + token);
2997 }
2998
2999 final ActivityStack stack = r.getStack();
3000 if (stack == null || !stack.inFreeformWindowingMode()) {
3001 throw new IllegalStateException(
3002 "exitFreeformMode: You can only go fullscreen from freeform.");
3003 }
3004
3005 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
3006 } finally {
3007 Binder.restoreCallingIdentity(ident);
3008 }
3009 }
3010 }
3011
3012 /** Sets the task stack listener that gets callbacks when a task stack changes. */
3013 @Override
3014 public void registerTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003015 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003016 "registerTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003017 mTaskChangeNotificationController.registerTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003018 }
3019
3020 /** Unregister a task stack listener so that it stops receiving callbacks. */
3021 @Override
3022 public void unregisterTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003023 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003024 "unregisterTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003025 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003026 }
3027
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003028 @Override
3029 public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
3030 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
3031 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
3032 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
3033 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
3034 }
3035
3036 @Override
3037 public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
3038 IBinder activityToken, int flags) {
3039 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
3040 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
3041 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
3042 }
3043
3044 @Override
3045 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
3046 Bundle args) {
3047 return enqueueAssistContext(requestType, intent, hint, null, null, null,
3048 true /* focused */, true /* newSessionId */, userHandle, args,
3049 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
3050 }
3051
3052 @Override
3053 public Bundle getAssistContextExtras(int requestType) {
3054 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
3055 null, null, true /* focused */, true /* newSessionId */,
3056 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
3057 if (pae == null) {
3058 return null;
3059 }
3060 synchronized (pae) {
3061 while (!pae.haveResult) {
3062 try {
3063 pae.wait();
3064 } catch (InterruptedException e) {
3065 }
3066 }
3067 }
3068 synchronized (mGlobalLock) {
3069 buildAssistBundleLocked(pae, pae.result);
3070 mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003071 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003072 }
3073 return pae.extras;
3074 }
3075
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003076 /**
3077 * Binder IPC calls go through the public entry point.
3078 * This can be called with or without the global lock held.
3079 */
3080 private static int checkCallingPermission(String permission) {
3081 return checkPermission(
3082 permission, Binder.getCallingPid(), UserHandle.getAppId(Binder.getCallingUid()));
3083 }
3084
3085 /** This can be called with or without the global lock held. */
Wale Ogunwale214f3482018-10-04 11:00:47 -07003086 private void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003087 if (!getRecentTasks().isCallerRecents(Binder.getCallingUid())) {
3088 mAmInternal.enforceCallingPermission(permission, func);
3089 }
3090 }
3091
3092 @VisibleForTesting
3093 int checkGetTasksPermission(String permission, int pid, int uid) {
3094 return checkPermission(permission, pid, uid);
3095 }
3096
3097 static int checkPermission(String permission, int pid, int uid) {
3098 if (permission == null) {
3099 return PackageManager.PERMISSION_DENIED;
3100 }
3101 return checkComponentPermission(permission, pid, uid, -1, true);
3102 }
3103
Wale Ogunwale214f3482018-10-04 11:00:47 -07003104 public static int checkComponentPermission(String permission, int pid, int uid,
3105 int owningUid, boolean exported) {
3106 return ActivityManagerService.checkComponentPermission(
3107 permission, pid, uid, owningUid, exported);
3108 }
3109
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003110 boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
3111 if (getRecentTasks().isCallerRecents(callingUid)) {
3112 // Always allow the recents component to get tasks
3113 return true;
3114 }
3115
3116 boolean allowed = checkGetTasksPermission(android.Manifest.permission.REAL_GET_TASKS,
3117 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
3118 if (!allowed) {
3119 if (checkGetTasksPermission(android.Manifest.permission.GET_TASKS,
3120 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
3121 // Temporary compatibility: some existing apps on the system image may
3122 // still be requesting the old permission and not switched to the new
3123 // one; if so, we'll still allow them full access. This means we need
3124 // to see if they are holding the old permission and are a system app.
3125 try {
3126 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
3127 allowed = true;
3128 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
3129 + " is using old GET_TASKS but privileged; allowing");
3130 }
3131 } catch (RemoteException e) {
3132 }
3133 }
3134 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
3135 + " does not hold REAL_GET_TASKS; limiting output");
3136 }
3137 return allowed;
3138 }
3139
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003140 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
3141 IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
3142 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
3143 int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003144 mAmInternal.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003145 "enqueueAssistContext()");
3146
3147 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003148 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003149 if (activity == null) {
3150 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
3151 return null;
3152 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003153 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003154 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
3155 return null;
3156 }
3157 if (focused) {
3158 if (activityToken != null) {
3159 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
3160 if (activity != caller) {
3161 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
3162 + " is not current top " + activity);
3163 return null;
3164 }
3165 }
3166 } else {
3167 activity = ActivityRecord.forTokenLocked(activityToken);
3168 if (activity == null) {
3169 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
3170 + " couldn't be found");
3171 return null;
3172 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003173 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003174 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
3175 return null;
3176 }
3177 }
3178
3179 PendingAssistExtras pae;
3180 Bundle extras = new Bundle();
3181 if (args != null) {
3182 extras.putAll(args);
3183 }
3184 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003185 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003186
3187 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
3188 userHandle);
3189 pae.isHome = activity.isActivityTypeHome();
3190
3191 // Increment the sessionId if necessary
3192 if (newSessionId) {
3193 mViSessionId++;
3194 }
3195 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003196 activity.app.getThread().requestAssistContextExtras(activity.appToken, pae,
3197 requestType, mViSessionId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003198 mPendingAssistExtras.add(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003199 mUiHandler.postDelayed(pae, timeout);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003200 } catch (RemoteException e) {
3201 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
3202 return null;
3203 }
3204 return pae;
3205 }
3206 }
3207
3208 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
3209 if (result != null) {
3210 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
3211 }
3212 if (pae.hint != null) {
3213 pae.extras.putBoolean(pae.hint, true);
3214 }
3215 }
3216
3217 private void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
3218 IAssistDataReceiver receiver;
3219 synchronized (mGlobalLock) {
3220 mPendingAssistExtras.remove(pae);
3221 receiver = pae.receiver;
3222 }
3223 if (receiver != null) {
3224 // Caller wants result sent back to them.
3225 Bundle sendBundle = new Bundle();
3226 // At least return the receiver extras
3227 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
3228 try {
3229 pae.receiver.onHandleAssistData(sendBundle);
3230 } catch (RemoteException e) {
3231 }
3232 }
3233 }
3234
3235 public class PendingAssistExtras extends Binder implements Runnable {
3236 public final ActivityRecord activity;
3237 public boolean isHome;
3238 public final Bundle extras;
3239 public final Intent intent;
3240 public final String hint;
3241 public final IAssistDataReceiver receiver;
3242 public final int userHandle;
3243 public boolean haveResult = false;
3244 public Bundle result = null;
3245 public AssistStructure structure = null;
3246 public AssistContent content = null;
3247 public Bundle receiverExtras;
3248
3249 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
3250 String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
3251 int _userHandle) {
3252 activity = _activity;
3253 extras = _extras;
3254 intent = _intent;
3255 hint = _hint;
3256 receiver = _receiver;
3257 receiverExtras = _receiverExtras;
3258 userHandle = _userHandle;
3259 }
3260
3261 @Override
3262 public void run() {
3263 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
3264 synchronized (this) {
3265 haveResult = true;
3266 notifyAll();
3267 }
3268 pendingAssistExtrasTimedOut(this);
3269 }
3270 }
3271
3272 @Override
3273 public boolean isAssistDataAllowedOnCurrentActivity() {
3274 int userId;
3275 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003276 final ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003277 if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
3278 return false;
3279 }
3280
3281 final ActivityRecord activity = focusedStack.getTopActivity();
3282 if (activity == null) {
3283 return false;
3284 }
3285 userId = activity.userId;
3286 }
3287 return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
3288 }
3289
3290 @Override
3291 public boolean showAssistFromActivity(IBinder token, Bundle args) {
3292 long ident = Binder.clearCallingIdentity();
3293 try {
3294 synchronized (mGlobalLock) {
3295 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003296 ActivityRecord top = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003297 if (top != caller) {
3298 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3299 + " is not current top " + top);
3300 return false;
3301 }
3302 if (!top.nowVisible) {
3303 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3304 + " is not visible");
3305 return false;
3306 }
3307 }
3308 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
3309 token);
3310 } finally {
3311 Binder.restoreCallingIdentity(ident);
3312 }
3313 }
3314
3315 @Override
3316 public boolean isRootVoiceInteraction(IBinder token) {
3317 synchronized (mGlobalLock) {
3318 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3319 if (r == null) {
3320 return false;
3321 }
3322 return r.rootVoiceInteraction;
3323 }
3324 }
3325
Wale Ogunwalef6733932018-06-27 05:14:34 -07003326 private void onLocalVoiceInteractionStartedLocked(IBinder activity,
3327 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
3328 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
3329 if (activityToCallback == null) return;
3330 activityToCallback.setVoiceSessionLocked(voiceSession);
3331
3332 // Inform the activity
3333 try {
3334 activityToCallback.app.getThread().scheduleLocalVoiceInteractionStarted(activity,
3335 voiceInteractor);
3336 long token = Binder.clearCallingIdentity();
3337 try {
3338 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
3339 } finally {
3340 Binder.restoreCallingIdentity(token);
3341 }
3342 // TODO: VI Should we cache the activity so that it's easier to find later
3343 // rather than scan through all the stacks and activities?
3344 } catch (RemoteException re) {
3345 activityToCallback.clearVoiceSessionLocked();
3346 // TODO: VI Should this terminate the voice session?
3347 }
3348 }
3349
3350 private void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
3351 Slog.d(TAG, "<<< startRunningVoiceLocked()");
3352 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
3353 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
3354 boolean wasRunningVoice = mRunningVoice != null;
3355 mRunningVoice = session;
3356 if (!wasRunningVoice) {
3357 mVoiceWakeLock.acquire();
3358 updateSleepIfNeededLocked();
3359 }
3360 }
3361 }
3362
3363 void finishRunningVoiceLocked() {
3364 if (mRunningVoice != null) {
3365 mRunningVoice = null;
3366 mVoiceWakeLock.release();
3367 updateSleepIfNeededLocked();
3368 }
3369 }
3370
3371 @Override
3372 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3373 synchronized (mGlobalLock) {
3374 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3375 if (keepAwake) {
3376 mVoiceWakeLock.acquire();
3377 } else {
3378 mVoiceWakeLock.release();
3379 }
3380 }
3381 }
3382 }
3383
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003384 @Override
3385 public ComponentName getActivityClassForToken(IBinder token) {
3386 synchronized (mGlobalLock) {
3387 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3388 if (r == null) {
3389 return null;
3390 }
3391 return r.intent.getComponent();
3392 }
3393 }
3394
3395 @Override
3396 public String getPackageForToken(IBinder token) {
3397 synchronized (mGlobalLock) {
3398 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3399 if (r == null) {
3400 return null;
3401 }
3402 return r.packageName;
3403 }
3404 }
3405
3406 @Override
3407 public void showLockTaskEscapeMessage(IBinder token) {
3408 synchronized (mGlobalLock) {
3409 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3410 if (r == null) {
3411 return;
3412 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003413 getLockTaskController().showLockTaskToast();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003414 }
3415 }
3416
3417 @Override
3418 public void keyguardGoingAway(int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003419 enforceNotIsolatedCaller("keyguardGoingAway");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003420 final long token = Binder.clearCallingIdentity();
3421 try {
3422 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003423 mKeyguardController.keyguardGoingAway(flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003424 }
3425 } finally {
3426 Binder.restoreCallingIdentity(token);
3427 }
3428 }
3429
3430 /**
3431 * Try to place task to provided position. The final position might be different depending on
3432 * current user and stacks state. The task will be moved to target stack if it's currently in
3433 * different stack.
3434 */
3435 @Override
3436 public void positionTaskInStack(int taskId, int stackId, int position) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003437 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003438 synchronized (mGlobalLock) {
3439 long ident = Binder.clearCallingIdentity();
3440 try {
3441 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
3442 + taskId + " in stackId=" + stackId + " at position=" + position);
3443 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3444 if (task == null) {
3445 throw new IllegalArgumentException("positionTaskInStack: no task for id="
3446 + taskId);
3447 }
3448
3449 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3450
3451 if (stack == null) {
3452 throw new IllegalArgumentException("positionTaskInStack: no stack for id="
3453 + stackId);
3454 }
3455 if (!stack.isActivityTypeStandardOrUndefined()) {
3456 throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
3457 + " the position of task " + taskId + " in/to non-standard stack");
3458 }
3459
3460 // TODO: Have the callers of this API call a separate reparent method if that is
3461 // what they intended to do vs. having this method also do reparenting.
3462 if (task.getStack() == stack) {
3463 // Change position in current stack.
3464 stack.positionChildAt(task, position);
3465 } else {
3466 // Reparent to new stack.
3467 task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
3468 !DEFER_RESUME, "positionTaskInStack");
3469 }
3470 } finally {
3471 Binder.restoreCallingIdentity(ident);
3472 }
3473 }
3474 }
3475
3476 @Override
3477 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
3478 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
3479 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
3480 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
3481 synchronized (mGlobalLock) {
3482 ActivityRecord record = ActivityRecord.isInStackLocked(token);
3483 if (record == null) {
3484 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
3485 + "found for: " + token);
3486 }
3487 record.setSizeConfigurations(horizontalSizeConfiguration,
3488 verticalSizeConfigurations, smallestSizeConfigurations);
3489 }
3490 }
3491
3492 /**
3493 * Dismisses split-screen multi-window mode.
3494 * @param toTop If true the current primary split-screen stack will be placed or left on top.
3495 */
3496 @Override
3497 public void dismissSplitScreenMode(boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003498 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003499 MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
3500 final long ident = Binder.clearCallingIdentity();
3501 try {
3502 synchronized (mGlobalLock) {
3503 final ActivityStack stack =
3504 mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
3505 if (stack == null) {
3506 Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
3507 return;
3508 }
3509
3510 if (toTop) {
3511 // Caller wants the current split-screen primary stack to be the top stack after
3512 // it goes fullscreen, so move it to the front.
3513 stack.moveToFront("dismissSplitScreenMode");
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003514 } else if (mStackSupervisor.isTopDisplayFocusedStack(stack)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003515 // In this case the current split-screen primary stack shouldn't be the top
3516 // stack after it goes fullscreen, but it current has focus, so we move the
3517 // focus to the top-most split-screen secondary stack next to it.
3518 final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
3519 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
3520 if (otherStack != null) {
3521 otherStack.moveToFront("dismissSplitScreenMode_other");
3522 }
3523 }
3524
Evan Rosky10475742018-09-05 19:02:48 -07003525 stack.setWindowingMode(WINDOWING_MODE_UNDEFINED);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003526 }
3527 } finally {
3528 Binder.restoreCallingIdentity(ident);
3529 }
3530 }
3531
3532 /**
3533 * Dismisses Pip
3534 * @param animate True if the dismissal should be animated.
3535 * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
3536 * default animation duration should be used.
3537 */
3538 @Override
3539 public void dismissPip(boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003540 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003541 final long ident = Binder.clearCallingIdentity();
3542 try {
3543 synchronized (mGlobalLock) {
3544 final PinnedActivityStack stack =
3545 mStackSupervisor.getDefaultDisplay().getPinnedStack();
3546 if (stack == null) {
3547 Slog.w(TAG, "dismissPip: pinned stack not found.");
3548 return;
3549 }
3550 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
3551 throw new IllegalArgumentException("Stack: " + stack
3552 + " doesn't support animated resize.");
3553 }
3554 if (animate) {
3555 stack.animateResizePinnedStack(null /* sourceHintBounds */,
3556 null /* destBounds */, animationDuration, false /* fromFullscreen */);
3557 } else {
3558 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
3559 }
3560 }
3561 } finally {
3562 Binder.restoreCallingIdentity(ident);
3563 }
3564 }
3565
3566 @Override
3567 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003568 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003569 synchronized (mGlobalLock) {
3570 mSuppressResizeConfigChanges = suppress;
3571 }
3572 }
3573
3574 /**
3575 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
3576 * animated the stack to the fullscreen, but can also be called if we are relaunching an
3577 * activity and clearing the task at the same time.
3578 */
3579 @Override
3580 // TODO: API should just be about changing windowing modes...
3581 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003582 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003583 "moveTasksToFullscreenStack()");
3584 synchronized (mGlobalLock) {
3585 final long origId = Binder.clearCallingIdentity();
3586 try {
3587 final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
3588 if (stack != null){
3589 if (!stack.isActivityTypeStandardOrUndefined()) {
3590 throw new IllegalArgumentException(
3591 "You can't move tasks from non-standard stacks.");
3592 }
3593 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
3594 }
3595 } finally {
3596 Binder.restoreCallingIdentity(origId);
3597 }
3598 }
3599 }
3600
3601 /**
3602 * Moves the top activity in the input stackId to the pinned stack.
3603 *
3604 * @param stackId Id of stack to move the top activity to pinned stack.
3605 * @param bounds Bounds to use for pinned stack.
3606 *
3607 * @return True if the top activity of the input stack was successfully moved to the pinned
3608 * stack.
3609 */
3610 @Override
3611 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003612 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003613 "moveTopActivityToPinnedStack()");
3614 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003615 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003616 throw new IllegalStateException("moveTopActivityToPinnedStack:"
3617 + "Device doesn't support picture-in-picture mode");
3618 }
3619
3620 long ident = Binder.clearCallingIdentity();
3621 try {
3622 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
3623 } finally {
3624 Binder.restoreCallingIdentity(ident);
3625 }
3626 }
3627 }
3628
3629 @Override
3630 public boolean isInMultiWindowMode(IBinder token) {
3631 final long origId = Binder.clearCallingIdentity();
3632 try {
3633 synchronized (mGlobalLock) {
3634 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3635 if (r == null) {
3636 return false;
3637 }
3638 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
3639 return r.inMultiWindowMode();
3640 }
3641 } finally {
3642 Binder.restoreCallingIdentity(origId);
3643 }
3644 }
3645
3646 @Override
3647 public boolean isInPictureInPictureMode(IBinder token) {
3648 final long origId = Binder.clearCallingIdentity();
3649 try {
3650 synchronized (mGlobalLock) {
3651 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
3652 }
3653 } finally {
3654 Binder.restoreCallingIdentity(origId);
3655 }
3656 }
3657
3658 private boolean isInPictureInPictureMode(ActivityRecord r) {
3659 if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
3660 || r.getStack().isInStackLocked(r) == null) {
3661 return false;
3662 }
3663
3664 // If we are animating to fullscreen then we have already dispatched the PIP mode
3665 // changed, so we should reflect that check here as well.
3666 final PinnedActivityStack stack = r.getStack();
3667 final PinnedStackWindowController windowController = stack.getWindowContainerController();
3668 return !windowController.isAnimatingBoundsToFullscreen();
3669 }
3670
3671 @Override
3672 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
3673 final long origId = Binder.clearCallingIdentity();
3674 try {
3675 synchronized (mGlobalLock) {
3676 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3677 "enterPictureInPictureMode", token, params);
3678
3679 // If the activity is already in picture in picture mode, then just return early
3680 if (isInPictureInPictureMode(r)) {
3681 return true;
3682 }
3683
3684 // Activity supports picture-in-picture, now check that we can enter PiP at this
3685 // point, if it is
3686 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
3687 false /* beforeStopping */)) {
3688 return false;
3689 }
3690
3691 final Runnable enterPipRunnable = () -> {
Wale Ogunwalef276a6f2018-06-15 08:26:07 -07003692 synchronized (mGlobalLock) {
3693 // Only update the saved args from the args that are set
3694 r.pictureInPictureArgs.copyOnlySet(params);
3695 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
3696 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
3697 // Adjust the source bounds by the insets for the transition down
3698 final Rect sourceBounds = new Rect(
3699 r.pictureInPictureArgs.getSourceRectHint());
3700 mStackSupervisor.moveActivityToPinnedStackLocked(
3701 r, sourceBounds, aspectRatio, "enterPictureInPictureMode");
3702 final PinnedActivityStack stack = r.getStack();
3703 stack.setPictureInPictureAspectRatio(aspectRatio);
3704 stack.setPictureInPictureActions(actions);
3705 MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
3706 r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
3707 logPictureInPictureArgs(params);
3708 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003709 };
3710
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003711 if (isKeyguardLocked()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003712 // If the keyguard is showing or occluded, then try and dismiss it before
3713 // entering picture-in-picture (this will prompt the user to authenticate if the
3714 // device is currently locked).
3715 dismissKeyguard(token, new KeyguardDismissCallback() {
3716 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003717 public void onDismissSucceeded() {
3718 mH.post(enterPipRunnable);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003719 }
3720 }, null /* message */);
3721 } else {
3722 // Enter picture in picture immediately otherwise
3723 enterPipRunnable.run();
3724 }
3725 return true;
3726 }
3727 } finally {
3728 Binder.restoreCallingIdentity(origId);
3729 }
3730 }
3731
3732 @Override
3733 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
3734 final long origId = Binder.clearCallingIdentity();
3735 try {
3736 synchronized (mGlobalLock) {
3737 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3738 "setPictureInPictureParams", token, params);
3739
3740 // Only update the saved args from the args that are set
3741 r.pictureInPictureArgs.copyOnlySet(params);
3742 if (r.inPinnedWindowingMode()) {
3743 // If the activity is already in picture-in-picture, update the pinned stack now
3744 // if it is not already expanding to fullscreen. Otherwise, the arguments will
3745 // be used the next time the activity enters PiP
3746 final PinnedActivityStack stack = r.getStack();
3747 if (!stack.isAnimatingBoundsToFullscreen()) {
3748 stack.setPictureInPictureAspectRatio(
3749 r.pictureInPictureArgs.getAspectRatio());
3750 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
3751 }
3752 }
3753 logPictureInPictureArgs(params);
3754 }
3755 } finally {
3756 Binder.restoreCallingIdentity(origId);
3757 }
3758 }
3759
3760 @Override
3761 public int getMaxNumPictureInPictureActions(IBinder token) {
3762 // Currently, this is a static constant, but later, we may change this to be dependent on
3763 // the context of the activity
3764 return 3;
3765 }
3766
3767 private void logPictureInPictureArgs(PictureInPictureParams params) {
3768 if (params.hasSetActions()) {
3769 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
3770 params.getActions().size());
3771 }
3772 if (params.hasSetAspectRatio()) {
3773 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
3774 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
3775 MetricsLogger.action(lm);
3776 }
3777 }
3778
3779 /**
3780 * Checks the state of the system and the activity associated with the given {@param token} to
3781 * verify that picture-in-picture is supported for that activity.
3782 *
3783 * @return the activity record for the given {@param token} if all the checks pass.
3784 */
3785 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
3786 IBinder token, PictureInPictureParams params) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003787 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003788 throw new IllegalStateException(caller
3789 + ": Device doesn't support picture-in-picture mode.");
3790 }
3791
3792 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3793 if (r == null) {
3794 throw new IllegalStateException(caller
3795 + ": Can't find activity for token=" + token);
3796 }
3797
3798 if (!r.supportsPictureInPicture()) {
3799 throw new IllegalStateException(caller
3800 + ": Current activity does not support picture-in-picture.");
3801 }
3802
3803 if (params.hasSetAspectRatio()
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003804 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003805 params.getAspectRatio())) {
3806 final float minAspectRatio = mContext.getResources().getFloat(
3807 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
3808 final float maxAspectRatio = mContext.getResources().getFloat(
3809 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
3810 throw new IllegalArgumentException(String.format(caller
3811 + ": Aspect ratio is too extreme (must be between %f and %f).",
3812 minAspectRatio, maxAspectRatio));
3813 }
3814
3815 // Truncate the number of actions if necessary
3816 params.truncateActions(getMaxNumPictureInPictureActions(token));
3817
3818 return r;
3819 }
3820
3821 @Override
3822 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003823 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003824 synchronized (mGlobalLock) {
3825 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
3826 if (r == null) {
3827 throw new IllegalArgumentException("Activity does not exist; token="
3828 + activityToken);
3829 }
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07003830 return r.getUriPermissionsLocked().getExternalToken();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003831 }
3832 }
3833
3834 @Override
3835 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
3836 Rect tempDockedTaskInsetBounds,
3837 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003838 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003839 long ident = Binder.clearCallingIdentity();
3840 try {
3841 synchronized (mGlobalLock) {
3842 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
3843 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
3844 PRESERVE_WINDOWS);
3845 }
3846 } finally {
3847 Binder.restoreCallingIdentity(ident);
3848 }
3849 }
3850
3851 @Override
3852 public void setSplitScreenResizing(boolean resizing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003853 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003854 final long ident = Binder.clearCallingIdentity();
3855 try {
3856 synchronized (mGlobalLock) {
3857 mStackSupervisor.setSplitScreenResizing(resizing);
3858 }
3859 } finally {
3860 Binder.restoreCallingIdentity(ident);
3861 }
3862 }
3863
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003864 /**
3865 * Check that we have the features required for VR-related API calls, and throw an exception if
3866 * not.
3867 */
3868 void enforceSystemHasVrFeature() {
3869 if (!mContext.getPackageManager().hasSystemFeature(
3870 PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
3871 throw new UnsupportedOperationException("VR mode not supported on this device!");
3872 }
3873 }
3874
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003875 @Override
3876 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003877 enforceSystemHasVrFeature();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003878
3879 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3880
3881 ActivityRecord r;
3882 synchronized (mGlobalLock) {
3883 r = ActivityRecord.isInStackLocked(token);
3884 }
3885
3886 if (r == null) {
3887 throw new IllegalArgumentException();
3888 }
3889
3890 int err;
3891 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
3892 VrManagerInternal.NO_ERROR) {
3893 return err;
3894 }
3895
3896 // Clear the binder calling uid since this path may call moveToTask().
3897 final long callingId = Binder.clearCallingIdentity();
3898 try {
3899 synchronized (mGlobalLock) {
3900 r.requestedVrComponent = (enabled) ? packageName : null;
3901
3902 // Update associated state if this activity is currently focused
Andrii Kulian52d255c2018-07-13 11:32:19 -07003903 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003904 applyUpdateVrModeLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003905 }
3906 return 0;
3907 }
3908 } finally {
3909 Binder.restoreCallingIdentity(callingId);
3910 }
3911 }
3912
3913 @Override
3914 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
3915 Slog.i(TAG, "Activity tried to startLocalVoiceInteraction");
3916 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003917 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003918 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
3919 throw new SecurityException("Only focused activity can call startVoiceInteraction");
3920 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07003921 if (mRunningVoice != null || activity.getTask().voiceSession != null
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003922 || activity.voiceSession != null) {
3923 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
3924 return;
3925 }
3926 if (activity.pendingVoiceInteractionStart) {
3927 Slog.w(TAG, "Pending start of voice interaction already.");
3928 return;
3929 }
3930 activity.pendingVoiceInteractionStart = true;
3931 }
3932 LocalServices.getService(VoiceInteractionManagerInternal.class)
3933 .startLocalVoiceInteraction(callingActivity, options);
3934 }
3935
3936 @Override
3937 public void stopLocalVoiceInteraction(IBinder callingActivity) {
3938 LocalServices.getService(VoiceInteractionManagerInternal.class)
3939 .stopLocalVoiceInteraction(callingActivity);
3940 }
3941
3942 @Override
3943 public boolean supportsLocalVoiceInteraction() {
3944 return LocalServices.getService(VoiceInteractionManagerInternal.class)
3945 .supportsLocalVoiceInteraction();
3946 }
3947
3948 /** Notifies all listeners when the pinned stack animation starts. */
3949 @Override
3950 public void notifyPinnedStackAnimationStarted() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003951 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003952 }
3953
3954 /** Notifies all listeners when the pinned stack animation ends. */
3955 @Override
3956 public void notifyPinnedStackAnimationEnded() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003957 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003958 }
3959
3960 @Override
3961 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003962 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003963 final long ident = Binder.clearCallingIdentity();
3964 try {
3965 synchronized (mGlobalLock) {
3966 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
3967 }
3968 } finally {
3969 Binder.restoreCallingIdentity(ident);
3970 }
3971 }
3972
3973 @Override
3974 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003975 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003976
3977 synchronized (mGlobalLock) {
3978 // Check if display is initialized in AM.
3979 if (!mStackSupervisor.isDisplayAdded(displayId)) {
3980 // Call might come when display is not yet added or has already been removed.
3981 if (DEBUG_CONFIGURATION) {
3982 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
3983 + displayId);
3984 }
3985 return false;
3986 }
3987
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003988 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003989 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003990 values = mWindowManager.computeNewConfiguration(displayId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003991 }
3992
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003993 if (mWindowManager != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07003994 final Message msg = PooledLambda.obtainMessage(
3995 ActivityManagerInternal::updateOomLevelsForDisplay, mAmInternal, displayId);
3996 mH.sendMessage(msg);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003997 }
3998
3999 final long origId = Binder.clearCallingIdentity();
4000 try {
4001 if (values != null) {
4002 Settings.System.clearConfiguration(values);
4003 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004004 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004005 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
4006 return mTmpUpdateConfigurationResult.changes != 0;
4007 } finally {
4008 Binder.restoreCallingIdentity(origId);
4009 }
4010 }
4011 }
4012
4013 @Override
4014 public boolean updateConfiguration(Configuration values) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004015 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004016
4017 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004018 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004019 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004020 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004021 }
4022
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004023 if (mWindowManager != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004024 final Message msg = PooledLambda.obtainMessage(
4025 ActivityManagerInternal::updateOomLevelsForDisplay, mAmInternal,
4026 DEFAULT_DISPLAY);
4027 mH.sendMessage(msg);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004028 }
4029
4030 final long origId = Binder.clearCallingIdentity();
4031 try {
4032 if (values != null) {
4033 Settings.System.clearConfiguration(values);
4034 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004035 updateConfigurationLocked(values, null, false, false /* persistent */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004036 UserHandle.USER_NULL, false /* deferResume */,
4037 mTmpUpdateConfigurationResult);
4038 return mTmpUpdateConfigurationResult.changes != 0;
4039 } finally {
4040 Binder.restoreCallingIdentity(origId);
4041 }
4042 }
4043 }
4044
4045 @Override
4046 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
4047 CharSequence message) {
4048 if (message != null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004049 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004050 Manifest.permission.SHOW_KEYGUARD_MESSAGE, "dismissKeyguard()");
4051 }
4052 final long callingId = Binder.clearCallingIdentity();
4053 try {
4054 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004055 mKeyguardController.dismissKeyguard(token, callback, message);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004056 }
4057 } finally {
4058 Binder.restoreCallingIdentity(callingId);
4059 }
4060 }
4061
4062 @Override
4063 public void cancelTaskWindowTransition(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004064 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004065 "cancelTaskWindowTransition()");
4066 final long ident = Binder.clearCallingIdentity();
4067 try {
4068 synchronized (mGlobalLock) {
4069 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
4070 MATCH_TASK_IN_STACKS_ONLY);
4071 if (task == null) {
4072 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
4073 return;
4074 }
4075 task.cancelWindowTransition();
4076 }
4077 } finally {
4078 Binder.restoreCallingIdentity(ident);
4079 }
4080 }
4081
4082 @Override
4083 public ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004084 enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004085 final long ident = Binder.clearCallingIdentity();
4086 try {
4087 final TaskRecord task;
4088 synchronized (mGlobalLock) {
4089 task = mStackSupervisor.anyTaskForIdLocked(taskId,
4090 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
4091 if (task == null) {
4092 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
4093 return null;
4094 }
4095 }
4096 // Don't call this while holding the lock as this operation might hit the disk.
4097 return task.getSnapshot(reducedResolution);
4098 } finally {
4099 Binder.restoreCallingIdentity(ident);
4100 }
4101 }
4102
4103 @Override
4104 public void setDisablePreviewScreenshots(IBinder token, boolean disable) {
4105 synchronized (mGlobalLock) {
4106 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4107 if (r == null) {
4108 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
4109 + token);
4110 return;
4111 }
4112 final long origId = Binder.clearCallingIdentity();
4113 try {
4114 r.setDisablePreviewScreenshots(disable);
4115 } finally {
4116 Binder.restoreCallingIdentity(origId);
4117 }
4118 }
4119 }
4120
4121 /** Return the user id of the last resumed activity. */
4122 @Override
4123 public @UserIdInt
4124 int getLastResumedActivityUserId() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004125 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004126 Manifest.permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
4127 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07004128 if (mLastResumedActivity == null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004129 return getCurrentUserId();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004130 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004131 return mLastResumedActivity.userId;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004132 }
4133 }
4134
4135 @Override
4136 public void updateLockTaskFeatures(int userId, int flags) {
4137 final int callingUid = Binder.getCallingUid();
4138 if (callingUid != 0 && callingUid != SYSTEM_UID) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004139 mAmInternal.enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004140 "updateLockTaskFeatures()");
4141 }
4142 synchronized (mGlobalLock) {
4143 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
4144 Integer.toHexString(flags));
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07004145 getLockTaskController().updateLockTaskFeatures(userId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004146 }
4147 }
4148
4149 @Override
4150 public void setShowWhenLocked(IBinder token, boolean showWhenLocked) {
4151 synchronized (mGlobalLock) {
4152 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4153 if (r == null) {
4154 return;
4155 }
4156 final long origId = Binder.clearCallingIdentity();
4157 try {
4158 r.setShowWhenLocked(showWhenLocked);
4159 } finally {
4160 Binder.restoreCallingIdentity(origId);
4161 }
4162 }
4163 }
4164
4165 @Override
4166 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) {
4167 synchronized (mGlobalLock) {
4168 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4169 if (r == null) {
4170 return;
4171 }
4172 final long origId = Binder.clearCallingIdentity();
4173 try {
4174 r.setTurnScreenOn(turnScreenOn);
4175 } finally {
4176 Binder.restoreCallingIdentity(origId);
4177 }
4178 }
4179 }
4180
4181 @Override
4182 public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004183 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004184 "registerRemoteAnimations");
4185 definition.setCallingPid(Binder.getCallingPid());
4186 synchronized (mGlobalLock) {
4187 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4188 if (r == null) {
4189 return;
4190 }
4191 final long origId = Binder.clearCallingIdentity();
4192 try {
4193 r.registerRemoteAnimations(definition);
4194 } finally {
4195 Binder.restoreCallingIdentity(origId);
4196 }
4197 }
4198 }
4199
4200 @Override
4201 public void registerRemoteAnimationForNextActivityStart(String packageName,
4202 RemoteAnimationAdapter adapter) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004203 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004204 "registerRemoteAnimationForNextActivityStart");
4205 adapter.setCallingPid(Binder.getCallingPid());
4206 synchronized (mGlobalLock) {
4207 final long origId = Binder.clearCallingIdentity();
4208 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07004209 getActivityStartController().registerRemoteAnimationForNextActivityStart(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004210 packageName, adapter);
4211 } finally {
4212 Binder.restoreCallingIdentity(origId);
4213 }
4214 }
4215 }
4216
4217 /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
4218 @Override
4219 public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
4220 synchronized (mGlobalLock) {
4221 final long origId = Binder.clearCallingIdentity();
4222 try {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004223 mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004224 } finally {
4225 Binder.restoreCallingIdentity(origId);
4226 }
4227 }
4228 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004229
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004230 @Override
4231 public void setVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004232 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004233 synchronized (mGlobalLock) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004234 final int pid = Binder.getCallingPid();
4235 final WindowProcessController wpc = mPidMap.get(pid);
4236 mVrController.setVrThreadLocked(tid, pid, wpc);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004237 }
4238 }
4239
4240 @Override
4241 public void setPersistentVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004242 if (checkCallingPermission(Manifest.permission.RESTRICTED_VR_ACCESS)
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004243 != PERMISSION_GRANTED) {
4244 final String msg = "Permission Denial: setPersistentVrThread() from pid="
4245 + Binder.getCallingPid()
4246 + ", uid=" + Binder.getCallingUid()
4247 + " requires " + Manifest.permission.RESTRICTED_VR_ACCESS;
4248 Slog.w(TAG, msg);
4249 throw new SecurityException(msg);
4250 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004251 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004252 synchronized (mGlobalLock) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004253 final int pid = Binder.getCallingPid();
4254 final WindowProcessController proc = mPidMap.get(pid);
4255 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004256 }
4257 }
4258
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004259 @Override
4260 public void stopAppSwitches() {
4261 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
4262 synchronized (mGlobalLock) {
4263 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME;
4264 mDidAppSwitch = false;
4265 getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
4266 }
4267 }
4268
4269 @Override
4270 public void resumeAppSwitches() {
4271 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
4272 synchronized (mGlobalLock) {
4273 // Note that we don't execute any pending app switches... we will
4274 // let those wait until either the timeout, or the next start
4275 // activity request.
4276 mAppSwitchesAllowedTime = 0;
4277 }
4278 }
4279
4280 void onStartActivitySetDidAppSwitch() {
4281 if (mDidAppSwitch) {
4282 // This is the second allowed switch since we stopped switches, so now just generally
4283 // allow switches. Use case:
4284 // - user presses home (switches disabled, switch to home, mDidAppSwitch now true);
4285 // - user taps a home icon (coming from home so allowed, we hit here and now allow
4286 // anyone to switch again).
4287 mAppSwitchesAllowedTime = 0;
4288 } else {
4289 mDidAppSwitch = true;
4290 }
4291 }
4292
4293 /** @return whether the system should disable UI modes incompatible with VR mode. */
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004294 boolean shouldDisableNonVrUiLocked() {
4295 return mVrController.shouldDisableNonVrUiLocked();
4296 }
4297
Wale Ogunwale53783742018-09-16 10:21:51 -07004298 private void applyUpdateVrModeLocked(ActivityRecord r) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004299 // VR apps are expected to run in a main display. If an app is turning on VR for
4300 // itself, but lives in a dynamic stack, then make sure that it is moved to the main
4301 // fullscreen stack before enabling VR Mode.
4302 // TODO: The goal of this code is to keep the VR app on the main display. When the
4303 // stack implementation changes in the future, keep in mind that the use of the fullscreen
4304 // stack is a means to move the activity to the main display and a moveActivityToDisplay()
4305 // option would be a better choice here.
4306 if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
4307 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
4308 + " to main stack for VR");
4309 final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
4310 WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
4311 moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
4312 }
4313 mH.post(() -> {
4314 if (!mVrController.onVrModeChanged(r)) {
4315 return;
4316 }
4317 synchronized (mGlobalLock) {
4318 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
4319 mWindowManager.disableNonVrUi(disableNonVrUi);
4320 if (disableNonVrUi) {
4321 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
4322 // then remove the pinned stack.
4323 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
4324 }
4325 }
4326 });
4327 }
4328
Wale Ogunwale53783742018-09-16 10:21:51 -07004329 @Override
4330 public int getPackageScreenCompatMode(String packageName) {
4331 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4332 synchronized (mGlobalLock) {
4333 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4334 }
4335 }
4336
4337 @Override
4338 public void setPackageScreenCompatMode(String packageName, int mode) {
4339 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4340 "setPackageScreenCompatMode");
4341 synchronized (mGlobalLock) {
4342 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4343 }
4344 }
4345
4346 @Override
4347 public boolean getPackageAskScreenCompat(String packageName) {
4348 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4349 synchronized (mGlobalLock) {
4350 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4351 }
4352 }
4353
4354 @Override
4355 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4356 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4357 "setPackageAskScreenCompat");
4358 synchronized (mGlobalLock) {
4359 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4360 }
4361 }
4362
Wale Ogunwale64258362018-10-16 15:13:37 -07004363 public static String relaunchReasonToString(int relaunchReason) {
4364 switch (relaunchReason) {
4365 case RELAUNCH_REASON_WINDOWING_MODE_RESIZE:
4366 return "window_resize";
4367 case RELAUNCH_REASON_FREE_RESIZE:
4368 return "free_resize";
4369 default:
4370 return null;
4371 }
4372 }
4373
Andrii Kulian5f750bc2018-07-17 08:57:23 -07004374 ActivityStack getTopDisplayFocusedStack() {
4375 return mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004376 }
4377
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004378 /** Pokes the task persister. */
4379 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
4380 mRecentTasks.notifyTaskPersisterLocked(task, flush);
4381 }
4382
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004383 boolean isKeyguardLocked() {
4384 return mKeyguardController.isKeyguardLocked();
4385 }
4386
4387 boolean isNextTransitionForward() {
4388 int transit = mWindowManager.getPendingAppTransition();
4389 return transit == TRANSIT_ACTIVITY_OPEN
4390 || transit == TRANSIT_TASK_OPEN
4391 || transit == TRANSIT_TASK_TO_FRONT;
4392 }
4393
Wale Ogunwale31913b52018-10-13 08:29:31 -07004394 void dumpLastANRLocked(PrintWriter pw) {
4395 pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
4396 if (mLastANRState == null) {
4397 pw.println(" <no ANR has occurred since boot>");
4398 } else {
4399 pw.println(mLastANRState);
4400 }
4401 }
4402
4403 void dumpLastANRTracesLocked(PrintWriter pw) {
4404 pw.println("ACTIVITY MANAGER LAST ANR TRACES (dumpsys activity lastanr-traces)");
4405
4406 final File[] files = new File(ANR_TRACE_DIR).listFiles();
4407 if (ArrayUtils.isEmpty(files)) {
4408 pw.println(" <no ANR has occurred since boot>");
4409 return;
4410 }
4411 // Find the latest file.
4412 File latest = null;
4413 for (File f : files) {
4414 if ((latest == null) || (latest.lastModified() < f.lastModified())) {
4415 latest = f;
Wale Ogunwalef6733932018-06-27 05:14:34 -07004416 }
Wale Ogunwale31913b52018-10-13 08:29:31 -07004417 }
4418 pw.print("File: ");
4419 pw.print(latest.getName());
4420 pw.println();
4421 try (BufferedReader in = new BufferedReader(new FileReader(latest))) {
4422 String line;
4423 while ((line = in.readLine()) != null) {
4424 pw.println(line);
4425 }
4426 } catch (IOException e) {
4427 pw.print("Unable to read: ");
4428 pw.print(e);
4429 pw.println();
4430 }
4431 }
4432
4433 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
4434 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
4435 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
4436 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
4437 }
4438
4439 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
4440 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
4441 pw.println(header);
4442
4443 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
4444 dumpPackage);
4445 boolean needSep = printedAnything;
4446
4447 boolean printed = ActivityStackSupervisor.printThisActivity(pw,
4448 mStackSupervisor.getTopResumedActivity(), dumpPackage, needSep,
4449 " ResumedActivity: ");
4450 if (printed) {
4451 printedAnything = true;
4452 needSep = false;
4453 }
4454
4455 if (dumpPackage == null) {
4456 if (needSep) {
4457 pw.println();
4458 }
4459 printedAnything = true;
4460 mStackSupervisor.dump(pw, " ");
4461 }
4462
4463 if (!printedAnything) {
4464 pw.println(" (nothing)");
4465 }
4466 }
4467
4468 void dumpActivityContainersLocked(PrintWriter pw) {
4469 pw.println("ACTIVITY MANAGER STARTER (dumpsys activity containers)");
4470 mStackSupervisor.dumpChildrenNames(pw, " ");
4471 pw.println(" ");
4472 }
4473
4474 void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
4475 pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
4476 getActivityStartController().dump(pw, "", dumpPackage);
4477 }
4478
4479 /**
4480 * There are three things that cmd can be:
4481 * - a flattened component name that matches an existing activity
4482 * - the cmd arg isn't the flattened component name of an existing activity:
4483 * dump all activity whose component contains the cmd as a substring
4484 * - A hex number of the ActivityRecord object instance.
4485 *
4486 * @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
4487 * @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
4488 */
4489 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
4490 int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
4491 ArrayList<ActivityRecord> activities;
4492
4493 synchronized (mGlobalLock) {
4494 activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
4495 dumpFocusedStackOnly);
4496 }
4497
4498 if (activities.size() <= 0) {
4499 return false;
4500 }
4501
4502 String[] newArgs = new String[args.length - opti];
4503 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
4504
4505 TaskRecord lastTask = null;
4506 boolean needSep = false;
4507 for (int i = activities.size() - 1; i >= 0; i--) {
4508 ActivityRecord r = activities.get(i);
4509 if (needSep) {
4510 pw.println();
4511 }
4512 needSep = true;
4513 synchronized (mGlobalLock) {
4514 final TaskRecord task = r.getTask();
4515 if (lastTask != task) {
4516 lastTask = task;
4517 pw.print("TASK "); pw.print(lastTask.affinity);
4518 pw.print(" id="); pw.print(lastTask.taskId);
4519 pw.print(" userId="); pw.println(lastTask.userId);
4520 if (dumpAll) {
4521 lastTask.dump(pw, " ");
4522 }
4523 }
4524 }
4525 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
4526 }
4527 return true;
4528 }
4529
4530 /**
4531 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
4532 * there is a thread associated with the activity.
4533 */
4534 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
4535 final ActivityRecord r, String[] args, boolean dumpAll) {
4536 String innerPrefix = prefix + " ";
4537 synchronized (mGlobalLock) {
4538 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
4539 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
4540 pw.print(" pid=");
4541 if (r.hasProcess()) pw.println(r.app.getPid());
4542 else pw.println("(not running)");
4543 if (dumpAll) {
4544 r.dump(pw, innerPrefix);
4545 }
4546 }
4547 if (r.attachedToProcess()) {
4548 // flush anything that is already in the PrintWriter since the thread is going
4549 // to write to the file descriptor directly
4550 pw.flush();
4551 try {
4552 TransferPipe tp = new TransferPipe();
4553 try {
4554 r.app.getThread().dumpActivity(tp.getWriteFd(),
4555 r.appToken, innerPrefix, args);
4556 tp.go(fd);
4557 } finally {
4558 tp.kill();
4559 }
4560 } catch (IOException e) {
4561 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
4562 } catch (RemoteException e) {
4563 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
4564 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004565 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004566 }
4567
Wale Ogunwalef6733932018-06-27 05:14:34 -07004568 void writeSleepStateToProto(ProtoOutputStream proto) {
4569 for (ActivityTaskManagerInternal.SleepToken st : mStackSupervisor.mSleepTokens) {
4570 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS,
4571 st.toString());
4572 }
4573
4574 if (mRunningVoice != null) {
4575 final long vrToken = proto.start(
4576 ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
4577 proto.write(ActivityManagerServiceDumpProcessesProto.Voice.SESSION,
4578 mRunningVoice.toString());
4579 mVoiceWakeLock.writeToProto(
4580 proto, ActivityManagerServiceDumpProcessesProto.Voice.WAKELOCK);
4581 proto.end(vrToken);
4582 }
4583
4584 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
4585 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN,
4586 mShuttingDown);
4587 mVrController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004588 }
4589
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004590 int getCurrentUserId() {
4591 return mAmInternal.getCurrentUserId();
4592 }
4593
4594 private void enforceNotIsolatedCaller(String caller) {
4595 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4596 throw new SecurityException("Isolated process not allowed to call " + caller);
4597 }
4598 }
4599
Wale Ogunwalef6733932018-06-27 05:14:34 -07004600 public Configuration getConfiguration() {
4601 Configuration ci;
4602 synchronized(mGlobalLock) {
Yunfan Chen75157d72018-07-27 14:47:21 +09004603 ci = new Configuration(getGlobalConfigurationForCallingPid());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004604 ci.userSetLocale = false;
4605 }
4606 return ci;
4607 }
4608
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004609 /**
4610 * Current global configuration information. Contains general settings for the entire system,
4611 * also corresponds to the merged configuration of the default display.
4612 */
4613 Configuration getGlobalConfiguration() {
4614 return mStackSupervisor.getConfiguration();
4615 }
4616
4617 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4618 boolean initLocale) {
4619 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
4620 }
4621
4622 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4623 boolean initLocale, boolean deferResume) {
4624 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
4625 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
4626 UserHandle.USER_NULL, deferResume);
4627 }
4628
4629 void updatePersistentConfiguration(Configuration values, @UserIdInt int userId) {
4630 final long origId = Binder.clearCallingIdentity();
4631 try {
4632 synchronized (mGlobalLock) {
4633 updateConfigurationLocked(values, null, false, true, userId,
4634 false /* deferResume */);
4635 }
4636 } finally {
4637 Binder.restoreCallingIdentity(origId);
4638 }
4639 }
4640
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004641 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4642 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
4643 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
4644 deferResume, null /* result */);
4645 }
4646
4647 /**
4648 * Do either or both things: (1) change the current configuration, and (2)
4649 * make sure the given activity is running with the (now) current
4650 * configuration. Returns true if the activity has been left running, or
4651 * false if <var>starting</var> is being destroyed to match the new
4652 * configuration.
4653 *
4654 * @param userId is only used when persistent parameter is set to true to persist configuration
4655 * for that particular user
4656 */
4657 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4658 boolean initLocale, boolean persistent, int userId, boolean deferResume,
4659 ActivityTaskManagerService.UpdateConfigurationResult result) {
4660 int changes = 0;
4661 boolean kept = true;
4662
4663 if (mWindowManager != null) {
4664 mWindowManager.deferSurfaceLayout();
4665 }
4666 try {
4667 if (values != null) {
4668 changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
4669 deferResume);
4670 }
4671
4672 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4673 } finally {
4674 if (mWindowManager != null) {
4675 mWindowManager.continueSurfaceLayout();
4676 }
4677 }
4678
4679 if (result != null) {
4680 result.changes = changes;
4681 result.activityRelaunched = !kept;
4682 }
4683 return kept;
4684 }
4685
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004686 /** Update default (global) configuration and notify listeners about changes. */
4687 private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
4688 boolean persistent, int userId, boolean deferResume) {
4689 mTempConfig.setTo(getGlobalConfiguration());
4690 final int changes = mTempConfig.updateFrom(values);
4691 if (changes == 0) {
4692 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
4693 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
4694 // performDisplayOverrideConfigUpdate in order to send the new display configuration
4695 // (even if there are no actual changes) to unfreeze the window.
4696 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
4697 return 0;
4698 }
4699
4700 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
4701 "Updating global configuration to: " + values);
4702
4703 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
4704 StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
4705 values.colorMode,
4706 values.densityDpi,
4707 values.fontScale,
4708 values.hardKeyboardHidden,
4709 values.keyboard,
4710 values.keyboardHidden,
4711 values.mcc,
4712 values.mnc,
4713 values.navigation,
4714 values.navigationHidden,
4715 values.orientation,
4716 values.screenHeightDp,
4717 values.screenLayout,
4718 values.screenWidthDp,
4719 values.smallestScreenWidthDp,
4720 values.touchscreen,
4721 values.uiMode);
4722
4723
4724 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
4725 final LocaleList locales = values.getLocales();
4726 int bestLocaleIndex = 0;
4727 if (locales.size() > 1) {
4728 if (mSupportedSystemLocales == null) {
4729 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
4730 }
4731 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
4732 }
4733 SystemProperties.set("persist.sys.locale",
4734 locales.get(bestLocaleIndex).toLanguageTag());
4735 LocaleList.setDefault(locales, bestLocaleIndex);
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004736
4737 final Message m = PooledLambda.obtainMessage(
4738 ActivityTaskManagerService::sendLocaleToMountDaemonMsg, this,
4739 locales.get(bestLocaleIndex));
4740 mH.sendMessage(m);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004741 }
4742
Yunfan Chen75157d72018-07-27 14:47:21 +09004743 mTempConfig.seq = increaseConfigurationSeqLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004744
4745 // Update stored global config and notify everyone about the change.
4746 mStackSupervisor.onConfigurationChanged(mTempConfig);
4747
4748 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
4749 // TODO(multi-display): Update UsageEvents#Event to include displayId.
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004750 mUsageStatsInternal.reportConfigurationChange(mTempConfig, mAmInternal.getCurrentUserId());
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004751
4752 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
Wale Ogunwalef6733932018-06-27 05:14:34 -07004753 updateShouldShowDialogsLocked(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004754
4755 AttributeCache ac = AttributeCache.instance();
4756 if (ac != null) {
4757 ac.updateConfiguration(mTempConfig);
4758 }
4759
4760 // Make sure all resources in our process are updated right now, so that anyone who is going
4761 // to retrieve resource values after we return will be sure to get the new ones. This is
4762 // especially important during boot, where the first config change needs to guarantee all
4763 // resources have that config before following boot code is executed.
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004764 mSystemThread.applyConfigurationToResources(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004765
4766 // We need another copy of global config because we're scheduling some calls instead of
4767 // running them in place. We need to be sure that object we send will be handled unchanged.
4768 final Configuration configCopy = new Configuration(mTempConfig);
4769 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004770 final Message msg = PooledLambda.obtainMessage(
4771 ActivityTaskManagerService::sendPutConfigurationForUserMsg,
4772 this, userId, configCopy);
4773 mH.sendMessage(msg);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004774 }
4775
Yunfan Chen34fcc7a2018-10-11 16:26:09 -07004776 for (int i = mPidMap.size() - 1; i >= 0; i--) {
Yunfan Chen79b96062018-10-17 12:45:23 -07004777 final int pid = mPidMap.keyAt(i);
4778 final WindowProcessController app = mPidMap.get(pid);
Yunfan Chen34fcc7a2018-10-11 16:26:09 -07004779 if (DEBUG_CONFIGURATION) {
4780 Slog.v(TAG_CONFIGURATION, "Update process config of "
4781 + app.mName + " to new config " + configCopy);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004782 }
Yunfan Chen34fcc7a2018-10-11 16:26:09 -07004783 app.onConfigurationChanged(configCopy);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004784 }
4785
Wale Ogunwale2ea36d42018-10-18 10:27:31 -07004786 final Message msg = PooledLambda.obtainMessage(
4787 ActivityManagerInternal::broadcastGlobalConfigurationChanged,
4788 mAmInternal, changes, initLocale);
4789 mH.sendMessage(msg);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004790
4791 // Override configuration of the default display duplicates global config, so we need to
4792 // update it also. This will also notify WindowManager about changes.
4793 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
4794 DEFAULT_DISPLAY);
4795
4796 return changes;
4797 }
4798
4799 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
4800 boolean deferResume, int displayId) {
4801 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
4802 displayId, null /* result */);
4803 }
4804
4805 /**
4806 * Updates override configuration specific for the selected display. If no config is provided,
4807 * new one will be computed in WM based on current display info.
4808 */
4809 boolean updateDisplayOverrideConfigurationLocked(Configuration values,
4810 ActivityRecord starting, boolean deferResume, int displayId,
4811 ActivityTaskManagerService.UpdateConfigurationResult result) {
4812 int changes = 0;
4813 boolean kept = true;
4814
4815 if (mWindowManager != null) {
4816 mWindowManager.deferSurfaceLayout();
4817 }
4818 try {
4819 if (values != null) {
4820 if (displayId == DEFAULT_DISPLAY) {
4821 // Override configuration of the default display duplicates global config, so
4822 // we're calling global config update instead for default display. It will also
4823 // apply the correct override config.
4824 changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
4825 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
4826 } else {
4827 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
4828 }
4829 }
4830
4831 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4832 } finally {
4833 if (mWindowManager != null) {
4834 mWindowManager.continueSurfaceLayout();
4835 }
4836 }
4837
4838 if (result != null) {
4839 result.changes = changes;
4840 result.activityRelaunched = !kept;
4841 }
4842 return kept;
4843 }
4844
4845 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
4846 int displayId) {
4847 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
4848 final int changes = mTempConfig.updateFrom(values);
4849 if (changes != 0) {
4850 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
4851 + mTempConfig + " for displayId=" + displayId);
4852 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
4853
4854 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
4855 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004856 mAppWarnings.onDensityChanged();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004857
Wale Ogunwale5c918702018-10-18 11:06:33 -07004858 // Post message to start process to avoid possible deadlock of calling into AMS with
4859 // the ATMS lock held.
4860 final Message msg = PooledLambda.obtainMessage(
4861 ActivityManagerInternal::killAllBackgroundProcessesExcept, mAmInternal,
4862 N, ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
4863 mH.sendMessage(msg);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004864 }
4865 }
4866
4867 // Update the configuration with WM first and check if any of the stacks need to be resized
4868 // due to the configuration change. If so, resize the stacks now and do any relaunches if
4869 // necessary. This way we don't need to relaunch again afterwards in
4870 // ensureActivityConfiguration().
4871 if (mWindowManager != null) {
4872 final int[] resizedStacks =
4873 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
4874 if (resizedStacks != null) {
4875 for (int stackId : resizedStacks) {
4876 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
4877 }
4878 }
4879 }
4880
4881 return changes;
4882 }
4883
Wale Ogunwalef6733932018-06-27 05:14:34 -07004884 private void updateEventDispatchingLocked(boolean booted) {
4885 mWindowManager.setEventDispatching(booted && !mShuttingDown);
4886 }
4887
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004888 private void sendPutConfigurationForUserMsg(int userId, Configuration config) {
4889 final ContentResolver resolver = mContext.getContentResolver();
4890 Settings.System.putConfigurationForUser(resolver, config, userId);
4891 }
4892
4893 private void sendLocaleToMountDaemonMsg(Locale l) {
4894 try {
4895 IBinder service = ServiceManager.getService("mount");
4896 IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
4897 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
4898 storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
4899 } catch (RemoteException e) {
4900 Log.e(TAG, "Error storing locale for decryption UI", e);
4901 }
4902 }
4903
4904 boolean isActivityStartsLoggingEnabled() {
4905 return mAmInternal.isActivityStartsLoggingEnabled();
4906 }
4907
Wale Ogunwalef6733932018-06-27 05:14:34 -07004908 void enableScreenAfterBoot(boolean booted) {
4909 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4910 SystemClock.uptimeMillis());
4911 mWindowManager.enableScreenAfterBoot();
4912
4913 synchronized (mGlobalLock) {
4914 updateEventDispatchingLocked(booted);
4915 }
4916 }
4917
Wale Ogunwale906f9c62018-07-23 11:23:44 -07004918 static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
4919 if (r == null || !r.hasProcess()) {
4920 return KEY_DISPATCHING_TIMEOUT_MS;
4921 }
4922 return getInputDispatchingTimeoutLocked(r.app);
4923 }
4924
4925 private static long getInputDispatchingTimeoutLocked(WindowProcessController r) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07004926 return r != null ? r.getInputDispatchingTimeout() : KEY_DISPATCHING_TIMEOUT_MS;
Wale Ogunwale906f9c62018-07-23 11:23:44 -07004927 }
4928
Wale Ogunwalef6733932018-06-27 05:14:34 -07004929 /**
4930 * Decide based on the configuration whether we should show the ANR,
4931 * crash, etc dialogs. The idea is that if there is no affordance to
4932 * press the on-screen buttons, or the user experience would be more
4933 * greatly impacted than the crash itself, we shouldn't show the dialog.
4934 *
4935 * A thought: SystemUI might also want to get told about this, the Power
4936 * dialog / global actions also might want different behaviors.
4937 */
4938 private void updateShouldShowDialogsLocked(Configuration config) {
4939 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
4940 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
4941 && config.navigation == Configuration.NAVIGATION_NONAV);
4942 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
4943 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
4944 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
4945 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
4946 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
4947 final boolean hideDialogsSet = Settings.Global.getInt(mContext.getContentResolver(),
4948 HIDE_ERROR_DIALOGS, 0) != 0;
4949 mShowDialogs = inputMethodExists && uiModeSupportsDialogs && !hideDialogsSet;
4950 }
4951
4952 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
4953 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
4954 FONT_SCALE, 1.0f, userId);
4955
4956 synchronized (this) {
4957 if (getGlobalConfiguration().fontScale == scaleFactor) {
4958 return;
4959 }
4960
4961 final Configuration configuration
4962 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
4963 configuration.fontScale = scaleFactor;
4964 updatePersistentConfiguration(configuration, userId);
4965 }
4966 }
4967
4968 // Actually is sleeping or shutting down or whatever else in the future
4969 // is an inactive state.
4970 boolean isSleepingOrShuttingDownLocked() {
4971 return isSleepingLocked() || mShuttingDown;
4972 }
4973
4974 boolean isSleepingLocked() {
4975 return mSleeping;
4976 }
4977
Riddle Hsu16567132018-08-16 21:37:47 +08004978 /** Update AMS states when an activity is resumed. */
Wale Ogunwalef6733932018-06-27 05:14:34 -07004979 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
4980 final TaskRecord task = r.getTask();
4981 if (task.isActivityTypeStandard()) {
4982 if (mCurAppTimeTracker != r.appTimeTracker) {
4983 // We are switching app tracking. Complete the current one.
4984 if (mCurAppTimeTracker != null) {
4985 mCurAppTimeTracker.stop();
4986 mH.obtainMessage(
4987 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
4988 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
4989 mCurAppTimeTracker = null;
4990 }
4991 if (r.appTimeTracker != null) {
4992 mCurAppTimeTracker = r.appTimeTracker;
4993 startTimeTrackingFocusedActivityLocked();
4994 }
4995 } else {
4996 startTimeTrackingFocusedActivityLocked();
4997 }
4998 } else {
4999 r.appTimeTracker = null;
5000 }
5001 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
5002 // TODO: Probably not, because we don't want to resume voice on switching
5003 // back to this activity
5004 if (task.voiceInteractor != null) {
5005 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
5006 } else {
5007 finishRunningVoiceLocked();
5008
5009 if (mLastResumedActivity != null) {
5010 final IVoiceInteractionSession session;
5011
5012 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
5013 if (lastResumedActivityTask != null
5014 && lastResumedActivityTask.voiceSession != null) {
5015 session = lastResumedActivityTask.voiceSession;
5016 } else {
5017 session = mLastResumedActivity.voiceSession;
5018 }
5019
5020 if (session != null) {
5021 // We had been in a voice interaction session, but now focused has
5022 // move to something different. Just finish the session, we can't
5023 // return to it and retain the proper state and synchronization with
5024 // the voice interaction service.
5025 finishVoiceTask(session);
5026 }
5027 }
5028 }
5029
5030 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
5031 mAmInternal.sendForegroundProfileChanged(r.userId);
5032 }
5033 updateResumedAppTrace(r);
5034 mLastResumedActivity = r;
5035
Tiger Huang1e5b10a2018-07-30 20:19:51 +08005036 r.getDisplay().setFocusedApp(r, true);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005037
5038 applyUpdateLockStateLocked(r);
5039 applyUpdateVrModeLocked(r);
5040
5041 EventLogTags.writeAmSetResumedActivity(
5042 r == null ? -1 : r.userId,
5043 r == null ? "NULL" : r.shortComponentName,
5044 reason);
5045 }
5046
5047 ActivityTaskManagerInternal.SleepToken acquireSleepToken(String tag, int displayId) {
5048 synchronized (mGlobalLock) {
5049 final ActivityTaskManagerInternal.SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
5050 updateSleepIfNeededLocked();
5051 return token;
5052 }
5053 }
5054
5055 void updateSleepIfNeededLocked() {
5056 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
5057 final boolean wasSleeping = mSleeping;
5058 boolean updateOomAdj = false;
5059
5060 if (!shouldSleep) {
5061 // If wasSleeping is true, we need to wake up activity manager state from when
5062 // we started sleeping. In either case, we need to apply the sleep tokens, which
5063 // will wake up stacks or put them to sleep as appropriate.
5064 if (wasSleeping) {
5065 mSleeping = false;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07005066 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
5067 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__AWAKE);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005068 startTimeTrackingFocusedActivityLocked();
5069 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
5070 mStackSupervisor.comeOutOfSleepIfNeededLocked();
5071 }
5072 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
5073 if (wasSleeping) {
5074 updateOomAdj = true;
5075 }
5076 } else if (!mSleeping && shouldSleep) {
5077 mSleeping = true;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07005078 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
5079 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__ASLEEP);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005080 if (mCurAppTimeTracker != null) {
5081 mCurAppTimeTracker.stop();
5082 }
5083 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
5084 mStackSupervisor.goingToSleepLocked();
5085 updateResumedAppTrace(null /* resumed */);
5086 updateOomAdj = true;
5087 }
5088 if (updateOomAdj) {
5089 mH.post(mAmInternal::updateOomAdj);
5090 }
5091 }
5092
5093 void updateOomAdj() {
5094 mH.post(mAmInternal::updateOomAdj);
5095 }
5096
Wale Ogunwale53783742018-09-16 10:21:51 -07005097 void updateCpuStats() {
5098 mH.post(mAmInternal::updateCpuStats);
5099 }
5100
5101 void updateUsageStats(ActivityRecord component, boolean resumed) {
5102 final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::updateUsageStats,
5103 mAmInternal, component.realActivity, component.app.mUid, component.userId, resumed);
5104 mH.sendMessage(m);
5105 }
5106
5107 void setBooting(boolean booting) {
5108 mAmInternal.setBooting(booting);
5109 }
5110
5111 boolean isBooting() {
5112 return mAmInternal.isBooting();
5113 }
5114
5115 void setBooted(boolean booted) {
5116 mAmInternal.setBooted(booted);
5117 }
5118
5119 boolean isBooted() {
5120 return mAmInternal.isBooted();
5121 }
5122
5123 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
5124 mH.post(() -> {
5125 if (finishBooting) {
5126 mAmInternal.finishBooting();
5127 }
5128 if (enableScreen) {
5129 mInternal.enableScreenAfterBoot(isBooted());
5130 }
5131 });
5132 }
5133
5134 void setHeavyWeightProcess(ActivityRecord root) {
5135 mHeavyWeightProcess = root.app;
5136 final Message m = PooledLambda.obtainMessage(
5137 ActivityTaskManagerService::postHeavyWeightProcessNotification, this,
5138 root.app, root.intent, root.userId);
5139 mH.sendMessage(m);
5140 }
5141
5142 void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
5143 if (mHeavyWeightProcess == null || mHeavyWeightProcess != proc) {
5144 return;
5145 }
5146
5147 mHeavyWeightProcess = null;
5148 final Message m = PooledLambda.obtainMessage(
5149 ActivityTaskManagerService::cancelHeavyWeightProcessNotification, this,
5150 proc.mUserId);
5151 mH.sendMessage(m);
5152 }
5153
5154 private void cancelHeavyWeightProcessNotification(int userId) {
5155 final INotificationManager inm = NotificationManager.getService();
5156 if (inm == null) {
5157 return;
5158 }
5159 try {
5160 inm.cancelNotificationWithTag("android", null,
5161 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, userId);
5162 } catch (RuntimeException e) {
5163 Slog.w(TAG, "Error canceling notification for service", e);
5164 } catch (RemoteException e) {
5165 }
5166
5167 }
5168
5169 private void postHeavyWeightProcessNotification(
5170 WindowProcessController proc, Intent intent, int userId) {
5171 if (proc == null) {
5172 return;
5173 }
5174
5175 final INotificationManager inm = NotificationManager.getService();
5176 if (inm == null) {
5177 return;
5178 }
5179
5180 try {
5181 Context context = mContext.createPackageContext(proc.mInfo.packageName, 0);
5182 String text = mContext.getString(R.string.heavy_weight_notification,
5183 context.getApplicationInfo().loadLabel(context.getPackageManager()));
5184 Notification notification =
5185 new Notification.Builder(context,
5186 SystemNotificationChannels.HEAVY_WEIGHT_APP)
5187 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
5188 .setWhen(0)
5189 .setOngoing(true)
5190 .setTicker(text)
5191 .setColor(mContext.getColor(
5192 com.android.internal.R.color.system_notification_accent_color))
5193 .setContentTitle(text)
5194 .setContentText(
5195 mContext.getText(R.string.heavy_weight_notification_detail))
5196 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
5197 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
5198 new UserHandle(userId)))
5199 .build();
5200 try {
5201 inm.enqueueNotificationWithTag("android", "android", null,
5202 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, notification, userId);
5203 } catch (RuntimeException e) {
5204 Slog.w(TAG, "Error showing notification for heavy-weight app", e);
5205 } catch (RemoteException e) {
5206 }
5207 } catch (PackageManager.NameNotFoundException e) {
5208 Slog.w(TAG, "Unable to create context for heavy notification", e);
5209 }
5210
5211 }
5212
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07005213 IIntentSender getIntentSenderLocked(int type, String packageName, int callingUid, int userId,
5214 IBinder token, String resultWho, int requestCode, Intent[] intents,
5215 String[] resolvedTypes, int flags, Bundle bOptions) {
5216
5217 ActivityRecord activity = null;
5218 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5219 activity = ActivityRecord.isInStackLocked(token);
5220 if (activity == null) {
5221 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
5222 return null;
5223 }
5224 if (activity.finishing) {
5225 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
5226 return null;
5227 }
5228 }
5229
5230 final PendingIntentRecord rec = mPendingIntentController.getIntentSender(type, packageName,
5231 callingUid, userId, token, resultWho, requestCode, intents, resolvedTypes, flags,
5232 bOptions);
5233 final boolean noCreate = (flags & PendingIntent.FLAG_NO_CREATE) != 0;
5234 if (noCreate) {
5235 return rec;
5236 }
5237 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5238 if (activity.pendingResults == null) {
5239 activity.pendingResults = new HashSet<>();
5240 }
5241 activity.pendingResults.add(rec.ref);
5242 }
5243 return rec;
5244 }
5245
Andrii Kulian52d255c2018-07-13 11:32:19 -07005246 // TODO(b/111541062): Update app time tracking to make it aware of multiple resumed activities
Wale Ogunwalef6733932018-06-27 05:14:34 -07005247 private void startTimeTrackingFocusedActivityLocked() {
Andrii Kulian52d255c2018-07-13 11:32:19 -07005248 final ActivityRecord resumedActivity = mStackSupervisor.getTopResumedActivity();
Wale Ogunwalef6733932018-06-27 05:14:34 -07005249 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
5250 mCurAppTimeTracker.start(resumedActivity.packageName);
5251 }
5252 }
5253
5254 private void updateResumedAppTrace(@Nullable ActivityRecord resumed) {
5255 if (mTracedResumedActivity != null) {
5256 Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER,
5257 constructResumedTraceName(mTracedResumedActivity.packageName), 0);
5258 }
5259 if (resumed != null) {
5260 Trace.asyncTraceBegin(TRACE_TAG_ACTIVITY_MANAGER,
5261 constructResumedTraceName(resumed.packageName), 0);
5262 }
5263 mTracedResumedActivity = resumed;
5264 }
5265
5266 private String constructResumedTraceName(String packageName) {
5267 return "focused app: " + packageName;
5268 }
5269
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005270 /** Helper method that requests bounds from WM and applies them to stack. */
5271 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
5272 final Rect newStackBounds = new Rect();
5273 final ActivityStack stack = mStackSupervisor.getStack(stackId);
5274
5275 // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
5276 if (stack == null) {
5277 final StringWriter writer = new StringWriter();
5278 final PrintWriter printWriter = new PrintWriter(writer);
5279 mStackSupervisor.dumpDisplays(printWriter);
5280 printWriter.flush();
5281
5282 Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
5283 }
5284
5285 stack.getBoundsForNewConfiguration(newStackBounds);
5286 mStackSupervisor.resizeStackLocked(
5287 stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
5288 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
5289 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
5290 }
5291
5292 /** Applies latest configuration and/or visibility updates if needed. */
5293 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
5294 boolean kept = true;
Andrii Kulian5f750bc2018-07-17 08:57:23 -07005295 final ActivityStack mainStack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005296 // mainStack is null during startup.
5297 if (mainStack != null) {
5298 if (changes != 0 && starting == null) {
5299 // If the configuration changed, and the caller is not already
5300 // in the process of starting an activity, then find the top
5301 // activity to check if its configuration needs to change.
5302 starting = mainStack.topRunningActivityLocked();
5303 }
5304
5305 if (starting != null) {
5306 kept = starting.ensureActivityConfiguration(changes,
5307 false /* preserveWindow */);
5308 // And we need to make sure at this point that all other activities
5309 // are made visible with the correct configuration.
5310 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
5311 !PRESERVE_WINDOWS);
5312 }
5313 }
5314
5315 return kept;
5316 }
5317
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005318 void scheduleAppGcsLocked() {
5319 mH.post(() -> mAmInternal.scheduleAppGcs());
5320 }
5321
Wale Ogunwale53783742018-09-16 10:21:51 -07005322 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
5323 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
5324 }
5325
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005326 /**
5327 * Returns the PackageManager. Used by classes hosted by {@link ActivityTaskManagerService}. The
5328 * PackageManager could be unavailable at construction time and therefore needs to be accessed
5329 * on demand.
5330 */
5331 IPackageManager getPackageManager() {
5332 return AppGlobals.getPackageManager();
5333 }
5334
5335 PackageManagerInternal getPackageManagerInternalLocked() {
5336 if (mPmInternal == null) {
5337 mPmInternal = LocalServices.getService(PackageManagerInternal.class);
5338 }
5339 return mPmInternal;
5340 }
5341
Wale Ogunwale008163e2018-07-23 23:11:08 -07005342 AppWarnings getAppWarningsLocked() {
5343 return mAppWarnings;
5344 }
5345
Wale Ogunwale214f3482018-10-04 11:00:47 -07005346 Intent getHomeIntent() {
5347 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
5348 intent.setComponent(mTopComponent);
5349 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
5350 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5351 intent.addCategory(Intent.CATEGORY_HOME);
5352 }
5353 return intent;
5354 }
5355
5356 /**
5357 * This starts home activity on displays that can have system decorations and only if the
5358 * home activity can have multiple instances.
5359 */
5360 boolean startHomeActivityLocked(int userId, String reason, int displayId) {
5361 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL && mTopAction == null) {
5362 // We are running in factory test mode, but unable to find the factory test app, so just
5363 // sit around displaying the error message and don't try to start anything.
5364 return false;
5365 }
5366
5367 final Intent intent = getHomeIntent();
5368 ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
5369 if (aInfo != null) {
5370 intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
5371 // Don't do this if the home app is currently being instrumented.
5372 aInfo = new ActivityInfo(aInfo);
5373 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
5374 WindowProcessController app =
5375 getProcessController(aInfo.processName, aInfo.applicationInfo.uid);
5376 if (app == null || !app.isInstrumenting()) {
5377 intent.setFlags(intent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
5378 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
5379 // For ANR debugging to verify if the user activity is the one that actually
5380 // launched.
5381 final String myReason = reason + ":" + userId + ":" + resolvedUserId;
5382 getActivityStartController().startHomeActivity(intent, aInfo, myReason, displayId);
5383 }
5384 } else {
5385 Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
5386 }
5387
5388 return true;
5389 }
5390
5391 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
5392 ActivityInfo ai = null;
5393 final ComponentName comp = intent.getComponent();
5394 try {
5395 if (comp != null) {
5396 // Factory test.
5397 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
5398 } else {
5399 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
5400 intent,
5401 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
5402 flags, userId);
5403
5404 if (info != null) {
5405 ai = info.activityInfo;
5406 }
5407 }
5408 } catch (RemoteException e) {
5409 // ignore
5410 }
5411
5412 return ai;
5413 }
5414
5415 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
5416 if (info == null) return null;
5417 ApplicationInfo newInfo = new ApplicationInfo(info);
5418 newInfo.initForUser(userId);
5419 return newInfo;
5420 }
5421
Wale Ogunwale9c103022018-10-18 07:44:54 -07005422 WindowProcessController getProcessController(String processName, int uid) {
Wale Ogunwale214f3482018-10-04 11:00:47 -07005423 if (uid == SYSTEM_UID) {
5424 // The system gets to run in any process. If there are multiple processes with the same
5425 // uid, just pick the first (this should never happen).
5426 final SparseArray<WindowProcessController> procs =
5427 mProcessNames.getMap().get(processName);
5428 if (procs == null) return null;
5429 final int procCount = procs.size();
5430 for (int i = 0; i < procCount; i++) {
5431 final int procUid = procs.keyAt(i);
5432 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
5433 // Don't use an app process or different user process for system component.
5434 continue;
5435 }
5436 return procs.valueAt(i);
5437 }
5438 }
5439
5440 return mProcessNames.get(processName, uid);
5441 }
5442
Wale Ogunwale342fbe92018-10-09 08:44:10 -07005443 WindowProcessController getProcessController(IApplicationThread thread) {
5444 if (thread == null) {
5445 return null;
5446 }
5447
5448 final IBinder threadBinder = thread.asBinder();
5449 final ArrayMap<String, SparseArray<WindowProcessController>> pmap = mProcessNames.getMap();
5450 for (int i = pmap.size()-1; i >= 0; i--) {
5451 final SparseArray<WindowProcessController> procs = pmap.valueAt(i);
5452 for (int j = procs.size() - 1; j >= 0; j--) {
5453 final WindowProcessController proc = procs.valueAt(j);
5454 if (proc.hasThread() && proc.getThread().asBinder() == threadBinder) {
5455 return proc;
5456 }
5457 }
5458 }
5459
5460 return null;
5461 }
5462
Wale Ogunwalebff2df42018-10-18 17:09:19 -07005463 int getUidStateLocked(int uid) {
5464 return mActiveUids.get(uid, PROCESS_STATE_NONEXISTENT);
5465 }
5466
Wale Ogunwale9de19442018-10-18 19:05:03 -07005467 /**
5468 * @return whitelist tag for a uid from mPendingTempWhitelist, null if not currently on
5469 * the whitelist
5470 */
5471 String getPendingTempWhitelistTagForUidLocked(int uid) {
5472 return mPendingTempWhitelist.get(uid);
5473 }
5474
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005475 void logAppTooSlow(WindowProcessController app, long startTime, String msg) {
5476 if (true || Build.IS_USER) {
5477 return;
5478 }
5479
5480 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5481 StrictMode.allowThreadDiskWrites();
5482 try {
5483 File tracesDir = new File("/data/anr");
5484 File tracesFile = null;
5485 try {
5486 tracesFile = File.createTempFile("app_slow", null, tracesDir);
5487
5488 StringBuilder sb = new StringBuilder();
5489 Time tobj = new Time();
5490 tobj.set(System.currentTimeMillis());
5491 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5492 sb.append(": ");
5493 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5494 sb.append(" since ");
5495 sb.append(msg);
5496 FileOutputStream fos = new FileOutputStream(tracesFile);
5497 fos.write(sb.toString().getBytes());
5498 if (app == null) {
5499 fos.write("\n*** No application process!".getBytes());
5500 }
5501 fos.close();
5502 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5503 } catch (IOException e) {
5504 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesFile, e);
5505 return;
5506 }
5507
5508 if (app != null && app.getPid() > 0) {
5509 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5510 firstPids.add(app.getPid());
5511 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, null, null);
5512 }
5513
5514 File lastTracesFile = null;
5515 File curTracesFile = null;
5516 for (int i=9; i>=0; i--) {
5517 String name = String.format(Locale.US, "slow%02d.txt", i);
5518 curTracesFile = new File(tracesDir, name);
5519 if (curTracesFile.exists()) {
5520 if (lastTracesFile != null) {
5521 curTracesFile.renameTo(lastTracesFile);
5522 } else {
5523 curTracesFile.delete();
5524 }
5525 }
5526 lastTracesFile = curTracesFile;
5527 }
5528 tracesFile.renameTo(curTracesFile);
5529 } finally {
5530 StrictMode.setThreadPolicy(oldPolicy);
5531 }
5532 }
5533
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005534 final class H extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005535 static final int REPORT_TIME_TRACKER_MSG = 1;
Wale Ogunwale98875612018-10-12 07:53:02 -07005536 static final int FIRST_ACTIVITY_STACK_MSG = 100;
5537 static final int FIRST_SUPERVISOR_STACK_MSG = 200;
Wale Ogunwalef6733932018-06-27 05:14:34 -07005538
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005539 public H(Looper looper) {
5540 super(looper, null, true);
5541 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005542
5543 @Override
5544 public void handleMessage(Message msg) {
5545 switch (msg.what) {
5546 case REPORT_TIME_TRACKER_MSG: {
5547 AppTimeTracker tracker = (AppTimeTracker) msg.obj;
5548 tracker.deliverResult(mContext);
5549 } break;
5550 }
5551 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005552 }
5553
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005554 final class UiHandler extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005555 static final int DISMISS_DIALOG_UI_MSG = 1;
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005556
5557 public UiHandler() {
5558 super(com.android.server.UiThread.get().getLooper(), null, true);
5559 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005560
5561 @Override
5562 public void handleMessage(Message msg) {
5563 switch (msg.what) {
5564 case DISMISS_DIALOG_UI_MSG: {
5565 final Dialog d = (Dialog) msg.obj;
5566 d.dismiss();
5567 break;
5568 }
5569 }
5570 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005571 }
5572
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005573 final class LocalService extends ActivityTaskManagerInternal {
5574 @Override
5575 public SleepToken acquireSleepToken(String tag, int displayId) {
5576 Preconditions.checkNotNull(tag);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005577 return ActivityTaskManagerService.this.acquireSleepToken(tag, displayId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005578 }
5579
5580 @Override
5581 public ComponentName getHomeActivityForUser(int userId) {
5582 synchronized (mGlobalLock) {
Louis Changbd48dca2018-08-29 17:44:34 +08005583 ActivityRecord homeActivity =
5584 mStackSupervisor.getDefaultDisplayHomeActivityForUser(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005585 return homeActivity == null ? null : homeActivity.realActivity;
5586 }
5587 }
5588
5589 @Override
5590 public void onLocalVoiceInteractionStarted(IBinder activity,
5591 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
5592 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005593 onLocalVoiceInteractionStartedLocked(activity, voiceSession, voiceInteractor);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005594 }
5595 }
5596
5597 @Override
5598 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
5599 synchronized (mGlobalLock) {
5600 mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
5601 reasons, timestamp);
5602 }
5603 }
5604
5605 @Override
5606 public void notifyAppTransitionFinished() {
5607 synchronized (mGlobalLock) {
5608 mStackSupervisor.notifyAppTransitionDone();
5609 }
5610 }
5611
5612 @Override
5613 public void notifyAppTransitionCancelled() {
5614 synchronized (mGlobalLock) {
5615 mStackSupervisor.notifyAppTransitionDone();
5616 }
5617 }
5618
5619 @Override
5620 public List<IBinder> getTopVisibleActivities() {
5621 synchronized (mGlobalLock) {
5622 return mStackSupervisor.getTopVisibleActivities();
5623 }
5624 }
5625
5626 @Override
5627 public void notifyDockedStackMinimizedChanged(boolean minimized) {
5628 synchronized (mGlobalLock) {
5629 mStackSupervisor.setDockedStackMinimized(minimized);
5630 }
5631 }
5632
5633 @Override
5634 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
5635 Bundle bOptions) {
5636 Preconditions.checkNotNull(intents, "intents");
5637 final String[] resolvedTypes = new String[intents.length];
5638
5639 // UID of the package on user userId.
5640 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
5641 // packageUid may not be initialized.
5642 int packageUid = 0;
5643 final long ident = Binder.clearCallingIdentity();
5644
5645 try {
5646 for (int i = 0; i < intents.length; i++) {
5647 resolvedTypes[i] =
5648 intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
5649 }
5650
5651 packageUid = AppGlobals.getPackageManager().getPackageUid(
5652 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
5653 } catch (RemoteException e) {
5654 // Shouldn't happen.
5655 } finally {
5656 Binder.restoreCallingIdentity(ident);
5657 }
5658
5659 synchronized (mGlobalLock) {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07005660 return getActivityStartController().startActivitiesInPackage(
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005661 packageUid, packageName,
5662 intents, resolvedTypes, null /* resultTo */,
5663 SafeActivityOptions.fromBundle(bOptions), userId,
Michal Karpinski201bc0c2018-07-20 15:32:00 +01005664 false /* validateIncomingUser */, null /* originatingPendingIntent */);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005665 }
5666 }
5667
5668 @Override
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07005669 public int startActivitiesInPackage(int uid, String callingPackage, Intent[] intents,
5670 String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, int userId,
5671 boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent) {
5672 synchronized (mGlobalLock) {
5673 return getActivityStartController().startActivitiesInPackage(uid, callingPackage,
5674 intents, resolvedTypes, resultTo, options, userId, validateIncomingUser,
5675 originatingPendingIntent);
5676 }
5677 }
5678
5679 @Override
5680 public int startActivityInPackage(int uid, int realCallingPid, int realCallingUid,
5681 String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
5682 String resultWho, int requestCode, int startFlags, SafeActivityOptions options,
5683 int userId, TaskRecord inTask, String reason, boolean validateIncomingUser,
5684 PendingIntentRecord originatingPendingIntent) {
5685 synchronized (mGlobalLock) {
5686 return getActivityStartController().startActivityInPackage(uid, realCallingPid,
5687 realCallingUid, callingPackage, intent, resolvedType, resultTo, resultWho,
5688 requestCode, startFlags, options, userId, inTask, reason,
5689 validateIncomingUser, originatingPendingIntent);
5690 }
5691 }
5692
5693 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005694 public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
5695 Intent intent, Bundle options, int userId) {
5696 return ActivityTaskManagerService.this.startActivityAsUser(
5697 caller, callerPacakge, intent,
5698 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
5699 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
5700 false /*validateIncomingUser*/);
5701 }
5702
5703 @Override
5704 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
5705 synchronized (mGlobalLock) {
5706
5707 // We might change the visibilities here, so prepare an empty app transition which
5708 // might be overridden later if we actually change visibilities.
5709 final boolean wasTransitionSet =
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005710 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005711 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005712 mWindowManager.prepareAppTransition(TRANSIT_NONE,
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005713 false /* alwaysKeepCurrent */);
5714 }
5715 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5716
5717 // If there was a transition set already we don't want to interfere with it as we
5718 // might be starting it too early.
5719 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005720 mWindowManager.executeAppTransition();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005721 }
5722 }
5723 if (callback != null) {
5724 callback.run();
5725 }
5726 }
5727
5728 @Override
5729 public void notifyKeyguardTrustedChanged() {
5730 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005731 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005732 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5733 }
5734 }
5735 }
5736
5737 /**
5738 * Called after virtual display Id is updated by
5739 * {@link com.android.server.vr.Vr2dDisplay} with a specific
5740 * {@param vrVr2dDisplayId}.
5741 */
5742 @Override
5743 public void setVr2dDisplayId(int vr2dDisplayId) {
5744 if (DEBUG_STACK) Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
5745 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005746 mVr2dDisplayId = vr2dDisplayId;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005747 }
5748 }
5749
5750 @Override
5751 public void setFocusedActivity(IBinder token) {
5752 synchronized (mGlobalLock) {
5753 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
5754 if (r == null) {
5755 throw new IllegalArgumentException(
5756 "setFocusedActivity: No activity record matching token=" + token);
5757 }
Louis Chang19443452018-10-09 12:10:21 +08005758 if (r.moveFocusableActivityToTop("setFocusedActivity")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08005759 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005760 }
5761 }
5762 }
5763
5764 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005765 public void registerScreenObserver(ScreenObserver observer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005766 mScreenObservers.add(observer);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005767 }
5768
5769 @Override
5770 public boolean isCallerRecents(int callingUid) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005771 return getRecentTasks().isCallerRecents(callingUid);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005772 }
5773
5774 @Override
5775 public boolean isRecentsComponentHomeActivity(int userId) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005776 return getRecentTasks().isRecentsComponentHomeActivity(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005777 }
5778
5779 @Override
5780 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
5781 ActivityTaskManagerService.this.cancelRecentsAnimation(restoreHomeStackPosition);
5782 }
5783
5784 @Override
5785 public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005786 ActivityTaskManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005787 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005788
5789 @Override
5790 public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
5791 synchronized (mGlobalLock) {
5792 mActiveVoiceInteractionServiceComponent = component;
5793 }
5794 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005795
5796 @Override
5797 public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
5798 if (!mAmInternal.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
5799 return;
5800 }
5801 synchronized (mGlobalLock) {
5802 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
5803 if (types == null) {
5804 if (uid < 0) {
5805 return;
5806 }
5807 types = new ArrayMap<>();
5808 mAllowAppSwitchUids.put(userId, types);
5809 }
5810 if (uid < 0) {
5811 types.remove(type);
5812 } else {
5813 types.put(type, uid);
5814 }
5815 }
5816 }
5817
5818 @Override
5819 public void onUserStopped(int userId) {
5820 synchronized (mGlobalLock) {
5821 getRecentTasks().unloadUserDataFromMemoryLocked(userId);
5822 mAllowAppSwitchUids.remove(userId);
5823 }
5824 }
5825
5826 @Override
5827 public boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
5828 synchronized (mGlobalLock) {
5829 return ActivityTaskManagerService.this.isGetTasksAllowed(
5830 caller, callingPid, callingUid);
5831 }
5832 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005833
5834 @Override
5835 public void onProcessAdded(WindowProcessController proc) {
5836 synchronized (mGlobalLock) {
5837 mProcessNames.put(proc.mName, proc.mUid, proc);
5838 }
5839 }
5840
5841 @Override
5842 public void onProcessRemoved(String name, int uid) {
5843 synchronized (mGlobalLock) {
5844 mProcessNames.remove(name, uid);
5845 }
5846 }
5847
5848 @Override
5849 public void onCleanUpApplicationRecord(WindowProcessController proc) {
5850 synchronized (mGlobalLock) {
5851 if (proc == mHomeProcess) {
5852 mHomeProcess = null;
5853 }
5854 if (proc == mPreviousProcess) {
5855 mPreviousProcess = null;
5856 }
5857 }
5858 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005859
5860 @Override
5861 public int getTopProcessState() {
5862 synchronized (mGlobalLock) {
5863 return mTopProcessState;
5864 }
5865 }
5866
5867 @Override
Wale Ogunwale53783742018-09-16 10:21:51 -07005868 public boolean isHeavyWeightProcess(WindowProcessController proc) {
5869 synchronized (mGlobalLock) {
5870 return proc == mHeavyWeightProcess;
5871 }
5872 }
5873
5874 @Override
5875 public void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
5876 synchronized (mGlobalLock) {
5877 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(proc);
5878 }
5879 }
5880
5881 @Override
5882 public void finishHeavyWeightApp() {
5883 synchronized (mGlobalLock) {
Sudheer Shankaee1da272018-10-20 20:11:44 -07005884 if (mHeavyWeightProcess != null) {
5885 mHeavyWeightProcess.finishActivities();
5886 }
Wale Ogunwale53783742018-09-16 10:21:51 -07005887 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(
5888 mHeavyWeightProcess);
5889 }
5890 }
5891
5892 @Override
Wale Ogunwalef6733932018-06-27 05:14:34 -07005893 public boolean isSleeping() {
5894 synchronized (mGlobalLock) {
5895 return isSleepingLocked();
5896 }
5897 }
5898
5899 @Override
5900 public boolean isShuttingDown() {
5901 synchronized (mGlobalLock) {
5902 return mShuttingDown;
5903 }
5904 }
5905
5906 @Override
5907 public boolean shuttingDown(boolean booted, int timeout) {
5908 synchronized (mGlobalLock) {
5909 mShuttingDown = true;
5910 mStackSupervisor.prepareForShutdownLocked();
5911 updateEventDispatchingLocked(booted);
Wale Ogunwaled4d67d02018-10-25 18:09:39 -07005912 notifyTaskPersisterLocked(null, true);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005913 return mStackSupervisor.shutdownLocked(timeout);
5914 }
5915 }
5916
5917 @Override
5918 public void enableScreenAfterBoot(boolean booted) {
5919 synchronized (mGlobalLock) {
5920 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5921 SystemClock.uptimeMillis());
5922 mWindowManager.enableScreenAfterBoot();
5923 updateEventDispatchingLocked(booted);
5924 }
5925 }
5926
5927 @Override
5928 public boolean showStrictModeViolationDialog() {
5929 synchronized (mGlobalLock) {
5930 return mShowDialogs && !mSleeping && !mShuttingDown;
5931 }
5932 }
5933
5934 @Override
5935 public void showSystemReadyErrorDialogsIfNeeded() {
5936 synchronized (mGlobalLock) {
5937 try {
5938 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
5939 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
5940 + " data partition or your device will be unstable.");
5941 mUiHandler.post(() -> {
5942 if (mShowDialogs) {
5943 AlertDialog d = new BaseErrorDialog(mUiContext);
5944 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5945 d.setCancelable(false);
5946 d.setTitle(mUiContext.getText(R.string.android_system_label));
5947 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
5948 d.setButton(DialogInterface.BUTTON_POSITIVE,
5949 mUiContext.getText(R.string.ok),
5950 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5951 d.show();
5952 }
5953 });
5954 }
5955 } catch (RemoteException e) {
5956 }
5957
5958 if (!Build.isBuildConsistent()) {
5959 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
5960 mUiHandler.post(() -> {
5961 if (mShowDialogs) {
5962 AlertDialog d = new BaseErrorDialog(mUiContext);
5963 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5964 d.setCancelable(false);
5965 d.setTitle(mUiContext.getText(R.string.android_system_label));
5966 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
5967 d.setButton(DialogInterface.BUTTON_POSITIVE,
5968 mUiContext.getText(R.string.ok),
5969 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5970 d.show();
5971 }
5972 });
5973 }
5974 }
5975 }
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005976
5977 @Override
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005978 public void onProcessMapped(int pid, WindowProcessController proc) {
5979 synchronized (mGlobalLock) {
5980 mPidMap.put(pid, proc);
5981 }
5982 }
5983
5984 @Override
5985 public void onProcessUnMapped(int pid) {
5986 synchronized (mGlobalLock) {
5987 mPidMap.remove(pid);
5988 }
5989 }
Wale Ogunwale008163e2018-07-23 23:11:08 -07005990
5991 @Override
5992 public void onPackageDataCleared(String name) {
5993 synchronized (mGlobalLock) {
Wale Ogunwale53783742018-09-16 10:21:51 -07005994 mCompatModePackages.handlePackageDataClearedLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07005995 mAppWarnings.onPackageDataCleared(name);
5996 }
5997 }
5998
5999 @Override
6000 public void onPackageUninstalled(String name) {
6001 synchronized (mGlobalLock) {
6002 mAppWarnings.onPackageUninstalled(name);
Wale Ogunwale53783742018-09-16 10:21:51 -07006003 mCompatModePackages.handlePackageUninstalledLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07006004 }
6005 }
Wale Ogunwale53783742018-09-16 10:21:51 -07006006
6007 @Override
6008 public void onPackageAdded(String name, boolean replacing) {
6009 synchronized (mGlobalLock) {
6010 mCompatModePackages.handlePackageAddedLocked(name, replacing);
6011 }
6012 }
6013
6014 @Override
Wale Ogunwale31913b52018-10-13 08:29:31 -07006015 public void onPackageReplaced(ApplicationInfo aInfo) {
6016 synchronized (mGlobalLock) {
6017 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
6018 }
6019 }
6020
6021 @Override
Wale Ogunwale53783742018-09-16 10:21:51 -07006022 public CompatibilityInfo compatibilityInfoForPackage(ApplicationInfo ai) {
6023 synchronized (mGlobalLock) {
6024 return compatibilityInfoForPackageLocked(ai);
6025 }
6026 }
6027
Yunfan Chen75157d72018-07-27 14:47:21 +09006028 /**
6029 * Set the corresponding display information for the process global configuration. To be
6030 * called when we need to show IME on a different display.
6031 *
6032 * @param pid The process id associated with the IME window.
6033 * @param displayId The ID of the display showing the IME.
6034 */
6035 @Override
Yunfan Chen79b96062018-10-17 12:45:23 -07006036 public void onImeWindowSetOnDisplay(final int pid, final int displayId) {
Yunfan Chen75157d72018-07-27 14:47:21 +09006037 if (pid == MY_PID || pid < 0) {
6038 if (DEBUG_CONFIGURATION) {
6039 Slog.w(TAG,
6040 "Trying to update display configuration for system/invalid process.");
6041 }
6042 return;
6043 }
6044 mH.post(() -> {
6045 synchronized (mGlobalLock) {
Yunfan Chen79b96062018-10-17 12:45:23 -07006046 final ActivityDisplay activityDisplay =
6047 mStackSupervisor.getActivityDisplay(displayId);
6048 if (activityDisplay == null) {
6049 // Call might come when display is not yet added or has been removed.
Yunfan Chen75157d72018-07-27 14:47:21 +09006050 if (DEBUG_CONFIGURATION) {
6051 Slog.w(TAG, "Trying to update display configuration for non-existing "
Yunfan Chen79b96062018-10-17 12:45:23 -07006052 + "displayId=" + displayId);
Yunfan Chen75157d72018-07-27 14:47:21 +09006053 }
6054 return;
6055 }
Yunfan Chen79b96062018-10-17 12:45:23 -07006056 final WindowProcessController process = mPidMap.get(pid);
6057 if (process == null) {
Yunfan Chen75157d72018-07-27 14:47:21 +09006058 if (DEBUG_CONFIGURATION) {
Yunfan Chen79b96062018-10-17 12:45:23 -07006059 Slog.w(TAG, "Trying to update display configuration for invalid "
6060 + "process, pid=" + pid);
Yunfan Chen75157d72018-07-27 14:47:21 +09006061 }
6062 return;
6063 }
Yunfan Chen79b96062018-10-17 12:45:23 -07006064 process.registerDisplayConfigurationListenerLocked(activityDisplay);
Yunfan Chen75157d72018-07-27 14:47:21 +09006065 }
6066 });
Yunfan Chen79b96062018-10-17 12:45:23 -07006067
Yunfan Chen75157d72018-07-27 14:47:21 +09006068 }
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07006069
6070 @Override
6071 public void sendActivityResult(int callingUid, IBinder activityToken, String resultWho,
6072 int requestCode, int resultCode, Intent data) {
6073 synchronized (mGlobalLock) {
6074 final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
6075 if (r != null && r.getStack() != null) {
6076 r.getStack().sendActivityResultLocked(callingUid, r, resultWho, requestCode,
6077 resultCode, data);
6078 }
6079 }
6080 }
6081
6082 @Override
6083 public void clearPendingResultForActivity(IBinder activityToken,
6084 WeakReference<PendingIntentRecord> pir) {
6085 synchronized (mGlobalLock) {
6086 final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
6087 if (r != null && r.pendingResults != null) {
6088 r.pendingResults.remove(pir);
6089 }
6090 }
6091 }
6092
6093 @Override
6094 public IIntentSender getIntentSender(int type, String packageName,
6095 int callingUid, int userId, IBinder token, String resultWho,
6096 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6097 Bundle bOptions) {
6098 synchronized (mGlobalLock) {
6099 return getIntentSenderLocked(type, packageName, callingUid, userId, token,
6100 resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6101 }
6102 }
Wale Ogunwalec4e63a42018-10-02 13:19:54 -07006103
6104 @Override
6105 public ActivityServiceConnectionsHolder getServiceConnectionsHolder(IBinder token) {
6106 synchronized (mGlobalLock) {
6107 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
6108 if (r == null) {
6109 return null;
6110 }
6111 if (r.mServiceConnectionsHolder == null) {
6112 r.mServiceConnectionsHolder = new ActivityServiceConnectionsHolder(
6113 ActivityTaskManagerService.this, r);
6114 }
6115
6116 return r.mServiceConnectionsHolder;
6117 }
6118 }
Wale Ogunwale214f3482018-10-04 11:00:47 -07006119
6120 @Override
6121 public Intent getHomeIntent() {
6122 synchronized (mGlobalLock) {
6123 return ActivityTaskManagerService.this.getHomeIntent();
6124 }
6125 }
6126
6127 @Override
6128 public boolean startHomeActivity(int userId, String reason) {
6129 synchronized (mGlobalLock) {
6130 return startHomeActivityLocked(userId, reason, DEFAULT_DISPLAY);
6131 }
6132 }
6133
6134 @Override
6135 public boolean isFactoryTestProcess(WindowProcessController wpc) {
6136 synchronized (mGlobalLock) {
6137 if (mFactoryTest == FACTORY_TEST_OFF) {
6138 return false;
6139 }
6140 if (mFactoryTest == FACTORY_TEST_LOW_LEVEL && mTopComponent != null
6141 && wpc.mName.equals(mTopComponent.getPackageName())) {
6142 return true;
6143 }
6144 return mFactoryTest == FACTORY_TEST_HIGH_LEVEL
6145 && (wpc.mInfo.flags & FLAG_FACTORY_TEST) != 0;
6146 }
6147 }
6148
6149 @Override
6150 public void updateTopComponentForFactoryTest() {
6151 synchronized (mGlobalLock) {
6152 if (mFactoryTest != FACTORY_TEST_LOW_LEVEL) {
6153 return;
6154 }
6155 final ResolveInfo ri = mContext.getPackageManager()
6156 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), STOCK_PM_FLAGS);
6157 final CharSequence errorMsg;
6158 if (ri != null) {
6159 final ActivityInfo ai = ri.activityInfo;
6160 final ApplicationInfo app = ai.applicationInfo;
6161 if ((app.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
6162 mTopAction = Intent.ACTION_FACTORY_TEST;
6163 mTopData = null;
6164 mTopComponent = new ComponentName(app.packageName, ai.name);
6165 errorMsg = null;
6166 } else {
6167 errorMsg = mContext.getResources().getText(
6168 com.android.internal.R.string.factorytest_not_system);
6169 }
6170 } else {
6171 errorMsg = mContext.getResources().getText(
6172 com.android.internal.R.string.factorytest_no_action);
6173 }
6174 if (errorMsg == null) {
6175 return;
6176 }
6177
6178 mTopAction = null;
6179 mTopData = null;
6180 mTopComponent = null;
6181 mUiHandler.post(() -> {
6182 Dialog d = new FactoryErrorDialog(mUiContext, errorMsg);
6183 d.show();
Wale Ogunwale342fbe92018-10-09 08:44:10 -07006184 mAmInternal.ensureBootCompleted();
Wale Ogunwale214f3482018-10-04 11:00:47 -07006185 });
6186 }
6187 }
Wale Ogunwale31913b52018-10-13 08:29:31 -07006188
6189 @Override
6190 public void handleAppDied(WindowProcessController wpc, boolean restarting,
6191 Runnable finishInstrumentationCallback) {
6192 synchronized (mGlobalLock) {
6193 // Remove this application's activities from active lists.
6194 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(wpc);
6195
6196 wpc.clearRecentTasks();
6197 wpc.clearActivities();
6198
6199 if (wpc.isInstrumenting()) {
6200 finishInstrumentationCallback.run();
6201 }
6202
6203 mWindowManager.deferSurfaceLayout();
6204 try {
6205 if (!restarting && hasVisibleActivities
6206 && !mStackSupervisor.resumeFocusedStacksTopActivitiesLocked()) {
6207 // If there was nothing to resume, and we are not already restarting this
6208 // process, but there is a visible activity that is hosted by the process...
6209 // then make sure all visible activities are running, taking care of
6210 // restarting this process.
6211 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6212 }
6213 } finally {
6214 mWindowManager.continueSurfaceLayout();
6215 }
6216 }
6217 }
6218
6219 @Override
6220 public void closeSystemDialogs(String reason) {
6221 enforceNotIsolatedCaller("closeSystemDialogs");
6222
6223 final int pid = Binder.getCallingPid();
6224 final int uid = Binder.getCallingUid();
6225 final long origId = Binder.clearCallingIdentity();
6226 try {
6227 synchronized (mGlobalLock) {
6228 // Only allow this from foreground processes, so that background
6229 // applications can't abuse it to prevent system UI from being shown.
6230 if (uid >= FIRST_APPLICATION_UID) {
6231 final WindowProcessController proc = mPidMap.get(pid);
6232 if (!proc.isPerceptible()) {
6233 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6234 + " from background process " + proc);
6235 return;
6236 }
6237 }
Wale Ogunwale31913b52018-10-13 08:29:31 -07006238 mWindowManager.closeSystemDialogs(reason);
6239
6240 mStackSupervisor.closeSystemDialogsLocked();
Wale Ogunwale31913b52018-10-13 08:29:31 -07006241 }
Wale Ogunwale2ea36d42018-10-18 10:27:31 -07006242 // Call into AM outside the synchronized block.
6243 mAmInternal.broadcastCloseSystemDialogs(reason);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006244 } finally {
6245 Binder.restoreCallingIdentity(origId);
6246 }
6247 }
6248
6249 @Override
6250 public void cleanupDisabledPackageComponents(
6251 String packageName, Set<String> disabledClasses, int userId, boolean booted) {
6252 synchronized (mGlobalLock) {
6253 // Clean-up disabled activities.
6254 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6255 packageName, disabledClasses, true, false, userId) && booted) {
6256 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
6257 mStackSupervisor.scheduleIdleLocked();
6258 }
6259
6260 // Clean-up disabled tasks
6261 getRecentTasks().cleanupDisabledPackageTasksLocked(
6262 packageName, disabledClasses, userId);
6263 }
6264 }
6265
6266 @Override
6267 public boolean onForceStopPackage(String packageName, boolean doit, boolean evenPersistent,
6268 int userId) {
6269 synchronized (mGlobalLock) {
6270
6271 boolean didSomething =
6272 getActivityStartController().clearPendingActivityLaunches(packageName);
6273 didSomething |= mStackSupervisor.finishDisabledPackageActivitiesLocked(packageName,
6274 null, doit, evenPersistent, userId);
6275 return didSomething;
6276 }
6277 }
6278
6279 @Override
6280 public void resumeTopActivities(boolean scheduleIdle) {
6281 synchronized (mGlobalLock) {
6282 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
6283 if (scheduleIdle) {
6284 mStackSupervisor.scheduleIdleLocked();
6285 }
6286 }
6287 }
6288
6289 @Override
6290 public void preBindApplication(WindowProcessController wpc) {
6291 synchronized (mGlobalLock) {
6292 mStackSupervisor.getActivityMetricsLogger().notifyBindApplication(wpc.mInfo);
6293 }
6294 }
6295
6296 @Override
6297 public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
6298 synchronized (mGlobalLock) {
6299 return mStackSupervisor.attachApplicationLocked(wpc);
6300 }
6301 }
6302
6303 @Override
6304 public void notifyLockedProfile(@UserIdInt int userId, int currentUserId) {
6305 try {
6306 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
6307 throw new SecurityException("Only privileged app can call notifyLockedProfile");
6308 }
6309 } catch (RemoteException ex) {
6310 throw new SecurityException("Fail to check is caller a privileged app", ex);
6311 }
6312
6313 synchronized (mGlobalLock) {
6314 final long ident = Binder.clearCallingIdentity();
6315 try {
6316 if (mAmInternal.shouldConfirmCredentials(userId)) {
6317 if (mKeyguardController.isKeyguardLocked()) {
6318 // Showing launcher to avoid user entering credential twice.
6319 startHomeActivity(currentUserId, "notifyLockedProfile");
6320 }
6321 mStackSupervisor.lockAllProfileTasks(userId);
6322 }
6323 } finally {
6324 Binder.restoreCallingIdentity(ident);
6325 }
6326 }
6327 }
6328
6329 @Override
6330 public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
6331 mAmInternal.enforceCallingPermission(
6332 MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
6333
6334 synchronized (mGlobalLock) {
6335 final long ident = Binder.clearCallingIdentity();
6336 try {
6337 intent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
6338 FLAG_ACTIVITY_TASK_ON_HOME);
6339 ActivityOptions activityOptions = options != null
6340 ? new ActivityOptions(options) : ActivityOptions.makeBasic();
6341 activityOptions.setLaunchTaskId(
6342 mStackSupervisor.getDefaultDisplayHomeActivity().getTask().taskId);
6343 mContext.startActivityAsUser(intent, activityOptions.toBundle(),
6344 UserHandle.CURRENT);
6345 } finally {
6346 Binder.restoreCallingIdentity(ident);
6347 }
6348 }
6349 }
6350
6351 @Override
6352 public void writeActivitiesToProto(ProtoOutputStream proto) {
6353 synchronized (mGlobalLock) {
6354 // The output proto of "activity --proto activities"
6355 // is ActivityManagerServiceDumpActivitiesProto
6356 mStackSupervisor.writeToProto(proto,
6357 ActivityManagerServiceDumpActivitiesProto.ACTIVITY_STACK_SUPERVISOR);
6358 }
6359 }
6360
6361 @Override
6362 public void saveANRState(String reason) {
6363 synchronized (mGlobalLock) {
6364 final StringWriter sw = new StringWriter();
6365 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
6366 pw.println(" ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
6367 if (reason != null) {
6368 pw.println(" Reason: " + reason);
6369 }
6370 pw.println();
6371 getActivityStartController().dump(pw, " ", null);
6372 pw.println();
6373 pw.println("-------------------------------------------------------------------------------");
6374 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
6375 true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
6376 "" /* header */);
6377 pw.println();
6378 pw.close();
6379
6380 mLastANRState = sw.toString();
6381 }
6382 }
6383
6384 @Override
6385 public void clearSavedANRState() {
6386 synchronized (mGlobalLock) {
6387 mLastANRState = null;
6388 }
6389 }
6390
6391 @Override
6392 public void dump(String cmd, FileDescriptor fd, PrintWriter pw, String[] args, int opti,
6393 boolean dumpAll, boolean dumpClient, String dumpPackage) {
6394 synchronized (mGlobalLock) {
6395 if (DUMP_ACTIVITIES_CMD.equals(cmd) || DUMP_ACTIVITIES_SHORT_CMD.equals(cmd)) {
6396 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
6397 } else if (DUMP_LASTANR_CMD.equals(cmd)) {
6398 dumpLastANRLocked(pw);
6399 } else if (DUMP_LASTANR_TRACES_CMD.equals(cmd)) {
6400 dumpLastANRTracesLocked(pw);
6401 } else if (DUMP_STARTER_CMD.equals(cmd)) {
6402 dumpActivityStarterLocked(pw, dumpPackage);
6403 } else if (DUMP_CONTAINERS_CMD.equals(cmd)) {
6404 dumpActivityContainersLocked(pw);
6405 } else if (DUMP_RECENTS_CMD.equals(cmd) || DUMP_RECENTS_SHORT_CMD.equals(cmd)) {
6406 if (getRecentTasks() != null) {
6407 getRecentTasks().dump(pw, dumpAll, dumpPackage);
6408 }
6409 }
6410 }
6411 }
6412
6413 @Override
6414 public boolean dumpForProcesses(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
6415 String dumpPackage, int dumpAppId, boolean needSep, boolean testPssMode,
6416 int wakefulness) {
6417 synchronized (mGlobalLock) {
6418 if (mHomeProcess != null && (dumpPackage == null
6419 || mHomeProcess.mPkgList.contains(dumpPackage))) {
6420 if (needSep) {
6421 pw.println();
6422 needSep = false;
6423 }
6424 pw.println(" mHomeProcess: " + mHomeProcess);
6425 }
6426 if (mPreviousProcess != null && (dumpPackage == null
6427 || mPreviousProcess.mPkgList.contains(dumpPackage))) {
6428 if (needSep) {
6429 pw.println();
6430 needSep = false;
6431 }
6432 pw.println(" mPreviousProcess: " + mPreviousProcess);
6433 }
6434 if (dumpAll && (mPreviousProcess == null || dumpPackage == null
6435 || mPreviousProcess.mPkgList.contains(dumpPackage))) {
6436 StringBuilder sb = new StringBuilder(128);
6437 sb.append(" mPreviousProcessVisibleTime: ");
6438 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
6439 pw.println(sb);
6440 }
6441 if (mHeavyWeightProcess != null && (dumpPackage == null
6442 || mHeavyWeightProcess.mPkgList.contains(dumpPackage))) {
6443 if (needSep) {
6444 pw.println();
6445 needSep = false;
6446 }
6447 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
6448 }
6449 if (dumpPackage == null) {
6450 pw.println(" mGlobalConfiguration: " + getGlobalConfiguration());
6451 mStackSupervisor.dumpDisplayConfigs(pw, " ");
6452 }
6453 if (dumpAll) {
6454 if (dumpPackage == null) {
6455 pw.println(" mConfigWillChange: "
6456 + getTopDisplayFocusedStack().mConfigWillChange);
6457 }
6458 if (mCompatModePackages.getPackages().size() > 0) {
6459 boolean printed = false;
6460 for (Map.Entry<String, Integer> entry
6461 : mCompatModePackages.getPackages().entrySet()) {
6462 String pkg = entry.getKey();
6463 int mode = entry.getValue();
6464 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
6465 continue;
6466 }
6467 if (!printed) {
6468 pw.println(" mScreenCompatPackages:");
6469 printed = true;
6470 }
6471 pw.println(" " + pkg + ": " + mode);
6472 }
6473 }
6474 }
6475
6476 if (dumpPackage == null) {
6477 pw.println(" mWakefulness="
6478 + PowerManagerInternal.wakefulnessToString(wakefulness));
6479 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
6480 if (mRunningVoice != null) {
6481 pw.println(" mRunningVoice=" + mRunningVoice);
6482 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
6483 }
6484 pw.println(" mSleeping=" + mSleeping);
6485 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + testPssMode);
6486 pw.println(" mVrController=" + mVrController);
6487 }
6488 if (mCurAppTimeTracker != null) {
6489 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
6490 }
6491 if (mAllowAppSwitchUids.size() > 0) {
6492 boolean printed = false;
6493 for (int i = 0; i < mAllowAppSwitchUids.size(); i++) {
6494 ArrayMap<String, Integer> types = mAllowAppSwitchUids.valueAt(i);
6495 for (int j = 0; j < types.size(); j++) {
6496 if (dumpPackage == null ||
6497 UserHandle.getAppId(types.valueAt(j).intValue()) == dumpAppId) {
6498 if (needSep) {
6499 pw.println();
6500 needSep = false;
6501 }
6502 if (!printed) {
6503 pw.println(" mAllowAppSwitchUids:");
6504 printed = true;
6505 }
6506 pw.print(" User ");
6507 pw.print(mAllowAppSwitchUids.keyAt(i));
6508 pw.print(": Type ");
6509 pw.print(types.keyAt(j));
6510 pw.print(" = ");
6511 UserHandle.formatUid(pw, types.valueAt(j).intValue());
6512 pw.println();
6513 }
6514 }
6515 }
6516 }
6517 if (dumpPackage == null) {
6518 if (mController != null) {
6519 pw.println(" mController=" + mController
6520 + " mControllerIsAMonkey=" + mControllerIsAMonkey);
6521 }
6522 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
6523 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
6524 }
6525
6526 return needSep;
6527 }
6528 }
6529
6530 @Override
6531 public void writeProcessesToProto(ProtoOutputStream proto, String dumpPackage) {
6532 synchronized (mGlobalLock) {
6533 if (dumpPackage == null) {
6534 getGlobalConfiguration().writeToProto(proto, GLOBAL_CONFIGURATION);
6535 proto.write(CONFIG_WILL_CHANGE, getTopDisplayFocusedStack().mConfigWillChange);
6536 writeSleepStateToProto(proto);
6537 if (mController != null) {
6538 final long token = proto.start(CONTROLLER);
6539 proto.write(CONTROLLER, mController.toString());
6540 proto.write(IS_A_MONKEY, mControllerIsAMonkey);
6541 proto.end(token);
6542 }
6543 mStackSupervisor.mGoingToSleep.writeToProto(proto, GOING_TO_SLEEP);
6544 mStackSupervisor.mLaunchingActivity.writeToProto(proto, LAUNCHING_ACTIVITY);
6545 }
6546
6547 if (mHomeProcess != null && (dumpPackage == null
6548 || mHomeProcess.mPkgList.contains(dumpPackage))) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07006549 mHomeProcess.writeToProto(proto, HOME_PROC);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006550 }
6551
6552 if (mPreviousProcess != null && (dumpPackage == null
6553 || mPreviousProcess.mPkgList.contains(dumpPackage))) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07006554 mPreviousProcess.writeToProto(proto, PREVIOUS_PROC);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006555 proto.write(PREVIOUS_PROC_VISIBLE_TIME_MS, mPreviousProcessVisibleTime);
6556 }
6557
6558 if (mHeavyWeightProcess != null && (dumpPackage == null
6559 || mHeavyWeightProcess.mPkgList.contains(dumpPackage))) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07006560 mHeavyWeightProcess.writeToProto(proto, HEAVY_WEIGHT_PROC);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006561 }
6562
6563 for (Map.Entry<String, Integer> entry
6564 : mCompatModePackages.getPackages().entrySet()) {
6565 String pkg = entry.getKey();
6566 int mode = entry.getValue();
6567 if (dumpPackage == null || dumpPackage.equals(pkg)) {
6568 long compatToken = proto.start(SCREEN_COMPAT_PACKAGES);
6569 proto.write(PACKAGE, pkg);
6570 proto.write(MODE, mode);
6571 proto.end(compatToken);
6572 }
6573 }
6574
6575 if (mCurAppTimeTracker != null) {
6576 mCurAppTimeTracker.writeToProto(proto, CURRENT_TRACKER, true);
6577 }
6578
6579 }
6580 }
6581
6582 @Override
6583 public boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name,
6584 String[] args, int opti, boolean dumpAll, boolean dumpVisibleStacksOnly,
6585 boolean dumpFocusedStackOnly) {
6586 synchronized (mGlobalLock) {
6587 return ActivityTaskManagerService.this.dumpActivity(fd, pw, name, args, opti,
6588 dumpAll, dumpVisibleStacksOnly, dumpFocusedStackOnly);
6589 }
6590 }
6591
6592 @Override
Wale Ogunwaled4d67d02018-10-25 18:09:39 -07006593 public void dumpForOom(PrintWriter pw) {
6594 synchronized (mGlobalLock) {
6595 pw.println(" mHomeProcess: " + mHomeProcess);
6596 pw.println(" mPreviousProcess: " + mPreviousProcess);
6597 if (mHeavyWeightProcess != null) {
6598 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
6599 }
6600 }
6601 }
6602
6603 @Override
Wale Ogunwale31913b52018-10-13 08:29:31 -07006604 public boolean canGcNow() {
6605 synchronized (mGlobalLock) {
6606 return isSleeping() || mStackSupervisor.allResumedActivitiesIdle();
6607 }
6608 }
6609
6610 @Override
6611 public WindowProcessController getTopApp() {
6612 synchronized (mGlobalLock) {
6613 final ActivityRecord top = mStackSupervisor.getTopResumedActivity();
6614 return top != null ? top.app : null;
6615 }
6616 }
6617
6618 @Override
6619 public void rankTaskLayersIfNeeded() {
6620 synchronized (mGlobalLock) {
6621 if (mStackSupervisor != null) {
6622 mStackSupervisor.rankTaskLayersIfNeeded();
6623 }
6624 }
6625 }
6626
6627 @Override
6628 public void scheduleDestroyAllActivities(String reason) {
6629 synchronized (mGlobalLock) {
6630 mStackSupervisor.scheduleDestroyAllActivities(null, reason);
6631 }
6632 }
6633
6634 @Override
6635 public void removeUser(int userId) {
6636 synchronized (mGlobalLock) {
6637 mStackSupervisor.removeUserLocked(userId);
6638 }
6639 }
6640
6641 @Override
6642 public boolean switchUser(int userId, UserState userState) {
6643 synchronized (mGlobalLock) {
6644 return mStackSupervisor.switchUserLocked(userId, userState);
6645 }
6646 }
6647
6648 @Override
6649 public void onHandleAppCrash(WindowProcessController wpc) {
6650 synchronized (mGlobalLock) {
6651 mStackSupervisor.handleAppCrashLocked(wpc);
6652 }
6653 }
Wale Ogunwale64258362018-10-16 15:13:37 -07006654
6655 @Override
6656 public int finishTopCrashedActivities(WindowProcessController crashedApp, String reason) {
6657 synchronized (mGlobalLock) {
6658 return mStackSupervisor.finishTopCrashedActivitiesLocked(crashedApp, reason);
6659 }
6660 }
Wale Ogunwalebff2df42018-10-18 17:09:19 -07006661
6662 @Override
6663 public void onUidActive(int uid, int procState) {
6664 synchronized (mGlobalLock) {
6665 mActiveUids.put(uid, procState);
6666 }
6667 }
6668
6669 @Override
6670 public void onUidInactive(int uid) {
6671 synchronized (mGlobalLock) {
6672 mActiveUids.remove(uid);
6673 }
6674 }
6675
6676 @Override
6677 public void onActiveUidsCleared() {
6678 synchronized (mGlobalLock) {
6679 mActiveUids.clear();
6680 }
6681 }
6682
6683 @Override
6684 public void onUidProcStateChanged(int uid, int procState) {
6685 synchronized (mGlobalLock) {
6686 if (mActiveUids.get(uid) != null) {
6687 mActiveUids.put(uid, procState);
6688 }
6689 }
6690 }
Wale Ogunwale9de19442018-10-18 19:05:03 -07006691
6692 @Override
6693 public void onUidAddedToPendingTempWhitelist(int uid, String tag) {
6694 synchronized (mGlobalLock) {
6695 mPendingTempWhitelist.put(uid, tag);
6696 }
6697 }
6698
6699 @Override
6700 public void onUidRemovedFromPendingTempWhitelist(int uid) {
6701 synchronized (mGlobalLock) {
6702 mPendingTempWhitelist.remove(uid);
6703 }
6704 }
Wale Ogunwalee2172292018-10-25 10:11:10 -07006705
6706 @Override
6707 public boolean handleAppCrashInActivityController(String processName, int pid,
6708 String shortMsg, String longMsg, long timeMillis, String stackTrace,
6709 Runnable killCrashingAppCallback) {
6710 synchronized (mGlobalLock) {
6711 if (mController == null) {
6712 return false;
6713 }
6714
6715 try {
6716 if (!mController.appCrashed(processName, pid, shortMsg, longMsg, timeMillis,
6717 stackTrace)) {
6718 killCrashingAppCallback.run();
6719 return true;
6720 }
6721 } catch (RemoteException e) {
6722 mController = null;
6723 Watchdog.getInstance().setActivityController(null);
6724 }
6725 return false;
6726 }
6727 }
Wale Ogunwaled7889f52018-10-25 11:03:20 -07006728
6729 @Override
6730 public void removeRecentTasksByPackageName(String packageName, int userId) {
6731 synchronized (mGlobalLock) {
6732 mRecentTasks.removeTasksByPackageName(packageName, userId);
6733 }
6734 }
6735
6736 @Override
6737 public void cleanupRecentTasksForUser(int userId) {
6738 synchronized (mGlobalLock) {
6739 mRecentTasks.cleanupLocked(userId);
6740 }
6741 }
6742
6743 @Override
6744 public void loadRecentTasksForUser(int userId) {
6745 synchronized (mGlobalLock) {
6746 mRecentTasks.loadUserRecentsLocked(userId);
6747 }
6748 }
6749
6750 @Override
6751 public void onPackagesSuspendedChanged(String[] packages, boolean suspended, int userId) {
6752 synchronized (mGlobalLock) {
6753 mRecentTasks.onPackagesSuspendedChanged(packages, suspended, userId);
6754 }
6755 }
6756
6757 @Override
6758 public void flushRecentTasks() {
6759 mRecentTasks.flush();
6760 }
Wale Ogunwaled4d67d02018-10-25 18:09:39 -07006761
6762 @Override
6763 public WindowProcessController getHomeProcess() {
6764 synchronized (mGlobalLock) {
6765 return mHomeProcess;
6766 }
6767 }
6768
6769 @Override
6770 public WindowProcessController getPreviousProcess() {
6771 synchronized (mGlobalLock) {
6772 return mPreviousProcess;
6773 }
6774 }
Wale Ogunwale27c48ae2018-10-25 19:01:01 -07006775
6776 @Override
6777 public void clearLockedTasks(String reason) {
6778 synchronized (mGlobalLock) {
6779 getLockTaskController().clearLockedTasks(reason);
6780 }
6781 }
6782
6783 @Override
6784 public void updateUserConfiguration() {
6785 synchronized (mGlobalLock) {
6786 final Configuration configuration = new Configuration(getGlobalConfiguration());
6787 final int currentUserId = mAmInternal.getCurrentUserId();
6788 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(),
6789 configuration, currentUserId, Settings.System.canWrite(mContext));
6790 updateConfigurationLocked(configuration, null /* starting */,
6791 false /* initLocale */, false /* persistent */, currentUserId,
6792 false /* deferResume */);
6793 }
6794 }
Wale Ogunwale387b34c2018-10-25 19:59:40 -07006795
6796 @Override
6797 public boolean canShowErrorDialogs() {
6798 synchronized (mGlobalLock) {
6799 return mShowDialogs && !mSleeping && !mShuttingDown
6800 && !mKeyguardController.isKeyguardOrAodShowing(DEFAULT_DISPLAY)
6801 && !hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
6802 mAmInternal.getCurrentUserId())
6803 && !(UserManager.isDeviceInDemoMode(mContext)
6804 && mAmInternal.getCurrentUser().isDemo());
6805 }
6806 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07006807 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07006808}