blob: 4ae9856e091c7c8eee01270a9180d06a6427d228 [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 Ogunwale04d9cb52018-04-30 13:55:07 -0700615 void onSystemReady() {
Wale Ogunwale214f3482018-10-04 11:00:47 -0700616 mHasHeavyWeightFeature = mContext.getPackageManager().hasSystemFeature(
617 PackageManager.FEATURE_CANT_SAVE_STATE);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700618 mAssistUtils = new AssistUtils(mContext);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700619 mVrController.onSystemReady();
620 mRecentTasks.onSystemReadyLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700621 }
622
Wale Ogunwalef6733932018-06-27 05:14:34 -0700623 void onInitPowerManagement() {
624 mStackSupervisor.initPowerManagement();
625 final PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700626 mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
Wale Ogunwalef6733932018-06-27 05:14:34 -0700627 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
628 mVoiceWakeLock.setReferenceCounted(false);
629 }
630
631 void installSystemProviders() {
632 mFontScaleSettingObserver = new FontScaleSettingObserver();
633 }
634
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700635 void retrieveSettings(ContentResolver resolver) {
636 final boolean freeformWindowManagement =
637 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
638 || Settings.Global.getInt(
639 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
640
641 final boolean supportsMultiWindow = ActivityTaskManager.supportsMultiWindow(mContext);
642 final boolean supportsPictureInPicture = supportsMultiWindow &&
643 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
644 final boolean supportsSplitScreenMultiWindow =
645 ActivityTaskManager.supportsSplitScreenMultiWindow(mContext);
646 final boolean supportsMultiDisplay = mContext.getPackageManager()
647 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
648 final boolean alwaysFinishActivities =
649 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
650 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
651 final boolean forceResizable = Settings.Global.getInt(
652 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
Garfield Tane0846042018-07-26 13:42:04 -0700653 final boolean isPc = mContext.getPackageManager().hasSystemFeature(FEATURE_PC);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700654
655 // Transfer any global setting for forcing RTL layout, into a System Property
656 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
657
658 final Configuration configuration = new Configuration();
659 Settings.System.getConfiguration(resolver, configuration);
660 if (forceRtl) {
661 // This will take care of setting the correct layout direction flags
662 configuration.setLayoutDirection(configuration.locale);
663 }
664
665 synchronized (mGlobalLock) {
666 mForceResizableActivities = forceResizable;
667 final boolean multiWindowFormEnabled = freeformWindowManagement
668 || supportsSplitScreenMultiWindow
669 || supportsPictureInPicture
670 || supportsMultiDisplay;
671 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
672 mSupportsMultiWindow = true;
673 mSupportsFreeformWindowManagement = freeformWindowManagement;
674 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
675 mSupportsPictureInPicture = supportsPictureInPicture;
676 mSupportsMultiDisplay = supportsMultiDisplay;
677 } else {
678 mSupportsMultiWindow = false;
679 mSupportsFreeformWindowManagement = false;
680 mSupportsSplitScreenMultiWindow = false;
681 mSupportsPictureInPicture = false;
682 mSupportsMultiDisplay = false;
683 }
684 mWindowManager.setForceResizableTasks(mForceResizableActivities);
685 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
Garfield Tane0846042018-07-26 13:42:04 -0700686 mWindowManager.setSupportsFreeformWindowManagement(mSupportsFreeformWindowManagement);
687 mWindowManager.setIsPc(isPc);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700688 // This happens before any activities are started, so we can change global configuration
689 // in-place.
690 updateConfigurationLocked(configuration, null, true);
691 final Configuration globalConfig = getGlobalConfiguration();
692 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
693
694 // Load resources only after the current configuration has been set.
695 final Resources res = mContext.getResources();
696 mThumbnailWidth = res.getDimensionPixelSize(
697 com.android.internal.R.dimen.thumbnail_width);
698 mThumbnailHeight = res.getDimensionPixelSize(
699 com.android.internal.R.dimen.thumbnail_height);
700
701 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
702 mFullscreenThumbnailScale = (float) res
703 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
704 (float) globalConfig.screenWidthDp;
705 } else {
706 mFullscreenThumbnailScale = res.getFraction(
707 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
708 }
709 }
710 }
711
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700712 // TODO: Will be converted to WM lock once transition is complete.
Wale Ogunwale9de19442018-10-18 19:05:03 -0700713 void setActivityManagerService(Object globalLock, Looper looper,
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700714 IntentFirewall intentFirewall, PendingIntentController intentController) {
Wale Ogunwale9de19442018-10-18 19:05:03 -0700715 mGlobalLock = globalLock;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700716 mH = new H(looper);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700717 mUiHandler = new UiHandler();
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700718 mIntentFirewall = intentFirewall;
Wale Ogunwale53783742018-09-16 10:21:51 -0700719 final File systemDir = SystemServiceManager.ensureSystemDir();
720 mAppWarnings = new AppWarnings(this, mUiContext, mH, mUiHandler, systemDir);
721 mCompatModePackages = new CompatModePackages(this, systemDir, mH);
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700722 mPendingIntentController = intentController;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700723
724 mTempConfig.setToDefaults();
725 mTempConfig.setLocales(LocaleList.getDefault());
726 mConfigurationSeq = mTempConfig.seq = 1;
727 mStackSupervisor = createStackSupervisor();
728 mStackSupervisor.onConfigurationChanged(mTempConfig);
729
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700730 mTaskChangeNotificationController =
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700731 new TaskChangeNotificationController(mGlobalLock, mStackSupervisor, mH);
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700732 mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mH);
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700733 mActivityStartController = new ActivityStartController(this);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700734 mRecentTasks = createRecentTasks();
735 mStackSupervisor.setRecentTasks(mRecentTasks);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700736 mVrController = new VrController(mGlobalLock);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700737 mKeyguardController = mStackSupervisor.getKeyguardController();
738 }
739
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700740 void onActivityManagerInternalAdded() {
741 mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700742 mUgmInternal = LocalServices.getService(UriGrantsManagerInternal.class);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700743 }
744
Yunfan Chen75157d72018-07-27 14:47:21 +0900745 int increaseConfigurationSeqLocked() {
746 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
747 return mConfigurationSeq;
748 }
749
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700750 protected ActivityStackSupervisor createStackSupervisor() {
751 final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mH.getLooper());
752 supervisor.initialize();
753 return supervisor;
754 }
755
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700756 void setWindowManager(WindowManagerService wm) {
757 mWindowManager = wm;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700758 mLockTaskController.setWindowManager(wm);
Wale Ogunwale31913b52018-10-13 08:29:31 -0700759 mStackSupervisor.setWindowManager(wm);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700760 }
761
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700762 void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
763 mUsageStatsInternal = usageStatsManager;
764 }
765
Wale Ogunwalef6733932018-06-27 05:14:34 -0700766 UserManagerService getUserManager() {
767 if (mUserManager == null) {
768 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
769 mUserManager = (UserManagerService) IUserManager.Stub.asInterface(b);
770 }
771 return mUserManager;
772 }
773
774 AppOpsService getAppOpsService() {
775 if (mAppOpsService == null) {
776 IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
777 mAppOpsService = (AppOpsService) IAppOpsService.Stub.asInterface(b);
778 }
779 return mAppOpsService;
780 }
781
782 boolean hasUserRestriction(String restriction, int userId) {
783 return getUserManager().hasUserRestriction(restriction, userId);
784 }
785
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700786 protected RecentTasks createRecentTasks() {
787 return new RecentTasks(this, mStackSupervisor);
788 }
789
790 RecentTasks getRecentTasks() {
791 return mRecentTasks;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700792 }
793
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700794 ClientLifecycleManager getLifecycleManager() {
795 return mLifecycleManager;
796 }
797
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700798 ActivityStartController getActivityStartController() {
799 return mActivityStartController;
800 }
801
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700802 TaskChangeNotificationController getTaskChangeNotificationController() {
803 return mTaskChangeNotificationController;
804 }
805
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700806 LockTaskController getLockTaskController() {
807 return mLockTaskController;
808 }
809
Yunfan Chen75157d72018-07-27 14:47:21 +0900810 /**
811 * Return the global configuration used by the process corresponding to the input pid. This is
812 * usually the global configuration with some overrides specific to that process.
813 */
814 Configuration getGlobalConfigurationForCallingPid() {
815 final int pid = Binder.getCallingPid();
816 if (pid == MY_PID || pid < 0) {
817 return getGlobalConfiguration();
818 }
819 synchronized (mGlobalLock) {
820 final WindowProcessController app = mPidMap.get(pid);
821 return app != null ? app.getConfiguration() : getGlobalConfiguration();
822 }
823 }
824
825 /**
826 * Return the device configuration info used by the process corresponding to the input pid.
827 * The value is consistent with the global configuration for the process.
828 */
829 @Override
830 public ConfigurationInfo getDeviceConfigurationInfo() {
831 ConfigurationInfo config = new ConfigurationInfo();
832 synchronized (mGlobalLock) {
833 final Configuration globalConfig = getGlobalConfigurationForCallingPid();
834 config.reqTouchScreen = globalConfig.touchscreen;
835 config.reqKeyboardType = globalConfig.keyboard;
836 config.reqNavigation = globalConfig.navigation;
837 if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
838 || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
839 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
840 }
841 if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
842 && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
843 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
844 }
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700845 config.reqGlEsVersion = GL_ES_VERSION;
Yunfan Chen75157d72018-07-27 14:47:21 +0900846 }
847 return config;
848 }
849
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700850 private void start() {
Wale Ogunwale53783742018-09-16 10:21:51 -0700851 mInternal = new LocalService();
852 LocalServices.addService(ActivityTaskManagerInternal.class, mInternal);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700853 }
854
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700855 public static final class Lifecycle extends SystemService {
856 private final ActivityTaskManagerService mService;
857
858 public Lifecycle(Context context) {
859 super(context);
860 mService = new ActivityTaskManagerService(context);
861 }
862
863 @Override
864 public void onStart() {
865 publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700866 mService.start();
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700867 }
868
869 public ActivityTaskManagerService getService() {
870 return mService;
871 }
872 }
873
874 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700875 public final int startActivity(IApplicationThread caller, String callingPackage,
876 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
877 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
878 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
879 resultWho, requestCode, startFlags, profilerInfo, bOptions,
880 UserHandle.getCallingUserId());
881 }
882
883 @Override
884 public final int startActivities(IApplicationThread caller, String callingPackage,
885 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
886 int userId) {
887 final String reason = "startActivities";
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700888 enforceNotIsolatedCaller(reason);
889 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, reason);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700890 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700891 return getActivityStartController().startActivities(caller, -1, callingPackage, intents,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100892 resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId, reason,
893 null /* originatingPendingIntent */);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700894 }
895
896 @Override
897 public int startActivityAsUser(IApplicationThread caller, String callingPackage,
898 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
899 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
900 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
901 resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
902 true /*validateIncomingUser*/);
903 }
904
905 int startActivityAsUser(IApplicationThread caller, String callingPackage,
906 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
907 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
908 boolean validateIncomingUser) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700909 enforceNotIsolatedCaller("startActivityAsUser");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700910
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700911 userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700912 Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
913
914 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700915 return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700916 .setCaller(caller)
917 .setCallingPackage(callingPackage)
918 .setResolvedType(resolvedType)
919 .setResultTo(resultTo)
920 .setResultWho(resultWho)
921 .setRequestCode(requestCode)
922 .setStartFlags(startFlags)
923 .setProfilerInfo(profilerInfo)
924 .setActivityOptions(bOptions)
925 .setMayWait(userId)
926 .execute();
927
928 }
929
930 @Override
931 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
932 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700933 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions) {
934 enforceNotIsolatedCaller("startActivityIntentSender");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700935 // Refuse possible leaked file descriptors
936 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
937 throw new IllegalArgumentException("File descriptors passed in Intent");
938 }
939
940 if (!(target instanceof PendingIntentRecord)) {
941 throw new IllegalArgumentException("Bad PendingIntent object");
942 }
943
944 PendingIntentRecord pir = (PendingIntentRecord)target;
945
946 synchronized (mGlobalLock) {
947 // If this is coming from the currently resumed activity, it is
948 // effectively saying that app switches are allowed at this point.
Andrii Kulian5f750bc2018-07-17 08:57:23 -0700949 final ActivityStack stack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700950 if (stack.mResumedActivity != null &&
951 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700952 mAppSwitchesAllowedTime = 0;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700953 }
954 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700955 return pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700956 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700957 }
958
959 @Override
960 public boolean startNextMatchingActivity(IBinder callingActivity, Intent intent,
961 Bundle bOptions) {
962 // Refuse possible leaked file descriptors
963 if (intent != null && intent.hasFileDescriptors()) {
964 throw new IllegalArgumentException("File descriptors passed in Intent");
965 }
966 SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
967
968 synchronized (mGlobalLock) {
969 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
970 if (r == null) {
971 SafeActivityOptions.abort(options);
972 return false;
973 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700974 if (!r.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700975 // The caller is not running... d'oh!
976 SafeActivityOptions.abort(options);
977 return false;
978 }
979 intent = new Intent(intent);
980 // The caller is not allowed to change the data.
981 intent.setDataAndType(r.intent.getData(), r.intent.getType());
982 // And we are resetting to find the next component...
983 intent.setComponent(null);
984
985 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
986
987 ActivityInfo aInfo = null;
988 try {
989 List<ResolveInfo> resolves =
990 AppGlobals.getPackageManager().queryIntentActivities(
991 intent, r.resolvedType,
992 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
993 UserHandle.getCallingUserId()).getList();
994
995 // Look for the original activity in the list...
996 final int N = resolves != null ? resolves.size() : 0;
997 for (int i=0; i<N; i++) {
998 ResolveInfo rInfo = resolves.get(i);
999 if (rInfo.activityInfo.packageName.equals(r.packageName)
1000 && rInfo.activityInfo.name.equals(r.info.name)) {
1001 // We found the current one... the next matching is
1002 // after it.
1003 i++;
1004 if (i<N) {
1005 aInfo = resolves.get(i).activityInfo;
1006 }
1007 if (debug) {
1008 Slog.v(TAG, "Next matching activity: found current " + r.packageName
1009 + "/" + r.info.name);
1010 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
1011 ? "null" : aInfo.packageName + "/" + aInfo.name));
1012 }
1013 break;
1014 }
1015 }
1016 } catch (RemoteException e) {
1017 }
1018
1019 if (aInfo == null) {
1020 // Nobody who is next!
1021 SafeActivityOptions.abort(options);
1022 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
1023 return false;
1024 }
1025
1026 intent.setComponent(new ComponentName(
1027 aInfo.applicationInfo.packageName, aInfo.name));
1028 intent.setFlags(intent.getFlags()&~(
1029 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
1030 Intent.FLAG_ACTIVITY_CLEAR_TOP|
1031 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
1032 FLAG_ACTIVITY_NEW_TASK));
1033
1034 // Okay now we need to start the new activity, replacing the currently running activity.
1035 // This is a little tricky because we want to start the new one as if the current one is
1036 // finished, but not finish the current one first so that there is no flicker.
1037 // And thus...
1038 final boolean wasFinishing = r.finishing;
1039 r.finishing = true;
1040
1041 // Propagate reply information over to the new activity.
1042 final ActivityRecord resultTo = r.resultTo;
1043 final String resultWho = r.resultWho;
1044 final int requestCode = r.requestCode;
1045 r.resultTo = null;
1046 if (resultTo != null) {
1047 resultTo.removeResultsLocked(r, resultWho, requestCode);
1048 }
1049
1050 final long origId = Binder.clearCallingIdentity();
1051 // TODO(b/64750076): Check if calling pid should really be -1.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001052 final int res = getActivityStartController()
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001053 .obtainStarter(intent, "startNextMatchingActivity")
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001054 .setCaller(r.app.getThread())
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001055 .setResolvedType(r.resolvedType)
1056 .setActivityInfo(aInfo)
1057 .setResultTo(resultTo != null ? resultTo.appToken : null)
1058 .setResultWho(resultWho)
1059 .setRequestCode(requestCode)
1060 .setCallingPid(-1)
1061 .setCallingUid(r.launchedFromUid)
1062 .setCallingPackage(r.launchedFromPackage)
1063 .setRealCallingPid(-1)
1064 .setRealCallingUid(r.launchedFromUid)
1065 .setActivityOptions(options)
1066 .execute();
1067 Binder.restoreCallingIdentity(origId);
1068
1069 r.finishing = wasFinishing;
1070 if (res != ActivityManager.START_SUCCESS) {
1071 return false;
1072 }
1073 return true;
1074 }
1075 }
1076
1077 @Override
1078 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
1079 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1080 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
1081 final WaitResult res = new WaitResult();
1082 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001083 enforceNotIsolatedCaller("startActivityAndWait");
1084 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
1085 userId, "startActivityAndWait");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001086 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001087 getActivityStartController().obtainStarter(intent, "startActivityAndWait")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001088 .setCaller(caller)
1089 .setCallingPackage(callingPackage)
1090 .setResolvedType(resolvedType)
1091 .setResultTo(resultTo)
1092 .setResultWho(resultWho)
1093 .setRequestCode(requestCode)
1094 .setStartFlags(startFlags)
1095 .setActivityOptions(bOptions)
1096 .setMayWait(userId)
1097 .setProfilerInfo(profilerInfo)
1098 .setWaitResult(res)
1099 .execute();
1100 }
1101 return res;
1102 }
1103
1104 @Override
1105 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
1106 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1107 int startFlags, Configuration config, Bundle bOptions, int userId) {
1108 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001109 enforceNotIsolatedCaller("startActivityWithConfig");
1110 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
1111 "startActivityWithConfig");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001112 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001113 return getActivityStartController().obtainStarter(intent, "startActivityWithConfig")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001114 .setCaller(caller)
1115 .setCallingPackage(callingPackage)
1116 .setResolvedType(resolvedType)
1117 .setResultTo(resultTo)
1118 .setResultWho(resultWho)
1119 .setRequestCode(requestCode)
1120 .setStartFlags(startFlags)
1121 .setGlobalConfiguration(config)
1122 .setActivityOptions(bOptions)
1123 .setMayWait(userId)
1124 .execute();
1125 }
1126 }
1127
1128 @Override
1129 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
1130 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1131 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
1132 int userId) {
1133
1134 // This is very dangerous -- it allows you to perform a start activity (including
1135 // permission grants) as any app that may launch one of your own activities. So
1136 // we will only allow this to be done from activities that are part of the core framework,
1137 // and then only when they are running as the system.
1138 final ActivityRecord sourceRecord;
1139 final int targetUid;
1140 final String targetPackage;
1141 final boolean isResolver;
1142 synchronized (mGlobalLock) {
1143 if (resultTo == null) {
1144 throw new SecurityException("Must be called from an activity");
1145 }
1146 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
1147 if (sourceRecord == null) {
1148 throw new SecurityException("Called with bad activity token: " + resultTo);
1149 }
1150 if (!sourceRecord.info.packageName.equals("android")) {
1151 throw new SecurityException(
1152 "Must be called from an activity that is declared in the android package");
1153 }
1154 if (sourceRecord.app == null) {
1155 throw new SecurityException("Called without a process attached to activity");
1156 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001157 if (UserHandle.getAppId(sourceRecord.app.mUid) != SYSTEM_UID) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001158 // This is still okay, as long as this activity is running under the
1159 // uid of the original calling activity.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001160 if (sourceRecord.app.mUid != sourceRecord.launchedFromUid) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001161 throw new SecurityException(
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001162 "Calling activity in uid " + sourceRecord.app.mUid
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001163 + " must be system uid or original calling uid "
1164 + sourceRecord.launchedFromUid);
1165 }
1166 }
1167 if (ignoreTargetSecurity) {
1168 if (intent.getComponent() == null) {
1169 throw new SecurityException(
1170 "Component must be specified with ignoreTargetSecurity");
1171 }
1172 if (intent.getSelector() != null) {
1173 throw new SecurityException(
1174 "Selector not allowed with ignoreTargetSecurity");
1175 }
1176 }
1177 targetUid = sourceRecord.launchedFromUid;
1178 targetPackage = sourceRecord.launchedFromPackage;
1179 isResolver = sourceRecord.isResolverOrChildActivity();
1180 }
1181
1182 if (userId == UserHandle.USER_NULL) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001183 userId = UserHandle.getUserId(sourceRecord.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001184 }
1185
1186 // TODO: Switch to user app stacks here.
1187 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001188 return getActivityStartController().obtainStarter(intent, "startActivityAsCaller")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001189 .setCallingUid(targetUid)
1190 .setCallingPackage(targetPackage)
1191 .setResolvedType(resolvedType)
1192 .setResultTo(resultTo)
1193 .setResultWho(resultWho)
1194 .setRequestCode(requestCode)
1195 .setStartFlags(startFlags)
1196 .setActivityOptions(bOptions)
1197 .setMayWait(userId)
1198 .setIgnoreTargetSecurity(ignoreTargetSecurity)
1199 .setFilterCallingUid(isResolver ? 0 /* system */ : targetUid)
1200 .execute();
1201 } catch (SecurityException e) {
1202 // XXX need to figure out how to propagate to original app.
1203 // A SecurityException here is generally actually a fault of the original
1204 // calling activity (such as a fairly granting permissions), so propagate it
1205 // back to them.
1206 /*
1207 StringBuilder msg = new StringBuilder();
1208 msg.append("While launching");
1209 msg.append(intent.toString());
1210 msg.append(": ");
1211 msg.append(e.getMessage());
1212 */
1213 throw e;
1214 }
1215 }
1216
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001217 int handleIncomingUser(int callingPid, int callingUid, int userId, String name) {
1218 return mAmInternal.handleIncomingUser(callingPid, callingUid, userId, false /* allowAll */,
1219 ALLOW_FULL_ONLY, name, null /* callerPackage */);
1220 }
1221
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001222 @Override
1223 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
1224 Intent intent, String resolvedType, IVoiceInteractionSession session,
1225 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
1226 Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001227 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001228 if (session == null || interactor == null) {
1229 throw new NullPointerException("null session or interactor");
1230 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001231 userId = handleIncomingUser(callingPid, callingUid, userId, "startVoiceActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001232 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001233 return getActivityStartController().obtainStarter(intent, "startVoiceActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001234 .setCallingUid(callingUid)
1235 .setCallingPackage(callingPackage)
1236 .setResolvedType(resolvedType)
1237 .setVoiceSession(session)
1238 .setVoiceInteractor(interactor)
1239 .setStartFlags(startFlags)
1240 .setProfilerInfo(profilerInfo)
1241 .setActivityOptions(bOptions)
1242 .setMayWait(userId)
1243 .execute();
1244 }
1245
1246 @Override
1247 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
1248 Intent intent, String resolvedType, Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001249 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
1250 userId = handleIncomingUser(callingPid, callingUid, userId, "startAssistantActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001251
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001252 return getActivityStartController().obtainStarter(intent, "startAssistantActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001253 .setCallingUid(callingUid)
1254 .setCallingPackage(callingPackage)
1255 .setResolvedType(resolvedType)
1256 .setActivityOptions(bOptions)
1257 .setMayWait(userId)
1258 .execute();
1259 }
1260
1261 @Override
1262 public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
1263 IRecentsAnimationRunner recentsAnimationRunner) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001264 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001265 final int callingPid = Binder.getCallingPid();
1266 final long origId = Binder.clearCallingIdentity();
1267 try {
1268 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07001269 final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
1270 final int recentsUid = mRecentTasks.getRecentsComponentUid();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001271
1272 // Start a new recents animation
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001273 final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
1274 getActivityStartController(), mWindowManager, callingPid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001275 anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
1276 recentsUid, assistDataReceiver);
1277 }
1278 } finally {
1279 Binder.restoreCallingIdentity(origId);
1280 }
1281 }
1282
1283 @Override
1284 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001285 enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001286 "startActivityFromRecents()");
1287
1288 final int callingPid = Binder.getCallingPid();
1289 final int callingUid = Binder.getCallingUid();
1290 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(bOptions);
1291 final long origId = Binder.clearCallingIdentity();
1292 try {
1293 synchronized (mGlobalLock) {
1294 return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
1295 safeOptions);
1296 }
1297 } finally {
1298 Binder.restoreCallingIdentity(origId);
1299 }
1300 }
1301
1302 /**
1303 * This is the internal entry point for handling Activity.finish().
1304 *
1305 * @param token The Binder token referencing the Activity we want to finish.
1306 * @param resultCode Result code, if any, from this Activity.
1307 * @param resultData Result data (Intent), if any, from this Activity.
1308 * @param finishTask Whether to finish the task associated with this Activity.
1309 *
1310 * @return Returns true if the activity successfully finished, or false if it is still running.
1311 */
1312 @Override
1313 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
1314 int finishTask) {
1315 // Refuse possible leaked file descriptors
1316 if (resultData != null && resultData.hasFileDescriptors()) {
1317 throw new IllegalArgumentException("File descriptors passed in Intent");
1318 }
1319
1320 synchronized (mGlobalLock) {
1321 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1322 if (r == null) {
1323 return true;
1324 }
1325 // Keep track of the root activity of the task before we finish it
1326 TaskRecord tr = r.getTask();
1327 ActivityRecord rootR = tr.getRootActivity();
1328 if (rootR == null) {
1329 Slog.w(TAG, "Finishing task with all activities already finished");
1330 }
1331 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
1332 // finish.
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001333 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001334 return false;
1335 }
1336
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001337 // TODO: There is a dup. of this block of code in ActivityStack.navigateUpToLocked
1338 // We should consolidate.
1339 if (mController != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001340 // Find the first activity that is not finishing.
1341 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
1342 if (next != null) {
1343 // ask watcher if this is allowed
1344 boolean resumeOK = true;
1345 try {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001346 resumeOK = mController.activityResuming(next.packageName);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001347 } catch (RemoteException e) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001348 mController = null;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001349 Watchdog.getInstance().setActivityController(null);
1350 }
1351
1352 if (!resumeOK) {
1353 Slog.i(TAG, "Not finishing activity because controller resumed");
1354 return false;
1355 }
1356 }
1357 }
1358 final long origId = Binder.clearCallingIdentity();
1359 try {
1360 boolean res;
1361 final boolean finishWithRootActivity =
1362 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
1363 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
1364 || (finishWithRootActivity && r == rootR)) {
1365 // If requested, remove the task that is associated to this activity only if it
1366 // was the root activity in the task. The result code and data is ignored
1367 // because we don't support returning them across task boundaries. Also, to
1368 // keep backwards compatibility we remove the task from recents when finishing
1369 // task with root activity.
1370 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
1371 finishWithRootActivity, "finish-activity");
1372 if (!res) {
1373 Slog.i(TAG, "Removing task failed to finish activity");
1374 }
Garfield Tan2746ab52018-07-25 12:33:01 -07001375 // Explicitly dismissing the activity so reset its relaunch flag.
Wale Ogunwale64258362018-10-16 15:13:37 -07001376 r.mRelaunchReason = RELAUNCH_REASON_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001377 } else {
1378 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
1379 resultData, "app-request", true);
1380 if (!res) {
1381 Slog.i(TAG, "Failed to finish by app-request");
1382 }
1383 }
1384 return res;
1385 } finally {
1386 Binder.restoreCallingIdentity(origId);
1387 }
1388 }
1389 }
1390
1391 @Override
1392 public boolean finishActivityAffinity(IBinder token) {
1393 synchronized (mGlobalLock) {
1394 final long origId = Binder.clearCallingIdentity();
1395 try {
1396 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1397 if (r == null) {
1398 return false;
1399 }
1400
1401 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
1402 // can finish.
1403 final TaskRecord task = r.getTask();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001404 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001405 return false;
1406 }
1407 return task.getStack().finishActivityAffinityLocked(r);
1408 } finally {
1409 Binder.restoreCallingIdentity(origId);
1410 }
1411 }
1412 }
1413
1414 @Override
1415 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
1416 final long origId = Binder.clearCallingIdentity();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001417 try {
1418 WindowProcessController proc = null;
1419 synchronized (mGlobalLock) {
1420 ActivityStack stack = ActivityRecord.getStackLocked(token);
1421 if (stack == null) {
1422 return;
1423 }
1424 final ActivityRecord r = mStackSupervisor.activityIdleInternalLocked(token,
1425 false /* fromTimeout */, false /* processPausingActivities */, config);
1426 if (r != null) {
1427 proc = r.app;
1428 }
1429 if (stopProfiling && proc != null) {
1430 proc.clearProfilerIfNeeded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001431 }
1432 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001433 } finally {
1434 Binder.restoreCallingIdentity(origId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001435 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001436 }
1437
1438 @Override
1439 public final void activityResumed(IBinder token) {
1440 final long origId = Binder.clearCallingIdentity();
1441 synchronized (mGlobalLock) {
1442 ActivityRecord.activityResumedLocked(token);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001443 mWindowManager.notifyAppResumedFinished(token);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001444 }
1445 Binder.restoreCallingIdentity(origId);
1446 }
1447
1448 @Override
1449 public final void activityPaused(IBinder token) {
1450 final long origId = Binder.clearCallingIdentity();
1451 synchronized (mGlobalLock) {
1452 ActivityStack stack = ActivityRecord.getStackLocked(token);
1453 if (stack != null) {
1454 stack.activityPausedLocked(token, false);
1455 }
1456 }
1457 Binder.restoreCallingIdentity(origId);
1458 }
1459
1460 @Override
1461 public final void activityStopped(IBinder token, Bundle icicle,
1462 PersistableBundle persistentState, CharSequence description) {
1463 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
1464
1465 // Refuse possible leaked file descriptors
1466 if (icicle != null && icicle.hasFileDescriptors()) {
1467 throw new IllegalArgumentException("File descriptors passed in Bundle");
1468 }
1469
1470 final long origId = Binder.clearCallingIdentity();
1471
1472 synchronized (mGlobalLock) {
1473 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1474 if (r != null) {
1475 r.activityStoppedLocked(icicle, persistentState, description);
1476 }
1477 }
1478
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001479 mAmInternal.trimApplications();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001480
1481 Binder.restoreCallingIdentity(origId);
1482 }
1483
1484 @Override
1485 public final void activityDestroyed(IBinder token) {
1486 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
1487 synchronized (mGlobalLock) {
1488 ActivityStack stack = ActivityRecord.getStackLocked(token);
1489 if (stack != null) {
1490 stack.activityDestroyedLocked(token, "activityDestroyed");
1491 }
1492 }
1493 }
1494
1495 @Override
1496 public final void activityRelaunched(IBinder token) {
1497 final long origId = Binder.clearCallingIdentity();
1498 synchronized (mGlobalLock) {
1499 mStackSupervisor.activityRelaunchedLocked(token);
1500 }
1501 Binder.restoreCallingIdentity(origId);
1502 }
1503
1504 public final void activitySlept(IBinder token) {
1505 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
1506
1507 final long origId = Binder.clearCallingIdentity();
1508
1509 synchronized (mGlobalLock) {
1510 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1511 if (r != null) {
1512 mStackSupervisor.activitySleptLocked(r);
1513 }
1514 }
1515
1516 Binder.restoreCallingIdentity(origId);
1517 }
1518
1519 @Override
1520 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
1521 synchronized (mGlobalLock) {
1522 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1523 if (r == null) {
1524 return;
1525 }
1526 final long origId = Binder.clearCallingIdentity();
1527 try {
1528 r.setRequestedOrientation(requestedOrientation);
1529 } finally {
1530 Binder.restoreCallingIdentity(origId);
1531 }
1532 }
1533 }
1534
1535 @Override
1536 public int getRequestedOrientation(IBinder token) {
1537 synchronized (mGlobalLock) {
1538 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1539 if (r == null) {
1540 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
1541 }
1542 return r.getRequestedOrientation();
1543 }
1544 }
1545
1546 @Override
1547 public void setImmersive(IBinder token, boolean immersive) {
1548 synchronized (mGlobalLock) {
1549 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1550 if (r == null) {
1551 throw new IllegalArgumentException();
1552 }
1553 r.immersive = immersive;
1554
1555 // update associated state if we're frontmost
Andrii Kulian52d255c2018-07-13 11:32:19 -07001556 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001557 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001558 applyUpdateLockStateLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001559 }
1560 }
1561 }
1562
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001563 void applyUpdateLockStateLocked(ActivityRecord r) {
1564 // Modifications to the UpdateLock state are done on our handler, outside
1565 // the activity manager's locks. The new state is determined based on the
1566 // state *now* of the relevant activity record. The object is passed to
1567 // the handler solely for logging detail, not to be consulted/modified.
1568 final boolean nextState = r != null && r.immersive;
1569 mH.post(() -> {
1570 if (mUpdateLock.isHeld() != nextState) {
1571 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1572 "Applying new update lock state '" + nextState + "' for " + r);
1573 if (nextState) {
1574 mUpdateLock.acquire();
1575 } else {
1576 mUpdateLock.release();
1577 }
1578 }
1579 });
1580 }
1581
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001582 @Override
1583 public boolean isImmersive(IBinder token) {
1584 synchronized (mGlobalLock) {
1585 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1586 if (r == null) {
1587 throw new IllegalArgumentException();
1588 }
1589 return r.immersive;
1590 }
1591 }
1592
1593 @Override
1594 public boolean isTopActivityImmersive() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001595 enforceNotIsolatedCaller("isTopActivityImmersive");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001596 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001597 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001598 return (r != null) ? r.immersive : false;
1599 }
1600 }
1601
1602 @Override
1603 public void overridePendingTransition(IBinder token, String packageName,
1604 int enterAnim, int exitAnim) {
1605 synchronized (mGlobalLock) {
1606 ActivityRecord self = ActivityRecord.isInStackLocked(token);
1607 if (self == null) {
1608 return;
1609 }
1610
1611 final long origId = Binder.clearCallingIdentity();
1612
1613 if (self.isState(
1614 ActivityStack.ActivityState.RESUMED, ActivityStack.ActivityState.PAUSING)) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001615 mWindowManager.overridePendingAppTransition(packageName,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001616 enterAnim, exitAnim, null);
1617 }
1618
1619 Binder.restoreCallingIdentity(origId);
1620 }
1621 }
1622
1623 @Override
1624 public int getFrontActivityScreenCompatMode() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001625 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001626 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001627 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001628 if (r == null) {
1629 return ActivityManager.COMPAT_MODE_UNKNOWN;
1630 }
Wale Ogunwale53783742018-09-16 10:21:51 -07001631 return mCompatModePackages.computeCompatModeLocked(r.info.applicationInfo);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001632 }
1633 }
1634
1635 @Override
1636 public void setFrontActivityScreenCompatMode(int mode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001637 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001638 "setFrontActivityScreenCompatMode");
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001639 ApplicationInfo ai;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001640 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001641 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001642 if (r == null) {
1643 Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity");
1644 return;
1645 }
1646 ai = r.info.applicationInfo;
Wale Ogunwale53783742018-09-16 10:21:51 -07001647 mCompatModePackages.setPackageScreenCompatModeLocked(ai, mode);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001648 }
1649 }
1650
1651 @Override
1652 public int getLaunchedFromUid(IBinder activityToken) {
1653 ActivityRecord srec;
1654 synchronized (mGlobalLock) {
1655 srec = ActivityRecord.forTokenLocked(activityToken);
1656 }
1657 if (srec == null) {
1658 return -1;
1659 }
1660 return srec.launchedFromUid;
1661 }
1662
1663 @Override
1664 public String getLaunchedFromPackage(IBinder activityToken) {
1665 ActivityRecord srec;
1666 synchronized (mGlobalLock) {
1667 srec = ActivityRecord.forTokenLocked(activityToken);
1668 }
1669 if (srec == null) {
1670 return null;
1671 }
1672 return srec.launchedFromPackage;
1673 }
1674
1675 @Override
1676 public boolean convertFromTranslucent(IBinder token) {
1677 final long origId = Binder.clearCallingIdentity();
1678 try {
1679 synchronized (mGlobalLock) {
1680 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1681 if (r == null) {
1682 return false;
1683 }
1684 final boolean translucentChanged = r.changeWindowTranslucency(true);
1685 if (translucentChanged) {
1686 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
1687 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001688 mWindowManager.setAppFullscreen(token, true);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001689 return translucentChanged;
1690 }
1691 } finally {
1692 Binder.restoreCallingIdentity(origId);
1693 }
1694 }
1695
1696 @Override
1697 public boolean convertToTranslucent(IBinder token, Bundle options) {
1698 SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
1699 final long origId = Binder.clearCallingIdentity();
1700 try {
1701 synchronized (mGlobalLock) {
1702 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1703 if (r == null) {
1704 return false;
1705 }
1706 final TaskRecord task = r.getTask();
1707 int index = task.mActivities.lastIndexOf(r);
1708 if (index > 0) {
1709 ActivityRecord under = task.mActivities.get(index - 1);
1710 under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
1711 }
1712 final boolean translucentChanged = r.changeWindowTranslucency(false);
1713 if (translucentChanged) {
1714 r.getStack().convertActivityToTranslucent(r);
1715 }
1716 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001717 mWindowManager.setAppFullscreen(token, false);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001718 return translucentChanged;
1719 }
1720 } finally {
1721 Binder.restoreCallingIdentity(origId);
1722 }
1723 }
1724
1725 @Override
1726 public void notifyActivityDrawn(IBinder token) {
1727 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
1728 synchronized (mGlobalLock) {
1729 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
1730 if (r != null) {
1731 r.getStack().notifyActivityDrawnLocked(r);
1732 }
1733 }
1734 }
1735
1736 @Override
1737 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
1738 synchronized (mGlobalLock) {
1739 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1740 if (r == null) {
1741 return;
1742 }
1743 r.reportFullyDrawnLocked(restoredFromBundle);
1744 }
1745 }
1746
1747 @Override
1748 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
1749 synchronized (mGlobalLock) {
1750 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
1751 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
1752 return stack.mDisplayId;
1753 }
1754 return DEFAULT_DISPLAY;
1755 }
1756 }
1757
1758 @Override
1759 public ActivityManager.StackInfo getFocusedStackInfo() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001760 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001761 long ident = Binder.clearCallingIdentity();
1762 try {
1763 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001764 ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001765 if (focusedStack != null) {
1766 return mStackSupervisor.getStackInfo(focusedStack.mStackId);
1767 }
1768 return null;
1769 }
1770 } finally {
1771 Binder.restoreCallingIdentity(ident);
1772 }
1773 }
1774
1775 @Override
1776 public void setFocusedStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001777 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001778 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
1779 final long callingId = Binder.clearCallingIdentity();
1780 try {
1781 synchronized (mGlobalLock) {
1782 final ActivityStack stack = mStackSupervisor.getStack(stackId);
1783 if (stack == null) {
1784 Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
1785 return;
1786 }
1787 final ActivityRecord r = stack.topRunningActivityLocked();
Louis Chang19443452018-10-09 12:10:21 +08001788 if (r != null && r.moveFocusableActivityToTop("setFocusedStack")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08001789 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001790 }
1791 }
1792 } finally {
1793 Binder.restoreCallingIdentity(callingId);
1794 }
1795 }
1796
1797 @Override
1798 public void setFocusedTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001799 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001800 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
1801 final long callingId = Binder.clearCallingIdentity();
1802 try {
1803 synchronized (mGlobalLock) {
1804 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1805 if (task == null) {
1806 return;
1807 }
1808 final ActivityRecord r = task.topRunningActivityLocked();
Louis Chang19443452018-10-09 12:10:21 +08001809 if (r != null && r.moveFocusableActivityToTop("setFocusedTask")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08001810 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001811 }
1812 }
1813 } finally {
1814 Binder.restoreCallingIdentity(callingId);
1815 }
1816 }
1817
1818 @Override
1819 public boolean removeTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001820 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001821 synchronized (mGlobalLock) {
1822 final long ident = Binder.clearCallingIdentity();
1823 try {
1824 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
1825 "remove-task");
1826 } finally {
1827 Binder.restoreCallingIdentity(ident);
1828 }
1829 }
1830 }
1831
1832 @Override
Winson Chunge6439102018-07-30 15:48:01 -07001833 public void removeAllVisibleRecentTasks() {
1834 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeAllVisibleRecentTasks()");
1835 synchronized (mGlobalLock) {
1836 final long ident = Binder.clearCallingIdentity();
1837 try {
1838 getRecentTasks().removeAllVisibleTasks();
1839 } finally {
1840 Binder.restoreCallingIdentity(ident);
1841 }
1842 }
1843 }
1844
1845 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001846 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
1847 synchronized (mGlobalLock) {
1848 final ActivityRecord srec = ActivityRecord.forTokenLocked(token);
1849 if (srec != null) {
1850 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
1851 }
1852 }
1853 return false;
1854 }
1855
1856 @Override
1857 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
1858 Intent resultData) {
1859
1860 synchronized (mGlobalLock) {
1861 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
1862 if (r != null) {
1863 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
1864 }
1865 return false;
1866 }
1867 }
1868
1869 /**
1870 * Attempts to move a task backwards in z-order (the order of activities within the task is
1871 * unchanged).
1872 *
1873 * There are several possible results of this call:
1874 * - if the task is locked, then we will show the lock toast
1875 * - if there is a task behind the provided task, then that task is made visible and resumed as
1876 * this task is moved to the back
1877 * - otherwise, if there are no other tasks in the stack:
1878 * - if this task is in the pinned stack, then we remove the stack completely, which will
1879 * have the effect of moving the task to the top or bottom of the fullscreen stack
1880 * (depending on whether it is visible)
1881 * - otherwise, we simply return home and hide this task
1882 *
1883 * @param token A reference to the activity we wish to move
1884 * @param nonRoot If false then this only works if the activity is the root
1885 * of a task; if true it will work for any activity in a task.
1886 * @return Returns true if the move completed, false if not.
1887 */
1888 @Override
1889 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001890 enforceNotIsolatedCaller("moveActivityTaskToBack");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001891 synchronized (mGlobalLock) {
1892 final long origId = Binder.clearCallingIdentity();
1893 try {
1894 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
1895 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1896 if (task != null) {
1897 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
1898 }
1899 } finally {
1900 Binder.restoreCallingIdentity(origId);
1901 }
1902 }
1903 return false;
1904 }
1905
1906 @Override
1907 public Rect getTaskBounds(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001908 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001909 long ident = Binder.clearCallingIdentity();
1910 Rect rect = new Rect();
1911 try {
1912 synchronized (mGlobalLock) {
1913 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
1914 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1915 if (task == null) {
1916 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
1917 return rect;
1918 }
1919 if (task.getStack() != null) {
1920 // Return the bounds from window manager since it will be adjusted for various
1921 // things like the presense of a docked stack for tasks that aren't resizeable.
1922 task.getWindowContainerBounds(rect);
1923 } else {
1924 // Task isn't in window manager yet since it isn't associated with a stack.
1925 // Return the persist value from activity manager
1926 if (!task.matchParentBounds()) {
1927 rect.set(task.getBounds());
1928 } else if (task.mLastNonFullscreenBounds != null) {
1929 rect.set(task.mLastNonFullscreenBounds);
1930 }
1931 }
1932 }
1933 } finally {
1934 Binder.restoreCallingIdentity(ident);
1935 }
1936 return rect;
1937 }
1938
1939 @Override
1940 public ActivityManager.TaskDescription getTaskDescription(int id) {
1941 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001942 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001943 MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
1944 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
1945 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1946 if (tr != null) {
1947 return tr.lastTaskDescription;
1948 }
1949 }
1950 return null;
1951 }
1952
1953 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001954 public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
1955 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
1956 setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
1957 toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
1958 return;
1959 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001960 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001961 synchronized (mGlobalLock) {
1962 final long ident = Binder.clearCallingIdentity();
1963 try {
1964 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1965 if (task == null) {
1966 Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
1967 return;
1968 }
1969
1970 if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
1971 + " to windowingMode=" + windowingMode + " toTop=" + toTop);
1972
1973 if (!task.isActivityTypeStandardOrUndefined()) {
1974 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
1975 + " non-standard task " + taskId + " to windowing mode="
1976 + windowingMode);
1977 }
1978
1979 final ActivityStack stack = task.getStack();
1980 if (toTop) {
1981 stack.moveToFront("setTaskWindowingMode", task);
1982 }
1983 stack.setWindowingMode(windowingMode);
1984 } finally {
1985 Binder.restoreCallingIdentity(ident);
1986 }
1987 }
1988 }
1989
1990 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001991 public String getCallingPackage(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001992 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001993 ActivityRecord r = getCallingRecordLocked(token);
1994 return r != null ? r.info.packageName : null;
1995 }
1996 }
1997
1998 @Override
1999 public ComponentName getCallingActivity(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002000 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002001 ActivityRecord r = getCallingRecordLocked(token);
2002 return r != null ? r.intent.getComponent() : null;
2003 }
2004 }
2005
2006 private ActivityRecord getCallingRecordLocked(IBinder token) {
2007 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2008 if (r == null) {
2009 return null;
2010 }
2011 return r.resultTo;
2012 }
2013
2014 @Override
2015 public void unhandledBack() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002016 mAmInternal.enforceCallingPermission(android.Manifest.permission.FORCE_BACK, "unhandledBack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002017
2018 synchronized (mGlobalLock) {
2019 final long origId = Binder.clearCallingIdentity();
2020 try {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002021 getTopDisplayFocusedStack().unhandledBackLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002022 } finally {
2023 Binder.restoreCallingIdentity(origId);
2024 }
2025 }
2026 }
2027
2028 /**
2029 * TODO: Add mController hook
2030 */
2031 @Override
2032 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002033 mAmInternal.enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002034
2035 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
2036 synchronized (mGlobalLock) {
2037 moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
2038 false /* fromRecents */);
2039 }
2040 }
2041
2042 void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
2043 boolean fromRecents) {
2044
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002045 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002046 Binder.getCallingUid(), -1, -1, "Task to front")) {
2047 SafeActivityOptions.abort(options);
2048 return;
2049 }
2050 final long origId = Binder.clearCallingIdentity();
2051 try {
2052 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2053 if (task == null) {
2054 Slog.d(TAG, "Could not find task for id: "+ taskId);
Winson Chungd0243682018-09-25 18:11:54 -07002055 SafeActivityOptions.abort(options);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002056 return;
2057 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002058 if (getLockTaskController().isLockTaskModeViolation(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002059 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
Winson Chungd0243682018-09-25 18:11:54 -07002060 SafeActivityOptions.abort(options);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002061 return;
2062 }
2063 ActivityOptions realOptions = options != null
2064 ? options.getOptions(mStackSupervisor)
2065 : null;
2066 mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
2067 false /* forceNonResizable */);
2068
2069 final ActivityRecord topActivity = task.getTopActivity();
2070 if (topActivity != null) {
2071
2072 // We are reshowing a task, use a starting window to hide the initial draw delay
2073 // so the transition can start earlier.
2074 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
2075 true /* taskSwitch */, fromRecents);
2076 }
2077 } finally {
2078 Binder.restoreCallingIdentity(origId);
2079 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002080 }
2081
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002082 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
2083 int callingPid, int callingUid, String name) {
2084 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
2085 return true;
2086 }
2087
2088 if (getRecentTasks().isCallerRecents(sourceUid)) {
2089 return true;
2090 }
2091
2092 int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
2093 if (perm == PackageManager.PERMISSION_GRANTED) {
2094 return true;
2095 }
2096 if (checkAllowAppSwitchUid(sourceUid)) {
2097 return true;
2098 }
2099
2100 // If the actual IPC caller is different from the logical source, then
2101 // also see if they are allowed to control app switches.
2102 if (callingUid != -1 && callingUid != sourceUid) {
2103 perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
2104 if (perm == PackageManager.PERMISSION_GRANTED) {
2105 return true;
2106 }
2107 if (checkAllowAppSwitchUid(callingUid)) {
2108 return true;
2109 }
2110 }
2111
2112 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
2113 return false;
2114 }
2115
2116 private boolean checkAllowAppSwitchUid(int uid) {
2117 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
2118 if (types != null) {
2119 for (int i = types.size() - 1; i >= 0; i--) {
2120 if (types.valueAt(i).intValue() == uid) {
2121 return true;
2122 }
2123 }
2124 }
2125 return false;
2126 }
2127
2128 @Override
2129 public void setActivityController(IActivityController controller, boolean imAMonkey) {
2130 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
2131 "setActivityController()");
2132 synchronized (mGlobalLock) {
2133 mController = controller;
2134 mControllerIsAMonkey = imAMonkey;
2135 Watchdog.getInstance().setActivityController(controller);
2136 }
2137 }
2138
2139 boolean isControllerAMonkey() {
2140 synchronized (mGlobalLock) {
2141 return mController != null && mControllerIsAMonkey;
2142 }
2143 }
2144
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002145 @Override
2146 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
2147 synchronized (mGlobalLock) {
2148 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
2149 }
2150 }
2151
2152 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002153 public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum) {
2154 return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
2155 }
2156
2157 @Override
2158 public List<ActivityManager.RunningTaskInfo> getFilteredTasks(int maxNum,
2159 @WindowConfiguration.ActivityType int ignoreActivityType,
2160 @WindowConfiguration.WindowingMode int ignoreWindowingMode) {
2161 final int callingUid = Binder.getCallingUid();
2162 ArrayList<ActivityManager.RunningTaskInfo> list = new ArrayList<>();
2163
2164 synchronized (mGlobalLock) {
2165 if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
2166
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002167 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002168 callingUid);
2169 mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
2170 ignoreWindowingMode, callingUid, allowed);
2171 }
2172
2173 return list;
2174 }
2175
2176 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002177 public final void finishSubActivity(IBinder token, String resultWho, int requestCode) {
2178 synchronized (mGlobalLock) {
2179 final long origId = Binder.clearCallingIdentity();
2180 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2181 if (r != null) {
2182 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
2183 }
2184 Binder.restoreCallingIdentity(origId);
2185 }
2186 }
2187
2188 @Override
2189 public boolean willActivityBeVisible(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002190 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002191 ActivityStack stack = ActivityRecord.getStackLocked(token);
2192 if (stack != null) {
2193 return stack.willActivityBeVisibleLocked(token);
2194 }
2195 return false;
2196 }
2197 }
2198
2199 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002200 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002201 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002202 synchronized (mGlobalLock) {
2203 final long ident = Binder.clearCallingIdentity();
2204 try {
2205 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2206 if (task == null) {
2207 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
2208 return;
2209 }
2210
2211 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
2212 + " to stackId=" + stackId + " toTop=" + toTop);
2213
2214 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2215 if (stack == null) {
2216 throw new IllegalStateException(
2217 "moveTaskToStack: No stack for stackId=" + stackId);
2218 }
2219 if (!stack.isActivityTypeStandardOrUndefined()) {
2220 throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
2221 + taskId + " to stack " + stackId);
2222 }
2223 if (stack.inSplitScreenPrimaryWindowingMode()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002224 mWindowManager.setDockedStackCreateState(
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002225 SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
2226 }
2227 task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
2228 "moveTaskToStack");
2229 } finally {
2230 Binder.restoreCallingIdentity(ident);
2231 }
2232 }
2233 }
2234
2235 @Override
2236 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
2237 boolean preserveWindows, boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002238 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002239
2240 final long ident = Binder.clearCallingIdentity();
2241 try {
2242 synchronized (mGlobalLock) {
2243 if (animate) {
2244 final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
2245 if (stack == null) {
2246 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2247 return;
2248 }
2249 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
2250 throw new IllegalArgumentException("Stack: " + stackId
2251 + " doesn't support animated resize.");
2252 }
2253 stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
2254 animationDuration, false /* fromFullscreen */);
2255 } else {
2256 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2257 if (stack == null) {
2258 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2259 return;
2260 }
2261 mStackSupervisor.resizeStackLocked(stack, destBounds,
2262 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
2263 preserveWindows, allowResizeInDockedMode, !DEFER_RESUME);
2264 }
2265 }
2266 } finally {
2267 Binder.restoreCallingIdentity(ident);
2268 }
2269 }
2270
2271 /**
2272 * Moves the specified task to the primary-split-screen stack.
2273 *
2274 * @param taskId Id of task to move.
2275 * @param createMode The mode the primary split screen stack should be created in if it doesn't
2276 * exist already. See
2277 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
2278 * and
2279 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
2280 * @param toTop If the task and stack should be moved to the top.
2281 * @param animate Whether we should play an animation for the moving the task.
2282 * @param initialBounds If the primary stack gets created, it will use these bounds for the
2283 * stack. Pass {@code null} to use default bounds.
2284 * @param showRecents If the recents activity should be shown on the other side of the task
2285 * going into split-screen mode.
2286 */
2287 @Override
2288 public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode,
2289 boolean toTop, boolean animate, Rect initialBounds, boolean showRecents) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002290 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002291 "setTaskWindowingModeSplitScreenPrimary()");
2292 synchronized (mGlobalLock) {
2293 final long ident = Binder.clearCallingIdentity();
2294 try {
2295 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2296 if (task == null) {
2297 Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
2298 return false;
2299 }
2300 if (DEBUG_STACK) Slog.d(TAG_STACK,
2301 "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
2302 + " to createMode=" + createMode + " toTop=" + toTop);
2303 if (!task.isActivityTypeStandardOrUndefined()) {
2304 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
2305 + " non-standard task " + taskId + " to split-screen windowing mode");
2306 }
2307
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002308 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002309 final int windowingMode = task.getWindowingMode();
2310 final ActivityStack stack = task.getStack();
2311 if (toTop) {
2312 stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
2313 }
2314 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
2315 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */);
2316 return windowingMode != task.getWindowingMode();
2317 } finally {
2318 Binder.restoreCallingIdentity(ident);
2319 }
2320 }
2321 }
2322
2323 /**
2324 * Removes stacks in the input windowing modes from the system if they are of activity type
2325 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
2326 */
2327 @Override
2328 public void removeStacksInWindowingModes(int[] windowingModes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002329 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002330 "removeStacksInWindowingModes()");
2331
2332 synchronized (mGlobalLock) {
2333 final long ident = Binder.clearCallingIdentity();
2334 try {
2335 mStackSupervisor.removeStacksInWindowingModes(windowingModes);
2336 } finally {
2337 Binder.restoreCallingIdentity(ident);
2338 }
2339 }
2340 }
2341
2342 @Override
2343 public void removeStacksWithActivityTypes(int[] activityTypes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002344 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002345 "removeStacksWithActivityTypes()");
2346
2347 synchronized (mGlobalLock) {
2348 final long ident = Binder.clearCallingIdentity();
2349 try {
2350 mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
2351 } finally {
2352 Binder.restoreCallingIdentity(ident);
2353 }
2354 }
2355 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002356
2357 @Override
2358 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
2359 int userId) {
2360 final int callingUid = Binder.getCallingUid();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002361 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, "getRecentTasks");
2362 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002363 callingUid);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002364 final boolean detailed = checkGetTasksPermission(
2365 android.Manifest.permission.GET_DETAILED_TASKS, Binder.getCallingPid(),
2366 UserHandle.getAppId(callingUid))
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002367 == PackageManager.PERMISSION_GRANTED;
2368
2369 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002370 return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002371 callingUid);
2372 }
2373 }
2374
2375 @Override
2376 public List<ActivityManager.StackInfo> getAllStackInfos() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002377 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002378 long ident = Binder.clearCallingIdentity();
2379 try {
2380 synchronized (mGlobalLock) {
2381 return mStackSupervisor.getAllStackInfosLocked();
2382 }
2383 } finally {
2384 Binder.restoreCallingIdentity(ident);
2385 }
2386 }
2387
2388 @Override
2389 public ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002390 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002391 long ident = Binder.clearCallingIdentity();
2392 try {
2393 synchronized (mGlobalLock) {
2394 return mStackSupervisor.getStackInfo(windowingMode, activityType);
2395 }
2396 } finally {
2397 Binder.restoreCallingIdentity(ident);
2398 }
2399 }
2400
2401 @Override
2402 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002403 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002404 final long callingUid = Binder.getCallingUid();
2405 final long origId = Binder.clearCallingIdentity();
2406 try {
2407 synchronized (mGlobalLock) {
2408 // Cancel the recents animation synchronously (do not hold the WM lock)
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002409 mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002410 ? REORDER_MOVE_TO_ORIGINAL_POSITION
2411 : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
2412 }
2413 } finally {
2414 Binder.restoreCallingIdentity(origId);
2415 }
2416 }
2417
2418 @Override
2419 public void startLockTaskModeByToken(IBinder token) {
2420 synchronized (mGlobalLock) {
2421 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2422 if (r == null) {
2423 return;
2424 }
2425 startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
2426 }
2427 }
2428
2429 @Override
2430 public void startSystemLockTaskMode(int taskId) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002431 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002432 // This makes inner call to look as if it was initiated by system.
2433 long ident = Binder.clearCallingIdentity();
2434 try {
2435 synchronized (mGlobalLock) {
2436 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2437
2438 // When starting lock task mode the stack must be in front and focused
2439 task.getStack().moveToFront("startSystemLockTaskMode");
2440 startLockTaskModeLocked(task, true /* isSystemCaller */);
2441 }
2442 } finally {
2443 Binder.restoreCallingIdentity(ident);
2444 }
2445 }
2446
2447 @Override
2448 public void stopLockTaskModeByToken(IBinder token) {
2449 synchronized (mGlobalLock) {
2450 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2451 if (r == null) {
2452 return;
2453 }
2454 stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
2455 }
2456 }
2457
2458 /**
2459 * This API should be called by SystemUI only when user perform certain action to dismiss
2460 * lock task mode. We should only dismiss pinned lock task mode in this case.
2461 */
2462 @Override
2463 public void stopSystemLockTaskMode() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002464 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002465 stopLockTaskModeInternal(null, true /* isSystemCaller */);
2466 }
2467
2468 private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
2469 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
2470 if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
2471 return;
2472 }
2473
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002474 final ActivityStack stack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002475 if (stack == null || task != stack.topTask()) {
2476 throw new IllegalArgumentException("Invalid task, not in foreground");
2477 }
2478
2479 // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
2480 // system or a specific app.
2481 // * System-initiated requests will only start the pinned mode (screen pinning)
2482 // * App-initiated requests
2483 // - will put the device in fully locked mode (LockTask), if the app is whitelisted
2484 // - will start the pinned mode, otherwise
2485 final int callingUid = Binder.getCallingUid();
2486 long ident = Binder.clearCallingIdentity();
2487 try {
2488 // When a task is locked, dismiss the pinned stack if it exists
2489 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2490
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002491 getLockTaskController().startLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002492 } finally {
2493 Binder.restoreCallingIdentity(ident);
2494 }
2495 }
2496
2497 private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
2498 final int callingUid = Binder.getCallingUid();
2499 long ident = Binder.clearCallingIdentity();
2500 try {
2501 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002502 getLockTaskController().stopLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002503 }
2504 // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
2505 // task and jumping straight into a call in the case of emergency call back.
2506 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
2507 if (tm != null) {
2508 tm.showInCallScreen(false);
2509 }
2510 } finally {
2511 Binder.restoreCallingIdentity(ident);
2512 }
2513 }
2514
2515 @Override
Wale Ogunwale27c48ae2018-10-25 19:01:01 -07002516 public void updateLockTaskPackages(int userId, String[] packages) {
2517 final int callingUid = Binder.getCallingUid();
2518 if (callingUid != 0 && callingUid != SYSTEM_UID) {
2519 mAmInternal.enforceCallingPermission(Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
2520 "updateLockTaskPackages()");
2521 }
2522 synchronized (this) {
2523 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":"
2524 + Arrays.toString(packages));
2525 getLockTaskController().updateLockTaskPackages(userId, packages);
2526 }
2527 }
2528
2529 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002530 public boolean isInLockTaskMode() {
2531 return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
2532 }
2533
2534 @Override
2535 public int getLockTaskModeState() {
2536 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002537 return getLockTaskController().getLockTaskModeState();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002538 }
2539 }
2540
2541 @Override
2542 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
2543 synchronized (mGlobalLock) {
2544 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2545 if (r != null) {
2546 r.setTaskDescription(td);
2547 final TaskRecord task = r.getTask();
2548 task.updateTaskDescription();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002549 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002550 }
2551 }
2552 }
2553
2554 @Override
2555 public Bundle getActivityOptions(IBinder token) {
2556 final long origId = Binder.clearCallingIdentity();
2557 try {
2558 synchronized (mGlobalLock) {
2559 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
2560 if (r != null) {
2561 final ActivityOptions activityOptions = r.takeOptionsLocked();
2562 return activityOptions == null ? null : activityOptions.toBundle();
2563 }
2564 return null;
2565 }
2566 } finally {
2567 Binder.restoreCallingIdentity(origId);
2568 }
2569 }
2570
2571 @Override
2572 public List<IBinder> getAppTasks(String callingPackage) {
2573 int callingUid = Binder.getCallingUid();
2574 long ident = Binder.clearCallingIdentity();
2575 try {
2576 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002577 return mRecentTasks.getAppTasksList(callingUid, callingPackage);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002578 }
2579 } finally {
2580 Binder.restoreCallingIdentity(ident);
2581 }
2582 }
2583
2584 @Override
2585 public void finishVoiceTask(IVoiceInteractionSession session) {
2586 synchronized (mGlobalLock) {
2587 final long origId = Binder.clearCallingIdentity();
2588 try {
2589 // TODO: VI Consider treating local voice interactions and voice tasks
2590 // differently here
2591 mStackSupervisor.finishVoiceTask(session);
2592 } finally {
2593 Binder.restoreCallingIdentity(origId);
2594 }
2595 }
2596
2597 }
2598
2599 @Override
2600 public boolean isTopOfTask(IBinder token) {
2601 synchronized (mGlobalLock) {
2602 ActivityRecord r = ActivityRecord.isInStackLocked(token);
Riddle Hsu66b74a82018-07-26 00:20:12 +08002603 return r != null && r.getTask().getTopActivity() == r;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002604 }
2605 }
2606
2607 @Override
2608 public void notifyLaunchTaskBehindComplete(IBinder token) {
2609 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
2610 }
2611
2612 @Override
2613 public void notifyEnterAnimationComplete(IBinder token) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002614 mH.post(() -> {
2615 synchronized (mGlobalLock) {
2616 ActivityRecord r = ActivityRecord.forTokenLocked(token);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002617 if (r != null && r.attachedToProcess()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002618 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002619 r.app.getThread().scheduleEnterAnimationComplete(r.appToken);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002620 } catch (RemoteException e) {
2621 }
2622 }
2623 }
2624
2625 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002626 }
2627
2628 /** Called from an app when assist data is ready. */
2629 @Override
2630 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
2631 AssistContent content, Uri referrer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002632 PendingAssistExtras pae = (PendingAssistExtras) token;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002633 synchronized (pae) {
2634 pae.result = extras;
2635 pae.structure = structure;
2636 pae.content = content;
2637 if (referrer != null) {
2638 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
2639 }
2640 if (structure != null) {
2641 structure.setHomeActivity(pae.isHome);
2642 }
2643 pae.haveResult = true;
2644 pae.notifyAll();
2645 if (pae.intent == null && pae.receiver == null) {
2646 // Caller is just waiting for the result.
2647 return;
2648 }
2649 }
2650 // We are now ready to launch the assist activity.
2651 IAssistDataReceiver sendReceiver = null;
2652 Bundle sendBundle = null;
2653 synchronized (mGlobalLock) {
2654 buildAssistBundleLocked(pae, extras);
2655 boolean exists = mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002656 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002657 if (!exists) {
2658 // Timed out.
2659 return;
2660 }
2661
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002662 if ((sendReceiver = pae.receiver) != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002663 // Caller wants result sent back to them.
2664 sendBundle = new Bundle();
2665 sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
2666 sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
2667 sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
2668 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
2669 }
2670 }
2671 if (sendReceiver != null) {
2672 try {
2673 sendReceiver.onHandleAssistData(sendBundle);
2674 } catch (RemoteException e) {
2675 }
2676 return;
2677 }
2678
2679 final long ident = Binder.clearCallingIdentity();
2680 try {
2681 if (TextUtils.equals(pae.intent.getAction(),
2682 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
2683 pae.intent.putExtras(pae.extras);
2684 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
2685 } else {
2686 pae.intent.replaceExtras(pae.extras);
2687 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
2688 | Intent.FLAG_ACTIVITY_SINGLE_TOP
2689 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Wale Ogunwale31913b52018-10-13 08:29:31 -07002690 mInternal.closeSystemDialogs("assist");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002691
2692 try {
2693 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
2694 } catch (ActivityNotFoundException e) {
2695 Slog.w(TAG, "No activity to handle assist action.", e);
2696 }
2697 }
2698 } finally {
2699 Binder.restoreCallingIdentity(ident);
2700 }
2701 }
2702
2703 @Override
2704 public int addAppTask(IBinder activityToken, Intent intent,
2705 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
2706 final int callingUid = Binder.getCallingUid();
2707 final long callingIdent = Binder.clearCallingIdentity();
2708
2709 try {
2710 synchronized (mGlobalLock) {
2711 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
2712 if (r == null) {
2713 throw new IllegalArgumentException("Activity does not exist; token="
2714 + activityToken);
2715 }
2716 ComponentName comp = intent.getComponent();
2717 if (comp == null) {
2718 throw new IllegalArgumentException("Intent " + intent
2719 + " must specify explicit component");
2720 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002721 if (thumbnail.getWidth() != mThumbnailWidth
2722 || thumbnail.getHeight() != mThumbnailHeight) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002723 throw new IllegalArgumentException("Bad thumbnail size: got "
2724 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002725 + mThumbnailWidth + "x" + mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002726 }
2727 if (intent.getSelector() != null) {
2728 intent.setSelector(null);
2729 }
2730 if (intent.getSourceBounds() != null) {
2731 intent.setSourceBounds(null);
2732 }
2733 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
2734 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
2735 // The caller has added this as an auto-remove task... that makes no
2736 // sense, so turn off auto-remove.
2737 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
2738 }
2739 }
2740 final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
2741 STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
2742 if (ainfo.applicationInfo.uid != callingUid) {
2743 throw new SecurityException(
2744 "Can't add task for another application: target uid="
2745 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
2746 }
2747
2748 final ActivityStack stack = r.getStack();
2749 final TaskRecord task = stack.createTaskRecord(
2750 mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent,
2751 null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002752 if (!mRecentTasks.addToBottom(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002753 // The app has too many tasks already and we can't add any more
2754 stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
2755 return INVALID_TASK_ID;
2756 }
2757 task.lastTaskDescription.copyFrom(description);
2758
2759 // TODO: Send the thumbnail to WM to store it.
2760
2761 return task.taskId;
2762 }
2763 } finally {
2764 Binder.restoreCallingIdentity(callingIdent);
2765 }
2766 }
2767
2768 @Override
2769 public Point getAppTaskThumbnailSize() {
2770 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002771 return new Point(mThumbnailWidth, mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002772 }
2773 }
2774
2775 @Override
2776 public void setTaskResizeable(int taskId, int resizeableMode) {
2777 synchronized (mGlobalLock) {
2778 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
2779 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
2780 if (task == null) {
2781 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
2782 return;
2783 }
2784 task.setResizeMode(resizeableMode);
2785 }
2786 }
2787
2788 @Override
2789 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002790 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002791 long ident = Binder.clearCallingIdentity();
2792 try {
2793 synchronized (mGlobalLock) {
2794 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2795 if (task == null) {
2796 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
2797 return;
2798 }
2799 // Place the task in the right stack if it isn't there already based on
2800 // the requested bounds.
2801 // The stack transition logic is:
2802 // - a null bounds on a freeform task moves that task to fullscreen
2803 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
2804 // that task to freeform
2805 // - otherwise the task is not moved
2806 ActivityStack stack = task.getStack();
2807 if (!task.getWindowConfiguration().canResizeTask()) {
2808 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
2809 }
2810 if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
2811 stack = stack.getDisplay().getOrCreateStack(
2812 WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
2813 } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
2814 stack = stack.getDisplay().getOrCreateStack(
2815 WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
2816 }
2817
2818 // Reparent the task to the right stack if necessary
2819 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
2820 if (stack != task.getStack()) {
2821 // Defer resume until the task is resized below
2822 task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
2823 DEFER_RESUME, "resizeTask");
2824 preserveWindow = false;
2825 }
2826
2827 // After reparenting (which only resizes the task to the stack bounds), resize the
2828 // task to the actual bounds provided
2829 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
2830 }
2831 } finally {
2832 Binder.restoreCallingIdentity(ident);
2833 }
2834 }
2835
2836 @Override
2837 public boolean releaseActivityInstance(IBinder token) {
2838 synchronized (mGlobalLock) {
2839 final long origId = Binder.clearCallingIdentity();
2840 try {
2841 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2842 if (r == null) {
2843 return false;
2844 }
2845 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
2846 } finally {
2847 Binder.restoreCallingIdentity(origId);
2848 }
2849 }
2850 }
2851
2852 @Override
2853 public void releaseSomeActivities(IApplicationThread appInt) {
2854 synchronized (mGlobalLock) {
2855 final long origId = Binder.clearCallingIdentity();
2856 try {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07002857 final WindowProcessController app = getProcessController(appInt);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002858 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
2859 } finally {
2860 Binder.restoreCallingIdentity(origId);
2861 }
2862 }
2863 }
2864
2865 @Override
2866 public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
2867 int secondaryDisplayShowing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002868 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002869 != PackageManager.PERMISSION_GRANTED) {
2870 throw new SecurityException("Requires permission "
2871 + android.Manifest.permission.DEVICE_POWER);
2872 }
2873
2874 synchronized (mGlobalLock) {
2875 long ident = Binder.clearCallingIdentity();
2876 if (mKeyguardShown != keyguardShowing) {
2877 mKeyguardShown = keyguardShowing;
Wale Ogunwale342fbe92018-10-09 08:44:10 -07002878 final Message msg = PooledLambda.obtainMessage(
2879 ActivityManagerInternal::reportCurKeyguardUsageEvent, mAmInternal,
2880 keyguardShowing);
2881 mH.sendMessage(msg);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002882 }
2883 try {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002884 mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002885 secondaryDisplayShowing);
2886 } finally {
2887 Binder.restoreCallingIdentity(ident);
2888 }
2889 }
2890
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002891 mH.post(() -> {
2892 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2893 mScreenObservers.get(i).onKeyguardStateChanged(keyguardShowing);
2894 }
2895 });
2896 }
2897
2898 void onScreenAwakeChanged(boolean isAwake) {
2899 mH.post(() -> {
2900 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2901 mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2902 }
2903 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002904 }
2905
2906 @Override
2907 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002908 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
2909 userId, "getTaskDescriptionIcon");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002910
2911 final File passedIconFile = new File(filePath);
2912 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
2913 passedIconFile.getName());
2914 if (!legitIconFile.getPath().equals(filePath)
2915 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
2916 throw new IllegalArgumentException("Bad file path: " + filePath
2917 + " passed for userId " + userId);
2918 }
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002919 return mRecentTasks.getTaskDescriptionIcon(filePath);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002920 }
2921
2922 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002923 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002924 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
2925 final ActivityOptions activityOptions = safeOptions != null
2926 ? safeOptions.getOptions(mStackSupervisor)
2927 : null;
2928 if (activityOptions == null
2929 || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
2930 || activityOptions.getCustomInPlaceResId() == 0) {
2931 throw new IllegalArgumentException("Expected in-place ActivityOption " +
2932 "with valid animation");
2933 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002934 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
2935 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002936 activityOptions.getCustomInPlaceResId());
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002937 mWindowManager.executeAppTransition();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002938 }
2939
2940 @Override
2941 public void removeStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002942 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002943 synchronized (mGlobalLock) {
2944 final long ident = Binder.clearCallingIdentity();
2945 try {
2946 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2947 if (stack == null) {
2948 Slog.w(TAG, "removeStack: No stack with id=" + stackId);
2949 return;
2950 }
2951 if (!stack.isActivityTypeStandardOrUndefined()) {
2952 throw new IllegalArgumentException(
2953 "Removing non-standard stack is not allowed.");
2954 }
2955 mStackSupervisor.removeStack(stack);
2956 } finally {
2957 Binder.restoreCallingIdentity(ident);
2958 }
2959 }
2960 }
2961
2962 @Override
2963 public void moveStackToDisplay(int stackId, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002964 mAmInternal.enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002965
2966 synchronized (mGlobalLock) {
2967 final long ident = Binder.clearCallingIdentity();
2968 try {
2969 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
2970 + " to displayId=" + displayId);
2971 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
2972 } finally {
2973 Binder.restoreCallingIdentity(ident);
2974 }
2975 }
2976 }
2977
2978 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002979 public void exitFreeformMode(IBinder token) {
2980 synchronized (mGlobalLock) {
2981 long ident = Binder.clearCallingIdentity();
2982 try {
2983 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2984 if (r == null) {
2985 throw new IllegalArgumentException(
2986 "exitFreeformMode: No activity record matching token=" + token);
2987 }
2988
2989 final ActivityStack stack = r.getStack();
2990 if (stack == null || !stack.inFreeformWindowingMode()) {
2991 throw new IllegalStateException(
2992 "exitFreeformMode: You can only go fullscreen from freeform.");
2993 }
2994
2995 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
2996 } finally {
2997 Binder.restoreCallingIdentity(ident);
2998 }
2999 }
3000 }
3001
3002 /** Sets the task stack listener that gets callbacks when a task stack changes. */
3003 @Override
3004 public void registerTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003005 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003006 "registerTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003007 mTaskChangeNotificationController.registerTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003008 }
3009
3010 /** Unregister a task stack listener so that it stops receiving callbacks. */
3011 @Override
3012 public void unregisterTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003013 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003014 "unregisterTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003015 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003016 }
3017
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003018 @Override
3019 public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
3020 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
3021 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
3022 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
3023 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
3024 }
3025
3026 @Override
3027 public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
3028 IBinder activityToken, int flags) {
3029 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
3030 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
3031 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
3032 }
3033
3034 @Override
3035 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
3036 Bundle args) {
3037 return enqueueAssistContext(requestType, intent, hint, null, null, null,
3038 true /* focused */, true /* newSessionId */, userHandle, args,
3039 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
3040 }
3041
3042 @Override
3043 public Bundle getAssistContextExtras(int requestType) {
3044 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
3045 null, null, true /* focused */, true /* newSessionId */,
3046 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
3047 if (pae == null) {
3048 return null;
3049 }
3050 synchronized (pae) {
3051 while (!pae.haveResult) {
3052 try {
3053 pae.wait();
3054 } catch (InterruptedException e) {
3055 }
3056 }
3057 }
3058 synchronized (mGlobalLock) {
3059 buildAssistBundleLocked(pae, pae.result);
3060 mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003061 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003062 }
3063 return pae.extras;
3064 }
3065
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003066 /**
3067 * Binder IPC calls go through the public entry point.
3068 * This can be called with or without the global lock held.
3069 */
3070 private static int checkCallingPermission(String permission) {
3071 return checkPermission(
3072 permission, Binder.getCallingPid(), UserHandle.getAppId(Binder.getCallingUid()));
3073 }
3074
3075 /** This can be called with or without the global lock held. */
Wale Ogunwale214f3482018-10-04 11:00:47 -07003076 private void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003077 if (!getRecentTasks().isCallerRecents(Binder.getCallingUid())) {
3078 mAmInternal.enforceCallingPermission(permission, func);
3079 }
3080 }
3081
3082 @VisibleForTesting
3083 int checkGetTasksPermission(String permission, int pid, int uid) {
3084 return checkPermission(permission, pid, uid);
3085 }
3086
3087 static int checkPermission(String permission, int pid, int uid) {
3088 if (permission == null) {
3089 return PackageManager.PERMISSION_DENIED;
3090 }
3091 return checkComponentPermission(permission, pid, uid, -1, true);
3092 }
3093
Wale Ogunwale214f3482018-10-04 11:00:47 -07003094 public static int checkComponentPermission(String permission, int pid, int uid,
3095 int owningUid, boolean exported) {
3096 return ActivityManagerService.checkComponentPermission(
3097 permission, pid, uid, owningUid, exported);
3098 }
3099
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003100 boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
3101 if (getRecentTasks().isCallerRecents(callingUid)) {
3102 // Always allow the recents component to get tasks
3103 return true;
3104 }
3105
3106 boolean allowed = checkGetTasksPermission(android.Manifest.permission.REAL_GET_TASKS,
3107 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
3108 if (!allowed) {
3109 if (checkGetTasksPermission(android.Manifest.permission.GET_TASKS,
3110 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
3111 // Temporary compatibility: some existing apps on the system image may
3112 // still be requesting the old permission and not switched to the new
3113 // one; if so, we'll still allow them full access. This means we need
3114 // to see if they are holding the old permission and are a system app.
3115 try {
3116 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
3117 allowed = true;
3118 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
3119 + " is using old GET_TASKS but privileged; allowing");
3120 }
3121 } catch (RemoteException e) {
3122 }
3123 }
3124 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
3125 + " does not hold REAL_GET_TASKS; limiting output");
3126 }
3127 return allowed;
3128 }
3129
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003130 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
3131 IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
3132 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
3133 int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003134 mAmInternal.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003135 "enqueueAssistContext()");
3136
3137 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003138 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003139 if (activity == null) {
3140 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
3141 return null;
3142 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003143 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003144 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
3145 return null;
3146 }
3147 if (focused) {
3148 if (activityToken != null) {
3149 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
3150 if (activity != caller) {
3151 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
3152 + " is not current top " + activity);
3153 return null;
3154 }
3155 }
3156 } else {
3157 activity = ActivityRecord.forTokenLocked(activityToken);
3158 if (activity == null) {
3159 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
3160 + " couldn't be found");
3161 return null;
3162 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003163 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003164 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
3165 return null;
3166 }
3167 }
3168
3169 PendingAssistExtras pae;
3170 Bundle extras = new Bundle();
3171 if (args != null) {
3172 extras.putAll(args);
3173 }
3174 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003175 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003176
3177 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
3178 userHandle);
3179 pae.isHome = activity.isActivityTypeHome();
3180
3181 // Increment the sessionId if necessary
3182 if (newSessionId) {
3183 mViSessionId++;
3184 }
3185 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003186 activity.app.getThread().requestAssistContextExtras(activity.appToken, pae,
3187 requestType, mViSessionId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003188 mPendingAssistExtras.add(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003189 mUiHandler.postDelayed(pae, timeout);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003190 } catch (RemoteException e) {
3191 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
3192 return null;
3193 }
3194 return pae;
3195 }
3196 }
3197
3198 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
3199 if (result != null) {
3200 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
3201 }
3202 if (pae.hint != null) {
3203 pae.extras.putBoolean(pae.hint, true);
3204 }
3205 }
3206
3207 private void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
3208 IAssistDataReceiver receiver;
3209 synchronized (mGlobalLock) {
3210 mPendingAssistExtras.remove(pae);
3211 receiver = pae.receiver;
3212 }
3213 if (receiver != null) {
3214 // Caller wants result sent back to them.
3215 Bundle sendBundle = new Bundle();
3216 // At least return the receiver extras
3217 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
3218 try {
3219 pae.receiver.onHandleAssistData(sendBundle);
3220 } catch (RemoteException e) {
3221 }
3222 }
3223 }
3224
3225 public class PendingAssistExtras extends Binder implements Runnable {
3226 public final ActivityRecord activity;
3227 public boolean isHome;
3228 public final Bundle extras;
3229 public final Intent intent;
3230 public final String hint;
3231 public final IAssistDataReceiver receiver;
3232 public final int userHandle;
3233 public boolean haveResult = false;
3234 public Bundle result = null;
3235 public AssistStructure structure = null;
3236 public AssistContent content = null;
3237 public Bundle receiverExtras;
3238
3239 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
3240 String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
3241 int _userHandle) {
3242 activity = _activity;
3243 extras = _extras;
3244 intent = _intent;
3245 hint = _hint;
3246 receiver = _receiver;
3247 receiverExtras = _receiverExtras;
3248 userHandle = _userHandle;
3249 }
3250
3251 @Override
3252 public void run() {
3253 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
3254 synchronized (this) {
3255 haveResult = true;
3256 notifyAll();
3257 }
3258 pendingAssistExtrasTimedOut(this);
3259 }
3260 }
3261
3262 @Override
3263 public boolean isAssistDataAllowedOnCurrentActivity() {
3264 int userId;
3265 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003266 final ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003267 if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
3268 return false;
3269 }
3270
3271 final ActivityRecord activity = focusedStack.getTopActivity();
3272 if (activity == null) {
3273 return false;
3274 }
3275 userId = activity.userId;
3276 }
3277 return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
3278 }
3279
3280 @Override
3281 public boolean showAssistFromActivity(IBinder token, Bundle args) {
3282 long ident = Binder.clearCallingIdentity();
3283 try {
3284 synchronized (mGlobalLock) {
3285 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003286 ActivityRecord top = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003287 if (top != caller) {
3288 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3289 + " is not current top " + top);
3290 return false;
3291 }
3292 if (!top.nowVisible) {
3293 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3294 + " is not visible");
3295 return false;
3296 }
3297 }
3298 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
3299 token);
3300 } finally {
3301 Binder.restoreCallingIdentity(ident);
3302 }
3303 }
3304
3305 @Override
3306 public boolean isRootVoiceInteraction(IBinder token) {
3307 synchronized (mGlobalLock) {
3308 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3309 if (r == null) {
3310 return false;
3311 }
3312 return r.rootVoiceInteraction;
3313 }
3314 }
3315
Wale Ogunwalef6733932018-06-27 05:14:34 -07003316 private void onLocalVoiceInteractionStartedLocked(IBinder activity,
3317 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
3318 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
3319 if (activityToCallback == null) return;
3320 activityToCallback.setVoiceSessionLocked(voiceSession);
3321
3322 // Inform the activity
3323 try {
3324 activityToCallback.app.getThread().scheduleLocalVoiceInteractionStarted(activity,
3325 voiceInteractor);
3326 long token = Binder.clearCallingIdentity();
3327 try {
3328 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
3329 } finally {
3330 Binder.restoreCallingIdentity(token);
3331 }
3332 // TODO: VI Should we cache the activity so that it's easier to find later
3333 // rather than scan through all the stacks and activities?
3334 } catch (RemoteException re) {
3335 activityToCallback.clearVoiceSessionLocked();
3336 // TODO: VI Should this terminate the voice session?
3337 }
3338 }
3339
3340 private void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
3341 Slog.d(TAG, "<<< startRunningVoiceLocked()");
3342 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
3343 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
3344 boolean wasRunningVoice = mRunningVoice != null;
3345 mRunningVoice = session;
3346 if (!wasRunningVoice) {
3347 mVoiceWakeLock.acquire();
3348 updateSleepIfNeededLocked();
3349 }
3350 }
3351 }
3352
3353 void finishRunningVoiceLocked() {
3354 if (mRunningVoice != null) {
3355 mRunningVoice = null;
3356 mVoiceWakeLock.release();
3357 updateSleepIfNeededLocked();
3358 }
3359 }
3360
3361 @Override
3362 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3363 synchronized (mGlobalLock) {
3364 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3365 if (keepAwake) {
3366 mVoiceWakeLock.acquire();
3367 } else {
3368 mVoiceWakeLock.release();
3369 }
3370 }
3371 }
3372 }
3373
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003374 @Override
3375 public ComponentName getActivityClassForToken(IBinder token) {
3376 synchronized (mGlobalLock) {
3377 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3378 if (r == null) {
3379 return null;
3380 }
3381 return r.intent.getComponent();
3382 }
3383 }
3384
3385 @Override
3386 public String getPackageForToken(IBinder token) {
3387 synchronized (mGlobalLock) {
3388 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3389 if (r == null) {
3390 return null;
3391 }
3392 return r.packageName;
3393 }
3394 }
3395
3396 @Override
3397 public void showLockTaskEscapeMessage(IBinder token) {
3398 synchronized (mGlobalLock) {
3399 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3400 if (r == null) {
3401 return;
3402 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003403 getLockTaskController().showLockTaskToast();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003404 }
3405 }
3406
3407 @Override
3408 public void keyguardGoingAway(int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003409 enforceNotIsolatedCaller("keyguardGoingAway");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003410 final long token = Binder.clearCallingIdentity();
3411 try {
3412 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003413 mKeyguardController.keyguardGoingAway(flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003414 }
3415 } finally {
3416 Binder.restoreCallingIdentity(token);
3417 }
3418 }
3419
3420 /**
3421 * Try to place task to provided position. The final position might be different depending on
3422 * current user and stacks state. The task will be moved to target stack if it's currently in
3423 * different stack.
3424 */
3425 @Override
3426 public void positionTaskInStack(int taskId, int stackId, int position) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003427 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003428 synchronized (mGlobalLock) {
3429 long ident = Binder.clearCallingIdentity();
3430 try {
3431 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
3432 + taskId + " in stackId=" + stackId + " at position=" + position);
3433 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3434 if (task == null) {
3435 throw new IllegalArgumentException("positionTaskInStack: no task for id="
3436 + taskId);
3437 }
3438
3439 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3440
3441 if (stack == null) {
3442 throw new IllegalArgumentException("positionTaskInStack: no stack for id="
3443 + stackId);
3444 }
3445 if (!stack.isActivityTypeStandardOrUndefined()) {
3446 throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
3447 + " the position of task " + taskId + " in/to non-standard stack");
3448 }
3449
3450 // TODO: Have the callers of this API call a separate reparent method if that is
3451 // what they intended to do vs. having this method also do reparenting.
3452 if (task.getStack() == stack) {
3453 // Change position in current stack.
3454 stack.positionChildAt(task, position);
3455 } else {
3456 // Reparent to new stack.
3457 task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
3458 !DEFER_RESUME, "positionTaskInStack");
3459 }
3460 } finally {
3461 Binder.restoreCallingIdentity(ident);
3462 }
3463 }
3464 }
3465
3466 @Override
3467 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
3468 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
3469 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
3470 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
3471 synchronized (mGlobalLock) {
3472 ActivityRecord record = ActivityRecord.isInStackLocked(token);
3473 if (record == null) {
3474 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
3475 + "found for: " + token);
3476 }
3477 record.setSizeConfigurations(horizontalSizeConfiguration,
3478 verticalSizeConfigurations, smallestSizeConfigurations);
3479 }
3480 }
3481
3482 /**
3483 * Dismisses split-screen multi-window mode.
3484 * @param toTop If true the current primary split-screen stack will be placed or left on top.
3485 */
3486 @Override
3487 public void dismissSplitScreenMode(boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003488 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003489 MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
3490 final long ident = Binder.clearCallingIdentity();
3491 try {
3492 synchronized (mGlobalLock) {
3493 final ActivityStack stack =
3494 mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
3495 if (stack == null) {
3496 Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
3497 return;
3498 }
3499
3500 if (toTop) {
3501 // Caller wants the current split-screen primary stack to be the top stack after
3502 // it goes fullscreen, so move it to the front.
3503 stack.moveToFront("dismissSplitScreenMode");
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003504 } else if (mStackSupervisor.isTopDisplayFocusedStack(stack)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003505 // In this case the current split-screen primary stack shouldn't be the top
3506 // stack after it goes fullscreen, but it current has focus, so we move the
3507 // focus to the top-most split-screen secondary stack next to it.
3508 final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
3509 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
3510 if (otherStack != null) {
3511 otherStack.moveToFront("dismissSplitScreenMode_other");
3512 }
3513 }
3514
Evan Rosky10475742018-09-05 19:02:48 -07003515 stack.setWindowingMode(WINDOWING_MODE_UNDEFINED);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003516 }
3517 } finally {
3518 Binder.restoreCallingIdentity(ident);
3519 }
3520 }
3521
3522 /**
3523 * Dismisses Pip
3524 * @param animate True if the dismissal should be animated.
3525 * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
3526 * default animation duration should be used.
3527 */
3528 @Override
3529 public void dismissPip(boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003530 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003531 final long ident = Binder.clearCallingIdentity();
3532 try {
3533 synchronized (mGlobalLock) {
3534 final PinnedActivityStack stack =
3535 mStackSupervisor.getDefaultDisplay().getPinnedStack();
3536 if (stack == null) {
3537 Slog.w(TAG, "dismissPip: pinned stack not found.");
3538 return;
3539 }
3540 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
3541 throw new IllegalArgumentException("Stack: " + stack
3542 + " doesn't support animated resize.");
3543 }
3544 if (animate) {
3545 stack.animateResizePinnedStack(null /* sourceHintBounds */,
3546 null /* destBounds */, animationDuration, false /* fromFullscreen */);
3547 } else {
3548 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
3549 }
3550 }
3551 } finally {
3552 Binder.restoreCallingIdentity(ident);
3553 }
3554 }
3555
3556 @Override
3557 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003558 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003559 synchronized (mGlobalLock) {
3560 mSuppressResizeConfigChanges = suppress;
3561 }
3562 }
3563
3564 /**
3565 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
3566 * animated the stack to the fullscreen, but can also be called if we are relaunching an
3567 * activity and clearing the task at the same time.
3568 */
3569 @Override
3570 // TODO: API should just be about changing windowing modes...
3571 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003572 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003573 "moveTasksToFullscreenStack()");
3574 synchronized (mGlobalLock) {
3575 final long origId = Binder.clearCallingIdentity();
3576 try {
3577 final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
3578 if (stack != null){
3579 if (!stack.isActivityTypeStandardOrUndefined()) {
3580 throw new IllegalArgumentException(
3581 "You can't move tasks from non-standard stacks.");
3582 }
3583 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
3584 }
3585 } finally {
3586 Binder.restoreCallingIdentity(origId);
3587 }
3588 }
3589 }
3590
3591 /**
3592 * Moves the top activity in the input stackId to the pinned stack.
3593 *
3594 * @param stackId Id of stack to move the top activity to pinned stack.
3595 * @param bounds Bounds to use for pinned stack.
3596 *
3597 * @return True if the top activity of the input stack was successfully moved to the pinned
3598 * stack.
3599 */
3600 @Override
3601 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003602 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003603 "moveTopActivityToPinnedStack()");
3604 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003605 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003606 throw new IllegalStateException("moveTopActivityToPinnedStack:"
3607 + "Device doesn't support picture-in-picture mode");
3608 }
3609
3610 long ident = Binder.clearCallingIdentity();
3611 try {
3612 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
3613 } finally {
3614 Binder.restoreCallingIdentity(ident);
3615 }
3616 }
3617 }
3618
3619 @Override
3620 public boolean isInMultiWindowMode(IBinder token) {
3621 final long origId = Binder.clearCallingIdentity();
3622 try {
3623 synchronized (mGlobalLock) {
3624 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3625 if (r == null) {
3626 return false;
3627 }
3628 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
3629 return r.inMultiWindowMode();
3630 }
3631 } finally {
3632 Binder.restoreCallingIdentity(origId);
3633 }
3634 }
3635
3636 @Override
3637 public boolean isInPictureInPictureMode(IBinder token) {
3638 final long origId = Binder.clearCallingIdentity();
3639 try {
3640 synchronized (mGlobalLock) {
3641 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
3642 }
3643 } finally {
3644 Binder.restoreCallingIdentity(origId);
3645 }
3646 }
3647
3648 private boolean isInPictureInPictureMode(ActivityRecord r) {
3649 if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
3650 || r.getStack().isInStackLocked(r) == null) {
3651 return false;
3652 }
3653
3654 // If we are animating to fullscreen then we have already dispatched the PIP mode
3655 // changed, so we should reflect that check here as well.
3656 final PinnedActivityStack stack = r.getStack();
3657 final PinnedStackWindowController windowController = stack.getWindowContainerController();
3658 return !windowController.isAnimatingBoundsToFullscreen();
3659 }
3660
3661 @Override
3662 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
3663 final long origId = Binder.clearCallingIdentity();
3664 try {
3665 synchronized (mGlobalLock) {
3666 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3667 "enterPictureInPictureMode", token, params);
3668
3669 // If the activity is already in picture in picture mode, then just return early
3670 if (isInPictureInPictureMode(r)) {
3671 return true;
3672 }
3673
3674 // Activity supports picture-in-picture, now check that we can enter PiP at this
3675 // point, if it is
3676 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
3677 false /* beforeStopping */)) {
3678 return false;
3679 }
3680
3681 final Runnable enterPipRunnable = () -> {
Wale Ogunwalef276a6f2018-06-15 08:26:07 -07003682 synchronized (mGlobalLock) {
3683 // Only update the saved args from the args that are set
3684 r.pictureInPictureArgs.copyOnlySet(params);
3685 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
3686 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
3687 // Adjust the source bounds by the insets for the transition down
3688 final Rect sourceBounds = new Rect(
3689 r.pictureInPictureArgs.getSourceRectHint());
3690 mStackSupervisor.moveActivityToPinnedStackLocked(
3691 r, sourceBounds, aspectRatio, "enterPictureInPictureMode");
3692 final PinnedActivityStack stack = r.getStack();
3693 stack.setPictureInPictureAspectRatio(aspectRatio);
3694 stack.setPictureInPictureActions(actions);
3695 MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
3696 r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
3697 logPictureInPictureArgs(params);
3698 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003699 };
3700
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003701 if (isKeyguardLocked()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003702 // If the keyguard is showing or occluded, then try and dismiss it before
3703 // entering picture-in-picture (this will prompt the user to authenticate if the
3704 // device is currently locked).
3705 dismissKeyguard(token, new KeyguardDismissCallback() {
3706 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003707 public void onDismissSucceeded() {
3708 mH.post(enterPipRunnable);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003709 }
3710 }, null /* message */);
3711 } else {
3712 // Enter picture in picture immediately otherwise
3713 enterPipRunnable.run();
3714 }
3715 return true;
3716 }
3717 } finally {
3718 Binder.restoreCallingIdentity(origId);
3719 }
3720 }
3721
3722 @Override
3723 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
3724 final long origId = Binder.clearCallingIdentity();
3725 try {
3726 synchronized (mGlobalLock) {
3727 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3728 "setPictureInPictureParams", token, params);
3729
3730 // Only update the saved args from the args that are set
3731 r.pictureInPictureArgs.copyOnlySet(params);
3732 if (r.inPinnedWindowingMode()) {
3733 // If the activity is already in picture-in-picture, update the pinned stack now
3734 // if it is not already expanding to fullscreen. Otherwise, the arguments will
3735 // be used the next time the activity enters PiP
3736 final PinnedActivityStack stack = r.getStack();
3737 if (!stack.isAnimatingBoundsToFullscreen()) {
3738 stack.setPictureInPictureAspectRatio(
3739 r.pictureInPictureArgs.getAspectRatio());
3740 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
3741 }
3742 }
3743 logPictureInPictureArgs(params);
3744 }
3745 } finally {
3746 Binder.restoreCallingIdentity(origId);
3747 }
3748 }
3749
3750 @Override
3751 public int getMaxNumPictureInPictureActions(IBinder token) {
3752 // Currently, this is a static constant, but later, we may change this to be dependent on
3753 // the context of the activity
3754 return 3;
3755 }
3756
3757 private void logPictureInPictureArgs(PictureInPictureParams params) {
3758 if (params.hasSetActions()) {
3759 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
3760 params.getActions().size());
3761 }
3762 if (params.hasSetAspectRatio()) {
3763 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
3764 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
3765 MetricsLogger.action(lm);
3766 }
3767 }
3768
3769 /**
3770 * Checks the state of the system and the activity associated with the given {@param token} to
3771 * verify that picture-in-picture is supported for that activity.
3772 *
3773 * @return the activity record for the given {@param token} if all the checks pass.
3774 */
3775 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
3776 IBinder token, PictureInPictureParams params) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003777 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003778 throw new IllegalStateException(caller
3779 + ": Device doesn't support picture-in-picture mode.");
3780 }
3781
3782 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3783 if (r == null) {
3784 throw new IllegalStateException(caller
3785 + ": Can't find activity for token=" + token);
3786 }
3787
3788 if (!r.supportsPictureInPicture()) {
3789 throw new IllegalStateException(caller
3790 + ": Current activity does not support picture-in-picture.");
3791 }
3792
3793 if (params.hasSetAspectRatio()
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003794 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003795 params.getAspectRatio())) {
3796 final float minAspectRatio = mContext.getResources().getFloat(
3797 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
3798 final float maxAspectRatio = mContext.getResources().getFloat(
3799 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
3800 throw new IllegalArgumentException(String.format(caller
3801 + ": Aspect ratio is too extreme (must be between %f and %f).",
3802 minAspectRatio, maxAspectRatio));
3803 }
3804
3805 // Truncate the number of actions if necessary
3806 params.truncateActions(getMaxNumPictureInPictureActions(token));
3807
3808 return r;
3809 }
3810
3811 @Override
3812 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003813 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003814 synchronized (mGlobalLock) {
3815 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
3816 if (r == null) {
3817 throw new IllegalArgumentException("Activity does not exist; token="
3818 + activityToken);
3819 }
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07003820 return r.getUriPermissionsLocked().getExternalToken();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003821 }
3822 }
3823
3824 @Override
3825 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
3826 Rect tempDockedTaskInsetBounds,
3827 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003828 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003829 long ident = Binder.clearCallingIdentity();
3830 try {
3831 synchronized (mGlobalLock) {
3832 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
3833 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
3834 PRESERVE_WINDOWS);
3835 }
3836 } finally {
3837 Binder.restoreCallingIdentity(ident);
3838 }
3839 }
3840
3841 @Override
3842 public void setSplitScreenResizing(boolean resizing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003843 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003844 final long ident = Binder.clearCallingIdentity();
3845 try {
3846 synchronized (mGlobalLock) {
3847 mStackSupervisor.setSplitScreenResizing(resizing);
3848 }
3849 } finally {
3850 Binder.restoreCallingIdentity(ident);
3851 }
3852 }
3853
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003854 /**
3855 * Check that we have the features required for VR-related API calls, and throw an exception if
3856 * not.
3857 */
3858 void enforceSystemHasVrFeature() {
3859 if (!mContext.getPackageManager().hasSystemFeature(
3860 PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
3861 throw new UnsupportedOperationException("VR mode not supported on this device!");
3862 }
3863 }
3864
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003865 @Override
3866 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003867 enforceSystemHasVrFeature();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003868
3869 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3870
3871 ActivityRecord r;
3872 synchronized (mGlobalLock) {
3873 r = ActivityRecord.isInStackLocked(token);
3874 }
3875
3876 if (r == null) {
3877 throw new IllegalArgumentException();
3878 }
3879
3880 int err;
3881 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
3882 VrManagerInternal.NO_ERROR) {
3883 return err;
3884 }
3885
3886 // Clear the binder calling uid since this path may call moveToTask().
3887 final long callingId = Binder.clearCallingIdentity();
3888 try {
3889 synchronized (mGlobalLock) {
3890 r.requestedVrComponent = (enabled) ? packageName : null;
3891
3892 // Update associated state if this activity is currently focused
Andrii Kulian52d255c2018-07-13 11:32:19 -07003893 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003894 applyUpdateVrModeLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003895 }
3896 return 0;
3897 }
3898 } finally {
3899 Binder.restoreCallingIdentity(callingId);
3900 }
3901 }
3902
3903 @Override
3904 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
3905 Slog.i(TAG, "Activity tried to startLocalVoiceInteraction");
3906 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003907 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003908 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
3909 throw new SecurityException("Only focused activity can call startVoiceInteraction");
3910 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07003911 if (mRunningVoice != null || activity.getTask().voiceSession != null
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003912 || activity.voiceSession != null) {
3913 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
3914 return;
3915 }
3916 if (activity.pendingVoiceInteractionStart) {
3917 Slog.w(TAG, "Pending start of voice interaction already.");
3918 return;
3919 }
3920 activity.pendingVoiceInteractionStart = true;
3921 }
3922 LocalServices.getService(VoiceInteractionManagerInternal.class)
3923 .startLocalVoiceInteraction(callingActivity, options);
3924 }
3925
3926 @Override
3927 public void stopLocalVoiceInteraction(IBinder callingActivity) {
3928 LocalServices.getService(VoiceInteractionManagerInternal.class)
3929 .stopLocalVoiceInteraction(callingActivity);
3930 }
3931
3932 @Override
3933 public boolean supportsLocalVoiceInteraction() {
3934 return LocalServices.getService(VoiceInteractionManagerInternal.class)
3935 .supportsLocalVoiceInteraction();
3936 }
3937
3938 /** Notifies all listeners when the pinned stack animation starts. */
3939 @Override
3940 public void notifyPinnedStackAnimationStarted() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003941 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003942 }
3943
3944 /** Notifies all listeners when the pinned stack animation ends. */
3945 @Override
3946 public void notifyPinnedStackAnimationEnded() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003947 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003948 }
3949
3950 @Override
3951 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003952 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003953 final long ident = Binder.clearCallingIdentity();
3954 try {
3955 synchronized (mGlobalLock) {
3956 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
3957 }
3958 } finally {
3959 Binder.restoreCallingIdentity(ident);
3960 }
3961 }
3962
3963 @Override
3964 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003965 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003966
3967 synchronized (mGlobalLock) {
3968 // Check if display is initialized in AM.
3969 if (!mStackSupervisor.isDisplayAdded(displayId)) {
3970 // Call might come when display is not yet added or has already been removed.
3971 if (DEBUG_CONFIGURATION) {
3972 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
3973 + displayId);
3974 }
3975 return false;
3976 }
3977
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003978 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003979 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003980 values = mWindowManager.computeNewConfiguration(displayId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003981 }
3982
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003983 if (mWindowManager != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07003984 final Message msg = PooledLambda.obtainMessage(
3985 ActivityManagerInternal::updateOomLevelsForDisplay, mAmInternal, displayId);
3986 mH.sendMessage(msg);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003987 }
3988
3989 final long origId = Binder.clearCallingIdentity();
3990 try {
3991 if (values != null) {
3992 Settings.System.clearConfiguration(values);
3993 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003994 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003995 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
3996 return mTmpUpdateConfigurationResult.changes != 0;
3997 } finally {
3998 Binder.restoreCallingIdentity(origId);
3999 }
4000 }
4001 }
4002
4003 @Override
4004 public boolean updateConfiguration(Configuration values) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004005 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004006
4007 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004008 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004009 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004010 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004011 }
4012
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004013 if (mWindowManager != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004014 final Message msg = PooledLambda.obtainMessage(
4015 ActivityManagerInternal::updateOomLevelsForDisplay, mAmInternal,
4016 DEFAULT_DISPLAY);
4017 mH.sendMessage(msg);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004018 }
4019
4020 final long origId = Binder.clearCallingIdentity();
4021 try {
4022 if (values != null) {
4023 Settings.System.clearConfiguration(values);
4024 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004025 updateConfigurationLocked(values, null, false, false /* persistent */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004026 UserHandle.USER_NULL, false /* deferResume */,
4027 mTmpUpdateConfigurationResult);
4028 return mTmpUpdateConfigurationResult.changes != 0;
4029 } finally {
4030 Binder.restoreCallingIdentity(origId);
4031 }
4032 }
4033 }
4034
4035 @Override
4036 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
4037 CharSequence message) {
4038 if (message != null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004039 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004040 Manifest.permission.SHOW_KEYGUARD_MESSAGE, "dismissKeyguard()");
4041 }
4042 final long callingId = Binder.clearCallingIdentity();
4043 try {
4044 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004045 mKeyguardController.dismissKeyguard(token, callback, message);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004046 }
4047 } finally {
4048 Binder.restoreCallingIdentity(callingId);
4049 }
4050 }
4051
4052 @Override
4053 public void cancelTaskWindowTransition(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004054 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004055 "cancelTaskWindowTransition()");
4056 final long ident = Binder.clearCallingIdentity();
4057 try {
4058 synchronized (mGlobalLock) {
4059 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
4060 MATCH_TASK_IN_STACKS_ONLY);
4061 if (task == null) {
4062 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
4063 return;
4064 }
4065 task.cancelWindowTransition();
4066 }
4067 } finally {
4068 Binder.restoreCallingIdentity(ident);
4069 }
4070 }
4071
4072 @Override
4073 public ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004074 enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004075 final long ident = Binder.clearCallingIdentity();
4076 try {
4077 final TaskRecord task;
4078 synchronized (mGlobalLock) {
4079 task = mStackSupervisor.anyTaskForIdLocked(taskId,
4080 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
4081 if (task == null) {
4082 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
4083 return null;
4084 }
4085 }
4086 // Don't call this while holding the lock as this operation might hit the disk.
4087 return task.getSnapshot(reducedResolution);
4088 } finally {
4089 Binder.restoreCallingIdentity(ident);
4090 }
4091 }
4092
4093 @Override
4094 public void setDisablePreviewScreenshots(IBinder token, boolean disable) {
4095 synchronized (mGlobalLock) {
4096 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4097 if (r == null) {
4098 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
4099 + token);
4100 return;
4101 }
4102 final long origId = Binder.clearCallingIdentity();
4103 try {
4104 r.setDisablePreviewScreenshots(disable);
4105 } finally {
4106 Binder.restoreCallingIdentity(origId);
4107 }
4108 }
4109 }
4110
4111 /** Return the user id of the last resumed activity. */
4112 @Override
4113 public @UserIdInt
4114 int getLastResumedActivityUserId() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004115 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004116 Manifest.permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
4117 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07004118 if (mLastResumedActivity == null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004119 return getCurrentUserId();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004120 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004121 return mLastResumedActivity.userId;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004122 }
4123 }
4124
4125 @Override
4126 public void updateLockTaskFeatures(int userId, int flags) {
4127 final int callingUid = Binder.getCallingUid();
4128 if (callingUid != 0 && callingUid != SYSTEM_UID) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004129 mAmInternal.enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004130 "updateLockTaskFeatures()");
4131 }
4132 synchronized (mGlobalLock) {
4133 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
4134 Integer.toHexString(flags));
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07004135 getLockTaskController().updateLockTaskFeatures(userId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004136 }
4137 }
4138
4139 @Override
4140 public void setShowWhenLocked(IBinder token, boolean showWhenLocked) {
4141 synchronized (mGlobalLock) {
4142 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4143 if (r == null) {
4144 return;
4145 }
4146 final long origId = Binder.clearCallingIdentity();
4147 try {
4148 r.setShowWhenLocked(showWhenLocked);
4149 } finally {
4150 Binder.restoreCallingIdentity(origId);
4151 }
4152 }
4153 }
4154
4155 @Override
4156 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) {
4157 synchronized (mGlobalLock) {
4158 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4159 if (r == null) {
4160 return;
4161 }
4162 final long origId = Binder.clearCallingIdentity();
4163 try {
4164 r.setTurnScreenOn(turnScreenOn);
4165 } finally {
4166 Binder.restoreCallingIdentity(origId);
4167 }
4168 }
4169 }
4170
4171 @Override
4172 public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004173 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004174 "registerRemoteAnimations");
4175 definition.setCallingPid(Binder.getCallingPid());
4176 synchronized (mGlobalLock) {
4177 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4178 if (r == null) {
4179 return;
4180 }
4181 final long origId = Binder.clearCallingIdentity();
4182 try {
4183 r.registerRemoteAnimations(definition);
4184 } finally {
4185 Binder.restoreCallingIdentity(origId);
4186 }
4187 }
4188 }
4189
4190 @Override
4191 public void registerRemoteAnimationForNextActivityStart(String packageName,
4192 RemoteAnimationAdapter adapter) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004193 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004194 "registerRemoteAnimationForNextActivityStart");
4195 adapter.setCallingPid(Binder.getCallingPid());
4196 synchronized (mGlobalLock) {
4197 final long origId = Binder.clearCallingIdentity();
4198 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07004199 getActivityStartController().registerRemoteAnimationForNextActivityStart(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004200 packageName, adapter);
4201 } finally {
4202 Binder.restoreCallingIdentity(origId);
4203 }
4204 }
4205 }
4206
4207 /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
4208 @Override
4209 public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
4210 synchronized (mGlobalLock) {
4211 final long origId = Binder.clearCallingIdentity();
4212 try {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004213 mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004214 } finally {
4215 Binder.restoreCallingIdentity(origId);
4216 }
4217 }
4218 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004219
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004220 @Override
4221 public void setVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004222 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004223 synchronized (mGlobalLock) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004224 final int pid = Binder.getCallingPid();
4225 final WindowProcessController wpc = mPidMap.get(pid);
4226 mVrController.setVrThreadLocked(tid, pid, wpc);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004227 }
4228 }
4229
4230 @Override
4231 public void setPersistentVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004232 if (checkCallingPermission(Manifest.permission.RESTRICTED_VR_ACCESS)
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004233 != PERMISSION_GRANTED) {
4234 final String msg = "Permission Denial: setPersistentVrThread() from pid="
4235 + Binder.getCallingPid()
4236 + ", uid=" + Binder.getCallingUid()
4237 + " requires " + Manifest.permission.RESTRICTED_VR_ACCESS;
4238 Slog.w(TAG, msg);
4239 throw new SecurityException(msg);
4240 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004241 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004242 synchronized (mGlobalLock) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004243 final int pid = Binder.getCallingPid();
4244 final WindowProcessController proc = mPidMap.get(pid);
4245 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004246 }
4247 }
4248
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004249 @Override
4250 public void stopAppSwitches() {
4251 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
4252 synchronized (mGlobalLock) {
4253 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME;
4254 mDidAppSwitch = false;
4255 getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
4256 }
4257 }
4258
4259 @Override
4260 public void resumeAppSwitches() {
4261 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
4262 synchronized (mGlobalLock) {
4263 // Note that we don't execute any pending app switches... we will
4264 // let those wait until either the timeout, or the next start
4265 // activity request.
4266 mAppSwitchesAllowedTime = 0;
4267 }
4268 }
4269
4270 void onStartActivitySetDidAppSwitch() {
4271 if (mDidAppSwitch) {
4272 // This is the second allowed switch since we stopped switches, so now just generally
4273 // allow switches. Use case:
4274 // - user presses home (switches disabled, switch to home, mDidAppSwitch now true);
4275 // - user taps a home icon (coming from home so allowed, we hit here and now allow
4276 // anyone to switch again).
4277 mAppSwitchesAllowedTime = 0;
4278 } else {
4279 mDidAppSwitch = true;
4280 }
4281 }
4282
4283 /** @return whether the system should disable UI modes incompatible with VR mode. */
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004284 boolean shouldDisableNonVrUiLocked() {
4285 return mVrController.shouldDisableNonVrUiLocked();
4286 }
4287
Wale Ogunwale53783742018-09-16 10:21:51 -07004288 private void applyUpdateVrModeLocked(ActivityRecord r) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004289 // VR apps are expected to run in a main display. If an app is turning on VR for
4290 // itself, but lives in a dynamic stack, then make sure that it is moved to the main
4291 // fullscreen stack before enabling VR Mode.
4292 // TODO: The goal of this code is to keep the VR app on the main display. When the
4293 // stack implementation changes in the future, keep in mind that the use of the fullscreen
4294 // stack is a means to move the activity to the main display and a moveActivityToDisplay()
4295 // option would be a better choice here.
4296 if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
4297 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
4298 + " to main stack for VR");
4299 final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
4300 WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
4301 moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
4302 }
4303 mH.post(() -> {
4304 if (!mVrController.onVrModeChanged(r)) {
4305 return;
4306 }
4307 synchronized (mGlobalLock) {
4308 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
4309 mWindowManager.disableNonVrUi(disableNonVrUi);
4310 if (disableNonVrUi) {
4311 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
4312 // then remove the pinned stack.
4313 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
4314 }
4315 }
4316 });
4317 }
4318
Wale Ogunwale53783742018-09-16 10:21:51 -07004319 @Override
4320 public int getPackageScreenCompatMode(String packageName) {
4321 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4322 synchronized (mGlobalLock) {
4323 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4324 }
4325 }
4326
4327 @Override
4328 public void setPackageScreenCompatMode(String packageName, int mode) {
4329 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4330 "setPackageScreenCompatMode");
4331 synchronized (mGlobalLock) {
4332 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4333 }
4334 }
4335
4336 @Override
4337 public boolean getPackageAskScreenCompat(String packageName) {
4338 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4339 synchronized (mGlobalLock) {
4340 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4341 }
4342 }
4343
4344 @Override
4345 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4346 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4347 "setPackageAskScreenCompat");
4348 synchronized (mGlobalLock) {
4349 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4350 }
4351 }
4352
Wale Ogunwale64258362018-10-16 15:13:37 -07004353 public static String relaunchReasonToString(int relaunchReason) {
4354 switch (relaunchReason) {
4355 case RELAUNCH_REASON_WINDOWING_MODE_RESIZE:
4356 return "window_resize";
4357 case RELAUNCH_REASON_FREE_RESIZE:
4358 return "free_resize";
4359 default:
4360 return null;
4361 }
4362 }
4363
Andrii Kulian5f750bc2018-07-17 08:57:23 -07004364 ActivityStack getTopDisplayFocusedStack() {
4365 return mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004366 }
4367
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004368 /** Pokes the task persister. */
4369 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
4370 mRecentTasks.notifyTaskPersisterLocked(task, flush);
4371 }
4372
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004373 boolean isKeyguardLocked() {
4374 return mKeyguardController.isKeyguardLocked();
4375 }
4376
4377 boolean isNextTransitionForward() {
4378 int transit = mWindowManager.getPendingAppTransition();
4379 return transit == TRANSIT_ACTIVITY_OPEN
4380 || transit == TRANSIT_TASK_OPEN
4381 || transit == TRANSIT_TASK_TO_FRONT;
4382 }
4383
Wale Ogunwale31913b52018-10-13 08:29:31 -07004384 void dumpLastANRLocked(PrintWriter pw) {
4385 pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
4386 if (mLastANRState == null) {
4387 pw.println(" <no ANR has occurred since boot>");
4388 } else {
4389 pw.println(mLastANRState);
4390 }
4391 }
4392
4393 void dumpLastANRTracesLocked(PrintWriter pw) {
4394 pw.println("ACTIVITY MANAGER LAST ANR TRACES (dumpsys activity lastanr-traces)");
4395
4396 final File[] files = new File(ANR_TRACE_DIR).listFiles();
4397 if (ArrayUtils.isEmpty(files)) {
4398 pw.println(" <no ANR has occurred since boot>");
4399 return;
4400 }
4401 // Find the latest file.
4402 File latest = null;
4403 for (File f : files) {
4404 if ((latest == null) || (latest.lastModified() < f.lastModified())) {
4405 latest = f;
Wale Ogunwalef6733932018-06-27 05:14:34 -07004406 }
Wale Ogunwale31913b52018-10-13 08:29:31 -07004407 }
4408 pw.print("File: ");
4409 pw.print(latest.getName());
4410 pw.println();
4411 try (BufferedReader in = new BufferedReader(new FileReader(latest))) {
4412 String line;
4413 while ((line = in.readLine()) != null) {
4414 pw.println(line);
4415 }
4416 } catch (IOException e) {
4417 pw.print("Unable to read: ");
4418 pw.print(e);
4419 pw.println();
4420 }
4421 }
4422
4423 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
4424 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
4425 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
4426 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
4427 }
4428
4429 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
4430 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
4431 pw.println(header);
4432
4433 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
4434 dumpPackage);
4435 boolean needSep = printedAnything;
4436
4437 boolean printed = ActivityStackSupervisor.printThisActivity(pw,
4438 mStackSupervisor.getTopResumedActivity(), dumpPackage, needSep,
4439 " ResumedActivity: ");
4440 if (printed) {
4441 printedAnything = true;
4442 needSep = false;
4443 }
4444
4445 if (dumpPackage == null) {
4446 if (needSep) {
4447 pw.println();
4448 }
4449 printedAnything = true;
4450 mStackSupervisor.dump(pw, " ");
4451 }
4452
4453 if (!printedAnything) {
4454 pw.println(" (nothing)");
4455 }
4456 }
4457
4458 void dumpActivityContainersLocked(PrintWriter pw) {
4459 pw.println("ACTIVITY MANAGER STARTER (dumpsys activity containers)");
4460 mStackSupervisor.dumpChildrenNames(pw, " ");
4461 pw.println(" ");
4462 }
4463
4464 void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
4465 pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
4466 getActivityStartController().dump(pw, "", dumpPackage);
4467 }
4468
4469 /**
4470 * There are three things that cmd can be:
4471 * - a flattened component name that matches an existing activity
4472 * - the cmd arg isn't the flattened component name of an existing activity:
4473 * dump all activity whose component contains the cmd as a substring
4474 * - A hex number of the ActivityRecord object instance.
4475 *
4476 * @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
4477 * @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
4478 */
4479 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
4480 int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
4481 ArrayList<ActivityRecord> activities;
4482
4483 synchronized (mGlobalLock) {
4484 activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
4485 dumpFocusedStackOnly);
4486 }
4487
4488 if (activities.size() <= 0) {
4489 return false;
4490 }
4491
4492 String[] newArgs = new String[args.length - opti];
4493 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
4494
4495 TaskRecord lastTask = null;
4496 boolean needSep = false;
4497 for (int i = activities.size() - 1; i >= 0; i--) {
4498 ActivityRecord r = activities.get(i);
4499 if (needSep) {
4500 pw.println();
4501 }
4502 needSep = true;
4503 synchronized (mGlobalLock) {
4504 final TaskRecord task = r.getTask();
4505 if (lastTask != task) {
4506 lastTask = task;
4507 pw.print("TASK "); pw.print(lastTask.affinity);
4508 pw.print(" id="); pw.print(lastTask.taskId);
4509 pw.print(" userId="); pw.println(lastTask.userId);
4510 if (dumpAll) {
4511 lastTask.dump(pw, " ");
4512 }
4513 }
4514 }
4515 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
4516 }
4517 return true;
4518 }
4519
4520 /**
4521 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
4522 * there is a thread associated with the activity.
4523 */
4524 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
4525 final ActivityRecord r, String[] args, boolean dumpAll) {
4526 String innerPrefix = prefix + " ";
4527 synchronized (mGlobalLock) {
4528 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
4529 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
4530 pw.print(" pid=");
4531 if (r.hasProcess()) pw.println(r.app.getPid());
4532 else pw.println("(not running)");
4533 if (dumpAll) {
4534 r.dump(pw, innerPrefix);
4535 }
4536 }
4537 if (r.attachedToProcess()) {
4538 // flush anything that is already in the PrintWriter since the thread is going
4539 // to write to the file descriptor directly
4540 pw.flush();
4541 try {
4542 TransferPipe tp = new TransferPipe();
4543 try {
4544 r.app.getThread().dumpActivity(tp.getWriteFd(),
4545 r.appToken, innerPrefix, args);
4546 tp.go(fd);
4547 } finally {
4548 tp.kill();
4549 }
4550 } catch (IOException e) {
4551 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
4552 } catch (RemoteException e) {
4553 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
4554 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004555 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004556 }
4557
Wale Ogunwalef6733932018-06-27 05:14:34 -07004558 void writeSleepStateToProto(ProtoOutputStream proto) {
4559 for (ActivityTaskManagerInternal.SleepToken st : mStackSupervisor.mSleepTokens) {
4560 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS,
4561 st.toString());
4562 }
4563
4564 if (mRunningVoice != null) {
4565 final long vrToken = proto.start(
4566 ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
4567 proto.write(ActivityManagerServiceDumpProcessesProto.Voice.SESSION,
4568 mRunningVoice.toString());
4569 mVoiceWakeLock.writeToProto(
4570 proto, ActivityManagerServiceDumpProcessesProto.Voice.WAKELOCK);
4571 proto.end(vrToken);
4572 }
4573
4574 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
4575 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN,
4576 mShuttingDown);
4577 mVrController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004578 }
4579
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004580 int getCurrentUserId() {
4581 return mAmInternal.getCurrentUserId();
4582 }
4583
4584 private void enforceNotIsolatedCaller(String caller) {
4585 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4586 throw new SecurityException("Isolated process not allowed to call " + caller);
4587 }
4588 }
4589
Wale Ogunwalef6733932018-06-27 05:14:34 -07004590 public Configuration getConfiguration() {
4591 Configuration ci;
4592 synchronized(mGlobalLock) {
Yunfan Chen75157d72018-07-27 14:47:21 +09004593 ci = new Configuration(getGlobalConfigurationForCallingPid());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004594 ci.userSetLocale = false;
4595 }
4596 return ci;
4597 }
4598
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004599 /**
4600 * Current global configuration information. Contains general settings for the entire system,
4601 * also corresponds to the merged configuration of the default display.
4602 */
4603 Configuration getGlobalConfiguration() {
4604 return mStackSupervisor.getConfiguration();
4605 }
4606
4607 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4608 boolean initLocale) {
4609 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
4610 }
4611
4612 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4613 boolean initLocale, boolean deferResume) {
4614 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
4615 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
4616 UserHandle.USER_NULL, deferResume);
4617 }
4618
4619 void updatePersistentConfiguration(Configuration values, @UserIdInt int userId) {
4620 final long origId = Binder.clearCallingIdentity();
4621 try {
4622 synchronized (mGlobalLock) {
4623 updateConfigurationLocked(values, null, false, true, userId,
4624 false /* deferResume */);
4625 }
4626 } finally {
4627 Binder.restoreCallingIdentity(origId);
4628 }
4629 }
4630
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004631 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4632 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
4633 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
4634 deferResume, null /* result */);
4635 }
4636
4637 /**
4638 * Do either or both things: (1) change the current configuration, and (2)
4639 * make sure the given activity is running with the (now) current
4640 * configuration. Returns true if the activity has been left running, or
4641 * false if <var>starting</var> is being destroyed to match the new
4642 * configuration.
4643 *
4644 * @param userId is only used when persistent parameter is set to true to persist configuration
4645 * for that particular user
4646 */
4647 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4648 boolean initLocale, boolean persistent, int userId, boolean deferResume,
4649 ActivityTaskManagerService.UpdateConfigurationResult result) {
4650 int changes = 0;
4651 boolean kept = true;
4652
4653 if (mWindowManager != null) {
4654 mWindowManager.deferSurfaceLayout();
4655 }
4656 try {
4657 if (values != null) {
4658 changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
4659 deferResume);
4660 }
4661
4662 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4663 } finally {
4664 if (mWindowManager != null) {
4665 mWindowManager.continueSurfaceLayout();
4666 }
4667 }
4668
4669 if (result != null) {
4670 result.changes = changes;
4671 result.activityRelaunched = !kept;
4672 }
4673 return kept;
4674 }
4675
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004676 /** Update default (global) configuration and notify listeners about changes. */
4677 private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
4678 boolean persistent, int userId, boolean deferResume) {
4679 mTempConfig.setTo(getGlobalConfiguration());
4680 final int changes = mTempConfig.updateFrom(values);
4681 if (changes == 0) {
4682 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
4683 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
4684 // performDisplayOverrideConfigUpdate in order to send the new display configuration
4685 // (even if there are no actual changes) to unfreeze the window.
4686 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
4687 return 0;
4688 }
4689
4690 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
4691 "Updating global configuration to: " + values);
4692
4693 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
4694 StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
4695 values.colorMode,
4696 values.densityDpi,
4697 values.fontScale,
4698 values.hardKeyboardHidden,
4699 values.keyboard,
4700 values.keyboardHidden,
4701 values.mcc,
4702 values.mnc,
4703 values.navigation,
4704 values.navigationHidden,
4705 values.orientation,
4706 values.screenHeightDp,
4707 values.screenLayout,
4708 values.screenWidthDp,
4709 values.smallestScreenWidthDp,
4710 values.touchscreen,
4711 values.uiMode);
4712
4713
4714 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
4715 final LocaleList locales = values.getLocales();
4716 int bestLocaleIndex = 0;
4717 if (locales.size() > 1) {
4718 if (mSupportedSystemLocales == null) {
4719 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
4720 }
4721 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
4722 }
4723 SystemProperties.set("persist.sys.locale",
4724 locales.get(bestLocaleIndex).toLanguageTag());
4725 LocaleList.setDefault(locales, bestLocaleIndex);
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004726
4727 final Message m = PooledLambda.obtainMessage(
4728 ActivityTaskManagerService::sendLocaleToMountDaemonMsg, this,
4729 locales.get(bestLocaleIndex));
4730 mH.sendMessage(m);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004731 }
4732
Yunfan Chen75157d72018-07-27 14:47:21 +09004733 mTempConfig.seq = increaseConfigurationSeqLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004734
4735 // Update stored global config and notify everyone about the change.
4736 mStackSupervisor.onConfigurationChanged(mTempConfig);
4737
4738 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
4739 // TODO(multi-display): Update UsageEvents#Event to include displayId.
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004740 mUsageStatsInternal.reportConfigurationChange(mTempConfig, mAmInternal.getCurrentUserId());
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004741
4742 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
Wale Ogunwalef6733932018-06-27 05:14:34 -07004743 updateShouldShowDialogsLocked(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004744
4745 AttributeCache ac = AttributeCache.instance();
4746 if (ac != null) {
4747 ac.updateConfiguration(mTempConfig);
4748 }
4749
4750 // Make sure all resources in our process are updated right now, so that anyone who is going
4751 // to retrieve resource values after we return will be sure to get the new ones. This is
4752 // especially important during boot, where the first config change needs to guarantee all
4753 // resources have that config before following boot code is executed.
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004754 mSystemThread.applyConfigurationToResources(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004755
4756 // We need another copy of global config because we're scheduling some calls instead of
4757 // running them in place. We need to be sure that object we send will be handled unchanged.
4758 final Configuration configCopy = new Configuration(mTempConfig);
4759 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004760 final Message msg = PooledLambda.obtainMessage(
4761 ActivityTaskManagerService::sendPutConfigurationForUserMsg,
4762 this, userId, configCopy);
4763 mH.sendMessage(msg);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004764 }
4765
Yunfan Chen34fcc7a2018-10-11 16:26:09 -07004766 for (int i = mPidMap.size() - 1; i >= 0; i--) {
Yunfan Chen79b96062018-10-17 12:45:23 -07004767 final int pid = mPidMap.keyAt(i);
4768 final WindowProcessController app = mPidMap.get(pid);
Yunfan Chen34fcc7a2018-10-11 16:26:09 -07004769 if (DEBUG_CONFIGURATION) {
4770 Slog.v(TAG_CONFIGURATION, "Update process config of "
4771 + app.mName + " to new config " + configCopy);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004772 }
Yunfan Chen34fcc7a2018-10-11 16:26:09 -07004773 app.onConfigurationChanged(configCopy);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004774 }
4775
Wale Ogunwale2ea36d42018-10-18 10:27:31 -07004776 final Message msg = PooledLambda.obtainMessage(
4777 ActivityManagerInternal::broadcastGlobalConfigurationChanged,
4778 mAmInternal, changes, initLocale);
4779 mH.sendMessage(msg);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004780
4781 // Override configuration of the default display duplicates global config, so we need to
4782 // update it also. This will also notify WindowManager about changes.
4783 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
4784 DEFAULT_DISPLAY);
4785
4786 return changes;
4787 }
4788
4789 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
4790 boolean deferResume, int displayId) {
4791 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
4792 displayId, null /* result */);
4793 }
4794
4795 /**
4796 * Updates override configuration specific for the selected display. If no config is provided,
4797 * new one will be computed in WM based on current display info.
4798 */
4799 boolean updateDisplayOverrideConfigurationLocked(Configuration values,
4800 ActivityRecord starting, boolean deferResume, int displayId,
4801 ActivityTaskManagerService.UpdateConfigurationResult result) {
4802 int changes = 0;
4803 boolean kept = true;
4804
4805 if (mWindowManager != null) {
4806 mWindowManager.deferSurfaceLayout();
4807 }
4808 try {
4809 if (values != null) {
4810 if (displayId == DEFAULT_DISPLAY) {
4811 // Override configuration of the default display duplicates global config, so
4812 // we're calling global config update instead for default display. It will also
4813 // apply the correct override config.
4814 changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
4815 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
4816 } else {
4817 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
4818 }
4819 }
4820
4821 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4822 } finally {
4823 if (mWindowManager != null) {
4824 mWindowManager.continueSurfaceLayout();
4825 }
4826 }
4827
4828 if (result != null) {
4829 result.changes = changes;
4830 result.activityRelaunched = !kept;
4831 }
4832 return kept;
4833 }
4834
4835 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
4836 int displayId) {
4837 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
4838 final int changes = mTempConfig.updateFrom(values);
4839 if (changes != 0) {
4840 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
4841 + mTempConfig + " for displayId=" + displayId);
4842 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
4843
4844 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
4845 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004846 mAppWarnings.onDensityChanged();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004847
Wale Ogunwale5c918702018-10-18 11:06:33 -07004848 // Post message to start process to avoid possible deadlock of calling into AMS with
4849 // the ATMS lock held.
4850 final Message msg = PooledLambda.obtainMessage(
4851 ActivityManagerInternal::killAllBackgroundProcessesExcept, mAmInternal,
4852 N, ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
4853 mH.sendMessage(msg);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004854 }
4855 }
4856
4857 // Update the configuration with WM first and check if any of the stacks need to be resized
4858 // due to the configuration change. If so, resize the stacks now and do any relaunches if
4859 // necessary. This way we don't need to relaunch again afterwards in
4860 // ensureActivityConfiguration().
4861 if (mWindowManager != null) {
4862 final int[] resizedStacks =
4863 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
4864 if (resizedStacks != null) {
4865 for (int stackId : resizedStacks) {
4866 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
4867 }
4868 }
4869 }
4870
4871 return changes;
4872 }
4873
Wale Ogunwalef6733932018-06-27 05:14:34 -07004874 private void updateEventDispatchingLocked(boolean booted) {
4875 mWindowManager.setEventDispatching(booted && !mShuttingDown);
4876 }
4877
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004878 private void sendPutConfigurationForUserMsg(int userId, Configuration config) {
4879 final ContentResolver resolver = mContext.getContentResolver();
4880 Settings.System.putConfigurationForUser(resolver, config, userId);
4881 }
4882
4883 private void sendLocaleToMountDaemonMsg(Locale l) {
4884 try {
4885 IBinder service = ServiceManager.getService("mount");
4886 IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
4887 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
4888 storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
4889 } catch (RemoteException e) {
4890 Log.e(TAG, "Error storing locale for decryption UI", e);
4891 }
4892 }
4893
4894 boolean isActivityStartsLoggingEnabled() {
4895 return mAmInternal.isActivityStartsLoggingEnabled();
4896 }
4897
Wale Ogunwalef6733932018-06-27 05:14:34 -07004898 void enableScreenAfterBoot(boolean booted) {
4899 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4900 SystemClock.uptimeMillis());
4901 mWindowManager.enableScreenAfterBoot();
4902
4903 synchronized (mGlobalLock) {
4904 updateEventDispatchingLocked(booted);
4905 }
4906 }
4907
4908 boolean canShowErrorDialogs() {
4909 return mShowDialogs && !mSleeping && !mShuttingDown
4910 && !mKeyguardController.isKeyguardOrAodShowing(DEFAULT_DISPLAY)
4911 && !hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
Wale Ogunwale86b74462018-07-02 08:42:43 -07004912 mAmInternal.getCurrentUserId())
Wale Ogunwalef6733932018-06-27 05:14:34 -07004913 && !(UserManager.isDeviceInDemoMode(mContext)
Wale Ogunwale86b74462018-07-02 08:42:43 -07004914 && mAmInternal.getCurrentUser().isDemo());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004915 }
4916
Wale Ogunwale906f9c62018-07-23 11:23:44 -07004917 static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
4918 if (r == null || !r.hasProcess()) {
4919 return KEY_DISPATCHING_TIMEOUT_MS;
4920 }
4921 return getInputDispatchingTimeoutLocked(r.app);
4922 }
4923
4924 private static long getInputDispatchingTimeoutLocked(WindowProcessController r) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07004925 return r != null ? r.getInputDispatchingTimeout() : KEY_DISPATCHING_TIMEOUT_MS;
Wale Ogunwale906f9c62018-07-23 11:23:44 -07004926 }
4927
Wale Ogunwalef6733932018-06-27 05:14:34 -07004928 /**
4929 * Decide based on the configuration whether we should show the ANR,
4930 * crash, etc dialogs. The idea is that if there is no affordance to
4931 * press the on-screen buttons, or the user experience would be more
4932 * greatly impacted than the crash itself, we shouldn't show the dialog.
4933 *
4934 * A thought: SystemUI might also want to get told about this, the Power
4935 * dialog / global actions also might want different behaviors.
4936 */
4937 private void updateShouldShowDialogsLocked(Configuration config) {
4938 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
4939 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
4940 && config.navigation == Configuration.NAVIGATION_NONAV);
4941 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
4942 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
4943 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
4944 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
4945 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
4946 final boolean hideDialogsSet = Settings.Global.getInt(mContext.getContentResolver(),
4947 HIDE_ERROR_DIALOGS, 0) != 0;
4948 mShowDialogs = inputMethodExists && uiModeSupportsDialogs && !hideDialogsSet;
4949 }
4950
4951 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
4952 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
4953 FONT_SCALE, 1.0f, userId);
4954
4955 synchronized (this) {
4956 if (getGlobalConfiguration().fontScale == scaleFactor) {
4957 return;
4958 }
4959
4960 final Configuration configuration
4961 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
4962 configuration.fontScale = scaleFactor;
4963 updatePersistentConfiguration(configuration, userId);
4964 }
4965 }
4966
4967 // Actually is sleeping or shutting down or whatever else in the future
4968 // is an inactive state.
4969 boolean isSleepingOrShuttingDownLocked() {
4970 return isSleepingLocked() || mShuttingDown;
4971 }
4972
4973 boolean isSleepingLocked() {
4974 return mSleeping;
4975 }
4976
Riddle Hsu16567132018-08-16 21:37:47 +08004977 /** Update AMS states when an activity is resumed. */
Wale Ogunwalef6733932018-06-27 05:14:34 -07004978 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
4979 final TaskRecord task = r.getTask();
4980 if (task.isActivityTypeStandard()) {
4981 if (mCurAppTimeTracker != r.appTimeTracker) {
4982 // We are switching app tracking. Complete the current one.
4983 if (mCurAppTimeTracker != null) {
4984 mCurAppTimeTracker.stop();
4985 mH.obtainMessage(
4986 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
4987 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
4988 mCurAppTimeTracker = null;
4989 }
4990 if (r.appTimeTracker != null) {
4991 mCurAppTimeTracker = r.appTimeTracker;
4992 startTimeTrackingFocusedActivityLocked();
4993 }
4994 } else {
4995 startTimeTrackingFocusedActivityLocked();
4996 }
4997 } else {
4998 r.appTimeTracker = null;
4999 }
5000 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
5001 // TODO: Probably not, because we don't want to resume voice on switching
5002 // back to this activity
5003 if (task.voiceInteractor != null) {
5004 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
5005 } else {
5006 finishRunningVoiceLocked();
5007
5008 if (mLastResumedActivity != null) {
5009 final IVoiceInteractionSession session;
5010
5011 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
5012 if (lastResumedActivityTask != null
5013 && lastResumedActivityTask.voiceSession != null) {
5014 session = lastResumedActivityTask.voiceSession;
5015 } else {
5016 session = mLastResumedActivity.voiceSession;
5017 }
5018
5019 if (session != null) {
5020 // We had been in a voice interaction session, but now focused has
5021 // move to something different. Just finish the session, we can't
5022 // return to it and retain the proper state and synchronization with
5023 // the voice interaction service.
5024 finishVoiceTask(session);
5025 }
5026 }
5027 }
5028
5029 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
5030 mAmInternal.sendForegroundProfileChanged(r.userId);
5031 }
5032 updateResumedAppTrace(r);
5033 mLastResumedActivity = r;
5034
Tiger Huang1e5b10a2018-07-30 20:19:51 +08005035 r.getDisplay().setFocusedApp(r, true);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005036
5037 applyUpdateLockStateLocked(r);
5038 applyUpdateVrModeLocked(r);
5039
5040 EventLogTags.writeAmSetResumedActivity(
5041 r == null ? -1 : r.userId,
5042 r == null ? "NULL" : r.shortComponentName,
5043 reason);
5044 }
5045
5046 ActivityTaskManagerInternal.SleepToken acquireSleepToken(String tag, int displayId) {
5047 synchronized (mGlobalLock) {
5048 final ActivityTaskManagerInternal.SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
5049 updateSleepIfNeededLocked();
5050 return token;
5051 }
5052 }
5053
5054 void updateSleepIfNeededLocked() {
5055 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
5056 final boolean wasSleeping = mSleeping;
5057 boolean updateOomAdj = false;
5058
5059 if (!shouldSleep) {
5060 // If wasSleeping is true, we need to wake up activity manager state from when
5061 // we started sleeping. In either case, we need to apply the sleep tokens, which
5062 // will wake up stacks or put them to sleep as appropriate.
5063 if (wasSleeping) {
5064 mSleeping = false;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07005065 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
5066 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__AWAKE);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005067 startTimeTrackingFocusedActivityLocked();
5068 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
5069 mStackSupervisor.comeOutOfSleepIfNeededLocked();
5070 }
5071 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
5072 if (wasSleeping) {
5073 updateOomAdj = true;
5074 }
5075 } else if (!mSleeping && shouldSleep) {
5076 mSleeping = true;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07005077 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
5078 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__ASLEEP);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005079 if (mCurAppTimeTracker != null) {
5080 mCurAppTimeTracker.stop();
5081 }
5082 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
5083 mStackSupervisor.goingToSleepLocked();
5084 updateResumedAppTrace(null /* resumed */);
5085 updateOomAdj = true;
5086 }
5087 if (updateOomAdj) {
5088 mH.post(mAmInternal::updateOomAdj);
5089 }
5090 }
5091
5092 void updateOomAdj() {
5093 mH.post(mAmInternal::updateOomAdj);
5094 }
5095
Wale Ogunwale53783742018-09-16 10:21:51 -07005096 void updateCpuStats() {
5097 mH.post(mAmInternal::updateCpuStats);
5098 }
5099
5100 void updateUsageStats(ActivityRecord component, boolean resumed) {
5101 final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::updateUsageStats,
5102 mAmInternal, component.realActivity, component.app.mUid, component.userId, resumed);
5103 mH.sendMessage(m);
5104 }
5105
5106 void setBooting(boolean booting) {
5107 mAmInternal.setBooting(booting);
5108 }
5109
5110 boolean isBooting() {
5111 return mAmInternal.isBooting();
5112 }
5113
5114 void setBooted(boolean booted) {
5115 mAmInternal.setBooted(booted);
5116 }
5117
5118 boolean isBooted() {
5119 return mAmInternal.isBooted();
5120 }
5121
5122 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
5123 mH.post(() -> {
5124 if (finishBooting) {
5125 mAmInternal.finishBooting();
5126 }
5127 if (enableScreen) {
5128 mInternal.enableScreenAfterBoot(isBooted());
5129 }
5130 });
5131 }
5132
5133 void setHeavyWeightProcess(ActivityRecord root) {
5134 mHeavyWeightProcess = root.app;
5135 final Message m = PooledLambda.obtainMessage(
5136 ActivityTaskManagerService::postHeavyWeightProcessNotification, this,
5137 root.app, root.intent, root.userId);
5138 mH.sendMessage(m);
5139 }
5140
5141 void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
5142 if (mHeavyWeightProcess == null || mHeavyWeightProcess != proc) {
5143 return;
5144 }
5145
5146 mHeavyWeightProcess = null;
5147 final Message m = PooledLambda.obtainMessage(
5148 ActivityTaskManagerService::cancelHeavyWeightProcessNotification, this,
5149 proc.mUserId);
5150 mH.sendMessage(m);
5151 }
5152
5153 private void cancelHeavyWeightProcessNotification(int userId) {
5154 final INotificationManager inm = NotificationManager.getService();
5155 if (inm == null) {
5156 return;
5157 }
5158 try {
5159 inm.cancelNotificationWithTag("android", null,
5160 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, userId);
5161 } catch (RuntimeException e) {
5162 Slog.w(TAG, "Error canceling notification for service", e);
5163 } catch (RemoteException e) {
5164 }
5165
5166 }
5167
5168 private void postHeavyWeightProcessNotification(
5169 WindowProcessController proc, Intent intent, int userId) {
5170 if (proc == null) {
5171 return;
5172 }
5173
5174 final INotificationManager inm = NotificationManager.getService();
5175 if (inm == null) {
5176 return;
5177 }
5178
5179 try {
5180 Context context = mContext.createPackageContext(proc.mInfo.packageName, 0);
5181 String text = mContext.getString(R.string.heavy_weight_notification,
5182 context.getApplicationInfo().loadLabel(context.getPackageManager()));
5183 Notification notification =
5184 new Notification.Builder(context,
5185 SystemNotificationChannels.HEAVY_WEIGHT_APP)
5186 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
5187 .setWhen(0)
5188 .setOngoing(true)
5189 .setTicker(text)
5190 .setColor(mContext.getColor(
5191 com.android.internal.R.color.system_notification_accent_color))
5192 .setContentTitle(text)
5193 .setContentText(
5194 mContext.getText(R.string.heavy_weight_notification_detail))
5195 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
5196 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
5197 new UserHandle(userId)))
5198 .build();
5199 try {
5200 inm.enqueueNotificationWithTag("android", "android", null,
5201 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, notification, userId);
5202 } catch (RuntimeException e) {
5203 Slog.w(TAG, "Error showing notification for heavy-weight app", e);
5204 } catch (RemoteException e) {
5205 }
5206 } catch (PackageManager.NameNotFoundException e) {
5207 Slog.w(TAG, "Unable to create context for heavy notification", e);
5208 }
5209
5210 }
5211
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07005212 IIntentSender getIntentSenderLocked(int type, String packageName, int callingUid, int userId,
5213 IBinder token, String resultWho, int requestCode, Intent[] intents,
5214 String[] resolvedTypes, int flags, Bundle bOptions) {
5215
5216 ActivityRecord activity = null;
5217 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5218 activity = ActivityRecord.isInStackLocked(token);
5219 if (activity == null) {
5220 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
5221 return null;
5222 }
5223 if (activity.finishing) {
5224 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
5225 return null;
5226 }
5227 }
5228
5229 final PendingIntentRecord rec = mPendingIntentController.getIntentSender(type, packageName,
5230 callingUid, userId, token, resultWho, requestCode, intents, resolvedTypes, flags,
5231 bOptions);
5232 final boolean noCreate = (flags & PendingIntent.FLAG_NO_CREATE) != 0;
5233 if (noCreate) {
5234 return rec;
5235 }
5236 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5237 if (activity.pendingResults == null) {
5238 activity.pendingResults = new HashSet<>();
5239 }
5240 activity.pendingResults.add(rec.ref);
5241 }
5242 return rec;
5243 }
5244
Andrii Kulian52d255c2018-07-13 11:32:19 -07005245 // TODO(b/111541062): Update app time tracking to make it aware of multiple resumed activities
Wale Ogunwalef6733932018-06-27 05:14:34 -07005246 private void startTimeTrackingFocusedActivityLocked() {
Andrii Kulian52d255c2018-07-13 11:32:19 -07005247 final ActivityRecord resumedActivity = mStackSupervisor.getTopResumedActivity();
Wale Ogunwalef6733932018-06-27 05:14:34 -07005248 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
5249 mCurAppTimeTracker.start(resumedActivity.packageName);
5250 }
5251 }
5252
5253 private void updateResumedAppTrace(@Nullable ActivityRecord resumed) {
5254 if (mTracedResumedActivity != null) {
5255 Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER,
5256 constructResumedTraceName(mTracedResumedActivity.packageName), 0);
5257 }
5258 if (resumed != null) {
5259 Trace.asyncTraceBegin(TRACE_TAG_ACTIVITY_MANAGER,
5260 constructResumedTraceName(resumed.packageName), 0);
5261 }
5262 mTracedResumedActivity = resumed;
5263 }
5264
5265 private String constructResumedTraceName(String packageName) {
5266 return "focused app: " + packageName;
5267 }
5268
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005269 /** Helper method that requests bounds from WM and applies them to stack. */
5270 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
5271 final Rect newStackBounds = new Rect();
5272 final ActivityStack stack = mStackSupervisor.getStack(stackId);
5273
5274 // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
5275 if (stack == null) {
5276 final StringWriter writer = new StringWriter();
5277 final PrintWriter printWriter = new PrintWriter(writer);
5278 mStackSupervisor.dumpDisplays(printWriter);
5279 printWriter.flush();
5280
5281 Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
5282 }
5283
5284 stack.getBoundsForNewConfiguration(newStackBounds);
5285 mStackSupervisor.resizeStackLocked(
5286 stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
5287 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
5288 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
5289 }
5290
5291 /** Applies latest configuration and/or visibility updates if needed. */
5292 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
5293 boolean kept = true;
Andrii Kulian5f750bc2018-07-17 08:57:23 -07005294 final ActivityStack mainStack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005295 // mainStack is null during startup.
5296 if (mainStack != null) {
5297 if (changes != 0 && starting == null) {
5298 // If the configuration changed, and the caller is not already
5299 // in the process of starting an activity, then find the top
5300 // activity to check if its configuration needs to change.
5301 starting = mainStack.topRunningActivityLocked();
5302 }
5303
5304 if (starting != null) {
5305 kept = starting.ensureActivityConfiguration(changes,
5306 false /* preserveWindow */);
5307 // And we need to make sure at this point that all other activities
5308 // are made visible with the correct configuration.
5309 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
5310 !PRESERVE_WINDOWS);
5311 }
5312 }
5313
5314 return kept;
5315 }
5316
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005317 void scheduleAppGcsLocked() {
5318 mH.post(() -> mAmInternal.scheduleAppGcs());
5319 }
5320
Wale Ogunwale53783742018-09-16 10:21:51 -07005321 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
5322 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
5323 }
5324
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005325 /**
5326 * Returns the PackageManager. Used by classes hosted by {@link ActivityTaskManagerService}. The
5327 * PackageManager could be unavailable at construction time and therefore needs to be accessed
5328 * on demand.
5329 */
5330 IPackageManager getPackageManager() {
5331 return AppGlobals.getPackageManager();
5332 }
5333
5334 PackageManagerInternal getPackageManagerInternalLocked() {
5335 if (mPmInternal == null) {
5336 mPmInternal = LocalServices.getService(PackageManagerInternal.class);
5337 }
5338 return mPmInternal;
5339 }
5340
Wale Ogunwale008163e2018-07-23 23:11:08 -07005341 AppWarnings getAppWarningsLocked() {
5342 return mAppWarnings;
5343 }
5344
Wale Ogunwale214f3482018-10-04 11:00:47 -07005345 Intent getHomeIntent() {
5346 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
5347 intent.setComponent(mTopComponent);
5348 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
5349 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5350 intent.addCategory(Intent.CATEGORY_HOME);
5351 }
5352 return intent;
5353 }
5354
5355 /**
5356 * This starts home activity on displays that can have system decorations and only if the
5357 * home activity can have multiple instances.
5358 */
5359 boolean startHomeActivityLocked(int userId, String reason, int displayId) {
5360 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL && mTopAction == null) {
5361 // We are running in factory test mode, but unable to find the factory test app, so just
5362 // sit around displaying the error message and don't try to start anything.
5363 return false;
5364 }
5365
5366 final Intent intent = getHomeIntent();
5367 ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
5368 if (aInfo != null) {
5369 intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
5370 // Don't do this if the home app is currently being instrumented.
5371 aInfo = new ActivityInfo(aInfo);
5372 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
5373 WindowProcessController app =
5374 getProcessController(aInfo.processName, aInfo.applicationInfo.uid);
5375 if (app == null || !app.isInstrumenting()) {
5376 intent.setFlags(intent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
5377 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
5378 // For ANR debugging to verify if the user activity is the one that actually
5379 // launched.
5380 final String myReason = reason + ":" + userId + ":" + resolvedUserId;
5381 getActivityStartController().startHomeActivity(intent, aInfo, myReason, displayId);
5382 }
5383 } else {
5384 Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
5385 }
5386
5387 return true;
5388 }
5389
5390 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
5391 ActivityInfo ai = null;
5392 final ComponentName comp = intent.getComponent();
5393 try {
5394 if (comp != null) {
5395 // Factory test.
5396 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
5397 } else {
5398 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
5399 intent,
5400 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
5401 flags, userId);
5402
5403 if (info != null) {
5404 ai = info.activityInfo;
5405 }
5406 }
5407 } catch (RemoteException e) {
5408 // ignore
5409 }
5410
5411 return ai;
5412 }
5413
5414 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
5415 if (info == null) return null;
5416 ApplicationInfo newInfo = new ApplicationInfo(info);
5417 newInfo.initForUser(userId);
5418 return newInfo;
5419 }
5420
Wale Ogunwale9c103022018-10-18 07:44:54 -07005421 WindowProcessController getProcessController(String processName, int uid) {
Wale Ogunwale214f3482018-10-04 11:00:47 -07005422 if (uid == SYSTEM_UID) {
5423 // The system gets to run in any process. If there are multiple processes with the same
5424 // uid, just pick the first (this should never happen).
5425 final SparseArray<WindowProcessController> procs =
5426 mProcessNames.getMap().get(processName);
5427 if (procs == null) return null;
5428 final int procCount = procs.size();
5429 for (int i = 0; i < procCount; i++) {
5430 final int procUid = procs.keyAt(i);
5431 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
5432 // Don't use an app process or different user process for system component.
5433 continue;
5434 }
5435 return procs.valueAt(i);
5436 }
5437 }
5438
5439 return mProcessNames.get(processName, uid);
5440 }
5441
Wale Ogunwale342fbe92018-10-09 08:44:10 -07005442 WindowProcessController getProcessController(IApplicationThread thread) {
5443 if (thread == null) {
5444 return null;
5445 }
5446
5447 final IBinder threadBinder = thread.asBinder();
5448 final ArrayMap<String, SparseArray<WindowProcessController>> pmap = mProcessNames.getMap();
5449 for (int i = pmap.size()-1; i >= 0; i--) {
5450 final SparseArray<WindowProcessController> procs = pmap.valueAt(i);
5451 for (int j = procs.size() - 1; j >= 0; j--) {
5452 final WindowProcessController proc = procs.valueAt(j);
5453 if (proc.hasThread() && proc.getThread().asBinder() == threadBinder) {
5454 return proc;
5455 }
5456 }
5457 }
5458
5459 return null;
5460 }
5461
Wale Ogunwalebff2df42018-10-18 17:09:19 -07005462 int getUidStateLocked(int uid) {
5463 return mActiveUids.get(uid, PROCESS_STATE_NONEXISTENT);
5464 }
5465
Wale Ogunwale9de19442018-10-18 19:05:03 -07005466 /**
5467 * @return whitelist tag for a uid from mPendingTempWhitelist, null if not currently on
5468 * the whitelist
5469 */
5470 String getPendingTempWhitelistTagForUidLocked(int uid) {
5471 return mPendingTempWhitelist.get(uid);
5472 }
5473
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005474 void logAppTooSlow(WindowProcessController app, long startTime, String msg) {
5475 if (true || Build.IS_USER) {
5476 return;
5477 }
5478
5479 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5480 StrictMode.allowThreadDiskWrites();
5481 try {
5482 File tracesDir = new File("/data/anr");
5483 File tracesFile = null;
5484 try {
5485 tracesFile = File.createTempFile("app_slow", null, tracesDir);
5486
5487 StringBuilder sb = new StringBuilder();
5488 Time tobj = new Time();
5489 tobj.set(System.currentTimeMillis());
5490 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5491 sb.append(": ");
5492 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5493 sb.append(" since ");
5494 sb.append(msg);
5495 FileOutputStream fos = new FileOutputStream(tracesFile);
5496 fos.write(sb.toString().getBytes());
5497 if (app == null) {
5498 fos.write("\n*** No application process!".getBytes());
5499 }
5500 fos.close();
5501 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5502 } catch (IOException e) {
5503 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesFile, e);
5504 return;
5505 }
5506
5507 if (app != null && app.getPid() > 0) {
5508 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5509 firstPids.add(app.getPid());
5510 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, null, null);
5511 }
5512
5513 File lastTracesFile = null;
5514 File curTracesFile = null;
5515 for (int i=9; i>=0; i--) {
5516 String name = String.format(Locale.US, "slow%02d.txt", i);
5517 curTracesFile = new File(tracesDir, name);
5518 if (curTracesFile.exists()) {
5519 if (lastTracesFile != null) {
5520 curTracesFile.renameTo(lastTracesFile);
5521 } else {
5522 curTracesFile.delete();
5523 }
5524 }
5525 lastTracesFile = curTracesFile;
5526 }
5527 tracesFile.renameTo(curTracesFile);
5528 } finally {
5529 StrictMode.setThreadPolicy(oldPolicy);
5530 }
5531 }
5532
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005533 final class H extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005534 static final int REPORT_TIME_TRACKER_MSG = 1;
Wale Ogunwale98875612018-10-12 07:53:02 -07005535 static final int FIRST_ACTIVITY_STACK_MSG = 100;
5536 static final int FIRST_SUPERVISOR_STACK_MSG = 200;
Wale Ogunwalef6733932018-06-27 05:14:34 -07005537
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005538 public H(Looper looper) {
5539 super(looper, null, true);
5540 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005541
5542 @Override
5543 public void handleMessage(Message msg) {
5544 switch (msg.what) {
5545 case REPORT_TIME_TRACKER_MSG: {
5546 AppTimeTracker tracker = (AppTimeTracker) msg.obj;
5547 tracker.deliverResult(mContext);
5548 } break;
5549 }
5550 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005551 }
5552
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005553 final class UiHandler extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005554 static final int DISMISS_DIALOG_UI_MSG = 1;
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005555
5556 public UiHandler() {
5557 super(com.android.server.UiThread.get().getLooper(), null, true);
5558 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005559
5560 @Override
5561 public void handleMessage(Message msg) {
5562 switch (msg.what) {
5563 case DISMISS_DIALOG_UI_MSG: {
5564 final Dialog d = (Dialog) msg.obj;
5565 d.dismiss();
5566 break;
5567 }
5568 }
5569 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005570 }
5571
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005572 final class LocalService extends ActivityTaskManagerInternal {
5573 @Override
5574 public SleepToken acquireSleepToken(String tag, int displayId) {
5575 Preconditions.checkNotNull(tag);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005576 return ActivityTaskManagerService.this.acquireSleepToken(tag, displayId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005577 }
5578
5579 @Override
5580 public ComponentName getHomeActivityForUser(int userId) {
5581 synchronized (mGlobalLock) {
Louis Changbd48dca2018-08-29 17:44:34 +08005582 ActivityRecord homeActivity =
5583 mStackSupervisor.getDefaultDisplayHomeActivityForUser(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005584 return homeActivity == null ? null : homeActivity.realActivity;
5585 }
5586 }
5587
5588 @Override
5589 public void onLocalVoiceInteractionStarted(IBinder activity,
5590 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
5591 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005592 onLocalVoiceInteractionStartedLocked(activity, voiceSession, voiceInteractor);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005593 }
5594 }
5595
5596 @Override
5597 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
5598 synchronized (mGlobalLock) {
5599 mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
5600 reasons, timestamp);
5601 }
5602 }
5603
5604 @Override
5605 public void notifyAppTransitionFinished() {
5606 synchronized (mGlobalLock) {
5607 mStackSupervisor.notifyAppTransitionDone();
5608 }
5609 }
5610
5611 @Override
5612 public void notifyAppTransitionCancelled() {
5613 synchronized (mGlobalLock) {
5614 mStackSupervisor.notifyAppTransitionDone();
5615 }
5616 }
5617
5618 @Override
5619 public List<IBinder> getTopVisibleActivities() {
5620 synchronized (mGlobalLock) {
5621 return mStackSupervisor.getTopVisibleActivities();
5622 }
5623 }
5624
5625 @Override
5626 public void notifyDockedStackMinimizedChanged(boolean minimized) {
5627 synchronized (mGlobalLock) {
5628 mStackSupervisor.setDockedStackMinimized(minimized);
5629 }
5630 }
5631
5632 @Override
5633 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
5634 Bundle bOptions) {
5635 Preconditions.checkNotNull(intents, "intents");
5636 final String[] resolvedTypes = new String[intents.length];
5637
5638 // UID of the package on user userId.
5639 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
5640 // packageUid may not be initialized.
5641 int packageUid = 0;
5642 final long ident = Binder.clearCallingIdentity();
5643
5644 try {
5645 for (int i = 0; i < intents.length; i++) {
5646 resolvedTypes[i] =
5647 intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
5648 }
5649
5650 packageUid = AppGlobals.getPackageManager().getPackageUid(
5651 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
5652 } catch (RemoteException e) {
5653 // Shouldn't happen.
5654 } finally {
5655 Binder.restoreCallingIdentity(ident);
5656 }
5657
5658 synchronized (mGlobalLock) {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07005659 return getActivityStartController().startActivitiesInPackage(
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005660 packageUid, packageName,
5661 intents, resolvedTypes, null /* resultTo */,
5662 SafeActivityOptions.fromBundle(bOptions), userId,
Michal Karpinski201bc0c2018-07-20 15:32:00 +01005663 false /* validateIncomingUser */, null /* originatingPendingIntent */);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005664 }
5665 }
5666
5667 @Override
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07005668 public int startActivitiesInPackage(int uid, String callingPackage, Intent[] intents,
5669 String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, int userId,
5670 boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent) {
5671 synchronized (mGlobalLock) {
5672 return getActivityStartController().startActivitiesInPackage(uid, callingPackage,
5673 intents, resolvedTypes, resultTo, options, userId, validateIncomingUser,
5674 originatingPendingIntent);
5675 }
5676 }
5677
5678 @Override
5679 public int startActivityInPackage(int uid, int realCallingPid, int realCallingUid,
5680 String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
5681 String resultWho, int requestCode, int startFlags, SafeActivityOptions options,
5682 int userId, TaskRecord inTask, String reason, boolean validateIncomingUser,
5683 PendingIntentRecord originatingPendingIntent) {
5684 synchronized (mGlobalLock) {
5685 return getActivityStartController().startActivityInPackage(uid, realCallingPid,
5686 realCallingUid, callingPackage, intent, resolvedType, resultTo, resultWho,
5687 requestCode, startFlags, options, userId, inTask, reason,
5688 validateIncomingUser, originatingPendingIntent);
5689 }
5690 }
5691
5692 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005693 public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
5694 Intent intent, Bundle options, int userId) {
5695 return ActivityTaskManagerService.this.startActivityAsUser(
5696 caller, callerPacakge, intent,
5697 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
5698 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
5699 false /*validateIncomingUser*/);
5700 }
5701
5702 @Override
5703 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
5704 synchronized (mGlobalLock) {
5705
5706 // We might change the visibilities here, so prepare an empty app transition which
5707 // might be overridden later if we actually change visibilities.
5708 final boolean wasTransitionSet =
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005709 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005710 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005711 mWindowManager.prepareAppTransition(TRANSIT_NONE,
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005712 false /* alwaysKeepCurrent */);
5713 }
5714 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5715
5716 // If there was a transition set already we don't want to interfere with it as we
5717 // might be starting it too early.
5718 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005719 mWindowManager.executeAppTransition();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005720 }
5721 }
5722 if (callback != null) {
5723 callback.run();
5724 }
5725 }
5726
5727 @Override
5728 public void notifyKeyguardTrustedChanged() {
5729 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005730 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005731 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5732 }
5733 }
5734 }
5735
5736 /**
5737 * Called after virtual display Id is updated by
5738 * {@link com.android.server.vr.Vr2dDisplay} with a specific
5739 * {@param vrVr2dDisplayId}.
5740 */
5741 @Override
5742 public void setVr2dDisplayId(int vr2dDisplayId) {
5743 if (DEBUG_STACK) Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
5744 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005745 mVr2dDisplayId = vr2dDisplayId;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005746 }
5747 }
5748
5749 @Override
5750 public void setFocusedActivity(IBinder token) {
5751 synchronized (mGlobalLock) {
5752 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
5753 if (r == null) {
5754 throw new IllegalArgumentException(
5755 "setFocusedActivity: No activity record matching token=" + token);
5756 }
Louis Chang19443452018-10-09 12:10:21 +08005757 if (r.moveFocusableActivityToTop("setFocusedActivity")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08005758 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005759 }
5760 }
5761 }
5762
5763 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005764 public void registerScreenObserver(ScreenObserver observer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005765 mScreenObservers.add(observer);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005766 }
5767
5768 @Override
5769 public boolean isCallerRecents(int callingUid) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005770 return getRecentTasks().isCallerRecents(callingUid);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005771 }
5772
5773 @Override
5774 public boolean isRecentsComponentHomeActivity(int userId) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005775 return getRecentTasks().isRecentsComponentHomeActivity(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005776 }
5777
5778 @Override
5779 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
5780 ActivityTaskManagerService.this.cancelRecentsAnimation(restoreHomeStackPosition);
5781 }
5782
5783 @Override
5784 public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005785 ActivityTaskManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005786 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005787
5788 @Override
5789 public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
5790 synchronized (mGlobalLock) {
5791 mActiveVoiceInteractionServiceComponent = component;
5792 }
5793 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005794
5795 @Override
5796 public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
5797 if (!mAmInternal.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
5798 return;
5799 }
5800 synchronized (mGlobalLock) {
5801 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
5802 if (types == null) {
5803 if (uid < 0) {
5804 return;
5805 }
5806 types = new ArrayMap<>();
5807 mAllowAppSwitchUids.put(userId, types);
5808 }
5809 if (uid < 0) {
5810 types.remove(type);
5811 } else {
5812 types.put(type, uid);
5813 }
5814 }
5815 }
5816
5817 @Override
5818 public void onUserStopped(int userId) {
5819 synchronized (mGlobalLock) {
5820 getRecentTasks().unloadUserDataFromMemoryLocked(userId);
5821 mAllowAppSwitchUids.remove(userId);
5822 }
5823 }
5824
5825 @Override
5826 public boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
5827 synchronized (mGlobalLock) {
5828 return ActivityTaskManagerService.this.isGetTasksAllowed(
5829 caller, callingPid, callingUid);
5830 }
5831 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005832
5833 @Override
5834 public void onProcessAdded(WindowProcessController proc) {
5835 synchronized (mGlobalLock) {
5836 mProcessNames.put(proc.mName, proc.mUid, proc);
5837 }
5838 }
5839
5840 @Override
5841 public void onProcessRemoved(String name, int uid) {
5842 synchronized (mGlobalLock) {
5843 mProcessNames.remove(name, uid);
5844 }
5845 }
5846
5847 @Override
5848 public void onCleanUpApplicationRecord(WindowProcessController proc) {
5849 synchronized (mGlobalLock) {
5850 if (proc == mHomeProcess) {
5851 mHomeProcess = null;
5852 }
5853 if (proc == mPreviousProcess) {
5854 mPreviousProcess = null;
5855 }
5856 }
5857 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005858
5859 @Override
5860 public int getTopProcessState() {
5861 synchronized (mGlobalLock) {
5862 return mTopProcessState;
5863 }
5864 }
5865
5866 @Override
Wale Ogunwale53783742018-09-16 10:21:51 -07005867 public boolean isHeavyWeightProcess(WindowProcessController proc) {
5868 synchronized (mGlobalLock) {
5869 return proc == mHeavyWeightProcess;
5870 }
5871 }
5872
5873 @Override
5874 public void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
5875 synchronized (mGlobalLock) {
5876 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(proc);
5877 }
5878 }
5879
5880 @Override
5881 public void finishHeavyWeightApp() {
5882 synchronized (mGlobalLock) {
Sudheer Shankaee1da272018-10-20 20:11:44 -07005883 if (mHeavyWeightProcess != null) {
5884 mHeavyWeightProcess.finishActivities();
5885 }
Wale Ogunwale53783742018-09-16 10:21:51 -07005886 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(
5887 mHeavyWeightProcess);
5888 }
5889 }
5890
5891 @Override
Wale Ogunwalef6733932018-06-27 05:14:34 -07005892 public boolean isSleeping() {
5893 synchronized (mGlobalLock) {
5894 return isSleepingLocked();
5895 }
5896 }
5897
5898 @Override
5899 public boolean isShuttingDown() {
5900 synchronized (mGlobalLock) {
5901 return mShuttingDown;
5902 }
5903 }
5904
5905 @Override
5906 public boolean shuttingDown(boolean booted, int timeout) {
5907 synchronized (mGlobalLock) {
5908 mShuttingDown = true;
5909 mStackSupervisor.prepareForShutdownLocked();
5910 updateEventDispatchingLocked(booted);
Wale Ogunwaled4d67d02018-10-25 18:09:39 -07005911 notifyTaskPersisterLocked(null, true);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005912 return mStackSupervisor.shutdownLocked(timeout);
5913 }
5914 }
5915
5916 @Override
5917 public void enableScreenAfterBoot(boolean booted) {
5918 synchronized (mGlobalLock) {
5919 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5920 SystemClock.uptimeMillis());
5921 mWindowManager.enableScreenAfterBoot();
5922 updateEventDispatchingLocked(booted);
5923 }
5924 }
5925
5926 @Override
5927 public boolean showStrictModeViolationDialog() {
5928 synchronized (mGlobalLock) {
5929 return mShowDialogs && !mSleeping && !mShuttingDown;
5930 }
5931 }
5932
5933 @Override
5934 public void showSystemReadyErrorDialogsIfNeeded() {
5935 synchronized (mGlobalLock) {
5936 try {
5937 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
5938 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
5939 + " data partition or your device will be unstable.");
5940 mUiHandler.post(() -> {
5941 if (mShowDialogs) {
5942 AlertDialog d = new BaseErrorDialog(mUiContext);
5943 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5944 d.setCancelable(false);
5945 d.setTitle(mUiContext.getText(R.string.android_system_label));
5946 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
5947 d.setButton(DialogInterface.BUTTON_POSITIVE,
5948 mUiContext.getText(R.string.ok),
5949 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5950 d.show();
5951 }
5952 });
5953 }
5954 } catch (RemoteException e) {
5955 }
5956
5957 if (!Build.isBuildConsistent()) {
5958 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
5959 mUiHandler.post(() -> {
5960 if (mShowDialogs) {
5961 AlertDialog d = new BaseErrorDialog(mUiContext);
5962 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5963 d.setCancelable(false);
5964 d.setTitle(mUiContext.getText(R.string.android_system_label));
5965 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
5966 d.setButton(DialogInterface.BUTTON_POSITIVE,
5967 mUiContext.getText(R.string.ok),
5968 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5969 d.show();
5970 }
5971 });
5972 }
5973 }
5974 }
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005975
5976 @Override
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005977 public void onProcessMapped(int pid, WindowProcessController proc) {
5978 synchronized (mGlobalLock) {
5979 mPidMap.put(pid, proc);
5980 }
5981 }
5982
5983 @Override
5984 public void onProcessUnMapped(int pid) {
5985 synchronized (mGlobalLock) {
5986 mPidMap.remove(pid);
5987 }
5988 }
Wale Ogunwale008163e2018-07-23 23:11:08 -07005989
5990 @Override
5991 public void onPackageDataCleared(String name) {
5992 synchronized (mGlobalLock) {
Wale Ogunwale53783742018-09-16 10:21:51 -07005993 mCompatModePackages.handlePackageDataClearedLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07005994 mAppWarnings.onPackageDataCleared(name);
5995 }
5996 }
5997
5998 @Override
5999 public void onPackageUninstalled(String name) {
6000 synchronized (mGlobalLock) {
6001 mAppWarnings.onPackageUninstalled(name);
Wale Ogunwale53783742018-09-16 10:21:51 -07006002 mCompatModePackages.handlePackageUninstalledLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07006003 }
6004 }
Wale Ogunwale53783742018-09-16 10:21:51 -07006005
6006 @Override
6007 public void onPackageAdded(String name, boolean replacing) {
6008 synchronized (mGlobalLock) {
6009 mCompatModePackages.handlePackageAddedLocked(name, replacing);
6010 }
6011 }
6012
6013 @Override
Wale Ogunwale31913b52018-10-13 08:29:31 -07006014 public void onPackageReplaced(ApplicationInfo aInfo) {
6015 synchronized (mGlobalLock) {
6016 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
6017 }
6018 }
6019
6020 @Override
Wale Ogunwale53783742018-09-16 10:21:51 -07006021 public CompatibilityInfo compatibilityInfoForPackage(ApplicationInfo ai) {
6022 synchronized (mGlobalLock) {
6023 return compatibilityInfoForPackageLocked(ai);
6024 }
6025 }
6026
Yunfan Chen75157d72018-07-27 14:47:21 +09006027 /**
6028 * Set the corresponding display information for the process global configuration. To be
6029 * called when we need to show IME on a different display.
6030 *
6031 * @param pid The process id associated with the IME window.
6032 * @param displayId The ID of the display showing the IME.
6033 */
6034 @Override
Yunfan Chen79b96062018-10-17 12:45:23 -07006035 public void onImeWindowSetOnDisplay(final int pid, final int displayId) {
Yunfan Chen75157d72018-07-27 14:47:21 +09006036 if (pid == MY_PID || pid < 0) {
6037 if (DEBUG_CONFIGURATION) {
6038 Slog.w(TAG,
6039 "Trying to update display configuration for system/invalid process.");
6040 }
6041 return;
6042 }
6043 mH.post(() -> {
6044 synchronized (mGlobalLock) {
Yunfan Chen79b96062018-10-17 12:45:23 -07006045 final ActivityDisplay activityDisplay =
6046 mStackSupervisor.getActivityDisplay(displayId);
6047 if (activityDisplay == null) {
6048 // Call might come when display is not yet added or has been removed.
Yunfan Chen75157d72018-07-27 14:47:21 +09006049 if (DEBUG_CONFIGURATION) {
6050 Slog.w(TAG, "Trying to update display configuration for non-existing "
Yunfan Chen79b96062018-10-17 12:45:23 -07006051 + "displayId=" + displayId);
Yunfan Chen75157d72018-07-27 14:47:21 +09006052 }
6053 return;
6054 }
Yunfan Chen79b96062018-10-17 12:45:23 -07006055 final WindowProcessController process = mPidMap.get(pid);
6056 if (process == null) {
Yunfan Chen75157d72018-07-27 14:47:21 +09006057 if (DEBUG_CONFIGURATION) {
Yunfan Chen79b96062018-10-17 12:45:23 -07006058 Slog.w(TAG, "Trying to update display configuration for invalid "
6059 + "process, pid=" + pid);
Yunfan Chen75157d72018-07-27 14:47:21 +09006060 }
6061 return;
6062 }
Yunfan Chen79b96062018-10-17 12:45:23 -07006063 process.registerDisplayConfigurationListenerLocked(activityDisplay);
Yunfan Chen75157d72018-07-27 14:47:21 +09006064 }
6065 });
Yunfan Chen79b96062018-10-17 12:45:23 -07006066
Yunfan Chen75157d72018-07-27 14:47:21 +09006067 }
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07006068
6069 @Override
6070 public void sendActivityResult(int callingUid, IBinder activityToken, String resultWho,
6071 int requestCode, int resultCode, Intent data) {
6072 synchronized (mGlobalLock) {
6073 final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
6074 if (r != null && r.getStack() != null) {
6075 r.getStack().sendActivityResultLocked(callingUid, r, resultWho, requestCode,
6076 resultCode, data);
6077 }
6078 }
6079 }
6080
6081 @Override
6082 public void clearPendingResultForActivity(IBinder activityToken,
6083 WeakReference<PendingIntentRecord> pir) {
6084 synchronized (mGlobalLock) {
6085 final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
6086 if (r != null && r.pendingResults != null) {
6087 r.pendingResults.remove(pir);
6088 }
6089 }
6090 }
6091
6092 @Override
6093 public IIntentSender getIntentSender(int type, String packageName,
6094 int callingUid, int userId, IBinder token, String resultWho,
6095 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6096 Bundle bOptions) {
6097 synchronized (mGlobalLock) {
6098 return getIntentSenderLocked(type, packageName, callingUid, userId, token,
6099 resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6100 }
6101 }
Wale Ogunwalec4e63a42018-10-02 13:19:54 -07006102
6103 @Override
6104 public ActivityServiceConnectionsHolder getServiceConnectionsHolder(IBinder token) {
6105 synchronized (mGlobalLock) {
6106 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
6107 if (r == null) {
6108 return null;
6109 }
6110 if (r.mServiceConnectionsHolder == null) {
6111 r.mServiceConnectionsHolder = new ActivityServiceConnectionsHolder(
6112 ActivityTaskManagerService.this, r);
6113 }
6114
6115 return r.mServiceConnectionsHolder;
6116 }
6117 }
Wale Ogunwale214f3482018-10-04 11:00:47 -07006118
6119 @Override
6120 public Intent getHomeIntent() {
6121 synchronized (mGlobalLock) {
6122 return ActivityTaskManagerService.this.getHomeIntent();
6123 }
6124 }
6125
6126 @Override
6127 public boolean startHomeActivity(int userId, String reason) {
6128 synchronized (mGlobalLock) {
6129 return startHomeActivityLocked(userId, reason, DEFAULT_DISPLAY);
6130 }
6131 }
6132
6133 @Override
6134 public boolean isFactoryTestProcess(WindowProcessController wpc) {
6135 synchronized (mGlobalLock) {
6136 if (mFactoryTest == FACTORY_TEST_OFF) {
6137 return false;
6138 }
6139 if (mFactoryTest == FACTORY_TEST_LOW_LEVEL && mTopComponent != null
6140 && wpc.mName.equals(mTopComponent.getPackageName())) {
6141 return true;
6142 }
6143 return mFactoryTest == FACTORY_TEST_HIGH_LEVEL
6144 && (wpc.mInfo.flags & FLAG_FACTORY_TEST) != 0;
6145 }
6146 }
6147
6148 @Override
6149 public void updateTopComponentForFactoryTest() {
6150 synchronized (mGlobalLock) {
6151 if (mFactoryTest != FACTORY_TEST_LOW_LEVEL) {
6152 return;
6153 }
6154 final ResolveInfo ri = mContext.getPackageManager()
6155 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), STOCK_PM_FLAGS);
6156 final CharSequence errorMsg;
6157 if (ri != null) {
6158 final ActivityInfo ai = ri.activityInfo;
6159 final ApplicationInfo app = ai.applicationInfo;
6160 if ((app.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
6161 mTopAction = Intent.ACTION_FACTORY_TEST;
6162 mTopData = null;
6163 mTopComponent = new ComponentName(app.packageName, ai.name);
6164 errorMsg = null;
6165 } else {
6166 errorMsg = mContext.getResources().getText(
6167 com.android.internal.R.string.factorytest_not_system);
6168 }
6169 } else {
6170 errorMsg = mContext.getResources().getText(
6171 com.android.internal.R.string.factorytest_no_action);
6172 }
6173 if (errorMsg == null) {
6174 return;
6175 }
6176
6177 mTopAction = null;
6178 mTopData = null;
6179 mTopComponent = null;
6180 mUiHandler.post(() -> {
6181 Dialog d = new FactoryErrorDialog(mUiContext, errorMsg);
6182 d.show();
Wale Ogunwale342fbe92018-10-09 08:44:10 -07006183 mAmInternal.ensureBootCompleted();
Wale Ogunwale214f3482018-10-04 11:00:47 -07006184 });
6185 }
6186 }
Wale Ogunwale31913b52018-10-13 08:29:31 -07006187
6188 @Override
6189 public void handleAppDied(WindowProcessController wpc, boolean restarting,
6190 Runnable finishInstrumentationCallback) {
6191 synchronized (mGlobalLock) {
6192 // Remove this application's activities from active lists.
6193 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(wpc);
6194
6195 wpc.clearRecentTasks();
6196 wpc.clearActivities();
6197
6198 if (wpc.isInstrumenting()) {
6199 finishInstrumentationCallback.run();
6200 }
6201
6202 mWindowManager.deferSurfaceLayout();
6203 try {
6204 if (!restarting && hasVisibleActivities
6205 && !mStackSupervisor.resumeFocusedStacksTopActivitiesLocked()) {
6206 // If there was nothing to resume, and we are not already restarting this
6207 // process, but there is a visible activity that is hosted by the process...
6208 // then make sure all visible activities are running, taking care of
6209 // restarting this process.
6210 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6211 }
6212 } finally {
6213 mWindowManager.continueSurfaceLayout();
6214 }
6215 }
6216 }
6217
6218 @Override
6219 public void closeSystemDialogs(String reason) {
6220 enforceNotIsolatedCaller("closeSystemDialogs");
6221
6222 final int pid = Binder.getCallingPid();
6223 final int uid = Binder.getCallingUid();
6224 final long origId = Binder.clearCallingIdentity();
6225 try {
6226 synchronized (mGlobalLock) {
6227 // Only allow this from foreground processes, so that background
6228 // applications can't abuse it to prevent system UI from being shown.
6229 if (uid >= FIRST_APPLICATION_UID) {
6230 final WindowProcessController proc = mPidMap.get(pid);
6231 if (!proc.isPerceptible()) {
6232 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6233 + " from background process " + proc);
6234 return;
6235 }
6236 }
Wale Ogunwale31913b52018-10-13 08:29:31 -07006237 mWindowManager.closeSystemDialogs(reason);
6238
6239 mStackSupervisor.closeSystemDialogsLocked();
Wale Ogunwale31913b52018-10-13 08:29:31 -07006240 }
Wale Ogunwale2ea36d42018-10-18 10:27:31 -07006241 // Call into AM outside the synchronized block.
6242 mAmInternal.broadcastCloseSystemDialogs(reason);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006243 } finally {
6244 Binder.restoreCallingIdentity(origId);
6245 }
6246 }
6247
6248 @Override
6249 public void cleanupDisabledPackageComponents(
6250 String packageName, Set<String> disabledClasses, int userId, boolean booted) {
6251 synchronized (mGlobalLock) {
6252 // Clean-up disabled activities.
6253 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6254 packageName, disabledClasses, true, false, userId) && booted) {
6255 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
6256 mStackSupervisor.scheduleIdleLocked();
6257 }
6258
6259 // Clean-up disabled tasks
6260 getRecentTasks().cleanupDisabledPackageTasksLocked(
6261 packageName, disabledClasses, userId);
6262 }
6263 }
6264
6265 @Override
6266 public boolean onForceStopPackage(String packageName, boolean doit, boolean evenPersistent,
6267 int userId) {
6268 synchronized (mGlobalLock) {
6269
6270 boolean didSomething =
6271 getActivityStartController().clearPendingActivityLaunches(packageName);
6272 didSomething |= mStackSupervisor.finishDisabledPackageActivitiesLocked(packageName,
6273 null, doit, evenPersistent, userId);
6274 return didSomething;
6275 }
6276 }
6277
6278 @Override
6279 public void resumeTopActivities(boolean scheduleIdle) {
6280 synchronized (mGlobalLock) {
6281 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
6282 if (scheduleIdle) {
6283 mStackSupervisor.scheduleIdleLocked();
6284 }
6285 }
6286 }
6287
6288 @Override
6289 public void preBindApplication(WindowProcessController wpc) {
6290 synchronized (mGlobalLock) {
6291 mStackSupervisor.getActivityMetricsLogger().notifyBindApplication(wpc.mInfo);
6292 }
6293 }
6294
6295 @Override
6296 public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
6297 synchronized (mGlobalLock) {
6298 return mStackSupervisor.attachApplicationLocked(wpc);
6299 }
6300 }
6301
6302 @Override
6303 public void notifyLockedProfile(@UserIdInt int userId, int currentUserId) {
6304 try {
6305 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
6306 throw new SecurityException("Only privileged app can call notifyLockedProfile");
6307 }
6308 } catch (RemoteException ex) {
6309 throw new SecurityException("Fail to check is caller a privileged app", ex);
6310 }
6311
6312 synchronized (mGlobalLock) {
6313 final long ident = Binder.clearCallingIdentity();
6314 try {
6315 if (mAmInternal.shouldConfirmCredentials(userId)) {
6316 if (mKeyguardController.isKeyguardLocked()) {
6317 // Showing launcher to avoid user entering credential twice.
6318 startHomeActivity(currentUserId, "notifyLockedProfile");
6319 }
6320 mStackSupervisor.lockAllProfileTasks(userId);
6321 }
6322 } finally {
6323 Binder.restoreCallingIdentity(ident);
6324 }
6325 }
6326 }
6327
6328 @Override
6329 public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
6330 mAmInternal.enforceCallingPermission(
6331 MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
6332
6333 synchronized (mGlobalLock) {
6334 final long ident = Binder.clearCallingIdentity();
6335 try {
6336 intent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
6337 FLAG_ACTIVITY_TASK_ON_HOME);
6338 ActivityOptions activityOptions = options != null
6339 ? new ActivityOptions(options) : ActivityOptions.makeBasic();
6340 activityOptions.setLaunchTaskId(
6341 mStackSupervisor.getDefaultDisplayHomeActivity().getTask().taskId);
6342 mContext.startActivityAsUser(intent, activityOptions.toBundle(),
6343 UserHandle.CURRENT);
6344 } finally {
6345 Binder.restoreCallingIdentity(ident);
6346 }
6347 }
6348 }
6349
6350 @Override
6351 public void writeActivitiesToProto(ProtoOutputStream proto) {
6352 synchronized (mGlobalLock) {
6353 // The output proto of "activity --proto activities"
6354 // is ActivityManagerServiceDumpActivitiesProto
6355 mStackSupervisor.writeToProto(proto,
6356 ActivityManagerServiceDumpActivitiesProto.ACTIVITY_STACK_SUPERVISOR);
6357 }
6358 }
6359
6360 @Override
6361 public void saveANRState(String reason) {
6362 synchronized (mGlobalLock) {
6363 final StringWriter sw = new StringWriter();
6364 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
6365 pw.println(" ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
6366 if (reason != null) {
6367 pw.println(" Reason: " + reason);
6368 }
6369 pw.println();
6370 getActivityStartController().dump(pw, " ", null);
6371 pw.println();
6372 pw.println("-------------------------------------------------------------------------------");
6373 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
6374 true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
6375 "" /* header */);
6376 pw.println();
6377 pw.close();
6378
6379 mLastANRState = sw.toString();
6380 }
6381 }
6382
6383 @Override
6384 public void clearSavedANRState() {
6385 synchronized (mGlobalLock) {
6386 mLastANRState = null;
6387 }
6388 }
6389
6390 @Override
6391 public void dump(String cmd, FileDescriptor fd, PrintWriter pw, String[] args, int opti,
6392 boolean dumpAll, boolean dumpClient, String dumpPackage) {
6393 synchronized (mGlobalLock) {
6394 if (DUMP_ACTIVITIES_CMD.equals(cmd) || DUMP_ACTIVITIES_SHORT_CMD.equals(cmd)) {
6395 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
6396 } else if (DUMP_LASTANR_CMD.equals(cmd)) {
6397 dumpLastANRLocked(pw);
6398 } else if (DUMP_LASTANR_TRACES_CMD.equals(cmd)) {
6399 dumpLastANRTracesLocked(pw);
6400 } else if (DUMP_STARTER_CMD.equals(cmd)) {
6401 dumpActivityStarterLocked(pw, dumpPackage);
6402 } else if (DUMP_CONTAINERS_CMD.equals(cmd)) {
6403 dumpActivityContainersLocked(pw);
6404 } else if (DUMP_RECENTS_CMD.equals(cmd) || DUMP_RECENTS_SHORT_CMD.equals(cmd)) {
6405 if (getRecentTasks() != null) {
6406 getRecentTasks().dump(pw, dumpAll, dumpPackage);
6407 }
6408 }
6409 }
6410 }
6411
6412 @Override
6413 public boolean dumpForProcesses(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
6414 String dumpPackage, int dumpAppId, boolean needSep, boolean testPssMode,
6415 int wakefulness) {
6416 synchronized (mGlobalLock) {
6417 if (mHomeProcess != null && (dumpPackage == null
6418 || mHomeProcess.mPkgList.contains(dumpPackage))) {
6419 if (needSep) {
6420 pw.println();
6421 needSep = false;
6422 }
6423 pw.println(" mHomeProcess: " + mHomeProcess);
6424 }
6425 if (mPreviousProcess != null && (dumpPackage == null
6426 || mPreviousProcess.mPkgList.contains(dumpPackage))) {
6427 if (needSep) {
6428 pw.println();
6429 needSep = false;
6430 }
6431 pw.println(" mPreviousProcess: " + mPreviousProcess);
6432 }
6433 if (dumpAll && (mPreviousProcess == null || dumpPackage == null
6434 || mPreviousProcess.mPkgList.contains(dumpPackage))) {
6435 StringBuilder sb = new StringBuilder(128);
6436 sb.append(" mPreviousProcessVisibleTime: ");
6437 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
6438 pw.println(sb);
6439 }
6440 if (mHeavyWeightProcess != null && (dumpPackage == null
6441 || mHeavyWeightProcess.mPkgList.contains(dumpPackage))) {
6442 if (needSep) {
6443 pw.println();
6444 needSep = false;
6445 }
6446 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
6447 }
6448 if (dumpPackage == null) {
6449 pw.println(" mGlobalConfiguration: " + getGlobalConfiguration());
6450 mStackSupervisor.dumpDisplayConfigs(pw, " ");
6451 }
6452 if (dumpAll) {
6453 if (dumpPackage == null) {
6454 pw.println(" mConfigWillChange: "
6455 + getTopDisplayFocusedStack().mConfigWillChange);
6456 }
6457 if (mCompatModePackages.getPackages().size() > 0) {
6458 boolean printed = false;
6459 for (Map.Entry<String, Integer> entry
6460 : mCompatModePackages.getPackages().entrySet()) {
6461 String pkg = entry.getKey();
6462 int mode = entry.getValue();
6463 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
6464 continue;
6465 }
6466 if (!printed) {
6467 pw.println(" mScreenCompatPackages:");
6468 printed = true;
6469 }
6470 pw.println(" " + pkg + ": " + mode);
6471 }
6472 }
6473 }
6474
6475 if (dumpPackage == null) {
6476 pw.println(" mWakefulness="
6477 + PowerManagerInternal.wakefulnessToString(wakefulness));
6478 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
6479 if (mRunningVoice != null) {
6480 pw.println(" mRunningVoice=" + mRunningVoice);
6481 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
6482 }
6483 pw.println(" mSleeping=" + mSleeping);
6484 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + testPssMode);
6485 pw.println(" mVrController=" + mVrController);
6486 }
6487 if (mCurAppTimeTracker != null) {
6488 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
6489 }
6490 if (mAllowAppSwitchUids.size() > 0) {
6491 boolean printed = false;
6492 for (int i = 0; i < mAllowAppSwitchUids.size(); i++) {
6493 ArrayMap<String, Integer> types = mAllowAppSwitchUids.valueAt(i);
6494 for (int j = 0; j < types.size(); j++) {
6495 if (dumpPackage == null ||
6496 UserHandle.getAppId(types.valueAt(j).intValue()) == dumpAppId) {
6497 if (needSep) {
6498 pw.println();
6499 needSep = false;
6500 }
6501 if (!printed) {
6502 pw.println(" mAllowAppSwitchUids:");
6503 printed = true;
6504 }
6505 pw.print(" User ");
6506 pw.print(mAllowAppSwitchUids.keyAt(i));
6507 pw.print(": Type ");
6508 pw.print(types.keyAt(j));
6509 pw.print(" = ");
6510 UserHandle.formatUid(pw, types.valueAt(j).intValue());
6511 pw.println();
6512 }
6513 }
6514 }
6515 }
6516 if (dumpPackage == null) {
6517 if (mController != null) {
6518 pw.println(" mController=" + mController
6519 + " mControllerIsAMonkey=" + mControllerIsAMonkey);
6520 }
6521 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
6522 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
6523 }
6524
6525 return needSep;
6526 }
6527 }
6528
6529 @Override
6530 public void writeProcessesToProto(ProtoOutputStream proto, String dumpPackage) {
6531 synchronized (mGlobalLock) {
6532 if (dumpPackage == null) {
6533 getGlobalConfiguration().writeToProto(proto, GLOBAL_CONFIGURATION);
6534 proto.write(CONFIG_WILL_CHANGE, getTopDisplayFocusedStack().mConfigWillChange);
6535 writeSleepStateToProto(proto);
6536 if (mController != null) {
6537 final long token = proto.start(CONTROLLER);
6538 proto.write(CONTROLLER, mController.toString());
6539 proto.write(IS_A_MONKEY, mControllerIsAMonkey);
6540 proto.end(token);
6541 }
6542 mStackSupervisor.mGoingToSleep.writeToProto(proto, GOING_TO_SLEEP);
6543 mStackSupervisor.mLaunchingActivity.writeToProto(proto, LAUNCHING_ACTIVITY);
6544 }
6545
6546 if (mHomeProcess != null && (dumpPackage == null
6547 || mHomeProcess.mPkgList.contains(dumpPackage))) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07006548 mHomeProcess.writeToProto(proto, HOME_PROC);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006549 }
6550
6551 if (mPreviousProcess != null && (dumpPackage == null
6552 || mPreviousProcess.mPkgList.contains(dumpPackage))) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07006553 mPreviousProcess.writeToProto(proto, PREVIOUS_PROC);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006554 proto.write(PREVIOUS_PROC_VISIBLE_TIME_MS, mPreviousProcessVisibleTime);
6555 }
6556
6557 if (mHeavyWeightProcess != null && (dumpPackage == null
6558 || mHeavyWeightProcess.mPkgList.contains(dumpPackage))) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07006559 mHeavyWeightProcess.writeToProto(proto, HEAVY_WEIGHT_PROC);
Wale Ogunwale31913b52018-10-13 08:29:31 -07006560 }
6561
6562 for (Map.Entry<String, Integer> entry
6563 : mCompatModePackages.getPackages().entrySet()) {
6564 String pkg = entry.getKey();
6565 int mode = entry.getValue();
6566 if (dumpPackage == null || dumpPackage.equals(pkg)) {
6567 long compatToken = proto.start(SCREEN_COMPAT_PACKAGES);
6568 proto.write(PACKAGE, pkg);
6569 proto.write(MODE, mode);
6570 proto.end(compatToken);
6571 }
6572 }
6573
6574 if (mCurAppTimeTracker != null) {
6575 mCurAppTimeTracker.writeToProto(proto, CURRENT_TRACKER, true);
6576 }
6577
6578 }
6579 }
6580
6581 @Override
6582 public boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name,
6583 String[] args, int opti, boolean dumpAll, boolean dumpVisibleStacksOnly,
6584 boolean dumpFocusedStackOnly) {
6585 synchronized (mGlobalLock) {
6586 return ActivityTaskManagerService.this.dumpActivity(fd, pw, name, args, opti,
6587 dumpAll, dumpVisibleStacksOnly, dumpFocusedStackOnly);
6588 }
6589 }
6590
6591 @Override
Wale Ogunwaled4d67d02018-10-25 18:09:39 -07006592 public void dumpForOom(PrintWriter pw) {
6593 synchronized (mGlobalLock) {
6594 pw.println(" mHomeProcess: " + mHomeProcess);
6595 pw.println(" mPreviousProcess: " + mPreviousProcess);
6596 if (mHeavyWeightProcess != null) {
6597 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
6598 }
6599 }
6600 }
6601
6602 @Override
Wale Ogunwale31913b52018-10-13 08:29:31 -07006603 public boolean canGcNow() {
6604 synchronized (mGlobalLock) {
6605 return isSleeping() || mStackSupervisor.allResumedActivitiesIdle();
6606 }
6607 }
6608
6609 @Override
6610 public WindowProcessController getTopApp() {
6611 synchronized (mGlobalLock) {
6612 final ActivityRecord top = mStackSupervisor.getTopResumedActivity();
6613 return top != null ? top.app : null;
6614 }
6615 }
6616
6617 @Override
6618 public void rankTaskLayersIfNeeded() {
6619 synchronized (mGlobalLock) {
6620 if (mStackSupervisor != null) {
6621 mStackSupervisor.rankTaskLayersIfNeeded();
6622 }
6623 }
6624 }
6625
6626 @Override
6627 public void scheduleDestroyAllActivities(String reason) {
6628 synchronized (mGlobalLock) {
6629 mStackSupervisor.scheduleDestroyAllActivities(null, reason);
6630 }
6631 }
6632
6633 @Override
6634 public void removeUser(int userId) {
6635 synchronized (mGlobalLock) {
6636 mStackSupervisor.removeUserLocked(userId);
6637 }
6638 }
6639
6640 @Override
6641 public boolean switchUser(int userId, UserState userState) {
6642 synchronized (mGlobalLock) {
6643 return mStackSupervisor.switchUserLocked(userId, userState);
6644 }
6645 }
6646
6647 @Override
6648 public void onHandleAppCrash(WindowProcessController wpc) {
6649 synchronized (mGlobalLock) {
6650 mStackSupervisor.handleAppCrashLocked(wpc);
6651 }
6652 }
Wale Ogunwale64258362018-10-16 15:13:37 -07006653
6654 @Override
6655 public int finishTopCrashedActivities(WindowProcessController crashedApp, String reason) {
6656 synchronized (mGlobalLock) {
6657 return mStackSupervisor.finishTopCrashedActivitiesLocked(crashedApp, reason);
6658 }
6659 }
Wale Ogunwalebff2df42018-10-18 17:09:19 -07006660
6661 @Override
6662 public void onUidActive(int uid, int procState) {
6663 synchronized (mGlobalLock) {
6664 mActiveUids.put(uid, procState);
6665 }
6666 }
6667
6668 @Override
6669 public void onUidInactive(int uid) {
6670 synchronized (mGlobalLock) {
6671 mActiveUids.remove(uid);
6672 }
6673 }
6674
6675 @Override
6676 public void onActiveUidsCleared() {
6677 synchronized (mGlobalLock) {
6678 mActiveUids.clear();
6679 }
6680 }
6681
6682 @Override
6683 public void onUidProcStateChanged(int uid, int procState) {
6684 synchronized (mGlobalLock) {
6685 if (mActiveUids.get(uid) != null) {
6686 mActiveUids.put(uid, procState);
6687 }
6688 }
6689 }
Wale Ogunwale9de19442018-10-18 19:05:03 -07006690
6691 @Override
6692 public void onUidAddedToPendingTempWhitelist(int uid, String tag) {
6693 synchronized (mGlobalLock) {
6694 mPendingTempWhitelist.put(uid, tag);
6695 }
6696 }
6697
6698 @Override
6699 public void onUidRemovedFromPendingTempWhitelist(int uid) {
6700 synchronized (mGlobalLock) {
6701 mPendingTempWhitelist.remove(uid);
6702 }
6703 }
Wale Ogunwalee2172292018-10-25 10:11:10 -07006704
6705 @Override
6706 public boolean handleAppCrashInActivityController(String processName, int pid,
6707 String shortMsg, String longMsg, long timeMillis, String stackTrace,
6708 Runnable killCrashingAppCallback) {
6709 synchronized (mGlobalLock) {
6710 if (mController == null) {
6711 return false;
6712 }
6713
6714 try {
6715 if (!mController.appCrashed(processName, pid, shortMsg, longMsg, timeMillis,
6716 stackTrace)) {
6717 killCrashingAppCallback.run();
6718 return true;
6719 }
6720 } catch (RemoteException e) {
6721 mController = null;
6722 Watchdog.getInstance().setActivityController(null);
6723 }
6724 return false;
6725 }
6726 }
Wale Ogunwaled7889f52018-10-25 11:03:20 -07006727
6728 @Override
6729 public void removeRecentTasksByPackageName(String packageName, int userId) {
6730 synchronized (mGlobalLock) {
6731 mRecentTasks.removeTasksByPackageName(packageName, userId);
6732 }
6733 }
6734
6735 @Override
6736 public void cleanupRecentTasksForUser(int userId) {
6737 synchronized (mGlobalLock) {
6738 mRecentTasks.cleanupLocked(userId);
6739 }
6740 }
6741
6742 @Override
6743 public void loadRecentTasksForUser(int userId) {
6744 synchronized (mGlobalLock) {
6745 mRecentTasks.loadUserRecentsLocked(userId);
6746 }
6747 }
6748
6749 @Override
6750 public void onPackagesSuspendedChanged(String[] packages, boolean suspended, int userId) {
6751 synchronized (mGlobalLock) {
6752 mRecentTasks.onPackagesSuspendedChanged(packages, suspended, userId);
6753 }
6754 }
6755
6756 @Override
6757 public void flushRecentTasks() {
6758 mRecentTasks.flush();
6759 }
Wale Ogunwaled4d67d02018-10-25 18:09:39 -07006760
6761 @Override
6762 public WindowProcessController getHomeProcess() {
6763 synchronized (mGlobalLock) {
6764 return mHomeProcess;
6765 }
6766 }
6767
6768 @Override
6769 public WindowProcessController getPreviousProcess() {
6770 synchronized (mGlobalLock) {
6771 return mPreviousProcess;
6772 }
6773 }
Wale Ogunwale27c48ae2018-10-25 19:01:01 -07006774
6775 @Override
6776 public void clearLockedTasks(String reason) {
6777 synchronized (mGlobalLock) {
6778 getLockTaskController().clearLockedTasks(reason);
6779 }
6780 }
6781
6782 @Override
6783 public void updateUserConfiguration() {
6784 synchronized (mGlobalLock) {
6785 final Configuration configuration = new Configuration(getGlobalConfiguration());
6786 final int currentUserId = mAmInternal.getCurrentUserId();
6787 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(),
6788 configuration, currentUserId, Settings.System.canWrite(mContext));
6789 updateConfigurationLocked(configuration, null /* starting */,
6790 false /* initLocale */, false /* persistent */, currentUserId,
6791 false /* deferResume */);
6792 }
6793 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07006794 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07006795}