blob: 4dd5a998d433c3e602f099827d8961c3abe670f6 [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 Ogunwalea6191b42018-05-09 07:41:32 -070043import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
44import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
Evan Rosky4505b352018-09-06 11:20:40 -070045import static android.content.pm.PackageManager.FEATURE_PC;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070046import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070047import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070048import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
49import static android.os.Build.VERSION_CODES.N;
Wale Ogunwale214f3482018-10-04 11:00:47 -070050import static android.os.FactoryTest.FACTORY_TEST_HIGH_LEVEL;
51import static android.os.FactoryTest.FACTORY_TEST_LOW_LEVEL;
52import static android.os.FactoryTest.FACTORY_TEST_OFF;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070053import static android.os.Process.SYSTEM_UID;
Evan Rosky4505b352018-09-06 11:20:40 -070054import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070055import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
56import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
57import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
58import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
Evan Rosky4505b352018-09-06 11:20:40 -070059import static android.provider.Settings.Global.HIDE_ERROR_DIALOGS;
60import static android.provider.Settings.System.FONT_SCALE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070061import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
62import static android.view.Display.DEFAULT_DISPLAY;
63import static android.view.Display.INVALID_DISPLAY;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070064import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
Wale Ogunwale6767eae2018-05-03 15:52:51 -070065import static android.view.WindowManager.TRANSIT_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070066import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070067import static android.view.WindowManager.TRANSIT_TASK_OPEN;
68import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
Evan Rosky4505b352018-09-06 11:20:40 -070069
Wale Ogunwale65ebd952018-04-25 15:41:44 -070070import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070071import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
72import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
73import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
74import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070075import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070076import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070077import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070078import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070079import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070080import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
81import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
82import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070083import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070084import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
85import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070086import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
87import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
88import static com.android.server.am.ActivityManagerService.ANIMATE;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070089import static com.android.server.am.ActivityManagerService.MY_PID;
90import static com.android.server.am.ActivityManagerService.SEND_LOCALE_TO_MOUNT_DAEMON_MSG;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070091import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070092import static com.android.server.am.ActivityManagerService.UPDATE_CONFIGURATION_MSG;
Evan Rosky4505b352018-09-06 11:20:40 -070093import static com.android.server.am.ActivityManagerService.dumpStackTraces;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070094import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070095import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070096import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
97import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
98import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
99import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
100import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
Evan Rosky4505b352018-09-06 11:20:40 -0700101import static com.android.server.am.ActivityTaskManagerService.H.REPORT_TIME_TRACKER_MSG;
102import static com.android.server.am.ActivityTaskManagerService.UiHandler.DISMISS_DIALOG_UI_MSG;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700103import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
104import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700105import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700106import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
Evan Rosky4505b352018-09-06 11:20:40 -0700107import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT;
108import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_DATA;
109import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
110import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700111import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
112import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700113
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700114import android.Manifest;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700115import android.annotation.NonNull;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700116import android.annotation.Nullable;
117import android.annotation.UserIdInt;
118import android.app.Activity;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700119import android.app.ActivityManager;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700120import android.app.ActivityManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700121import android.app.ActivityOptions;
122import android.app.ActivityTaskManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700123import android.app.ActivityThread;
124import android.app.AlertDialog;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700125import android.app.AppGlobals;
Evan Rosky4505b352018-09-06 11:20:40 -0700126import android.app.Dialog;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700127import android.app.IActivityController;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700128import android.app.IActivityTaskManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700129import android.app.IApplicationThread;
130import android.app.IAssistDataReceiver;
Wale Ogunwale53783742018-09-16 10:21:51 -0700131import android.app.INotificationManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700132import android.app.ITaskStackListener;
Wale Ogunwale53783742018-09-16 10:21:51 -0700133import android.app.Notification;
134import android.app.NotificationManager;
135import android.app.PendingIntent;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700136import android.app.PictureInPictureParams;
137import android.app.ProfilerInfo;
138import android.app.RemoteAction;
139import android.app.WaitResult;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700140import android.app.WindowConfiguration;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700141import android.app.admin.DevicePolicyCache;
142import android.app.assist.AssistContent;
143import android.app.assist.AssistStructure;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700144import android.app.servertransaction.ConfigurationChangeItem;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700145import android.app.usage.UsageEvents;
146import android.content.ActivityNotFoundException;
147import android.content.ComponentName;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700148import android.content.ContentResolver;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700149import android.content.Context;
Evan Rosky4505b352018-09-06 11:20:40 -0700150import android.content.DialogInterface;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700151import android.content.IIntentSender;
152import android.content.Intent;
153import android.content.pm.ActivityInfo;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700154import android.content.pm.ApplicationInfo;
Yunfan Chen75157d72018-07-27 14:47:21 +0900155import android.content.pm.ConfigurationInfo;
Evan Rosky4505b352018-09-06 11:20:40 -0700156import android.content.pm.IPackageManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700157import android.content.pm.PackageManager;
Evan Rosky4505b352018-09-06 11:20:40 -0700158import android.content.pm.PackageManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700159import android.content.pm.ParceledListSlice;
160import android.content.pm.ResolveInfo;
Wale Ogunwale53783742018-09-16 10:21:51 -0700161import android.content.res.CompatibilityInfo;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700162import android.content.res.Configuration;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700163import android.content.res.Resources;
Evan Rosky4505b352018-09-06 11:20:40 -0700164import android.database.ContentObserver;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700165import android.graphics.Bitmap;
166import android.graphics.Point;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700167import android.graphics.Rect;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700168import android.metrics.LogMaker;
169import android.net.Uri;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700170import android.os.Binder;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700171import android.os.Build;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700172import android.os.Bundle;
Wale Ogunwale214f3482018-10-04 11:00:47 -0700173import android.os.FactoryTest;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700174import android.os.FileUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700175import android.os.Handler;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700176import android.os.IBinder;
Evan Rosky4505b352018-09-06 11:20:40 -0700177import android.os.IUserManager;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700178import android.os.LocaleList;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700179import android.os.Looper;
180import android.os.Message;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700181import android.os.PersistableBundle;
Evan Rosky4505b352018-09-06 11:20:40 -0700182import android.os.PowerManager;
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 Ogunwale04d9cb52018-04-30 13:55:07 -0700193import android.provider.Settings;
194import android.service.voice.IVoiceInteractionSession;
195import android.service.voice.VoiceInteractionManagerInternal;
196import android.telecom.TelecomManager;
197import android.text.TextUtils;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700198import android.text.format.Time;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700199import android.util.ArrayMap;
200import android.util.EventLog;
201import android.util.Log;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700202import android.util.Slog;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700203import android.util.SparseArray;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700204import android.util.SparseIntArray;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700205import android.util.StatsLog;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700206import android.util.TimeUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700207import android.util.proto.ProtoOutputStream;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700208import android.view.IRecentsAnimationRunner;
209import android.view.RemoteAnimationAdapter;
210import android.view.RemoteAnimationDefinition;
Evan Rosky4505b352018-09-06 11:20:40 -0700211import android.view.WindowManager;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700212
Evan Rosky4505b352018-09-06 11:20:40 -0700213import com.android.internal.R;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700214import com.android.internal.annotations.VisibleForTesting;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700215import com.android.internal.app.AssistUtils;
Evan Rosky4505b352018-09-06 11:20:40 -0700216import com.android.internal.app.IAppOpsService;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700217import com.android.internal.app.IVoiceInteractor;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700218import com.android.internal.app.ProcessMap;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700219import com.android.internal.logging.MetricsLogger;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700220import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Wale Ogunwale53783742018-09-16 10:21:51 -0700221import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
222import com.android.internal.notification.SystemNotificationChannels;
Evan Rosky4505b352018-09-06 11:20:40 -0700223import com.android.internal.os.logging.MetricsLoggerWrapper;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700224import com.android.internal.policy.IKeyguardDismissCallback;
225import com.android.internal.policy.KeyguardDismissCallback;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700226import com.android.internal.util.Preconditions;
Wale Ogunwale53783742018-09-16 10:21:51 -0700227import com.android.internal.util.function.pooled.PooledLambda;
Evan Rosky4505b352018-09-06 11:20:40 -0700228import com.android.server.AppOpsService;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700229import com.android.server.AttributeCache;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700230import com.android.server.LocalServices;
231import com.android.server.SystemService;
Evan Rosky4505b352018-09-06 11:20:40 -0700232import com.android.server.SystemServiceManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700233import com.android.server.Watchdog;
Evan Rosky4505b352018-09-06 11:20:40 -0700234import com.android.server.pm.UserManagerService;
235import com.android.server.uri.UriGrantsManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700236import com.android.server.vr.VrManagerInternal;
Evan Rosky4505b352018-09-06 11:20:40 -0700237import com.android.server.wm.ActivityTaskManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700238import com.android.server.wm.PinnedStackWindowController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700239import com.android.server.wm.WindowManagerService;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700240
241import java.io.File;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700242import java.io.FileOutputStream;
243import java.io.IOException;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700244import java.io.PrintWriter;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700245import java.io.StringWriter;
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700246import java.lang.ref.WeakReference;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700247import java.util.ArrayList;
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700248import java.util.HashSet;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700249import java.util.List;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700250import java.util.Locale;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700251
252/**
253 * System service for managing activities and their containers (task, stacks, displays,... ).
254 *
255 * {@hide}
256 */
257public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
258 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityTaskManagerService" : TAG_AM;
259 private static final String TAG_STACK = TAG + POSTFIX_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700260 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
261 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
262 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
263 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
264 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700265 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700266
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700267 // How long we wait until we timeout on key dispatching.
268 private static final int KEY_DISPATCHING_TIMEOUT_MS = 5 * 1000;
269 // How long we wait until we timeout on key dispatching during instrumentation.
270 private static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS = 60 * 1000;
271
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700272 Context mContext;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700273 /**
274 * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
275 * change at runtime. Use mContext for non-UI purposes.
276 */
277 final Context mUiContext;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700278 H mH;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700279 UiHandler mUiHandler;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700280 ActivityManagerService mAm;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700281 ActivityManagerInternal mAmInternal;
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700282 UriGrantsManagerInternal mUgmInternal;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700283 private PackageManagerInternal mPmInternal;
Wale Ogunwale53783742018-09-16 10:21:51 -0700284 private ActivityTaskManagerInternal mInternal;
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700285 PendingIntentController mPendingIntentController;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700286 /* Global service lock used by the package the owns this service. */
287 Object mGlobalLock;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700288 ActivityStackSupervisor mStackSupervisor;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700289 WindowManagerService mWindowManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700290 private UserManagerService mUserManager;
291 private AppOpsService mAppOpsService;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700292 /** All processes currently running that might have a window organized by name. */
293 final ProcessMap<WindowProcessController> mProcessNames = new ProcessMap<>();
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700294 /** All processes we currently have running mapped by pid */
295 final SparseArray<WindowProcessController> mPidMap = new SparseArray<>();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700296 /** This is the process holding what we currently consider to be the "home" activity. */
297 WindowProcessController mHomeProcess;
Wale Ogunwale53783742018-09-16 10:21:51 -0700298 /** The currently running heavy-weight process, if any. */
299 WindowProcessController mHeavyWeightProcess = null;
Wale Ogunwale214f3482018-10-04 11:00:47 -0700300 boolean mHasHeavyWeightFeature;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700301 /**
302 * This is the process holding the activity the user last visited that is in a different process
303 * from the one they are currently in.
304 */
305 WindowProcessController mPreviousProcess;
306 /** The time at which the previous process was last visible. */
307 long mPreviousProcessVisibleTime;
308
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700309 /** List of intents that were used to start the most recent tasks. */
310 private RecentTasks mRecentTasks;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700311 /** State of external calls telling us if the device is awake or asleep. */
312 private boolean mKeyguardShown = false;
313
314 // Wrapper around VoiceInteractionServiceManager
315 private AssistUtils mAssistUtils;
316
317 // VoiceInteraction session ID that changes for each new request except when
318 // being called for multi-window assist in a single session.
319 private int mViSessionId = 1000;
320
321 // How long to wait in getAssistContextExtras for the activity and foreground services
322 // to respond with the result.
323 private static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
324
325 // How long top wait when going through the modern assist (which doesn't need to block
326 // on getting this result before starting to launch its UI).
327 private static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
328
329 // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
330 private static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
331
332 private final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
333
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700334 // Keeps track of the active voice interaction service component, notified from
335 // VoiceInteractionManagerService
336 ComponentName mActiveVoiceInteractionServiceComponent;
337
338 private VrController mVrController;
339 KeyguardController mKeyguardController;
340 private final ClientLifecycleManager mLifecycleManager;
341 private TaskChangeNotificationController mTaskChangeNotificationController;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700342 /** The controller for all operations related to locktask. */
343 private LockTaskController mLockTaskController;
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700344 private ActivityStartController mActivityStartController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700345
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700346 boolean mSuppressResizeConfigChanges;
347
348 private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
349 new UpdateConfigurationResult();
350
351 static final class UpdateConfigurationResult {
352 // Configuration changes that were updated.
353 int changes;
354 // If the activity was relaunched to match the new configuration.
355 boolean activityRelaunched;
356
357 void reset() {
358 changes = 0;
359 activityRelaunched = false;
360 }
361 }
362
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700363 /** Current sequencing integer of the configuration, for skipping old configurations. */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700364 private int mConfigurationSeq;
365 // To cache the list of supported system locales
366 private String[] mSupportedSystemLocales = null;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700367
368 /**
369 * Temp object used when global and/or display override configuration is updated. It is also
370 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
371 * anyone...
372 */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700373 private Configuration mTempConfig = new Configuration();
374
Wale Ogunwalef6733932018-06-27 05:14:34 -0700375 /** Temporary to avoid allocations. */
376 final StringBuilder mStringBuilder = new StringBuilder(256);
377
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700378 // Amount of time after a call to stopAppSwitches() during which we will
379 // prevent further untrusted switches from happening.
380 private static final long APP_SWITCH_DELAY_TIME = 5 * 1000;
381
382 /**
383 * The time at which we will allow normal application switches again,
384 * after a call to {@link #stopAppSwitches()}.
385 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700386 private long mAppSwitchesAllowedTime;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700387 /**
388 * This is set to true after the first switch after mAppSwitchesAllowedTime
389 * is set; any switches after that will clear the time.
390 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700391 private boolean mDidAppSwitch;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700392
393 IActivityController mController = null;
394 boolean mControllerIsAMonkey = false;
395
Wale Ogunwale214f3482018-10-04 11:00:47 -0700396 final int mFactoryTest;
397
398 /** Used to control how we initialize the service. */
399 ComponentName mTopComponent;
400 String mTopAction = Intent.ACTION_MAIN;
401 String mTopData;
402
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700403 /**
404 * Used to retain an update lock when the foreground activity is in
405 * immersive mode.
406 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700407 private final UpdateLock mUpdateLock = new UpdateLock("immersive");
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700408
409 /**
410 * Packages that are being allowed to perform unrestricted app switches. Mapping is
411 * User -> Type -> uid.
412 */
413 final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
414
415 /** The dimensions of the thumbnails in the Recents UI. */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700416 private int mThumbnailWidth;
417 private int mThumbnailHeight;
418 private float mFullscreenThumbnailScale;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700419
420 /**
421 * Flag that indicates if multi-window is enabled.
422 *
423 * For any particular form of multi-window to be enabled, generic multi-window must be enabled
424 * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
425 * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
426 * At least one of the forms of multi-window must be enabled in order for this flag to be
427 * initialized to 'true'.
428 *
429 * @see #mSupportsSplitScreenMultiWindow
430 * @see #mSupportsFreeformWindowManagement
431 * @see #mSupportsPictureInPicture
432 * @see #mSupportsMultiDisplay
433 */
434 boolean mSupportsMultiWindow;
435 boolean mSupportsSplitScreenMultiWindow;
436 boolean mSupportsFreeformWindowManagement;
437 boolean mSupportsPictureInPicture;
438 boolean mSupportsMultiDisplay;
439 boolean mForceResizableActivities;
440
441 final List<ActivityTaskManagerInternal.ScreenObserver> mScreenObservers = new ArrayList<>();
442
443 // VR Vr2d Display Id.
444 int mVr2dDisplayId = INVALID_DISPLAY;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700445
Wale Ogunwalef6733932018-06-27 05:14:34 -0700446 /**
447 * Set while we are wanting to sleep, to prevent any
448 * activities from being started/resumed.
449 *
450 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
451 *
452 * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
453 * while in the sleep state until there is a pending transition out of sleep, in which case
454 * mSleeping is set to false, and remains false while awake.
455 *
456 * Whether mSleeping can quickly toggled between true/false without the device actually
457 * display changing states is undefined.
458 */
459 private boolean mSleeping = false;
460
461 /**
462 * The process state used for processes that are running the top activities.
463 * This changes between TOP and TOP_SLEEPING to following mSleeping.
464 */
465 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
466
467 // Whether we should show our dialogs (ANR, crash, etc) or just perform their default action
468 // automatically. Important for devices without direct input devices.
469 private boolean mShowDialogs = true;
470
471 /** Set if we are shutting down the system, similar to sleeping. */
472 boolean mShuttingDown = false;
473
474 /**
475 * We want to hold a wake lock while running a voice interaction session, since
476 * this may happen with the screen off and we need to keep the CPU running to
477 * be able to continue to interact with the user.
478 */
479 PowerManager.WakeLock mVoiceWakeLock;
480
481 /**
482 * Set while we are running a voice interaction. This overrides sleeping while it is active.
483 */
484 IVoiceInteractionSession mRunningVoice;
485
486 /**
487 * The last resumed activity. This is identical to the current resumed activity most
488 * of the time but could be different when we're pausing one activity before we resume
489 * another activity.
490 */
491 ActivityRecord mLastResumedActivity;
492
493 /**
494 * The activity that is currently being traced as the active resumed activity.
495 *
496 * @see #updateResumedAppTrace
497 */
498 private @Nullable ActivityRecord mTracedResumedActivity;
499
500 /** If non-null, we are tracking the time the user spends in the currently focused app. */
501 AppTimeTracker mCurAppTimeTracker;
502
Wale Ogunwale008163e2018-07-23 23:11:08 -0700503 private AppWarnings mAppWarnings;
504
Wale Ogunwale53783742018-09-16 10:21:51 -0700505 /**
506 * Packages that the user has asked to have run in screen size
507 * compatibility mode instead of filling the screen.
508 */
509 CompatModePackages mCompatModePackages;
510
Wale Ogunwalef6733932018-06-27 05:14:34 -0700511 private FontScaleSettingObserver mFontScaleSettingObserver;
512
513 private final class FontScaleSettingObserver extends ContentObserver {
514 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
515 private final Uri mHideErrorDialogsUri = Settings.Global.getUriFor(HIDE_ERROR_DIALOGS);
516
517 public FontScaleSettingObserver() {
518 super(mH);
519 final ContentResolver resolver = mContext.getContentResolver();
520 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
521 resolver.registerContentObserver(mHideErrorDialogsUri, false, this,
522 UserHandle.USER_ALL);
523 }
524
525 @Override
526 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
527 if (mFontScaleUri.equals(uri)) {
528 updateFontScaleIfNeeded(userId);
529 } else if (mHideErrorDialogsUri.equals(uri)) {
530 synchronized (mGlobalLock) {
531 updateShouldShowDialogsLocked(getGlobalConfiguration());
532 }
533 }
534 }
535 }
536
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700537 ActivityTaskManagerService(Context context) {
538 mContext = context;
Wale Ogunwale214f3482018-10-04 11:00:47 -0700539 mFactoryTest = FactoryTest.getMode();
Wale Ogunwalef6733932018-06-27 05:14:34 -0700540 mUiContext = ActivityThread.currentActivityThread().getSystemUiContext();
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700541 mLifecycleManager = new ClientLifecycleManager();
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700542 }
543
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700544 void onSystemReady() {
Wale Ogunwale214f3482018-10-04 11:00:47 -0700545 mHasHeavyWeightFeature = mContext.getPackageManager().hasSystemFeature(
546 PackageManager.FEATURE_CANT_SAVE_STATE);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700547 mAssistUtils = new AssistUtils(mContext);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700548 mVrController.onSystemReady();
549 mRecentTasks.onSystemReadyLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700550 }
551
Wale Ogunwalef6733932018-06-27 05:14:34 -0700552 void onInitPowerManagement() {
553 mStackSupervisor.initPowerManagement();
554 final PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
555 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
556 mVoiceWakeLock.setReferenceCounted(false);
557 }
558
559 void installSystemProviders() {
560 mFontScaleSettingObserver = new FontScaleSettingObserver();
561 }
562
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700563 void retrieveSettings(ContentResolver resolver) {
564 final boolean freeformWindowManagement =
565 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
566 || Settings.Global.getInt(
567 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
568
569 final boolean supportsMultiWindow = ActivityTaskManager.supportsMultiWindow(mContext);
570 final boolean supportsPictureInPicture = supportsMultiWindow &&
571 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
572 final boolean supportsSplitScreenMultiWindow =
573 ActivityTaskManager.supportsSplitScreenMultiWindow(mContext);
574 final boolean supportsMultiDisplay = mContext.getPackageManager()
575 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
576 final boolean alwaysFinishActivities =
577 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
578 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
579 final boolean forceResizable = Settings.Global.getInt(
580 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
Garfield Tane0846042018-07-26 13:42:04 -0700581 final boolean isPc = mContext.getPackageManager().hasSystemFeature(FEATURE_PC);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700582
583 // Transfer any global setting for forcing RTL layout, into a System Property
584 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
585
586 final Configuration configuration = new Configuration();
587 Settings.System.getConfiguration(resolver, configuration);
588 if (forceRtl) {
589 // This will take care of setting the correct layout direction flags
590 configuration.setLayoutDirection(configuration.locale);
591 }
592
593 synchronized (mGlobalLock) {
594 mForceResizableActivities = forceResizable;
595 final boolean multiWindowFormEnabled = freeformWindowManagement
596 || supportsSplitScreenMultiWindow
597 || supportsPictureInPicture
598 || supportsMultiDisplay;
599 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
600 mSupportsMultiWindow = true;
601 mSupportsFreeformWindowManagement = freeformWindowManagement;
602 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
603 mSupportsPictureInPicture = supportsPictureInPicture;
604 mSupportsMultiDisplay = supportsMultiDisplay;
605 } else {
606 mSupportsMultiWindow = false;
607 mSupportsFreeformWindowManagement = false;
608 mSupportsSplitScreenMultiWindow = false;
609 mSupportsPictureInPicture = false;
610 mSupportsMultiDisplay = false;
611 }
612 mWindowManager.setForceResizableTasks(mForceResizableActivities);
613 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
Garfield Tane0846042018-07-26 13:42:04 -0700614 mWindowManager.setSupportsFreeformWindowManagement(mSupportsFreeformWindowManagement);
615 mWindowManager.setIsPc(isPc);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700616 // This happens before any activities are started, so we can change global configuration
617 // in-place.
618 updateConfigurationLocked(configuration, null, true);
619 final Configuration globalConfig = getGlobalConfiguration();
620 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
621
622 // Load resources only after the current configuration has been set.
623 final Resources res = mContext.getResources();
624 mThumbnailWidth = res.getDimensionPixelSize(
625 com.android.internal.R.dimen.thumbnail_width);
626 mThumbnailHeight = res.getDimensionPixelSize(
627 com.android.internal.R.dimen.thumbnail_height);
628
629 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
630 mFullscreenThumbnailScale = (float) res
631 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
632 (float) globalConfig.screenWidthDp;
633 } else {
634 mFullscreenThumbnailScale = res.getFraction(
635 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
636 }
637 }
638 }
639
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700640 // TODO: Will be converted to WM lock once transition is complete.
641 void setActivityManagerService(ActivityManagerService am) {
642 mAm = am;
643 mGlobalLock = mAm;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700644 mH = new H(mAm.mHandlerThread.getLooper());
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700645 mUiHandler = new UiHandler();
Wale Ogunwale53783742018-09-16 10:21:51 -0700646 final File systemDir = SystemServiceManager.ensureSystemDir();
647 mAppWarnings = new AppWarnings(this, mUiContext, mH, mUiHandler, systemDir);
648 mCompatModePackages = new CompatModePackages(this, systemDir, mH);
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700649 mPendingIntentController = mAm.mPendingIntentController;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700650
651 mTempConfig.setToDefaults();
652 mTempConfig.setLocales(LocaleList.getDefault());
653 mConfigurationSeq = mTempConfig.seq = 1;
654 mStackSupervisor = createStackSupervisor();
655 mStackSupervisor.onConfigurationChanged(mTempConfig);
656
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700657 mTaskChangeNotificationController =
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700658 new TaskChangeNotificationController(mGlobalLock, mStackSupervisor, mH);
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700659 mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mH);
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700660 mActivityStartController = new ActivityStartController(this);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700661 mRecentTasks = createRecentTasks();
662 mStackSupervisor.setRecentTasks(mRecentTasks);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700663 mVrController = new VrController(mGlobalLock);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700664 mKeyguardController = mStackSupervisor.getKeyguardController();
665 }
666
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700667 void onActivityManagerInternalAdded() {
668 mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700669 mUgmInternal = LocalServices.getService(UriGrantsManagerInternal.class);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700670 }
671
Yunfan Chen75157d72018-07-27 14:47:21 +0900672 int increaseConfigurationSeqLocked() {
673 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
674 return mConfigurationSeq;
675 }
676
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700677 protected ActivityStackSupervisor createStackSupervisor() {
678 final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mH.getLooper());
679 supervisor.initialize();
680 return supervisor;
681 }
682
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700683 void setWindowManager(WindowManagerService wm) {
684 mWindowManager = wm;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700685 mLockTaskController.setWindowManager(wm);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700686 }
687
Wale Ogunwalef6733932018-06-27 05:14:34 -0700688 UserManagerService getUserManager() {
689 if (mUserManager == null) {
690 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
691 mUserManager = (UserManagerService) IUserManager.Stub.asInterface(b);
692 }
693 return mUserManager;
694 }
695
696 AppOpsService getAppOpsService() {
697 if (mAppOpsService == null) {
698 IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
699 mAppOpsService = (AppOpsService) IAppOpsService.Stub.asInterface(b);
700 }
701 return mAppOpsService;
702 }
703
704 boolean hasUserRestriction(String restriction, int userId) {
705 return getUserManager().hasUserRestriction(restriction, userId);
706 }
707
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700708 protected RecentTasks createRecentTasks() {
709 return new RecentTasks(this, mStackSupervisor);
710 }
711
712 RecentTasks getRecentTasks() {
713 return mRecentTasks;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700714 }
715
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700716 ClientLifecycleManager getLifecycleManager() {
717 return mLifecycleManager;
718 }
719
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700720 ActivityStartController getActivityStartController() {
721 return mActivityStartController;
722 }
723
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700724 TaskChangeNotificationController getTaskChangeNotificationController() {
725 return mTaskChangeNotificationController;
726 }
727
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700728 LockTaskController getLockTaskController() {
729 return mLockTaskController;
730 }
731
Yunfan Chen75157d72018-07-27 14:47:21 +0900732 /**
733 * Return the global configuration used by the process corresponding to the input pid. This is
734 * usually the global configuration with some overrides specific to that process.
735 */
736 Configuration getGlobalConfigurationForCallingPid() {
737 final int pid = Binder.getCallingPid();
738 if (pid == MY_PID || pid < 0) {
739 return getGlobalConfiguration();
740 }
741 synchronized (mGlobalLock) {
742 final WindowProcessController app = mPidMap.get(pid);
743 return app != null ? app.getConfiguration() : getGlobalConfiguration();
744 }
745 }
746
747 /**
748 * Return the device configuration info used by the process corresponding to the input pid.
749 * The value is consistent with the global configuration for the process.
750 */
751 @Override
752 public ConfigurationInfo getDeviceConfigurationInfo() {
753 ConfigurationInfo config = new ConfigurationInfo();
754 synchronized (mGlobalLock) {
755 final Configuration globalConfig = getGlobalConfigurationForCallingPid();
756 config.reqTouchScreen = globalConfig.touchscreen;
757 config.reqKeyboardType = globalConfig.keyboard;
758 config.reqNavigation = globalConfig.navigation;
759 if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
760 || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
761 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
762 }
763 if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
764 && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
765 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
766 }
767 config.reqGlEsVersion = mAm.GL_ES_VERSION;
768 }
769 return config;
770 }
771
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700772 private void start() {
Wale Ogunwale53783742018-09-16 10:21:51 -0700773 mInternal = new LocalService();
774 LocalServices.addService(ActivityTaskManagerInternal.class, mInternal);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700775 }
776
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700777 public static final class Lifecycle extends SystemService {
778 private final ActivityTaskManagerService mService;
779
780 public Lifecycle(Context context) {
781 super(context);
782 mService = new ActivityTaskManagerService(context);
783 }
784
785 @Override
786 public void onStart() {
787 publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700788 mService.start();
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700789 }
790
791 public ActivityTaskManagerService getService() {
792 return mService;
793 }
794 }
795
796 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700797 public final int startActivity(IApplicationThread caller, String callingPackage,
798 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
799 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
800 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
801 resultWho, requestCode, startFlags, profilerInfo, bOptions,
802 UserHandle.getCallingUserId());
803 }
804
805 @Override
806 public final int startActivities(IApplicationThread caller, String callingPackage,
807 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
808 int userId) {
809 final String reason = "startActivities";
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700810 enforceNotIsolatedCaller(reason);
811 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, reason);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700812 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700813 return getActivityStartController().startActivities(caller, -1, callingPackage, intents,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100814 resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId, reason,
815 null /* originatingPendingIntent */);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700816 }
817
818 @Override
819 public int startActivityAsUser(IApplicationThread caller, String callingPackage,
820 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
821 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
822 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
823 resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
824 true /*validateIncomingUser*/);
825 }
826
827 int startActivityAsUser(IApplicationThread caller, String callingPackage,
828 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
829 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
830 boolean validateIncomingUser) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700831 enforceNotIsolatedCaller("startActivityAsUser");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700832
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700833 userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700834 Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
835
836 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700837 return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700838 .setCaller(caller)
839 .setCallingPackage(callingPackage)
840 .setResolvedType(resolvedType)
841 .setResultTo(resultTo)
842 .setResultWho(resultWho)
843 .setRequestCode(requestCode)
844 .setStartFlags(startFlags)
845 .setProfilerInfo(profilerInfo)
846 .setActivityOptions(bOptions)
847 .setMayWait(userId)
848 .execute();
849
850 }
851
852 @Override
853 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
854 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700855 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions) {
856 enforceNotIsolatedCaller("startActivityIntentSender");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700857 // Refuse possible leaked file descriptors
858 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
859 throw new IllegalArgumentException("File descriptors passed in Intent");
860 }
861
862 if (!(target instanceof PendingIntentRecord)) {
863 throw new IllegalArgumentException("Bad PendingIntent object");
864 }
865
866 PendingIntentRecord pir = (PendingIntentRecord)target;
867
868 synchronized (mGlobalLock) {
869 // If this is coming from the currently resumed activity, it is
870 // effectively saying that app switches are allowed at this point.
Andrii Kulian5f750bc2018-07-17 08:57:23 -0700871 final ActivityStack stack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700872 if (stack.mResumedActivity != null &&
873 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700874 mAppSwitchesAllowedTime = 0;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700875 }
876 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700877 return pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700878 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700879 }
880
881 @Override
882 public boolean startNextMatchingActivity(IBinder callingActivity, Intent intent,
883 Bundle bOptions) {
884 // Refuse possible leaked file descriptors
885 if (intent != null && intent.hasFileDescriptors()) {
886 throw new IllegalArgumentException("File descriptors passed in Intent");
887 }
888 SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
889
890 synchronized (mGlobalLock) {
891 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
892 if (r == null) {
893 SafeActivityOptions.abort(options);
894 return false;
895 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700896 if (!r.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700897 // The caller is not running... d'oh!
898 SafeActivityOptions.abort(options);
899 return false;
900 }
901 intent = new Intent(intent);
902 // The caller is not allowed to change the data.
903 intent.setDataAndType(r.intent.getData(), r.intent.getType());
904 // And we are resetting to find the next component...
905 intent.setComponent(null);
906
907 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
908
909 ActivityInfo aInfo = null;
910 try {
911 List<ResolveInfo> resolves =
912 AppGlobals.getPackageManager().queryIntentActivities(
913 intent, r.resolvedType,
914 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
915 UserHandle.getCallingUserId()).getList();
916
917 // Look for the original activity in the list...
918 final int N = resolves != null ? resolves.size() : 0;
919 for (int i=0; i<N; i++) {
920 ResolveInfo rInfo = resolves.get(i);
921 if (rInfo.activityInfo.packageName.equals(r.packageName)
922 && rInfo.activityInfo.name.equals(r.info.name)) {
923 // We found the current one... the next matching is
924 // after it.
925 i++;
926 if (i<N) {
927 aInfo = resolves.get(i).activityInfo;
928 }
929 if (debug) {
930 Slog.v(TAG, "Next matching activity: found current " + r.packageName
931 + "/" + r.info.name);
932 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
933 ? "null" : aInfo.packageName + "/" + aInfo.name));
934 }
935 break;
936 }
937 }
938 } catch (RemoteException e) {
939 }
940
941 if (aInfo == null) {
942 // Nobody who is next!
943 SafeActivityOptions.abort(options);
944 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
945 return false;
946 }
947
948 intent.setComponent(new ComponentName(
949 aInfo.applicationInfo.packageName, aInfo.name));
950 intent.setFlags(intent.getFlags()&~(
951 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
952 Intent.FLAG_ACTIVITY_CLEAR_TOP|
953 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
954 FLAG_ACTIVITY_NEW_TASK));
955
956 // Okay now we need to start the new activity, replacing the currently running activity.
957 // This is a little tricky because we want to start the new one as if the current one is
958 // finished, but not finish the current one first so that there is no flicker.
959 // And thus...
960 final boolean wasFinishing = r.finishing;
961 r.finishing = true;
962
963 // Propagate reply information over to the new activity.
964 final ActivityRecord resultTo = r.resultTo;
965 final String resultWho = r.resultWho;
966 final int requestCode = r.requestCode;
967 r.resultTo = null;
968 if (resultTo != null) {
969 resultTo.removeResultsLocked(r, resultWho, requestCode);
970 }
971
972 final long origId = Binder.clearCallingIdentity();
973 // TODO(b/64750076): Check if calling pid should really be -1.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700974 final int res = getActivityStartController()
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700975 .obtainStarter(intent, "startNextMatchingActivity")
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700976 .setCaller(r.app.getThread())
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700977 .setResolvedType(r.resolvedType)
978 .setActivityInfo(aInfo)
979 .setResultTo(resultTo != null ? resultTo.appToken : null)
980 .setResultWho(resultWho)
981 .setRequestCode(requestCode)
982 .setCallingPid(-1)
983 .setCallingUid(r.launchedFromUid)
984 .setCallingPackage(r.launchedFromPackage)
985 .setRealCallingPid(-1)
986 .setRealCallingUid(r.launchedFromUid)
987 .setActivityOptions(options)
988 .execute();
989 Binder.restoreCallingIdentity(origId);
990
991 r.finishing = wasFinishing;
992 if (res != ActivityManager.START_SUCCESS) {
993 return false;
994 }
995 return true;
996 }
997 }
998
999 @Override
1000 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
1001 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1002 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
1003 final WaitResult res = new WaitResult();
1004 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001005 enforceNotIsolatedCaller("startActivityAndWait");
1006 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
1007 userId, "startActivityAndWait");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001008 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001009 getActivityStartController().obtainStarter(intent, "startActivityAndWait")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001010 .setCaller(caller)
1011 .setCallingPackage(callingPackage)
1012 .setResolvedType(resolvedType)
1013 .setResultTo(resultTo)
1014 .setResultWho(resultWho)
1015 .setRequestCode(requestCode)
1016 .setStartFlags(startFlags)
1017 .setActivityOptions(bOptions)
1018 .setMayWait(userId)
1019 .setProfilerInfo(profilerInfo)
1020 .setWaitResult(res)
1021 .execute();
1022 }
1023 return res;
1024 }
1025
1026 @Override
1027 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
1028 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1029 int startFlags, Configuration config, Bundle bOptions, int userId) {
1030 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001031 enforceNotIsolatedCaller("startActivityWithConfig");
1032 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
1033 "startActivityWithConfig");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001034 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001035 return getActivityStartController().obtainStarter(intent, "startActivityWithConfig")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001036 .setCaller(caller)
1037 .setCallingPackage(callingPackage)
1038 .setResolvedType(resolvedType)
1039 .setResultTo(resultTo)
1040 .setResultWho(resultWho)
1041 .setRequestCode(requestCode)
1042 .setStartFlags(startFlags)
1043 .setGlobalConfiguration(config)
1044 .setActivityOptions(bOptions)
1045 .setMayWait(userId)
1046 .execute();
1047 }
1048 }
1049
1050 @Override
1051 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
1052 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1053 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
1054 int userId) {
1055
1056 // This is very dangerous -- it allows you to perform a start activity (including
1057 // permission grants) as any app that may launch one of your own activities. So
1058 // we will only allow this to be done from activities that are part of the core framework,
1059 // and then only when they are running as the system.
1060 final ActivityRecord sourceRecord;
1061 final int targetUid;
1062 final String targetPackage;
1063 final boolean isResolver;
1064 synchronized (mGlobalLock) {
1065 if (resultTo == null) {
1066 throw new SecurityException("Must be called from an activity");
1067 }
1068 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
1069 if (sourceRecord == null) {
1070 throw new SecurityException("Called with bad activity token: " + resultTo);
1071 }
1072 if (!sourceRecord.info.packageName.equals("android")) {
1073 throw new SecurityException(
1074 "Must be called from an activity that is declared in the android package");
1075 }
1076 if (sourceRecord.app == null) {
1077 throw new SecurityException("Called without a process attached to activity");
1078 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001079 if (UserHandle.getAppId(sourceRecord.app.mUid) != SYSTEM_UID) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001080 // This is still okay, as long as this activity is running under the
1081 // uid of the original calling activity.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001082 if (sourceRecord.app.mUid != sourceRecord.launchedFromUid) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001083 throw new SecurityException(
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001084 "Calling activity in uid " + sourceRecord.app.mUid
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001085 + " must be system uid or original calling uid "
1086 + sourceRecord.launchedFromUid);
1087 }
1088 }
1089 if (ignoreTargetSecurity) {
1090 if (intent.getComponent() == null) {
1091 throw new SecurityException(
1092 "Component must be specified with ignoreTargetSecurity");
1093 }
1094 if (intent.getSelector() != null) {
1095 throw new SecurityException(
1096 "Selector not allowed with ignoreTargetSecurity");
1097 }
1098 }
1099 targetUid = sourceRecord.launchedFromUid;
1100 targetPackage = sourceRecord.launchedFromPackage;
1101 isResolver = sourceRecord.isResolverOrChildActivity();
1102 }
1103
1104 if (userId == UserHandle.USER_NULL) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001105 userId = UserHandle.getUserId(sourceRecord.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001106 }
1107
1108 // TODO: Switch to user app stacks here.
1109 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001110 return getActivityStartController().obtainStarter(intent, "startActivityAsCaller")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001111 .setCallingUid(targetUid)
1112 .setCallingPackage(targetPackage)
1113 .setResolvedType(resolvedType)
1114 .setResultTo(resultTo)
1115 .setResultWho(resultWho)
1116 .setRequestCode(requestCode)
1117 .setStartFlags(startFlags)
1118 .setActivityOptions(bOptions)
1119 .setMayWait(userId)
1120 .setIgnoreTargetSecurity(ignoreTargetSecurity)
1121 .setFilterCallingUid(isResolver ? 0 /* system */ : targetUid)
1122 .execute();
1123 } catch (SecurityException e) {
1124 // XXX need to figure out how to propagate to original app.
1125 // A SecurityException here is generally actually a fault of the original
1126 // calling activity (such as a fairly granting permissions), so propagate it
1127 // back to them.
1128 /*
1129 StringBuilder msg = new StringBuilder();
1130 msg.append("While launching");
1131 msg.append(intent.toString());
1132 msg.append(": ");
1133 msg.append(e.getMessage());
1134 */
1135 throw e;
1136 }
1137 }
1138
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001139 int handleIncomingUser(int callingPid, int callingUid, int userId, String name) {
1140 return mAmInternal.handleIncomingUser(callingPid, callingUid, userId, false /* allowAll */,
1141 ALLOW_FULL_ONLY, name, null /* callerPackage */);
1142 }
1143
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001144 @Override
1145 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
1146 Intent intent, String resolvedType, IVoiceInteractionSession session,
1147 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
1148 Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001149 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001150 if (session == null || interactor == null) {
1151 throw new NullPointerException("null session or interactor");
1152 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001153 userId = handleIncomingUser(callingPid, callingUid, userId, "startVoiceActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001154 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001155 return getActivityStartController().obtainStarter(intent, "startVoiceActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001156 .setCallingUid(callingUid)
1157 .setCallingPackage(callingPackage)
1158 .setResolvedType(resolvedType)
1159 .setVoiceSession(session)
1160 .setVoiceInteractor(interactor)
1161 .setStartFlags(startFlags)
1162 .setProfilerInfo(profilerInfo)
1163 .setActivityOptions(bOptions)
1164 .setMayWait(userId)
1165 .execute();
1166 }
1167
1168 @Override
1169 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
1170 Intent intent, String resolvedType, Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001171 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
1172 userId = handleIncomingUser(callingPid, callingUid, userId, "startAssistantActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001173
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001174 return getActivityStartController().obtainStarter(intent, "startAssistantActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001175 .setCallingUid(callingUid)
1176 .setCallingPackage(callingPackage)
1177 .setResolvedType(resolvedType)
1178 .setActivityOptions(bOptions)
1179 .setMayWait(userId)
1180 .execute();
1181 }
1182
1183 @Override
1184 public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
1185 IRecentsAnimationRunner recentsAnimationRunner) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001186 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001187 final int callingPid = Binder.getCallingPid();
1188 final long origId = Binder.clearCallingIdentity();
1189 try {
1190 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07001191 final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
1192 final int recentsUid = mRecentTasks.getRecentsComponentUid();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001193
1194 // Start a new recents animation
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001195 final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
1196 getActivityStartController(), mWindowManager, callingPid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001197 anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
1198 recentsUid, assistDataReceiver);
1199 }
1200 } finally {
1201 Binder.restoreCallingIdentity(origId);
1202 }
1203 }
1204
1205 @Override
1206 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001207 enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001208 "startActivityFromRecents()");
1209
1210 final int callingPid = Binder.getCallingPid();
1211 final int callingUid = Binder.getCallingUid();
1212 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(bOptions);
1213 final long origId = Binder.clearCallingIdentity();
1214 try {
1215 synchronized (mGlobalLock) {
1216 return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
1217 safeOptions);
1218 }
1219 } finally {
1220 Binder.restoreCallingIdentity(origId);
1221 }
1222 }
1223
1224 /**
1225 * This is the internal entry point for handling Activity.finish().
1226 *
1227 * @param token The Binder token referencing the Activity we want to finish.
1228 * @param resultCode Result code, if any, from this Activity.
1229 * @param resultData Result data (Intent), if any, from this Activity.
1230 * @param finishTask Whether to finish the task associated with this Activity.
1231 *
1232 * @return Returns true if the activity successfully finished, or false if it is still running.
1233 */
1234 @Override
1235 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
1236 int finishTask) {
1237 // Refuse possible leaked file descriptors
1238 if (resultData != null && resultData.hasFileDescriptors()) {
1239 throw new IllegalArgumentException("File descriptors passed in Intent");
1240 }
1241
1242 synchronized (mGlobalLock) {
1243 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1244 if (r == null) {
1245 return true;
1246 }
1247 // Keep track of the root activity of the task before we finish it
1248 TaskRecord tr = r.getTask();
1249 ActivityRecord rootR = tr.getRootActivity();
1250 if (rootR == null) {
1251 Slog.w(TAG, "Finishing task with all activities already finished");
1252 }
1253 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
1254 // finish.
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001255 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001256 return false;
1257 }
1258
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001259 // TODO: There is a dup. of this block of code in ActivityStack.navigateUpToLocked
1260 // We should consolidate.
1261 if (mController != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001262 // Find the first activity that is not finishing.
1263 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
1264 if (next != null) {
1265 // ask watcher if this is allowed
1266 boolean resumeOK = true;
1267 try {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001268 resumeOK = mController.activityResuming(next.packageName);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001269 } catch (RemoteException e) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001270 mController = null;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001271 Watchdog.getInstance().setActivityController(null);
1272 }
1273
1274 if (!resumeOK) {
1275 Slog.i(TAG, "Not finishing activity because controller resumed");
1276 return false;
1277 }
1278 }
1279 }
1280 final long origId = Binder.clearCallingIdentity();
1281 try {
1282 boolean res;
1283 final boolean finishWithRootActivity =
1284 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
1285 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
1286 || (finishWithRootActivity && r == rootR)) {
1287 // If requested, remove the task that is associated to this activity only if it
1288 // was the root activity in the task. The result code and data is ignored
1289 // because we don't support returning them across task boundaries. Also, to
1290 // keep backwards compatibility we remove the task from recents when finishing
1291 // task with root activity.
1292 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
1293 finishWithRootActivity, "finish-activity");
1294 if (!res) {
1295 Slog.i(TAG, "Removing task failed to finish activity");
1296 }
Garfield Tan2746ab52018-07-25 12:33:01 -07001297 // Explicitly dismissing the activity so reset its relaunch flag.
1298 r.mRelaunchReason = ActivityRecord.RELAUNCH_REASON_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001299 } else {
1300 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
1301 resultData, "app-request", true);
1302 if (!res) {
1303 Slog.i(TAG, "Failed to finish by app-request");
1304 }
1305 }
1306 return res;
1307 } finally {
1308 Binder.restoreCallingIdentity(origId);
1309 }
1310 }
1311 }
1312
1313 @Override
1314 public boolean finishActivityAffinity(IBinder token) {
1315 synchronized (mGlobalLock) {
1316 final long origId = Binder.clearCallingIdentity();
1317 try {
1318 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1319 if (r == null) {
1320 return false;
1321 }
1322
1323 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
1324 // can finish.
1325 final TaskRecord task = r.getTask();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001326 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001327 return false;
1328 }
1329 return task.getStack().finishActivityAffinityLocked(r);
1330 } finally {
1331 Binder.restoreCallingIdentity(origId);
1332 }
1333 }
1334 }
1335
1336 @Override
1337 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
1338 final long origId = Binder.clearCallingIdentity();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001339 try {
1340 WindowProcessController proc = null;
1341 synchronized (mGlobalLock) {
1342 ActivityStack stack = ActivityRecord.getStackLocked(token);
1343 if (stack == null) {
1344 return;
1345 }
1346 final ActivityRecord r = mStackSupervisor.activityIdleInternalLocked(token,
1347 false /* fromTimeout */, false /* processPausingActivities */, config);
1348 if (r != null) {
1349 proc = r.app;
1350 }
1351 if (stopProfiling && proc != null) {
1352 proc.clearProfilerIfNeeded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001353 }
1354 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001355 } finally {
1356 Binder.restoreCallingIdentity(origId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001357 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001358 }
1359
1360 @Override
1361 public final void activityResumed(IBinder token) {
1362 final long origId = Binder.clearCallingIdentity();
1363 synchronized (mGlobalLock) {
1364 ActivityRecord.activityResumedLocked(token);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001365 mWindowManager.notifyAppResumedFinished(token);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001366 }
1367 Binder.restoreCallingIdentity(origId);
1368 }
1369
1370 @Override
1371 public final void activityPaused(IBinder token) {
1372 final long origId = Binder.clearCallingIdentity();
1373 synchronized (mGlobalLock) {
1374 ActivityStack stack = ActivityRecord.getStackLocked(token);
1375 if (stack != null) {
1376 stack.activityPausedLocked(token, false);
1377 }
1378 }
1379 Binder.restoreCallingIdentity(origId);
1380 }
1381
1382 @Override
1383 public final void activityStopped(IBinder token, Bundle icicle,
1384 PersistableBundle persistentState, CharSequence description) {
1385 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
1386
1387 // Refuse possible leaked file descriptors
1388 if (icicle != null && icicle.hasFileDescriptors()) {
1389 throw new IllegalArgumentException("File descriptors passed in Bundle");
1390 }
1391
1392 final long origId = Binder.clearCallingIdentity();
1393
1394 synchronized (mGlobalLock) {
1395 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1396 if (r != null) {
1397 r.activityStoppedLocked(icicle, persistentState, description);
1398 }
1399 }
1400
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001401 mAmInternal.trimApplications();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001402
1403 Binder.restoreCallingIdentity(origId);
1404 }
1405
1406 @Override
1407 public final void activityDestroyed(IBinder token) {
1408 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
1409 synchronized (mGlobalLock) {
1410 ActivityStack stack = ActivityRecord.getStackLocked(token);
1411 if (stack != null) {
1412 stack.activityDestroyedLocked(token, "activityDestroyed");
1413 }
1414 }
1415 }
1416
1417 @Override
1418 public final void activityRelaunched(IBinder token) {
1419 final long origId = Binder.clearCallingIdentity();
1420 synchronized (mGlobalLock) {
1421 mStackSupervisor.activityRelaunchedLocked(token);
1422 }
1423 Binder.restoreCallingIdentity(origId);
1424 }
1425
1426 public final void activitySlept(IBinder token) {
1427 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
1428
1429 final long origId = Binder.clearCallingIdentity();
1430
1431 synchronized (mGlobalLock) {
1432 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1433 if (r != null) {
1434 mStackSupervisor.activitySleptLocked(r);
1435 }
1436 }
1437
1438 Binder.restoreCallingIdentity(origId);
1439 }
1440
1441 @Override
1442 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
1443 synchronized (mGlobalLock) {
1444 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1445 if (r == null) {
1446 return;
1447 }
1448 final long origId = Binder.clearCallingIdentity();
1449 try {
1450 r.setRequestedOrientation(requestedOrientation);
1451 } finally {
1452 Binder.restoreCallingIdentity(origId);
1453 }
1454 }
1455 }
1456
1457 @Override
1458 public int getRequestedOrientation(IBinder token) {
1459 synchronized (mGlobalLock) {
1460 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1461 if (r == null) {
1462 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
1463 }
1464 return r.getRequestedOrientation();
1465 }
1466 }
1467
1468 @Override
1469 public void setImmersive(IBinder token, boolean immersive) {
1470 synchronized (mGlobalLock) {
1471 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1472 if (r == null) {
1473 throw new IllegalArgumentException();
1474 }
1475 r.immersive = immersive;
1476
1477 // update associated state if we're frontmost
Andrii Kulian52d255c2018-07-13 11:32:19 -07001478 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001479 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001480 applyUpdateLockStateLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001481 }
1482 }
1483 }
1484
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001485 void applyUpdateLockStateLocked(ActivityRecord r) {
1486 // Modifications to the UpdateLock state are done on our handler, outside
1487 // the activity manager's locks. The new state is determined based on the
1488 // state *now* of the relevant activity record. The object is passed to
1489 // the handler solely for logging detail, not to be consulted/modified.
1490 final boolean nextState = r != null && r.immersive;
1491 mH.post(() -> {
1492 if (mUpdateLock.isHeld() != nextState) {
1493 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1494 "Applying new update lock state '" + nextState + "' for " + r);
1495 if (nextState) {
1496 mUpdateLock.acquire();
1497 } else {
1498 mUpdateLock.release();
1499 }
1500 }
1501 });
1502 }
1503
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001504 @Override
1505 public boolean isImmersive(IBinder token) {
1506 synchronized (mGlobalLock) {
1507 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1508 if (r == null) {
1509 throw new IllegalArgumentException();
1510 }
1511 return r.immersive;
1512 }
1513 }
1514
1515 @Override
1516 public boolean isTopActivityImmersive() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001517 enforceNotIsolatedCaller("isTopActivityImmersive");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001518 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001519 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001520 return (r != null) ? r.immersive : false;
1521 }
1522 }
1523
1524 @Override
1525 public void overridePendingTransition(IBinder token, String packageName,
1526 int enterAnim, int exitAnim) {
1527 synchronized (mGlobalLock) {
1528 ActivityRecord self = ActivityRecord.isInStackLocked(token);
1529 if (self == null) {
1530 return;
1531 }
1532
1533 final long origId = Binder.clearCallingIdentity();
1534
1535 if (self.isState(
1536 ActivityStack.ActivityState.RESUMED, ActivityStack.ActivityState.PAUSING)) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001537 mWindowManager.overridePendingAppTransition(packageName,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001538 enterAnim, exitAnim, null);
1539 }
1540
1541 Binder.restoreCallingIdentity(origId);
1542 }
1543 }
1544
1545 @Override
1546 public int getFrontActivityScreenCompatMode() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001547 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001548 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001549 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001550 if (r == null) {
1551 return ActivityManager.COMPAT_MODE_UNKNOWN;
1552 }
Wale Ogunwale53783742018-09-16 10:21:51 -07001553 return mCompatModePackages.computeCompatModeLocked(r.info.applicationInfo);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001554 }
1555 }
1556
1557 @Override
1558 public void setFrontActivityScreenCompatMode(int mode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001559 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001560 "setFrontActivityScreenCompatMode");
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001561 ApplicationInfo ai;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001562 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001563 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001564 if (r == null) {
1565 Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity");
1566 return;
1567 }
1568 ai = r.info.applicationInfo;
Wale Ogunwale53783742018-09-16 10:21:51 -07001569 mCompatModePackages.setPackageScreenCompatModeLocked(ai, mode);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001570 }
1571 }
1572
1573 @Override
1574 public int getLaunchedFromUid(IBinder activityToken) {
1575 ActivityRecord srec;
1576 synchronized (mGlobalLock) {
1577 srec = ActivityRecord.forTokenLocked(activityToken);
1578 }
1579 if (srec == null) {
1580 return -1;
1581 }
1582 return srec.launchedFromUid;
1583 }
1584
1585 @Override
1586 public String getLaunchedFromPackage(IBinder activityToken) {
1587 ActivityRecord srec;
1588 synchronized (mGlobalLock) {
1589 srec = ActivityRecord.forTokenLocked(activityToken);
1590 }
1591 if (srec == null) {
1592 return null;
1593 }
1594 return srec.launchedFromPackage;
1595 }
1596
1597 @Override
1598 public boolean convertFromTranslucent(IBinder token) {
1599 final long origId = Binder.clearCallingIdentity();
1600 try {
1601 synchronized (mGlobalLock) {
1602 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1603 if (r == null) {
1604 return false;
1605 }
1606 final boolean translucentChanged = r.changeWindowTranslucency(true);
1607 if (translucentChanged) {
1608 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
1609 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001610 mWindowManager.setAppFullscreen(token, true);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001611 return translucentChanged;
1612 }
1613 } finally {
1614 Binder.restoreCallingIdentity(origId);
1615 }
1616 }
1617
1618 @Override
1619 public boolean convertToTranslucent(IBinder token, Bundle options) {
1620 SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
1621 final long origId = Binder.clearCallingIdentity();
1622 try {
1623 synchronized (mGlobalLock) {
1624 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1625 if (r == null) {
1626 return false;
1627 }
1628 final TaskRecord task = r.getTask();
1629 int index = task.mActivities.lastIndexOf(r);
1630 if (index > 0) {
1631 ActivityRecord under = task.mActivities.get(index - 1);
1632 under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
1633 }
1634 final boolean translucentChanged = r.changeWindowTranslucency(false);
1635 if (translucentChanged) {
1636 r.getStack().convertActivityToTranslucent(r);
1637 }
1638 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001639 mWindowManager.setAppFullscreen(token, false);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001640 return translucentChanged;
1641 }
1642 } finally {
1643 Binder.restoreCallingIdentity(origId);
1644 }
1645 }
1646
1647 @Override
1648 public void notifyActivityDrawn(IBinder token) {
1649 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
1650 synchronized (mGlobalLock) {
1651 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
1652 if (r != null) {
1653 r.getStack().notifyActivityDrawnLocked(r);
1654 }
1655 }
1656 }
1657
1658 @Override
1659 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
1660 synchronized (mGlobalLock) {
1661 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1662 if (r == null) {
1663 return;
1664 }
1665 r.reportFullyDrawnLocked(restoredFromBundle);
1666 }
1667 }
1668
1669 @Override
1670 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
1671 synchronized (mGlobalLock) {
1672 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
1673 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
1674 return stack.mDisplayId;
1675 }
1676 return DEFAULT_DISPLAY;
1677 }
1678 }
1679
1680 @Override
1681 public ActivityManager.StackInfo getFocusedStackInfo() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001682 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001683 long ident = Binder.clearCallingIdentity();
1684 try {
1685 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001686 ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001687 if (focusedStack != null) {
1688 return mStackSupervisor.getStackInfo(focusedStack.mStackId);
1689 }
1690 return null;
1691 }
1692 } finally {
1693 Binder.restoreCallingIdentity(ident);
1694 }
1695 }
1696
1697 @Override
1698 public void setFocusedStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001699 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001700 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
1701 final long callingId = Binder.clearCallingIdentity();
1702 try {
1703 synchronized (mGlobalLock) {
1704 final ActivityStack stack = mStackSupervisor.getStack(stackId);
1705 if (stack == null) {
1706 Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
1707 return;
1708 }
1709 final ActivityRecord r = stack.topRunningActivityLocked();
Louis Chang19443452018-10-09 12:10:21 +08001710 if (r != null && r.moveFocusableActivityToTop("setFocusedStack")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08001711 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001712 }
1713 }
1714 } finally {
1715 Binder.restoreCallingIdentity(callingId);
1716 }
1717 }
1718
1719 @Override
1720 public void setFocusedTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001721 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001722 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
1723 final long callingId = Binder.clearCallingIdentity();
1724 try {
1725 synchronized (mGlobalLock) {
1726 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1727 if (task == null) {
1728 return;
1729 }
1730 final ActivityRecord r = task.topRunningActivityLocked();
Louis Chang19443452018-10-09 12:10:21 +08001731 if (r != null && r.moveFocusableActivityToTop("setFocusedTask")) {
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 boolean removeTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001742 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001743 synchronized (mGlobalLock) {
1744 final long ident = Binder.clearCallingIdentity();
1745 try {
1746 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
1747 "remove-task");
1748 } finally {
1749 Binder.restoreCallingIdentity(ident);
1750 }
1751 }
1752 }
1753
1754 @Override
Winson Chunge6439102018-07-30 15:48:01 -07001755 public void removeAllVisibleRecentTasks() {
1756 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeAllVisibleRecentTasks()");
1757 synchronized (mGlobalLock) {
1758 final long ident = Binder.clearCallingIdentity();
1759 try {
1760 getRecentTasks().removeAllVisibleTasks();
1761 } finally {
1762 Binder.restoreCallingIdentity(ident);
1763 }
1764 }
1765 }
1766
1767 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001768 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
1769 synchronized (mGlobalLock) {
1770 final ActivityRecord srec = ActivityRecord.forTokenLocked(token);
1771 if (srec != null) {
1772 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
1773 }
1774 }
1775 return false;
1776 }
1777
1778 @Override
1779 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
1780 Intent resultData) {
1781
1782 synchronized (mGlobalLock) {
1783 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
1784 if (r != null) {
1785 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
1786 }
1787 return false;
1788 }
1789 }
1790
1791 /**
1792 * Attempts to move a task backwards in z-order (the order of activities within the task is
1793 * unchanged).
1794 *
1795 * There are several possible results of this call:
1796 * - if the task is locked, then we will show the lock toast
1797 * - if there is a task behind the provided task, then that task is made visible and resumed as
1798 * this task is moved to the back
1799 * - otherwise, if there are no other tasks in the stack:
1800 * - if this task is in the pinned stack, then we remove the stack completely, which will
1801 * have the effect of moving the task to the top or bottom of the fullscreen stack
1802 * (depending on whether it is visible)
1803 * - otherwise, we simply return home and hide this task
1804 *
1805 * @param token A reference to the activity we wish to move
1806 * @param nonRoot If false then this only works if the activity is the root
1807 * of a task; if true it will work for any activity in a task.
1808 * @return Returns true if the move completed, false if not.
1809 */
1810 @Override
1811 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001812 enforceNotIsolatedCaller("moveActivityTaskToBack");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001813 synchronized (mGlobalLock) {
1814 final long origId = Binder.clearCallingIdentity();
1815 try {
1816 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
1817 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1818 if (task != null) {
1819 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
1820 }
1821 } finally {
1822 Binder.restoreCallingIdentity(origId);
1823 }
1824 }
1825 return false;
1826 }
1827
1828 @Override
1829 public Rect getTaskBounds(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001830 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001831 long ident = Binder.clearCallingIdentity();
1832 Rect rect = new Rect();
1833 try {
1834 synchronized (mGlobalLock) {
1835 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
1836 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1837 if (task == null) {
1838 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
1839 return rect;
1840 }
1841 if (task.getStack() != null) {
1842 // Return the bounds from window manager since it will be adjusted for various
1843 // things like the presense of a docked stack for tasks that aren't resizeable.
1844 task.getWindowContainerBounds(rect);
1845 } else {
1846 // Task isn't in window manager yet since it isn't associated with a stack.
1847 // Return the persist value from activity manager
1848 if (!task.matchParentBounds()) {
1849 rect.set(task.getBounds());
1850 } else if (task.mLastNonFullscreenBounds != null) {
1851 rect.set(task.mLastNonFullscreenBounds);
1852 }
1853 }
1854 }
1855 } finally {
1856 Binder.restoreCallingIdentity(ident);
1857 }
1858 return rect;
1859 }
1860
1861 @Override
1862 public ActivityManager.TaskDescription getTaskDescription(int id) {
1863 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001864 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001865 MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
1866 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
1867 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1868 if (tr != null) {
1869 return tr.lastTaskDescription;
1870 }
1871 }
1872 return null;
1873 }
1874
1875 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001876 public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
1877 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
1878 setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
1879 toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
1880 return;
1881 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001882 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001883 synchronized (mGlobalLock) {
1884 final long ident = Binder.clearCallingIdentity();
1885 try {
1886 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1887 if (task == null) {
1888 Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
1889 return;
1890 }
1891
1892 if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
1893 + " to windowingMode=" + windowingMode + " toTop=" + toTop);
1894
1895 if (!task.isActivityTypeStandardOrUndefined()) {
1896 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
1897 + " non-standard task " + taskId + " to windowing mode="
1898 + windowingMode);
1899 }
1900
1901 final ActivityStack stack = task.getStack();
1902 if (toTop) {
1903 stack.moveToFront("setTaskWindowingMode", task);
1904 }
1905 stack.setWindowingMode(windowingMode);
1906 } finally {
1907 Binder.restoreCallingIdentity(ident);
1908 }
1909 }
1910 }
1911
1912 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001913 public String getCallingPackage(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001914 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001915 ActivityRecord r = getCallingRecordLocked(token);
1916 return r != null ? r.info.packageName : null;
1917 }
1918 }
1919
1920 @Override
1921 public ComponentName getCallingActivity(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001922 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001923 ActivityRecord r = getCallingRecordLocked(token);
1924 return r != null ? r.intent.getComponent() : null;
1925 }
1926 }
1927
1928 private ActivityRecord getCallingRecordLocked(IBinder token) {
1929 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1930 if (r == null) {
1931 return null;
1932 }
1933 return r.resultTo;
1934 }
1935
1936 @Override
1937 public void unhandledBack() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001938 mAmInternal.enforceCallingPermission(android.Manifest.permission.FORCE_BACK, "unhandledBack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001939
1940 synchronized (mGlobalLock) {
1941 final long origId = Binder.clearCallingIdentity();
1942 try {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001943 getTopDisplayFocusedStack().unhandledBackLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001944 } finally {
1945 Binder.restoreCallingIdentity(origId);
1946 }
1947 }
1948 }
1949
1950 /**
1951 * TODO: Add mController hook
1952 */
1953 @Override
1954 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001955 mAmInternal.enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001956
1957 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
1958 synchronized (mGlobalLock) {
1959 moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
1960 false /* fromRecents */);
1961 }
1962 }
1963
1964 void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
1965 boolean fromRecents) {
1966
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001967 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001968 Binder.getCallingUid(), -1, -1, "Task to front")) {
1969 SafeActivityOptions.abort(options);
1970 return;
1971 }
1972 final long origId = Binder.clearCallingIdentity();
1973 try {
1974 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1975 if (task == null) {
1976 Slog.d(TAG, "Could not find task for id: "+ taskId);
Winson Chungd0243682018-09-25 18:11:54 -07001977 SafeActivityOptions.abort(options);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001978 return;
1979 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001980 if (getLockTaskController().isLockTaskModeViolation(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001981 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
Winson Chungd0243682018-09-25 18:11:54 -07001982 SafeActivityOptions.abort(options);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001983 return;
1984 }
1985 ActivityOptions realOptions = options != null
1986 ? options.getOptions(mStackSupervisor)
1987 : null;
1988 mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
1989 false /* forceNonResizable */);
1990
1991 final ActivityRecord topActivity = task.getTopActivity();
1992 if (topActivity != null) {
1993
1994 // We are reshowing a task, use a starting window to hide the initial draw delay
1995 // so the transition can start earlier.
1996 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
1997 true /* taskSwitch */, fromRecents);
1998 }
1999 } finally {
2000 Binder.restoreCallingIdentity(origId);
2001 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002002 }
2003
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002004 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
2005 int callingPid, int callingUid, String name) {
2006 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
2007 return true;
2008 }
2009
2010 if (getRecentTasks().isCallerRecents(sourceUid)) {
2011 return true;
2012 }
2013
2014 int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
2015 if (perm == PackageManager.PERMISSION_GRANTED) {
2016 return true;
2017 }
2018 if (checkAllowAppSwitchUid(sourceUid)) {
2019 return true;
2020 }
2021
2022 // If the actual IPC caller is different from the logical source, then
2023 // also see if they are allowed to control app switches.
2024 if (callingUid != -1 && callingUid != sourceUid) {
2025 perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
2026 if (perm == PackageManager.PERMISSION_GRANTED) {
2027 return true;
2028 }
2029 if (checkAllowAppSwitchUid(callingUid)) {
2030 return true;
2031 }
2032 }
2033
2034 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
2035 return false;
2036 }
2037
2038 private boolean checkAllowAppSwitchUid(int uid) {
2039 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
2040 if (types != null) {
2041 for (int i = types.size() - 1; i >= 0; i--) {
2042 if (types.valueAt(i).intValue() == uid) {
2043 return true;
2044 }
2045 }
2046 }
2047 return false;
2048 }
2049
2050 @Override
2051 public void setActivityController(IActivityController controller, boolean imAMonkey) {
2052 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
2053 "setActivityController()");
2054 synchronized (mGlobalLock) {
2055 mController = controller;
2056 mControllerIsAMonkey = imAMonkey;
2057 Watchdog.getInstance().setActivityController(controller);
2058 }
2059 }
2060
2061 boolean isControllerAMonkey() {
2062 synchronized (mGlobalLock) {
2063 return mController != null && mControllerIsAMonkey;
2064 }
2065 }
2066
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002067 @Override
2068 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
2069 synchronized (mGlobalLock) {
2070 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
2071 }
2072 }
2073
2074 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002075 public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum) {
2076 return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
2077 }
2078
2079 @Override
2080 public List<ActivityManager.RunningTaskInfo> getFilteredTasks(int maxNum,
2081 @WindowConfiguration.ActivityType int ignoreActivityType,
2082 @WindowConfiguration.WindowingMode int ignoreWindowingMode) {
2083 final int callingUid = Binder.getCallingUid();
2084 ArrayList<ActivityManager.RunningTaskInfo> list = new ArrayList<>();
2085
2086 synchronized (mGlobalLock) {
2087 if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
2088
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002089 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002090 callingUid);
2091 mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
2092 ignoreWindowingMode, callingUid, allowed);
2093 }
2094
2095 return list;
2096 }
2097
2098 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002099 public final void finishSubActivity(IBinder token, String resultWho, int requestCode) {
2100 synchronized (mGlobalLock) {
2101 final long origId = Binder.clearCallingIdentity();
2102 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2103 if (r != null) {
2104 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
2105 }
2106 Binder.restoreCallingIdentity(origId);
2107 }
2108 }
2109
2110 @Override
2111 public boolean willActivityBeVisible(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002112 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002113 ActivityStack stack = ActivityRecord.getStackLocked(token);
2114 if (stack != null) {
2115 return stack.willActivityBeVisibleLocked(token);
2116 }
2117 return false;
2118 }
2119 }
2120
2121 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002122 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002123 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002124 synchronized (mGlobalLock) {
2125 final long ident = Binder.clearCallingIdentity();
2126 try {
2127 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2128 if (task == null) {
2129 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
2130 return;
2131 }
2132
2133 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
2134 + " to stackId=" + stackId + " toTop=" + toTop);
2135
2136 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2137 if (stack == null) {
2138 throw new IllegalStateException(
2139 "moveTaskToStack: No stack for stackId=" + stackId);
2140 }
2141 if (!stack.isActivityTypeStandardOrUndefined()) {
2142 throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
2143 + taskId + " to stack " + stackId);
2144 }
2145 if (stack.inSplitScreenPrimaryWindowingMode()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002146 mWindowManager.setDockedStackCreateState(
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002147 SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
2148 }
2149 task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
2150 "moveTaskToStack");
2151 } finally {
2152 Binder.restoreCallingIdentity(ident);
2153 }
2154 }
2155 }
2156
2157 @Override
2158 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
2159 boolean preserveWindows, boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002160 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002161
2162 final long ident = Binder.clearCallingIdentity();
2163 try {
2164 synchronized (mGlobalLock) {
2165 if (animate) {
2166 final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
2167 if (stack == null) {
2168 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2169 return;
2170 }
2171 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
2172 throw new IllegalArgumentException("Stack: " + stackId
2173 + " doesn't support animated resize.");
2174 }
2175 stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
2176 animationDuration, false /* fromFullscreen */);
2177 } else {
2178 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2179 if (stack == null) {
2180 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2181 return;
2182 }
2183 mStackSupervisor.resizeStackLocked(stack, destBounds,
2184 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
2185 preserveWindows, allowResizeInDockedMode, !DEFER_RESUME);
2186 }
2187 }
2188 } finally {
2189 Binder.restoreCallingIdentity(ident);
2190 }
2191 }
2192
2193 /**
2194 * Moves the specified task to the primary-split-screen stack.
2195 *
2196 * @param taskId Id of task to move.
2197 * @param createMode The mode the primary split screen stack should be created in if it doesn't
2198 * exist already. See
2199 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
2200 * and
2201 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
2202 * @param toTop If the task and stack should be moved to the top.
2203 * @param animate Whether we should play an animation for the moving the task.
2204 * @param initialBounds If the primary stack gets created, it will use these bounds for the
2205 * stack. Pass {@code null} to use default bounds.
2206 * @param showRecents If the recents activity should be shown on the other side of the task
2207 * going into split-screen mode.
2208 */
2209 @Override
2210 public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode,
2211 boolean toTop, boolean animate, Rect initialBounds, boolean showRecents) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002212 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002213 "setTaskWindowingModeSplitScreenPrimary()");
2214 synchronized (mGlobalLock) {
2215 final long ident = Binder.clearCallingIdentity();
2216 try {
2217 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2218 if (task == null) {
2219 Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
2220 return false;
2221 }
2222 if (DEBUG_STACK) Slog.d(TAG_STACK,
2223 "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
2224 + " to createMode=" + createMode + " toTop=" + toTop);
2225 if (!task.isActivityTypeStandardOrUndefined()) {
2226 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
2227 + " non-standard task " + taskId + " to split-screen windowing mode");
2228 }
2229
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002230 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002231 final int windowingMode = task.getWindowingMode();
2232 final ActivityStack stack = task.getStack();
2233 if (toTop) {
2234 stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
2235 }
2236 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
2237 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */);
2238 return windowingMode != task.getWindowingMode();
2239 } finally {
2240 Binder.restoreCallingIdentity(ident);
2241 }
2242 }
2243 }
2244
2245 /**
2246 * Removes stacks in the input windowing modes from the system if they are of activity type
2247 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
2248 */
2249 @Override
2250 public void removeStacksInWindowingModes(int[] windowingModes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002251 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002252 "removeStacksInWindowingModes()");
2253
2254 synchronized (mGlobalLock) {
2255 final long ident = Binder.clearCallingIdentity();
2256 try {
2257 mStackSupervisor.removeStacksInWindowingModes(windowingModes);
2258 } finally {
2259 Binder.restoreCallingIdentity(ident);
2260 }
2261 }
2262 }
2263
2264 @Override
2265 public void removeStacksWithActivityTypes(int[] activityTypes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002266 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002267 "removeStacksWithActivityTypes()");
2268
2269 synchronized (mGlobalLock) {
2270 final long ident = Binder.clearCallingIdentity();
2271 try {
2272 mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
2273 } finally {
2274 Binder.restoreCallingIdentity(ident);
2275 }
2276 }
2277 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002278
2279 @Override
2280 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
2281 int userId) {
2282 final int callingUid = Binder.getCallingUid();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002283 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, "getRecentTasks");
2284 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002285 callingUid);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002286 final boolean detailed = checkGetTasksPermission(
2287 android.Manifest.permission.GET_DETAILED_TASKS, Binder.getCallingPid(),
2288 UserHandle.getAppId(callingUid))
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002289 == PackageManager.PERMISSION_GRANTED;
2290
2291 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002292 return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002293 callingUid);
2294 }
2295 }
2296
2297 @Override
2298 public List<ActivityManager.StackInfo> getAllStackInfos() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002299 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002300 long ident = Binder.clearCallingIdentity();
2301 try {
2302 synchronized (mGlobalLock) {
2303 return mStackSupervisor.getAllStackInfosLocked();
2304 }
2305 } finally {
2306 Binder.restoreCallingIdentity(ident);
2307 }
2308 }
2309
2310 @Override
2311 public ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002312 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002313 long ident = Binder.clearCallingIdentity();
2314 try {
2315 synchronized (mGlobalLock) {
2316 return mStackSupervisor.getStackInfo(windowingMode, activityType);
2317 }
2318 } finally {
2319 Binder.restoreCallingIdentity(ident);
2320 }
2321 }
2322
2323 @Override
2324 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002325 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002326 final long callingUid = Binder.getCallingUid();
2327 final long origId = Binder.clearCallingIdentity();
2328 try {
2329 synchronized (mGlobalLock) {
2330 // Cancel the recents animation synchronously (do not hold the WM lock)
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002331 mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002332 ? REORDER_MOVE_TO_ORIGINAL_POSITION
2333 : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
2334 }
2335 } finally {
2336 Binder.restoreCallingIdentity(origId);
2337 }
2338 }
2339
2340 @Override
2341 public void startLockTaskModeByToken(IBinder token) {
2342 synchronized (mGlobalLock) {
2343 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2344 if (r == null) {
2345 return;
2346 }
2347 startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
2348 }
2349 }
2350
2351 @Override
2352 public void startSystemLockTaskMode(int taskId) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002353 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002354 // This makes inner call to look as if it was initiated by system.
2355 long ident = Binder.clearCallingIdentity();
2356 try {
2357 synchronized (mGlobalLock) {
2358 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2359
2360 // When starting lock task mode the stack must be in front and focused
2361 task.getStack().moveToFront("startSystemLockTaskMode");
2362 startLockTaskModeLocked(task, true /* isSystemCaller */);
2363 }
2364 } finally {
2365 Binder.restoreCallingIdentity(ident);
2366 }
2367 }
2368
2369 @Override
2370 public void stopLockTaskModeByToken(IBinder token) {
2371 synchronized (mGlobalLock) {
2372 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2373 if (r == null) {
2374 return;
2375 }
2376 stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
2377 }
2378 }
2379
2380 /**
2381 * This API should be called by SystemUI only when user perform certain action to dismiss
2382 * lock task mode. We should only dismiss pinned lock task mode in this case.
2383 */
2384 @Override
2385 public void stopSystemLockTaskMode() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002386 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002387 stopLockTaskModeInternal(null, true /* isSystemCaller */);
2388 }
2389
2390 private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
2391 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
2392 if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
2393 return;
2394 }
2395
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002396 final ActivityStack stack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002397 if (stack == null || task != stack.topTask()) {
2398 throw new IllegalArgumentException("Invalid task, not in foreground");
2399 }
2400
2401 // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
2402 // system or a specific app.
2403 // * System-initiated requests will only start the pinned mode (screen pinning)
2404 // * App-initiated requests
2405 // - will put the device in fully locked mode (LockTask), if the app is whitelisted
2406 // - will start the pinned mode, otherwise
2407 final int callingUid = Binder.getCallingUid();
2408 long ident = Binder.clearCallingIdentity();
2409 try {
2410 // When a task is locked, dismiss the pinned stack if it exists
2411 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2412
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002413 getLockTaskController().startLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002414 } finally {
2415 Binder.restoreCallingIdentity(ident);
2416 }
2417 }
2418
2419 private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
2420 final int callingUid = Binder.getCallingUid();
2421 long ident = Binder.clearCallingIdentity();
2422 try {
2423 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002424 getLockTaskController().stopLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002425 }
2426 // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
2427 // task and jumping straight into a call in the case of emergency call back.
2428 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
2429 if (tm != null) {
2430 tm.showInCallScreen(false);
2431 }
2432 } finally {
2433 Binder.restoreCallingIdentity(ident);
2434 }
2435 }
2436
2437 @Override
2438 public boolean isInLockTaskMode() {
2439 return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
2440 }
2441
2442 @Override
2443 public int getLockTaskModeState() {
2444 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002445 return getLockTaskController().getLockTaskModeState();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002446 }
2447 }
2448
2449 @Override
2450 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
2451 synchronized (mGlobalLock) {
2452 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2453 if (r != null) {
2454 r.setTaskDescription(td);
2455 final TaskRecord task = r.getTask();
2456 task.updateTaskDescription();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002457 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002458 }
2459 }
2460 }
2461
2462 @Override
2463 public Bundle getActivityOptions(IBinder token) {
2464 final long origId = Binder.clearCallingIdentity();
2465 try {
2466 synchronized (mGlobalLock) {
2467 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
2468 if (r != null) {
2469 final ActivityOptions activityOptions = r.takeOptionsLocked();
2470 return activityOptions == null ? null : activityOptions.toBundle();
2471 }
2472 return null;
2473 }
2474 } finally {
2475 Binder.restoreCallingIdentity(origId);
2476 }
2477 }
2478
2479 @Override
2480 public List<IBinder> getAppTasks(String callingPackage) {
2481 int callingUid = Binder.getCallingUid();
2482 long ident = Binder.clearCallingIdentity();
2483 try {
2484 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002485 return mRecentTasks.getAppTasksList(callingUid, callingPackage);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002486 }
2487 } finally {
2488 Binder.restoreCallingIdentity(ident);
2489 }
2490 }
2491
2492 @Override
2493 public void finishVoiceTask(IVoiceInteractionSession session) {
2494 synchronized (mGlobalLock) {
2495 final long origId = Binder.clearCallingIdentity();
2496 try {
2497 // TODO: VI Consider treating local voice interactions and voice tasks
2498 // differently here
2499 mStackSupervisor.finishVoiceTask(session);
2500 } finally {
2501 Binder.restoreCallingIdentity(origId);
2502 }
2503 }
2504
2505 }
2506
2507 @Override
2508 public boolean isTopOfTask(IBinder token) {
2509 synchronized (mGlobalLock) {
2510 ActivityRecord r = ActivityRecord.isInStackLocked(token);
Riddle Hsu66b74a82018-07-26 00:20:12 +08002511 return r != null && r.getTask().getTopActivity() == r;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002512 }
2513 }
2514
2515 @Override
2516 public void notifyLaunchTaskBehindComplete(IBinder token) {
2517 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
2518 }
2519
2520 @Override
2521 public void notifyEnterAnimationComplete(IBinder token) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002522 mH.post(() -> {
2523 synchronized (mGlobalLock) {
2524 ActivityRecord r = ActivityRecord.forTokenLocked(token);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002525 if (r != null && r.attachedToProcess()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002526 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002527 r.app.getThread().scheduleEnterAnimationComplete(r.appToken);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002528 } catch (RemoteException e) {
2529 }
2530 }
2531 }
2532
2533 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002534 }
2535
2536 /** Called from an app when assist data is ready. */
2537 @Override
2538 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
2539 AssistContent content, Uri referrer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002540 PendingAssistExtras pae = (PendingAssistExtras) token;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002541 synchronized (pae) {
2542 pae.result = extras;
2543 pae.structure = structure;
2544 pae.content = content;
2545 if (referrer != null) {
2546 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
2547 }
2548 if (structure != null) {
2549 structure.setHomeActivity(pae.isHome);
2550 }
2551 pae.haveResult = true;
2552 pae.notifyAll();
2553 if (pae.intent == null && pae.receiver == null) {
2554 // Caller is just waiting for the result.
2555 return;
2556 }
2557 }
2558 // We are now ready to launch the assist activity.
2559 IAssistDataReceiver sendReceiver = null;
2560 Bundle sendBundle = null;
2561 synchronized (mGlobalLock) {
2562 buildAssistBundleLocked(pae, extras);
2563 boolean exists = mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002564 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002565 if (!exists) {
2566 // Timed out.
2567 return;
2568 }
2569
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002570 if ((sendReceiver = pae.receiver) != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002571 // Caller wants result sent back to them.
2572 sendBundle = new Bundle();
2573 sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
2574 sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
2575 sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
2576 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
2577 }
2578 }
2579 if (sendReceiver != null) {
2580 try {
2581 sendReceiver.onHandleAssistData(sendBundle);
2582 } catch (RemoteException e) {
2583 }
2584 return;
2585 }
2586
2587 final long ident = Binder.clearCallingIdentity();
2588 try {
2589 if (TextUtils.equals(pae.intent.getAction(),
2590 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
2591 pae.intent.putExtras(pae.extras);
2592 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
2593 } else {
2594 pae.intent.replaceExtras(pae.extras);
2595 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
2596 | Intent.FLAG_ACTIVITY_SINGLE_TOP
2597 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002598 mAmInternal.closeSystemDialogs("assist");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002599
2600 try {
2601 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
2602 } catch (ActivityNotFoundException e) {
2603 Slog.w(TAG, "No activity to handle assist action.", e);
2604 }
2605 }
2606 } finally {
2607 Binder.restoreCallingIdentity(ident);
2608 }
2609 }
2610
2611 @Override
2612 public int addAppTask(IBinder activityToken, Intent intent,
2613 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
2614 final int callingUid = Binder.getCallingUid();
2615 final long callingIdent = Binder.clearCallingIdentity();
2616
2617 try {
2618 synchronized (mGlobalLock) {
2619 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
2620 if (r == null) {
2621 throw new IllegalArgumentException("Activity does not exist; token="
2622 + activityToken);
2623 }
2624 ComponentName comp = intent.getComponent();
2625 if (comp == null) {
2626 throw new IllegalArgumentException("Intent " + intent
2627 + " must specify explicit component");
2628 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002629 if (thumbnail.getWidth() != mThumbnailWidth
2630 || thumbnail.getHeight() != mThumbnailHeight) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002631 throw new IllegalArgumentException("Bad thumbnail size: got "
2632 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002633 + mThumbnailWidth + "x" + mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002634 }
2635 if (intent.getSelector() != null) {
2636 intent.setSelector(null);
2637 }
2638 if (intent.getSourceBounds() != null) {
2639 intent.setSourceBounds(null);
2640 }
2641 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
2642 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
2643 // The caller has added this as an auto-remove task... that makes no
2644 // sense, so turn off auto-remove.
2645 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
2646 }
2647 }
2648 final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
2649 STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
2650 if (ainfo.applicationInfo.uid != callingUid) {
2651 throw new SecurityException(
2652 "Can't add task for another application: target uid="
2653 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
2654 }
2655
2656 final ActivityStack stack = r.getStack();
2657 final TaskRecord task = stack.createTaskRecord(
2658 mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent,
2659 null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002660 if (!mRecentTasks.addToBottom(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002661 // The app has too many tasks already and we can't add any more
2662 stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
2663 return INVALID_TASK_ID;
2664 }
2665 task.lastTaskDescription.copyFrom(description);
2666
2667 // TODO: Send the thumbnail to WM to store it.
2668
2669 return task.taskId;
2670 }
2671 } finally {
2672 Binder.restoreCallingIdentity(callingIdent);
2673 }
2674 }
2675
2676 @Override
2677 public Point getAppTaskThumbnailSize() {
2678 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002679 return new Point(mThumbnailWidth, mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002680 }
2681 }
2682
2683 @Override
2684 public void setTaskResizeable(int taskId, int resizeableMode) {
2685 synchronized (mGlobalLock) {
2686 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
2687 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
2688 if (task == null) {
2689 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
2690 return;
2691 }
2692 task.setResizeMode(resizeableMode);
2693 }
2694 }
2695
2696 @Override
2697 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002698 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002699 long ident = Binder.clearCallingIdentity();
2700 try {
2701 synchronized (mGlobalLock) {
2702 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2703 if (task == null) {
2704 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
2705 return;
2706 }
2707 // Place the task in the right stack if it isn't there already based on
2708 // the requested bounds.
2709 // The stack transition logic is:
2710 // - a null bounds on a freeform task moves that task to fullscreen
2711 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
2712 // that task to freeform
2713 // - otherwise the task is not moved
2714 ActivityStack stack = task.getStack();
2715 if (!task.getWindowConfiguration().canResizeTask()) {
2716 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
2717 }
2718 if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
2719 stack = stack.getDisplay().getOrCreateStack(
2720 WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
2721 } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
2722 stack = stack.getDisplay().getOrCreateStack(
2723 WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
2724 }
2725
2726 // Reparent the task to the right stack if necessary
2727 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
2728 if (stack != task.getStack()) {
2729 // Defer resume until the task is resized below
2730 task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
2731 DEFER_RESUME, "resizeTask");
2732 preserveWindow = false;
2733 }
2734
2735 // After reparenting (which only resizes the task to the stack bounds), resize the
2736 // task to the actual bounds provided
2737 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
2738 }
2739 } finally {
2740 Binder.restoreCallingIdentity(ident);
2741 }
2742 }
2743
2744 @Override
2745 public boolean releaseActivityInstance(IBinder token) {
2746 synchronized (mGlobalLock) {
2747 final long origId = Binder.clearCallingIdentity();
2748 try {
2749 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2750 if (r == null) {
2751 return false;
2752 }
2753 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
2754 } finally {
2755 Binder.restoreCallingIdentity(origId);
2756 }
2757 }
2758 }
2759
2760 @Override
2761 public void releaseSomeActivities(IApplicationThread appInt) {
2762 synchronized (mGlobalLock) {
2763 final long origId = Binder.clearCallingIdentity();
2764 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002765 WindowProcessController app =
2766 mAm.getRecordForAppLocked(appInt).getWindowProcessController();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002767 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
2768 } finally {
2769 Binder.restoreCallingIdentity(origId);
2770 }
2771 }
2772 }
2773
2774 @Override
2775 public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
2776 int secondaryDisplayShowing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002777 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002778 != PackageManager.PERMISSION_GRANTED) {
2779 throw new SecurityException("Requires permission "
2780 + android.Manifest.permission.DEVICE_POWER);
2781 }
2782
2783 synchronized (mGlobalLock) {
2784 long ident = Binder.clearCallingIdentity();
2785 if (mKeyguardShown != keyguardShowing) {
2786 mKeyguardShown = keyguardShowing;
2787 reportCurKeyguardUsageEventLocked(keyguardShowing);
2788 }
2789 try {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002790 mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002791 secondaryDisplayShowing);
2792 } finally {
2793 Binder.restoreCallingIdentity(ident);
2794 }
2795 }
2796
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002797 mH.post(() -> {
2798 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2799 mScreenObservers.get(i).onKeyguardStateChanged(keyguardShowing);
2800 }
2801 });
2802 }
2803
2804 void onScreenAwakeChanged(boolean isAwake) {
2805 mH.post(() -> {
2806 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2807 mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2808 }
2809 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002810 }
2811
2812 @Override
2813 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002814 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
2815 userId, "getTaskDescriptionIcon");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002816
2817 final File passedIconFile = new File(filePath);
2818 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
2819 passedIconFile.getName());
2820 if (!legitIconFile.getPath().equals(filePath)
2821 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
2822 throw new IllegalArgumentException("Bad file path: " + filePath
2823 + " passed for userId " + userId);
2824 }
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002825 return mRecentTasks.getTaskDescriptionIcon(filePath);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002826 }
2827
2828 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002829 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002830 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
2831 final ActivityOptions activityOptions = safeOptions != null
2832 ? safeOptions.getOptions(mStackSupervisor)
2833 : null;
2834 if (activityOptions == null
2835 || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
2836 || activityOptions.getCustomInPlaceResId() == 0) {
2837 throw new IllegalArgumentException("Expected in-place ActivityOption " +
2838 "with valid animation");
2839 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002840 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
2841 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002842 activityOptions.getCustomInPlaceResId());
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002843 mWindowManager.executeAppTransition();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002844 }
2845
2846 @Override
2847 public void removeStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002848 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002849 synchronized (mGlobalLock) {
2850 final long ident = Binder.clearCallingIdentity();
2851 try {
2852 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2853 if (stack == null) {
2854 Slog.w(TAG, "removeStack: No stack with id=" + stackId);
2855 return;
2856 }
2857 if (!stack.isActivityTypeStandardOrUndefined()) {
2858 throw new IllegalArgumentException(
2859 "Removing non-standard stack is not allowed.");
2860 }
2861 mStackSupervisor.removeStack(stack);
2862 } finally {
2863 Binder.restoreCallingIdentity(ident);
2864 }
2865 }
2866 }
2867
2868 @Override
2869 public void moveStackToDisplay(int stackId, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002870 mAmInternal.enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002871
2872 synchronized (mGlobalLock) {
2873 final long ident = Binder.clearCallingIdentity();
2874 try {
2875 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
2876 + " to displayId=" + displayId);
2877 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
2878 } finally {
2879 Binder.restoreCallingIdentity(ident);
2880 }
2881 }
2882 }
2883
2884 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002885 public void exitFreeformMode(IBinder token) {
2886 synchronized (mGlobalLock) {
2887 long ident = Binder.clearCallingIdentity();
2888 try {
2889 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2890 if (r == null) {
2891 throw new IllegalArgumentException(
2892 "exitFreeformMode: No activity record matching token=" + token);
2893 }
2894
2895 final ActivityStack stack = r.getStack();
2896 if (stack == null || !stack.inFreeformWindowingMode()) {
2897 throw new IllegalStateException(
2898 "exitFreeformMode: You can only go fullscreen from freeform.");
2899 }
2900
2901 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
2902 } finally {
2903 Binder.restoreCallingIdentity(ident);
2904 }
2905 }
2906 }
2907
2908 /** Sets the task stack listener that gets callbacks when a task stack changes. */
2909 @Override
2910 public void registerTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002911 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002912 "registerTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002913 mTaskChangeNotificationController.registerTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002914 }
2915
2916 /** Unregister a task stack listener so that it stops receiving callbacks. */
2917 @Override
2918 public void unregisterTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002919 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002920 "unregisterTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002921 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002922 }
2923
2924 private void reportCurKeyguardUsageEventLocked(boolean keyguardShowing) {
2925 mAm.reportGlobalUsageEventLocked(keyguardShowing
2926 ? UsageEvents.Event.KEYGUARD_SHOWN
2927 : UsageEvents.Event.KEYGUARD_HIDDEN);
2928 }
2929
2930 @Override
2931 public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
2932 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
2933 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
2934 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
2935 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
2936 }
2937
2938 @Override
2939 public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
2940 IBinder activityToken, int flags) {
2941 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
2942 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
2943 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
2944 }
2945
2946 @Override
2947 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
2948 Bundle args) {
2949 return enqueueAssistContext(requestType, intent, hint, null, null, null,
2950 true /* focused */, true /* newSessionId */, userHandle, args,
2951 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
2952 }
2953
2954 @Override
2955 public Bundle getAssistContextExtras(int requestType) {
2956 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
2957 null, null, true /* focused */, true /* newSessionId */,
2958 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
2959 if (pae == null) {
2960 return null;
2961 }
2962 synchronized (pae) {
2963 while (!pae.haveResult) {
2964 try {
2965 pae.wait();
2966 } catch (InterruptedException e) {
2967 }
2968 }
2969 }
2970 synchronized (mGlobalLock) {
2971 buildAssistBundleLocked(pae, pae.result);
2972 mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002973 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002974 }
2975 return pae.extras;
2976 }
2977
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002978 /**
2979 * Binder IPC calls go through the public entry point.
2980 * This can be called with or without the global lock held.
2981 */
2982 private static int checkCallingPermission(String permission) {
2983 return checkPermission(
2984 permission, Binder.getCallingPid(), UserHandle.getAppId(Binder.getCallingUid()));
2985 }
2986
2987 /** This can be called with or without the global lock held. */
Wale Ogunwale214f3482018-10-04 11:00:47 -07002988 private void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002989 if (!getRecentTasks().isCallerRecents(Binder.getCallingUid())) {
2990 mAmInternal.enforceCallingPermission(permission, func);
2991 }
2992 }
2993
2994 @VisibleForTesting
2995 int checkGetTasksPermission(String permission, int pid, int uid) {
2996 return checkPermission(permission, pid, uid);
2997 }
2998
2999 static int checkPermission(String permission, int pid, int uid) {
3000 if (permission == null) {
3001 return PackageManager.PERMISSION_DENIED;
3002 }
3003 return checkComponentPermission(permission, pid, uid, -1, true);
3004 }
3005
Wale Ogunwale214f3482018-10-04 11:00:47 -07003006 public static int checkComponentPermission(String permission, int pid, int uid,
3007 int owningUid, boolean exported) {
3008 return ActivityManagerService.checkComponentPermission(
3009 permission, pid, uid, owningUid, exported);
3010 }
3011
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003012 boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
3013 if (getRecentTasks().isCallerRecents(callingUid)) {
3014 // Always allow the recents component to get tasks
3015 return true;
3016 }
3017
3018 boolean allowed = checkGetTasksPermission(android.Manifest.permission.REAL_GET_TASKS,
3019 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
3020 if (!allowed) {
3021 if (checkGetTasksPermission(android.Manifest.permission.GET_TASKS,
3022 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
3023 // Temporary compatibility: some existing apps on the system image may
3024 // still be requesting the old permission and not switched to the new
3025 // one; if so, we'll still allow them full access. This means we need
3026 // to see if they are holding the old permission and are a system app.
3027 try {
3028 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
3029 allowed = true;
3030 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
3031 + " is using old GET_TASKS but privileged; allowing");
3032 }
3033 } catch (RemoteException e) {
3034 }
3035 }
3036 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
3037 + " does not hold REAL_GET_TASKS; limiting output");
3038 }
3039 return allowed;
3040 }
3041
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003042 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
3043 IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
3044 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
3045 int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003046 mAmInternal.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003047 "enqueueAssistContext()");
3048
3049 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003050 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003051 if (activity == null) {
3052 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
3053 return null;
3054 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003055 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003056 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
3057 return null;
3058 }
3059 if (focused) {
3060 if (activityToken != null) {
3061 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
3062 if (activity != caller) {
3063 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
3064 + " is not current top " + activity);
3065 return null;
3066 }
3067 }
3068 } else {
3069 activity = ActivityRecord.forTokenLocked(activityToken);
3070 if (activity == null) {
3071 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
3072 + " couldn't be found");
3073 return null;
3074 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003075 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003076 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
3077 return null;
3078 }
3079 }
3080
3081 PendingAssistExtras pae;
3082 Bundle extras = new Bundle();
3083 if (args != null) {
3084 extras.putAll(args);
3085 }
3086 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003087 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003088
3089 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
3090 userHandle);
3091 pae.isHome = activity.isActivityTypeHome();
3092
3093 // Increment the sessionId if necessary
3094 if (newSessionId) {
3095 mViSessionId++;
3096 }
3097 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003098 activity.app.getThread().requestAssistContextExtras(activity.appToken, pae,
3099 requestType, mViSessionId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003100 mPendingAssistExtras.add(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003101 mUiHandler.postDelayed(pae, timeout);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003102 } catch (RemoteException e) {
3103 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
3104 return null;
3105 }
3106 return pae;
3107 }
3108 }
3109
3110 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
3111 if (result != null) {
3112 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
3113 }
3114 if (pae.hint != null) {
3115 pae.extras.putBoolean(pae.hint, true);
3116 }
3117 }
3118
3119 private void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
3120 IAssistDataReceiver receiver;
3121 synchronized (mGlobalLock) {
3122 mPendingAssistExtras.remove(pae);
3123 receiver = pae.receiver;
3124 }
3125 if (receiver != null) {
3126 // Caller wants result sent back to them.
3127 Bundle sendBundle = new Bundle();
3128 // At least return the receiver extras
3129 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
3130 try {
3131 pae.receiver.onHandleAssistData(sendBundle);
3132 } catch (RemoteException e) {
3133 }
3134 }
3135 }
3136
3137 public class PendingAssistExtras extends Binder implements Runnable {
3138 public final ActivityRecord activity;
3139 public boolean isHome;
3140 public final Bundle extras;
3141 public final Intent intent;
3142 public final String hint;
3143 public final IAssistDataReceiver receiver;
3144 public final int userHandle;
3145 public boolean haveResult = false;
3146 public Bundle result = null;
3147 public AssistStructure structure = null;
3148 public AssistContent content = null;
3149 public Bundle receiverExtras;
3150
3151 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
3152 String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
3153 int _userHandle) {
3154 activity = _activity;
3155 extras = _extras;
3156 intent = _intent;
3157 hint = _hint;
3158 receiver = _receiver;
3159 receiverExtras = _receiverExtras;
3160 userHandle = _userHandle;
3161 }
3162
3163 @Override
3164 public void run() {
3165 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
3166 synchronized (this) {
3167 haveResult = true;
3168 notifyAll();
3169 }
3170 pendingAssistExtrasTimedOut(this);
3171 }
3172 }
3173
3174 @Override
3175 public boolean isAssistDataAllowedOnCurrentActivity() {
3176 int userId;
3177 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003178 final ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003179 if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
3180 return false;
3181 }
3182
3183 final ActivityRecord activity = focusedStack.getTopActivity();
3184 if (activity == null) {
3185 return false;
3186 }
3187 userId = activity.userId;
3188 }
3189 return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
3190 }
3191
3192 @Override
3193 public boolean showAssistFromActivity(IBinder token, Bundle args) {
3194 long ident = Binder.clearCallingIdentity();
3195 try {
3196 synchronized (mGlobalLock) {
3197 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003198 ActivityRecord top = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003199 if (top != caller) {
3200 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3201 + " is not current top " + top);
3202 return false;
3203 }
3204 if (!top.nowVisible) {
3205 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3206 + " is not visible");
3207 return false;
3208 }
3209 }
3210 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
3211 token);
3212 } finally {
3213 Binder.restoreCallingIdentity(ident);
3214 }
3215 }
3216
3217 @Override
3218 public boolean isRootVoiceInteraction(IBinder token) {
3219 synchronized (mGlobalLock) {
3220 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3221 if (r == null) {
3222 return false;
3223 }
3224 return r.rootVoiceInteraction;
3225 }
3226 }
3227
Wale Ogunwalef6733932018-06-27 05:14:34 -07003228 private void onLocalVoiceInteractionStartedLocked(IBinder activity,
3229 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
3230 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
3231 if (activityToCallback == null) return;
3232 activityToCallback.setVoiceSessionLocked(voiceSession);
3233
3234 // Inform the activity
3235 try {
3236 activityToCallback.app.getThread().scheduleLocalVoiceInteractionStarted(activity,
3237 voiceInteractor);
3238 long token = Binder.clearCallingIdentity();
3239 try {
3240 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
3241 } finally {
3242 Binder.restoreCallingIdentity(token);
3243 }
3244 // TODO: VI Should we cache the activity so that it's easier to find later
3245 // rather than scan through all the stacks and activities?
3246 } catch (RemoteException re) {
3247 activityToCallback.clearVoiceSessionLocked();
3248 // TODO: VI Should this terminate the voice session?
3249 }
3250 }
3251
3252 private void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
3253 Slog.d(TAG, "<<< startRunningVoiceLocked()");
3254 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
3255 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
3256 boolean wasRunningVoice = mRunningVoice != null;
3257 mRunningVoice = session;
3258 if (!wasRunningVoice) {
3259 mVoiceWakeLock.acquire();
3260 updateSleepIfNeededLocked();
3261 }
3262 }
3263 }
3264
3265 void finishRunningVoiceLocked() {
3266 if (mRunningVoice != null) {
3267 mRunningVoice = null;
3268 mVoiceWakeLock.release();
3269 updateSleepIfNeededLocked();
3270 }
3271 }
3272
3273 @Override
3274 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3275 synchronized (mGlobalLock) {
3276 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3277 if (keepAwake) {
3278 mVoiceWakeLock.acquire();
3279 } else {
3280 mVoiceWakeLock.release();
3281 }
3282 }
3283 }
3284 }
3285
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003286 @Override
3287 public ComponentName getActivityClassForToken(IBinder token) {
3288 synchronized (mGlobalLock) {
3289 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3290 if (r == null) {
3291 return null;
3292 }
3293 return r.intent.getComponent();
3294 }
3295 }
3296
3297 @Override
3298 public String getPackageForToken(IBinder token) {
3299 synchronized (mGlobalLock) {
3300 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3301 if (r == null) {
3302 return null;
3303 }
3304 return r.packageName;
3305 }
3306 }
3307
3308 @Override
3309 public void showLockTaskEscapeMessage(IBinder token) {
3310 synchronized (mGlobalLock) {
3311 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3312 if (r == null) {
3313 return;
3314 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003315 getLockTaskController().showLockTaskToast();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003316 }
3317 }
3318
3319 @Override
3320 public void keyguardGoingAway(int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003321 enforceNotIsolatedCaller("keyguardGoingAway");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003322 final long token = Binder.clearCallingIdentity();
3323 try {
3324 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003325 mKeyguardController.keyguardGoingAway(flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003326 }
3327 } finally {
3328 Binder.restoreCallingIdentity(token);
3329 }
3330 }
3331
3332 /**
3333 * Try to place task to provided position. The final position might be different depending on
3334 * current user and stacks state. The task will be moved to target stack if it's currently in
3335 * different stack.
3336 */
3337 @Override
3338 public void positionTaskInStack(int taskId, int stackId, int position) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003339 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003340 synchronized (mGlobalLock) {
3341 long ident = Binder.clearCallingIdentity();
3342 try {
3343 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
3344 + taskId + " in stackId=" + stackId + " at position=" + position);
3345 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3346 if (task == null) {
3347 throw new IllegalArgumentException("positionTaskInStack: no task for id="
3348 + taskId);
3349 }
3350
3351 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3352
3353 if (stack == null) {
3354 throw new IllegalArgumentException("positionTaskInStack: no stack for id="
3355 + stackId);
3356 }
3357 if (!stack.isActivityTypeStandardOrUndefined()) {
3358 throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
3359 + " the position of task " + taskId + " in/to non-standard stack");
3360 }
3361
3362 // TODO: Have the callers of this API call a separate reparent method if that is
3363 // what they intended to do vs. having this method also do reparenting.
3364 if (task.getStack() == stack) {
3365 // Change position in current stack.
3366 stack.positionChildAt(task, position);
3367 } else {
3368 // Reparent to new stack.
3369 task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
3370 !DEFER_RESUME, "positionTaskInStack");
3371 }
3372 } finally {
3373 Binder.restoreCallingIdentity(ident);
3374 }
3375 }
3376 }
3377
3378 @Override
3379 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
3380 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
3381 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
3382 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
3383 synchronized (mGlobalLock) {
3384 ActivityRecord record = ActivityRecord.isInStackLocked(token);
3385 if (record == null) {
3386 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
3387 + "found for: " + token);
3388 }
3389 record.setSizeConfigurations(horizontalSizeConfiguration,
3390 verticalSizeConfigurations, smallestSizeConfigurations);
3391 }
3392 }
3393
3394 /**
3395 * Dismisses split-screen multi-window mode.
3396 * @param toTop If true the current primary split-screen stack will be placed or left on top.
3397 */
3398 @Override
3399 public void dismissSplitScreenMode(boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003400 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003401 MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
3402 final long ident = Binder.clearCallingIdentity();
3403 try {
3404 synchronized (mGlobalLock) {
3405 final ActivityStack stack =
3406 mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
3407 if (stack == null) {
3408 Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
3409 return;
3410 }
3411
3412 if (toTop) {
3413 // Caller wants the current split-screen primary stack to be the top stack after
3414 // it goes fullscreen, so move it to the front.
3415 stack.moveToFront("dismissSplitScreenMode");
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003416 } else if (mStackSupervisor.isTopDisplayFocusedStack(stack)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003417 // In this case the current split-screen primary stack shouldn't be the top
3418 // stack after it goes fullscreen, but it current has focus, so we move the
3419 // focus to the top-most split-screen secondary stack next to it.
3420 final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
3421 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
3422 if (otherStack != null) {
3423 otherStack.moveToFront("dismissSplitScreenMode_other");
3424 }
3425 }
3426
Evan Rosky10475742018-09-05 19:02:48 -07003427 stack.setWindowingMode(WINDOWING_MODE_UNDEFINED);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003428 }
3429 } finally {
3430 Binder.restoreCallingIdentity(ident);
3431 }
3432 }
3433
3434 /**
3435 * Dismisses Pip
3436 * @param animate True if the dismissal should be animated.
3437 * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
3438 * default animation duration should be used.
3439 */
3440 @Override
3441 public void dismissPip(boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003442 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003443 final long ident = Binder.clearCallingIdentity();
3444 try {
3445 synchronized (mGlobalLock) {
3446 final PinnedActivityStack stack =
3447 mStackSupervisor.getDefaultDisplay().getPinnedStack();
3448 if (stack == null) {
3449 Slog.w(TAG, "dismissPip: pinned stack not found.");
3450 return;
3451 }
3452 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
3453 throw new IllegalArgumentException("Stack: " + stack
3454 + " doesn't support animated resize.");
3455 }
3456 if (animate) {
3457 stack.animateResizePinnedStack(null /* sourceHintBounds */,
3458 null /* destBounds */, animationDuration, false /* fromFullscreen */);
3459 } else {
3460 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
3461 }
3462 }
3463 } finally {
3464 Binder.restoreCallingIdentity(ident);
3465 }
3466 }
3467
3468 @Override
3469 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003470 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003471 synchronized (mGlobalLock) {
3472 mSuppressResizeConfigChanges = suppress;
3473 }
3474 }
3475
3476 /**
3477 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
3478 * animated the stack to the fullscreen, but can also be called if we are relaunching an
3479 * activity and clearing the task at the same time.
3480 */
3481 @Override
3482 // TODO: API should just be about changing windowing modes...
3483 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003484 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003485 "moveTasksToFullscreenStack()");
3486 synchronized (mGlobalLock) {
3487 final long origId = Binder.clearCallingIdentity();
3488 try {
3489 final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
3490 if (stack != null){
3491 if (!stack.isActivityTypeStandardOrUndefined()) {
3492 throw new IllegalArgumentException(
3493 "You can't move tasks from non-standard stacks.");
3494 }
3495 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
3496 }
3497 } finally {
3498 Binder.restoreCallingIdentity(origId);
3499 }
3500 }
3501 }
3502
3503 /**
3504 * Moves the top activity in the input stackId to the pinned stack.
3505 *
3506 * @param stackId Id of stack to move the top activity to pinned stack.
3507 * @param bounds Bounds to use for pinned stack.
3508 *
3509 * @return True if the top activity of the input stack was successfully moved to the pinned
3510 * stack.
3511 */
3512 @Override
3513 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003514 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003515 "moveTopActivityToPinnedStack()");
3516 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003517 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003518 throw new IllegalStateException("moveTopActivityToPinnedStack:"
3519 + "Device doesn't support picture-in-picture mode");
3520 }
3521
3522 long ident = Binder.clearCallingIdentity();
3523 try {
3524 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
3525 } finally {
3526 Binder.restoreCallingIdentity(ident);
3527 }
3528 }
3529 }
3530
3531 @Override
3532 public boolean isInMultiWindowMode(IBinder token) {
3533 final long origId = Binder.clearCallingIdentity();
3534 try {
3535 synchronized (mGlobalLock) {
3536 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3537 if (r == null) {
3538 return false;
3539 }
3540 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
3541 return r.inMultiWindowMode();
3542 }
3543 } finally {
3544 Binder.restoreCallingIdentity(origId);
3545 }
3546 }
3547
3548 @Override
3549 public boolean isInPictureInPictureMode(IBinder token) {
3550 final long origId = Binder.clearCallingIdentity();
3551 try {
3552 synchronized (mGlobalLock) {
3553 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
3554 }
3555 } finally {
3556 Binder.restoreCallingIdentity(origId);
3557 }
3558 }
3559
3560 private boolean isInPictureInPictureMode(ActivityRecord r) {
3561 if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
3562 || r.getStack().isInStackLocked(r) == null) {
3563 return false;
3564 }
3565
3566 // If we are animating to fullscreen then we have already dispatched the PIP mode
3567 // changed, so we should reflect that check here as well.
3568 final PinnedActivityStack stack = r.getStack();
3569 final PinnedStackWindowController windowController = stack.getWindowContainerController();
3570 return !windowController.isAnimatingBoundsToFullscreen();
3571 }
3572
3573 @Override
3574 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
3575 final long origId = Binder.clearCallingIdentity();
3576 try {
3577 synchronized (mGlobalLock) {
3578 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3579 "enterPictureInPictureMode", token, params);
3580
3581 // If the activity is already in picture in picture mode, then just return early
3582 if (isInPictureInPictureMode(r)) {
3583 return true;
3584 }
3585
3586 // Activity supports picture-in-picture, now check that we can enter PiP at this
3587 // point, if it is
3588 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
3589 false /* beforeStopping */)) {
3590 return false;
3591 }
3592
3593 final Runnable enterPipRunnable = () -> {
Wale Ogunwalef276a6f2018-06-15 08:26:07 -07003594 synchronized (mGlobalLock) {
3595 // Only update the saved args from the args that are set
3596 r.pictureInPictureArgs.copyOnlySet(params);
3597 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
3598 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
3599 // Adjust the source bounds by the insets for the transition down
3600 final Rect sourceBounds = new Rect(
3601 r.pictureInPictureArgs.getSourceRectHint());
3602 mStackSupervisor.moveActivityToPinnedStackLocked(
3603 r, sourceBounds, aspectRatio, "enterPictureInPictureMode");
3604 final PinnedActivityStack stack = r.getStack();
3605 stack.setPictureInPictureAspectRatio(aspectRatio);
3606 stack.setPictureInPictureActions(actions);
3607 MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
3608 r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
3609 logPictureInPictureArgs(params);
3610 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003611 };
3612
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003613 if (isKeyguardLocked()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003614 // If the keyguard is showing or occluded, then try and dismiss it before
3615 // entering picture-in-picture (this will prompt the user to authenticate if the
3616 // device is currently locked).
3617 dismissKeyguard(token, new KeyguardDismissCallback() {
3618 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003619 public void onDismissSucceeded() {
3620 mH.post(enterPipRunnable);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003621 }
3622 }, null /* message */);
3623 } else {
3624 // Enter picture in picture immediately otherwise
3625 enterPipRunnable.run();
3626 }
3627 return true;
3628 }
3629 } finally {
3630 Binder.restoreCallingIdentity(origId);
3631 }
3632 }
3633
3634 @Override
3635 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
3636 final long origId = Binder.clearCallingIdentity();
3637 try {
3638 synchronized (mGlobalLock) {
3639 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3640 "setPictureInPictureParams", token, params);
3641
3642 // Only update the saved args from the args that are set
3643 r.pictureInPictureArgs.copyOnlySet(params);
3644 if (r.inPinnedWindowingMode()) {
3645 // If the activity is already in picture-in-picture, update the pinned stack now
3646 // if it is not already expanding to fullscreen. Otherwise, the arguments will
3647 // be used the next time the activity enters PiP
3648 final PinnedActivityStack stack = r.getStack();
3649 if (!stack.isAnimatingBoundsToFullscreen()) {
3650 stack.setPictureInPictureAspectRatio(
3651 r.pictureInPictureArgs.getAspectRatio());
3652 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
3653 }
3654 }
3655 logPictureInPictureArgs(params);
3656 }
3657 } finally {
3658 Binder.restoreCallingIdentity(origId);
3659 }
3660 }
3661
3662 @Override
3663 public int getMaxNumPictureInPictureActions(IBinder token) {
3664 // Currently, this is a static constant, but later, we may change this to be dependent on
3665 // the context of the activity
3666 return 3;
3667 }
3668
3669 private void logPictureInPictureArgs(PictureInPictureParams params) {
3670 if (params.hasSetActions()) {
3671 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
3672 params.getActions().size());
3673 }
3674 if (params.hasSetAspectRatio()) {
3675 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
3676 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
3677 MetricsLogger.action(lm);
3678 }
3679 }
3680
3681 /**
3682 * Checks the state of the system and the activity associated with the given {@param token} to
3683 * verify that picture-in-picture is supported for that activity.
3684 *
3685 * @return the activity record for the given {@param token} if all the checks pass.
3686 */
3687 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
3688 IBinder token, PictureInPictureParams params) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003689 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003690 throw new IllegalStateException(caller
3691 + ": Device doesn't support picture-in-picture mode.");
3692 }
3693
3694 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3695 if (r == null) {
3696 throw new IllegalStateException(caller
3697 + ": Can't find activity for token=" + token);
3698 }
3699
3700 if (!r.supportsPictureInPicture()) {
3701 throw new IllegalStateException(caller
3702 + ": Current activity does not support picture-in-picture.");
3703 }
3704
3705 if (params.hasSetAspectRatio()
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003706 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003707 params.getAspectRatio())) {
3708 final float minAspectRatio = mContext.getResources().getFloat(
3709 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
3710 final float maxAspectRatio = mContext.getResources().getFloat(
3711 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
3712 throw new IllegalArgumentException(String.format(caller
3713 + ": Aspect ratio is too extreme (must be between %f and %f).",
3714 minAspectRatio, maxAspectRatio));
3715 }
3716
3717 // Truncate the number of actions if necessary
3718 params.truncateActions(getMaxNumPictureInPictureActions(token));
3719
3720 return r;
3721 }
3722
3723 @Override
3724 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003725 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003726 synchronized (mGlobalLock) {
3727 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
3728 if (r == null) {
3729 throw new IllegalArgumentException("Activity does not exist; token="
3730 + activityToken);
3731 }
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07003732 return r.getUriPermissionsLocked().getExternalToken();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003733 }
3734 }
3735
3736 @Override
3737 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
3738 Rect tempDockedTaskInsetBounds,
3739 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003740 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003741 long ident = Binder.clearCallingIdentity();
3742 try {
3743 synchronized (mGlobalLock) {
3744 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
3745 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
3746 PRESERVE_WINDOWS);
3747 }
3748 } finally {
3749 Binder.restoreCallingIdentity(ident);
3750 }
3751 }
3752
3753 @Override
3754 public void setSplitScreenResizing(boolean resizing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003755 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003756 final long ident = Binder.clearCallingIdentity();
3757 try {
3758 synchronized (mGlobalLock) {
3759 mStackSupervisor.setSplitScreenResizing(resizing);
3760 }
3761 } finally {
3762 Binder.restoreCallingIdentity(ident);
3763 }
3764 }
3765
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003766 /**
3767 * Check that we have the features required for VR-related API calls, and throw an exception if
3768 * not.
3769 */
3770 void enforceSystemHasVrFeature() {
3771 if (!mContext.getPackageManager().hasSystemFeature(
3772 PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
3773 throw new UnsupportedOperationException("VR mode not supported on this device!");
3774 }
3775 }
3776
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003777 @Override
3778 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003779 enforceSystemHasVrFeature();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003780
3781 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3782
3783 ActivityRecord r;
3784 synchronized (mGlobalLock) {
3785 r = ActivityRecord.isInStackLocked(token);
3786 }
3787
3788 if (r == null) {
3789 throw new IllegalArgumentException();
3790 }
3791
3792 int err;
3793 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
3794 VrManagerInternal.NO_ERROR) {
3795 return err;
3796 }
3797
3798 // Clear the binder calling uid since this path may call moveToTask().
3799 final long callingId = Binder.clearCallingIdentity();
3800 try {
3801 synchronized (mGlobalLock) {
3802 r.requestedVrComponent = (enabled) ? packageName : null;
3803
3804 // Update associated state if this activity is currently focused
Andrii Kulian52d255c2018-07-13 11:32:19 -07003805 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003806 applyUpdateVrModeLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003807 }
3808 return 0;
3809 }
3810 } finally {
3811 Binder.restoreCallingIdentity(callingId);
3812 }
3813 }
3814
3815 @Override
3816 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
3817 Slog.i(TAG, "Activity tried to startLocalVoiceInteraction");
3818 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003819 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003820 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
3821 throw new SecurityException("Only focused activity can call startVoiceInteraction");
3822 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07003823 if (mRunningVoice != null || activity.getTask().voiceSession != null
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003824 || activity.voiceSession != null) {
3825 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
3826 return;
3827 }
3828 if (activity.pendingVoiceInteractionStart) {
3829 Slog.w(TAG, "Pending start of voice interaction already.");
3830 return;
3831 }
3832 activity.pendingVoiceInteractionStart = true;
3833 }
3834 LocalServices.getService(VoiceInteractionManagerInternal.class)
3835 .startLocalVoiceInteraction(callingActivity, options);
3836 }
3837
3838 @Override
3839 public void stopLocalVoiceInteraction(IBinder callingActivity) {
3840 LocalServices.getService(VoiceInteractionManagerInternal.class)
3841 .stopLocalVoiceInteraction(callingActivity);
3842 }
3843
3844 @Override
3845 public boolean supportsLocalVoiceInteraction() {
3846 return LocalServices.getService(VoiceInteractionManagerInternal.class)
3847 .supportsLocalVoiceInteraction();
3848 }
3849
3850 /** Notifies all listeners when the pinned stack animation starts. */
3851 @Override
3852 public void notifyPinnedStackAnimationStarted() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003853 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003854 }
3855
3856 /** Notifies all listeners when the pinned stack animation ends. */
3857 @Override
3858 public void notifyPinnedStackAnimationEnded() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003859 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003860 }
3861
3862 @Override
3863 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003864 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003865 final long ident = Binder.clearCallingIdentity();
3866 try {
3867 synchronized (mGlobalLock) {
3868 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
3869 }
3870 } finally {
3871 Binder.restoreCallingIdentity(ident);
3872 }
3873 }
3874
3875 @Override
3876 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003877 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003878
3879 synchronized (mGlobalLock) {
3880 // Check if display is initialized in AM.
3881 if (!mStackSupervisor.isDisplayAdded(displayId)) {
3882 // Call might come when display is not yet added or has already been removed.
3883 if (DEBUG_CONFIGURATION) {
3884 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
3885 + displayId);
3886 }
3887 return false;
3888 }
3889
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003890 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003891 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003892 values = mWindowManager.computeNewConfiguration(displayId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003893 }
3894
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003895 if (mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003896 // Update OOM levels based on display size.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003897 mAm.mProcessList.applyDisplaySize(mWindowManager);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003898 }
3899
3900 final long origId = Binder.clearCallingIdentity();
3901 try {
3902 if (values != null) {
3903 Settings.System.clearConfiguration(values);
3904 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003905 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003906 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
3907 return mTmpUpdateConfigurationResult.changes != 0;
3908 } finally {
3909 Binder.restoreCallingIdentity(origId);
3910 }
3911 }
3912 }
3913
3914 @Override
3915 public boolean updateConfiguration(Configuration values) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003916 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003917
3918 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003919 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003920 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003921 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003922 }
3923
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003924 if (mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003925 // Update OOM levels based on display size.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003926 mAm.mProcessList.applyDisplaySize(mWindowManager);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003927 }
3928
3929 final long origId = Binder.clearCallingIdentity();
3930 try {
3931 if (values != null) {
3932 Settings.System.clearConfiguration(values);
3933 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003934 updateConfigurationLocked(values, null, false, false /* persistent */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003935 UserHandle.USER_NULL, false /* deferResume */,
3936 mTmpUpdateConfigurationResult);
3937 return mTmpUpdateConfigurationResult.changes != 0;
3938 } finally {
3939 Binder.restoreCallingIdentity(origId);
3940 }
3941 }
3942 }
3943
3944 @Override
3945 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
3946 CharSequence message) {
3947 if (message != null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003948 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003949 Manifest.permission.SHOW_KEYGUARD_MESSAGE, "dismissKeyguard()");
3950 }
3951 final long callingId = Binder.clearCallingIdentity();
3952 try {
3953 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003954 mKeyguardController.dismissKeyguard(token, callback, message);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003955 }
3956 } finally {
3957 Binder.restoreCallingIdentity(callingId);
3958 }
3959 }
3960
3961 @Override
3962 public void cancelTaskWindowTransition(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003963 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003964 "cancelTaskWindowTransition()");
3965 final long ident = Binder.clearCallingIdentity();
3966 try {
3967 synchronized (mGlobalLock) {
3968 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
3969 MATCH_TASK_IN_STACKS_ONLY);
3970 if (task == null) {
3971 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
3972 return;
3973 }
3974 task.cancelWindowTransition();
3975 }
3976 } finally {
3977 Binder.restoreCallingIdentity(ident);
3978 }
3979 }
3980
3981 @Override
3982 public ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003983 enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003984 final long ident = Binder.clearCallingIdentity();
3985 try {
3986 final TaskRecord task;
3987 synchronized (mGlobalLock) {
3988 task = mStackSupervisor.anyTaskForIdLocked(taskId,
3989 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
3990 if (task == null) {
3991 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
3992 return null;
3993 }
3994 }
3995 // Don't call this while holding the lock as this operation might hit the disk.
3996 return task.getSnapshot(reducedResolution);
3997 } finally {
3998 Binder.restoreCallingIdentity(ident);
3999 }
4000 }
4001
4002 @Override
4003 public void setDisablePreviewScreenshots(IBinder token, boolean disable) {
4004 synchronized (mGlobalLock) {
4005 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4006 if (r == null) {
4007 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
4008 + token);
4009 return;
4010 }
4011 final long origId = Binder.clearCallingIdentity();
4012 try {
4013 r.setDisablePreviewScreenshots(disable);
4014 } finally {
4015 Binder.restoreCallingIdentity(origId);
4016 }
4017 }
4018 }
4019
4020 /** Return the user id of the last resumed activity. */
4021 @Override
4022 public @UserIdInt
4023 int getLastResumedActivityUserId() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004024 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004025 Manifest.permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
4026 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07004027 if (mLastResumedActivity == null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004028 return getCurrentUserId();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004029 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004030 return mLastResumedActivity.userId;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004031 }
4032 }
4033
4034 @Override
4035 public void updateLockTaskFeatures(int userId, int flags) {
4036 final int callingUid = Binder.getCallingUid();
4037 if (callingUid != 0 && callingUid != SYSTEM_UID) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004038 mAmInternal.enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004039 "updateLockTaskFeatures()");
4040 }
4041 synchronized (mGlobalLock) {
4042 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
4043 Integer.toHexString(flags));
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07004044 getLockTaskController().updateLockTaskFeatures(userId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004045 }
4046 }
4047
4048 @Override
4049 public void setShowWhenLocked(IBinder token, boolean showWhenLocked) {
4050 synchronized (mGlobalLock) {
4051 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4052 if (r == null) {
4053 return;
4054 }
4055 final long origId = Binder.clearCallingIdentity();
4056 try {
4057 r.setShowWhenLocked(showWhenLocked);
4058 } finally {
4059 Binder.restoreCallingIdentity(origId);
4060 }
4061 }
4062 }
4063
4064 @Override
4065 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) {
4066 synchronized (mGlobalLock) {
4067 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4068 if (r == null) {
4069 return;
4070 }
4071 final long origId = Binder.clearCallingIdentity();
4072 try {
4073 r.setTurnScreenOn(turnScreenOn);
4074 } finally {
4075 Binder.restoreCallingIdentity(origId);
4076 }
4077 }
4078 }
4079
4080 @Override
4081 public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004082 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004083 "registerRemoteAnimations");
4084 definition.setCallingPid(Binder.getCallingPid());
4085 synchronized (mGlobalLock) {
4086 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4087 if (r == null) {
4088 return;
4089 }
4090 final long origId = Binder.clearCallingIdentity();
4091 try {
4092 r.registerRemoteAnimations(definition);
4093 } finally {
4094 Binder.restoreCallingIdentity(origId);
4095 }
4096 }
4097 }
4098
4099 @Override
4100 public void registerRemoteAnimationForNextActivityStart(String packageName,
4101 RemoteAnimationAdapter adapter) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004102 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004103 "registerRemoteAnimationForNextActivityStart");
4104 adapter.setCallingPid(Binder.getCallingPid());
4105 synchronized (mGlobalLock) {
4106 final long origId = Binder.clearCallingIdentity();
4107 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07004108 getActivityStartController().registerRemoteAnimationForNextActivityStart(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004109 packageName, adapter);
4110 } finally {
4111 Binder.restoreCallingIdentity(origId);
4112 }
4113 }
4114 }
4115
4116 /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
4117 @Override
4118 public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
4119 synchronized (mGlobalLock) {
4120 final long origId = Binder.clearCallingIdentity();
4121 try {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004122 mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004123 } finally {
4124 Binder.restoreCallingIdentity(origId);
4125 }
4126 }
4127 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004128
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004129 @Override
4130 public void setVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004131 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004132 synchronized (mGlobalLock) {
4133 synchronized (mAm.mPidsSelfLocked) {
4134 final int pid = Binder.getCallingPid();
4135 final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004136 mVrController.setVrThreadLocked(tid, pid, proc.getWindowProcessController());
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004137 }
4138 }
4139 }
4140
4141 @Override
4142 public void setPersistentVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004143 if (checkCallingPermission(Manifest.permission.RESTRICTED_VR_ACCESS)
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004144 != PERMISSION_GRANTED) {
4145 final String msg = "Permission Denial: setPersistentVrThread() from pid="
4146 + Binder.getCallingPid()
4147 + ", uid=" + Binder.getCallingUid()
4148 + " requires " + Manifest.permission.RESTRICTED_VR_ACCESS;
4149 Slog.w(TAG, msg);
4150 throw new SecurityException(msg);
4151 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004152 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004153 synchronized (mGlobalLock) {
4154 synchronized (mAm.mPidsSelfLocked) {
4155 final int pid = Binder.getCallingPid();
4156 final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
4157 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
4158 }
4159 }
4160 }
4161
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004162 @Override
4163 public void stopAppSwitches() {
4164 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
4165 synchronized (mGlobalLock) {
4166 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME;
4167 mDidAppSwitch = false;
4168 getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
4169 }
4170 }
4171
4172 @Override
4173 public void resumeAppSwitches() {
4174 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
4175 synchronized (mGlobalLock) {
4176 // Note that we don't execute any pending app switches... we will
4177 // let those wait until either the timeout, or the next start
4178 // activity request.
4179 mAppSwitchesAllowedTime = 0;
4180 }
4181 }
4182
4183 void onStartActivitySetDidAppSwitch() {
4184 if (mDidAppSwitch) {
4185 // This is the second allowed switch since we stopped switches, so now just generally
4186 // allow switches. Use case:
4187 // - user presses home (switches disabled, switch to home, mDidAppSwitch now true);
4188 // - user taps a home icon (coming from home so allowed, we hit here and now allow
4189 // anyone to switch again).
4190 mAppSwitchesAllowedTime = 0;
4191 } else {
4192 mDidAppSwitch = true;
4193 }
4194 }
4195
4196 /** @return whether the system should disable UI modes incompatible with VR mode. */
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004197 boolean shouldDisableNonVrUiLocked() {
4198 return mVrController.shouldDisableNonVrUiLocked();
4199 }
4200
Wale Ogunwale53783742018-09-16 10:21:51 -07004201 private void applyUpdateVrModeLocked(ActivityRecord r) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004202 // VR apps are expected to run in a main display. If an app is turning on VR for
4203 // itself, but lives in a dynamic stack, then make sure that it is moved to the main
4204 // fullscreen stack before enabling VR Mode.
4205 // TODO: The goal of this code is to keep the VR app on the main display. When the
4206 // stack implementation changes in the future, keep in mind that the use of the fullscreen
4207 // stack is a means to move the activity to the main display and a moveActivityToDisplay()
4208 // option would be a better choice here.
4209 if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
4210 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
4211 + " to main stack for VR");
4212 final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
4213 WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
4214 moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
4215 }
4216 mH.post(() -> {
4217 if (!mVrController.onVrModeChanged(r)) {
4218 return;
4219 }
4220 synchronized (mGlobalLock) {
4221 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
4222 mWindowManager.disableNonVrUi(disableNonVrUi);
4223 if (disableNonVrUi) {
4224 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
4225 // then remove the pinned stack.
4226 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
4227 }
4228 }
4229 });
4230 }
4231
Wale Ogunwale53783742018-09-16 10:21:51 -07004232 @Override
4233 public int getPackageScreenCompatMode(String packageName) {
4234 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4235 synchronized (mGlobalLock) {
4236 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4237 }
4238 }
4239
4240 @Override
4241 public void setPackageScreenCompatMode(String packageName, int mode) {
4242 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4243 "setPackageScreenCompatMode");
4244 synchronized (mGlobalLock) {
4245 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4246 }
4247 }
4248
4249 @Override
4250 public boolean getPackageAskScreenCompat(String packageName) {
4251 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4252 synchronized (mGlobalLock) {
4253 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4254 }
4255 }
4256
4257 @Override
4258 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4259 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4260 "setPackageAskScreenCompat");
4261 synchronized (mGlobalLock) {
4262 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4263 }
4264 }
4265
Andrii Kulian5f750bc2018-07-17 08:57:23 -07004266 ActivityStack getTopDisplayFocusedStack() {
4267 return mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004268 }
4269
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004270 /** Pokes the task persister. */
4271 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
4272 mRecentTasks.notifyTaskPersisterLocked(task, flush);
4273 }
4274
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004275 void onTopProcChangedLocked(WindowProcessController proc) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004276 mVrController.onTopProcChangedLocked(proc);
4277 }
4278
4279 boolean isKeyguardLocked() {
4280 return mKeyguardController.isKeyguardLocked();
4281 }
4282
4283 boolean isNextTransitionForward() {
4284 int transit = mWindowManager.getPendingAppTransition();
4285 return transit == TRANSIT_ACTIVITY_OPEN
4286 || transit == TRANSIT_TASK_OPEN
4287 || transit == TRANSIT_TASK_TO_FRONT;
4288 }
4289
Wale Ogunwalef6733932018-06-27 05:14:34 -07004290 void dumpSleepStates(PrintWriter pw, boolean testPssMode) {
4291 synchronized (mGlobalLock) {
4292 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
4293 if (mRunningVoice != null) {
4294 pw.println(" mRunningVoice=" + mRunningVoice);
4295 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
4296 }
4297 pw.println(" mSleeping=" + mSleeping);
4298 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + testPssMode);
4299 pw.println(" mVrController=" + mVrController);
4300 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004301 }
4302
Wale Ogunwalef6733932018-06-27 05:14:34 -07004303 void writeSleepStateToProto(ProtoOutputStream proto) {
4304 for (ActivityTaskManagerInternal.SleepToken st : mStackSupervisor.mSleepTokens) {
4305 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS,
4306 st.toString());
4307 }
4308
4309 if (mRunningVoice != null) {
4310 final long vrToken = proto.start(
4311 ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
4312 proto.write(ActivityManagerServiceDumpProcessesProto.Voice.SESSION,
4313 mRunningVoice.toString());
4314 mVoiceWakeLock.writeToProto(
4315 proto, ActivityManagerServiceDumpProcessesProto.Voice.WAKELOCK);
4316 proto.end(vrToken);
4317 }
4318
4319 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
4320 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN,
4321 mShuttingDown);
4322 mVrController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004323 }
4324
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004325 int getCurrentUserId() {
4326 return mAmInternal.getCurrentUserId();
4327 }
4328
4329 private void enforceNotIsolatedCaller(String caller) {
4330 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4331 throw new SecurityException("Isolated process not allowed to call " + caller);
4332 }
4333 }
4334
Wale Ogunwalef6733932018-06-27 05:14:34 -07004335 public Configuration getConfiguration() {
4336 Configuration ci;
4337 synchronized(mGlobalLock) {
Yunfan Chen75157d72018-07-27 14:47:21 +09004338 ci = new Configuration(getGlobalConfigurationForCallingPid());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004339 ci.userSetLocale = false;
4340 }
4341 return ci;
4342 }
4343
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004344 /**
4345 * Current global configuration information. Contains general settings for the entire system,
4346 * also corresponds to the merged configuration of the default display.
4347 */
4348 Configuration getGlobalConfiguration() {
4349 return mStackSupervisor.getConfiguration();
4350 }
4351
4352 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4353 boolean initLocale) {
4354 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
4355 }
4356
4357 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4358 boolean initLocale, boolean deferResume) {
4359 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
4360 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
4361 UserHandle.USER_NULL, deferResume);
4362 }
4363
4364 void updatePersistentConfiguration(Configuration values, @UserIdInt int userId) {
4365 final long origId = Binder.clearCallingIdentity();
4366 try {
4367 synchronized (mGlobalLock) {
4368 updateConfigurationLocked(values, null, false, true, userId,
4369 false /* deferResume */);
4370 }
4371 } finally {
4372 Binder.restoreCallingIdentity(origId);
4373 }
4374 }
4375
4376 void updateUserConfiguration() {
4377 synchronized (mGlobalLock) {
4378 final Configuration configuration = new Configuration(getGlobalConfiguration());
4379 final int currentUserId = mAmInternal.getCurrentUserId();
4380 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
4381 currentUserId, Settings.System.canWrite(mContext));
4382 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
4383 false /* persistent */, currentUserId, false /* deferResume */);
4384 }
4385 }
4386
4387 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4388 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
4389 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
4390 deferResume, null /* result */);
4391 }
4392
4393 /**
4394 * Do either or both things: (1) change the current configuration, and (2)
4395 * make sure the given activity is running with the (now) current
4396 * configuration. Returns true if the activity has been left running, or
4397 * false if <var>starting</var> is being destroyed to match the new
4398 * configuration.
4399 *
4400 * @param userId is only used when persistent parameter is set to true to persist configuration
4401 * for that particular user
4402 */
4403 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4404 boolean initLocale, boolean persistent, int userId, boolean deferResume,
4405 ActivityTaskManagerService.UpdateConfigurationResult result) {
4406 int changes = 0;
4407 boolean kept = true;
4408
4409 if (mWindowManager != null) {
4410 mWindowManager.deferSurfaceLayout();
4411 }
4412 try {
4413 if (values != null) {
4414 changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
4415 deferResume);
4416 }
4417
4418 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4419 } finally {
4420 if (mWindowManager != null) {
4421 mWindowManager.continueSurfaceLayout();
4422 }
4423 }
4424
4425 if (result != null) {
4426 result.changes = changes;
4427 result.activityRelaunched = !kept;
4428 }
4429 return kept;
4430 }
4431
4432 /**
4433 * Returns true if this configuration change is interesting enough to send an
4434 * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
4435 */
4436 private static boolean isSplitConfigurationChange(int configDiff) {
4437 return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
4438 }
4439
4440 /** Update default (global) configuration and notify listeners about changes. */
4441 private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
4442 boolean persistent, int userId, boolean deferResume) {
4443 mTempConfig.setTo(getGlobalConfiguration());
4444 final int changes = mTempConfig.updateFrom(values);
4445 if (changes == 0) {
4446 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
4447 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
4448 // performDisplayOverrideConfigUpdate in order to send the new display configuration
4449 // (even if there are no actual changes) to unfreeze the window.
4450 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
4451 return 0;
4452 }
4453
4454 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
4455 "Updating global configuration to: " + values);
4456
4457 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
4458 StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
4459 values.colorMode,
4460 values.densityDpi,
4461 values.fontScale,
4462 values.hardKeyboardHidden,
4463 values.keyboard,
4464 values.keyboardHidden,
4465 values.mcc,
4466 values.mnc,
4467 values.navigation,
4468 values.navigationHidden,
4469 values.orientation,
4470 values.screenHeightDp,
4471 values.screenLayout,
4472 values.screenWidthDp,
4473 values.smallestScreenWidthDp,
4474 values.touchscreen,
4475 values.uiMode);
4476
4477
4478 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
4479 final LocaleList locales = values.getLocales();
4480 int bestLocaleIndex = 0;
4481 if (locales.size() > 1) {
4482 if (mSupportedSystemLocales == null) {
4483 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
4484 }
4485 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
4486 }
4487 SystemProperties.set("persist.sys.locale",
4488 locales.get(bestLocaleIndex).toLanguageTag());
4489 LocaleList.setDefault(locales, bestLocaleIndex);
4490 mAm.mHandler.sendMessage(mAm.mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
4491 locales.get(bestLocaleIndex)));
4492 }
4493
Yunfan Chen75157d72018-07-27 14:47:21 +09004494 mTempConfig.seq = increaseConfigurationSeqLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004495
4496 // Update stored global config and notify everyone about the change.
4497 mStackSupervisor.onConfigurationChanged(mTempConfig);
4498
4499 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
4500 // TODO(multi-display): Update UsageEvents#Event to include displayId.
4501 mAm.mUsageStatsService.reportConfigurationChange(
4502 mTempConfig, mAmInternal.getCurrentUserId());
4503
4504 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
Wale Ogunwalef6733932018-06-27 05:14:34 -07004505 updateShouldShowDialogsLocked(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004506
4507 AttributeCache ac = AttributeCache.instance();
4508 if (ac != null) {
4509 ac.updateConfiguration(mTempConfig);
4510 }
4511
4512 // Make sure all resources in our process are updated right now, so that anyone who is going
4513 // to retrieve resource values after we return will be sure to get the new ones. This is
4514 // especially important during boot, where the first config change needs to guarantee all
4515 // resources have that config before following boot code is executed.
4516 mAm.mSystemThread.applyConfigurationToResources(mTempConfig);
4517
4518 // We need another copy of global config because we're scheduling some calls instead of
4519 // running them in place. We need to be sure that object we send will be handled unchanged.
4520 final Configuration configCopy = new Configuration(mTempConfig);
4521 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
4522 Message msg = mAm.mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
4523 msg.obj = configCopy;
4524 msg.arg1 = userId;
4525 mAm.mHandler.sendMessage(msg);
4526 }
4527
Yunfan Chen75157d72018-07-27 14:47:21 +09004528 // TODO: Consider using mPidMap to update configurations for processes.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004529 for (int i = mAm.mLruProcesses.size() - 1; i >= 0; i--) {
4530 ProcessRecord app = mAm.mLruProcesses.get(i);
4531 try {
4532 if (app.thread != null) {
4533 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
4534 + app.processName + " new config " + configCopy);
4535 getLifecycleManager().scheduleTransaction(app.thread,
4536 ConfigurationChangeItem.obtain(configCopy));
4537 }
4538 } catch (Exception e) {
4539 Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
4540 }
4541 }
4542
4543 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
4544 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
4545 | Intent.FLAG_RECEIVER_FOREGROUND
4546 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4547 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4548 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4549 UserHandle.USER_ALL);
4550 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
4551 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
4552 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
4553 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
4554 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4555 if (initLocale || !mAm.mProcessesReady) {
4556 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
4557 }
4558 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4559 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4560 UserHandle.USER_ALL);
4561 }
4562
4563 // Send a broadcast to PackageInstallers if the configuration change is interesting
4564 // for the purposes of installing additional splits.
4565 if (!initLocale && isSplitConfigurationChange(changes)) {
4566 intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
4567 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
4568 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
4569
4570 // Typically only app stores will have this permission.
4571 String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES };
4572 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions,
4573 OP_NONE, null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
4574 }
4575
4576 // Override configuration of the default display duplicates global config, so we need to
4577 // update it also. This will also notify WindowManager about changes.
4578 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
4579 DEFAULT_DISPLAY);
4580
4581 return changes;
4582 }
4583
4584 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
4585 boolean deferResume, int displayId) {
4586 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
4587 displayId, null /* result */);
4588 }
4589
4590 /**
4591 * Updates override configuration specific for the selected display. If no config is provided,
4592 * new one will be computed in WM based on current display info.
4593 */
4594 boolean updateDisplayOverrideConfigurationLocked(Configuration values,
4595 ActivityRecord starting, boolean deferResume, int displayId,
4596 ActivityTaskManagerService.UpdateConfigurationResult result) {
4597 int changes = 0;
4598 boolean kept = true;
4599
4600 if (mWindowManager != null) {
4601 mWindowManager.deferSurfaceLayout();
4602 }
4603 try {
4604 if (values != null) {
4605 if (displayId == DEFAULT_DISPLAY) {
4606 // Override configuration of the default display duplicates global config, so
4607 // we're calling global config update instead for default display. It will also
4608 // apply the correct override config.
4609 changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
4610 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
4611 } else {
4612 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
4613 }
4614 }
4615
4616 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4617 } finally {
4618 if (mWindowManager != null) {
4619 mWindowManager.continueSurfaceLayout();
4620 }
4621 }
4622
4623 if (result != null) {
4624 result.changes = changes;
4625 result.activityRelaunched = !kept;
4626 }
4627 return kept;
4628 }
4629
4630 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
4631 int displayId) {
4632 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
4633 final int changes = mTempConfig.updateFrom(values);
4634 if (changes != 0) {
4635 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
4636 + mTempConfig + " for displayId=" + displayId);
4637 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
4638
4639 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
4640 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004641 mAppWarnings.onDensityChanged();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004642
4643 mAm.killAllBackgroundProcessesExcept(N,
4644 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
4645 }
4646 }
4647
4648 // Update the configuration with WM first and check if any of the stacks need to be resized
4649 // due to the configuration change. If so, resize the stacks now and do any relaunches if
4650 // necessary. This way we don't need to relaunch again afterwards in
4651 // ensureActivityConfiguration().
4652 if (mWindowManager != null) {
4653 final int[] resizedStacks =
4654 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
4655 if (resizedStacks != null) {
4656 for (int stackId : resizedStacks) {
4657 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
4658 }
4659 }
4660 }
4661
4662 return changes;
4663 }
4664
Wale Ogunwalef6733932018-06-27 05:14:34 -07004665 private void updateEventDispatchingLocked(boolean booted) {
4666 mWindowManager.setEventDispatching(booted && !mShuttingDown);
4667 }
4668
4669 void enableScreenAfterBoot(boolean booted) {
4670 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4671 SystemClock.uptimeMillis());
4672 mWindowManager.enableScreenAfterBoot();
4673
4674 synchronized (mGlobalLock) {
4675 updateEventDispatchingLocked(booted);
4676 }
4677 }
4678
4679 boolean canShowErrorDialogs() {
4680 return mShowDialogs && !mSleeping && !mShuttingDown
4681 && !mKeyguardController.isKeyguardOrAodShowing(DEFAULT_DISPLAY)
4682 && !hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
Wale Ogunwale86b74462018-07-02 08:42:43 -07004683 mAmInternal.getCurrentUserId())
Wale Ogunwalef6733932018-06-27 05:14:34 -07004684 && !(UserManager.isDeviceInDemoMode(mContext)
Wale Ogunwale86b74462018-07-02 08:42:43 -07004685 && mAmInternal.getCurrentUser().isDemo());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004686 }
4687
Wale Ogunwale906f9c62018-07-23 11:23:44 -07004688 static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
4689 if (r == null || !r.hasProcess()) {
4690 return KEY_DISPATCHING_TIMEOUT_MS;
4691 }
4692 return getInputDispatchingTimeoutLocked(r.app);
4693 }
4694
4695 private static long getInputDispatchingTimeoutLocked(WindowProcessController r) {
4696 if (r != null && (r.isInstrumenting() || r.isUsingWrapper())) {
4697 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS;
4698 }
4699 return KEY_DISPATCHING_TIMEOUT_MS;
4700 }
4701
4702 long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
4703 if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
4704 throw new SecurityException("Requires permission " + FILTER_EVENTS);
4705 }
4706 WindowProcessController proc;
4707 long timeout;
4708 synchronized (mGlobalLock) {
4709 proc = mPidMap.get(pid);
4710 timeout = getInputDispatchingTimeoutLocked(proc);
4711 }
4712
4713 if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
4714 return -1;
4715 }
4716
4717 return timeout;
4718 }
4719
4720 /**
4721 * Handle input dispatching timeouts.
4722 * Returns whether input dispatching should be aborted or not.
4723 */
4724 boolean inputDispatchingTimedOut(final WindowProcessController proc,
4725 final ActivityRecord activity, final ActivityRecord parent,
4726 final boolean aboveSystem, String reason) {
4727 if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
4728 throw new SecurityException("Requires permission " + FILTER_EVENTS);
4729 }
4730
4731 final String annotation;
4732 if (reason == null) {
4733 annotation = "Input dispatching timed out";
4734 } else {
4735 annotation = "Input dispatching timed out (" + reason + ")";
4736 }
4737
4738 if (proc != null) {
4739 synchronized (mGlobalLock) {
4740 if (proc.isDebugging()) {
4741 return false;
4742 }
4743
4744 if (proc.isInstrumenting()) {
4745 Bundle info = new Bundle();
4746 info.putString("shortMsg", "keyDispatchingTimedOut");
4747 info.putString("longMsg", annotation);
4748 mAm.finishInstrumentationLocked(
4749 (ProcessRecord) proc.mOwner, Activity.RESULT_CANCELED, info);
4750 return true;
4751 }
4752 }
4753 mH.post(() -> {
4754 mAm.mAppErrors.appNotResponding(
4755 (ProcessRecord) proc.mOwner, activity, parent, aboveSystem, annotation);
4756 });
4757 }
4758
4759 return true;
4760 }
4761
Wale Ogunwalef6733932018-06-27 05:14:34 -07004762 /**
4763 * Decide based on the configuration whether we should show the ANR,
4764 * crash, etc dialogs. The idea is that if there is no affordance to
4765 * press the on-screen buttons, or the user experience would be more
4766 * greatly impacted than the crash itself, we shouldn't show the dialog.
4767 *
4768 * A thought: SystemUI might also want to get told about this, the Power
4769 * dialog / global actions also might want different behaviors.
4770 */
4771 private void updateShouldShowDialogsLocked(Configuration config) {
4772 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
4773 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
4774 && config.navigation == Configuration.NAVIGATION_NONAV);
4775 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
4776 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
4777 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
4778 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
4779 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
4780 final boolean hideDialogsSet = Settings.Global.getInt(mContext.getContentResolver(),
4781 HIDE_ERROR_DIALOGS, 0) != 0;
4782 mShowDialogs = inputMethodExists && uiModeSupportsDialogs && !hideDialogsSet;
4783 }
4784
4785 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
4786 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
4787 FONT_SCALE, 1.0f, userId);
4788
4789 synchronized (this) {
4790 if (getGlobalConfiguration().fontScale == scaleFactor) {
4791 return;
4792 }
4793
4794 final Configuration configuration
4795 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
4796 configuration.fontScale = scaleFactor;
4797 updatePersistentConfiguration(configuration, userId);
4798 }
4799 }
4800
4801 // Actually is sleeping or shutting down or whatever else in the future
4802 // is an inactive state.
4803 boolean isSleepingOrShuttingDownLocked() {
4804 return isSleepingLocked() || mShuttingDown;
4805 }
4806
4807 boolean isSleepingLocked() {
4808 return mSleeping;
4809 }
4810
Riddle Hsu16567132018-08-16 21:37:47 +08004811 /** Update AMS states when an activity is resumed. */
Wale Ogunwalef6733932018-06-27 05:14:34 -07004812 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
4813 final TaskRecord task = r.getTask();
4814 if (task.isActivityTypeStandard()) {
4815 if (mCurAppTimeTracker != r.appTimeTracker) {
4816 // We are switching app tracking. Complete the current one.
4817 if (mCurAppTimeTracker != null) {
4818 mCurAppTimeTracker.stop();
4819 mH.obtainMessage(
4820 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
4821 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
4822 mCurAppTimeTracker = null;
4823 }
4824 if (r.appTimeTracker != null) {
4825 mCurAppTimeTracker = r.appTimeTracker;
4826 startTimeTrackingFocusedActivityLocked();
4827 }
4828 } else {
4829 startTimeTrackingFocusedActivityLocked();
4830 }
4831 } else {
4832 r.appTimeTracker = null;
4833 }
4834 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
4835 // TODO: Probably not, because we don't want to resume voice on switching
4836 // back to this activity
4837 if (task.voiceInteractor != null) {
4838 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
4839 } else {
4840 finishRunningVoiceLocked();
4841
4842 if (mLastResumedActivity != null) {
4843 final IVoiceInteractionSession session;
4844
4845 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
4846 if (lastResumedActivityTask != null
4847 && lastResumedActivityTask.voiceSession != null) {
4848 session = lastResumedActivityTask.voiceSession;
4849 } else {
4850 session = mLastResumedActivity.voiceSession;
4851 }
4852
4853 if (session != null) {
4854 // We had been in a voice interaction session, but now focused has
4855 // move to something different. Just finish the session, we can't
4856 // return to it and retain the proper state and synchronization with
4857 // the voice interaction service.
4858 finishVoiceTask(session);
4859 }
4860 }
4861 }
4862
4863 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
4864 mAmInternal.sendForegroundProfileChanged(r.userId);
4865 }
4866 updateResumedAppTrace(r);
4867 mLastResumedActivity = r;
4868
Tiger Huang1e5b10a2018-07-30 20:19:51 +08004869 r.getDisplay().setFocusedApp(r, true);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004870
4871 applyUpdateLockStateLocked(r);
4872 applyUpdateVrModeLocked(r);
4873
4874 EventLogTags.writeAmSetResumedActivity(
4875 r == null ? -1 : r.userId,
4876 r == null ? "NULL" : r.shortComponentName,
4877 reason);
4878 }
4879
4880 ActivityTaskManagerInternal.SleepToken acquireSleepToken(String tag, int displayId) {
4881 synchronized (mGlobalLock) {
4882 final ActivityTaskManagerInternal.SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
4883 updateSleepIfNeededLocked();
4884 return token;
4885 }
4886 }
4887
4888 void updateSleepIfNeededLocked() {
4889 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
4890 final boolean wasSleeping = mSleeping;
4891 boolean updateOomAdj = false;
4892
4893 if (!shouldSleep) {
4894 // If wasSleeping is true, we need to wake up activity manager state from when
4895 // we started sleeping. In either case, we need to apply the sleep tokens, which
4896 // will wake up stacks or put them to sleep as appropriate.
4897 if (wasSleeping) {
4898 mSleeping = false;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07004899 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
4900 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__AWAKE);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004901 startTimeTrackingFocusedActivityLocked();
4902 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
4903 mStackSupervisor.comeOutOfSleepIfNeededLocked();
4904 }
4905 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
4906 if (wasSleeping) {
4907 updateOomAdj = true;
4908 }
4909 } else if (!mSleeping && shouldSleep) {
4910 mSleeping = true;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07004911 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
4912 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__ASLEEP);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004913 if (mCurAppTimeTracker != null) {
4914 mCurAppTimeTracker.stop();
4915 }
4916 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
4917 mStackSupervisor.goingToSleepLocked();
4918 updateResumedAppTrace(null /* resumed */);
4919 updateOomAdj = true;
4920 }
4921 if (updateOomAdj) {
4922 mH.post(mAmInternal::updateOomAdj);
4923 }
4924 }
4925
4926 void updateOomAdj() {
4927 mH.post(mAmInternal::updateOomAdj);
4928 }
4929
Wale Ogunwale53783742018-09-16 10:21:51 -07004930 void updateCpuStats() {
4931 mH.post(mAmInternal::updateCpuStats);
4932 }
4933
4934 void updateUsageStats(ActivityRecord component, boolean resumed) {
4935 final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::updateUsageStats,
4936 mAmInternal, component.realActivity, component.app.mUid, component.userId, resumed);
4937 mH.sendMessage(m);
4938 }
4939
4940 void setBooting(boolean booting) {
4941 mAmInternal.setBooting(booting);
4942 }
4943
4944 boolean isBooting() {
4945 return mAmInternal.isBooting();
4946 }
4947
4948 void setBooted(boolean booted) {
4949 mAmInternal.setBooted(booted);
4950 }
4951
4952 boolean isBooted() {
4953 return mAmInternal.isBooted();
4954 }
4955
4956 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
4957 mH.post(() -> {
4958 if (finishBooting) {
4959 mAmInternal.finishBooting();
4960 }
4961 if (enableScreen) {
4962 mInternal.enableScreenAfterBoot(isBooted());
4963 }
4964 });
4965 }
4966
4967 void setHeavyWeightProcess(ActivityRecord root) {
4968 mHeavyWeightProcess = root.app;
4969 final Message m = PooledLambda.obtainMessage(
4970 ActivityTaskManagerService::postHeavyWeightProcessNotification, this,
4971 root.app, root.intent, root.userId);
4972 mH.sendMessage(m);
4973 }
4974
4975 void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
4976 if (mHeavyWeightProcess == null || mHeavyWeightProcess != proc) {
4977 return;
4978 }
4979
4980 mHeavyWeightProcess = null;
4981 final Message m = PooledLambda.obtainMessage(
4982 ActivityTaskManagerService::cancelHeavyWeightProcessNotification, this,
4983 proc.mUserId);
4984 mH.sendMessage(m);
4985 }
4986
4987 private void cancelHeavyWeightProcessNotification(int userId) {
4988 final INotificationManager inm = NotificationManager.getService();
4989 if (inm == null) {
4990 return;
4991 }
4992 try {
4993 inm.cancelNotificationWithTag("android", null,
4994 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, userId);
4995 } catch (RuntimeException e) {
4996 Slog.w(TAG, "Error canceling notification for service", e);
4997 } catch (RemoteException e) {
4998 }
4999
5000 }
5001
5002 private void postHeavyWeightProcessNotification(
5003 WindowProcessController proc, Intent intent, int userId) {
5004 if (proc == null) {
5005 return;
5006 }
5007
5008 final INotificationManager inm = NotificationManager.getService();
5009 if (inm == null) {
5010 return;
5011 }
5012
5013 try {
5014 Context context = mContext.createPackageContext(proc.mInfo.packageName, 0);
5015 String text = mContext.getString(R.string.heavy_weight_notification,
5016 context.getApplicationInfo().loadLabel(context.getPackageManager()));
5017 Notification notification =
5018 new Notification.Builder(context,
5019 SystemNotificationChannels.HEAVY_WEIGHT_APP)
5020 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
5021 .setWhen(0)
5022 .setOngoing(true)
5023 .setTicker(text)
5024 .setColor(mContext.getColor(
5025 com.android.internal.R.color.system_notification_accent_color))
5026 .setContentTitle(text)
5027 .setContentText(
5028 mContext.getText(R.string.heavy_weight_notification_detail))
5029 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
5030 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
5031 new UserHandle(userId)))
5032 .build();
5033 try {
5034 inm.enqueueNotificationWithTag("android", "android", null,
5035 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, notification, userId);
5036 } catch (RuntimeException e) {
5037 Slog.w(TAG, "Error showing notification for heavy-weight app", e);
5038 } catch (RemoteException e) {
5039 }
5040 } catch (PackageManager.NameNotFoundException e) {
5041 Slog.w(TAG, "Unable to create context for heavy notification", e);
5042 }
5043
5044 }
5045
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07005046 IIntentSender getIntentSenderLocked(int type, String packageName, int callingUid, int userId,
5047 IBinder token, String resultWho, int requestCode, Intent[] intents,
5048 String[] resolvedTypes, int flags, Bundle bOptions) {
5049
5050 ActivityRecord activity = null;
5051 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5052 activity = ActivityRecord.isInStackLocked(token);
5053 if (activity == null) {
5054 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
5055 return null;
5056 }
5057 if (activity.finishing) {
5058 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
5059 return null;
5060 }
5061 }
5062
5063 final PendingIntentRecord rec = mPendingIntentController.getIntentSender(type, packageName,
5064 callingUid, userId, token, resultWho, requestCode, intents, resolvedTypes, flags,
5065 bOptions);
5066 final boolean noCreate = (flags & PendingIntent.FLAG_NO_CREATE) != 0;
5067 if (noCreate) {
5068 return rec;
5069 }
5070 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5071 if (activity.pendingResults == null) {
5072 activity.pendingResults = new HashSet<>();
5073 }
5074 activity.pendingResults.add(rec.ref);
5075 }
5076 return rec;
5077 }
5078
Andrii Kulian52d255c2018-07-13 11:32:19 -07005079 // TODO(b/111541062): Update app time tracking to make it aware of multiple resumed activities
Wale Ogunwalef6733932018-06-27 05:14:34 -07005080 private void startTimeTrackingFocusedActivityLocked() {
Andrii Kulian52d255c2018-07-13 11:32:19 -07005081 final ActivityRecord resumedActivity = mStackSupervisor.getTopResumedActivity();
Wale Ogunwalef6733932018-06-27 05:14:34 -07005082 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
5083 mCurAppTimeTracker.start(resumedActivity.packageName);
5084 }
5085 }
5086
5087 private void updateResumedAppTrace(@Nullable ActivityRecord resumed) {
5088 if (mTracedResumedActivity != null) {
5089 Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER,
5090 constructResumedTraceName(mTracedResumedActivity.packageName), 0);
5091 }
5092 if (resumed != null) {
5093 Trace.asyncTraceBegin(TRACE_TAG_ACTIVITY_MANAGER,
5094 constructResumedTraceName(resumed.packageName), 0);
5095 }
5096 mTracedResumedActivity = resumed;
5097 }
5098
5099 private String constructResumedTraceName(String packageName) {
5100 return "focused app: " + packageName;
5101 }
5102
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005103 /** Helper method that requests bounds from WM and applies them to stack. */
5104 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
5105 final Rect newStackBounds = new Rect();
5106 final ActivityStack stack = mStackSupervisor.getStack(stackId);
5107
5108 // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
5109 if (stack == null) {
5110 final StringWriter writer = new StringWriter();
5111 final PrintWriter printWriter = new PrintWriter(writer);
5112 mStackSupervisor.dumpDisplays(printWriter);
5113 printWriter.flush();
5114
5115 Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
5116 }
5117
5118 stack.getBoundsForNewConfiguration(newStackBounds);
5119 mStackSupervisor.resizeStackLocked(
5120 stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
5121 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
5122 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
5123 }
5124
5125 /** Applies latest configuration and/or visibility updates if needed. */
5126 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
5127 boolean kept = true;
Andrii Kulian5f750bc2018-07-17 08:57:23 -07005128 final ActivityStack mainStack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005129 // mainStack is null during startup.
5130 if (mainStack != null) {
5131 if (changes != 0 && starting == null) {
5132 // If the configuration changed, and the caller is not already
5133 // in the process of starting an activity, then find the top
5134 // activity to check if its configuration needs to change.
5135 starting = mainStack.topRunningActivityLocked();
5136 }
5137
5138 if (starting != null) {
5139 kept = starting.ensureActivityConfiguration(changes,
5140 false /* preserveWindow */);
5141 // And we need to make sure at this point that all other activities
5142 // are made visible with the correct configuration.
5143 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
5144 !PRESERVE_WINDOWS);
5145 }
5146 }
5147
5148 return kept;
5149 }
5150
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005151 void scheduleAppGcsLocked() {
5152 mH.post(() -> mAmInternal.scheduleAppGcs());
5153 }
5154
Wale Ogunwale53783742018-09-16 10:21:51 -07005155 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
5156 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
5157 }
5158
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005159 /**
5160 * Returns the PackageManager. Used by classes hosted by {@link ActivityTaskManagerService}. The
5161 * PackageManager could be unavailable at construction time and therefore needs to be accessed
5162 * on demand.
5163 */
5164 IPackageManager getPackageManager() {
5165 return AppGlobals.getPackageManager();
5166 }
5167
5168 PackageManagerInternal getPackageManagerInternalLocked() {
5169 if (mPmInternal == null) {
5170 mPmInternal = LocalServices.getService(PackageManagerInternal.class);
5171 }
5172 return mPmInternal;
5173 }
5174
Wale Ogunwale008163e2018-07-23 23:11:08 -07005175 AppWarnings getAppWarningsLocked() {
5176 return mAppWarnings;
5177 }
5178
Wale Ogunwale214f3482018-10-04 11:00:47 -07005179 Intent getHomeIntent() {
5180 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
5181 intent.setComponent(mTopComponent);
5182 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
5183 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5184 intent.addCategory(Intent.CATEGORY_HOME);
5185 }
5186 return intent;
5187 }
5188
5189 /**
5190 * This starts home activity on displays that can have system decorations and only if the
5191 * home activity can have multiple instances.
5192 */
5193 boolean startHomeActivityLocked(int userId, String reason, int displayId) {
5194 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL && mTopAction == null) {
5195 // We are running in factory test mode, but unable to find the factory test app, so just
5196 // sit around displaying the error message and don't try to start anything.
5197 return false;
5198 }
5199
5200 final Intent intent = getHomeIntent();
5201 ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
5202 if (aInfo != null) {
5203 intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
5204 // Don't do this if the home app is currently being instrumented.
5205 aInfo = new ActivityInfo(aInfo);
5206 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
5207 WindowProcessController app =
5208 getProcessController(aInfo.processName, aInfo.applicationInfo.uid);
5209 if (app == null || !app.isInstrumenting()) {
5210 intent.setFlags(intent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
5211 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
5212 // For ANR debugging to verify if the user activity is the one that actually
5213 // launched.
5214 final String myReason = reason + ":" + userId + ":" + resolvedUserId;
5215 getActivityStartController().startHomeActivity(intent, aInfo, myReason, displayId);
5216 }
5217 } else {
5218 Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
5219 }
5220
5221 return true;
5222 }
5223
5224 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
5225 ActivityInfo ai = null;
5226 final ComponentName comp = intent.getComponent();
5227 try {
5228 if (comp != null) {
5229 // Factory test.
5230 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
5231 } else {
5232 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
5233 intent,
5234 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
5235 flags, userId);
5236
5237 if (info != null) {
5238 ai = info.activityInfo;
5239 }
5240 }
5241 } catch (RemoteException e) {
5242 // ignore
5243 }
5244
5245 return ai;
5246 }
5247
5248 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
5249 if (info == null) return null;
5250 ApplicationInfo newInfo = new ApplicationInfo(info);
5251 newInfo.initForUser(userId);
5252 return newInfo;
5253 }
5254
5255 private WindowProcessController getProcessController(String processName, int uid) {
5256 if (uid == SYSTEM_UID) {
5257 // The system gets to run in any process. If there are multiple processes with the same
5258 // uid, just pick the first (this should never happen).
5259 final SparseArray<WindowProcessController> procs =
5260 mProcessNames.getMap().get(processName);
5261 if (procs == null) return null;
5262 final int procCount = procs.size();
5263 for (int i = 0; i < procCount; i++) {
5264 final int procUid = procs.keyAt(i);
5265 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
5266 // Don't use an app process or different user process for system component.
5267 continue;
5268 }
5269 return procs.valueAt(i);
5270 }
5271 }
5272
5273 return mProcessNames.get(processName, uid);
5274 }
5275
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005276 void logAppTooSlow(WindowProcessController app, long startTime, String msg) {
5277 if (true || Build.IS_USER) {
5278 return;
5279 }
5280
5281 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5282 StrictMode.allowThreadDiskWrites();
5283 try {
5284 File tracesDir = new File("/data/anr");
5285 File tracesFile = null;
5286 try {
5287 tracesFile = File.createTempFile("app_slow", null, tracesDir);
5288
5289 StringBuilder sb = new StringBuilder();
5290 Time tobj = new Time();
5291 tobj.set(System.currentTimeMillis());
5292 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5293 sb.append(": ");
5294 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5295 sb.append(" since ");
5296 sb.append(msg);
5297 FileOutputStream fos = new FileOutputStream(tracesFile);
5298 fos.write(sb.toString().getBytes());
5299 if (app == null) {
5300 fos.write("\n*** No application process!".getBytes());
5301 }
5302 fos.close();
5303 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5304 } catch (IOException e) {
5305 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesFile, e);
5306 return;
5307 }
5308
5309 if (app != null && app.getPid() > 0) {
5310 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5311 firstPids.add(app.getPid());
5312 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, null, null);
5313 }
5314
5315 File lastTracesFile = null;
5316 File curTracesFile = null;
5317 for (int i=9; i>=0; i--) {
5318 String name = String.format(Locale.US, "slow%02d.txt", i);
5319 curTracesFile = new File(tracesDir, name);
5320 if (curTracesFile.exists()) {
5321 if (lastTracesFile != null) {
5322 curTracesFile.renameTo(lastTracesFile);
5323 } else {
5324 curTracesFile.delete();
5325 }
5326 }
5327 lastTracesFile = curTracesFile;
5328 }
5329 tracesFile.renameTo(curTracesFile);
5330 } finally {
5331 StrictMode.setThreadPolicy(oldPolicy);
5332 }
5333 }
5334
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005335 final class H extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005336 static final int REPORT_TIME_TRACKER_MSG = 1;
5337
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005338 public H(Looper looper) {
5339 super(looper, null, true);
5340 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005341
5342 @Override
5343 public void handleMessage(Message msg) {
5344 switch (msg.what) {
5345 case REPORT_TIME_TRACKER_MSG: {
5346 AppTimeTracker tracker = (AppTimeTracker) msg.obj;
5347 tracker.deliverResult(mContext);
5348 } break;
5349 }
5350 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005351 }
5352
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005353 final class UiHandler extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005354 static final int DISMISS_DIALOG_UI_MSG = 1;
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005355
5356 public UiHandler() {
5357 super(com.android.server.UiThread.get().getLooper(), null, true);
5358 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005359
5360 @Override
5361 public void handleMessage(Message msg) {
5362 switch (msg.what) {
5363 case DISMISS_DIALOG_UI_MSG: {
5364 final Dialog d = (Dialog) msg.obj;
5365 d.dismiss();
5366 break;
5367 }
5368 }
5369 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005370 }
5371
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005372 final class LocalService extends ActivityTaskManagerInternal {
5373 @Override
5374 public SleepToken acquireSleepToken(String tag, int displayId) {
5375 Preconditions.checkNotNull(tag);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005376 return ActivityTaskManagerService.this.acquireSleepToken(tag, displayId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005377 }
5378
5379 @Override
5380 public ComponentName getHomeActivityForUser(int userId) {
5381 synchronized (mGlobalLock) {
Louis Changbd48dca2018-08-29 17:44:34 +08005382 ActivityRecord homeActivity =
5383 mStackSupervisor.getDefaultDisplayHomeActivityForUser(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005384 return homeActivity == null ? null : homeActivity.realActivity;
5385 }
5386 }
5387
5388 @Override
5389 public void onLocalVoiceInteractionStarted(IBinder activity,
5390 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
5391 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005392 onLocalVoiceInteractionStartedLocked(activity, voiceSession, voiceInteractor);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005393 }
5394 }
5395
5396 @Override
5397 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
5398 synchronized (mGlobalLock) {
5399 mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
5400 reasons, timestamp);
5401 }
5402 }
5403
5404 @Override
5405 public void notifyAppTransitionFinished() {
5406 synchronized (mGlobalLock) {
5407 mStackSupervisor.notifyAppTransitionDone();
5408 }
5409 }
5410
5411 @Override
5412 public void notifyAppTransitionCancelled() {
5413 synchronized (mGlobalLock) {
5414 mStackSupervisor.notifyAppTransitionDone();
5415 }
5416 }
5417
5418 @Override
5419 public List<IBinder> getTopVisibleActivities() {
5420 synchronized (mGlobalLock) {
5421 return mStackSupervisor.getTopVisibleActivities();
5422 }
5423 }
5424
5425 @Override
5426 public void notifyDockedStackMinimizedChanged(boolean minimized) {
5427 synchronized (mGlobalLock) {
5428 mStackSupervisor.setDockedStackMinimized(minimized);
5429 }
5430 }
5431
5432 @Override
5433 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
5434 Bundle bOptions) {
5435 Preconditions.checkNotNull(intents, "intents");
5436 final String[] resolvedTypes = new String[intents.length];
5437
5438 // UID of the package on user userId.
5439 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
5440 // packageUid may not be initialized.
5441 int packageUid = 0;
5442 final long ident = Binder.clearCallingIdentity();
5443
5444 try {
5445 for (int i = 0; i < intents.length; i++) {
5446 resolvedTypes[i] =
5447 intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
5448 }
5449
5450 packageUid = AppGlobals.getPackageManager().getPackageUid(
5451 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
5452 } catch (RemoteException e) {
5453 // Shouldn't happen.
5454 } finally {
5455 Binder.restoreCallingIdentity(ident);
5456 }
5457
5458 synchronized (mGlobalLock) {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07005459 return getActivityStartController().startActivitiesInPackage(
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005460 packageUid, packageName,
5461 intents, resolvedTypes, null /* resultTo */,
5462 SafeActivityOptions.fromBundle(bOptions), userId,
Michal Karpinski201bc0c2018-07-20 15:32:00 +01005463 false /* validateIncomingUser */, null /* originatingPendingIntent */);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005464 }
5465 }
5466
5467 @Override
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07005468 public int startActivitiesInPackage(int uid, String callingPackage, Intent[] intents,
5469 String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, int userId,
5470 boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent) {
5471 synchronized (mGlobalLock) {
5472 return getActivityStartController().startActivitiesInPackage(uid, callingPackage,
5473 intents, resolvedTypes, resultTo, options, userId, validateIncomingUser,
5474 originatingPendingIntent);
5475 }
5476 }
5477
5478 @Override
5479 public int startActivityInPackage(int uid, int realCallingPid, int realCallingUid,
5480 String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
5481 String resultWho, int requestCode, int startFlags, SafeActivityOptions options,
5482 int userId, TaskRecord inTask, String reason, boolean validateIncomingUser,
5483 PendingIntentRecord originatingPendingIntent) {
5484 synchronized (mGlobalLock) {
5485 return getActivityStartController().startActivityInPackage(uid, realCallingPid,
5486 realCallingUid, callingPackage, intent, resolvedType, resultTo, resultWho,
5487 requestCode, startFlags, options, userId, inTask, reason,
5488 validateIncomingUser, originatingPendingIntent);
5489 }
5490 }
5491
5492 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005493 public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
5494 Intent intent, Bundle options, int userId) {
5495 return ActivityTaskManagerService.this.startActivityAsUser(
5496 caller, callerPacakge, intent,
5497 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
5498 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
5499 false /*validateIncomingUser*/);
5500 }
5501
5502 @Override
5503 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
5504 synchronized (mGlobalLock) {
5505
5506 // We might change the visibilities here, so prepare an empty app transition which
5507 // might be overridden later if we actually change visibilities.
5508 final boolean wasTransitionSet =
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005509 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005510 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005511 mWindowManager.prepareAppTransition(TRANSIT_NONE,
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005512 false /* alwaysKeepCurrent */);
5513 }
5514 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5515
5516 // If there was a transition set already we don't want to interfere with it as we
5517 // might be starting it too early.
5518 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005519 mWindowManager.executeAppTransition();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005520 }
5521 }
5522 if (callback != null) {
5523 callback.run();
5524 }
5525 }
5526
5527 @Override
5528 public void notifyKeyguardTrustedChanged() {
5529 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005530 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005531 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5532 }
5533 }
5534 }
5535
5536 /**
5537 * Called after virtual display Id is updated by
5538 * {@link com.android.server.vr.Vr2dDisplay} with a specific
5539 * {@param vrVr2dDisplayId}.
5540 */
5541 @Override
5542 public void setVr2dDisplayId(int vr2dDisplayId) {
5543 if (DEBUG_STACK) Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
5544 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005545 mVr2dDisplayId = vr2dDisplayId;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005546 }
5547 }
5548
5549 @Override
5550 public void setFocusedActivity(IBinder token) {
5551 synchronized (mGlobalLock) {
5552 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
5553 if (r == null) {
5554 throw new IllegalArgumentException(
5555 "setFocusedActivity: No activity record matching token=" + token);
5556 }
Louis Chang19443452018-10-09 12:10:21 +08005557 if (r.moveFocusableActivityToTop("setFocusedActivity")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08005558 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005559 }
5560 }
5561 }
5562
5563 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005564 public void registerScreenObserver(ScreenObserver observer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005565 mScreenObservers.add(observer);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005566 }
5567
5568 @Override
5569 public boolean isCallerRecents(int callingUid) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005570 return getRecentTasks().isCallerRecents(callingUid);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005571 }
5572
5573 @Override
5574 public boolean isRecentsComponentHomeActivity(int userId) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005575 return getRecentTasks().isRecentsComponentHomeActivity(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005576 }
5577
5578 @Override
5579 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
5580 ActivityTaskManagerService.this.cancelRecentsAnimation(restoreHomeStackPosition);
5581 }
5582
5583 @Override
5584 public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005585 ActivityTaskManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005586 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005587
5588 @Override
5589 public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
5590 synchronized (mGlobalLock) {
5591 mActiveVoiceInteractionServiceComponent = component;
5592 }
5593 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005594
5595 @Override
5596 public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
5597 if (!mAmInternal.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
5598 return;
5599 }
5600 synchronized (mGlobalLock) {
5601 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
5602 if (types == null) {
5603 if (uid < 0) {
5604 return;
5605 }
5606 types = new ArrayMap<>();
5607 mAllowAppSwitchUids.put(userId, types);
5608 }
5609 if (uid < 0) {
5610 types.remove(type);
5611 } else {
5612 types.put(type, uid);
5613 }
5614 }
5615 }
5616
5617 @Override
5618 public void onUserStopped(int userId) {
5619 synchronized (mGlobalLock) {
5620 getRecentTasks().unloadUserDataFromMemoryLocked(userId);
5621 mAllowAppSwitchUids.remove(userId);
5622 }
5623 }
5624
5625 @Override
5626 public boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
5627 synchronized (mGlobalLock) {
5628 return ActivityTaskManagerService.this.isGetTasksAllowed(
5629 caller, callingPid, callingUid);
5630 }
5631 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005632
5633 @Override
5634 public void onProcessAdded(WindowProcessController proc) {
5635 synchronized (mGlobalLock) {
5636 mProcessNames.put(proc.mName, proc.mUid, proc);
5637 }
5638 }
5639
5640 @Override
5641 public void onProcessRemoved(String name, int uid) {
5642 synchronized (mGlobalLock) {
5643 mProcessNames.remove(name, uid);
5644 }
5645 }
5646
5647 @Override
5648 public void onCleanUpApplicationRecord(WindowProcessController proc) {
5649 synchronized (mGlobalLock) {
5650 if (proc == mHomeProcess) {
5651 mHomeProcess = null;
5652 }
5653 if (proc == mPreviousProcess) {
5654 mPreviousProcess = null;
5655 }
5656 }
5657 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005658
5659 @Override
5660 public int getTopProcessState() {
5661 synchronized (mGlobalLock) {
5662 return mTopProcessState;
5663 }
5664 }
5665
5666 @Override
Wale Ogunwale53783742018-09-16 10:21:51 -07005667 public boolean isHeavyWeightProcess(WindowProcessController proc) {
5668 synchronized (mGlobalLock) {
5669 return proc == mHeavyWeightProcess;
5670 }
5671 }
5672
5673 @Override
5674 public void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
5675 synchronized (mGlobalLock) {
5676 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(proc);
5677 }
5678 }
5679
5680 @Override
5681 public void finishHeavyWeightApp() {
5682 synchronized (mGlobalLock) {
5683 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(
5684 mHeavyWeightProcess);
5685 }
5686 }
5687
5688 @Override
Wale Ogunwalef6733932018-06-27 05:14:34 -07005689 public boolean isSleeping() {
5690 synchronized (mGlobalLock) {
5691 return isSleepingLocked();
5692 }
5693 }
5694
5695 @Override
5696 public boolean isShuttingDown() {
5697 synchronized (mGlobalLock) {
5698 return mShuttingDown;
5699 }
5700 }
5701
5702 @Override
5703 public boolean shuttingDown(boolean booted, int timeout) {
5704 synchronized (mGlobalLock) {
5705 mShuttingDown = true;
5706 mStackSupervisor.prepareForShutdownLocked();
5707 updateEventDispatchingLocked(booted);
5708 return mStackSupervisor.shutdownLocked(timeout);
5709 }
5710 }
5711
5712 @Override
5713 public void enableScreenAfterBoot(boolean booted) {
5714 synchronized (mGlobalLock) {
5715 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5716 SystemClock.uptimeMillis());
5717 mWindowManager.enableScreenAfterBoot();
5718 updateEventDispatchingLocked(booted);
5719 }
5720 }
5721
5722 @Override
5723 public boolean showStrictModeViolationDialog() {
5724 synchronized (mGlobalLock) {
5725 return mShowDialogs && !mSleeping && !mShuttingDown;
5726 }
5727 }
5728
5729 @Override
5730 public void showSystemReadyErrorDialogsIfNeeded() {
5731 synchronized (mGlobalLock) {
5732 try {
5733 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
5734 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
5735 + " data partition or your device will be unstable.");
5736 mUiHandler.post(() -> {
5737 if (mShowDialogs) {
5738 AlertDialog d = new BaseErrorDialog(mUiContext);
5739 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5740 d.setCancelable(false);
5741 d.setTitle(mUiContext.getText(R.string.android_system_label));
5742 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
5743 d.setButton(DialogInterface.BUTTON_POSITIVE,
5744 mUiContext.getText(R.string.ok),
5745 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5746 d.show();
5747 }
5748 });
5749 }
5750 } catch (RemoteException e) {
5751 }
5752
5753 if (!Build.isBuildConsistent()) {
5754 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
5755 mUiHandler.post(() -> {
5756 if (mShowDialogs) {
5757 AlertDialog d = new BaseErrorDialog(mUiContext);
5758 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5759 d.setCancelable(false);
5760 d.setTitle(mUiContext.getText(R.string.android_system_label));
5761 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
5762 d.setButton(DialogInterface.BUTTON_POSITIVE,
5763 mUiContext.getText(R.string.ok),
5764 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5765 d.show();
5766 }
5767 });
5768 }
5769 }
5770 }
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005771
5772 @Override
5773 public long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason) {
5774 synchronized (mGlobalLock) {
5775 return ActivityTaskManagerService.this.inputDispatchingTimedOut(
5776 pid, aboveSystem, reason);
5777 }
5778 }
5779
5780 @Override
5781 public void onProcessMapped(int pid, WindowProcessController proc) {
5782 synchronized (mGlobalLock) {
5783 mPidMap.put(pid, proc);
5784 }
5785 }
5786
5787 @Override
5788 public void onProcessUnMapped(int pid) {
5789 synchronized (mGlobalLock) {
5790 mPidMap.remove(pid);
5791 }
5792 }
Wale Ogunwale008163e2018-07-23 23:11:08 -07005793
5794 @Override
5795 public void onPackageDataCleared(String name) {
5796 synchronized (mGlobalLock) {
Wale Ogunwale53783742018-09-16 10:21:51 -07005797 mCompatModePackages.handlePackageDataClearedLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07005798 mAppWarnings.onPackageDataCleared(name);
5799 }
5800 }
5801
5802 @Override
5803 public void onPackageUninstalled(String name) {
5804 synchronized (mGlobalLock) {
5805 mAppWarnings.onPackageUninstalled(name);
Wale Ogunwale53783742018-09-16 10:21:51 -07005806 mCompatModePackages.handlePackageUninstalledLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07005807 }
5808 }
Wale Ogunwale53783742018-09-16 10:21:51 -07005809
5810 @Override
5811 public void onPackageAdded(String name, boolean replacing) {
5812 synchronized (mGlobalLock) {
5813 mCompatModePackages.handlePackageAddedLocked(name, replacing);
5814 }
5815 }
5816
5817 @Override
5818 public CompatibilityInfo compatibilityInfoForPackage(ApplicationInfo ai) {
5819 synchronized (mGlobalLock) {
5820 return compatibilityInfoForPackageLocked(ai);
5821 }
5822 }
5823
Yunfan Chen75157d72018-07-27 14:47:21 +09005824 /**
5825 * Set the corresponding display information for the process global configuration. To be
5826 * called when we need to show IME on a different display.
5827 *
5828 * @param pid The process id associated with the IME window.
5829 * @param displayId The ID of the display showing the IME.
5830 */
5831 @Override
5832 public void onImeWindowSetOnDisplay(int pid, int displayId) {
5833 if (pid == MY_PID || pid < 0) {
5834 if (DEBUG_CONFIGURATION) {
5835 Slog.w(TAG,
5836 "Trying to update display configuration for system/invalid process.");
5837 }
5838 return;
5839 }
5840 mH.post(() -> {
5841 synchronized (mGlobalLock) {
5842 // Check if display is initialized in AM.
5843 if (!mStackSupervisor.isDisplayAdded(displayId)) {
5844 // Call come when display is not yet added or has already been removed.
5845 if (DEBUG_CONFIGURATION) {
5846 Slog.w(TAG, "Trying to update display configuration for non-existing "
5847 + "displayId=" + displayId);
5848 }
5849 return;
5850 }
5851 final WindowProcessController imeProcess = mPidMap.get(pid);
5852 if (imeProcess == null) {
5853 if (DEBUG_CONFIGURATION) {
5854 Slog.w(TAG, "Trying to update display configuration for invalid pid: "
5855 + pid);
5856 }
5857 return;
5858 }
5859 // Fetch the current override configuration of the display and set it to the
5860 // process global configuration.
5861 imeProcess.onConfigurationChanged(
5862 mStackSupervisor.getDisplayOverrideConfiguration(displayId));
5863 }
5864 });
5865 }
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07005866
5867 @Override
5868 public void sendActivityResult(int callingUid, IBinder activityToken, String resultWho,
5869 int requestCode, int resultCode, Intent data) {
5870 synchronized (mGlobalLock) {
5871 final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
5872 if (r != null && r.getStack() != null) {
5873 r.getStack().sendActivityResultLocked(callingUid, r, resultWho, requestCode,
5874 resultCode, data);
5875 }
5876 }
5877 }
5878
5879 @Override
5880 public void clearPendingResultForActivity(IBinder activityToken,
5881 WeakReference<PendingIntentRecord> pir) {
5882 synchronized (mGlobalLock) {
5883 final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
5884 if (r != null && r.pendingResults != null) {
5885 r.pendingResults.remove(pir);
5886 }
5887 }
5888 }
5889
5890 @Override
5891 public IIntentSender getIntentSender(int type, String packageName,
5892 int callingUid, int userId, IBinder token, String resultWho,
5893 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5894 Bundle bOptions) {
5895 synchronized (mGlobalLock) {
5896 return getIntentSenderLocked(type, packageName, callingUid, userId, token,
5897 resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
5898 }
5899 }
Wale Ogunwalec4e63a42018-10-02 13:19:54 -07005900
5901 @Override
5902 public ActivityServiceConnectionsHolder getServiceConnectionsHolder(IBinder token) {
5903 synchronized (mGlobalLock) {
5904 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
5905 if (r == null) {
5906 return null;
5907 }
5908 if (r.mServiceConnectionsHolder == null) {
5909 r.mServiceConnectionsHolder = new ActivityServiceConnectionsHolder(
5910 ActivityTaskManagerService.this, r);
5911 }
5912
5913 return r.mServiceConnectionsHolder;
5914 }
5915 }
Wale Ogunwale214f3482018-10-04 11:00:47 -07005916
5917 @Override
5918 public Intent getHomeIntent() {
5919 synchronized (mGlobalLock) {
5920 return ActivityTaskManagerService.this.getHomeIntent();
5921 }
5922 }
5923
5924 @Override
5925 public boolean startHomeActivity(int userId, String reason) {
5926 synchronized (mGlobalLock) {
5927 return startHomeActivityLocked(userId, reason, DEFAULT_DISPLAY);
5928 }
5929 }
5930
5931 @Override
5932 public boolean isFactoryTestProcess(WindowProcessController wpc) {
5933 synchronized (mGlobalLock) {
5934 if (mFactoryTest == FACTORY_TEST_OFF) {
5935 return false;
5936 }
5937 if (mFactoryTest == FACTORY_TEST_LOW_LEVEL && mTopComponent != null
5938 && wpc.mName.equals(mTopComponent.getPackageName())) {
5939 return true;
5940 }
5941 return mFactoryTest == FACTORY_TEST_HIGH_LEVEL
5942 && (wpc.mInfo.flags & FLAG_FACTORY_TEST) != 0;
5943 }
5944 }
5945
5946 @Override
5947 public void updateTopComponentForFactoryTest() {
5948 synchronized (mGlobalLock) {
5949 if (mFactoryTest != FACTORY_TEST_LOW_LEVEL) {
5950 return;
5951 }
5952 final ResolveInfo ri = mContext.getPackageManager()
5953 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), STOCK_PM_FLAGS);
5954 final CharSequence errorMsg;
5955 if (ri != null) {
5956 final ActivityInfo ai = ri.activityInfo;
5957 final ApplicationInfo app = ai.applicationInfo;
5958 if ((app.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
5959 mTopAction = Intent.ACTION_FACTORY_TEST;
5960 mTopData = null;
5961 mTopComponent = new ComponentName(app.packageName, ai.name);
5962 errorMsg = null;
5963 } else {
5964 errorMsg = mContext.getResources().getText(
5965 com.android.internal.R.string.factorytest_not_system);
5966 }
5967 } else {
5968 errorMsg = mContext.getResources().getText(
5969 com.android.internal.R.string.factorytest_no_action);
5970 }
5971 if (errorMsg == null) {
5972 return;
5973 }
5974
5975 mTopAction = null;
5976 mTopData = null;
5977 mTopComponent = null;
5978 mUiHandler.post(() -> {
5979 Dialog d = new FactoryErrorDialog(mUiContext, errorMsg);
5980 d.show();
5981 mAm.ensureBootCompleted();
5982 });
5983 }
5984 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005985 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07005986}