blob: a4fd428cb4cb0cb33473a3a14c55ebdc4688d53d [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;
Evan Rosky4505b352018-09-06 11:20:40 -070030import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070031import static android.app.ActivityTaskManager.RESIZE_MODE_PRESERVE_WINDOW;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070032import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070033import static android.app.AppOpsManager.OP_NONE;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070034import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070035import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
36import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070037import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
38import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070039import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070040import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070041import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
Wale Ogunwale214f3482018-10-04 11:00:47 -070042import static android.content.pm.ApplicationInfo.FLAG_FACTORY_TEST;
Wale Ogunwale342fbe92018-10-09 08:44:10 -070043import static android.content.pm.ConfigurationInfo.GL_ES_VERSION_UNDEFINED;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070044import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
45import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
Evan Rosky4505b352018-09-06 11:20:40 -070046import static android.content.pm.PackageManager.FEATURE_PC;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070047import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070048import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070049import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
50import static android.os.Build.VERSION_CODES.N;
Wale Ogunwale214f3482018-10-04 11:00:47 -070051import static android.os.FactoryTest.FACTORY_TEST_HIGH_LEVEL;
52import static android.os.FactoryTest.FACTORY_TEST_LOW_LEVEL;
53import static android.os.FactoryTest.FACTORY_TEST_OFF;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070054import static android.os.Process.SYSTEM_UID;
Evan Rosky4505b352018-09-06 11:20:40 -070055import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070056import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
57import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
58import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
59import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
Evan Rosky4505b352018-09-06 11:20:40 -070060import static android.provider.Settings.Global.HIDE_ERROR_DIALOGS;
61import static android.provider.Settings.System.FONT_SCALE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070062import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
63import static android.view.Display.DEFAULT_DISPLAY;
64import static android.view.Display.INVALID_DISPLAY;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070065import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
Wale Ogunwale6767eae2018-05-03 15:52:51 -070066import static android.view.WindowManager.TRANSIT_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070067import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070068import static android.view.WindowManager.TRANSIT_TASK_OPEN;
69import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
Evan Rosky4505b352018-09-06 11:20:40 -070070
Wale Ogunwale65ebd952018-04-25 15:41:44 -070071import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070072import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
73import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
74import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
75import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070076import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070077import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070078import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070079import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070080import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070081import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
82import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
83import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070084import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070085import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
86import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070087import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
88import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
89import static com.android.server.am.ActivityManagerService.ANIMATE;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070090import static com.android.server.am.ActivityManagerService.MY_PID;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070091import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS;
Evan Rosky4505b352018-09-06 11:20:40 -070092import static com.android.server.am.ActivityManagerService.dumpStackTraces;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070093import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070094import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070095import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
96import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
97import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
98import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
99import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
Evan Rosky4505b352018-09-06 11:20:40 -0700100import static com.android.server.am.ActivityTaskManagerService.H.REPORT_TIME_TRACKER_MSG;
101import static com.android.server.am.ActivityTaskManagerService.UiHandler.DISMISS_DIALOG_UI_MSG;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700102import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
103import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700104import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700105import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
Evan Rosky4505b352018-09-06 11:20:40 -0700106import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT;
107import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_DATA;
108import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
109import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700110import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
111import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700112
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700113import android.Manifest;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700114import android.annotation.NonNull;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700115import android.annotation.Nullable;
116import android.annotation.UserIdInt;
117import android.app.Activity;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700118import android.app.ActivityManager;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700119import android.app.ActivityManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700120import android.app.ActivityOptions;
121import android.app.ActivityTaskManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700122import android.app.ActivityThread;
123import android.app.AlertDialog;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700124import android.app.AppGlobals;
Evan Rosky4505b352018-09-06 11:20:40 -0700125import android.app.Dialog;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700126import android.app.IActivityController;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700127import android.app.IActivityTaskManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700128import android.app.IApplicationThread;
129import android.app.IAssistDataReceiver;
Wale Ogunwale53783742018-09-16 10:21:51 -0700130import android.app.INotificationManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700131import android.app.ITaskStackListener;
Wale Ogunwale53783742018-09-16 10:21:51 -0700132import android.app.Notification;
133import android.app.NotificationManager;
134import android.app.PendingIntent;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700135import android.app.PictureInPictureParams;
136import android.app.ProfilerInfo;
137import android.app.RemoteAction;
138import android.app.WaitResult;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700139import android.app.WindowConfiguration;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700140import android.app.admin.DevicePolicyCache;
141import android.app.assist.AssistContent;
142import android.app.assist.AssistStructure;
143import android.app.usage.UsageEvents;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700144import android.app.usage.UsageStatsManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700145import android.content.ActivityNotFoundException;
146import android.content.ComponentName;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700147import android.content.ContentResolver;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700148import android.content.Context;
Evan Rosky4505b352018-09-06 11:20:40 -0700149import android.content.DialogInterface;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700150import android.content.IIntentSender;
151import android.content.Intent;
152import android.content.pm.ActivityInfo;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700153import android.content.pm.ApplicationInfo;
Yunfan Chen75157d72018-07-27 14:47:21 +0900154import android.content.pm.ConfigurationInfo;
Evan Rosky4505b352018-09-06 11:20:40 -0700155import android.content.pm.IPackageManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700156import android.content.pm.PackageManager;
Evan Rosky4505b352018-09-06 11:20:40 -0700157import android.content.pm.PackageManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700158import android.content.pm.ParceledListSlice;
159import android.content.pm.ResolveInfo;
Wale Ogunwale53783742018-09-16 10:21:51 -0700160import android.content.res.CompatibilityInfo;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700161import android.content.res.Configuration;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700162import android.content.res.Resources;
Evan Rosky4505b352018-09-06 11:20:40 -0700163import android.database.ContentObserver;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700164import android.graphics.Bitmap;
165import android.graphics.Point;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700166import android.graphics.Rect;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700167import android.metrics.LogMaker;
168import android.net.Uri;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700169import android.os.Binder;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700170import android.os.Build;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700171import android.os.Bundle;
Wale Ogunwale214f3482018-10-04 11:00:47 -0700172import android.os.FactoryTest;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700173import android.os.FileUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700174import android.os.Handler;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700175import android.os.IBinder;
Evan Rosky4505b352018-09-06 11:20:40 -0700176import android.os.IUserManager;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700177import android.os.LocaleList;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700178import android.os.Looper;
179import android.os.Message;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700180import android.os.PersistableBundle;
Evan Rosky4505b352018-09-06 11:20:40 -0700181import android.os.PowerManager;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700182import android.os.PowerManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700183import android.os.RemoteException;
Evan Rosky4505b352018-09-06 11:20:40 -0700184import android.os.ServiceManager;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700185import android.os.StrictMode;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700186import android.os.SystemClock;
187import android.os.SystemProperties;
Evan Rosky4505b352018-09-06 11:20:40 -0700188import android.os.Trace;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700189import android.os.UpdateLock;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700190import android.os.UserHandle;
Evan Rosky4505b352018-09-06 11:20:40 -0700191import android.os.UserManager;
192import android.os.WorkSource;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700193import android.os.storage.IStorageManager;
194import android.os.storage.StorageManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700195import android.provider.Settings;
196import android.service.voice.IVoiceInteractionSession;
197import android.service.voice.VoiceInteractionManagerInternal;
198import android.telecom.TelecomManager;
199import android.text.TextUtils;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700200import android.text.format.Time;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700201import android.util.ArrayMap;
202import android.util.EventLog;
203import android.util.Log;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700204import android.util.Slog;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700205import android.util.SparseArray;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700206import android.util.SparseIntArray;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700207import android.util.StatsLog;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700208import android.util.TimeUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700209import android.util.proto.ProtoOutputStream;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700210import android.view.IRecentsAnimationRunner;
211import android.view.RemoteAnimationAdapter;
212import android.view.RemoteAnimationDefinition;
Evan Rosky4505b352018-09-06 11:20:40 -0700213import android.view.WindowManager;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700214
Evan Rosky4505b352018-09-06 11:20:40 -0700215import com.android.internal.R;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700216import com.android.internal.annotations.VisibleForTesting;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700217import com.android.internal.app.AssistUtils;
Evan Rosky4505b352018-09-06 11:20:40 -0700218import com.android.internal.app.IAppOpsService;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700219import com.android.internal.app.IVoiceInteractor;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700220import com.android.internal.app.ProcessMap;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700221import com.android.internal.logging.MetricsLogger;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700222import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Wale Ogunwale53783742018-09-16 10:21:51 -0700223import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
224import com.android.internal.notification.SystemNotificationChannels;
Evan Rosky4505b352018-09-06 11:20:40 -0700225import com.android.internal.os.logging.MetricsLoggerWrapper;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700226import com.android.internal.policy.IKeyguardDismissCallback;
227import com.android.internal.policy.KeyguardDismissCallback;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700228import com.android.internal.util.Preconditions;
Wale Ogunwale53783742018-09-16 10:21:51 -0700229import com.android.internal.util.function.pooled.PooledLambda;
Evan Rosky4505b352018-09-06 11:20:40 -0700230import com.android.server.AppOpsService;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700231import com.android.server.AttributeCache;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700232import com.android.server.LocalServices;
233import com.android.server.SystemService;
Evan Rosky4505b352018-09-06 11:20:40 -0700234import com.android.server.SystemServiceManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700235import com.android.server.Watchdog;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700236import com.android.server.firewall.IntentFirewall;
Evan Rosky4505b352018-09-06 11:20:40 -0700237import com.android.server.pm.UserManagerService;
238import com.android.server.uri.UriGrantsManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700239import com.android.server.vr.VrManagerInternal;
Evan Rosky4505b352018-09-06 11:20:40 -0700240import com.android.server.wm.ActivityTaskManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700241import com.android.server.wm.PinnedStackWindowController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700242import com.android.server.wm.WindowManagerService;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700243
244import java.io.File;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700245import java.io.FileOutputStream;
246import java.io.IOException;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700247import java.io.PrintWriter;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700248import java.io.StringWriter;
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700249import java.lang.ref.WeakReference;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700250import java.util.ArrayList;
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700251import java.util.HashSet;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700252import java.util.List;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700253import java.util.Locale;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700254
255/**
256 * System service for managing activities and their containers (task, stacks, displays,... ).
257 *
258 * {@hide}
259 */
260public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
261 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityTaskManagerService" : TAG_AM;
262 private static final String TAG_STACK = TAG + POSTFIX_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700263 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
264 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
265 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
266 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
267 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700268 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700269
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700270 // How long we wait until we timeout on key dispatching.
271 private static final int KEY_DISPATCHING_TIMEOUT_MS = 5 * 1000;
272 // How long we wait until we timeout on key dispatching during instrumentation.
273 private static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS = 60 * 1000;
274
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700275 /** Hardware-reported OpenGLES version. */
276 final int GL_ES_VERSION;
277
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700278 Context mContext;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700279 /**
280 * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
281 * change at runtime. Use mContext for non-UI purposes.
282 */
283 final Context mUiContext;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700284 final ActivityThread mSystemThread;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700285 H mH;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700286 UiHandler mUiHandler;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700287 ActivityManagerService mAm;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700288 ActivityManagerInternal mAmInternal;
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700289 UriGrantsManagerInternal mUgmInternal;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700290 private PackageManagerInternal mPmInternal;
Wale Ogunwale53783742018-09-16 10:21:51 -0700291 private ActivityTaskManagerInternal mInternal;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700292 PowerManagerInternal mPowerManagerInternal;
293 private UsageStatsManagerInternal mUsageStatsInternal;
294
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700295 PendingIntentController mPendingIntentController;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700296 IntentFirewall mIntentFirewall;
297
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700298 /* Global service lock used by the package the owns this service. */
299 Object mGlobalLock;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700300 ActivityStackSupervisor mStackSupervisor;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700301 WindowManagerService mWindowManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700302 private UserManagerService mUserManager;
303 private AppOpsService mAppOpsService;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700304 /** All processes currently running that might have a window organized by name. */
305 final ProcessMap<WindowProcessController> mProcessNames = new ProcessMap<>();
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700306 /** All processes we currently have running mapped by pid */
307 final SparseArray<WindowProcessController> mPidMap = new SparseArray<>();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700308 /** This is the process holding what we currently consider to be the "home" activity. */
309 WindowProcessController mHomeProcess;
Wale Ogunwale53783742018-09-16 10:21:51 -0700310 /** The currently running heavy-weight process, if any. */
311 WindowProcessController mHeavyWeightProcess = null;
Wale Ogunwale214f3482018-10-04 11:00:47 -0700312 boolean mHasHeavyWeightFeature;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700313 /**
314 * This is the process holding the activity the user last visited that is in a different process
315 * from the one they are currently in.
316 */
317 WindowProcessController mPreviousProcess;
318 /** The time at which the previous process was last visible. */
319 long mPreviousProcessVisibleTime;
320
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700321 /** List of intents that were used to start the most recent tasks. */
322 private RecentTasks mRecentTasks;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700323 /** State of external calls telling us if the device is awake or asleep. */
324 private boolean mKeyguardShown = false;
325
326 // Wrapper around VoiceInteractionServiceManager
327 private AssistUtils mAssistUtils;
328
329 // VoiceInteraction session ID that changes for each new request except when
330 // being called for multi-window assist in a single session.
331 private int mViSessionId = 1000;
332
333 // How long to wait in getAssistContextExtras for the activity and foreground services
334 // to respond with the result.
335 private static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
336
337 // How long top wait when going through the modern assist (which doesn't need to block
338 // on getting this result before starting to launch its UI).
339 private static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
340
341 // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
342 private static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
343
344 private final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
345
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700346 // Keeps track of the active voice interaction service component, notified from
347 // VoiceInteractionManagerService
348 ComponentName mActiveVoiceInteractionServiceComponent;
349
350 private VrController mVrController;
351 KeyguardController mKeyguardController;
352 private final ClientLifecycleManager mLifecycleManager;
353 private TaskChangeNotificationController mTaskChangeNotificationController;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700354 /** The controller for all operations related to locktask. */
355 private LockTaskController mLockTaskController;
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700356 private ActivityStartController mActivityStartController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700357
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700358 boolean mSuppressResizeConfigChanges;
359
360 private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
361 new UpdateConfigurationResult();
362
363 static final class UpdateConfigurationResult {
364 // Configuration changes that were updated.
365 int changes;
366 // If the activity was relaunched to match the new configuration.
367 boolean activityRelaunched;
368
369 void reset() {
370 changes = 0;
371 activityRelaunched = false;
372 }
373 }
374
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700375 /** Current sequencing integer of the configuration, for skipping old configurations. */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700376 private int mConfigurationSeq;
377 // To cache the list of supported system locales
378 private String[] mSupportedSystemLocales = null;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700379
380 /**
381 * Temp object used when global and/or display override configuration is updated. It is also
382 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
383 * anyone...
384 */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700385 private Configuration mTempConfig = new Configuration();
386
Wale Ogunwalef6733932018-06-27 05:14:34 -0700387 /** Temporary to avoid allocations. */
388 final StringBuilder mStringBuilder = new StringBuilder(256);
389
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700390 // Amount of time after a call to stopAppSwitches() during which we will
391 // prevent further untrusted switches from happening.
392 private static final long APP_SWITCH_DELAY_TIME = 5 * 1000;
393
394 /**
395 * The time at which we will allow normal application switches again,
396 * after a call to {@link #stopAppSwitches()}.
397 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700398 private long mAppSwitchesAllowedTime;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700399 /**
400 * This is set to true after the first switch after mAppSwitchesAllowedTime
401 * is set; any switches after that will clear the time.
402 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700403 private boolean mDidAppSwitch;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700404
405 IActivityController mController = null;
406 boolean mControllerIsAMonkey = false;
407
Wale Ogunwale214f3482018-10-04 11:00:47 -0700408 final int mFactoryTest;
409
410 /** Used to control how we initialize the service. */
411 ComponentName mTopComponent;
412 String mTopAction = Intent.ACTION_MAIN;
413 String mTopData;
414
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700415 /**
416 * Used to retain an update lock when the foreground activity is in
417 * immersive mode.
418 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700419 private final UpdateLock mUpdateLock = new UpdateLock("immersive");
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700420
421 /**
422 * Packages that are being allowed to perform unrestricted app switches. Mapping is
423 * User -> Type -> uid.
424 */
425 final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
426
427 /** The dimensions of the thumbnails in the Recents UI. */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700428 private int mThumbnailWidth;
429 private int mThumbnailHeight;
430 private float mFullscreenThumbnailScale;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700431
432 /**
433 * Flag that indicates if multi-window is enabled.
434 *
435 * For any particular form of multi-window to be enabled, generic multi-window must be enabled
436 * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
437 * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
438 * At least one of the forms of multi-window must be enabled in order for this flag to be
439 * initialized to 'true'.
440 *
441 * @see #mSupportsSplitScreenMultiWindow
442 * @see #mSupportsFreeformWindowManagement
443 * @see #mSupportsPictureInPicture
444 * @see #mSupportsMultiDisplay
445 */
446 boolean mSupportsMultiWindow;
447 boolean mSupportsSplitScreenMultiWindow;
448 boolean mSupportsFreeformWindowManagement;
449 boolean mSupportsPictureInPicture;
450 boolean mSupportsMultiDisplay;
451 boolean mForceResizableActivities;
452
453 final List<ActivityTaskManagerInternal.ScreenObserver> mScreenObservers = new ArrayList<>();
454
455 // VR Vr2d Display Id.
456 int mVr2dDisplayId = INVALID_DISPLAY;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700457
Wale Ogunwalef6733932018-06-27 05:14:34 -0700458 /**
459 * Set while we are wanting to sleep, to prevent any
460 * activities from being started/resumed.
461 *
462 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
463 *
464 * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
465 * while in the sleep state until there is a pending transition out of sleep, in which case
466 * mSleeping is set to false, and remains false while awake.
467 *
468 * Whether mSleeping can quickly toggled between true/false without the device actually
469 * display changing states is undefined.
470 */
471 private boolean mSleeping = false;
472
473 /**
474 * The process state used for processes that are running the top activities.
475 * This changes between TOP and TOP_SLEEPING to following mSleeping.
476 */
477 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
478
479 // Whether we should show our dialogs (ANR, crash, etc) or just perform their default action
480 // automatically. Important for devices without direct input devices.
481 private boolean mShowDialogs = true;
482
483 /** Set if we are shutting down the system, similar to sleeping. */
484 boolean mShuttingDown = false;
485
486 /**
487 * We want to hold a wake lock while running a voice interaction session, since
488 * this may happen with the screen off and we need to keep the CPU running to
489 * be able to continue to interact with the user.
490 */
491 PowerManager.WakeLock mVoiceWakeLock;
492
493 /**
494 * Set while we are running a voice interaction. This overrides sleeping while it is active.
495 */
496 IVoiceInteractionSession mRunningVoice;
497
498 /**
499 * The last resumed activity. This is identical to the current resumed activity most
500 * of the time but could be different when we're pausing one activity before we resume
501 * another activity.
502 */
503 ActivityRecord mLastResumedActivity;
504
505 /**
506 * The activity that is currently being traced as the active resumed activity.
507 *
508 * @see #updateResumedAppTrace
509 */
510 private @Nullable ActivityRecord mTracedResumedActivity;
511
512 /** If non-null, we are tracking the time the user spends in the currently focused app. */
513 AppTimeTracker mCurAppTimeTracker;
514
Wale Ogunwale008163e2018-07-23 23:11:08 -0700515 private AppWarnings mAppWarnings;
516
Wale Ogunwale53783742018-09-16 10:21:51 -0700517 /**
518 * Packages that the user has asked to have run in screen size
519 * compatibility mode instead of filling the screen.
520 */
521 CompatModePackages mCompatModePackages;
522
Wale Ogunwalef6733932018-06-27 05:14:34 -0700523 private FontScaleSettingObserver mFontScaleSettingObserver;
524
525 private final class FontScaleSettingObserver extends ContentObserver {
526 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
527 private final Uri mHideErrorDialogsUri = Settings.Global.getUriFor(HIDE_ERROR_DIALOGS);
528
529 public FontScaleSettingObserver() {
530 super(mH);
531 final ContentResolver resolver = mContext.getContentResolver();
532 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
533 resolver.registerContentObserver(mHideErrorDialogsUri, false, this,
534 UserHandle.USER_ALL);
535 }
536
537 @Override
538 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
539 if (mFontScaleUri.equals(uri)) {
540 updateFontScaleIfNeeded(userId);
541 } else if (mHideErrorDialogsUri.equals(uri)) {
542 synchronized (mGlobalLock) {
543 updateShouldShowDialogsLocked(getGlobalConfiguration());
544 }
545 }
546 }
547 }
548
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700549 ActivityTaskManagerService(Context context) {
550 mContext = context;
Wale Ogunwale214f3482018-10-04 11:00:47 -0700551 mFactoryTest = FactoryTest.getMode();
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700552 mSystemThread = ActivityThread.currentActivityThread();
553 mUiContext = mSystemThread.getSystemUiContext();
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700554 mLifecycleManager = new ClientLifecycleManager();
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700555 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", GL_ES_VERSION_UNDEFINED);
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700556 }
557
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700558 void onSystemReady() {
Wale Ogunwale214f3482018-10-04 11:00:47 -0700559 mHasHeavyWeightFeature = mContext.getPackageManager().hasSystemFeature(
560 PackageManager.FEATURE_CANT_SAVE_STATE);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700561 mAssistUtils = new AssistUtils(mContext);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700562 mVrController.onSystemReady();
563 mRecentTasks.onSystemReadyLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700564 }
565
Wale Ogunwalef6733932018-06-27 05:14:34 -0700566 void onInitPowerManagement() {
567 mStackSupervisor.initPowerManagement();
568 final PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700569 mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
Wale Ogunwalef6733932018-06-27 05:14:34 -0700570 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
571 mVoiceWakeLock.setReferenceCounted(false);
572 }
573
574 void installSystemProviders() {
575 mFontScaleSettingObserver = new FontScaleSettingObserver();
576 }
577
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700578 void retrieveSettings(ContentResolver resolver) {
579 final boolean freeformWindowManagement =
580 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
581 || Settings.Global.getInt(
582 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
583
584 final boolean supportsMultiWindow = ActivityTaskManager.supportsMultiWindow(mContext);
585 final boolean supportsPictureInPicture = supportsMultiWindow &&
586 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
587 final boolean supportsSplitScreenMultiWindow =
588 ActivityTaskManager.supportsSplitScreenMultiWindow(mContext);
589 final boolean supportsMultiDisplay = mContext.getPackageManager()
590 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
591 final boolean alwaysFinishActivities =
592 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
593 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
594 final boolean forceResizable = Settings.Global.getInt(
595 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
Garfield Tane0846042018-07-26 13:42:04 -0700596 final boolean isPc = mContext.getPackageManager().hasSystemFeature(FEATURE_PC);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700597
598 // Transfer any global setting for forcing RTL layout, into a System Property
599 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
600
601 final Configuration configuration = new Configuration();
602 Settings.System.getConfiguration(resolver, configuration);
603 if (forceRtl) {
604 // This will take care of setting the correct layout direction flags
605 configuration.setLayoutDirection(configuration.locale);
606 }
607
608 synchronized (mGlobalLock) {
609 mForceResizableActivities = forceResizable;
610 final boolean multiWindowFormEnabled = freeformWindowManagement
611 || supportsSplitScreenMultiWindow
612 || supportsPictureInPicture
613 || supportsMultiDisplay;
614 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
615 mSupportsMultiWindow = true;
616 mSupportsFreeformWindowManagement = freeformWindowManagement;
617 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
618 mSupportsPictureInPicture = supportsPictureInPicture;
619 mSupportsMultiDisplay = supportsMultiDisplay;
620 } else {
621 mSupportsMultiWindow = false;
622 mSupportsFreeformWindowManagement = false;
623 mSupportsSplitScreenMultiWindow = false;
624 mSupportsPictureInPicture = false;
625 mSupportsMultiDisplay = false;
626 }
627 mWindowManager.setForceResizableTasks(mForceResizableActivities);
628 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
Garfield Tane0846042018-07-26 13:42:04 -0700629 mWindowManager.setSupportsFreeformWindowManagement(mSupportsFreeformWindowManagement);
630 mWindowManager.setIsPc(isPc);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700631 // This happens before any activities are started, so we can change global configuration
632 // in-place.
633 updateConfigurationLocked(configuration, null, true);
634 final Configuration globalConfig = getGlobalConfiguration();
635 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
636
637 // Load resources only after the current configuration has been set.
638 final Resources res = mContext.getResources();
639 mThumbnailWidth = res.getDimensionPixelSize(
640 com.android.internal.R.dimen.thumbnail_width);
641 mThumbnailHeight = res.getDimensionPixelSize(
642 com.android.internal.R.dimen.thumbnail_height);
643
644 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
645 mFullscreenThumbnailScale = (float) res
646 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
647 (float) globalConfig.screenWidthDp;
648 } else {
649 mFullscreenThumbnailScale = res.getFraction(
650 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
651 }
652 }
653 }
654
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700655 // TODO: Will be converted to WM lock once transition is complete.
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700656 void setActivityManagerService(ActivityManagerService am, Looper looper,
657 IntentFirewall intentFirewall, PendingIntentController intentController) {
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700658 mAm = am;
659 mGlobalLock = mAm;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700660 mH = new H(looper);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700661 mUiHandler = new UiHandler();
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700662 mIntentFirewall = intentFirewall;
Wale Ogunwale53783742018-09-16 10:21:51 -0700663 final File systemDir = SystemServiceManager.ensureSystemDir();
664 mAppWarnings = new AppWarnings(this, mUiContext, mH, mUiHandler, systemDir);
665 mCompatModePackages = new CompatModePackages(this, systemDir, mH);
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700666 mPendingIntentController = intentController;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700667
668 mTempConfig.setToDefaults();
669 mTempConfig.setLocales(LocaleList.getDefault());
670 mConfigurationSeq = mTempConfig.seq = 1;
671 mStackSupervisor = createStackSupervisor();
672 mStackSupervisor.onConfigurationChanged(mTempConfig);
673
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700674 mTaskChangeNotificationController =
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700675 new TaskChangeNotificationController(mGlobalLock, mStackSupervisor, mH);
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700676 mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mH);
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700677 mActivityStartController = new ActivityStartController(this);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700678 mRecentTasks = createRecentTasks();
679 mStackSupervisor.setRecentTasks(mRecentTasks);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700680 mVrController = new VrController(mGlobalLock);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700681 mKeyguardController = mStackSupervisor.getKeyguardController();
682 }
683
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700684 void onActivityManagerInternalAdded() {
685 mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700686 mUgmInternal = LocalServices.getService(UriGrantsManagerInternal.class);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700687 }
688
Yunfan Chen75157d72018-07-27 14:47:21 +0900689 int increaseConfigurationSeqLocked() {
690 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
691 return mConfigurationSeq;
692 }
693
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700694 protected ActivityStackSupervisor createStackSupervisor() {
695 final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mH.getLooper());
696 supervisor.initialize();
697 return supervisor;
698 }
699
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700700 void setWindowManager(WindowManagerService wm) {
701 mWindowManager = wm;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700702 mLockTaskController.setWindowManager(wm);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700703 }
704
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700705 void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
706 mUsageStatsInternal = usageStatsManager;
707 }
708
Wale Ogunwalef6733932018-06-27 05:14:34 -0700709 UserManagerService getUserManager() {
710 if (mUserManager == null) {
711 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
712 mUserManager = (UserManagerService) IUserManager.Stub.asInterface(b);
713 }
714 return mUserManager;
715 }
716
717 AppOpsService getAppOpsService() {
718 if (mAppOpsService == null) {
719 IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
720 mAppOpsService = (AppOpsService) IAppOpsService.Stub.asInterface(b);
721 }
722 return mAppOpsService;
723 }
724
725 boolean hasUserRestriction(String restriction, int userId) {
726 return getUserManager().hasUserRestriction(restriction, userId);
727 }
728
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700729 protected RecentTasks createRecentTasks() {
730 return new RecentTasks(this, mStackSupervisor);
731 }
732
733 RecentTasks getRecentTasks() {
734 return mRecentTasks;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700735 }
736
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700737 ClientLifecycleManager getLifecycleManager() {
738 return mLifecycleManager;
739 }
740
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700741 ActivityStartController getActivityStartController() {
742 return mActivityStartController;
743 }
744
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700745 TaskChangeNotificationController getTaskChangeNotificationController() {
746 return mTaskChangeNotificationController;
747 }
748
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700749 LockTaskController getLockTaskController() {
750 return mLockTaskController;
751 }
752
Yunfan Chen75157d72018-07-27 14:47:21 +0900753 /**
754 * Return the global configuration used by the process corresponding to the input pid. This is
755 * usually the global configuration with some overrides specific to that process.
756 */
757 Configuration getGlobalConfigurationForCallingPid() {
758 final int pid = Binder.getCallingPid();
759 if (pid == MY_PID || pid < 0) {
760 return getGlobalConfiguration();
761 }
762 synchronized (mGlobalLock) {
763 final WindowProcessController app = mPidMap.get(pid);
764 return app != null ? app.getConfiguration() : getGlobalConfiguration();
765 }
766 }
767
768 /**
769 * Return the device configuration info used by the process corresponding to the input pid.
770 * The value is consistent with the global configuration for the process.
771 */
772 @Override
773 public ConfigurationInfo getDeviceConfigurationInfo() {
774 ConfigurationInfo config = new ConfigurationInfo();
775 synchronized (mGlobalLock) {
776 final Configuration globalConfig = getGlobalConfigurationForCallingPid();
777 config.reqTouchScreen = globalConfig.touchscreen;
778 config.reqKeyboardType = globalConfig.keyboard;
779 config.reqNavigation = globalConfig.navigation;
780 if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
781 || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
782 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
783 }
784 if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
785 && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
786 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
787 }
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700788 config.reqGlEsVersion = GL_ES_VERSION;
Yunfan Chen75157d72018-07-27 14:47:21 +0900789 }
790 return config;
791 }
792
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700793 private void start() {
Wale Ogunwale53783742018-09-16 10:21:51 -0700794 mInternal = new LocalService();
795 LocalServices.addService(ActivityTaskManagerInternal.class, mInternal);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700796 }
797
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700798 public static final class Lifecycle extends SystemService {
799 private final ActivityTaskManagerService mService;
800
801 public Lifecycle(Context context) {
802 super(context);
803 mService = new ActivityTaskManagerService(context);
804 }
805
806 @Override
807 public void onStart() {
808 publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700809 mService.start();
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700810 }
811
812 public ActivityTaskManagerService getService() {
813 return mService;
814 }
815 }
816
817 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700818 public final int startActivity(IApplicationThread caller, String callingPackage,
819 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
820 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
821 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
822 resultWho, requestCode, startFlags, profilerInfo, bOptions,
823 UserHandle.getCallingUserId());
824 }
825
826 @Override
827 public final int startActivities(IApplicationThread caller, String callingPackage,
828 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
829 int userId) {
830 final String reason = "startActivities";
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700831 enforceNotIsolatedCaller(reason);
832 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, reason);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700833 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700834 return getActivityStartController().startActivities(caller, -1, callingPackage, intents,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100835 resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId, reason,
836 null /* originatingPendingIntent */);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700837 }
838
839 @Override
840 public int startActivityAsUser(IApplicationThread caller, String callingPackage,
841 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
842 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
843 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
844 resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
845 true /*validateIncomingUser*/);
846 }
847
848 int startActivityAsUser(IApplicationThread caller, String callingPackage,
849 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
850 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
851 boolean validateIncomingUser) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700852 enforceNotIsolatedCaller("startActivityAsUser");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700853
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700854 userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700855 Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
856
857 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700858 return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700859 .setCaller(caller)
860 .setCallingPackage(callingPackage)
861 .setResolvedType(resolvedType)
862 .setResultTo(resultTo)
863 .setResultWho(resultWho)
864 .setRequestCode(requestCode)
865 .setStartFlags(startFlags)
866 .setProfilerInfo(profilerInfo)
867 .setActivityOptions(bOptions)
868 .setMayWait(userId)
869 .execute();
870
871 }
872
873 @Override
874 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
875 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700876 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions) {
877 enforceNotIsolatedCaller("startActivityIntentSender");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700878 // Refuse possible leaked file descriptors
879 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
880 throw new IllegalArgumentException("File descriptors passed in Intent");
881 }
882
883 if (!(target instanceof PendingIntentRecord)) {
884 throw new IllegalArgumentException("Bad PendingIntent object");
885 }
886
887 PendingIntentRecord pir = (PendingIntentRecord)target;
888
889 synchronized (mGlobalLock) {
890 // If this is coming from the currently resumed activity, it is
891 // effectively saying that app switches are allowed at this point.
Andrii Kulian5f750bc2018-07-17 08:57:23 -0700892 final ActivityStack stack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700893 if (stack.mResumedActivity != null &&
894 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700895 mAppSwitchesAllowedTime = 0;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700896 }
897 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700898 return pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700899 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700900 }
901
902 @Override
903 public boolean startNextMatchingActivity(IBinder callingActivity, Intent intent,
904 Bundle bOptions) {
905 // Refuse possible leaked file descriptors
906 if (intent != null && intent.hasFileDescriptors()) {
907 throw new IllegalArgumentException("File descriptors passed in Intent");
908 }
909 SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
910
911 synchronized (mGlobalLock) {
912 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
913 if (r == null) {
914 SafeActivityOptions.abort(options);
915 return false;
916 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700917 if (!r.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700918 // The caller is not running... d'oh!
919 SafeActivityOptions.abort(options);
920 return false;
921 }
922 intent = new Intent(intent);
923 // The caller is not allowed to change the data.
924 intent.setDataAndType(r.intent.getData(), r.intent.getType());
925 // And we are resetting to find the next component...
926 intent.setComponent(null);
927
928 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
929
930 ActivityInfo aInfo = null;
931 try {
932 List<ResolveInfo> resolves =
933 AppGlobals.getPackageManager().queryIntentActivities(
934 intent, r.resolvedType,
935 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
936 UserHandle.getCallingUserId()).getList();
937
938 // Look for the original activity in the list...
939 final int N = resolves != null ? resolves.size() : 0;
940 for (int i=0; i<N; i++) {
941 ResolveInfo rInfo = resolves.get(i);
942 if (rInfo.activityInfo.packageName.equals(r.packageName)
943 && rInfo.activityInfo.name.equals(r.info.name)) {
944 // We found the current one... the next matching is
945 // after it.
946 i++;
947 if (i<N) {
948 aInfo = resolves.get(i).activityInfo;
949 }
950 if (debug) {
951 Slog.v(TAG, "Next matching activity: found current " + r.packageName
952 + "/" + r.info.name);
953 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
954 ? "null" : aInfo.packageName + "/" + aInfo.name));
955 }
956 break;
957 }
958 }
959 } catch (RemoteException e) {
960 }
961
962 if (aInfo == null) {
963 // Nobody who is next!
964 SafeActivityOptions.abort(options);
965 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
966 return false;
967 }
968
969 intent.setComponent(new ComponentName(
970 aInfo.applicationInfo.packageName, aInfo.name));
971 intent.setFlags(intent.getFlags()&~(
972 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
973 Intent.FLAG_ACTIVITY_CLEAR_TOP|
974 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
975 FLAG_ACTIVITY_NEW_TASK));
976
977 // Okay now we need to start the new activity, replacing the currently running activity.
978 // This is a little tricky because we want to start the new one as if the current one is
979 // finished, but not finish the current one first so that there is no flicker.
980 // And thus...
981 final boolean wasFinishing = r.finishing;
982 r.finishing = true;
983
984 // Propagate reply information over to the new activity.
985 final ActivityRecord resultTo = r.resultTo;
986 final String resultWho = r.resultWho;
987 final int requestCode = r.requestCode;
988 r.resultTo = null;
989 if (resultTo != null) {
990 resultTo.removeResultsLocked(r, resultWho, requestCode);
991 }
992
993 final long origId = Binder.clearCallingIdentity();
994 // TODO(b/64750076): Check if calling pid should really be -1.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700995 final int res = getActivityStartController()
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700996 .obtainStarter(intent, "startNextMatchingActivity")
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700997 .setCaller(r.app.getThread())
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700998 .setResolvedType(r.resolvedType)
999 .setActivityInfo(aInfo)
1000 .setResultTo(resultTo != null ? resultTo.appToken : null)
1001 .setResultWho(resultWho)
1002 .setRequestCode(requestCode)
1003 .setCallingPid(-1)
1004 .setCallingUid(r.launchedFromUid)
1005 .setCallingPackage(r.launchedFromPackage)
1006 .setRealCallingPid(-1)
1007 .setRealCallingUid(r.launchedFromUid)
1008 .setActivityOptions(options)
1009 .execute();
1010 Binder.restoreCallingIdentity(origId);
1011
1012 r.finishing = wasFinishing;
1013 if (res != ActivityManager.START_SUCCESS) {
1014 return false;
1015 }
1016 return true;
1017 }
1018 }
1019
1020 @Override
1021 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
1022 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1023 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
1024 final WaitResult res = new WaitResult();
1025 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001026 enforceNotIsolatedCaller("startActivityAndWait");
1027 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
1028 userId, "startActivityAndWait");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001029 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001030 getActivityStartController().obtainStarter(intent, "startActivityAndWait")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001031 .setCaller(caller)
1032 .setCallingPackage(callingPackage)
1033 .setResolvedType(resolvedType)
1034 .setResultTo(resultTo)
1035 .setResultWho(resultWho)
1036 .setRequestCode(requestCode)
1037 .setStartFlags(startFlags)
1038 .setActivityOptions(bOptions)
1039 .setMayWait(userId)
1040 .setProfilerInfo(profilerInfo)
1041 .setWaitResult(res)
1042 .execute();
1043 }
1044 return res;
1045 }
1046
1047 @Override
1048 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
1049 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1050 int startFlags, Configuration config, Bundle bOptions, int userId) {
1051 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001052 enforceNotIsolatedCaller("startActivityWithConfig");
1053 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
1054 "startActivityWithConfig");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001055 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001056 return getActivityStartController().obtainStarter(intent, "startActivityWithConfig")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001057 .setCaller(caller)
1058 .setCallingPackage(callingPackage)
1059 .setResolvedType(resolvedType)
1060 .setResultTo(resultTo)
1061 .setResultWho(resultWho)
1062 .setRequestCode(requestCode)
1063 .setStartFlags(startFlags)
1064 .setGlobalConfiguration(config)
1065 .setActivityOptions(bOptions)
1066 .setMayWait(userId)
1067 .execute();
1068 }
1069 }
1070
1071 @Override
1072 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
1073 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1074 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
1075 int userId) {
1076
1077 // This is very dangerous -- it allows you to perform a start activity (including
1078 // permission grants) as any app that may launch one of your own activities. So
1079 // we will only allow this to be done from activities that are part of the core framework,
1080 // and then only when they are running as the system.
1081 final ActivityRecord sourceRecord;
1082 final int targetUid;
1083 final String targetPackage;
1084 final boolean isResolver;
1085 synchronized (mGlobalLock) {
1086 if (resultTo == null) {
1087 throw new SecurityException("Must be called from an activity");
1088 }
1089 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
1090 if (sourceRecord == null) {
1091 throw new SecurityException("Called with bad activity token: " + resultTo);
1092 }
1093 if (!sourceRecord.info.packageName.equals("android")) {
1094 throw new SecurityException(
1095 "Must be called from an activity that is declared in the android package");
1096 }
1097 if (sourceRecord.app == null) {
1098 throw new SecurityException("Called without a process attached to activity");
1099 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001100 if (UserHandle.getAppId(sourceRecord.app.mUid) != SYSTEM_UID) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001101 // This is still okay, as long as this activity is running under the
1102 // uid of the original calling activity.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001103 if (sourceRecord.app.mUid != sourceRecord.launchedFromUid) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001104 throw new SecurityException(
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001105 "Calling activity in uid " + sourceRecord.app.mUid
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001106 + " must be system uid or original calling uid "
1107 + sourceRecord.launchedFromUid);
1108 }
1109 }
1110 if (ignoreTargetSecurity) {
1111 if (intent.getComponent() == null) {
1112 throw new SecurityException(
1113 "Component must be specified with ignoreTargetSecurity");
1114 }
1115 if (intent.getSelector() != null) {
1116 throw new SecurityException(
1117 "Selector not allowed with ignoreTargetSecurity");
1118 }
1119 }
1120 targetUid = sourceRecord.launchedFromUid;
1121 targetPackage = sourceRecord.launchedFromPackage;
1122 isResolver = sourceRecord.isResolverOrChildActivity();
1123 }
1124
1125 if (userId == UserHandle.USER_NULL) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001126 userId = UserHandle.getUserId(sourceRecord.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001127 }
1128
1129 // TODO: Switch to user app stacks here.
1130 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001131 return getActivityStartController().obtainStarter(intent, "startActivityAsCaller")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001132 .setCallingUid(targetUid)
1133 .setCallingPackage(targetPackage)
1134 .setResolvedType(resolvedType)
1135 .setResultTo(resultTo)
1136 .setResultWho(resultWho)
1137 .setRequestCode(requestCode)
1138 .setStartFlags(startFlags)
1139 .setActivityOptions(bOptions)
1140 .setMayWait(userId)
1141 .setIgnoreTargetSecurity(ignoreTargetSecurity)
1142 .setFilterCallingUid(isResolver ? 0 /* system */ : targetUid)
1143 .execute();
1144 } catch (SecurityException e) {
1145 // XXX need to figure out how to propagate to original app.
1146 // A SecurityException here is generally actually a fault of the original
1147 // calling activity (such as a fairly granting permissions), so propagate it
1148 // back to them.
1149 /*
1150 StringBuilder msg = new StringBuilder();
1151 msg.append("While launching");
1152 msg.append(intent.toString());
1153 msg.append(": ");
1154 msg.append(e.getMessage());
1155 */
1156 throw e;
1157 }
1158 }
1159
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001160 int handleIncomingUser(int callingPid, int callingUid, int userId, String name) {
1161 return mAmInternal.handleIncomingUser(callingPid, callingUid, userId, false /* allowAll */,
1162 ALLOW_FULL_ONLY, name, null /* callerPackage */);
1163 }
1164
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001165 @Override
1166 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
1167 Intent intent, String resolvedType, IVoiceInteractionSession session,
1168 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
1169 Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001170 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001171 if (session == null || interactor == null) {
1172 throw new NullPointerException("null session or interactor");
1173 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001174 userId = handleIncomingUser(callingPid, callingUid, userId, "startVoiceActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001175 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001176 return getActivityStartController().obtainStarter(intent, "startVoiceActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001177 .setCallingUid(callingUid)
1178 .setCallingPackage(callingPackage)
1179 .setResolvedType(resolvedType)
1180 .setVoiceSession(session)
1181 .setVoiceInteractor(interactor)
1182 .setStartFlags(startFlags)
1183 .setProfilerInfo(profilerInfo)
1184 .setActivityOptions(bOptions)
1185 .setMayWait(userId)
1186 .execute();
1187 }
1188
1189 @Override
1190 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
1191 Intent intent, String resolvedType, Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001192 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
1193 userId = handleIncomingUser(callingPid, callingUid, userId, "startAssistantActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001194
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001195 return getActivityStartController().obtainStarter(intent, "startAssistantActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001196 .setCallingUid(callingUid)
1197 .setCallingPackage(callingPackage)
1198 .setResolvedType(resolvedType)
1199 .setActivityOptions(bOptions)
1200 .setMayWait(userId)
1201 .execute();
1202 }
1203
1204 @Override
1205 public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
1206 IRecentsAnimationRunner recentsAnimationRunner) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001207 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001208 final int callingPid = Binder.getCallingPid();
1209 final long origId = Binder.clearCallingIdentity();
1210 try {
1211 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07001212 final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
1213 final int recentsUid = mRecentTasks.getRecentsComponentUid();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001214
1215 // Start a new recents animation
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001216 final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
1217 getActivityStartController(), mWindowManager, callingPid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001218 anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
1219 recentsUid, assistDataReceiver);
1220 }
1221 } finally {
1222 Binder.restoreCallingIdentity(origId);
1223 }
1224 }
1225
1226 @Override
1227 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001228 enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001229 "startActivityFromRecents()");
1230
1231 final int callingPid = Binder.getCallingPid();
1232 final int callingUid = Binder.getCallingUid();
1233 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(bOptions);
1234 final long origId = Binder.clearCallingIdentity();
1235 try {
1236 synchronized (mGlobalLock) {
1237 return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
1238 safeOptions);
1239 }
1240 } finally {
1241 Binder.restoreCallingIdentity(origId);
1242 }
1243 }
1244
1245 /**
1246 * This is the internal entry point for handling Activity.finish().
1247 *
1248 * @param token The Binder token referencing the Activity we want to finish.
1249 * @param resultCode Result code, if any, from this Activity.
1250 * @param resultData Result data (Intent), if any, from this Activity.
1251 * @param finishTask Whether to finish the task associated with this Activity.
1252 *
1253 * @return Returns true if the activity successfully finished, or false if it is still running.
1254 */
1255 @Override
1256 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
1257 int finishTask) {
1258 // Refuse possible leaked file descriptors
1259 if (resultData != null && resultData.hasFileDescriptors()) {
1260 throw new IllegalArgumentException("File descriptors passed in Intent");
1261 }
1262
1263 synchronized (mGlobalLock) {
1264 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1265 if (r == null) {
1266 return true;
1267 }
1268 // Keep track of the root activity of the task before we finish it
1269 TaskRecord tr = r.getTask();
1270 ActivityRecord rootR = tr.getRootActivity();
1271 if (rootR == null) {
1272 Slog.w(TAG, "Finishing task with all activities already finished");
1273 }
1274 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
1275 // finish.
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001276 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001277 return false;
1278 }
1279
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001280 // TODO: There is a dup. of this block of code in ActivityStack.navigateUpToLocked
1281 // We should consolidate.
1282 if (mController != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001283 // Find the first activity that is not finishing.
1284 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
1285 if (next != null) {
1286 // ask watcher if this is allowed
1287 boolean resumeOK = true;
1288 try {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001289 resumeOK = mController.activityResuming(next.packageName);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001290 } catch (RemoteException e) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001291 mController = null;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001292 Watchdog.getInstance().setActivityController(null);
1293 }
1294
1295 if (!resumeOK) {
1296 Slog.i(TAG, "Not finishing activity because controller resumed");
1297 return false;
1298 }
1299 }
1300 }
1301 final long origId = Binder.clearCallingIdentity();
1302 try {
1303 boolean res;
1304 final boolean finishWithRootActivity =
1305 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
1306 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
1307 || (finishWithRootActivity && r == rootR)) {
1308 // If requested, remove the task that is associated to this activity only if it
1309 // was the root activity in the task. The result code and data is ignored
1310 // because we don't support returning them across task boundaries. Also, to
1311 // keep backwards compatibility we remove the task from recents when finishing
1312 // task with root activity.
1313 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
1314 finishWithRootActivity, "finish-activity");
1315 if (!res) {
1316 Slog.i(TAG, "Removing task failed to finish activity");
1317 }
Garfield Tan2746ab52018-07-25 12:33:01 -07001318 // Explicitly dismissing the activity so reset its relaunch flag.
1319 r.mRelaunchReason = ActivityRecord.RELAUNCH_REASON_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001320 } else {
1321 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
1322 resultData, "app-request", true);
1323 if (!res) {
1324 Slog.i(TAG, "Failed to finish by app-request");
1325 }
1326 }
1327 return res;
1328 } finally {
1329 Binder.restoreCallingIdentity(origId);
1330 }
1331 }
1332 }
1333
1334 @Override
1335 public boolean finishActivityAffinity(IBinder token) {
1336 synchronized (mGlobalLock) {
1337 final long origId = Binder.clearCallingIdentity();
1338 try {
1339 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1340 if (r == null) {
1341 return false;
1342 }
1343
1344 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
1345 // can finish.
1346 final TaskRecord task = r.getTask();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001347 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001348 return false;
1349 }
1350 return task.getStack().finishActivityAffinityLocked(r);
1351 } finally {
1352 Binder.restoreCallingIdentity(origId);
1353 }
1354 }
1355 }
1356
1357 @Override
1358 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
1359 final long origId = Binder.clearCallingIdentity();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001360 try {
1361 WindowProcessController proc = null;
1362 synchronized (mGlobalLock) {
1363 ActivityStack stack = ActivityRecord.getStackLocked(token);
1364 if (stack == null) {
1365 return;
1366 }
1367 final ActivityRecord r = mStackSupervisor.activityIdleInternalLocked(token,
1368 false /* fromTimeout */, false /* processPausingActivities */, config);
1369 if (r != null) {
1370 proc = r.app;
1371 }
1372 if (stopProfiling && proc != null) {
1373 proc.clearProfilerIfNeeded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001374 }
1375 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001376 } finally {
1377 Binder.restoreCallingIdentity(origId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001378 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001379 }
1380
1381 @Override
1382 public final void activityResumed(IBinder token) {
1383 final long origId = Binder.clearCallingIdentity();
1384 synchronized (mGlobalLock) {
1385 ActivityRecord.activityResumedLocked(token);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001386 mWindowManager.notifyAppResumedFinished(token);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001387 }
1388 Binder.restoreCallingIdentity(origId);
1389 }
1390
1391 @Override
1392 public final void activityPaused(IBinder token) {
1393 final long origId = Binder.clearCallingIdentity();
1394 synchronized (mGlobalLock) {
1395 ActivityStack stack = ActivityRecord.getStackLocked(token);
1396 if (stack != null) {
1397 stack.activityPausedLocked(token, false);
1398 }
1399 }
1400 Binder.restoreCallingIdentity(origId);
1401 }
1402
1403 @Override
1404 public final void activityStopped(IBinder token, Bundle icicle,
1405 PersistableBundle persistentState, CharSequence description) {
1406 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
1407
1408 // Refuse possible leaked file descriptors
1409 if (icicle != null && icicle.hasFileDescriptors()) {
1410 throw new IllegalArgumentException("File descriptors passed in Bundle");
1411 }
1412
1413 final long origId = Binder.clearCallingIdentity();
1414
1415 synchronized (mGlobalLock) {
1416 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1417 if (r != null) {
1418 r.activityStoppedLocked(icicle, persistentState, description);
1419 }
1420 }
1421
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001422 mAmInternal.trimApplications();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001423
1424 Binder.restoreCallingIdentity(origId);
1425 }
1426
1427 @Override
1428 public final void activityDestroyed(IBinder token) {
1429 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
1430 synchronized (mGlobalLock) {
1431 ActivityStack stack = ActivityRecord.getStackLocked(token);
1432 if (stack != null) {
1433 stack.activityDestroyedLocked(token, "activityDestroyed");
1434 }
1435 }
1436 }
1437
1438 @Override
1439 public final void activityRelaunched(IBinder token) {
1440 final long origId = Binder.clearCallingIdentity();
1441 synchronized (mGlobalLock) {
1442 mStackSupervisor.activityRelaunchedLocked(token);
1443 }
1444 Binder.restoreCallingIdentity(origId);
1445 }
1446
1447 public final void activitySlept(IBinder token) {
1448 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
1449
1450 final long origId = Binder.clearCallingIdentity();
1451
1452 synchronized (mGlobalLock) {
1453 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1454 if (r != null) {
1455 mStackSupervisor.activitySleptLocked(r);
1456 }
1457 }
1458
1459 Binder.restoreCallingIdentity(origId);
1460 }
1461
1462 @Override
1463 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
1464 synchronized (mGlobalLock) {
1465 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1466 if (r == null) {
1467 return;
1468 }
1469 final long origId = Binder.clearCallingIdentity();
1470 try {
1471 r.setRequestedOrientation(requestedOrientation);
1472 } finally {
1473 Binder.restoreCallingIdentity(origId);
1474 }
1475 }
1476 }
1477
1478 @Override
1479 public int getRequestedOrientation(IBinder token) {
1480 synchronized (mGlobalLock) {
1481 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1482 if (r == null) {
1483 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
1484 }
1485 return r.getRequestedOrientation();
1486 }
1487 }
1488
1489 @Override
1490 public void setImmersive(IBinder token, boolean immersive) {
1491 synchronized (mGlobalLock) {
1492 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1493 if (r == null) {
1494 throw new IllegalArgumentException();
1495 }
1496 r.immersive = immersive;
1497
1498 // update associated state if we're frontmost
Andrii Kulian52d255c2018-07-13 11:32:19 -07001499 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001500 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001501 applyUpdateLockStateLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001502 }
1503 }
1504 }
1505
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001506 void applyUpdateLockStateLocked(ActivityRecord r) {
1507 // Modifications to the UpdateLock state are done on our handler, outside
1508 // the activity manager's locks. The new state is determined based on the
1509 // state *now* of the relevant activity record. The object is passed to
1510 // the handler solely for logging detail, not to be consulted/modified.
1511 final boolean nextState = r != null && r.immersive;
1512 mH.post(() -> {
1513 if (mUpdateLock.isHeld() != nextState) {
1514 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1515 "Applying new update lock state '" + nextState + "' for " + r);
1516 if (nextState) {
1517 mUpdateLock.acquire();
1518 } else {
1519 mUpdateLock.release();
1520 }
1521 }
1522 });
1523 }
1524
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001525 @Override
1526 public boolean isImmersive(IBinder token) {
1527 synchronized (mGlobalLock) {
1528 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1529 if (r == null) {
1530 throw new IllegalArgumentException();
1531 }
1532 return r.immersive;
1533 }
1534 }
1535
1536 @Override
1537 public boolean isTopActivityImmersive() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001538 enforceNotIsolatedCaller("isTopActivityImmersive");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001539 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001540 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001541 return (r != null) ? r.immersive : false;
1542 }
1543 }
1544
1545 @Override
1546 public void overridePendingTransition(IBinder token, String packageName,
1547 int enterAnim, int exitAnim) {
1548 synchronized (mGlobalLock) {
1549 ActivityRecord self = ActivityRecord.isInStackLocked(token);
1550 if (self == null) {
1551 return;
1552 }
1553
1554 final long origId = Binder.clearCallingIdentity();
1555
1556 if (self.isState(
1557 ActivityStack.ActivityState.RESUMED, ActivityStack.ActivityState.PAUSING)) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001558 mWindowManager.overridePendingAppTransition(packageName,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001559 enterAnim, exitAnim, null);
1560 }
1561
1562 Binder.restoreCallingIdentity(origId);
1563 }
1564 }
1565
1566 @Override
1567 public int getFrontActivityScreenCompatMode() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001568 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001569 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001570 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001571 if (r == null) {
1572 return ActivityManager.COMPAT_MODE_UNKNOWN;
1573 }
Wale Ogunwale53783742018-09-16 10:21:51 -07001574 return mCompatModePackages.computeCompatModeLocked(r.info.applicationInfo);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001575 }
1576 }
1577
1578 @Override
1579 public void setFrontActivityScreenCompatMode(int mode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001580 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001581 "setFrontActivityScreenCompatMode");
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001582 ApplicationInfo ai;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001583 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001584 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001585 if (r == null) {
1586 Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity");
1587 return;
1588 }
1589 ai = r.info.applicationInfo;
Wale Ogunwale53783742018-09-16 10:21:51 -07001590 mCompatModePackages.setPackageScreenCompatModeLocked(ai, mode);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001591 }
1592 }
1593
1594 @Override
1595 public int getLaunchedFromUid(IBinder activityToken) {
1596 ActivityRecord srec;
1597 synchronized (mGlobalLock) {
1598 srec = ActivityRecord.forTokenLocked(activityToken);
1599 }
1600 if (srec == null) {
1601 return -1;
1602 }
1603 return srec.launchedFromUid;
1604 }
1605
1606 @Override
1607 public String getLaunchedFromPackage(IBinder activityToken) {
1608 ActivityRecord srec;
1609 synchronized (mGlobalLock) {
1610 srec = ActivityRecord.forTokenLocked(activityToken);
1611 }
1612 if (srec == null) {
1613 return null;
1614 }
1615 return srec.launchedFromPackage;
1616 }
1617
1618 @Override
1619 public boolean convertFromTranslucent(IBinder token) {
1620 final long origId = Binder.clearCallingIdentity();
1621 try {
1622 synchronized (mGlobalLock) {
1623 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1624 if (r == null) {
1625 return false;
1626 }
1627 final boolean translucentChanged = r.changeWindowTranslucency(true);
1628 if (translucentChanged) {
1629 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
1630 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001631 mWindowManager.setAppFullscreen(token, true);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001632 return translucentChanged;
1633 }
1634 } finally {
1635 Binder.restoreCallingIdentity(origId);
1636 }
1637 }
1638
1639 @Override
1640 public boolean convertToTranslucent(IBinder token, Bundle options) {
1641 SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
1642 final long origId = Binder.clearCallingIdentity();
1643 try {
1644 synchronized (mGlobalLock) {
1645 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1646 if (r == null) {
1647 return false;
1648 }
1649 final TaskRecord task = r.getTask();
1650 int index = task.mActivities.lastIndexOf(r);
1651 if (index > 0) {
1652 ActivityRecord under = task.mActivities.get(index - 1);
1653 under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
1654 }
1655 final boolean translucentChanged = r.changeWindowTranslucency(false);
1656 if (translucentChanged) {
1657 r.getStack().convertActivityToTranslucent(r);
1658 }
1659 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001660 mWindowManager.setAppFullscreen(token, false);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001661 return translucentChanged;
1662 }
1663 } finally {
1664 Binder.restoreCallingIdentity(origId);
1665 }
1666 }
1667
1668 @Override
1669 public void notifyActivityDrawn(IBinder token) {
1670 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
1671 synchronized (mGlobalLock) {
1672 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
1673 if (r != null) {
1674 r.getStack().notifyActivityDrawnLocked(r);
1675 }
1676 }
1677 }
1678
1679 @Override
1680 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
1681 synchronized (mGlobalLock) {
1682 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1683 if (r == null) {
1684 return;
1685 }
1686 r.reportFullyDrawnLocked(restoredFromBundle);
1687 }
1688 }
1689
1690 @Override
1691 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
1692 synchronized (mGlobalLock) {
1693 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
1694 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
1695 return stack.mDisplayId;
1696 }
1697 return DEFAULT_DISPLAY;
1698 }
1699 }
1700
1701 @Override
1702 public ActivityManager.StackInfo getFocusedStackInfo() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001703 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001704 long ident = Binder.clearCallingIdentity();
1705 try {
1706 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001707 ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001708 if (focusedStack != null) {
1709 return mStackSupervisor.getStackInfo(focusedStack.mStackId);
1710 }
1711 return null;
1712 }
1713 } finally {
1714 Binder.restoreCallingIdentity(ident);
1715 }
1716 }
1717
1718 @Override
1719 public void setFocusedStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001720 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001721 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
1722 final long callingId = Binder.clearCallingIdentity();
1723 try {
1724 synchronized (mGlobalLock) {
1725 final ActivityStack stack = mStackSupervisor.getStack(stackId);
1726 if (stack == null) {
1727 Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
1728 return;
1729 }
1730 final ActivityRecord r = stack.topRunningActivityLocked();
Louis Chang19443452018-10-09 12:10:21 +08001731 if (r != null && r.moveFocusableActivityToTop("setFocusedStack")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08001732 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001733 }
1734 }
1735 } finally {
1736 Binder.restoreCallingIdentity(callingId);
1737 }
1738 }
1739
1740 @Override
1741 public void setFocusedTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001742 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001743 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
1744 final long callingId = Binder.clearCallingIdentity();
1745 try {
1746 synchronized (mGlobalLock) {
1747 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1748 if (task == null) {
1749 return;
1750 }
1751 final ActivityRecord r = task.topRunningActivityLocked();
Louis Chang19443452018-10-09 12:10:21 +08001752 if (r != null && r.moveFocusableActivityToTop("setFocusedTask")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08001753 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001754 }
1755 }
1756 } finally {
1757 Binder.restoreCallingIdentity(callingId);
1758 }
1759 }
1760
1761 @Override
1762 public boolean removeTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001763 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001764 synchronized (mGlobalLock) {
1765 final long ident = Binder.clearCallingIdentity();
1766 try {
1767 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
1768 "remove-task");
1769 } finally {
1770 Binder.restoreCallingIdentity(ident);
1771 }
1772 }
1773 }
1774
1775 @Override
Winson Chunge6439102018-07-30 15:48:01 -07001776 public void removeAllVisibleRecentTasks() {
1777 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeAllVisibleRecentTasks()");
1778 synchronized (mGlobalLock) {
1779 final long ident = Binder.clearCallingIdentity();
1780 try {
1781 getRecentTasks().removeAllVisibleTasks();
1782 } finally {
1783 Binder.restoreCallingIdentity(ident);
1784 }
1785 }
1786 }
1787
1788 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001789 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
1790 synchronized (mGlobalLock) {
1791 final ActivityRecord srec = ActivityRecord.forTokenLocked(token);
1792 if (srec != null) {
1793 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
1794 }
1795 }
1796 return false;
1797 }
1798
1799 @Override
1800 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
1801 Intent resultData) {
1802
1803 synchronized (mGlobalLock) {
1804 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
1805 if (r != null) {
1806 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
1807 }
1808 return false;
1809 }
1810 }
1811
1812 /**
1813 * Attempts to move a task backwards in z-order (the order of activities within the task is
1814 * unchanged).
1815 *
1816 * There are several possible results of this call:
1817 * - if the task is locked, then we will show the lock toast
1818 * - if there is a task behind the provided task, then that task is made visible and resumed as
1819 * this task is moved to the back
1820 * - otherwise, if there are no other tasks in the stack:
1821 * - if this task is in the pinned stack, then we remove the stack completely, which will
1822 * have the effect of moving the task to the top or bottom of the fullscreen stack
1823 * (depending on whether it is visible)
1824 * - otherwise, we simply return home and hide this task
1825 *
1826 * @param token A reference to the activity we wish to move
1827 * @param nonRoot If false then this only works if the activity is the root
1828 * of a task; if true it will work for any activity in a task.
1829 * @return Returns true if the move completed, false if not.
1830 */
1831 @Override
1832 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001833 enforceNotIsolatedCaller("moveActivityTaskToBack");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001834 synchronized (mGlobalLock) {
1835 final long origId = Binder.clearCallingIdentity();
1836 try {
1837 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
1838 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1839 if (task != null) {
1840 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
1841 }
1842 } finally {
1843 Binder.restoreCallingIdentity(origId);
1844 }
1845 }
1846 return false;
1847 }
1848
1849 @Override
1850 public Rect getTaskBounds(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001851 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001852 long ident = Binder.clearCallingIdentity();
1853 Rect rect = new Rect();
1854 try {
1855 synchronized (mGlobalLock) {
1856 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
1857 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1858 if (task == null) {
1859 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
1860 return rect;
1861 }
1862 if (task.getStack() != null) {
1863 // Return the bounds from window manager since it will be adjusted for various
1864 // things like the presense of a docked stack for tasks that aren't resizeable.
1865 task.getWindowContainerBounds(rect);
1866 } else {
1867 // Task isn't in window manager yet since it isn't associated with a stack.
1868 // Return the persist value from activity manager
1869 if (!task.matchParentBounds()) {
1870 rect.set(task.getBounds());
1871 } else if (task.mLastNonFullscreenBounds != null) {
1872 rect.set(task.mLastNonFullscreenBounds);
1873 }
1874 }
1875 }
1876 } finally {
1877 Binder.restoreCallingIdentity(ident);
1878 }
1879 return rect;
1880 }
1881
1882 @Override
1883 public ActivityManager.TaskDescription getTaskDescription(int id) {
1884 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001885 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001886 MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
1887 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
1888 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1889 if (tr != null) {
1890 return tr.lastTaskDescription;
1891 }
1892 }
1893 return null;
1894 }
1895
1896 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001897 public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
1898 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
1899 setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
1900 toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
1901 return;
1902 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001903 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001904 synchronized (mGlobalLock) {
1905 final long ident = Binder.clearCallingIdentity();
1906 try {
1907 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1908 if (task == null) {
1909 Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
1910 return;
1911 }
1912
1913 if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
1914 + " to windowingMode=" + windowingMode + " toTop=" + toTop);
1915
1916 if (!task.isActivityTypeStandardOrUndefined()) {
1917 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
1918 + " non-standard task " + taskId + " to windowing mode="
1919 + windowingMode);
1920 }
1921
1922 final ActivityStack stack = task.getStack();
1923 if (toTop) {
1924 stack.moveToFront("setTaskWindowingMode", task);
1925 }
1926 stack.setWindowingMode(windowingMode);
1927 } finally {
1928 Binder.restoreCallingIdentity(ident);
1929 }
1930 }
1931 }
1932
1933 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001934 public String getCallingPackage(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001935 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001936 ActivityRecord r = getCallingRecordLocked(token);
1937 return r != null ? r.info.packageName : null;
1938 }
1939 }
1940
1941 @Override
1942 public ComponentName getCallingActivity(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001943 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001944 ActivityRecord r = getCallingRecordLocked(token);
1945 return r != null ? r.intent.getComponent() : null;
1946 }
1947 }
1948
1949 private ActivityRecord getCallingRecordLocked(IBinder token) {
1950 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1951 if (r == null) {
1952 return null;
1953 }
1954 return r.resultTo;
1955 }
1956
1957 @Override
1958 public void unhandledBack() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001959 mAmInternal.enforceCallingPermission(android.Manifest.permission.FORCE_BACK, "unhandledBack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001960
1961 synchronized (mGlobalLock) {
1962 final long origId = Binder.clearCallingIdentity();
1963 try {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001964 getTopDisplayFocusedStack().unhandledBackLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001965 } finally {
1966 Binder.restoreCallingIdentity(origId);
1967 }
1968 }
1969 }
1970
1971 /**
1972 * TODO: Add mController hook
1973 */
1974 @Override
1975 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001976 mAmInternal.enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001977
1978 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
1979 synchronized (mGlobalLock) {
1980 moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
1981 false /* fromRecents */);
1982 }
1983 }
1984
1985 void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
1986 boolean fromRecents) {
1987
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001988 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001989 Binder.getCallingUid(), -1, -1, "Task to front")) {
1990 SafeActivityOptions.abort(options);
1991 return;
1992 }
1993 final long origId = Binder.clearCallingIdentity();
1994 try {
1995 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1996 if (task == null) {
1997 Slog.d(TAG, "Could not find task for id: "+ taskId);
Winson Chungd0243682018-09-25 18:11:54 -07001998 SafeActivityOptions.abort(options);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001999 return;
2000 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002001 if (getLockTaskController().isLockTaskModeViolation(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002002 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
Winson Chungd0243682018-09-25 18:11:54 -07002003 SafeActivityOptions.abort(options);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002004 return;
2005 }
2006 ActivityOptions realOptions = options != null
2007 ? options.getOptions(mStackSupervisor)
2008 : null;
2009 mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
2010 false /* forceNonResizable */);
2011
2012 final ActivityRecord topActivity = task.getTopActivity();
2013 if (topActivity != null) {
2014
2015 // We are reshowing a task, use a starting window to hide the initial draw delay
2016 // so the transition can start earlier.
2017 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
2018 true /* taskSwitch */, fromRecents);
2019 }
2020 } finally {
2021 Binder.restoreCallingIdentity(origId);
2022 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002023 }
2024
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002025 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
2026 int callingPid, int callingUid, String name) {
2027 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
2028 return true;
2029 }
2030
2031 if (getRecentTasks().isCallerRecents(sourceUid)) {
2032 return true;
2033 }
2034
2035 int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
2036 if (perm == PackageManager.PERMISSION_GRANTED) {
2037 return true;
2038 }
2039 if (checkAllowAppSwitchUid(sourceUid)) {
2040 return true;
2041 }
2042
2043 // If the actual IPC caller is different from the logical source, then
2044 // also see if they are allowed to control app switches.
2045 if (callingUid != -1 && callingUid != sourceUid) {
2046 perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
2047 if (perm == PackageManager.PERMISSION_GRANTED) {
2048 return true;
2049 }
2050 if (checkAllowAppSwitchUid(callingUid)) {
2051 return true;
2052 }
2053 }
2054
2055 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
2056 return false;
2057 }
2058
2059 private boolean checkAllowAppSwitchUid(int uid) {
2060 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
2061 if (types != null) {
2062 for (int i = types.size() - 1; i >= 0; i--) {
2063 if (types.valueAt(i).intValue() == uid) {
2064 return true;
2065 }
2066 }
2067 }
2068 return false;
2069 }
2070
2071 @Override
2072 public void setActivityController(IActivityController controller, boolean imAMonkey) {
2073 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
2074 "setActivityController()");
2075 synchronized (mGlobalLock) {
2076 mController = controller;
2077 mControllerIsAMonkey = imAMonkey;
2078 Watchdog.getInstance().setActivityController(controller);
2079 }
2080 }
2081
2082 boolean isControllerAMonkey() {
2083 synchronized (mGlobalLock) {
2084 return mController != null && mControllerIsAMonkey;
2085 }
2086 }
2087
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002088 @Override
2089 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
2090 synchronized (mGlobalLock) {
2091 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
2092 }
2093 }
2094
2095 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002096 public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum) {
2097 return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
2098 }
2099
2100 @Override
2101 public List<ActivityManager.RunningTaskInfo> getFilteredTasks(int maxNum,
2102 @WindowConfiguration.ActivityType int ignoreActivityType,
2103 @WindowConfiguration.WindowingMode int ignoreWindowingMode) {
2104 final int callingUid = Binder.getCallingUid();
2105 ArrayList<ActivityManager.RunningTaskInfo> list = new ArrayList<>();
2106
2107 synchronized (mGlobalLock) {
2108 if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
2109
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002110 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002111 callingUid);
2112 mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
2113 ignoreWindowingMode, callingUid, allowed);
2114 }
2115
2116 return list;
2117 }
2118
2119 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002120 public final void finishSubActivity(IBinder token, String resultWho, int requestCode) {
2121 synchronized (mGlobalLock) {
2122 final long origId = Binder.clearCallingIdentity();
2123 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2124 if (r != null) {
2125 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
2126 }
2127 Binder.restoreCallingIdentity(origId);
2128 }
2129 }
2130
2131 @Override
2132 public boolean willActivityBeVisible(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002133 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002134 ActivityStack stack = ActivityRecord.getStackLocked(token);
2135 if (stack != null) {
2136 return stack.willActivityBeVisibleLocked(token);
2137 }
2138 return false;
2139 }
2140 }
2141
2142 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002143 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002144 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002145 synchronized (mGlobalLock) {
2146 final long ident = Binder.clearCallingIdentity();
2147 try {
2148 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2149 if (task == null) {
2150 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
2151 return;
2152 }
2153
2154 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
2155 + " to stackId=" + stackId + " toTop=" + toTop);
2156
2157 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2158 if (stack == null) {
2159 throw new IllegalStateException(
2160 "moveTaskToStack: No stack for stackId=" + stackId);
2161 }
2162 if (!stack.isActivityTypeStandardOrUndefined()) {
2163 throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
2164 + taskId + " to stack " + stackId);
2165 }
2166 if (stack.inSplitScreenPrimaryWindowingMode()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002167 mWindowManager.setDockedStackCreateState(
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002168 SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
2169 }
2170 task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
2171 "moveTaskToStack");
2172 } finally {
2173 Binder.restoreCallingIdentity(ident);
2174 }
2175 }
2176 }
2177
2178 @Override
2179 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
2180 boolean preserveWindows, boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002181 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002182
2183 final long ident = Binder.clearCallingIdentity();
2184 try {
2185 synchronized (mGlobalLock) {
2186 if (animate) {
2187 final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
2188 if (stack == null) {
2189 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2190 return;
2191 }
2192 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
2193 throw new IllegalArgumentException("Stack: " + stackId
2194 + " doesn't support animated resize.");
2195 }
2196 stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
2197 animationDuration, false /* fromFullscreen */);
2198 } else {
2199 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2200 if (stack == null) {
2201 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2202 return;
2203 }
2204 mStackSupervisor.resizeStackLocked(stack, destBounds,
2205 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
2206 preserveWindows, allowResizeInDockedMode, !DEFER_RESUME);
2207 }
2208 }
2209 } finally {
2210 Binder.restoreCallingIdentity(ident);
2211 }
2212 }
2213
2214 /**
2215 * Moves the specified task to the primary-split-screen stack.
2216 *
2217 * @param taskId Id of task to move.
2218 * @param createMode The mode the primary split screen stack should be created in if it doesn't
2219 * exist already. See
2220 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
2221 * and
2222 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
2223 * @param toTop If the task and stack should be moved to the top.
2224 * @param animate Whether we should play an animation for the moving the task.
2225 * @param initialBounds If the primary stack gets created, it will use these bounds for the
2226 * stack. Pass {@code null} to use default bounds.
2227 * @param showRecents If the recents activity should be shown on the other side of the task
2228 * going into split-screen mode.
2229 */
2230 @Override
2231 public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode,
2232 boolean toTop, boolean animate, Rect initialBounds, boolean showRecents) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002233 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002234 "setTaskWindowingModeSplitScreenPrimary()");
2235 synchronized (mGlobalLock) {
2236 final long ident = Binder.clearCallingIdentity();
2237 try {
2238 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2239 if (task == null) {
2240 Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
2241 return false;
2242 }
2243 if (DEBUG_STACK) Slog.d(TAG_STACK,
2244 "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
2245 + " to createMode=" + createMode + " toTop=" + toTop);
2246 if (!task.isActivityTypeStandardOrUndefined()) {
2247 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
2248 + " non-standard task " + taskId + " to split-screen windowing mode");
2249 }
2250
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002251 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002252 final int windowingMode = task.getWindowingMode();
2253 final ActivityStack stack = task.getStack();
2254 if (toTop) {
2255 stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
2256 }
2257 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
2258 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */);
2259 return windowingMode != task.getWindowingMode();
2260 } finally {
2261 Binder.restoreCallingIdentity(ident);
2262 }
2263 }
2264 }
2265
2266 /**
2267 * Removes stacks in the input windowing modes from the system if they are of activity type
2268 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
2269 */
2270 @Override
2271 public void removeStacksInWindowingModes(int[] windowingModes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002272 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002273 "removeStacksInWindowingModes()");
2274
2275 synchronized (mGlobalLock) {
2276 final long ident = Binder.clearCallingIdentity();
2277 try {
2278 mStackSupervisor.removeStacksInWindowingModes(windowingModes);
2279 } finally {
2280 Binder.restoreCallingIdentity(ident);
2281 }
2282 }
2283 }
2284
2285 @Override
2286 public void removeStacksWithActivityTypes(int[] activityTypes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002287 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002288 "removeStacksWithActivityTypes()");
2289
2290 synchronized (mGlobalLock) {
2291 final long ident = Binder.clearCallingIdentity();
2292 try {
2293 mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
2294 } finally {
2295 Binder.restoreCallingIdentity(ident);
2296 }
2297 }
2298 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002299
2300 @Override
2301 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
2302 int userId) {
2303 final int callingUid = Binder.getCallingUid();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002304 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, "getRecentTasks");
2305 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002306 callingUid);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002307 final boolean detailed = checkGetTasksPermission(
2308 android.Manifest.permission.GET_DETAILED_TASKS, Binder.getCallingPid(),
2309 UserHandle.getAppId(callingUid))
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002310 == PackageManager.PERMISSION_GRANTED;
2311
2312 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002313 return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002314 callingUid);
2315 }
2316 }
2317
2318 @Override
2319 public List<ActivityManager.StackInfo> getAllStackInfos() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002320 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002321 long ident = Binder.clearCallingIdentity();
2322 try {
2323 synchronized (mGlobalLock) {
2324 return mStackSupervisor.getAllStackInfosLocked();
2325 }
2326 } finally {
2327 Binder.restoreCallingIdentity(ident);
2328 }
2329 }
2330
2331 @Override
2332 public ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002333 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002334 long ident = Binder.clearCallingIdentity();
2335 try {
2336 synchronized (mGlobalLock) {
2337 return mStackSupervisor.getStackInfo(windowingMode, activityType);
2338 }
2339 } finally {
2340 Binder.restoreCallingIdentity(ident);
2341 }
2342 }
2343
2344 @Override
2345 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002346 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002347 final long callingUid = Binder.getCallingUid();
2348 final long origId = Binder.clearCallingIdentity();
2349 try {
2350 synchronized (mGlobalLock) {
2351 // Cancel the recents animation synchronously (do not hold the WM lock)
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002352 mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002353 ? REORDER_MOVE_TO_ORIGINAL_POSITION
2354 : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
2355 }
2356 } finally {
2357 Binder.restoreCallingIdentity(origId);
2358 }
2359 }
2360
2361 @Override
2362 public void startLockTaskModeByToken(IBinder token) {
2363 synchronized (mGlobalLock) {
2364 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2365 if (r == null) {
2366 return;
2367 }
2368 startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
2369 }
2370 }
2371
2372 @Override
2373 public void startSystemLockTaskMode(int taskId) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002374 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002375 // This makes inner call to look as if it was initiated by system.
2376 long ident = Binder.clearCallingIdentity();
2377 try {
2378 synchronized (mGlobalLock) {
2379 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2380
2381 // When starting lock task mode the stack must be in front and focused
2382 task.getStack().moveToFront("startSystemLockTaskMode");
2383 startLockTaskModeLocked(task, true /* isSystemCaller */);
2384 }
2385 } finally {
2386 Binder.restoreCallingIdentity(ident);
2387 }
2388 }
2389
2390 @Override
2391 public void stopLockTaskModeByToken(IBinder token) {
2392 synchronized (mGlobalLock) {
2393 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2394 if (r == null) {
2395 return;
2396 }
2397 stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
2398 }
2399 }
2400
2401 /**
2402 * This API should be called by SystemUI only when user perform certain action to dismiss
2403 * lock task mode. We should only dismiss pinned lock task mode in this case.
2404 */
2405 @Override
2406 public void stopSystemLockTaskMode() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002407 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002408 stopLockTaskModeInternal(null, true /* isSystemCaller */);
2409 }
2410
2411 private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
2412 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
2413 if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
2414 return;
2415 }
2416
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002417 final ActivityStack stack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002418 if (stack == null || task != stack.topTask()) {
2419 throw new IllegalArgumentException("Invalid task, not in foreground");
2420 }
2421
2422 // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
2423 // system or a specific app.
2424 // * System-initiated requests will only start the pinned mode (screen pinning)
2425 // * App-initiated requests
2426 // - will put the device in fully locked mode (LockTask), if the app is whitelisted
2427 // - will start the pinned mode, otherwise
2428 final int callingUid = Binder.getCallingUid();
2429 long ident = Binder.clearCallingIdentity();
2430 try {
2431 // When a task is locked, dismiss the pinned stack if it exists
2432 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2433
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002434 getLockTaskController().startLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002435 } finally {
2436 Binder.restoreCallingIdentity(ident);
2437 }
2438 }
2439
2440 private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
2441 final int callingUid = Binder.getCallingUid();
2442 long ident = Binder.clearCallingIdentity();
2443 try {
2444 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002445 getLockTaskController().stopLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002446 }
2447 // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
2448 // task and jumping straight into a call in the case of emergency call back.
2449 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
2450 if (tm != null) {
2451 tm.showInCallScreen(false);
2452 }
2453 } finally {
2454 Binder.restoreCallingIdentity(ident);
2455 }
2456 }
2457
2458 @Override
2459 public boolean isInLockTaskMode() {
2460 return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
2461 }
2462
2463 @Override
2464 public int getLockTaskModeState() {
2465 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002466 return getLockTaskController().getLockTaskModeState();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002467 }
2468 }
2469
2470 @Override
2471 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
2472 synchronized (mGlobalLock) {
2473 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2474 if (r != null) {
2475 r.setTaskDescription(td);
2476 final TaskRecord task = r.getTask();
2477 task.updateTaskDescription();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002478 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002479 }
2480 }
2481 }
2482
2483 @Override
2484 public Bundle getActivityOptions(IBinder token) {
2485 final long origId = Binder.clearCallingIdentity();
2486 try {
2487 synchronized (mGlobalLock) {
2488 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
2489 if (r != null) {
2490 final ActivityOptions activityOptions = r.takeOptionsLocked();
2491 return activityOptions == null ? null : activityOptions.toBundle();
2492 }
2493 return null;
2494 }
2495 } finally {
2496 Binder.restoreCallingIdentity(origId);
2497 }
2498 }
2499
2500 @Override
2501 public List<IBinder> getAppTasks(String callingPackage) {
2502 int callingUid = Binder.getCallingUid();
2503 long ident = Binder.clearCallingIdentity();
2504 try {
2505 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002506 return mRecentTasks.getAppTasksList(callingUid, callingPackage);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002507 }
2508 } finally {
2509 Binder.restoreCallingIdentity(ident);
2510 }
2511 }
2512
2513 @Override
2514 public void finishVoiceTask(IVoiceInteractionSession session) {
2515 synchronized (mGlobalLock) {
2516 final long origId = Binder.clearCallingIdentity();
2517 try {
2518 // TODO: VI Consider treating local voice interactions and voice tasks
2519 // differently here
2520 mStackSupervisor.finishVoiceTask(session);
2521 } finally {
2522 Binder.restoreCallingIdentity(origId);
2523 }
2524 }
2525
2526 }
2527
2528 @Override
2529 public boolean isTopOfTask(IBinder token) {
2530 synchronized (mGlobalLock) {
2531 ActivityRecord r = ActivityRecord.isInStackLocked(token);
Riddle Hsu66b74a82018-07-26 00:20:12 +08002532 return r != null && r.getTask().getTopActivity() == r;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002533 }
2534 }
2535
2536 @Override
2537 public void notifyLaunchTaskBehindComplete(IBinder token) {
2538 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
2539 }
2540
2541 @Override
2542 public void notifyEnterAnimationComplete(IBinder token) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002543 mH.post(() -> {
2544 synchronized (mGlobalLock) {
2545 ActivityRecord r = ActivityRecord.forTokenLocked(token);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002546 if (r != null && r.attachedToProcess()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002547 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002548 r.app.getThread().scheduleEnterAnimationComplete(r.appToken);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002549 } catch (RemoteException e) {
2550 }
2551 }
2552 }
2553
2554 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002555 }
2556
2557 /** Called from an app when assist data is ready. */
2558 @Override
2559 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
2560 AssistContent content, Uri referrer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002561 PendingAssistExtras pae = (PendingAssistExtras) token;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002562 synchronized (pae) {
2563 pae.result = extras;
2564 pae.structure = structure;
2565 pae.content = content;
2566 if (referrer != null) {
2567 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
2568 }
2569 if (structure != null) {
2570 structure.setHomeActivity(pae.isHome);
2571 }
2572 pae.haveResult = true;
2573 pae.notifyAll();
2574 if (pae.intent == null && pae.receiver == null) {
2575 // Caller is just waiting for the result.
2576 return;
2577 }
2578 }
2579 // We are now ready to launch the assist activity.
2580 IAssistDataReceiver sendReceiver = null;
2581 Bundle sendBundle = null;
2582 synchronized (mGlobalLock) {
2583 buildAssistBundleLocked(pae, extras);
2584 boolean exists = mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002585 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002586 if (!exists) {
2587 // Timed out.
2588 return;
2589 }
2590
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002591 if ((sendReceiver = pae.receiver) != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002592 // Caller wants result sent back to them.
2593 sendBundle = new Bundle();
2594 sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
2595 sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
2596 sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
2597 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
2598 }
2599 }
2600 if (sendReceiver != null) {
2601 try {
2602 sendReceiver.onHandleAssistData(sendBundle);
2603 } catch (RemoteException e) {
2604 }
2605 return;
2606 }
2607
2608 final long ident = Binder.clearCallingIdentity();
2609 try {
2610 if (TextUtils.equals(pae.intent.getAction(),
2611 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
2612 pae.intent.putExtras(pae.extras);
2613 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
2614 } else {
2615 pae.intent.replaceExtras(pae.extras);
2616 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
2617 | Intent.FLAG_ACTIVITY_SINGLE_TOP
2618 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002619 mAmInternal.closeSystemDialogs("assist");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002620
2621 try {
2622 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
2623 } catch (ActivityNotFoundException e) {
2624 Slog.w(TAG, "No activity to handle assist action.", e);
2625 }
2626 }
2627 } finally {
2628 Binder.restoreCallingIdentity(ident);
2629 }
2630 }
2631
2632 @Override
2633 public int addAppTask(IBinder activityToken, Intent intent,
2634 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
2635 final int callingUid = Binder.getCallingUid();
2636 final long callingIdent = Binder.clearCallingIdentity();
2637
2638 try {
2639 synchronized (mGlobalLock) {
2640 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
2641 if (r == null) {
2642 throw new IllegalArgumentException("Activity does not exist; token="
2643 + activityToken);
2644 }
2645 ComponentName comp = intent.getComponent();
2646 if (comp == null) {
2647 throw new IllegalArgumentException("Intent " + intent
2648 + " must specify explicit component");
2649 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002650 if (thumbnail.getWidth() != mThumbnailWidth
2651 || thumbnail.getHeight() != mThumbnailHeight) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002652 throw new IllegalArgumentException("Bad thumbnail size: got "
2653 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002654 + mThumbnailWidth + "x" + mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002655 }
2656 if (intent.getSelector() != null) {
2657 intent.setSelector(null);
2658 }
2659 if (intent.getSourceBounds() != null) {
2660 intent.setSourceBounds(null);
2661 }
2662 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
2663 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
2664 // The caller has added this as an auto-remove task... that makes no
2665 // sense, so turn off auto-remove.
2666 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
2667 }
2668 }
2669 final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
2670 STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
2671 if (ainfo.applicationInfo.uid != callingUid) {
2672 throw new SecurityException(
2673 "Can't add task for another application: target uid="
2674 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
2675 }
2676
2677 final ActivityStack stack = r.getStack();
2678 final TaskRecord task = stack.createTaskRecord(
2679 mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent,
2680 null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002681 if (!mRecentTasks.addToBottom(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002682 // The app has too many tasks already and we can't add any more
2683 stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
2684 return INVALID_TASK_ID;
2685 }
2686 task.lastTaskDescription.copyFrom(description);
2687
2688 // TODO: Send the thumbnail to WM to store it.
2689
2690 return task.taskId;
2691 }
2692 } finally {
2693 Binder.restoreCallingIdentity(callingIdent);
2694 }
2695 }
2696
2697 @Override
2698 public Point getAppTaskThumbnailSize() {
2699 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002700 return new Point(mThumbnailWidth, mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002701 }
2702 }
2703
2704 @Override
2705 public void setTaskResizeable(int taskId, int resizeableMode) {
2706 synchronized (mGlobalLock) {
2707 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
2708 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
2709 if (task == null) {
2710 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
2711 return;
2712 }
2713 task.setResizeMode(resizeableMode);
2714 }
2715 }
2716
2717 @Override
2718 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002719 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002720 long ident = Binder.clearCallingIdentity();
2721 try {
2722 synchronized (mGlobalLock) {
2723 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2724 if (task == null) {
2725 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
2726 return;
2727 }
2728 // Place the task in the right stack if it isn't there already based on
2729 // the requested bounds.
2730 // The stack transition logic is:
2731 // - a null bounds on a freeform task moves that task to fullscreen
2732 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
2733 // that task to freeform
2734 // - otherwise the task is not moved
2735 ActivityStack stack = task.getStack();
2736 if (!task.getWindowConfiguration().canResizeTask()) {
2737 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
2738 }
2739 if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
2740 stack = stack.getDisplay().getOrCreateStack(
2741 WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
2742 } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
2743 stack = stack.getDisplay().getOrCreateStack(
2744 WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
2745 }
2746
2747 // Reparent the task to the right stack if necessary
2748 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
2749 if (stack != task.getStack()) {
2750 // Defer resume until the task is resized below
2751 task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
2752 DEFER_RESUME, "resizeTask");
2753 preserveWindow = false;
2754 }
2755
2756 // After reparenting (which only resizes the task to the stack bounds), resize the
2757 // task to the actual bounds provided
2758 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
2759 }
2760 } finally {
2761 Binder.restoreCallingIdentity(ident);
2762 }
2763 }
2764
2765 @Override
2766 public boolean releaseActivityInstance(IBinder token) {
2767 synchronized (mGlobalLock) {
2768 final long origId = Binder.clearCallingIdentity();
2769 try {
2770 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2771 if (r == null) {
2772 return false;
2773 }
2774 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
2775 } finally {
2776 Binder.restoreCallingIdentity(origId);
2777 }
2778 }
2779 }
2780
2781 @Override
2782 public void releaseSomeActivities(IApplicationThread appInt) {
2783 synchronized (mGlobalLock) {
2784 final long origId = Binder.clearCallingIdentity();
2785 try {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07002786 final WindowProcessController app = getProcessController(appInt);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002787 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
2788 } finally {
2789 Binder.restoreCallingIdentity(origId);
2790 }
2791 }
2792 }
2793
2794 @Override
2795 public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
2796 int secondaryDisplayShowing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002797 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002798 != PackageManager.PERMISSION_GRANTED) {
2799 throw new SecurityException("Requires permission "
2800 + android.Manifest.permission.DEVICE_POWER);
2801 }
2802
2803 synchronized (mGlobalLock) {
2804 long ident = Binder.clearCallingIdentity();
2805 if (mKeyguardShown != keyguardShowing) {
2806 mKeyguardShown = keyguardShowing;
Wale Ogunwale342fbe92018-10-09 08:44:10 -07002807 final Message msg = PooledLambda.obtainMessage(
2808 ActivityManagerInternal::reportCurKeyguardUsageEvent, mAmInternal,
2809 keyguardShowing);
2810 mH.sendMessage(msg);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002811 }
2812 try {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002813 mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002814 secondaryDisplayShowing);
2815 } finally {
2816 Binder.restoreCallingIdentity(ident);
2817 }
2818 }
2819
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002820 mH.post(() -> {
2821 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2822 mScreenObservers.get(i).onKeyguardStateChanged(keyguardShowing);
2823 }
2824 });
2825 }
2826
2827 void onScreenAwakeChanged(boolean isAwake) {
2828 mH.post(() -> {
2829 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2830 mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2831 }
2832 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002833 }
2834
2835 @Override
2836 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002837 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
2838 userId, "getTaskDescriptionIcon");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002839
2840 final File passedIconFile = new File(filePath);
2841 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
2842 passedIconFile.getName());
2843 if (!legitIconFile.getPath().equals(filePath)
2844 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
2845 throw new IllegalArgumentException("Bad file path: " + filePath
2846 + " passed for userId " + userId);
2847 }
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002848 return mRecentTasks.getTaskDescriptionIcon(filePath);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002849 }
2850
2851 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002852 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002853 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
2854 final ActivityOptions activityOptions = safeOptions != null
2855 ? safeOptions.getOptions(mStackSupervisor)
2856 : null;
2857 if (activityOptions == null
2858 || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
2859 || activityOptions.getCustomInPlaceResId() == 0) {
2860 throw new IllegalArgumentException("Expected in-place ActivityOption " +
2861 "with valid animation");
2862 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002863 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
2864 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002865 activityOptions.getCustomInPlaceResId());
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002866 mWindowManager.executeAppTransition();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002867 }
2868
2869 @Override
2870 public void removeStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002871 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002872 synchronized (mGlobalLock) {
2873 final long ident = Binder.clearCallingIdentity();
2874 try {
2875 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2876 if (stack == null) {
2877 Slog.w(TAG, "removeStack: No stack with id=" + stackId);
2878 return;
2879 }
2880 if (!stack.isActivityTypeStandardOrUndefined()) {
2881 throw new IllegalArgumentException(
2882 "Removing non-standard stack is not allowed.");
2883 }
2884 mStackSupervisor.removeStack(stack);
2885 } finally {
2886 Binder.restoreCallingIdentity(ident);
2887 }
2888 }
2889 }
2890
2891 @Override
2892 public void moveStackToDisplay(int stackId, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002893 mAmInternal.enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002894
2895 synchronized (mGlobalLock) {
2896 final long ident = Binder.clearCallingIdentity();
2897 try {
2898 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
2899 + " to displayId=" + displayId);
2900 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
2901 } finally {
2902 Binder.restoreCallingIdentity(ident);
2903 }
2904 }
2905 }
2906
2907 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002908 public void exitFreeformMode(IBinder token) {
2909 synchronized (mGlobalLock) {
2910 long ident = Binder.clearCallingIdentity();
2911 try {
2912 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2913 if (r == null) {
2914 throw new IllegalArgumentException(
2915 "exitFreeformMode: No activity record matching token=" + token);
2916 }
2917
2918 final ActivityStack stack = r.getStack();
2919 if (stack == null || !stack.inFreeformWindowingMode()) {
2920 throw new IllegalStateException(
2921 "exitFreeformMode: You can only go fullscreen from freeform.");
2922 }
2923
2924 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
2925 } finally {
2926 Binder.restoreCallingIdentity(ident);
2927 }
2928 }
2929 }
2930
2931 /** Sets the task stack listener that gets callbacks when a task stack changes. */
2932 @Override
2933 public void registerTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002934 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002935 "registerTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002936 mTaskChangeNotificationController.registerTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002937 }
2938
2939 /** Unregister a task stack listener so that it stops receiving callbacks. */
2940 @Override
2941 public void unregisterTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002942 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002943 "unregisterTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002944 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002945 }
2946
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002947 @Override
2948 public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
2949 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
2950 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
2951 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
2952 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
2953 }
2954
2955 @Override
2956 public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
2957 IBinder activityToken, int flags) {
2958 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
2959 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
2960 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
2961 }
2962
2963 @Override
2964 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
2965 Bundle args) {
2966 return enqueueAssistContext(requestType, intent, hint, null, null, null,
2967 true /* focused */, true /* newSessionId */, userHandle, args,
2968 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
2969 }
2970
2971 @Override
2972 public Bundle getAssistContextExtras(int requestType) {
2973 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
2974 null, null, true /* focused */, true /* newSessionId */,
2975 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
2976 if (pae == null) {
2977 return null;
2978 }
2979 synchronized (pae) {
2980 while (!pae.haveResult) {
2981 try {
2982 pae.wait();
2983 } catch (InterruptedException e) {
2984 }
2985 }
2986 }
2987 synchronized (mGlobalLock) {
2988 buildAssistBundleLocked(pae, pae.result);
2989 mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002990 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002991 }
2992 return pae.extras;
2993 }
2994
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002995 /**
2996 * Binder IPC calls go through the public entry point.
2997 * This can be called with or without the global lock held.
2998 */
2999 private static int checkCallingPermission(String permission) {
3000 return checkPermission(
3001 permission, Binder.getCallingPid(), UserHandle.getAppId(Binder.getCallingUid()));
3002 }
3003
3004 /** This can be called with or without the global lock held. */
Wale Ogunwale214f3482018-10-04 11:00:47 -07003005 private void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003006 if (!getRecentTasks().isCallerRecents(Binder.getCallingUid())) {
3007 mAmInternal.enforceCallingPermission(permission, func);
3008 }
3009 }
3010
3011 @VisibleForTesting
3012 int checkGetTasksPermission(String permission, int pid, int uid) {
3013 return checkPermission(permission, pid, uid);
3014 }
3015
3016 static int checkPermission(String permission, int pid, int uid) {
3017 if (permission == null) {
3018 return PackageManager.PERMISSION_DENIED;
3019 }
3020 return checkComponentPermission(permission, pid, uid, -1, true);
3021 }
3022
Wale Ogunwale214f3482018-10-04 11:00:47 -07003023 public static int checkComponentPermission(String permission, int pid, int uid,
3024 int owningUid, boolean exported) {
3025 return ActivityManagerService.checkComponentPermission(
3026 permission, pid, uid, owningUid, exported);
3027 }
3028
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003029 boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
3030 if (getRecentTasks().isCallerRecents(callingUid)) {
3031 // Always allow the recents component to get tasks
3032 return true;
3033 }
3034
3035 boolean allowed = checkGetTasksPermission(android.Manifest.permission.REAL_GET_TASKS,
3036 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
3037 if (!allowed) {
3038 if (checkGetTasksPermission(android.Manifest.permission.GET_TASKS,
3039 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
3040 // Temporary compatibility: some existing apps on the system image may
3041 // still be requesting the old permission and not switched to the new
3042 // one; if so, we'll still allow them full access. This means we need
3043 // to see if they are holding the old permission and are a system app.
3044 try {
3045 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
3046 allowed = true;
3047 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
3048 + " is using old GET_TASKS but privileged; allowing");
3049 }
3050 } catch (RemoteException e) {
3051 }
3052 }
3053 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
3054 + " does not hold REAL_GET_TASKS; limiting output");
3055 }
3056 return allowed;
3057 }
3058
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003059 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
3060 IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
3061 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
3062 int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003063 mAmInternal.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003064 "enqueueAssistContext()");
3065
3066 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003067 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003068 if (activity == null) {
3069 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
3070 return null;
3071 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003072 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003073 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
3074 return null;
3075 }
3076 if (focused) {
3077 if (activityToken != null) {
3078 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
3079 if (activity != caller) {
3080 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
3081 + " is not current top " + activity);
3082 return null;
3083 }
3084 }
3085 } else {
3086 activity = ActivityRecord.forTokenLocked(activityToken);
3087 if (activity == null) {
3088 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
3089 + " couldn't be found");
3090 return null;
3091 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003092 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003093 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
3094 return null;
3095 }
3096 }
3097
3098 PendingAssistExtras pae;
3099 Bundle extras = new Bundle();
3100 if (args != null) {
3101 extras.putAll(args);
3102 }
3103 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003104 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003105
3106 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
3107 userHandle);
3108 pae.isHome = activity.isActivityTypeHome();
3109
3110 // Increment the sessionId if necessary
3111 if (newSessionId) {
3112 mViSessionId++;
3113 }
3114 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003115 activity.app.getThread().requestAssistContextExtras(activity.appToken, pae,
3116 requestType, mViSessionId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003117 mPendingAssistExtras.add(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003118 mUiHandler.postDelayed(pae, timeout);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003119 } catch (RemoteException e) {
3120 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
3121 return null;
3122 }
3123 return pae;
3124 }
3125 }
3126
3127 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
3128 if (result != null) {
3129 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
3130 }
3131 if (pae.hint != null) {
3132 pae.extras.putBoolean(pae.hint, true);
3133 }
3134 }
3135
3136 private void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
3137 IAssistDataReceiver receiver;
3138 synchronized (mGlobalLock) {
3139 mPendingAssistExtras.remove(pae);
3140 receiver = pae.receiver;
3141 }
3142 if (receiver != null) {
3143 // Caller wants result sent back to them.
3144 Bundle sendBundle = new Bundle();
3145 // At least return the receiver extras
3146 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
3147 try {
3148 pae.receiver.onHandleAssistData(sendBundle);
3149 } catch (RemoteException e) {
3150 }
3151 }
3152 }
3153
3154 public class PendingAssistExtras extends Binder implements Runnable {
3155 public final ActivityRecord activity;
3156 public boolean isHome;
3157 public final Bundle extras;
3158 public final Intent intent;
3159 public final String hint;
3160 public final IAssistDataReceiver receiver;
3161 public final int userHandle;
3162 public boolean haveResult = false;
3163 public Bundle result = null;
3164 public AssistStructure structure = null;
3165 public AssistContent content = null;
3166 public Bundle receiverExtras;
3167
3168 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
3169 String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
3170 int _userHandle) {
3171 activity = _activity;
3172 extras = _extras;
3173 intent = _intent;
3174 hint = _hint;
3175 receiver = _receiver;
3176 receiverExtras = _receiverExtras;
3177 userHandle = _userHandle;
3178 }
3179
3180 @Override
3181 public void run() {
3182 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
3183 synchronized (this) {
3184 haveResult = true;
3185 notifyAll();
3186 }
3187 pendingAssistExtrasTimedOut(this);
3188 }
3189 }
3190
3191 @Override
3192 public boolean isAssistDataAllowedOnCurrentActivity() {
3193 int userId;
3194 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003195 final ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003196 if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
3197 return false;
3198 }
3199
3200 final ActivityRecord activity = focusedStack.getTopActivity();
3201 if (activity == null) {
3202 return false;
3203 }
3204 userId = activity.userId;
3205 }
3206 return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
3207 }
3208
3209 @Override
3210 public boolean showAssistFromActivity(IBinder token, Bundle args) {
3211 long ident = Binder.clearCallingIdentity();
3212 try {
3213 synchronized (mGlobalLock) {
3214 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003215 ActivityRecord top = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003216 if (top != caller) {
3217 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3218 + " is not current top " + top);
3219 return false;
3220 }
3221 if (!top.nowVisible) {
3222 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3223 + " is not visible");
3224 return false;
3225 }
3226 }
3227 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
3228 token);
3229 } finally {
3230 Binder.restoreCallingIdentity(ident);
3231 }
3232 }
3233
3234 @Override
3235 public boolean isRootVoiceInteraction(IBinder token) {
3236 synchronized (mGlobalLock) {
3237 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3238 if (r == null) {
3239 return false;
3240 }
3241 return r.rootVoiceInteraction;
3242 }
3243 }
3244
Wale Ogunwalef6733932018-06-27 05:14:34 -07003245 private void onLocalVoiceInteractionStartedLocked(IBinder activity,
3246 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
3247 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
3248 if (activityToCallback == null) return;
3249 activityToCallback.setVoiceSessionLocked(voiceSession);
3250
3251 // Inform the activity
3252 try {
3253 activityToCallback.app.getThread().scheduleLocalVoiceInteractionStarted(activity,
3254 voiceInteractor);
3255 long token = Binder.clearCallingIdentity();
3256 try {
3257 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
3258 } finally {
3259 Binder.restoreCallingIdentity(token);
3260 }
3261 // TODO: VI Should we cache the activity so that it's easier to find later
3262 // rather than scan through all the stacks and activities?
3263 } catch (RemoteException re) {
3264 activityToCallback.clearVoiceSessionLocked();
3265 // TODO: VI Should this terminate the voice session?
3266 }
3267 }
3268
3269 private void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
3270 Slog.d(TAG, "<<< startRunningVoiceLocked()");
3271 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
3272 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
3273 boolean wasRunningVoice = mRunningVoice != null;
3274 mRunningVoice = session;
3275 if (!wasRunningVoice) {
3276 mVoiceWakeLock.acquire();
3277 updateSleepIfNeededLocked();
3278 }
3279 }
3280 }
3281
3282 void finishRunningVoiceLocked() {
3283 if (mRunningVoice != null) {
3284 mRunningVoice = null;
3285 mVoiceWakeLock.release();
3286 updateSleepIfNeededLocked();
3287 }
3288 }
3289
3290 @Override
3291 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3292 synchronized (mGlobalLock) {
3293 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3294 if (keepAwake) {
3295 mVoiceWakeLock.acquire();
3296 } else {
3297 mVoiceWakeLock.release();
3298 }
3299 }
3300 }
3301 }
3302
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003303 @Override
3304 public ComponentName getActivityClassForToken(IBinder token) {
3305 synchronized (mGlobalLock) {
3306 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3307 if (r == null) {
3308 return null;
3309 }
3310 return r.intent.getComponent();
3311 }
3312 }
3313
3314 @Override
3315 public String getPackageForToken(IBinder token) {
3316 synchronized (mGlobalLock) {
3317 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3318 if (r == null) {
3319 return null;
3320 }
3321 return r.packageName;
3322 }
3323 }
3324
3325 @Override
3326 public void showLockTaskEscapeMessage(IBinder token) {
3327 synchronized (mGlobalLock) {
3328 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3329 if (r == null) {
3330 return;
3331 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003332 getLockTaskController().showLockTaskToast();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003333 }
3334 }
3335
3336 @Override
3337 public void keyguardGoingAway(int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003338 enforceNotIsolatedCaller("keyguardGoingAway");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003339 final long token = Binder.clearCallingIdentity();
3340 try {
3341 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003342 mKeyguardController.keyguardGoingAway(flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003343 }
3344 } finally {
3345 Binder.restoreCallingIdentity(token);
3346 }
3347 }
3348
3349 /**
3350 * Try to place task to provided position. The final position might be different depending on
3351 * current user and stacks state. The task will be moved to target stack if it's currently in
3352 * different stack.
3353 */
3354 @Override
3355 public void positionTaskInStack(int taskId, int stackId, int position) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003356 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003357 synchronized (mGlobalLock) {
3358 long ident = Binder.clearCallingIdentity();
3359 try {
3360 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
3361 + taskId + " in stackId=" + stackId + " at position=" + position);
3362 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3363 if (task == null) {
3364 throw new IllegalArgumentException("positionTaskInStack: no task for id="
3365 + taskId);
3366 }
3367
3368 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3369
3370 if (stack == null) {
3371 throw new IllegalArgumentException("positionTaskInStack: no stack for id="
3372 + stackId);
3373 }
3374 if (!stack.isActivityTypeStandardOrUndefined()) {
3375 throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
3376 + " the position of task " + taskId + " in/to non-standard stack");
3377 }
3378
3379 // TODO: Have the callers of this API call a separate reparent method if that is
3380 // what they intended to do vs. having this method also do reparenting.
3381 if (task.getStack() == stack) {
3382 // Change position in current stack.
3383 stack.positionChildAt(task, position);
3384 } else {
3385 // Reparent to new stack.
3386 task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
3387 !DEFER_RESUME, "positionTaskInStack");
3388 }
3389 } finally {
3390 Binder.restoreCallingIdentity(ident);
3391 }
3392 }
3393 }
3394
3395 @Override
3396 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
3397 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
3398 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
3399 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
3400 synchronized (mGlobalLock) {
3401 ActivityRecord record = ActivityRecord.isInStackLocked(token);
3402 if (record == null) {
3403 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
3404 + "found for: " + token);
3405 }
3406 record.setSizeConfigurations(horizontalSizeConfiguration,
3407 verticalSizeConfigurations, smallestSizeConfigurations);
3408 }
3409 }
3410
3411 /**
3412 * Dismisses split-screen multi-window mode.
3413 * @param toTop If true the current primary split-screen stack will be placed or left on top.
3414 */
3415 @Override
3416 public void dismissSplitScreenMode(boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003417 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003418 MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
3419 final long ident = Binder.clearCallingIdentity();
3420 try {
3421 synchronized (mGlobalLock) {
3422 final ActivityStack stack =
3423 mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
3424 if (stack == null) {
3425 Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
3426 return;
3427 }
3428
3429 if (toTop) {
3430 // Caller wants the current split-screen primary stack to be the top stack after
3431 // it goes fullscreen, so move it to the front.
3432 stack.moveToFront("dismissSplitScreenMode");
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003433 } else if (mStackSupervisor.isTopDisplayFocusedStack(stack)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003434 // In this case the current split-screen primary stack shouldn't be the top
3435 // stack after it goes fullscreen, but it current has focus, so we move the
3436 // focus to the top-most split-screen secondary stack next to it.
3437 final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
3438 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
3439 if (otherStack != null) {
3440 otherStack.moveToFront("dismissSplitScreenMode_other");
3441 }
3442 }
3443
Evan Rosky10475742018-09-05 19:02:48 -07003444 stack.setWindowingMode(WINDOWING_MODE_UNDEFINED);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003445 }
3446 } finally {
3447 Binder.restoreCallingIdentity(ident);
3448 }
3449 }
3450
3451 /**
3452 * Dismisses Pip
3453 * @param animate True if the dismissal should be animated.
3454 * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
3455 * default animation duration should be used.
3456 */
3457 @Override
3458 public void dismissPip(boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003459 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003460 final long ident = Binder.clearCallingIdentity();
3461 try {
3462 synchronized (mGlobalLock) {
3463 final PinnedActivityStack stack =
3464 mStackSupervisor.getDefaultDisplay().getPinnedStack();
3465 if (stack == null) {
3466 Slog.w(TAG, "dismissPip: pinned stack not found.");
3467 return;
3468 }
3469 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
3470 throw new IllegalArgumentException("Stack: " + stack
3471 + " doesn't support animated resize.");
3472 }
3473 if (animate) {
3474 stack.animateResizePinnedStack(null /* sourceHintBounds */,
3475 null /* destBounds */, animationDuration, false /* fromFullscreen */);
3476 } else {
3477 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
3478 }
3479 }
3480 } finally {
3481 Binder.restoreCallingIdentity(ident);
3482 }
3483 }
3484
3485 @Override
3486 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003487 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003488 synchronized (mGlobalLock) {
3489 mSuppressResizeConfigChanges = suppress;
3490 }
3491 }
3492
3493 /**
3494 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
3495 * animated the stack to the fullscreen, but can also be called if we are relaunching an
3496 * activity and clearing the task at the same time.
3497 */
3498 @Override
3499 // TODO: API should just be about changing windowing modes...
3500 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003501 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003502 "moveTasksToFullscreenStack()");
3503 synchronized (mGlobalLock) {
3504 final long origId = Binder.clearCallingIdentity();
3505 try {
3506 final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
3507 if (stack != null){
3508 if (!stack.isActivityTypeStandardOrUndefined()) {
3509 throw new IllegalArgumentException(
3510 "You can't move tasks from non-standard stacks.");
3511 }
3512 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
3513 }
3514 } finally {
3515 Binder.restoreCallingIdentity(origId);
3516 }
3517 }
3518 }
3519
3520 /**
3521 * Moves the top activity in the input stackId to the pinned stack.
3522 *
3523 * @param stackId Id of stack to move the top activity to pinned stack.
3524 * @param bounds Bounds to use for pinned stack.
3525 *
3526 * @return True if the top activity of the input stack was successfully moved to the pinned
3527 * stack.
3528 */
3529 @Override
3530 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003531 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003532 "moveTopActivityToPinnedStack()");
3533 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003534 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003535 throw new IllegalStateException("moveTopActivityToPinnedStack:"
3536 + "Device doesn't support picture-in-picture mode");
3537 }
3538
3539 long ident = Binder.clearCallingIdentity();
3540 try {
3541 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
3542 } finally {
3543 Binder.restoreCallingIdentity(ident);
3544 }
3545 }
3546 }
3547
3548 @Override
3549 public boolean isInMultiWindowMode(IBinder token) {
3550 final long origId = Binder.clearCallingIdentity();
3551 try {
3552 synchronized (mGlobalLock) {
3553 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3554 if (r == null) {
3555 return false;
3556 }
3557 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
3558 return r.inMultiWindowMode();
3559 }
3560 } finally {
3561 Binder.restoreCallingIdentity(origId);
3562 }
3563 }
3564
3565 @Override
3566 public boolean isInPictureInPictureMode(IBinder token) {
3567 final long origId = Binder.clearCallingIdentity();
3568 try {
3569 synchronized (mGlobalLock) {
3570 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
3571 }
3572 } finally {
3573 Binder.restoreCallingIdentity(origId);
3574 }
3575 }
3576
3577 private boolean isInPictureInPictureMode(ActivityRecord r) {
3578 if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
3579 || r.getStack().isInStackLocked(r) == null) {
3580 return false;
3581 }
3582
3583 // If we are animating to fullscreen then we have already dispatched the PIP mode
3584 // changed, so we should reflect that check here as well.
3585 final PinnedActivityStack stack = r.getStack();
3586 final PinnedStackWindowController windowController = stack.getWindowContainerController();
3587 return !windowController.isAnimatingBoundsToFullscreen();
3588 }
3589
3590 @Override
3591 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
3592 final long origId = Binder.clearCallingIdentity();
3593 try {
3594 synchronized (mGlobalLock) {
3595 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3596 "enterPictureInPictureMode", token, params);
3597
3598 // If the activity is already in picture in picture mode, then just return early
3599 if (isInPictureInPictureMode(r)) {
3600 return true;
3601 }
3602
3603 // Activity supports picture-in-picture, now check that we can enter PiP at this
3604 // point, if it is
3605 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
3606 false /* beforeStopping */)) {
3607 return false;
3608 }
3609
3610 final Runnable enterPipRunnable = () -> {
Wale Ogunwalef276a6f2018-06-15 08:26:07 -07003611 synchronized (mGlobalLock) {
3612 // Only update the saved args from the args that are set
3613 r.pictureInPictureArgs.copyOnlySet(params);
3614 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
3615 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
3616 // Adjust the source bounds by the insets for the transition down
3617 final Rect sourceBounds = new Rect(
3618 r.pictureInPictureArgs.getSourceRectHint());
3619 mStackSupervisor.moveActivityToPinnedStackLocked(
3620 r, sourceBounds, aspectRatio, "enterPictureInPictureMode");
3621 final PinnedActivityStack stack = r.getStack();
3622 stack.setPictureInPictureAspectRatio(aspectRatio);
3623 stack.setPictureInPictureActions(actions);
3624 MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
3625 r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
3626 logPictureInPictureArgs(params);
3627 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003628 };
3629
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003630 if (isKeyguardLocked()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003631 // If the keyguard is showing or occluded, then try and dismiss it before
3632 // entering picture-in-picture (this will prompt the user to authenticate if the
3633 // device is currently locked).
3634 dismissKeyguard(token, new KeyguardDismissCallback() {
3635 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003636 public void onDismissSucceeded() {
3637 mH.post(enterPipRunnable);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003638 }
3639 }, null /* message */);
3640 } else {
3641 // Enter picture in picture immediately otherwise
3642 enterPipRunnable.run();
3643 }
3644 return true;
3645 }
3646 } finally {
3647 Binder.restoreCallingIdentity(origId);
3648 }
3649 }
3650
3651 @Override
3652 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
3653 final long origId = Binder.clearCallingIdentity();
3654 try {
3655 synchronized (mGlobalLock) {
3656 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3657 "setPictureInPictureParams", token, params);
3658
3659 // Only update the saved args from the args that are set
3660 r.pictureInPictureArgs.copyOnlySet(params);
3661 if (r.inPinnedWindowingMode()) {
3662 // If the activity is already in picture-in-picture, update the pinned stack now
3663 // if it is not already expanding to fullscreen. Otherwise, the arguments will
3664 // be used the next time the activity enters PiP
3665 final PinnedActivityStack stack = r.getStack();
3666 if (!stack.isAnimatingBoundsToFullscreen()) {
3667 stack.setPictureInPictureAspectRatio(
3668 r.pictureInPictureArgs.getAspectRatio());
3669 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
3670 }
3671 }
3672 logPictureInPictureArgs(params);
3673 }
3674 } finally {
3675 Binder.restoreCallingIdentity(origId);
3676 }
3677 }
3678
3679 @Override
3680 public int getMaxNumPictureInPictureActions(IBinder token) {
3681 // Currently, this is a static constant, but later, we may change this to be dependent on
3682 // the context of the activity
3683 return 3;
3684 }
3685
3686 private void logPictureInPictureArgs(PictureInPictureParams params) {
3687 if (params.hasSetActions()) {
3688 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
3689 params.getActions().size());
3690 }
3691 if (params.hasSetAspectRatio()) {
3692 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
3693 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
3694 MetricsLogger.action(lm);
3695 }
3696 }
3697
3698 /**
3699 * Checks the state of the system and the activity associated with the given {@param token} to
3700 * verify that picture-in-picture is supported for that activity.
3701 *
3702 * @return the activity record for the given {@param token} if all the checks pass.
3703 */
3704 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
3705 IBinder token, PictureInPictureParams params) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003706 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003707 throw new IllegalStateException(caller
3708 + ": Device doesn't support picture-in-picture mode.");
3709 }
3710
3711 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3712 if (r == null) {
3713 throw new IllegalStateException(caller
3714 + ": Can't find activity for token=" + token);
3715 }
3716
3717 if (!r.supportsPictureInPicture()) {
3718 throw new IllegalStateException(caller
3719 + ": Current activity does not support picture-in-picture.");
3720 }
3721
3722 if (params.hasSetAspectRatio()
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003723 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003724 params.getAspectRatio())) {
3725 final float minAspectRatio = mContext.getResources().getFloat(
3726 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
3727 final float maxAspectRatio = mContext.getResources().getFloat(
3728 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
3729 throw new IllegalArgumentException(String.format(caller
3730 + ": Aspect ratio is too extreme (must be between %f and %f).",
3731 minAspectRatio, maxAspectRatio));
3732 }
3733
3734 // Truncate the number of actions if necessary
3735 params.truncateActions(getMaxNumPictureInPictureActions(token));
3736
3737 return r;
3738 }
3739
3740 @Override
3741 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003742 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003743 synchronized (mGlobalLock) {
3744 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
3745 if (r == null) {
3746 throw new IllegalArgumentException("Activity does not exist; token="
3747 + activityToken);
3748 }
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07003749 return r.getUriPermissionsLocked().getExternalToken();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003750 }
3751 }
3752
3753 @Override
3754 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
3755 Rect tempDockedTaskInsetBounds,
3756 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003757 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003758 long ident = Binder.clearCallingIdentity();
3759 try {
3760 synchronized (mGlobalLock) {
3761 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
3762 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
3763 PRESERVE_WINDOWS);
3764 }
3765 } finally {
3766 Binder.restoreCallingIdentity(ident);
3767 }
3768 }
3769
3770 @Override
3771 public void setSplitScreenResizing(boolean resizing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003772 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003773 final long ident = Binder.clearCallingIdentity();
3774 try {
3775 synchronized (mGlobalLock) {
3776 mStackSupervisor.setSplitScreenResizing(resizing);
3777 }
3778 } finally {
3779 Binder.restoreCallingIdentity(ident);
3780 }
3781 }
3782
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003783 /**
3784 * Check that we have the features required for VR-related API calls, and throw an exception if
3785 * not.
3786 */
3787 void enforceSystemHasVrFeature() {
3788 if (!mContext.getPackageManager().hasSystemFeature(
3789 PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
3790 throw new UnsupportedOperationException("VR mode not supported on this device!");
3791 }
3792 }
3793
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003794 @Override
3795 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003796 enforceSystemHasVrFeature();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003797
3798 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3799
3800 ActivityRecord r;
3801 synchronized (mGlobalLock) {
3802 r = ActivityRecord.isInStackLocked(token);
3803 }
3804
3805 if (r == null) {
3806 throw new IllegalArgumentException();
3807 }
3808
3809 int err;
3810 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
3811 VrManagerInternal.NO_ERROR) {
3812 return err;
3813 }
3814
3815 // Clear the binder calling uid since this path may call moveToTask().
3816 final long callingId = Binder.clearCallingIdentity();
3817 try {
3818 synchronized (mGlobalLock) {
3819 r.requestedVrComponent = (enabled) ? packageName : null;
3820
3821 // Update associated state if this activity is currently focused
Andrii Kulian52d255c2018-07-13 11:32:19 -07003822 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003823 applyUpdateVrModeLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003824 }
3825 return 0;
3826 }
3827 } finally {
3828 Binder.restoreCallingIdentity(callingId);
3829 }
3830 }
3831
3832 @Override
3833 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
3834 Slog.i(TAG, "Activity tried to startLocalVoiceInteraction");
3835 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003836 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003837 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
3838 throw new SecurityException("Only focused activity can call startVoiceInteraction");
3839 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07003840 if (mRunningVoice != null || activity.getTask().voiceSession != null
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003841 || activity.voiceSession != null) {
3842 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
3843 return;
3844 }
3845 if (activity.pendingVoiceInteractionStart) {
3846 Slog.w(TAG, "Pending start of voice interaction already.");
3847 return;
3848 }
3849 activity.pendingVoiceInteractionStart = true;
3850 }
3851 LocalServices.getService(VoiceInteractionManagerInternal.class)
3852 .startLocalVoiceInteraction(callingActivity, options);
3853 }
3854
3855 @Override
3856 public void stopLocalVoiceInteraction(IBinder callingActivity) {
3857 LocalServices.getService(VoiceInteractionManagerInternal.class)
3858 .stopLocalVoiceInteraction(callingActivity);
3859 }
3860
3861 @Override
3862 public boolean supportsLocalVoiceInteraction() {
3863 return LocalServices.getService(VoiceInteractionManagerInternal.class)
3864 .supportsLocalVoiceInteraction();
3865 }
3866
3867 /** Notifies all listeners when the pinned stack animation starts. */
3868 @Override
3869 public void notifyPinnedStackAnimationStarted() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003870 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003871 }
3872
3873 /** Notifies all listeners when the pinned stack animation ends. */
3874 @Override
3875 public void notifyPinnedStackAnimationEnded() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003876 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003877 }
3878
3879 @Override
3880 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003881 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003882 final long ident = Binder.clearCallingIdentity();
3883 try {
3884 synchronized (mGlobalLock) {
3885 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
3886 }
3887 } finally {
3888 Binder.restoreCallingIdentity(ident);
3889 }
3890 }
3891
3892 @Override
3893 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003894 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003895
3896 synchronized (mGlobalLock) {
3897 // Check if display is initialized in AM.
3898 if (!mStackSupervisor.isDisplayAdded(displayId)) {
3899 // Call might come when display is not yet added or has already been removed.
3900 if (DEBUG_CONFIGURATION) {
3901 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
3902 + displayId);
3903 }
3904 return false;
3905 }
3906
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003907 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003908 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003909 values = mWindowManager.computeNewConfiguration(displayId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003910 }
3911
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003912 if (mWindowManager != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07003913 final Message msg = PooledLambda.obtainMessage(
3914 ActivityManagerInternal::updateOomLevelsForDisplay, mAmInternal, displayId);
3915 mH.sendMessage(msg);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003916 }
3917
3918 final long origId = Binder.clearCallingIdentity();
3919 try {
3920 if (values != null) {
3921 Settings.System.clearConfiguration(values);
3922 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003923 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003924 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
3925 return mTmpUpdateConfigurationResult.changes != 0;
3926 } finally {
3927 Binder.restoreCallingIdentity(origId);
3928 }
3929 }
3930 }
3931
3932 @Override
3933 public boolean updateConfiguration(Configuration values) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003934 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003935
3936 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003937 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003938 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003939 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003940 }
3941
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003942 if (mWindowManager != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07003943 final Message msg = PooledLambda.obtainMessage(
3944 ActivityManagerInternal::updateOomLevelsForDisplay, mAmInternal,
3945 DEFAULT_DISPLAY);
3946 mH.sendMessage(msg);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003947 }
3948
3949 final long origId = Binder.clearCallingIdentity();
3950 try {
3951 if (values != null) {
3952 Settings.System.clearConfiguration(values);
3953 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003954 updateConfigurationLocked(values, null, false, false /* persistent */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003955 UserHandle.USER_NULL, false /* deferResume */,
3956 mTmpUpdateConfigurationResult);
3957 return mTmpUpdateConfigurationResult.changes != 0;
3958 } finally {
3959 Binder.restoreCallingIdentity(origId);
3960 }
3961 }
3962 }
3963
3964 @Override
3965 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
3966 CharSequence message) {
3967 if (message != null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003968 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003969 Manifest.permission.SHOW_KEYGUARD_MESSAGE, "dismissKeyguard()");
3970 }
3971 final long callingId = Binder.clearCallingIdentity();
3972 try {
3973 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003974 mKeyguardController.dismissKeyguard(token, callback, message);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003975 }
3976 } finally {
3977 Binder.restoreCallingIdentity(callingId);
3978 }
3979 }
3980
3981 @Override
3982 public void cancelTaskWindowTransition(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003983 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003984 "cancelTaskWindowTransition()");
3985 final long ident = Binder.clearCallingIdentity();
3986 try {
3987 synchronized (mGlobalLock) {
3988 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
3989 MATCH_TASK_IN_STACKS_ONLY);
3990 if (task == null) {
3991 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
3992 return;
3993 }
3994 task.cancelWindowTransition();
3995 }
3996 } finally {
3997 Binder.restoreCallingIdentity(ident);
3998 }
3999 }
4000
4001 @Override
4002 public ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004003 enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004004 final long ident = Binder.clearCallingIdentity();
4005 try {
4006 final TaskRecord task;
4007 synchronized (mGlobalLock) {
4008 task = mStackSupervisor.anyTaskForIdLocked(taskId,
4009 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
4010 if (task == null) {
4011 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
4012 return null;
4013 }
4014 }
4015 // Don't call this while holding the lock as this operation might hit the disk.
4016 return task.getSnapshot(reducedResolution);
4017 } finally {
4018 Binder.restoreCallingIdentity(ident);
4019 }
4020 }
4021
4022 @Override
4023 public void setDisablePreviewScreenshots(IBinder token, boolean disable) {
4024 synchronized (mGlobalLock) {
4025 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4026 if (r == null) {
4027 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
4028 + token);
4029 return;
4030 }
4031 final long origId = Binder.clearCallingIdentity();
4032 try {
4033 r.setDisablePreviewScreenshots(disable);
4034 } finally {
4035 Binder.restoreCallingIdentity(origId);
4036 }
4037 }
4038 }
4039
4040 /** Return the user id of the last resumed activity. */
4041 @Override
4042 public @UserIdInt
4043 int getLastResumedActivityUserId() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004044 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004045 Manifest.permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
4046 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07004047 if (mLastResumedActivity == null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004048 return getCurrentUserId();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004049 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004050 return mLastResumedActivity.userId;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004051 }
4052 }
4053
4054 @Override
4055 public void updateLockTaskFeatures(int userId, int flags) {
4056 final int callingUid = Binder.getCallingUid();
4057 if (callingUid != 0 && callingUid != SYSTEM_UID) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004058 mAmInternal.enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004059 "updateLockTaskFeatures()");
4060 }
4061 synchronized (mGlobalLock) {
4062 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
4063 Integer.toHexString(flags));
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07004064 getLockTaskController().updateLockTaskFeatures(userId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004065 }
4066 }
4067
4068 @Override
4069 public void setShowWhenLocked(IBinder token, boolean showWhenLocked) {
4070 synchronized (mGlobalLock) {
4071 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4072 if (r == null) {
4073 return;
4074 }
4075 final long origId = Binder.clearCallingIdentity();
4076 try {
4077 r.setShowWhenLocked(showWhenLocked);
4078 } finally {
4079 Binder.restoreCallingIdentity(origId);
4080 }
4081 }
4082 }
4083
4084 @Override
4085 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) {
4086 synchronized (mGlobalLock) {
4087 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4088 if (r == null) {
4089 return;
4090 }
4091 final long origId = Binder.clearCallingIdentity();
4092 try {
4093 r.setTurnScreenOn(turnScreenOn);
4094 } finally {
4095 Binder.restoreCallingIdentity(origId);
4096 }
4097 }
4098 }
4099
4100 @Override
4101 public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004102 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004103 "registerRemoteAnimations");
4104 definition.setCallingPid(Binder.getCallingPid());
4105 synchronized (mGlobalLock) {
4106 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4107 if (r == null) {
4108 return;
4109 }
4110 final long origId = Binder.clearCallingIdentity();
4111 try {
4112 r.registerRemoteAnimations(definition);
4113 } finally {
4114 Binder.restoreCallingIdentity(origId);
4115 }
4116 }
4117 }
4118
4119 @Override
4120 public void registerRemoteAnimationForNextActivityStart(String packageName,
4121 RemoteAnimationAdapter adapter) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004122 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004123 "registerRemoteAnimationForNextActivityStart");
4124 adapter.setCallingPid(Binder.getCallingPid());
4125 synchronized (mGlobalLock) {
4126 final long origId = Binder.clearCallingIdentity();
4127 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07004128 getActivityStartController().registerRemoteAnimationForNextActivityStart(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004129 packageName, adapter);
4130 } finally {
4131 Binder.restoreCallingIdentity(origId);
4132 }
4133 }
4134 }
4135
4136 /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
4137 @Override
4138 public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
4139 synchronized (mGlobalLock) {
4140 final long origId = Binder.clearCallingIdentity();
4141 try {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004142 mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004143 } finally {
4144 Binder.restoreCallingIdentity(origId);
4145 }
4146 }
4147 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004148
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004149 @Override
4150 public void setVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004151 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004152 synchronized (mGlobalLock) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004153 final int pid = Binder.getCallingPid();
4154 final WindowProcessController wpc = mPidMap.get(pid);
4155 mVrController.setVrThreadLocked(tid, pid, wpc);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004156 }
4157 }
4158
4159 @Override
4160 public void setPersistentVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004161 if (checkCallingPermission(Manifest.permission.RESTRICTED_VR_ACCESS)
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004162 != PERMISSION_GRANTED) {
4163 final String msg = "Permission Denial: setPersistentVrThread() from pid="
4164 + Binder.getCallingPid()
4165 + ", uid=" + Binder.getCallingUid()
4166 + " requires " + Manifest.permission.RESTRICTED_VR_ACCESS;
4167 Slog.w(TAG, msg);
4168 throw new SecurityException(msg);
4169 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004170 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004171 synchronized (mGlobalLock) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004172 final int pid = Binder.getCallingPid();
4173 final WindowProcessController proc = mPidMap.get(pid);
4174 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004175 }
4176 }
4177
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004178 @Override
4179 public void stopAppSwitches() {
4180 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
4181 synchronized (mGlobalLock) {
4182 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME;
4183 mDidAppSwitch = false;
4184 getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
4185 }
4186 }
4187
4188 @Override
4189 public void resumeAppSwitches() {
4190 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
4191 synchronized (mGlobalLock) {
4192 // Note that we don't execute any pending app switches... we will
4193 // let those wait until either the timeout, or the next start
4194 // activity request.
4195 mAppSwitchesAllowedTime = 0;
4196 }
4197 }
4198
4199 void onStartActivitySetDidAppSwitch() {
4200 if (mDidAppSwitch) {
4201 // This is the second allowed switch since we stopped switches, so now just generally
4202 // allow switches. Use case:
4203 // - user presses home (switches disabled, switch to home, mDidAppSwitch now true);
4204 // - user taps a home icon (coming from home so allowed, we hit here and now allow
4205 // anyone to switch again).
4206 mAppSwitchesAllowedTime = 0;
4207 } else {
4208 mDidAppSwitch = true;
4209 }
4210 }
4211
4212 /** @return whether the system should disable UI modes incompatible with VR mode. */
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004213 boolean shouldDisableNonVrUiLocked() {
4214 return mVrController.shouldDisableNonVrUiLocked();
4215 }
4216
Wale Ogunwale53783742018-09-16 10:21:51 -07004217 private void applyUpdateVrModeLocked(ActivityRecord r) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004218 // VR apps are expected to run in a main display. If an app is turning on VR for
4219 // itself, but lives in a dynamic stack, then make sure that it is moved to the main
4220 // fullscreen stack before enabling VR Mode.
4221 // TODO: The goal of this code is to keep the VR app on the main display. When the
4222 // stack implementation changes in the future, keep in mind that the use of the fullscreen
4223 // stack is a means to move the activity to the main display and a moveActivityToDisplay()
4224 // option would be a better choice here.
4225 if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
4226 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
4227 + " to main stack for VR");
4228 final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
4229 WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
4230 moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
4231 }
4232 mH.post(() -> {
4233 if (!mVrController.onVrModeChanged(r)) {
4234 return;
4235 }
4236 synchronized (mGlobalLock) {
4237 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
4238 mWindowManager.disableNonVrUi(disableNonVrUi);
4239 if (disableNonVrUi) {
4240 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
4241 // then remove the pinned stack.
4242 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
4243 }
4244 }
4245 });
4246 }
4247
Wale Ogunwale53783742018-09-16 10:21:51 -07004248 @Override
4249 public int getPackageScreenCompatMode(String packageName) {
4250 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4251 synchronized (mGlobalLock) {
4252 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4253 }
4254 }
4255
4256 @Override
4257 public void setPackageScreenCompatMode(String packageName, int mode) {
4258 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4259 "setPackageScreenCompatMode");
4260 synchronized (mGlobalLock) {
4261 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4262 }
4263 }
4264
4265 @Override
4266 public boolean getPackageAskScreenCompat(String packageName) {
4267 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4268 synchronized (mGlobalLock) {
4269 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4270 }
4271 }
4272
4273 @Override
4274 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4275 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4276 "setPackageAskScreenCompat");
4277 synchronized (mGlobalLock) {
4278 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4279 }
4280 }
4281
Andrii Kulian5f750bc2018-07-17 08:57:23 -07004282 ActivityStack getTopDisplayFocusedStack() {
4283 return mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004284 }
4285
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004286 /** Pokes the task persister. */
4287 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
4288 mRecentTasks.notifyTaskPersisterLocked(task, flush);
4289 }
4290
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004291 void onTopProcChangedLocked(WindowProcessController proc) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004292 mVrController.onTopProcChangedLocked(proc);
4293 }
4294
4295 boolean isKeyguardLocked() {
4296 return mKeyguardController.isKeyguardLocked();
4297 }
4298
4299 boolean isNextTransitionForward() {
4300 int transit = mWindowManager.getPendingAppTransition();
4301 return transit == TRANSIT_ACTIVITY_OPEN
4302 || transit == TRANSIT_TASK_OPEN
4303 || transit == TRANSIT_TASK_TO_FRONT;
4304 }
4305
Wale Ogunwalef6733932018-06-27 05:14:34 -07004306 void dumpSleepStates(PrintWriter pw, boolean testPssMode) {
4307 synchronized (mGlobalLock) {
4308 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
4309 if (mRunningVoice != null) {
4310 pw.println(" mRunningVoice=" + mRunningVoice);
4311 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
4312 }
4313 pw.println(" mSleeping=" + mSleeping);
4314 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + testPssMode);
4315 pw.println(" mVrController=" + mVrController);
4316 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004317 }
4318
Wale Ogunwalef6733932018-06-27 05:14:34 -07004319 void writeSleepStateToProto(ProtoOutputStream proto) {
4320 for (ActivityTaskManagerInternal.SleepToken st : mStackSupervisor.mSleepTokens) {
4321 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS,
4322 st.toString());
4323 }
4324
4325 if (mRunningVoice != null) {
4326 final long vrToken = proto.start(
4327 ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
4328 proto.write(ActivityManagerServiceDumpProcessesProto.Voice.SESSION,
4329 mRunningVoice.toString());
4330 mVoiceWakeLock.writeToProto(
4331 proto, ActivityManagerServiceDumpProcessesProto.Voice.WAKELOCK);
4332 proto.end(vrToken);
4333 }
4334
4335 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
4336 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN,
4337 mShuttingDown);
4338 mVrController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004339 }
4340
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004341 int getCurrentUserId() {
4342 return mAmInternal.getCurrentUserId();
4343 }
4344
4345 private void enforceNotIsolatedCaller(String caller) {
4346 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4347 throw new SecurityException("Isolated process not allowed to call " + caller);
4348 }
4349 }
4350
Wale Ogunwalef6733932018-06-27 05:14:34 -07004351 public Configuration getConfiguration() {
4352 Configuration ci;
4353 synchronized(mGlobalLock) {
Yunfan Chen75157d72018-07-27 14:47:21 +09004354 ci = new Configuration(getGlobalConfigurationForCallingPid());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004355 ci.userSetLocale = false;
4356 }
4357 return ci;
4358 }
4359
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004360 /**
4361 * Current global configuration information. Contains general settings for the entire system,
4362 * also corresponds to the merged configuration of the default display.
4363 */
4364 Configuration getGlobalConfiguration() {
4365 return mStackSupervisor.getConfiguration();
4366 }
4367
4368 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4369 boolean initLocale) {
4370 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
4371 }
4372
4373 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4374 boolean initLocale, boolean deferResume) {
4375 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
4376 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
4377 UserHandle.USER_NULL, deferResume);
4378 }
4379
4380 void updatePersistentConfiguration(Configuration values, @UserIdInt int userId) {
4381 final long origId = Binder.clearCallingIdentity();
4382 try {
4383 synchronized (mGlobalLock) {
4384 updateConfigurationLocked(values, null, false, true, userId,
4385 false /* deferResume */);
4386 }
4387 } finally {
4388 Binder.restoreCallingIdentity(origId);
4389 }
4390 }
4391
4392 void updateUserConfiguration() {
4393 synchronized (mGlobalLock) {
4394 final Configuration configuration = new Configuration(getGlobalConfiguration());
4395 final int currentUserId = mAmInternal.getCurrentUserId();
4396 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
4397 currentUserId, Settings.System.canWrite(mContext));
4398 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
4399 false /* persistent */, currentUserId, false /* deferResume */);
4400 }
4401 }
4402
4403 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4404 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
4405 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
4406 deferResume, null /* result */);
4407 }
4408
4409 /**
4410 * Do either or both things: (1) change the current configuration, and (2)
4411 * make sure the given activity is running with the (now) current
4412 * configuration. Returns true if the activity has been left running, or
4413 * false if <var>starting</var> is being destroyed to match the new
4414 * configuration.
4415 *
4416 * @param userId is only used when persistent parameter is set to true to persist configuration
4417 * for that particular user
4418 */
4419 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4420 boolean initLocale, boolean persistent, int userId, boolean deferResume,
4421 ActivityTaskManagerService.UpdateConfigurationResult result) {
4422 int changes = 0;
4423 boolean kept = true;
4424
4425 if (mWindowManager != null) {
4426 mWindowManager.deferSurfaceLayout();
4427 }
4428 try {
4429 if (values != null) {
4430 changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
4431 deferResume);
4432 }
4433
4434 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4435 } finally {
4436 if (mWindowManager != null) {
4437 mWindowManager.continueSurfaceLayout();
4438 }
4439 }
4440
4441 if (result != null) {
4442 result.changes = changes;
4443 result.activityRelaunched = !kept;
4444 }
4445 return kept;
4446 }
4447
4448 /**
4449 * Returns true if this configuration change is interesting enough to send an
4450 * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
4451 */
4452 private static boolean isSplitConfigurationChange(int configDiff) {
4453 return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
4454 }
4455
4456 /** Update default (global) configuration and notify listeners about changes. */
4457 private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
4458 boolean persistent, int userId, boolean deferResume) {
4459 mTempConfig.setTo(getGlobalConfiguration());
4460 final int changes = mTempConfig.updateFrom(values);
4461 if (changes == 0) {
4462 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
4463 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
4464 // performDisplayOverrideConfigUpdate in order to send the new display configuration
4465 // (even if there are no actual changes) to unfreeze the window.
4466 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
4467 return 0;
4468 }
4469
4470 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
4471 "Updating global configuration to: " + values);
4472
4473 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
4474 StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
4475 values.colorMode,
4476 values.densityDpi,
4477 values.fontScale,
4478 values.hardKeyboardHidden,
4479 values.keyboard,
4480 values.keyboardHidden,
4481 values.mcc,
4482 values.mnc,
4483 values.navigation,
4484 values.navigationHidden,
4485 values.orientation,
4486 values.screenHeightDp,
4487 values.screenLayout,
4488 values.screenWidthDp,
4489 values.smallestScreenWidthDp,
4490 values.touchscreen,
4491 values.uiMode);
4492
4493
4494 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
4495 final LocaleList locales = values.getLocales();
4496 int bestLocaleIndex = 0;
4497 if (locales.size() > 1) {
4498 if (mSupportedSystemLocales == null) {
4499 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
4500 }
4501 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
4502 }
4503 SystemProperties.set("persist.sys.locale",
4504 locales.get(bestLocaleIndex).toLanguageTag());
4505 LocaleList.setDefault(locales, bestLocaleIndex);
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004506
4507 final Message m = PooledLambda.obtainMessage(
4508 ActivityTaskManagerService::sendLocaleToMountDaemonMsg, this,
4509 locales.get(bestLocaleIndex));
4510 mH.sendMessage(m);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004511 }
4512
Yunfan Chen75157d72018-07-27 14:47:21 +09004513 mTempConfig.seq = increaseConfigurationSeqLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004514
4515 // Update stored global config and notify everyone about the change.
4516 mStackSupervisor.onConfigurationChanged(mTempConfig);
4517
4518 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
4519 // TODO(multi-display): Update UsageEvents#Event to include displayId.
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004520 mUsageStatsInternal.reportConfigurationChange(mTempConfig, mAmInternal.getCurrentUserId());
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004521
4522 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
Wale Ogunwalef6733932018-06-27 05:14:34 -07004523 updateShouldShowDialogsLocked(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004524
4525 AttributeCache ac = AttributeCache.instance();
4526 if (ac != null) {
4527 ac.updateConfiguration(mTempConfig);
4528 }
4529
4530 // Make sure all resources in our process are updated right now, so that anyone who is going
4531 // to retrieve resource values after we return will be sure to get the new ones. This is
4532 // especially important during boot, where the first config change needs to guarantee all
4533 // resources have that config before following boot code is executed.
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004534 mSystemThread.applyConfigurationToResources(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004535
4536 // We need another copy of global config because we're scheduling some calls instead of
4537 // running them in place. We need to be sure that object we send will be handled unchanged.
4538 final Configuration configCopy = new Configuration(mTempConfig);
4539 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004540 final Message msg = PooledLambda.obtainMessage(
4541 ActivityTaskManagerService::sendPutConfigurationForUserMsg,
4542 this, userId, configCopy);
4543 mH.sendMessage(msg);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004544 }
4545
Yunfan Chen34fcc7a2018-10-11 16:26:09 -07004546 for (int i = mPidMap.size() - 1; i >= 0; i--) {
4547 WindowProcessController app = mPidMap.get(mPidMap.keyAt(i));
4548 if (DEBUG_CONFIGURATION) {
4549 Slog.v(TAG_CONFIGURATION, "Update process config of "
4550 + app.mName + " to new config " + configCopy);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004551 }
Yunfan Chen34fcc7a2018-10-11 16:26:09 -07004552 app.onConfigurationChanged(configCopy);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004553 }
4554
4555 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
4556 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
4557 | Intent.FLAG_RECEIVER_FOREGROUND
4558 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4559 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4560 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4561 UserHandle.USER_ALL);
4562 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
4563 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
4564 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
4565 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
4566 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4567 if (initLocale || !mAm.mProcessesReady) {
4568 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
4569 }
4570 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4571 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4572 UserHandle.USER_ALL);
4573 }
4574
4575 // Send a broadcast to PackageInstallers if the configuration change is interesting
4576 // for the purposes of installing additional splits.
4577 if (!initLocale && isSplitConfigurationChange(changes)) {
4578 intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
4579 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
4580 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
4581
4582 // Typically only app stores will have this permission.
4583 String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES };
4584 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions,
4585 OP_NONE, null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
4586 }
4587
4588 // Override configuration of the default display duplicates global config, so we need to
4589 // update it also. This will also notify WindowManager about changes.
4590 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
4591 DEFAULT_DISPLAY);
4592
4593 return changes;
4594 }
4595
4596 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
4597 boolean deferResume, int displayId) {
4598 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
4599 displayId, null /* result */);
4600 }
4601
4602 /**
4603 * Updates override configuration specific for the selected display. If no config is provided,
4604 * new one will be computed in WM based on current display info.
4605 */
4606 boolean updateDisplayOverrideConfigurationLocked(Configuration values,
4607 ActivityRecord starting, boolean deferResume, int displayId,
4608 ActivityTaskManagerService.UpdateConfigurationResult result) {
4609 int changes = 0;
4610 boolean kept = true;
4611
4612 if (mWindowManager != null) {
4613 mWindowManager.deferSurfaceLayout();
4614 }
4615 try {
4616 if (values != null) {
4617 if (displayId == DEFAULT_DISPLAY) {
4618 // Override configuration of the default display duplicates global config, so
4619 // we're calling global config update instead for default display. It will also
4620 // apply the correct override config.
4621 changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
4622 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
4623 } else {
4624 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
4625 }
4626 }
4627
4628 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4629 } finally {
4630 if (mWindowManager != null) {
4631 mWindowManager.continueSurfaceLayout();
4632 }
4633 }
4634
4635 if (result != null) {
4636 result.changes = changes;
4637 result.activityRelaunched = !kept;
4638 }
4639 return kept;
4640 }
4641
4642 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
4643 int displayId) {
4644 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
4645 final int changes = mTempConfig.updateFrom(values);
4646 if (changes != 0) {
4647 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
4648 + mTempConfig + " for displayId=" + displayId);
4649 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
4650
4651 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
4652 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004653 mAppWarnings.onDensityChanged();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004654
4655 mAm.killAllBackgroundProcessesExcept(N,
4656 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
4657 }
4658 }
4659
4660 // Update the configuration with WM first and check if any of the stacks need to be resized
4661 // due to the configuration change. If so, resize the stacks now and do any relaunches if
4662 // necessary. This way we don't need to relaunch again afterwards in
4663 // ensureActivityConfiguration().
4664 if (mWindowManager != null) {
4665 final int[] resizedStacks =
4666 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
4667 if (resizedStacks != null) {
4668 for (int stackId : resizedStacks) {
4669 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
4670 }
4671 }
4672 }
4673
4674 return changes;
4675 }
4676
Wale Ogunwalef6733932018-06-27 05:14:34 -07004677 private void updateEventDispatchingLocked(boolean booted) {
4678 mWindowManager.setEventDispatching(booted && !mShuttingDown);
4679 }
4680
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004681 private void sendPutConfigurationForUserMsg(int userId, Configuration config) {
4682 final ContentResolver resolver = mContext.getContentResolver();
4683 Settings.System.putConfigurationForUser(resolver, config, userId);
4684 }
4685
4686 private void sendLocaleToMountDaemonMsg(Locale l) {
4687 try {
4688 IBinder service = ServiceManager.getService("mount");
4689 IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
4690 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
4691 storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
4692 } catch (RemoteException e) {
4693 Log.e(TAG, "Error storing locale for decryption UI", e);
4694 }
4695 }
4696
4697 boolean isActivityStartsLoggingEnabled() {
4698 return mAmInternal.isActivityStartsLoggingEnabled();
4699 }
4700
Wale Ogunwalef6733932018-06-27 05:14:34 -07004701 void enableScreenAfterBoot(boolean booted) {
4702 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4703 SystemClock.uptimeMillis());
4704 mWindowManager.enableScreenAfterBoot();
4705
4706 synchronized (mGlobalLock) {
4707 updateEventDispatchingLocked(booted);
4708 }
4709 }
4710
4711 boolean canShowErrorDialogs() {
4712 return mShowDialogs && !mSleeping && !mShuttingDown
4713 && !mKeyguardController.isKeyguardOrAodShowing(DEFAULT_DISPLAY)
4714 && !hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
Wale Ogunwale86b74462018-07-02 08:42:43 -07004715 mAmInternal.getCurrentUserId())
Wale Ogunwalef6733932018-06-27 05:14:34 -07004716 && !(UserManager.isDeviceInDemoMode(mContext)
Wale Ogunwale86b74462018-07-02 08:42:43 -07004717 && mAmInternal.getCurrentUser().isDemo());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004718 }
4719
Wale Ogunwale906f9c62018-07-23 11:23:44 -07004720 static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
4721 if (r == null || !r.hasProcess()) {
4722 return KEY_DISPATCHING_TIMEOUT_MS;
4723 }
4724 return getInputDispatchingTimeoutLocked(r.app);
4725 }
4726
4727 private static long getInputDispatchingTimeoutLocked(WindowProcessController r) {
4728 if (r != null && (r.isInstrumenting() || r.isUsingWrapper())) {
4729 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS;
4730 }
4731 return KEY_DISPATCHING_TIMEOUT_MS;
4732 }
4733
4734 long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
4735 if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
4736 throw new SecurityException("Requires permission " + FILTER_EVENTS);
4737 }
4738 WindowProcessController proc;
4739 long timeout;
4740 synchronized (mGlobalLock) {
4741 proc = mPidMap.get(pid);
4742 timeout = getInputDispatchingTimeoutLocked(proc);
4743 }
4744
4745 if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
4746 return -1;
4747 }
4748
4749 return timeout;
4750 }
4751
4752 /**
4753 * Handle input dispatching timeouts.
4754 * Returns whether input dispatching should be aborted or not.
4755 */
4756 boolean inputDispatchingTimedOut(final WindowProcessController proc,
4757 final ActivityRecord activity, final ActivityRecord parent,
4758 final boolean aboveSystem, String reason) {
4759 if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
4760 throw new SecurityException("Requires permission " + FILTER_EVENTS);
4761 }
4762
4763 final String annotation;
4764 if (reason == null) {
4765 annotation = "Input dispatching timed out";
4766 } else {
4767 annotation = "Input dispatching timed out (" + reason + ")";
4768 }
4769
4770 if (proc != null) {
4771 synchronized (mGlobalLock) {
4772 if (proc.isDebugging()) {
4773 return false;
4774 }
4775
4776 if (proc.isInstrumenting()) {
4777 Bundle info = new Bundle();
4778 info.putString("shortMsg", "keyDispatchingTimedOut");
4779 info.putString("longMsg", annotation);
4780 mAm.finishInstrumentationLocked(
4781 (ProcessRecord) proc.mOwner, Activity.RESULT_CANCELED, info);
4782 return true;
4783 }
4784 }
4785 mH.post(() -> {
4786 mAm.mAppErrors.appNotResponding(
4787 (ProcessRecord) proc.mOwner, activity, parent, aboveSystem, annotation);
4788 });
4789 }
4790
4791 return true;
4792 }
4793
Wale Ogunwalef6733932018-06-27 05:14:34 -07004794 /**
4795 * Decide based on the configuration whether we should show the ANR,
4796 * crash, etc dialogs. The idea is that if there is no affordance to
4797 * press the on-screen buttons, or the user experience would be more
4798 * greatly impacted than the crash itself, we shouldn't show the dialog.
4799 *
4800 * A thought: SystemUI might also want to get told about this, the Power
4801 * dialog / global actions also might want different behaviors.
4802 */
4803 private void updateShouldShowDialogsLocked(Configuration config) {
4804 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
4805 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
4806 && config.navigation == Configuration.NAVIGATION_NONAV);
4807 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
4808 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
4809 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
4810 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
4811 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
4812 final boolean hideDialogsSet = Settings.Global.getInt(mContext.getContentResolver(),
4813 HIDE_ERROR_DIALOGS, 0) != 0;
4814 mShowDialogs = inputMethodExists && uiModeSupportsDialogs && !hideDialogsSet;
4815 }
4816
4817 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
4818 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
4819 FONT_SCALE, 1.0f, userId);
4820
4821 synchronized (this) {
4822 if (getGlobalConfiguration().fontScale == scaleFactor) {
4823 return;
4824 }
4825
4826 final Configuration configuration
4827 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
4828 configuration.fontScale = scaleFactor;
4829 updatePersistentConfiguration(configuration, userId);
4830 }
4831 }
4832
4833 // Actually is sleeping or shutting down or whatever else in the future
4834 // is an inactive state.
4835 boolean isSleepingOrShuttingDownLocked() {
4836 return isSleepingLocked() || mShuttingDown;
4837 }
4838
4839 boolean isSleepingLocked() {
4840 return mSleeping;
4841 }
4842
Riddle Hsu16567132018-08-16 21:37:47 +08004843 /** Update AMS states when an activity is resumed. */
Wale Ogunwalef6733932018-06-27 05:14:34 -07004844 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
4845 final TaskRecord task = r.getTask();
4846 if (task.isActivityTypeStandard()) {
4847 if (mCurAppTimeTracker != r.appTimeTracker) {
4848 // We are switching app tracking. Complete the current one.
4849 if (mCurAppTimeTracker != null) {
4850 mCurAppTimeTracker.stop();
4851 mH.obtainMessage(
4852 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
4853 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
4854 mCurAppTimeTracker = null;
4855 }
4856 if (r.appTimeTracker != null) {
4857 mCurAppTimeTracker = r.appTimeTracker;
4858 startTimeTrackingFocusedActivityLocked();
4859 }
4860 } else {
4861 startTimeTrackingFocusedActivityLocked();
4862 }
4863 } else {
4864 r.appTimeTracker = null;
4865 }
4866 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
4867 // TODO: Probably not, because we don't want to resume voice on switching
4868 // back to this activity
4869 if (task.voiceInteractor != null) {
4870 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
4871 } else {
4872 finishRunningVoiceLocked();
4873
4874 if (mLastResumedActivity != null) {
4875 final IVoiceInteractionSession session;
4876
4877 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
4878 if (lastResumedActivityTask != null
4879 && lastResumedActivityTask.voiceSession != null) {
4880 session = lastResumedActivityTask.voiceSession;
4881 } else {
4882 session = mLastResumedActivity.voiceSession;
4883 }
4884
4885 if (session != null) {
4886 // We had been in a voice interaction session, but now focused has
4887 // move to something different. Just finish the session, we can't
4888 // return to it and retain the proper state and synchronization with
4889 // the voice interaction service.
4890 finishVoiceTask(session);
4891 }
4892 }
4893 }
4894
4895 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
4896 mAmInternal.sendForegroundProfileChanged(r.userId);
4897 }
4898 updateResumedAppTrace(r);
4899 mLastResumedActivity = r;
4900
Tiger Huang1e5b10a2018-07-30 20:19:51 +08004901 r.getDisplay().setFocusedApp(r, true);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004902
4903 applyUpdateLockStateLocked(r);
4904 applyUpdateVrModeLocked(r);
4905
4906 EventLogTags.writeAmSetResumedActivity(
4907 r == null ? -1 : r.userId,
4908 r == null ? "NULL" : r.shortComponentName,
4909 reason);
4910 }
4911
4912 ActivityTaskManagerInternal.SleepToken acquireSleepToken(String tag, int displayId) {
4913 synchronized (mGlobalLock) {
4914 final ActivityTaskManagerInternal.SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
4915 updateSleepIfNeededLocked();
4916 return token;
4917 }
4918 }
4919
4920 void updateSleepIfNeededLocked() {
4921 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
4922 final boolean wasSleeping = mSleeping;
4923 boolean updateOomAdj = false;
4924
4925 if (!shouldSleep) {
4926 // If wasSleeping is true, we need to wake up activity manager state from when
4927 // we started sleeping. In either case, we need to apply the sleep tokens, which
4928 // will wake up stacks or put them to sleep as appropriate.
4929 if (wasSleeping) {
4930 mSleeping = false;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07004931 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
4932 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__AWAKE);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004933 startTimeTrackingFocusedActivityLocked();
4934 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
4935 mStackSupervisor.comeOutOfSleepIfNeededLocked();
4936 }
4937 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
4938 if (wasSleeping) {
4939 updateOomAdj = true;
4940 }
4941 } else if (!mSleeping && shouldSleep) {
4942 mSleeping = true;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07004943 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
4944 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__ASLEEP);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004945 if (mCurAppTimeTracker != null) {
4946 mCurAppTimeTracker.stop();
4947 }
4948 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
4949 mStackSupervisor.goingToSleepLocked();
4950 updateResumedAppTrace(null /* resumed */);
4951 updateOomAdj = true;
4952 }
4953 if (updateOomAdj) {
4954 mH.post(mAmInternal::updateOomAdj);
4955 }
4956 }
4957
4958 void updateOomAdj() {
4959 mH.post(mAmInternal::updateOomAdj);
4960 }
4961
Wale Ogunwale53783742018-09-16 10:21:51 -07004962 void updateCpuStats() {
4963 mH.post(mAmInternal::updateCpuStats);
4964 }
4965
4966 void updateUsageStats(ActivityRecord component, boolean resumed) {
4967 final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::updateUsageStats,
4968 mAmInternal, component.realActivity, component.app.mUid, component.userId, resumed);
4969 mH.sendMessage(m);
4970 }
4971
4972 void setBooting(boolean booting) {
4973 mAmInternal.setBooting(booting);
4974 }
4975
4976 boolean isBooting() {
4977 return mAmInternal.isBooting();
4978 }
4979
4980 void setBooted(boolean booted) {
4981 mAmInternal.setBooted(booted);
4982 }
4983
4984 boolean isBooted() {
4985 return mAmInternal.isBooted();
4986 }
4987
4988 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
4989 mH.post(() -> {
4990 if (finishBooting) {
4991 mAmInternal.finishBooting();
4992 }
4993 if (enableScreen) {
4994 mInternal.enableScreenAfterBoot(isBooted());
4995 }
4996 });
4997 }
4998
4999 void setHeavyWeightProcess(ActivityRecord root) {
5000 mHeavyWeightProcess = root.app;
5001 final Message m = PooledLambda.obtainMessage(
5002 ActivityTaskManagerService::postHeavyWeightProcessNotification, this,
5003 root.app, root.intent, root.userId);
5004 mH.sendMessage(m);
5005 }
5006
5007 void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
5008 if (mHeavyWeightProcess == null || mHeavyWeightProcess != proc) {
5009 return;
5010 }
5011
5012 mHeavyWeightProcess = null;
5013 final Message m = PooledLambda.obtainMessage(
5014 ActivityTaskManagerService::cancelHeavyWeightProcessNotification, this,
5015 proc.mUserId);
5016 mH.sendMessage(m);
5017 }
5018
5019 private void cancelHeavyWeightProcessNotification(int userId) {
5020 final INotificationManager inm = NotificationManager.getService();
5021 if (inm == null) {
5022 return;
5023 }
5024 try {
5025 inm.cancelNotificationWithTag("android", null,
5026 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, userId);
5027 } catch (RuntimeException e) {
5028 Slog.w(TAG, "Error canceling notification for service", e);
5029 } catch (RemoteException e) {
5030 }
5031
5032 }
5033
5034 private void postHeavyWeightProcessNotification(
5035 WindowProcessController proc, Intent intent, int userId) {
5036 if (proc == null) {
5037 return;
5038 }
5039
5040 final INotificationManager inm = NotificationManager.getService();
5041 if (inm == null) {
5042 return;
5043 }
5044
5045 try {
5046 Context context = mContext.createPackageContext(proc.mInfo.packageName, 0);
5047 String text = mContext.getString(R.string.heavy_weight_notification,
5048 context.getApplicationInfo().loadLabel(context.getPackageManager()));
5049 Notification notification =
5050 new Notification.Builder(context,
5051 SystemNotificationChannels.HEAVY_WEIGHT_APP)
5052 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
5053 .setWhen(0)
5054 .setOngoing(true)
5055 .setTicker(text)
5056 .setColor(mContext.getColor(
5057 com.android.internal.R.color.system_notification_accent_color))
5058 .setContentTitle(text)
5059 .setContentText(
5060 mContext.getText(R.string.heavy_weight_notification_detail))
5061 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
5062 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
5063 new UserHandle(userId)))
5064 .build();
5065 try {
5066 inm.enqueueNotificationWithTag("android", "android", null,
5067 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, notification, userId);
5068 } catch (RuntimeException e) {
5069 Slog.w(TAG, "Error showing notification for heavy-weight app", e);
5070 } catch (RemoteException e) {
5071 }
5072 } catch (PackageManager.NameNotFoundException e) {
5073 Slog.w(TAG, "Unable to create context for heavy notification", e);
5074 }
5075
5076 }
5077
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07005078 IIntentSender getIntentSenderLocked(int type, String packageName, int callingUid, int userId,
5079 IBinder token, String resultWho, int requestCode, Intent[] intents,
5080 String[] resolvedTypes, int flags, Bundle bOptions) {
5081
5082 ActivityRecord activity = null;
5083 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5084 activity = ActivityRecord.isInStackLocked(token);
5085 if (activity == null) {
5086 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
5087 return null;
5088 }
5089 if (activity.finishing) {
5090 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
5091 return null;
5092 }
5093 }
5094
5095 final PendingIntentRecord rec = mPendingIntentController.getIntentSender(type, packageName,
5096 callingUid, userId, token, resultWho, requestCode, intents, resolvedTypes, flags,
5097 bOptions);
5098 final boolean noCreate = (flags & PendingIntent.FLAG_NO_CREATE) != 0;
5099 if (noCreate) {
5100 return rec;
5101 }
5102 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5103 if (activity.pendingResults == null) {
5104 activity.pendingResults = new HashSet<>();
5105 }
5106 activity.pendingResults.add(rec.ref);
5107 }
5108 return rec;
5109 }
5110
Andrii Kulian52d255c2018-07-13 11:32:19 -07005111 // TODO(b/111541062): Update app time tracking to make it aware of multiple resumed activities
Wale Ogunwalef6733932018-06-27 05:14:34 -07005112 private void startTimeTrackingFocusedActivityLocked() {
Andrii Kulian52d255c2018-07-13 11:32:19 -07005113 final ActivityRecord resumedActivity = mStackSupervisor.getTopResumedActivity();
Wale Ogunwalef6733932018-06-27 05:14:34 -07005114 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
5115 mCurAppTimeTracker.start(resumedActivity.packageName);
5116 }
5117 }
5118
5119 private void updateResumedAppTrace(@Nullable ActivityRecord resumed) {
5120 if (mTracedResumedActivity != null) {
5121 Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER,
5122 constructResumedTraceName(mTracedResumedActivity.packageName), 0);
5123 }
5124 if (resumed != null) {
5125 Trace.asyncTraceBegin(TRACE_TAG_ACTIVITY_MANAGER,
5126 constructResumedTraceName(resumed.packageName), 0);
5127 }
5128 mTracedResumedActivity = resumed;
5129 }
5130
5131 private String constructResumedTraceName(String packageName) {
5132 return "focused app: " + packageName;
5133 }
5134
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005135 /** Helper method that requests bounds from WM and applies them to stack. */
5136 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
5137 final Rect newStackBounds = new Rect();
5138 final ActivityStack stack = mStackSupervisor.getStack(stackId);
5139
5140 // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
5141 if (stack == null) {
5142 final StringWriter writer = new StringWriter();
5143 final PrintWriter printWriter = new PrintWriter(writer);
5144 mStackSupervisor.dumpDisplays(printWriter);
5145 printWriter.flush();
5146
5147 Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
5148 }
5149
5150 stack.getBoundsForNewConfiguration(newStackBounds);
5151 mStackSupervisor.resizeStackLocked(
5152 stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
5153 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
5154 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
5155 }
5156
5157 /** Applies latest configuration and/or visibility updates if needed. */
5158 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
5159 boolean kept = true;
Andrii Kulian5f750bc2018-07-17 08:57:23 -07005160 final ActivityStack mainStack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005161 // mainStack is null during startup.
5162 if (mainStack != null) {
5163 if (changes != 0 && starting == null) {
5164 // If the configuration changed, and the caller is not already
5165 // in the process of starting an activity, then find the top
5166 // activity to check if its configuration needs to change.
5167 starting = mainStack.topRunningActivityLocked();
5168 }
5169
5170 if (starting != null) {
5171 kept = starting.ensureActivityConfiguration(changes,
5172 false /* preserveWindow */);
5173 // And we need to make sure at this point that all other activities
5174 // are made visible with the correct configuration.
5175 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
5176 !PRESERVE_WINDOWS);
5177 }
5178 }
5179
5180 return kept;
5181 }
5182
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005183 void scheduleAppGcsLocked() {
5184 mH.post(() -> mAmInternal.scheduleAppGcs());
5185 }
5186
Wale Ogunwale53783742018-09-16 10:21:51 -07005187 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
5188 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
5189 }
5190
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005191 /**
5192 * Returns the PackageManager. Used by classes hosted by {@link ActivityTaskManagerService}. The
5193 * PackageManager could be unavailable at construction time and therefore needs to be accessed
5194 * on demand.
5195 */
5196 IPackageManager getPackageManager() {
5197 return AppGlobals.getPackageManager();
5198 }
5199
5200 PackageManagerInternal getPackageManagerInternalLocked() {
5201 if (mPmInternal == null) {
5202 mPmInternal = LocalServices.getService(PackageManagerInternal.class);
5203 }
5204 return mPmInternal;
5205 }
5206
Wale Ogunwale008163e2018-07-23 23:11:08 -07005207 AppWarnings getAppWarningsLocked() {
5208 return mAppWarnings;
5209 }
5210
Wale Ogunwale214f3482018-10-04 11:00:47 -07005211 Intent getHomeIntent() {
5212 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
5213 intent.setComponent(mTopComponent);
5214 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
5215 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5216 intent.addCategory(Intent.CATEGORY_HOME);
5217 }
5218 return intent;
5219 }
5220
5221 /**
5222 * This starts home activity on displays that can have system decorations and only if the
5223 * home activity can have multiple instances.
5224 */
5225 boolean startHomeActivityLocked(int userId, String reason, int displayId) {
5226 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL && mTopAction == null) {
5227 // We are running in factory test mode, but unable to find the factory test app, so just
5228 // sit around displaying the error message and don't try to start anything.
5229 return false;
5230 }
5231
5232 final Intent intent = getHomeIntent();
5233 ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
5234 if (aInfo != null) {
5235 intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
5236 // Don't do this if the home app is currently being instrumented.
5237 aInfo = new ActivityInfo(aInfo);
5238 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
5239 WindowProcessController app =
5240 getProcessController(aInfo.processName, aInfo.applicationInfo.uid);
5241 if (app == null || !app.isInstrumenting()) {
5242 intent.setFlags(intent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
5243 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
5244 // For ANR debugging to verify if the user activity is the one that actually
5245 // launched.
5246 final String myReason = reason + ":" + userId + ":" + resolvedUserId;
5247 getActivityStartController().startHomeActivity(intent, aInfo, myReason, displayId);
5248 }
5249 } else {
5250 Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
5251 }
5252
5253 return true;
5254 }
5255
5256 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
5257 ActivityInfo ai = null;
5258 final ComponentName comp = intent.getComponent();
5259 try {
5260 if (comp != null) {
5261 // Factory test.
5262 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
5263 } else {
5264 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
5265 intent,
5266 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
5267 flags, userId);
5268
5269 if (info != null) {
5270 ai = info.activityInfo;
5271 }
5272 }
5273 } catch (RemoteException e) {
5274 // ignore
5275 }
5276
5277 return ai;
5278 }
5279
5280 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
5281 if (info == null) return null;
5282 ApplicationInfo newInfo = new ApplicationInfo(info);
5283 newInfo.initForUser(userId);
5284 return newInfo;
5285 }
5286
5287 private WindowProcessController getProcessController(String processName, int uid) {
5288 if (uid == SYSTEM_UID) {
5289 // The system gets to run in any process. If there are multiple processes with the same
5290 // uid, just pick the first (this should never happen).
5291 final SparseArray<WindowProcessController> procs =
5292 mProcessNames.getMap().get(processName);
5293 if (procs == null) return null;
5294 final int procCount = procs.size();
5295 for (int i = 0; i < procCount; i++) {
5296 final int procUid = procs.keyAt(i);
5297 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
5298 // Don't use an app process or different user process for system component.
5299 continue;
5300 }
5301 return procs.valueAt(i);
5302 }
5303 }
5304
5305 return mProcessNames.get(processName, uid);
5306 }
5307
Wale Ogunwale342fbe92018-10-09 08:44:10 -07005308 WindowProcessController getProcessController(IApplicationThread thread) {
5309 if (thread == null) {
5310 return null;
5311 }
5312
5313 final IBinder threadBinder = thread.asBinder();
5314 final ArrayMap<String, SparseArray<WindowProcessController>> pmap = mProcessNames.getMap();
5315 for (int i = pmap.size()-1; i >= 0; i--) {
5316 final SparseArray<WindowProcessController> procs = pmap.valueAt(i);
5317 for (int j = procs.size() - 1; j >= 0; j--) {
5318 final WindowProcessController proc = procs.valueAt(j);
5319 if (proc.hasThread() && proc.getThread().asBinder() == threadBinder) {
5320 return proc;
5321 }
5322 }
5323 }
5324
5325 return null;
5326 }
5327
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005328 void logAppTooSlow(WindowProcessController app, long startTime, String msg) {
5329 if (true || Build.IS_USER) {
5330 return;
5331 }
5332
5333 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5334 StrictMode.allowThreadDiskWrites();
5335 try {
5336 File tracesDir = new File("/data/anr");
5337 File tracesFile = null;
5338 try {
5339 tracesFile = File.createTempFile("app_slow", null, tracesDir);
5340
5341 StringBuilder sb = new StringBuilder();
5342 Time tobj = new Time();
5343 tobj.set(System.currentTimeMillis());
5344 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5345 sb.append(": ");
5346 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5347 sb.append(" since ");
5348 sb.append(msg);
5349 FileOutputStream fos = new FileOutputStream(tracesFile);
5350 fos.write(sb.toString().getBytes());
5351 if (app == null) {
5352 fos.write("\n*** No application process!".getBytes());
5353 }
5354 fos.close();
5355 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5356 } catch (IOException e) {
5357 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesFile, e);
5358 return;
5359 }
5360
5361 if (app != null && app.getPid() > 0) {
5362 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5363 firstPids.add(app.getPid());
5364 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, null, null);
5365 }
5366
5367 File lastTracesFile = null;
5368 File curTracesFile = null;
5369 for (int i=9; i>=0; i--) {
5370 String name = String.format(Locale.US, "slow%02d.txt", i);
5371 curTracesFile = new File(tracesDir, name);
5372 if (curTracesFile.exists()) {
5373 if (lastTracesFile != null) {
5374 curTracesFile.renameTo(lastTracesFile);
5375 } else {
5376 curTracesFile.delete();
5377 }
5378 }
5379 lastTracesFile = curTracesFile;
5380 }
5381 tracesFile.renameTo(curTracesFile);
5382 } finally {
5383 StrictMode.setThreadPolicy(oldPolicy);
5384 }
5385 }
5386
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005387 final class H extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005388 static final int REPORT_TIME_TRACKER_MSG = 1;
5389
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005390 public H(Looper looper) {
5391 super(looper, null, true);
5392 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005393
5394 @Override
5395 public void handleMessage(Message msg) {
5396 switch (msg.what) {
5397 case REPORT_TIME_TRACKER_MSG: {
5398 AppTimeTracker tracker = (AppTimeTracker) msg.obj;
5399 tracker.deliverResult(mContext);
5400 } break;
5401 }
5402 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005403 }
5404
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005405 final class UiHandler extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005406 static final int DISMISS_DIALOG_UI_MSG = 1;
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005407
5408 public UiHandler() {
5409 super(com.android.server.UiThread.get().getLooper(), null, true);
5410 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005411
5412 @Override
5413 public void handleMessage(Message msg) {
5414 switch (msg.what) {
5415 case DISMISS_DIALOG_UI_MSG: {
5416 final Dialog d = (Dialog) msg.obj;
5417 d.dismiss();
5418 break;
5419 }
5420 }
5421 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005422 }
5423
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005424 final class LocalService extends ActivityTaskManagerInternal {
5425 @Override
5426 public SleepToken acquireSleepToken(String tag, int displayId) {
5427 Preconditions.checkNotNull(tag);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005428 return ActivityTaskManagerService.this.acquireSleepToken(tag, displayId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005429 }
5430
5431 @Override
5432 public ComponentName getHomeActivityForUser(int userId) {
5433 synchronized (mGlobalLock) {
Louis Changbd48dca2018-08-29 17:44:34 +08005434 ActivityRecord homeActivity =
5435 mStackSupervisor.getDefaultDisplayHomeActivityForUser(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005436 return homeActivity == null ? null : homeActivity.realActivity;
5437 }
5438 }
5439
5440 @Override
5441 public void onLocalVoiceInteractionStarted(IBinder activity,
5442 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
5443 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005444 onLocalVoiceInteractionStartedLocked(activity, voiceSession, voiceInteractor);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005445 }
5446 }
5447
5448 @Override
5449 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
5450 synchronized (mGlobalLock) {
5451 mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
5452 reasons, timestamp);
5453 }
5454 }
5455
5456 @Override
5457 public void notifyAppTransitionFinished() {
5458 synchronized (mGlobalLock) {
5459 mStackSupervisor.notifyAppTransitionDone();
5460 }
5461 }
5462
5463 @Override
5464 public void notifyAppTransitionCancelled() {
5465 synchronized (mGlobalLock) {
5466 mStackSupervisor.notifyAppTransitionDone();
5467 }
5468 }
5469
5470 @Override
5471 public List<IBinder> getTopVisibleActivities() {
5472 synchronized (mGlobalLock) {
5473 return mStackSupervisor.getTopVisibleActivities();
5474 }
5475 }
5476
5477 @Override
5478 public void notifyDockedStackMinimizedChanged(boolean minimized) {
5479 synchronized (mGlobalLock) {
5480 mStackSupervisor.setDockedStackMinimized(minimized);
5481 }
5482 }
5483
5484 @Override
5485 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
5486 Bundle bOptions) {
5487 Preconditions.checkNotNull(intents, "intents");
5488 final String[] resolvedTypes = new String[intents.length];
5489
5490 // UID of the package on user userId.
5491 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
5492 // packageUid may not be initialized.
5493 int packageUid = 0;
5494 final long ident = Binder.clearCallingIdentity();
5495
5496 try {
5497 for (int i = 0; i < intents.length; i++) {
5498 resolvedTypes[i] =
5499 intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
5500 }
5501
5502 packageUid = AppGlobals.getPackageManager().getPackageUid(
5503 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
5504 } catch (RemoteException e) {
5505 // Shouldn't happen.
5506 } finally {
5507 Binder.restoreCallingIdentity(ident);
5508 }
5509
5510 synchronized (mGlobalLock) {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07005511 return getActivityStartController().startActivitiesInPackage(
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005512 packageUid, packageName,
5513 intents, resolvedTypes, null /* resultTo */,
5514 SafeActivityOptions.fromBundle(bOptions), userId,
Michal Karpinski201bc0c2018-07-20 15:32:00 +01005515 false /* validateIncomingUser */, null /* originatingPendingIntent */);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005516 }
5517 }
5518
5519 @Override
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07005520 public int startActivitiesInPackage(int uid, String callingPackage, Intent[] intents,
5521 String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, int userId,
5522 boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent) {
5523 synchronized (mGlobalLock) {
5524 return getActivityStartController().startActivitiesInPackage(uid, callingPackage,
5525 intents, resolvedTypes, resultTo, options, userId, validateIncomingUser,
5526 originatingPendingIntent);
5527 }
5528 }
5529
5530 @Override
5531 public int startActivityInPackage(int uid, int realCallingPid, int realCallingUid,
5532 String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
5533 String resultWho, int requestCode, int startFlags, SafeActivityOptions options,
5534 int userId, TaskRecord inTask, String reason, boolean validateIncomingUser,
5535 PendingIntentRecord originatingPendingIntent) {
5536 synchronized (mGlobalLock) {
5537 return getActivityStartController().startActivityInPackage(uid, realCallingPid,
5538 realCallingUid, callingPackage, intent, resolvedType, resultTo, resultWho,
5539 requestCode, startFlags, options, userId, inTask, reason,
5540 validateIncomingUser, originatingPendingIntent);
5541 }
5542 }
5543
5544 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005545 public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
5546 Intent intent, Bundle options, int userId) {
5547 return ActivityTaskManagerService.this.startActivityAsUser(
5548 caller, callerPacakge, intent,
5549 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
5550 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
5551 false /*validateIncomingUser*/);
5552 }
5553
5554 @Override
5555 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
5556 synchronized (mGlobalLock) {
5557
5558 // We might change the visibilities here, so prepare an empty app transition which
5559 // might be overridden later if we actually change visibilities.
5560 final boolean wasTransitionSet =
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005561 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005562 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005563 mWindowManager.prepareAppTransition(TRANSIT_NONE,
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005564 false /* alwaysKeepCurrent */);
5565 }
5566 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5567
5568 // If there was a transition set already we don't want to interfere with it as we
5569 // might be starting it too early.
5570 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005571 mWindowManager.executeAppTransition();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005572 }
5573 }
5574 if (callback != null) {
5575 callback.run();
5576 }
5577 }
5578
5579 @Override
5580 public void notifyKeyguardTrustedChanged() {
5581 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005582 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005583 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5584 }
5585 }
5586 }
5587
5588 /**
5589 * Called after virtual display Id is updated by
5590 * {@link com.android.server.vr.Vr2dDisplay} with a specific
5591 * {@param vrVr2dDisplayId}.
5592 */
5593 @Override
5594 public void setVr2dDisplayId(int vr2dDisplayId) {
5595 if (DEBUG_STACK) Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
5596 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005597 mVr2dDisplayId = vr2dDisplayId;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005598 }
5599 }
5600
5601 @Override
5602 public void setFocusedActivity(IBinder token) {
5603 synchronized (mGlobalLock) {
5604 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
5605 if (r == null) {
5606 throw new IllegalArgumentException(
5607 "setFocusedActivity: No activity record matching token=" + token);
5608 }
Louis Chang19443452018-10-09 12:10:21 +08005609 if (r.moveFocusableActivityToTop("setFocusedActivity")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08005610 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005611 }
5612 }
5613 }
5614
5615 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005616 public void registerScreenObserver(ScreenObserver observer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005617 mScreenObservers.add(observer);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005618 }
5619
5620 @Override
5621 public boolean isCallerRecents(int callingUid) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005622 return getRecentTasks().isCallerRecents(callingUid);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005623 }
5624
5625 @Override
5626 public boolean isRecentsComponentHomeActivity(int userId) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005627 return getRecentTasks().isRecentsComponentHomeActivity(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005628 }
5629
5630 @Override
5631 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
5632 ActivityTaskManagerService.this.cancelRecentsAnimation(restoreHomeStackPosition);
5633 }
5634
5635 @Override
5636 public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005637 ActivityTaskManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005638 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005639
5640 @Override
5641 public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
5642 synchronized (mGlobalLock) {
5643 mActiveVoiceInteractionServiceComponent = component;
5644 }
5645 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005646
5647 @Override
5648 public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
5649 if (!mAmInternal.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
5650 return;
5651 }
5652 synchronized (mGlobalLock) {
5653 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
5654 if (types == null) {
5655 if (uid < 0) {
5656 return;
5657 }
5658 types = new ArrayMap<>();
5659 mAllowAppSwitchUids.put(userId, types);
5660 }
5661 if (uid < 0) {
5662 types.remove(type);
5663 } else {
5664 types.put(type, uid);
5665 }
5666 }
5667 }
5668
5669 @Override
5670 public void onUserStopped(int userId) {
5671 synchronized (mGlobalLock) {
5672 getRecentTasks().unloadUserDataFromMemoryLocked(userId);
5673 mAllowAppSwitchUids.remove(userId);
5674 }
5675 }
5676
5677 @Override
5678 public boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
5679 synchronized (mGlobalLock) {
5680 return ActivityTaskManagerService.this.isGetTasksAllowed(
5681 caller, callingPid, callingUid);
5682 }
5683 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005684
5685 @Override
5686 public void onProcessAdded(WindowProcessController proc) {
5687 synchronized (mGlobalLock) {
5688 mProcessNames.put(proc.mName, proc.mUid, proc);
5689 }
5690 }
5691
5692 @Override
5693 public void onProcessRemoved(String name, int uid) {
5694 synchronized (mGlobalLock) {
5695 mProcessNames.remove(name, uid);
5696 }
5697 }
5698
5699 @Override
5700 public void onCleanUpApplicationRecord(WindowProcessController proc) {
5701 synchronized (mGlobalLock) {
5702 if (proc == mHomeProcess) {
5703 mHomeProcess = null;
5704 }
5705 if (proc == mPreviousProcess) {
5706 mPreviousProcess = null;
5707 }
5708 }
5709 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005710
5711 @Override
5712 public int getTopProcessState() {
5713 synchronized (mGlobalLock) {
5714 return mTopProcessState;
5715 }
5716 }
5717
5718 @Override
Wale Ogunwale53783742018-09-16 10:21:51 -07005719 public boolean isHeavyWeightProcess(WindowProcessController proc) {
5720 synchronized (mGlobalLock) {
5721 return proc == mHeavyWeightProcess;
5722 }
5723 }
5724
5725 @Override
5726 public void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
5727 synchronized (mGlobalLock) {
5728 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(proc);
5729 }
5730 }
5731
5732 @Override
5733 public void finishHeavyWeightApp() {
5734 synchronized (mGlobalLock) {
5735 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(
5736 mHeavyWeightProcess);
5737 }
5738 }
5739
5740 @Override
Wale Ogunwalef6733932018-06-27 05:14:34 -07005741 public boolean isSleeping() {
5742 synchronized (mGlobalLock) {
5743 return isSleepingLocked();
5744 }
5745 }
5746
5747 @Override
5748 public boolean isShuttingDown() {
5749 synchronized (mGlobalLock) {
5750 return mShuttingDown;
5751 }
5752 }
5753
5754 @Override
5755 public boolean shuttingDown(boolean booted, int timeout) {
5756 synchronized (mGlobalLock) {
5757 mShuttingDown = true;
5758 mStackSupervisor.prepareForShutdownLocked();
5759 updateEventDispatchingLocked(booted);
5760 return mStackSupervisor.shutdownLocked(timeout);
5761 }
5762 }
5763
5764 @Override
5765 public void enableScreenAfterBoot(boolean booted) {
5766 synchronized (mGlobalLock) {
5767 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5768 SystemClock.uptimeMillis());
5769 mWindowManager.enableScreenAfterBoot();
5770 updateEventDispatchingLocked(booted);
5771 }
5772 }
5773
5774 @Override
5775 public boolean showStrictModeViolationDialog() {
5776 synchronized (mGlobalLock) {
5777 return mShowDialogs && !mSleeping && !mShuttingDown;
5778 }
5779 }
5780
5781 @Override
5782 public void showSystemReadyErrorDialogsIfNeeded() {
5783 synchronized (mGlobalLock) {
5784 try {
5785 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
5786 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
5787 + " data partition or your device will be unstable.");
5788 mUiHandler.post(() -> {
5789 if (mShowDialogs) {
5790 AlertDialog d = new BaseErrorDialog(mUiContext);
5791 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5792 d.setCancelable(false);
5793 d.setTitle(mUiContext.getText(R.string.android_system_label));
5794 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
5795 d.setButton(DialogInterface.BUTTON_POSITIVE,
5796 mUiContext.getText(R.string.ok),
5797 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5798 d.show();
5799 }
5800 });
5801 }
5802 } catch (RemoteException e) {
5803 }
5804
5805 if (!Build.isBuildConsistent()) {
5806 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
5807 mUiHandler.post(() -> {
5808 if (mShowDialogs) {
5809 AlertDialog d = new BaseErrorDialog(mUiContext);
5810 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5811 d.setCancelable(false);
5812 d.setTitle(mUiContext.getText(R.string.android_system_label));
5813 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
5814 d.setButton(DialogInterface.BUTTON_POSITIVE,
5815 mUiContext.getText(R.string.ok),
5816 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5817 d.show();
5818 }
5819 });
5820 }
5821 }
5822 }
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005823
5824 @Override
5825 public long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason) {
5826 synchronized (mGlobalLock) {
5827 return ActivityTaskManagerService.this.inputDispatchingTimedOut(
5828 pid, aboveSystem, reason);
5829 }
5830 }
5831
5832 @Override
5833 public void onProcessMapped(int pid, WindowProcessController proc) {
5834 synchronized (mGlobalLock) {
5835 mPidMap.put(pid, proc);
5836 }
5837 }
5838
5839 @Override
5840 public void onProcessUnMapped(int pid) {
5841 synchronized (mGlobalLock) {
5842 mPidMap.remove(pid);
5843 }
5844 }
Wale Ogunwale008163e2018-07-23 23:11:08 -07005845
5846 @Override
5847 public void onPackageDataCleared(String name) {
5848 synchronized (mGlobalLock) {
Wale Ogunwale53783742018-09-16 10:21:51 -07005849 mCompatModePackages.handlePackageDataClearedLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07005850 mAppWarnings.onPackageDataCleared(name);
5851 }
5852 }
5853
5854 @Override
5855 public void onPackageUninstalled(String name) {
5856 synchronized (mGlobalLock) {
5857 mAppWarnings.onPackageUninstalled(name);
Wale Ogunwale53783742018-09-16 10:21:51 -07005858 mCompatModePackages.handlePackageUninstalledLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07005859 }
5860 }
Wale Ogunwale53783742018-09-16 10:21:51 -07005861
5862 @Override
5863 public void onPackageAdded(String name, boolean replacing) {
5864 synchronized (mGlobalLock) {
5865 mCompatModePackages.handlePackageAddedLocked(name, replacing);
5866 }
5867 }
5868
5869 @Override
5870 public CompatibilityInfo compatibilityInfoForPackage(ApplicationInfo ai) {
5871 synchronized (mGlobalLock) {
5872 return compatibilityInfoForPackageLocked(ai);
5873 }
5874 }
5875
Yunfan Chen75157d72018-07-27 14:47:21 +09005876 /**
5877 * Set the corresponding display information for the process global configuration. To be
5878 * called when we need to show IME on a different display.
5879 *
5880 * @param pid The process id associated with the IME window.
5881 * @param displayId The ID of the display showing the IME.
5882 */
5883 @Override
5884 public void onImeWindowSetOnDisplay(int pid, int displayId) {
5885 if (pid == MY_PID || pid < 0) {
5886 if (DEBUG_CONFIGURATION) {
5887 Slog.w(TAG,
5888 "Trying to update display configuration for system/invalid process.");
5889 }
5890 return;
5891 }
5892 mH.post(() -> {
5893 synchronized (mGlobalLock) {
5894 // Check if display is initialized in AM.
5895 if (!mStackSupervisor.isDisplayAdded(displayId)) {
5896 // Call come when display is not yet added or has already been removed.
5897 if (DEBUG_CONFIGURATION) {
5898 Slog.w(TAG, "Trying to update display configuration for non-existing "
5899 + "displayId=" + displayId);
5900 }
5901 return;
5902 }
5903 final WindowProcessController imeProcess = mPidMap.get(pid);
5904 if (imeProcess == null) {
5905 if (DEBUG_CONFIGURATION) {
5906 Slog.w(TAG, "Trying to update display configuration for invalid pid: "
5907 + pid);
5908 }
5909 return;
5910 }
5911 // Fetch the current override configuration of the display and set it to the
5912 // process global configuration.
5913 imeProcess.onConfigurationChanged(
5914 mStackSupervisor.getDisplayOverrideConfiguration(displayId));
5915 }
5916 });
5917 }
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07005918
5919 @Override
5920 public void sendActivityResult(int callingUid, IBinder activityToken, String resultWho,
5921 int requestCode, int resultCode, Intent data) {
5922 synchronized (mGlobalLock) {
5923 final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
5924 if (r != null && r.getStack() != null) {
5925 r.getStack().sendActivityResultLocked(callingUid, r, resultWho, requestCode,
5926 resultCode, data);
5927 }
5928 }
5929 }
5930
5931 @Override
5932 public void clearPendingResultForActivity(IBinder activityToken,
5933 WeakReference<PendingIntentRecord> pir) {
5934 synchronized (mGlobalLock) {
5935 final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
5936 if (r != null && r.pendingResults != null) {
5937 r.pendingResults.remove(pir);
5938 }
5939 }
5940 }
5941
5942 @Override
5943 public IIntentSender getIntentSender(int type, String packageName,
5944 int callingUid, int userId, IBinder token, String resultWho,
5945 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5946 Bundle bOptions) {
5947 synchronized (mGlobalLock) {
5948 return getIntentSenderLocked(type, packageName, callingUid, userId, token,
5949 resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
5950 }
5951 }
Wale Ogunwalec4e63a42018-10-02 13:19:54 -07005952
5953 @Override
5954 public ActivityServiceConnectionsHolder getServiceConnectionsHolder(IBinder token) {
5955 synchronized (mGlobalLock) {
5956 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
5957 if (r == null) {
5958 return null;
5959 }
5960 if (r.mServiceConnectionsHolder == null) {
5961 r.mServiceConnectionsHolder = new ActivityServiceConnectionsHolder(
5962 ActivityTaskManagerService.this, r);
5963 }
5964
5965 return r.mServiceConnectionsHolder;
5966 }
5967 }
Wale Ogunwale214f3482018-10-04 11:00:47 -07005968
5969 @Override
5970 public Intent getHomeIntent() {
5971 synchronized (mGlobalLock) {
5972 return ActivityTaskManagerService.this.getHomeIntent();
5973 }
5974 }
5975
5976 @Override
5977 public boolean startHomeActivity(int userId, String reason) {
5978 synchronized (mGlobalLock) {
5979 return startHomeActivityLocked(userId, reason, DEFAULT_DISPLAY);
5980 }
5981 }
5982
5983 @Override
5984 public boolean isFactoryTestProcess(WindowProcessController wpc) {
5985 synchronized (mGlobalLock) {
5986 if (mFactoryTest == FACTORY_TEST_OFF) {
5987 return false;
5988 }
5989 if (mFactoryTest == FACTORY_TEST_LOW_LEVEL && mTopComponent != null
5990 && wpc.mName.equals(mTopComponent.getPackageName())) {
5991 return true;
5992 }
5993 return mFactoryTest == FACTORY_TEST_HIGH_LEVEL
5994 && (wpc.mInfo.flags & FLAG_FACTORY_TEST) != 0;
5995 }
5996 }
5997
5998 @Override
5999 public void updateTopComponentForFactoryTest() {
6000 synchronized (mGlobalLock) {
6001 if (mFactoryTest != FACTORY_TEST_LOW_LEVEL) {
6002 return;
6003 }
6004 final ResolveInfo ri = mContext.getPackageManager()
6005 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), STOCK_PM_FLAGS);
6006 final CharSequence errorMsg;
6007 if (ri != null) {
6008 final ActivityInfo ai = ri.activityInfo;
6009 final ApplicationInfo app = ai.applicationInfo;
6010 if ((app.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
6011 mTopAction = Intent.ACTION_FACTORY_TEST;
6012 mTopData = null;
6013 mTopComponent = new ComponentName(app.packageName, ai.name);
6014 errorMsg = null;
6015 } else {
6016 errorMsg = mContext.getResources().getText(
6017 com.android.internal.R.string.factorytest_not_system);
6018 }
6019 } else {
6020 errorMsg = mContext.getResources().getText(
6021 com.android.internal.R.string.factorytest_no_action);
6022 }
6023 if (errorMsg == null) {
6024 return;
6025 }
6026
6027 mTopAction = null;
6028 mTopData = null;
6029 mTopComponent = null;
6030 mUiHandler.post(() -> {
6031 Dialog d = new FactoryErrorDialog(mUiContext, errorMsg);
6032 d.show();
Wale Ogunwale342fbe92018-10-09 08:44:10 -07006033 mAmInternal.ensureBootCompleted();
Wale Ogunwale214f3482018-10-04 11:00:47 -07006034 });
6035 }
6036 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07006037 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07006038}