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