blob: e7ec7b6c05ebb41e0b39cca69c8640d85ed69538 [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 Ogunwalea6191b42018-05-09 07:41:32 -070042import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
43import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
Evan Rosky4505b352018-09-06 11:20:40 -070044import static android.content.pm.PackageManager.FEATURE_PC;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070045import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070046import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070047import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
48import static android.os.Build.VERSION_CODES.N;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070049import static android.os.Process.SYSTEM_UID;
Evan Rosky4505b352018-09-06 11:20:40 -070050import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070051import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
52import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
53import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
54import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
Evan Rosky4505b352018-09-06 11:20:40 -070055import static android.provider.Settings.Global.HIDE_ERROR_DIALOGS;
56import static android.provider.Settings.System.FONT_SCALE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070057import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
58import static android.view.Display.DEFAULT_DISPLAY;
59import static android.view.Display.INVALID_DISPLAY;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070060import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
Wale Ogunwale6767eae2018-05-03 15:52:51 -070061import static android.view.WindowManager.TRANSIT_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070062import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070063import static android.view.WindowManager.TRANSIT_TASK_OPEN;
64import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
Evan Rosky4505b352018-09-06 11:20:40 -070065
Wale Ogunwale65ebd952018-04-25 15:41:44 -070066import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070067import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
68import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
69import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
70import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070071import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070072import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070073import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070074import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070075import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070076import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
77import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
78import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070079import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070080import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
81import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070082import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
83import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
84import static com.android.server.am.ActivityManagerService.ANIMATE;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070085import static com.android.server.am.ActivityManagerService.MY_PID;
86import static com.android.server.am.ActivityManagerService.SEND_LOCALE_TO_MOUNT_DAEMON_MSG;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070087import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070088import static com.android.server.am.ActivityManagerService.UPDATE_CONFIGURATION_MSG;
89import static com.android.server.am.ActivityManagerService.checkComponentPermission;
Evan Rosky4505b352018-09-06 11:20:40 -070090import static com.android.server.am.ActivityManagerService.dumpStackTraces;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070091import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070092import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070093import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
94import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
95import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
96import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
97import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
Evan Rosky4505b352018-09-06 11:20:40 -070098import static com.android.server.am.ActivityTaskManagerService.H.REPORT_TIME_TRACKER_MSG;
99import static com.android.server.am.ActivityTaskManagerService.UiHandler.DISMISS_DIALOG_UI_MSG;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700100import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
101import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700102import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700103import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
Evan Rosky4505b352018-09-06 11:20:40 -0700104import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT;
105import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_DATA;
106import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
107import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700108import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
109import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700110
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700111import android.Manifest;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700112import android.annotation.NonNull;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700113import android.annotation.Nullable;
114import android.annotation.UserIdInt;
115import android.app.Activity;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700116import android.app.ActivityManager;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700117import android.app.ActivityManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700118import android.app.ActivityOptions;
119import android.app.ActivityTaskManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700120import android.app.ActivityThread;
121import android.app.AlertDialog;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700122import android.app.AppGlobals;
Evan Rosky4505b352018-09-06 11:20:40 -0700123import android.app.Dialog;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700124import android.app.IActivityController;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700125import android.app.IActivityTaskManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700126import android.app.IApplicationThread;
127import android.app.IAssistDataReceiver;
Wale Ogunwale53783742018-09-16 10:21:51 -0700128import android.app.INotificationManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700129import android.app.ITaskStackListener;
Wale Ogunwale53783742018-09-16 10:21:51 -0700130import android.app.Notification;
131import android.app.NotificationManager;
132import android.app.PendingIntent;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700133import android.app.PictureInPictureParams;
134import android.app.ProfilerInfo;
135import android.app.RemoteAction;
136import android.app.WaitResult;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700137import android.app.WindowConfiguration;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700138import android.app.admin.DevicePolicyCache;
139import android.app.assist.AssistContent;
140import android.app.assist.AssistStructure;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700141import android.app.servertransaction.ConfigurationChangeItem;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700142import android.app.usage.UsageEvents;
143import android.content.ActivityNotFoundException;
144import android.content.ComponentName;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700145import android.content.ContentResolver;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700146import android.content.Context;
Evan Rosky4505b352018-09-06 11:20:40 -0700147import android.content.DialogInterface;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700148import android.content.IIntentSender;
149import android.content.Intent;
150import android.content.pm.ActivityInfo;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700151import android.content.pm.ApplicationInfo;
Yunfan Chen75157d72018-07-27 14:47:21 +0900152import android.content.pm.ConfigurationInfo;
Evan Rosky4505b352018-09-06 11:20:40 -0700153import android.content.pm.IPackageManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700154import android.content.pm.PackageManager;
Evan Rosky4505b352018-09-06 11:20:40 -0700155import android.content.pm.PackageManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700156import android.content.pm.ParceledListSlice;
157import android.content.pm.ResolveInfo;
Wale Ogunwale53783742018-09-16 10:21:51 -0700158import android.content.res.CompatibilityInfo;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700159import android.content.res.Configuration;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700160import android.content.res.Resources;
Evan Rosky4505b352018-09-06 11:20:40 -0700161import android.database.ContentObserver;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700162import android.graphics.Bitmap;
163import android.graphics.Point;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700164import android.graphics.Rect;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700165import android.metrics.LogMaker;
166import android.net.Uri;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700167import android.os.Binder;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700168import android.os.Build;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700169import android.os.Bundle;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700170import android.os.FileUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700171import android.os.Handler;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700172import android.os.IBinder;
Evan Rosky4505b352018-09-06 11:20:40 -0700173import android.os.IUserManager;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700174import android.os.LocaleList;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700175import android.os.Looper;
176import android.os.Message;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700177import android.os.PersistableBundle;
Evan Rosky4505b352018-09-06 11:20:40 -0700178import android.os.PowerManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700179import android.os.RemoteException;
Evan Rosky4505b352018-09-06 11:20:40 -0700180import android.os.ServiceManager;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700181import android.os.StrictMode;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700182import android.os.SystemClock;
183import android.os.SystemProperties;
Evan Rosky4505b352018-09-06 11:20:40 -0700184import android.os.Trace;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700185import android.os.UpdateLock;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700186import android.os.UserHandle;
Evan Rosky4505b352018-09-06 11:20:40 -0700187import android.os.UserManager;
188import android.os.WorkSource;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700189import android.provider.Settings;
190import android.service.voice.IVoiceInteractionSession;
191import android.service.voice.VoiceInteractionManagerInternal;
192import android.telecom.TelecomManager;
193import android.text.TextUtils;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700194import android.text.format.Time;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700195import android.util.ArrayMap;
196import android.util.EventLog;
197import android.util.Log;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700198import android.util.Slog;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700199import android.util.SparseArray;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700200import android.util.SparseIntArray;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700201import android.util.StatsLog;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700202import android.util.TimeUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700203import android.util.proto.ProtoOutputStream;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700204import android.view.IRecentsAnimationRunner;
205import android.view.RemoteAnimationAdapter;
206import android.view.RemoteAnimationDefinition;
Evan Rosky4505b352018-09-06 11:20:40 -0700207import android.view.WindowManager;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700208
Evan Rosky4505b352018-09-06 11:20:40 -0700209import com.android.internal.R;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700210import com.android.internal.annotations.VisibleForTesting;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700211import com.android.internal.app.AssistUtils;
Evan Rosky4505b352018-09-06 11:20:40 -0700212import com.android.internal.app.IAppOpsService;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700213import com.android.internal.app.IVoiceInteractor;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700214import com.android.internal.app.ProcessMap;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700215import com.android.internal.logging.MetricsLogger;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700216import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Wale Ogunwale53783742018-09-16 10:21:51 -0700217import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
218import com.android.internal.notification.SystemNotificationChannels;
Evan Rosky4505b352018-09-06 11:20:40 -0700219import com.android.internal.os.logging.MetricsLoggerWrapper;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700220import com.android.internal.policy.IKeyguardDismissCallback;
221import com.android.internal.policy.KeyguardDismissCallback;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700222import com.android.internal.util.Preconditions;
Wale Ogunwale53783742018-09-16 10:21:51 -0700223import com.android.internal.util.function.pooled.PooledLambda;
Evan Rosky4505b352018-09-06 11:20:40 -0700224import com.android.server.AppOpsService;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700225import com.android.server.AttributeCache;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700226import com.android.server.LocalServices;
227import com.android.server.SystemService;
Evan Rosky4505b352018-09-06 11:20:40 -0700228import com.android.server.SystemServiceManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700229import com.android.server.Watchdog;
Evan Rosky4505b352018-09-06 11:20:40 -0700230import com.android.server.pm.UserManagerService;
231import com.android.server.uri.UriGrantsManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700232import com.android.server.vr.VrManagerInternal;
Evan Rosky4505b352018-09-06 11:20:40 -0700233import com.android.server.wm.ActivityTaskManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700234import com.android.server.wm.PinnedStackWindowController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700235import com.android.server.wm.WindowManagerService;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700236
237import java.io.File;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700238import java.io.FileOutputStream;
239import java.io.IOException;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700240import java.io.PrintWriter;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700241import java.io.StringWriter;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700242import java.util.ArrayList;
243import java.util.List;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700244import java.util.Locale;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700245
246/**
247 * System service for managing activities and their containers (task, stacks, displays,... ).
248 *
249 * {@hide}
250 */
251public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
252 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityTaskManagerService" : TAG_AM;
253 private static final String TAG_STACK = TAG + POSTFIX_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700254 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
255 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
256 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
257 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
258 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700259 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700260
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700261 // How long we wait until we timeout on key dispatching.
262 private static final int KEY_DISPATCHING_TIMEOUT_MS = 5 * 1000;
263 // How long we wait until we timeout on key dispatching during instrumentation.
264 private static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS = 60 * 1000;
265
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700266 Context mContext;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700267 /**
268 * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
269 * change at runtime. Use mContext for non-UI purposes.
270 */
271 final Context mUiContext;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700272 H mH;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700273 UiHandler mUiHandler;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700274 ActivityManagerService mAm;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700275 ActivityManagerInternal mAmInternal;
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700276 UriGrantsManagerInternal mUgmInternal;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700277 private PackageManagerInternal mPmInternal;
Wale Ogunwale53783742018-09-16 10:21:51 -0700278 private ActivityTaskManagerInternal mInternal;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700279 /* Global service lock used by the package the owns this service. */
280 Object mGlobalLock;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700281 ActivityStackSupervisor mStackSupervisor;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700282 WindowManagerService mWindowManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700283 private UserManagerService mUserManager;
284 private AppOpsService mAppOpsService;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700285 /** All processes currently running that might have a window organized by name. */
286 final ProcessMap<WindowProcessController> mProcessNames = new ProcessMap<>();
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700287 /** All processes we currently have running mapped by pid */
288 final SparseArray<WindowProcessController> mPidMap = new SparseArray<>();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700289 /** This is the process holding what we currently consider to be the "home" activity. */
290 WindowProcessController mHomeProcess;
Wale Ogunwale53783742018-09-16 10:21:51 -0700291 /** The currently running heavy-weight process, if any. */
292 WindowProcessController mHeavyWeightProcess = null;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700293 /**
294 * This is the process holding the activity the user last visited that is in a different process
295 * from the one they are currently in.
296 */
297 WindowProcessController mPreviousProcess;
298 /** The time at which the previous process was last visible. */
299 long mPreviousProcessVisibleTime;
300
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700301 /** List of intents that were used to start the most recent tasks. */
302 private RecentTasks mRecentTasks;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700303 /** State of external calls telling us if the device is awake or asleep. */
304 private boolean mKeyguardShown = false;
305
306 // Wrapper around VoiceInteractionServiceManager
307 private AssistUtils mAssistUtils;
308
309 // VoiceInteraction session ID that changes for each new request except when
310 // being called for multi-window assist in a single session.
311 private int mViSessionId = 1000;
312
313 // How long to wait in getAssistContextExtras for the activity and foreground services
314 // to respond with the result.
315 private static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
316
317 // How long top wait when going through the modern assist (which doesn't need to block
318 // on getting this result before starting to launch its UI).
319 private static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
320
321 // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
322 private static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
323
324 private final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
325
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700326 // Keeps track of the active voice interaction service component, notified from
327 // VoiceInteractionManagerService
328 ComponentName mActiveVoiceInteractionServiceComponent;
329
330 private VrController mVrController;
331 KeyguardController mKeyguardController;
332 private final ClientLifecycleManager mLifecycleManager;
333 private TaskChangeNotificationController mTaskChangeNotificationController;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700334 /** The controller for all operations related to locktask. */
335 private LockTaskController mLockTaskController;
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700336 private ActivityStartController mActivityStartController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700337
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700338 boolean mSuppressResizeConfigChanges;
339
340 private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
341 new UpdateConfigurationResult();
342
343 static final class UpdateConfigurationResult {
344 // Configuration changes that were updated.
345 int changes;
346 // If the activity was relaunched to match the new configuration.
347 boolean activityRelaunched;
348
349 void reset() {
350 changes = 0;
351 activityRelaunched = false;
352 }
353 }
354
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700355 /** Current sequencing integer of the configuration, for skipping old configurations. */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700356 private int mConfigurationSeq;
357 // To cache the list of supported system locales
358 private String[] mSupportedSystemLocales = null;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700359
360 /**
361 * Temp object used when global and/or display override configuration is updated. It is also
362 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
363 * anyone...
364 */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700365 private Configuration mTempConfig = new Configuration();
366
Wale Ogunwalef6733932018-06-27 05:14:34 -0700367 /** Temporary to avoid allocations. */
368 final StringBuilder mStringBuilder = new StringBuilder(256);
369
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700370 // Amount of time after a call to stopAppSwitches() during which we will
371 // prevent further untrusted switches from happening.
372 private static final long APP_SWITCH_DELAY_TIME = 5 * 1000;
373
374 /**
375 * The time at which we will allow normal application switches again,
376 * after a call to {@link #stopAppSwitches()}.
377 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700378 private long mAppSwitchesAllowedTime;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700379 /**
380 * This is set to true after the first switch after mAppSwitchesAllowedTime
381 * is set; any switches after that will clear the time.
382 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700383 private boolean mDidAppSwitch;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700384
385 IActivityController mController = null;
386 boolean mControllerIsAMonkey = false;
387
388 /**
389 * Used to retain an update lock when the foreground activity is in
390 * immersive mode.
391 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700392 private final UpdateLock mUpdateLock = new UpdateLock("immersive");
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700393
394 /**
395 * Packages that are being allowed to perform unrestricted app switches. Mapping is
396 * User -> Type -> uid.
397 */
398 final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
399
400 /** The dimensions of the thumbnails in the Recents UI. */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700401 private int mThumbnailWidth;
402 private int mThumbnailHeight;
403 private float mFullscreenThumbnailScale;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700404
405 /**
406 * Flag that indicates if multi-window is enabled.
407 *
408 * For any particular form of multi-window to be enabled, generic multi-window must be enabled
409 * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
410 * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
411 * At least one of the forms of multi-window must be enabled in order for this flag to be
412 * initialized to 'true'.
413 *
414 * @see #mSupportsSplitScreenMultiWindow
415 * @see #mSupportsFreeformWindowManagement
416 * @see #mSupportsPictureInPicture
417 * @see #mSupportsMultiDisplay
418 */
419 boolean mSupportsMultiWindow;
420 boolean mSupportsSplitScreenMultiWindow;
421 boolean mSupportsFreeformWindowManagement;
422 boolean mSupportsPictureInPicture;
423 boolean mSupportsMultiDisplay;
424 boolean mForceResizableActivities;
425
426 final List<ActivityTaskManagerInternal.ScreenObserver> mScreenObservers = new ArrayList<>();
427
428 // VR Vr2d Display Id.
429 int mVr2dDisplayId = INVALID_DISPLAY;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700430
Wale Ogunwalef6733932018-06-27 05:14:34 -0700431 /**
432 * Set while we are wanting to sleep, to prevent any
433 * activities from being started/resumed.
434 *
435 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
436 *
437 * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
438 * while in the sleep state until there is a pending transition out of sleep, in which case
439 * mSleeping is set to false, and remains false while awake.
440 *
441 * Whether mSleeping can quickly toggled between true/false without the device actually
442 * display changing states is undefined.
443 */
444 private boolean mSleeping = false;
445
446 /**
447 * The process state used for processes that are running the top activities.
448 * This changes between TOP and TOP_SLEEPING to following mSleeping.
449 */
450 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
451
452 // Whether we should show our dialogs (ANR, crash, etc) or just perform their default action
453 // automatically. Important for devices without direct input devices.
454 private boolean mShowDialogs = true;
455
456 /** Set if we are shutting down the system, similar to sleeping. */
457 boolean mShuttingDown = false;
458
459 /**
460 * We want to hold a wake lock while running a voice interaction session, since
461 * this may happen with the screen off and we need to keep the CPU running to
462 * be able to continue to interact with the user.
463 */
464 PowerManager.WakeLock mVoiceWakeLock;
465
466 /**
467 * Set while we are running a voice interaction. This overrides sleeping while it is active.
468 */
469 IVoiceInteractionSession mRunningVoice;
470
471 /**
472 * The last resumed activity. This is identical to the current resumed activity most
473 * of the time but could be different when we're pausing one activity before we resume
474 * another activity.
475 */
476 ActivityRecord mLastResumedActivity;
477
478 /**
479 * The activity that is currently being traced as the active resumed activity.
480 *
481 * @see #updateResumedAppTrace
482 */
483 private @Nullable ActivityRecord mTracedResumedActivity;
484
485 /** If non-null, we are tracking the time the user spends in the currently focused app. */
486 AppTimeTracker mCurAppTimeTracker;
487
Wale Ogunwale008163e2018-07-23 23:11:08 -0700488 private AppWarnings mAppWarnings;
489
Wale Ogunwale53783742018-09-16 10:21:51 -0700490 /**
491 * Packages that the user has asked to have run in screen size
492 * compatibility mode instead of filling the screen.
493 */
494 CompatModePackages mCompatModePackages;
495
Wale Ogunwalef6733932018-06-27 05:14:34 -0700496 private FontScaleSettingObserver mFontScaleSettingObserver;
497
498 private final class FontScaleSettingObserver extends ContentObserver {
499 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
500 private final Uri mHideErrorDialogsUri = Settings.Global.getUriFor(HIDE_ERROR_DIALOGS);
501
502 public FontScaleSettingObserver() {
503 super(mH);
504 final ContentResolver resolver = mContext.getContentResolver();
505 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
506 resolver.registerContentObserver(mHideErrorDialogsUri, false, this,
507 UserHandle.USER_ALL);
508 }
509
510 @Override
511 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
512 if (mFontScaleUri.equals(uri)) {
513 updateFontScaleIfNeeded(userId);
514 } else if (mHideErrorDialogsUri.equals(uri)) {
515 synchronized (mGlobalLock) {
516 updateShouldShowDialogsLocked(getGlobalConfiguration());
517 }
518 }
519 }
520 }
521
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700522 ActivityTaskManagerService(Context context) {
523 mContext = context;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700524 mUiContext = ActivityThread.currentActivityThread().getSystemUiContext();
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700525 mLifecycleManager = new ClientLifecycleManager();
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700526 }
527
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700528 void onSystemReady() {
529 mAssistUtils = new AssistUtils(mContext);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700530 mVrController.onSystemReady();
531 mRecentTasks.onSystemReadyLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700532 }
533
Wale Ogunwalef6733932018-06-27 05:14:34 -0700534 void onInitPowerManagement() {
535 mStackSupervisor.initPowerManagement();
536 final PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
537 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
538 mVoiceWakeLock.setReferenceCounted(false);
539 }
540
541 void installSystemProviders() {
542 mFontScaleSettingObserver = new FontScaleSettingObserver();
543 }
544
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700545 void retrieveSettings(ContentResolver resolver) {
546 final boolean freeformWindowManagement =
547 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
548 || Settings.Global.getInt(
549 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
550
551 final boolean supportsMultiWindow = ActivityTaskManager.supportsMultiWindow(mContext);
552 final boolean supportsPictureInPicture = supportsMultiWindow &&
553 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
554 final boolean supportsSplitScreenMultiWindow =
555 ActivityTaskManager.supportsSplitScreenMultiWindow(mContext);
556 final boolean supportsMultiDisplay = mContext.getPackageManager()
557 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
558 final boolean alwaysFinishActivities =
559 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
560 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
561 final boolean forceResizable = Settings.Global.getInt(
562 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
Garfield Tane0846042018-07-26 13:42:04 -0700563 final boolean isPc = mContext.getPackageManager().hasSystemFeature(FEATURE_PC);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700564
565 // Transfer any global setting for forcing RTL layout, into a System Property
566 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
567
568 final Configuration configuration = new Configuration();
569 Settings.System.getConfiguration(resolver, configuration);
570 if (forceRtl) {
571 // This will take care of setting the correct layout direction flags
572 configuration.setLayoutDirection(configuration.locale);
573 }
574
575 synchronized (mGlobalLock) {
576 mForceResizableActivities = forceResizable;
577 final boolean multiWindowFormEnabled = freeformWindowManagement
578 || supportsSplitScreenMultiWindow
579 || supportsPictureInPicture
580 || supportsMultiDisplay;
581 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
582 mSupportsMultiWindow = true;
583 mSupportsFreeformWindowManagement = freeformWindowManagement;
584 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
585 mSupportsPictureInPicture = supportsPictureInPicture;
586 mSupportsMultiDisplay = supportsMultiDisplay;
587 } else {
588 mSupportsMultiWindow = false;
589 mSupportsFreeformWindowManagement = false;
590 mSupportsSplitScreenMultiWindow = false;
591 mSupportsPictureInPicture = false;
592 mSupportsMultiDisplay = false;
593 }
594 mWindowManager.setForceResizableTasks(mForceResizableActivities);
595 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
Garfield Tane0846042018-07-26 13:42:04 -0700596 mWindowManager.setSupportsFreeformWindowManagement(mSupportsFreeformWindowManagement);
597 mWindowManager.setIsPc(isPc);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700598 // This happens before any activities are started, so we can change global configuration
599 // in-place.
600 updateConfigurationLocked(configuration, null, true);
601 final Configuration globalConfig = getGlobalConfiguration();
602 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
603
604 // Load resources only after the current configuration has been set.
605 final Resources res = mContext.getResources();
606 mThumbnailWidth = res.getDimensionPixelSize(
607 com.android.internal.R.dimen.thumbnail_width);
608 mThumbnailHeight = res.getDimensionPixelSize(
609 com.android.internal.R.dimen.thumbnail_height);
610
611 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
612 mFullscreenThumbnailScale = (float) res
613 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
614 (float) globalConfig.screenWidthDp;
615 } else {
616 mFullscreenThumbnailScale = res.getFraction(
617 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
618 }
619 }
620 }
621
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700622 // TODO: Will be converted to WM lock once transition is complete.
623 void setActivityManagerService(ActivityManagerService am) {
624 mAm = am;
625 mGlobalLock = mAm;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700626 mH = new H(mAm.mHandlerThread.getLooper());
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700627 mUiHandler = new UiHandler();
Wale Ogunwale53783742018-09-16 10:21:51 -0700628 final File systemDir = SystemServiceManager.ensureSystemDir();
629 mAppWarnings = new AppWarnings(this, mUiContext, mH, mUiHandler, systemDir);
630 mCompatModePackages = new CompatModePackages(this, systemDir, mH);
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700631
632 mTempConfig.setToDefaults();
633 mTempConfig.setLocales(LocaleList.getDefault());
634 mConfigurationSeq = mTempConfig.seq = 1;
635 mStackSupervisor = createStackSupervisor();
636 mStackSupervisor.onConfigurationChanged(mTempConfig);
637
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700638 mTaskChangeNotificationController =
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700639 new TaskChangeNotificationController(mGlobalLock, mStackSupervisor, mH);
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700640 mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mH);
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700641 mActivityStartController = new ActivityStartController(this);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700642 mRecentTasks = createRecentTasks();
643 mStackSupervisor.setRecentTasks(mRecentTasks);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700644 mVrController = new VrController(mGlobalLock);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700645 mKeyguardController = mStackSupervisor.getKeyguardController();
646 }
647
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700648 void onActivityManagerInternalAdded() {
649 mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700650 mUgmInternal = LocalServices.getService(UriGrantsManagerInternal.class);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700651 }
652
Yunfan Chen75157d72018-07-27 14:47:21 +0900653 int increaseConfigurationSeqLocked() {
654 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
655 return mConfigurationSeq;
656 }
657
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700658 protected ActivityStackSupervisor createStackSupervisor() {
659 final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mH.getLooper());
660 supervisor.initialize();
661 return supervisor;
662 }
663
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700664 void setWindowManager(WindowManagerService wm) {
665 mWindowManager = wm;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700666 mLockTaskController.setWindowManager(wm);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700667 }
668
Wale Ogunwalef6733932018-06-27 05:14:34 -0700669 UserManagerService getUserManager() {
670 if (mUserManager == null) {
671 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
672 mUserManager = (UserManagerService) IUserManager.Stub.asInterface(b);
673 }
674 return mUserManager;
675 }
676
677 AppOpsService getAppOpsService() {
678 if (mAppOpsService == null) {
679 IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
680 mAppOpsService = (AppOpsService) IAppOpsService.Stub.asInterface(b);
681 }
682 return mAppOpsService;
683 }
684
685 boolean hasUserRestriction(String restriction, int userId) {
686 return getUserManager().hasUserRestriction(restriction, userId);
687 }
688
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700689 protected RecentTasks createRecentTasks() {
690 return new RecentTasks(this, mStackSupervisor);
691 }
692
693 RecentTasks getRecentTasks() {
694 return mRecentTasks;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700695 }
696
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700697 ClientLifecycleManager getLifecycleManager() {
698 return mLifecycleManager;
699 }
700
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700701 ActivityStartController getActivityStartController() {
702 return mActivityStartController;
703 }
704
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700705 TaskChangeNotificationController getTaskChangeNotificationController() {
706 return mTaskChangeNotificationController;
707 }
708
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700709 LockTaskController getLockTaskController() {
710 return mLockTaskController;
711 }
712
Yunfan Chen75157d72018-07-27 14:47:21 +0900713 /**
714 * Return the global configuration used by the process corresponding to the input pid. This is
715 * usually the global configuration with some overrides specific to that process.
716 */
717 Configuration getGlobalConfigurationForCallingPid() {
718 final int pid = Binder.getCallingPid();
719 if (pid == MY_PID || pid < 0) {
720 return getGlobalConfiguration();
721 }
722 synchronized (mGlobalLock) {
723 final WindowProcessController app = mPidMap.get(pid);
724 return app != null ? app.getConfiguration() : getGlobalConfiguration();
725 }
726 }
727
728 /**
729 * Return the device configuration info used by the process corresponding to the input pid.
730 * The value is consistent with the global configuration for the process.
731 */
732 @Override
733 public ConfigurationInfo getDeviceConfigurationInfo() {
734 ConfigurationInfo config = new ConfigurationInfo();
735 synchronized (mGlobalLock) {
736 final Configuration globalConfig = getGlobalConfigurationForCallingPid();
737 config.reqTouchScreen = globalConfig.touchscreen;
738 config.reqKeyboardType = globalConfig.keyboard;
739 config.reqNavigation = globalConfig.navigation;
740 if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
741 || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
742 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
743 }
744 if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
745 && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
746 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
747 }
748 config.reqGlEsVersion = mAm.GL_ES_VERSION;
749 }
750 return config;
751 }
752
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700753 private void start() {
Wale Ogunwale53783742018-09-16 10:21:51 -0700754 mInternal = new LocalService();
755 LocalServices.addService(ActivityTaskManagerInternal.class, mInternal);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700756 }
757
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700758 public static final class Lifecycle extends SystemService {
759 private final ActivityTaskManagerService mService;
760
761 public Lifecycle(Context context) {
762 super(context);
763 mService = new ActivityTaskManagerService(context);
764 }
765
766 @Override
767 public void onStart() {
768 publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700769 mService.start();
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700770 }
771
772 public ActivityTaskManagerService getService() {
773 return mService;
774 }
775 }
776
777 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700778 public final int startActivity(IApplicationThread caller, String callingPackage,
779 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
780 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
781 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
782 resultWho, requestCode, startFlags, profilerInfo, bOptions,
783 UserHandle.getCallingUserId());
784 }
785
786 @Override
787 public final int startActivities(IApplicationThread caller, String callingPackage,
788 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
789 int userId) {
790 final String reason = "startActivities";
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700791 enforceNotIsolatedCaller(reason);
792 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, reason);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700793 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700794 return getActivityStartController().startActivities(caller, -1, callingPackage, intents,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100795 resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId, reason,
796 null /* originatingPendingIntent */);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700797 }
798
799 @Override
800 public int startActivityAsUser(IApplicationThread caller, String callingPackage,
801 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
802 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
803 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
804 resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
805 true /*validateIncomingUser*/);
806 }
807
808 int startActivityAsUser(IApplicationThread caller, String callingPackage,
809 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
810 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
811 boolean validateIncomingUser) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700812 enforceNotIsolatedCaller("startActivityAsUser");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700813
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700814 userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700815 Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
816
817 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700818 return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700819 .setCaller(caller)
820 .setCallingPackage(callingPackage)
821 .setResolvedType(resolvedType)
822 .setResultTo(resultTo)
823 .setResultWho(resultWho)
824 .setRequestCode(requestCode)
825 .setStartFlags(startFlags)
826 .setProfilerInfo(profilerInfo)
827 .setActivityOptions(bOptions)
828 .setMayWait(userId)
829 .execute();
830
831 }
832
833 @Override
834 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
835 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700836 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions) {
837 enforceNotIsolatedCaller("startActivityIntentSender");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700838 // Refuse possible leaked file descriptors
839 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
840 throw new IllegalArgumentException("File descriptors passed in Intent");
841 }
842
843 if (!(target instanceof PendingIntentRecord)) {
844 throw new IllegalArgumentException("Bad PendingIntent object");
845 }
846
847 PendingIntentRecord pir = (PendingIntentRecord)target;
848
849 synchronized (mGlobalLock) {
850 // If this is coming from the currently resumed activity, it is
851 // effectively saying that app switches are allowed at this point.
Andrii Kulian5f750bc2018-07-17 08:57:23 -0700852 final ActivityStack stack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700853 if (stack.mResumedActivity != null &&
854 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700855 mAppSwitchesAllowedTime = 0;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700856 }
857 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700858 return pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700859 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700860 }
861
862 @Override
863 public boolean startNextMatchingActivity(IBinder callingActivity, Intent intent,
864 Bundle bOptions) {
865 // Refuse possible leaked file descriptors
866 if (intent != null && intent.hasFileDescriptors()) {
867 throw new IllegalArgumentException("File descriptors passed in Intent");
868 }
869 SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
870
871 synchronized (mGlobalLock) {
872 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
873 if (r == null) {
874 SafeActivityOptions.abort(options);
875 return false;
876 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700877 if (!r.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700878 // The caller is not running... d'oh!
879 SafeActivityOptions.abort(options);
880 return false;
881 }
882 intent = new Intent(intent);
883 // The caller is not allowed to change the data.
884 intent.setDataAndType(r.intent.getData(), r.intent.getType());
885 // And we are resetting to find the next component...
886 intent.setComponent(null);
887
888 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
889
890 ActivityInfo aInfo = null;
891 try {
892 List<ResolveInfo> resolves =
893 AppGlobals.getPackageManager().queryIntentActivities(
894 intent, r.resolvedType,
895 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
896 UserHandle.getCallingUserId()).getList();
897
898 // Look for the original activity in the list...
899 final int N = resolves != null ? resolves.size() : 0;
900 for (int i=0; i<N; i++) {
901 ResolveInfo rInfo = resolves.get(i);
902 if (rInfo.activityInfo.packageName.equals(r.packageName)
903 && rInfo.activityInfo.name.equals(r.info.name)) {
904 // We found the current one... the next matching is
905 // after it.
906 i++;
907 if (i<N) {
908 aInfo = resolves.get(i).activityInfo;
909 }
910 if (debug) {
911 Slog.v(TAG, "Next matching activity: found current " + r.packageName
912 + "/" + r.info.name);
913 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
914 ? "null" : aInfo.packageName + "/" + aInfo.name));
915 }
916 break;
917 }
918 }
919 } catch (RemoteException e) {
920 }
921
922 if (aInfo == null) {
923 // Nobody who is next!
924 SafeActivityOptions.abort(options);
925 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
926 return false;
927 }
928
929 intent.setComponent(new ComponentName(
930 aInfo.applicationInfo.packageName, aInfo.name));
931 intent.setFlags(intent.getFlags()&~(
932 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
933 Intent.FLAG_ACTIVITY_CLEAR_TOP|
934 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
935 FLAG_ACTIVITY_NEW_TASK));
936
937 // Okay now we need to start the new activity, replacing the currently running activity.
938 // This is a little tricky because we want to start the new one as if the current one is
939 // finished, but not finish the current one first so that there is no flicker.
940 // And thus...
941 final boolean wasFinishing = r.finishing;
942 r.finishing = true;
943
944 // Propagate reply information over to the new activity.
945 final ActivityRecord resultTo = r.resultTo;
946 final String resultWho = r.resultWho;
947 final int requestCode = r.requestCode;
948 r.resultTo = null;
949 if (resultTo != null) {
950 resultTo.removeResultsLocked(r, resultWho, requestCode);
951 }
952
953 final long origId = Binder.clearCallingIdentity();
954 // TODO(b/64750076): Check if calling pid should really be -1.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700955 final int res = getActivityStartController()
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700956 .obtainStarter(intent, "startNextMatchingActivity")
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700957 .setCaller(r.app.getThread())
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700958 .setResolvedType(r.resolvedType)
959 .setActivityInfo(aInfo)
960 .setResultTo(resultTo != null ? resultTo.appToken : null)
961 .setResultWho(resultWho)
962 .setRequestCode(requestCode)
963 .setCallingPid(-1)
964 .setCallingUid(r.launchedFromUid)
965 .setCallingPackage(r.launchedFromPackage)
966 .setRealCallingPid(-1)
967 .setRealCallingUid(r.launchedFromUid)
968 .setActivityOptions(options)
969 .execute();
970 Binder.restoreCallingIdentity(origId);
971
972 r.finishing = wasFinishing;
973 if (res != ActivityManager.START_SUCCESS) {
974 return false;
975 }
976 return true;
977 }
978 }
979
980 @Override
981 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
982 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
983 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
984 final WaitResult res = new WaitResult();
985 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700986 enforceNotIsolatedCaller("startActivityAndWait");
987 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
988 userId, "startActivityAndWait");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700989 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700990 getActivityStartController().obtainStarter(intent, "startActivityAndWait")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700991 .setCaller(caller)
992 .setCallingPackage(callingPackage)
993 .setResolvedType(resolvedType)
994 .setResultTo(resultTo)
995 .setResultWho(resultWho)
996 .setRequestCode(requestCode)
997 .setStartFlags(startFlags)
998 .setActivityOptions(bOptions)
999 .setMayWait(userId)
1000 .setProfilerInfo(profilerInfo)
1001 .setWaitResult(res)
1002 .execute();
1003 }
1004 return res;
1005 }
1006
1007 @Override
1008 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
1009 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1010 int startFlags, Configuration config, Bundle bOptions, int userId) {
1011 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001012 enforceNotIsolatedCaller("startActivityWithConfig");
1013 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
1014 "startActivityWithConfig");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001015 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001016 return getActivityStartController().obtainStarter(intent, "startActivityWithConfig")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001017 .setCaller(caller)
1018 .setCallingPackage(callingPackage)
1019 .setResolvedType(resolvedType)
1020 .setResultTo(resultTo)
1021 .setResultWho(resultWho)
1022 .setRequestCode(requestCode)
1023 .setStartFlags(startFlags)
1024 .setGlobalConfiguration(config)
1025 .setActivityOptions(bOptions)
1026 .setMayWait(userId)
1027 .execute();
1028 }
1029 }
1030
1031 @Override
1032 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
1033 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1034 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
1035 int userId) {
1036
1037 // This is very dangerous -- it allows you to perform a start activity (including
1038 // permission grants) as any app that may launch one of your own activities. So
1039 // we will only allow this to be done from activities that are part of the core framework,
1040 // and then only when they are running as the system.
1041 final ActivityRecord sourceRecord;
1042 final int targetUid;
1043 final String targetPackage;
1044 final boolean isResolver;
1045 synchronized (mGlobalLock) {
1046 if (resultTo == null) {
1047 throw new SecurityException("Must be called from an activity");
1048 }
1049 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
1050 if (sourceRecord == null) {
1051 throw new SecurityException("Called with bad activity token: " + resultTo);
1052 }
1053 if (!sourceRecord.info.packageName.equals("android")) {
1054 throw new SecurityException(
1055 "Must be called from an activity that is declared in the android package");
1056 }
1057 if (sourceRecord.app == null) {
1058 throw new SecurityException("Called without a process attached to activity");
1059 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001060 if (UserHandle.getAppId(sourceRecord.app.mUid) != SYSTEM_UID) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001061 // This is still okay, as long as this activity is running under the
1062 // uid of the original calling activity.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001063 if (sourceRecord.app.mUid != sourceRecord.launchedFromUid) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001064 throw new SecurityException(
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001065 "Calling activity in uid " + sourceRecord.app.mUid
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001066 + " must be system uid or original calling uid "
1067 + sourceRecord.launchedFromUid);
1068 }
1069 }
1070 if (ignoreTargetSecurity) {
1071 if (intent.getComponent() == null) {
1072 throw new SecurityException(
1073 "Component must be specified with ignoreTargetSecurity");
1074 }
1075 if (intent.getSelector() != null) {
1076 throw new SecurityException(
1077 "Selector not allowed with ignoreTargetSecurity");
1078 }
1079 }
1080 targetUid = sourceRecord.launchedFromUid;
1081 targetPackage = sourceRecord.launchedFromPackage;
1082 isResolver = sourceRecord.isResolverOrChildActivity();
1083 }
1084
1085 if (userId == UserHandle.USER_NULL) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001086 userId = UserHandle.getUserId(sourceRecord.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001087 }
1088
1089 // TODO: Switch to user app stacks here.
1090 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001091 return getActivityStartController().obtainStarter(intent, "startActivityAsCaller")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001092 .setCallingUid(targetUid)
1093 .setCallingPackage(targetPackage)
1094 .setResolvedType(resolvedType)
1095 .setResultTo(resultTo)
1096 .setResultWho(resultWho)
1097 .setRequestCode(requestCode)
1098 .setStartFlags(startFlags)
1099 .setActivityOptions(bOptions)
1100 .setMayWait(userId)
1101 .setIgnoreTargetSecurity(ignoreTargetSecurity)
1102 .setFilterCallingUid(isResolver ? 0 /* system */ : targetUid)
1103 .execute();
1104 } catch (SecurityException e) {
1105 // XXX need to figure out how to propagate to original app.
1106 // A SecurityException here is generally actually a fault of the original
1107 // calling activity (such as a fairly granting permissions), so propagate it
1108 // back to them.
1109 /*
1110 StringBuilder msg = new StringBuilder();
1111 msg.append("While launching");
1112 msg.append(intent.toString());
1113 msg.append(": ");
1114 msg.append(e.getMessage());
1115 */
1116 throw e;
1117 }
1118 }
1119
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001120 int handleIncomingUser(int callingPid, int callingUid, int userId, String name) {
1121 return mAmInternal.handleIncomingUser(callingPid, callingUid, userId, false /* allowAll */,
1122 ALLOW_FULL_ONLY, name, null /* callerPackage */);
1123 }
1124
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001125 @Override
1126 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
1127 Intent intent, String resolvedType, IVoiceInteractionSession session,
1128 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
1129 Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001130 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001131 if (session == null || interactor == null) {
1132 throw new NullPointerException("null session or interactor");
1133 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001134 userId = handleIncomingUser(callingPid, callingUid, userId, "startVoiceActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001135 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001136 return getActivityStartController().obtainStarter(intent, "startVoiceActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001137 .setCallingUid(callingUid)
1138 .setCallingPackage(callingPackage)
1139 .setResolvedType(resolvedType)
1140 .setVoiceSession(session)
1141 .setVoiceInteractor(interactor)
1142 .setStartFlags(startFlags)
1143 .setProfilerInfo(profilerInfo)
1144 .setActivityOptions(bOptions)
1145 .setMayWait(userId)
1146 .execute();
1147 }
1148
1149 @Override
1150 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
1151 Intent intent, String resolvedType, Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001152 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
1153 userId = handleIncomingUser(callingPid, callingUid, userId, "startAssistantActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001154
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001155 return getActivityStartController().obtainStarter(intent, "startAssistantActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001156 .setCallingUid(callingUid)
1157 .setCallingPackage(callingPackage)
1158 .setResolvedType(resolvedType)
1159 .setActivityOptions(bOptions)
1160 .setMayWait(userId)
1161 .execute();
1162 }
1163
1164 @Override
1165 public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
1166 IRecentsAnimationRunner recentsAnimationRunner) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001167 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001168 final int callingPid = Binder.getCallingPid();
1169 final long origId = Binder.clearCallingIdentity();
1170 try {
1171 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07001172 final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
1173 final int recentsUid = mRecentTasks.getRecentsComponentUid();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001174
1175 // Start a new recents animation
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001176 final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
1177 getActivityStartController(), mWindowManager, callingPid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001178 anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
1179 recentsUid, assistDataReceiver);
1180 }
1181 } finally {
1182 Binder.restoreCallingIdentity(origId);
1183 }
1184 }
1185
1186 @Override
1187 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001188 enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001189 "startActivityFromRecents()");
1190
1191 final int callingPid = Binder.getCallingPid();
1192 final int callingUid = Binder.getCallingUid();
1193 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(bOptions);
1194 final long origId = Binder.clearCallingIdentity();
1195 try {
1196 synchronized (mGlobalLock) {
1197 return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
1198 safeOptions);
1199 }
1200 } finally {
1201 Binder.restoreCallingIdentity(origId);
1202 }
1203 }
1204
1205 /**
1206 * This is the internal entry point for handling Activity.finish().
1207 *
1208 * @param token The Binder token referencing the Activity we want to finish.
1209 * @param resultCode Result code, if any, from this Activity.
1210 * @param resultData Result data (Intent), if any, from this Activity.
1211 * @param finishTask Whether to finish the task associated with this Activity.
1212 *
1213 * @return Returns true if the activity successfully finished, or false if it is still running.
1214 */
1215 @Override
1216 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
1217 int finishTask) {
1218 // Refuse possible leaked file descriptors
1219 if (resultData != null && resultData.hasFileDescriptors()) {
1220 throw new IllegalArgumentException("File descriptors passed in Intent");
1221 }
1222
1223 synchronized (mGlobalLock) {
1224 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1225 if (r == null) {
1226 return true;
1227 }
1228 // Keep track of the root activity of the task before we finish it
1229 TaskRecord tr = r.getTask();
1230 ActivityRecord rootR = tr.getRootActivity();
1231 if (rootR == null) {
1232 Slog.w(TAG, "Finishing task with all activities already finished");
1233 }
1234 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
1235 // finish.
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001236 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001237 return false;
1238 }
1239
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001240 // TODO: There is a dup. of this block of code in ActivityStack.navigateUpToLocked
1241 // We should consolidate.
1242 if (mController != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001243 // Find the first activity that is not finishing.
1244 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
1245 if (next != null) {
1246 // ask watcher if this is allowed
1247 boolean resumeOK = true;
1248 try {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001249 resumeOK = mController.activityResuming(next.packageName);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001250 } catch (RemoteException e) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001251 mController = null;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001252 Watchdog.getInstance().setActivityController(null);
1253 }
1254
1255 if (!resumeOK) {
1256 Slog.i(TAG, "Not finishing activity because controller resumed");
1257 return false;
1258 }
1259 }
1260 }
1261 final long origId = Binder.clearCallingIdentity();
1262 try {
1263 boolean res;
1264 final boolean finishWithRootActivity =
1265 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
1266 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
1267 || (finishWithRootActivity && r == rootR)) {
1268 // If requested, remove the task that is associated to this activity only if it
1269 // was the root activity in the task. The result code and data is ignored
1270 // because we don't support returning them across task boundaries. Also, to
1271 // keep backwards compatibility we remove the task from recents when finishing
1272 // task with root activity.
1273 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
1274 finishWithRootActivity, "finish-activity");
1275 if (!res) {
1276 Slog.i(TAG, "Removing task failed to finish activity");
1277 }
Garfield Tan2746ab52018-07-25 12:33:01 -07001278 // Explicitly dismissing the activity so reset its relaunch flag.
1279 r.mRelaunchReason = ActivityRecord.RELAUNCH_REASON_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001280 } else {
1281 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
1282 resultData, "app-request", true);
1283 if (!res) {
1284 Slog.i(TAG, "Failed to finish by app-request");
1285 }
1286 }
1287 return res;
1288 } finally {
1289 Binder.restoreCallingIdentity(origId);
1290 }
1291 }
1292 }
1293
1294 @Override
1295 public boolean finishActivityAffinity(IBinder token) {
1296 synchronized (mGlobalLock) {
1297 final long origId = Binder.clearCallingIdentity();
1298 try {
1299 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1300 if (r == null) {
1301 return false;
1302 }
1303
1304 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
1305 // can finish.
1306 final TaskRecord task = r.getTask();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001307 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001308 return false;
1309 }
1310 return task.getStack().finishActivityAffinityLocked(r);
1311 } finally {
1312 Binder.restoreCallingIdentity(origId);
1313 }
1314 }
1315 }
1316
1317 @Override
1318 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
1319 final long origId = Binder.clearCallingIdentity();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001320 try {
1321 WindowProcessController proc = null;
1322 synchronized (mGlobalLock) {
1323 ActivityStack stack = ActivityRecord.getStackLocked(token);
1324 if (stack == null) {
1325 return;
1326 }
1327 final ActivityRecord r = mStackSupervisor.activityIdleInternalLocked(token,
1328 false /* fromTimeout */, false /* processPausingActivities */, config);
1329 if (r != null) {
1330 proc = r.app;
1331 }
1332 if (stopProfiling && proc != null) {
1333 proc.clearProfilerIfNeeded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001334 }
1335 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001336 } finally {
1337 Binder.restoreCallingIdentity(origId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001338 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001339 }
1340
1341 @Override
1342 public final void activityResumed(IBinder token) {
1343 final long origId = Binder.clearCallingIdentity();
1344 synchronized (mGlobalLock) {
1345 ActivityRecord.activityResumedLocked(token);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001346 mWindowManager.notifyAppResumedFinished(token);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001347 }
1348 Binder.restoreCallingIdentity(origId);
1349 }
1350
1351 @Override
1352 public final void activityPaused(IBinder token) {
1353 final long origId = Binder.clearCallingIdentity();
1354 synchronized (mGlobalLock) {
1355 ActivityStack stack = ActivityRecord.getStackLocked(token);
1356 if (stack != null) {
1357 stack.activityPausedLocked(token, false);
1358 }
1359 }
1360 Binder.restoreCallingIdentity(origId);
1361 }
1362
1363 @Override
1364 public final void activityStopped(IBinder token, Bundle icicle,
1365 PersistableBundle persistentState, CharSequence description) {
1366 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
1367
1368 // Refuse possible leaked file descriptors
1369 if (icicle != null && icicle.hasFileDescriptors()) {
1370 throw new IllegalArgumentException("File descriptors passed in Bundle");
1371 }
1372
1373 final long origId = Binder.clearCallingIdentity();
1374
1375 synchronized (mGlobalLock) {
1376 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1377 if (r != null) {
1378 r.activityStoppedLocked(icicle, persistentState, description);
1379 }
1380 }
1381
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001382 mAmInternal.trimApplications();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001383
1384 Binder.restoreCallingIdentity(origId);
1385 }
1386
1387 @Override
1388 public final void activityDestroyed(IBinder token) {
1389 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
1390 synchronized (mGlobalLock) {
1391 ActivityStack stack = ActivityRecord.getStackLocked(token);
1392 if (stack != null) {
1393 stack.activityDestroyedLocked(token, "activityDestroyed");
1394 }
1395 }
1396 }
1397
1398 @Override
1399 public final void activityRelaunched(IBinder token) {
1400 final long origId = Binder.clearCallingIdentity();
1401 synchronized (mGlobalLock) {
1402 mStackSupervisor.activityRelaunchedLocked(token);
1403 }
1404 Binder.restoreCallingIdentity(origId);
1405 }
1406
1407 public final void activitySlept(IBinder token) {
1408 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
1409
1410 final long origId = Binder.clearCallingIdentity();
1411
1412 synchronized (mGlobalLock) {
1413 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1414 if (r != null) {
1415 mStackSupervisor.activitySleptLocked(r);
1416 }
1417 }
1418
1419 Binder.restoreCallingIdentity(origId);
1420 }
1421
1422 @Override
1423 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
1424 synchronized (mGlobalLock) {
1425 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1426 if (r == null) {
1427 return;
1428 }
1429 final long origId = Binder.clearCallingIdentity();
1430 try {
1431 r.setRequestedOrientation(requestedOrientation);
1432 } finally {
1433 Binder.restoreCallingIdentity(origId);
1434 }
1435 }
1436 }
1437
1438 @Override
1439 public int getRequestedOrientation(IBinder token) {
1440 synchronized (mGlobalLock) {
1441 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1442 if (r == null) {
1443 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
1444 }
1445 return r.getRequestedOrientation();
1446 }
1447 }
1448
1449 @Override
1450 public void setImmersive(IBinder token, boolean immersive) {
1451 synchronized (mGlobalLock) {
1452 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1453 if (r == null) {
1454 throw new IllegalArgumentException();
1455 }
1456 r.immersive = immersive;
1457
1458 // update associated state if we're frontmost
Andrii Kulian52d255c2018-07-13 11:32:19 -07001459 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001460 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001461 applyUpdateLockStateLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001462 }
1463 }
1464 }
1465
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001466 void applyUpdateLockStateLocked(ActivityRecord r) {
1467 // Modifications to the UpdateLock state are done on our handler, outside
1468 // the activity manager's locks. The new state is determined based on the
1469 // state *now* of the relevant activity record. The object is passed to
1470 // the handler solely for logging detail, not to be consulted/modified.
1471 final boolean nextState = r != null && r.immersive;
1472 mH.post(() -> {
1473 if (mUpdateLock.isHeld() != nextState) {
1474 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1475 "Applying new update lock state '" + nextState + "' for " + r);
1476 if (nextState) {
1477 mUpdateLock.acquire();
1478 } else {
1479 mUpdateLock.release();
1480 }
1481 }
1482 });
1483 }
1484
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001485 @Override
1486 public boolean isImmersive(IBinder token) {
1487 synchronized (mGlobalLock) {
1488 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1489 if (r == null) {
1490 throw new IllegalArgumentException();
1491 }
1492 return r.immersive;
1493 }
1494 }
1495
1496 @Override
1497 public boolean isTopActivityImmersive() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001498 enforceNotIsolatedCaller("isTopActivityImmersive");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001499 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001500 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001501 return (r != null) ? r.immersive : false;
1502 }
1503 }
1504
1505 @Override
1506 public void overridePendingTransition(IBinder token, String packageName,
1507 int enterAnim, int exitAnim) {
1508 synchronized (mGlobalLock) {
1509 ActivityRecord self = ActivityRecord.isInStackLocked(token);
1510 if (self == null) {
1511 return;
1512 }
1513
1514 final long origId = Binder.clearCallingIdentity();
1515
1516 if (self.isState(
1517 ActivityStack.ActivityState.RESUMED, ActivityStack.ActivityState.PAUSING)) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001518 mWindowManager.overridePendingAppTransition(packageName,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001519 enterAnim, exitAnim, null);
1520 }
1521
1522 Binder.restoreCallingIdentity(origId);
1523 }
1524 }
1525
1526 @Override
1527 public int getFrontActivityScreenCompatMode() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001528 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001529 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001530 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001531 if (r == null) {
1532 return ActivityManager.COMPAT_MODE_UNKNOWN;
1533 }
Wale Ogunwale53783742018-09-16 10:21:51 -07001534 return mCompatModePackages.computeCompatModeLocked(r.info.applicationInfo);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001535 }
1536 }
1537
1538 @Override
1539 public void setFrontActivityScreenCompatMode(int mode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001540 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001541 "setFrontActivityScreenCompatMode");
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001542 ApplicationInfo ai;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001543 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001544 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001545 if (r == null) {
1546 Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity");
1547 return;
1548 }
1549 ai = r.info.applicationInfo;
Wale Ogunwale53783742018-09-16 10:21:51 -07001550 mCompatModePackages.setPackageScreenCompatModeLocked(ai, mode);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001551 }
1552 }
1553
1554 @Override
1555 public int getLaunchedFromUid(IBinder activityToken) {
1556 ActivityRecord srec;
1557 synchronized (mGlobalLock) {
1558 srec = ActivityRecord.forTokenLocked(activityToken);
1559 }
1560 if (srec == null) {
1561 return -1;
1562 }
1563 return srec.launchedFromUid;
1564 }
1565
1566 @Override
1567 public String getLaunchedFromPackage(IBinder activityToken) {
1568 ActivityRecord srec;
1569 synchronized (mGlobalLock) {
1570 srec = ActivityRecord.forTokenLocked(activityToken);
1571 }
1572 if (srec == null) {
1573 return null;
1574 }
1575 return srec.launchedFromPackage;
1576 }
1577
1578 @Override
1579 public boolean convertFromTranslucent(IBinder token) {
1580 final long origId = Binder.clearCallingIdentity();
1581 try {
1582 synchronized (mGlobalLock) {
1583 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1584 if (r == null) {
1585 return false;
1586 }
1587 final boolean translucentChanged = r.changeWindowTranslucency(true);
1588 if (translucentChanged) {
1589 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
1590 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001591 mWindowManager.setAppFullscreen(token, true);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001592 return translucentChanged;
1593 }
1594 } finally {
1595 Binder.restoreCallingIdentity(origId);
1596 }
1597 }
1598
1599 @Override
1600 public boolean convertToTranslucent(IBinder token, Bundle options) {
1601 SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
1602 final long origId = Binder.clearCallingIdentity();
1603 try {
1604 synchronized (mGlobalLock) {
1605 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1606 if (r == null) {
1607 return false;
1608 }
1609 final TaskRecord task = r.getTask();
1610 int index = task.mActivities.lastIndexOf(r);
1611 if (index > 0) {
1612 ActivityRecord under = task.mActivities.get(index - 1);
1613 under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
1614 }
1615 final boolean translucentChanged = r.changeWindowTranslucency(false);
1616 if (translucentChanged) {
1617 r.getStack().convertActivityToTranslucent(r);
1618 }
1619 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001620 mWindowManager.setAppFullscreen(token, false);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001621 return translucentChanged;
1622 }
1623 } finally {
1624 Binder.restoreCallingIdentity(origId);
1625 }
1626 }
1627
1628 @Override
1629 public void notifyActivityDrawn(IBinder token) {
1630 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
1631 synchronized (mGlobalLock) {
1632 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
1633 if (r != null) {
1634 r.getStack().notifyActivityDrawnLocked(r);
1635 }
1636 }
1637 }
1638
1639 @Override
1640 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
1641 synchronized (mGlobalLock) {
1642 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1643 if (r == null) {
1644 return;
1645 }
1646 r.reportFullyDrawnLocked(restoredFromBundle);
1647 }
1648 }
1649
1650 @Override
1651 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
1652 synchronized (mGlobalLock) {
1653 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
1654 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
1655 return stack.mDisplayId;
1656 }
1657 return DEFAULT_DISPLAY;
1658 }
1659 }
1660
1661 @Override
1662 public ActivityManager.StackInfo getFocusedStackInfo() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001663 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001664 long ident = Binder.clearCallingIdentity();
1665 try {
1666 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001667 ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001668 if (focusedStack != null) {
1669 return mStackSupervisor.getStackInfo(focusedStack.mStackId);
1670 }
1671 return null;
1672 }
1673 } finally {
1674 Binder.restoreCallingIdentity(ident);
1675 }
1676 }
1677
1678 @Override
1679 public void setFocusedStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001680 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001681 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
1682 final long callingId = Binder.clearCallingIdentity();
1683 try {
1684 synchronized (mGlobalLock) {
1685 final ActivityStack stack = mStackSupervisor.getStack(stackId);
1686 if (stack == null) {
1687 Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
1688 return;
1689 }
1690 final ActivityRecord r = stack.topRunningActivityLocked();
1691 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
1692 r, "setFocusedStack")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08001693 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001694 }
1695 }
1696 } finally {
1697 Binder.restoreCallingIdentity(callingId);
1698 }
1699 }
1700
1701 @Override
1702 public void setFocusedTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001703 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001704 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
1705 final long callingId = Binder.clearCallingIdentity();
1706 try {
1707 synchronized (mGlobalLock) {
1708 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1709 if (task == null) {
1710 return;
1711 }
1712 final ActivityRecord r = task.topRunningActivityLocked();
1713 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08001714 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001715 }
1716 }
1717 } finally {
1718 Binder.restoreCallingIdentity(callingId);
1719 }
1720 }
1721
1722 @Override
1723 public boolean removeTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001724 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001725 synchronized (mGlobalLock) {
1726 final long ident = Binder.clearCallingIdentity();
1727 try {
1728 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
1729 "remove-task");
1730 } finally {
1731 Binder.restoreCallingIdentity(ident);
1732 }
1733 }
1734 }
1735
1736 @Override
Winson Chunge6439102018-07-30 15:48:01 -07001737 public void removeAllVisibleRecentTasks() {
1738 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeAllVisibleRecentTasks()");
1739 synchronized (mGlobalLock) {
1740 final long ident = Binder.clearCallingIdentity();
1741 try {
1742 getRecentTasks().removeAllVisibleTasks();
1743 } finally {
1744 Binder.restoreCallingIdentity(ident);
1745 }
1746 }
1747 }
1748
1749 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001750 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
1751 synchronized (mGlobalLock) {
1752 final ActivityRecord srec = ActivityRecord.forTokenLocked(token);
1753 if (srec != null) {
1754 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
1755 }
1756 }
1757 return false;
1758 }
1759
1760 @Override
1761 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
1762 Intent resultData) {
1763
1764 synchronized (mGlobalLock) {
1765 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
1766 if (r != null) {
1767 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
1768 }
1769 return false;
1770 }
1771 }
1772
1773 /**
1774 * Attempts to move a task backwards in z-order (the order of activities within the task is
1775 * unchanged).
1776 *
1777 * There are several possible results of this call:
1778 * - if the task is locked, then we will show the lock toast
1779 * - if there is a task behind the provided task, then that task is made visible and resumed as
1780 * this task is moved to the back
1781 * - otherwise, if there are no other tasks in the stack:
1782 * - if this task is in the pinned stack, then we remove the stack completely, which will
1783 * have the effect of moving the task to the top or bottom of the fullscreen stack
1784 * (depending on whether it is visible)
1785 * - otherwise, we simply return home and hide this task
1786 *
1787 * @param token A reference to the activity we wish to move
1788 * @param nonRoot If false then this only works if the activity is the root
1789 * of a task; if true it will work for any activity in a task.
1790 * @return Returns true if the move completed, false if not.
1791 */
1792 @Override
1793 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001794 enforceNotIsolatedCaller("moveActivityTaskToBack");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001795 synchronized (mGlobalLock) {
1796 final long origId = Binder.clearCallingIdentity();
1797 try {
1798 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
1799 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1800 if (task != null) {
1801 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
1802 }
1803 } finally {
1804 Binder.restoreCallingIdentity(origId);
1805 }
1806 }
1807 return false;
1808 }
1809
1810 @Override
1811 public Rect getTaskBounds(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001812 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001813 long ident = Binder.clearCallingIdentity();
1814 Rect rect = new Rect();
1815 try {
1816 synchronized (mGlobalLock) {
1817 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
1818 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1819 if (task == null) {
1820 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
1821 return rect;
1822 }
1823 if (task.getStack() != null) {
1824 // Return the bounds from window manager since it will be adjusted for various
1825 // things like the presense of a docked stack for tasks that aren't resizeable.
1826 task.getWindowContainerBounds(rect);
1827 } else {
1828 // Task isn't in window manager yet since it isn't associated with a stack.
1829 // Return the persist value from activity manager
1830 if (!task.matchParentBounds()) {
1831 rect.set(task.getBounds());
1832 } else if (task.mLastNonFullscreenBounds != null) {
1833 rect.set(task.mLastNonFullscreenBounds);
1834 }
1835 }
1836 }
1837 } finally {
1838 Binder.restoreCallingIdentity(ident);
1839 }
1840 return rect;
1841 }
1842
1843 @Override
1844 public ActivityManager.TaskDescription getTaskDescription(int id) {
1845 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001846 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001847 MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
1848 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
1849 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1850 if (tr != null) {
1851 return tr.lastTaskDescription;
1852 }
1853 }
1854 return null;
1855 }
1856
1857 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001858 public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
1859 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
1860 setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
1861 toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
1862 return;
1863 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001864 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001865 synchronized (mGlobalLock) {
1866 final long ident = Binder.clearCallingIdentity();
1867 try {
1868 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1869 if (task == null) {
1870 Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
1871 return;
1872 }
1873
1874 if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
1875 + " to windowingMode=" + windowingMode + " toTop=" + toTop);
1876
1877 if (!task.isActivityTypeStandardOrUndefined()) {
1878 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
1879 + " non-standard task " + taskId + " to windowing mode="
1880 + windowingMode);
1881 }
1882
1883 final ActivityStack stack = task.getStack();
1884 if (toTop) {
1885 stack.moveToFront("setTaskWindowingMode", task);
1886 }
1887 stack.setWindowingMode(windowingMode);
1888 } finally {
1889 Binder.restoreCallingIdentity(ident);
1890 }
1891 }
1892 }
1893
1894 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001895 public String getCallingPackage(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001896 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001897 ActivityRecord r = getCallingRecordLocked(token);
1898 return r != null ? r.info.packageName : null;
1899 }
1900 }
1901
1902 @Override
1903 public ComponentName getCallingActivity(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001904 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001905 ActivityRecord r = getCallingRecordLocked(token);
1906 return r != null ? r.intent.getComponent() : null;
1907 }
1908 }
1909
1910 private ActivityRecord getCallingRecordLocked(IBinder token) {
1911 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1912 if (r == null) {
1913 return null;
1914 }
1915 return r.resultTo;
1916 }
1917
1918 @Override
1919 public void unhandledBack() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001920 mAmInternal.enforceCallingPermission(android.Manifest.permission.FORCE_BACK, "unhandledBack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001921
1922 synchronized (mGlobalLock) {
1923 final long origId = Binder.clearCallingIdentity();
1924 try {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001925 getTopDisplayFocusedStack().unhandledBackLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001926 } finally {
1927 Binder.restoreCallingIdentity(origId);
1928 }
1929 }
1930 }
1931
1932 /**
1933 * TODO: Add mController hook
1934 */
1935 @Override
1936 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001937 mAmInternal.enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001938
1939 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
1940 synchronized (mGlobalLock) {
1941 moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
1942 false /* fromRecents */);
1943 }
1944 }
1945
1946 void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
1947 boolean fromRecents) {
1948
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001949 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001950 Binder.getCallingUid(), -1, -1, "Task to front")) {
1951 SafeActivityOptions.abort(options);
1952 return;
1953 }
1954 final long origId = Binder.clearCallingIdentity();
1955 try {
1956 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1957 if (task == null) {
1958 Slog.d(TAG, "Could not find task for id: "+ taskId);
Winson Chungd0243682018-09-25 18:11:54 -07001959 SafeActivityOptions.abort(options);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001960 return;
1961 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001962 if (getLockTaskController().isLockTaskModeViolation(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001963 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
Winson Chungd0243682018-09-25 18:11:54 -07001964 SafeActivityOptions.abort(options);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001965 return;
1966 }
1967 ActivityOptions realOptions = options != null
1968 ? options.getOptions(mStackSupervisor)
1969 : null;
1970 mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
1971 false /* forceNonResizable */);
1972
1973 final ActivityRecord topActivity = task.getTopActivity();
1974 if (topActivity != null) {
1975
1976 // We are reshowing a task, use a starting window to hide the initial draw delay
1977 // so the transition can start earlier.
1978 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
1979 true /* taskSwitch */, fromRecents);
1980 }
1981 } finally {
1982 Binder.restoreCallingIdentity(origId);
1983 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001984 }
1985
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001986 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
1987 int callingPid, int callingUid, String name) {
1988 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
1989 return true;
1990 }
1991
1992 if (getRecentTasks().isCallerRecents(sourceUid)) {
1993 return true;
1994 }
1995
1996 int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
1997 if (perm == PackageManager.PERMISSION_GRANTED) {
1998 return true;
1999 }
2000 if (checkAllowAppSwitchUid(sourceUid)) {
2001 return true;
2002 }
2003
2004 // If the actual IPC caller is different from the logical source, then
2005 // also see if they are allowed to control app switches.
2006 if (callingUid != -1 && callingUid != sourceUid) {
2007 perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
2008 if (perm == PackageManager.PERMISSION_GRANTED) {
2009 return true;
2010 }
2011 if (checkAllowAppSwitchUid(callingUid)) {
2012 return true;
2013 }
2014 }
2015
2016 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
2017 return false;
2018 }
2019
2020 private boolean checkAllowAppSwitchUid(int uid) {
2021 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
2022 if (types != null) {
2023 for (int i = types.size() - 1; i >= 0; i--) {
2024 if (types.valueAt(i).intValue() == uid) {
2025 return true;
2026 }
2027 }
2028 }
2029 return false;
2030 }
2031
2032 @Override
2033 public void setActivityController(IActivityController controller, boolean imAMonkey) {
2034 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
2035 "setActivityController()");
2036 synchronized (mGlobalLock) {
2037 mController = controller;
2038 mControllerIsAMonkey = imAMonkey;
2039 Watchdog.getInstance().setActivityController(controller);
2040 }
2041 }
2042
2043 boolean isControllerAMonkey() {
2044 synchronized (mGlobalLock) {
2045 return mController != null && mControllerIsAMonkey;
2046 }
2047 }
2048
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002049 @Override
2050 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
2051 synchronized (mGlobalLock) {
2052 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
2053 }
2054 }
2055
2056 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002057 public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum) {
2058 return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
2059 }
2060
2061 @Override
2062 public List<ActivityManager.RunningTaskInfo> getFilteredTasks(int maxNum,
2063 @WindowConfiguration.ActivityType int ignoreActivityType,
2064 @WindowConfiguration.WindowingMode int ignoreWindowingMode) {
2065 final int callingUid = Binder.getCallingUid();
2066 ArrayList<ActivityManager.RunningTaskInfo> list = new ArrayList<>();
2067
2068 synchronized (mGlobalLock) {
2069 if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
2070
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002071 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002072 callingUid);
2073 mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
2074 ignoreWindowingMode, callingUid, allowed);
2075 }
2076
2077 return list;
2078 }
2079
2080 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002081 public final void finishSubActivity(IBinder token, String resultWho, int requestCode) {
2082 synchronized (mGlobalLock) {
2083 final long origId = Binder.clearCallingIdentity();
2084 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2085 if (r != null) {
2086 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
2087 }
2088 Binder.restoreCallingIdentity(origId);
2089 }
2090 }
2091
2092 @Override
2093 public boolean willActivityBeVisible(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002094 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002095 ActivityStack stack = ActivityRecord.getStackLocked(token);
2096 if (stack != null) {
2097 return stack.willActivityBeVisibleLocked(token);
2098 }
2099 return false;
2100 }
2101 }
2102
2103 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002104 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002105 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002106 synchronized (mGlobalLock) {
2107 final long ident = Binder.clearCallingIdentity();
2108 try {
2109 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2110 if (task == null) {
2111 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
2112 return;
2113 }
2114
2115 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
2116 + " to stackId=" + stackId + " toTop=" + toTop);
2117
2118 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2119 if (stack == null) {
2120 throw new IllegalStateException(
2121 "moveTaskToStack: No stack for stackId=" + stackId);
2122 }
2123 if (!stack.isActivityTypeStandardOrUndefined()) {
2124 throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
2125 + taskId + " to stack " + stackId);
2126 }
2127 if (stack.inSplitScreenPrimaryWindowingMode()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002128 mWindowManager.setDockedStackCreateState(
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002129 SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
2130 }
2131 task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
2132 "moveTaskToStack");
2133 } finally {
2134 Binder.restoreCallingIdentity(ident);
2135 }
2136 }
2137 }
2138
2139 @Override
2140 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
2141 boolean preserveWindows, boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002142 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002143
2144 final long ident = Binder.clearCallingIdentity();
2145 try {
2146 synchronized (mGlobalLock) {
2147 if (animate) {
2148 final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
2149 if (stack == null) {
2150 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2151 return;
2152 }
2153 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
2154 throw new IllegalArgumentException("Stack: " + stackId
2155 + " doesn't support animated resize.");
2156 }
2157 stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
2158 animationDuration, false /* fromFullscreen */);
2159 } else {
2160 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2161 if (stack == null) {
2162 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2163 return;
2164 }
2165 mStackSupervisor.resizeStackLocked(stack, destBounds,
2166 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
2167 preserveWindows, allowResizeInDockedMode, !DEFER_RESUME);
2168 }
2169 }
2170 } finally {
2171 Binder.restoreCallingIdentity(ident);
2172 }
2173 }
2174
2175 /**
2176 * Moves the specified task to the primary-split-screen stack.
2177 *
2178 * @param taskId Id of task to move.
2179 * @param createMode The mode the primary split screen stack should be created in if it doesn't
2180 * exist already. See
2181 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
2182 * and
2183 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
2184 * @param toTop If the task and stack should be moved to the top.
2185 * @param animate Whether we should play an animation for the moving the task.
2186 * @param initialBounds If the primary stack gets created, it will use these bounds for the
2187 * stack. Pass {@code null} to use default bounds.
2188 * @param showRecents If the recents activity should be shown on the other side of the task
2189 * going into split-screen mode.
2190 */
2191 @Override
2192 public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode,
2193 boolean toTop, boolean animate, Rect initialBounds, boolean showRecents) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002194 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002195 "setTaskWindowingModeSplitScreenPrimary()");
2196 synchronized (mGlobalLock) {
2197 final long ident = Binder.clearCallingIdentity();
2198 try {
2199 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2200 if (task == null) {
2201 Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
2202 return false;
2203 }
2204 if (DEBUG_STACK) Slog.d(TAG_STACK,
2205 "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
2206 + " to createMode=" + createMode + " toTop=" + toTop);
2207 if (!task.isActivityTypeStandardOrUndefined()) {
2208 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
2209 + " non-standard task " + taskId + " to split-screen windowing mode");
2210 }
2211
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002212 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002213 final int windowingMode = task.getWindowingMode();
2214 final ActivityStack stack = task.getStack();
2215 if (toTop) {
2216 stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
2217 }
2218 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
2219 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */);
2220 return windowingMode != task.getWindowingMode();
2221 } finally {
2222 Binder.restoreCallingIdentity(ident);
2223 }
2224 }
2225 }
2226
2227 /**
2228 * Removes stacks in the input windowing modes from the system if they are of activity type
2229 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
2230 */
2231 @Override
2232 public void removeStacksInWindowingModes(int[] windowingModes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002233 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002234 "removeStacksInWindowingModes()");
2235
2236 synchronized (mGlobalLock) {
2237 final long ident = Binder.clearCallingIdentity();
2238 try {
2239 mStackSupervisor.removeStacksInWindowingModes(windowingModes);
2240 } finally {
2241 Binder.restoreCallingIdentity(ident);
2242 }
2243 }
2244 }
2245
2246 @Override
2247 public void removeStacksWithActivityTypes(int[] activityTypes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002248 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002249 "removeStacksWithActivityTypes()");
2250
2251 synchronized (mGlobalLock) {
2252 final long ident = Binder.clearCallingIdentity();
2253 try {
2254 mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
2255 } finally {
2256 Binder.restoreCallingIdentity(ident);
2257 }
2258 }
2259 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002260
2261 @Override
2262 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
2263 int userId) {
2264 final int callingUid = Binder.getCallingUid();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002265 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, "getRecentTasks");
2266 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002267 callingUid);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002268 final boolean detailed = checkGetTasksPermission(
2269 android.Manifest.permission.GET_DETAILED_TASKS, Binder.getCallingPid(),
2270 UserHandle.getAppId(callingUid))
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002271 == PackageManager.PERMISSION_GRANTED;
2272
2273 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002274 return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002275 callingUid);
2276 }
2277 }
2278
2279 @Override
2280 public List<ActivityManager.StackInfo> getAllStackInfos() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002281 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002282 long ident = Binder.clearCallingIdentity();
2283 try {
2284 synchronized (mGlobalLock) {
2285 return mStackSupervisor.getAllStackInfosLocked();
2286 }
2287 } finally {
2288 Binder.restoreCallingIdentity(ident);
2289 }
2290 }
2291
2292 @Override
2293 public ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002294 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002295 long ident = Binder.clearCallingIdentity();
2296 try {
2297 synchronized (mGlobalLock) {
2298 return mStackSupervisor.getStackInfo(windowingMode, activityType);
2299 }
2300 } finally {
2301 Binder.restoreCallingIdentity(ident);
2302 }
2303 }
2304
2305 @Override
2306 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002307 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002308 final long callingUid = Binder.getCallingUid();
2309 final long origId = Binder.clearCallingIdentity();
2310 try {
2311 synchronized (mGlobalLock) {
2312 // Cancel the recents animation synchronously (do not hold the WM lock)
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002313 mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002314 ? REORDER_MOVE_TO_ORIGINAL_POSITION
2315 : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
2316 }
2317 } finally {
2318 Binder.restoreCallingIdentity(origId);
2319 }
2320 }
2321
2322 @Override
2323 public void startLockTaskModeByToken(IBinder token) {
2324 synchronized (mGlobalLock) {
2325 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2326 if (r == null) {
2327 return;
2328 }
2329 startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
2330 }
2331 }
2332
2333 @Override
2334 public void startSystemLockTaskMode(int taskId) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002335 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002336 // This makes inner call to look as if it was initiated by system.
2337 long ident = Binder.clearCallingIdentity();
2338 try {
2339 synchronized (mGlobalLock) {
2340 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2341
2342 // When starting lock task mode the stack must be in front and focused
2343 task.getStack().moveToFront("startSystemLockTaskMode");
2344 startLockTaskModeLocked(task, true /* isSystemCaller */);
2345 }
2346 } finally {
2347 Binder.restoreCallingIdentity(ident);
2348 }
2349 }
2350
2351 @Override
2352 public void stopLockTaskModeByToken(IBinder token) {
2353 synchronized (mGlobalLock) {
2354 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2355 if (r == null) {
2356 return;
2357 }
2358 stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
2359 }
2360 }
2361
2362 /**
2363 * This API should be called by SystemUI only when user perform certain action to dismiss
2364 * lock task mode. We should only dismiss pinned lock task mode in this case.
2365 */
2366 @Override
2367 public void stopSystemLockTaskMode() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002368 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002369 stopLockTaskModeInternal(null, true /* isSystemCaller */);
2370 }
2371
2372 private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
2373 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
2374 if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
2375 return;
2376 }
2377
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002378 final ActivityStack stack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002379 if (stack == null || task != stack.topTask()) {
2380 throw new IllegalArgumentException("Invalid task, not in foreground");
2381 }
2382
2383 // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
2384 // system or a specific app.
2385 // * System-initiated requests will only start the pinned mode (screen pinning)
2386 // * App-initiated requests
2387 // - will put the device in fully locked mode (LockTask), if the app is whitelisted
2388 // - will start the pinned mode, otherwise
2389 final int callingUid = Binder.getCallingUid();
2390 long ident = Binder.clearCallingIdentity();
2391 try {
2392 // When a task is locked, dismiss the pinned stack if it exists
2393 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2394
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002395 getLockTaskController().startLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002396 } finally {
2397 Binder.restoreCallingIdentity(ident);
2398 }
2399 }
2400
2401 private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
2402 final int callingUid = Binder.getCallingUid();
2403 long ident = Binder.clearCallingIdentity();
2404 try {
2405 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002406 getLockTaskController().stopLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002407 }
2408 // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
2409 // task and jumping straight into a call in the case of emergency call back.
2410 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
2411 if (tm != null) {
2412 tm.showInCallScreen(false);
2413 }
2414 } finally {
2415 Binder.restoreCallingIdentity(ident);
2416 }
2417 }
2418
2419 @Override
2420 public boolean isInLockTaskMode() {
2421 return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
2422 }
2423
2424 @Override
2425 public int getLockTaskModeState() {
2426 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002427 return getLockTaskController().getLockTaskModeState();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002428 }
2429 }
2430
2431 @Override
2432 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
2433 synchronized (mGlobalLock) {
2434 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2435 if (r != null) {
2436 r.setTaskDescription(td);
2437 final TaskRecord task = r.getTask();
2438 task.updateTaskDescription();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002439 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002440 }
2441 }
2442 }
2443
2444 @Override
2445 public Bundle getActivityOptions(IBinder token) {
2446 final long origId = Binder.clearCallingIdentity();
2447 try {
2448 synchronized (mGlobalLock) {
2449 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
2450 if (r != null) {
2451 final ActivityOptions activityOptions = r.takeOptionsLocked();
2452 return activityOptions == null ? null : activityOptions.toBundle();
2453 }
2454 return null;
2455 }
2456 } finally {
2457 Binder.restoreCallingIdentity(origId);
2458 }
2459 }
2460
2461 @Override
2462 public List<IBinder> getAppTasks(String callingPackage) {
2463 int callingUid = Binder.getCallingUid();
2464 long ident = Binder.clearCallingIdentity();
2465 try {
2466 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002467 return mRecentTasks.getAppTasksList(callingUid, callingPackage);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002468 }
2469 } finally {
2470 Binder.restoreCallingIdentity(ident);
2471 }
2472 }
2473
2474 @Override
2475 public void finishVoiceTask(IVoiceInteractionSession session) {
2476 synchronized (mGlobalLock) {
2477 final long origId = Binder.clearCallingIdentity();
2478 try {
2479 // TODO: VI Consider treating local voice interactions and voice tasks
2480 // differently here
2481 mStackSupervisor.finishVoiceTask(session);
2482 } finally {
2483 Binder.restoreCallingIdentity(origId);
2484 }
2485 }
2486
2487 }
2488
2489 @Override
2490 public boolean isTopOfTask(IBinder token) {
2491 synchronized (mGlobalLock) {
2492 ActivityRecord r = ActivityRecord.isInStackLocked(token);
Riddle Hsu66b74a82018-07-26 00:20:12 +08002493 return r != null && r.getTask().getTopActivity() == r;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002494 }
2495 }
2496
2497 @Override
2498 public void notifyLaunchTaskBehindComplete(IBinder token) {
2499 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
2500 }
2501
2502 @Override
2503 public void notifyEnterAnimationComplete(IBinder token) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002504 mH.post(() -> {
2505 synchronized (mGlobalLock) {
2506 ActivityRecord r = ActivityRecord.forTokenLocked(token);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002507 if (r != null && r.attachedToProcess()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002508 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002509 r.app.getThread().scheduleEnterAnimationComplete(r.appToken);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002510 } catch (RemoteException e) {
2511 }
2512 }
2513 }
2514
2515 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002516 }
2517
2518 /** Called from an app when assist data is ready. */
2519 @Override
2520 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
2521 AssistContent content, Uri referrer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002522 PendingAssistExtras pae = (PendingAssistExtras) token;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002523 synchronized (pae) {
2524 pae.result = extras;
2525 pae.structure = structure;
2526 pae.content = content;
2527 if (referrer != null) {
2528 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
2529 }
2530 if (structure != null) {
2531 structure.setHomeActivity(pae.isHome);
2532 }
2533 pae.haveResult = true;
2534 pae.notifyAll();
2535 if (pae.intent == null && pae.receiver == null) {
2536 // Caller is just waiting for the result.
2537 return;
2538 }
2539 }
2540 // We are now ready to launch the assist activity.
2541 IAssistDataReceiver sendReceiver = null;
2542 Bundle sendBundle = null;
2543 synchronized (mGlobalLock) {
2544 buildAssistBundleLocked(pae, extras);
2545 boolean exists = mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002546 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002547 if (!exists) {
2548 // Timed out.
2549 return;
2550 }
2551
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002552 if ((sendReceiver = pae.receiver) != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002553 // Caller wants result sent back to them.
2554 sendBundle = new Bundle();
2555 sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
2556 sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
2557 sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
2558 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
2559 }
2560 }
2561 if (sendReceiver != null) {
2562 try {
2563 sendReceiver.onHandleAssistData(sendBundle);
2564 } catch (RemoteException e) {
2565 }
2566 return;
2567 }
2568
2569 final long ident = Binder.clearCallingIdentity();
2570 try {
2571 if (TextUtils.equals(pae.intent.getAction(),
2572 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
2573 pae.intent.putExtras(pae.extras);
2574 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
2575 } else {
2576 pae.intent.replaceExtras(pae.extras);
2577 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
2578 | Intent.FLAG_ACTIVITY_SINGLE_TOP
2579 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002580 mAmInternal.closeSystemDialogs("assist");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002581
2582 try {
2583 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
2584 } catch (ActivityNotFoundException e) {
2585 Slog.w(TAG, "No activity to handle assist action.", e);
2586 }
2587 }
2588 } finally {
2589 Binder.restoreCallingIdentity(ident);
2590 }
2591 }
2592
2593 @Override
2594 public int addAppTask(IBinder activityToken, Intent intent,
2595 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
2596 final int callingUid = Binder.getCallingUid();
2597 final long callingIdent = Binder.clearCallingIdentity();
2598
2599 try {
2600 synchronized (mGlobalLock) {
2601 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
2602 if (r == null) {
2603 throw new IllegalArgumentException("Activity does not exist; token="
2604 + activityToken);
2605 }
2606 ComponentName comp = intent.getComponent();
2607 if (comp == null) {
2608 throw new IllegalArgumentException("Intent " + intent
2609 + " must specify explicit component");
2610 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002611 if (thumbnail.getWidth() != mThumbnailWidth
2612 || thumbnail.getHeight() != mThumbnailHeight) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002613 throw new IllegalArgumentException("Bad thumbnail size: got "
2614 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002615 + mThumbnailWidth + "x" + mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002616 }
2617 if (intent.getSelector() != null) {
2618 intent.setSelector(null);
2619 }
2620 if (intent.getSourceBounds() != null) {
2621 intent.setSourceBounds(null);
2622 }
2623 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
2624 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
2625 // The caller has added this as an auto-remove task... that makes no
2626 // sense, so turn off auto-remove.
2627 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
2628 }
2629 }
2630 final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
2631 STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
2632 if (ainfo.applicationInfo.uid != callingUid) {
2633 throw new SecurityException(
2634 "Can't add task for another application: target uid="
2635 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
2636 }
2637
2638 final ActivityStack stack = r.getStack();
2639 final TaskRecord task = stack.createTaskRecord(
2640 mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent,
2641 null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002642 if (!mRecentTasks.addToBottom(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002643 // The app has too many tasks already and we can't add any more
2644 stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
2645 return INVALID_TASK_ID;
2646 }
2647 task.lastTaskDescription.copyFrom(description);
2648
2649 // TODO: Send the thumbnail to WM to store it.
2650
2651 return task.taskId;
2652 }
2653 } finally {
2654 Binder.restoreCallingIdentity(callingIdent);
2655 }
2656 }
2657
2658 @Override
2659 public Point getAppTaskThumbnailSize() {
2660 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002661 return new Point(mThumbnailWidth, mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002662 }
2663 }
2664
2665 @Override
2666 public void setTaskResizeable(int taskId, int resizeableMode) {
2667 synchronized (mGlobalLock) {
2668 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
2669 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
2670 if (task == null) {
2671 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
2672 return;
2673 }
2674 task.setResizeMode(resizeableMode);
2675 }
2676 }
2677
2678 @Override
2679 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002680 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002681 long ident = Binder.clearCallingIdentity();
2682 try {
2683 synchronized (mGlobalLock) {
2684 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2685 if (task == null) {
2686 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
2687 return;
2688 }
2689 // Place the task in the right stack if it isn't there already based on
2690 // the requested bounds.
2691 // The stack transition logic is:
2692 // - a null bounds on a freeform task moves that task to fullscreen
2693 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
2694 // that task to freeform
2695 // - otherwise the task is not moved
2696 ActivityStack stack = task.getStack();
2697 if (!task.getWindowConfiguration().canResizeTask()) {
2698 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
2699 }
2700 if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
2701 stack = stack.getDisplay().getOrCreateStack(
2702 WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
2703 } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
2704 stack = stack.getDisplay().getOrCreateStack(
2705 WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
2706 }
2707
2708 // Reparent the task to the right stack if necessary
2709 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
2710 if (stack != task.getStack()) {
2711 // Defer resume until the task is resized below
2712 task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
2713 DEFER_RESUME, "resizeTask");
2714 preserveWindow = false;
2715 }
2716
2717 // After reparenting (which only resizes the task to the stack bounds), resize the
2718 // task to the actual bounds provided
2719 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
2720 }
2721 } finally {
2722 Binder.restoreCallingIdentity(ident);
2723 }
2724 }
2725
2726 @Override
2727 public boolean releaseActivityInstance(IBinder token) {
2728 synchronized (mGlobalLock) {
2729 final long origId = Binder.clearCallingIdentity();
2730 try {
2731 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2732 if (r == null) {
2733 return false;
2734 }
2735 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
2736 } finally {
2737 Binder.restoreCallingIdentity(origId);
2738 }
2739 }
2740 }
2741
2742 @Override
2743 public void releaseSomeActivities(IApplicationThread appInt) {
2744 synchronized (mGlobalLock) {
2745 final long origId = Binder.clearCallingIdentity();
2746 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002747 WindowProcessController app =
2748 mAm.getRecordForAppLocked(appInt).getWindowProcessController();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002749 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
2750 } finally {
2751 Binder.restoreCallingIdentity(origId);
2752 }
2753 }
2754 }
2755
2756 @Override
2757 public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
2758 int secondaryDisplayShowing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002759 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002760 != PackageManager.PERMISSION_GRANTED) {
2761 throw new SecurityException("Requires permission "
2762 + android.Manifest.permission.DEVICE_POWER);
2763 }
2764
2765 synchronized (mGlobalLock) {
2766 long ident = Binder.clearCallingIdentity();
2767 if (mKeyguardShown != keyguardShowing) {
2768 mKeyguardShown = keyguardShowing;
2769 reportCurKeyguardUsageEventLocked(keyguardShowing);
2770 }
2771 try {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002772 mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002773 secondaryDisplayShowing);
2774 } finally {
2775 Binder.restoreCallingIdentity(ident);
2776 }
2777 }
2778
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002779 mH.post(() -> {
2780 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2781 mScreenObservers.get(i).onKeyguardStateChanged(keyguardShowing);
2782 }
2783 });
2784 }
2785
2786 void onScreenAwakeChanged(boolean isAwake) {
2787 mH.post(() -> {
2788 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2789 mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2790 }
2791 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002792 }
2793
2794 @Override
2795 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002796 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
2797 userId, "getTaskDescriptionIcon");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002798
2799 final File passedIconFile = new File(filePath);
2800 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
2801 passedIconFile.getName());
2802 if (!legitIconFile.getPath().equals(filePath)
2803 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
2804 throw new IllegalArgumentException("Bad file path: " + filePath
2805 + " passed for userId " + userId);
2806 }
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002807 return mRecentTasks.getTaskDescriptionIcon(filePath);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002808 }
2809
2810 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002811 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002812 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
2813 final ActivityOptions activityOptions = safeOptions != null
2814 ? safeOptions.getOptions(mStackSupervisor)
2815 : null;
2816 if (activityOptions == null
2817 || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
2818 || activityOptions.getCustomInPlaceResId() == 0) {
2819 throw new IllegalArgumentException("Expected in-place ActivityOption " +
2820 "with valid animation");
2821 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002822 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
2823 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002824 activityOptions.getCustomInPlaceResId());
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002825 mWindowManager.executeAppTransition();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002826 }
2827
2828 @Override
2829 public void removeStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002830 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002831 synchronized (mGlobalLock) {
2832 final long ident = Binder.clearCallingIdentity();
2833 try {
2834 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2835 if (stack == null) {
2836 Slog.w(TAG, "removeStack: No stack with id=" + stackId);
2837 return;
2838 }
2839 if (!stack.isActivityTypeStandardOrUndefined()) {
2840 throw new IllegalArgumentException(
2841 "Removing non-standard stack is not allowed.");
2842 }
2843 mStackSupervisor.removeStack(stack);
2844 } finally {
2845 Binder.restoreCallingIdentity(ident);
2846 }
2847 }
2848 }
2849
2850 @Override
2851 public void moveStackToDisplay(int stackId, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002852 mAmInternal.enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002853
2854 synchronized (mGlobalLock) {
2855 final long ident = Binder.clearCallingIdentity();
2856 try {
2857 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
2858 + " to displayId=" + displayId);
2859 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
2860 } finally {
2861 Binder.restoreCallingIdentity(ident);
2862 }
2863 }
2864 }
2865
2866 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002867 public void exitFreeformMode(IBinder token) {
2868 synchronized (mGlobalLock) {
2869 long ident = Binder.clearCallingIdentity();
2870 try {
2871 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2872 if (r == null) {
2873 throw new IllegalArgumentException(
2874 "exitFreeformMode: No activity record matching token=" + token);
2875 }
2876
2877 final ActivityStack stack = r.getStack();
2878 if (stack == null || !stack.inFreeformWindowingMode()) {
2879 throw new IllegalStateException(
2880 "exitFreeformMode: You can only go fullscreen from freeform.");
2881 }
2882
2883 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
2884 } finally {
2885 Binder.restoreCallingIdentity(ident);
2886 }
2887 }
2888 }
2889
2890 /** Sets the task stack listener that gets callbacks when a task stack changes. */
2891 @Override
2892 public void registerTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002893 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002894 "registerTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002895 mTaskChangeNotificationController.registerTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002896 }
2897
2898 /** Unregister a task stack listener so that it stops receiving callbacks. */
2899 @Override
2900 public void unregisterTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002901 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002902 "unregisterTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002903 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002904 }
2905
2906 private void reportCurKeyguardUsageEventLocked(boolean keyguardShowing) {
2907 mAm.reportGlobalUsageEventLocked(keyguardShowing
2908 ? UsageEvents.Event.KEYGUARD_SHOWN
2909 : UsageEvents.Event.KEYGUARD_HIDDEN);
2910 }
2911
2912 @Override
2913 public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
2914 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
2915 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
2916 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
2917 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
2918 }
2919
2920 @Override
2921 public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
2922 IBinder activityToken, int flags) {
2923 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
2924 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
2925 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
2926 }
2927
2928 @Override
2929 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
2930 Bundle args) {
2931 return enqueueAssistContext(requestType, intent, hint, null, null, null,
2932 true /* focused */, true /* newSessionId */, userHandle, args,
2933 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
2934 }
2935
2936 @Override
2937 public Bundle getAssistContextExtras(int requestType) {
2938 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
2939 null, null, true /* focused */, true /* newSessionId */,
2940 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
2941 if (pae == null) {
2942 return null;
2943 }
2944 synchronized (pae) {
2945 while (!pae.haveResult) {
2946 try {
2947 pae.wait();
2948 } catch (InterruptedException e) {
2949 }
2950 }
2951 }
2952 synchronized (mGlobalLock) {
2953 buildAssistBundleLocked(pae, pae.result);
2954 mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002955 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002956 }
2957 return pae.extras;
2958 }
2959
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002960 /**
2961 * Binder IPC calls go through the public entry point.
2962 * This can be called with or without the global lock held.
2963 */
2964 private static int checkCallingPermission(String permission) {
2965 return checkPermission(
2966 permission, Binder.getCallingPid(), UserHandle.getAppId(Binder.getCallingUid()));
2967 }
2968
2969 /** This can be called with or without the global lock held. */
2970 void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
2971 if (!getRecentTasks().isCallerRecents(Binder.getCallingUid())) {
2972 mAmInternal.enforceCallingPermission(permission, func);
2973 }
2974 }
2975
2976 @VisibleForTesting
2977 int checkGetTasksPermission(String permission, int pid, int uid) {
2978 return checkPermission(permission, pid, uid);
2979 }
2980
2981 static int checkPermission(String permission, int pid, int uid) {
2982 if (permission == null) {
2983 return PackageManager.PERMISSION_DENIED;
2984 }
2985 return checkComponentPermission(permission, pid, uid, -1, true);
2986 }
2987
2988 boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
2989 if (getRecentTasks().isCallerRecents(callingUid)) {
2990 // Always allow the recents component to get tasks
2991 return true;
2992 }
2993
2994 boolean allowed = checkGetTasksPermission(android.Manifest.permission.REAL_GET_TASKS,
2995 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
2996 if (!allowed) {
2997 if (checkGetTasksPermission(android.Manifest.permission.GET_TASKS,
2998 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
2999 // Temporary compatibility: some existing apps on the system image may
3000 // still be requesting the old permission and not switched to the new
3001 // one; if so, we'll still allow them full access. This means we need
3002 // to see if they are holding the old permission and are a system app.
3003 try {
3004 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
3005 allowed = true;
3006 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
3007 + " is using old GET_TASKS but privileged; allowing");
3008 }
3009 } catch (RemoteException e) {
3010 }
3011 }
3012 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
3013 + " does not hold REAL_GET_TASKS; limiting output");
3014 }
3015 return allowed;
3016 }
3017
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003018 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
3019 IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
3020 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
3021 int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003022 mAmInternal.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003023 "enqueueAssistContext()");
3024
3025 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003026 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003027 if (activity == null) {
3028 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
3029 return null;
3030 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003031 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003032 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
3033 return null;
3034 }
3035 if (focused) {
3036 if (activityToken != null) {
3037 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
3038 if (activity != caller) {
3039 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
3040 + " is not current top " + activity);
3041 return null;
3042 }
3043 }
3044 } else {
3045 activity = ActivityRecord.forTokenLocked(activityToken);
3046 if (activity == null) {
3047 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
3048 + " couldn't be found");
3049 return null;
3050 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003051 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003052 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
3053 return null;
3054 }
3055 }
3056
3057 PendingAssistExtras pae;
3058 Bundle extras = new Bundle();
3059 if (args != null) {
3060 extras.putAll(args);
3061 }
3062 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003063 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003064
3065 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
3066 userHandle);
3067 pae.isHome = activity.isActivityTypeHome();
3068
3069 // Increment the sessionId if necessary
3070 if (newSessionId) {
3071 mViSessionId++;
3072 }
3073 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003074 activity.app.getThread().requestAssistContextExtras(activity.appToken, pae,
3075 requestType, mViSessionId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003076 mPendingAssistExtras.add(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003077 mUiHandler.postDelayed(pae, timeout);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003078 } catch (RemoteException e) {
3079 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
3080 return null;
3081 }
3082 return pae;
3083 }
3084 }
3085
3086 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
3087 if (result != null) {
3088 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
3089 }
3090 if (pae.hint != null) {
3091 pae.extras.putBoolean(pae.hint, true);
3092 }
3093 }
3094
3095 private void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
3096 IAssistDataReceiver receiver;
3097 synchronized (mGlobalLock) {
3098 mPendingAssistExtras.remove(pae);
3099 receiver = pae.receiver;
3100 }
3101 if (receiver != null) {
3102 // Caller wants result sent back to them.
3103 Bundle sendBundle = new Bundle();
3104 // At least return the receiver extras
3105 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
3106 try {
3107 pae.receiver.onHandleAssistData(sendBundle);
3108 } catch (RemoteException e) {
3109 }
3110 }
3111 }
3112
3113 public class PendingAssistExtras extends Binder implements Runnable {
3114 public final ActivityRecord activity;
3115 public boolean isHome;
3116 public final Bundle extras;
3117 public final Intent intent;
3118 public final String hint;
3119 public final IAssistDataReceiver receiver;
3120 public final int userHandle;
3121 public boolean haveResult = false;
3122 public Bundle result = null;
3123 public AssistStructure structure = null;
3124 public AssistContent content = null;
3125 public Bundle receiverExtras;
3126
3127 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
3128 String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
3129 int _userHandle) {
3130 activity = _activity;
3131 extras = _extras;
3132 intent = _intent;
3133 hint = _hint;
3134 receiver = _receiver;
3135 receiverExtras = _receiverExtras;
3136 userHandle = _userHandle;
3137 }
3138
3139 @Override
3140 public void run() {
3141 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
3142 synchronized (this) {
3143 haveResult = true;
3144 notifyAll();
3145 }
3146 pendingAssistExtrasTimedOut(this);
3147 }
3148 }
3149
3150 @Override
3151 public boolean isAssistDataAllowedOnCurrentActivity() {
3152 int userId;
3153 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003154 final ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003155 if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
3156 return false;
3157 }
3158
3159 final ActivityRecord activity = focusedStack.getTopActivity();
3160 if (activity == null) {
3161 return false;
3162 }
3163 userId = activity.userId;
3164 }
3165 return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
3166 }
3167
3168 @Override
3169 public boolean showAssistFromActivity(IBinder token, Bundle args) {
3170 long ident = Binder.clearCallingIdentity();
3171 try {
3172 synchronized (mGlobalLock) {
3173 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003174 ActivityRecord top = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003175 if (top != caller) {
3176 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3177 + " is not current top " + top);
3178 return false;
3179 }
3180 if (!top.nowVisible) {
3181 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3182 + " is not visible");
3183 return false;
3184 }
3185 }
3186 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
3187 token);
3188 } finally {
3189 Binder.restoreCallingIdentity(ident);
3190 }
3191 }
3192
3193 @Override
3194 public boolean isRootVoiceInteraction(IBinder token) {
3195 synchronized (mGlobalLock) {
3196 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3197 if (r == null) {
3198 return false;
3199 }
3200 return r.rootVoiceInteraction;
3201 }
3202 }
3203
Wale Ogunwalef6733932018-06-27 05:14:34 -07003204 private void onLocalVoiceInteractionStartedLocked(IBinder activity,
3205 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
3206 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
3207 if (activityToCallback == null) return;
3208 activityToCallback.setVoiceSessionLocked(voiceSession);
3209
3210 // Inform the activity
3211 try {
3212 activityToCallback.app.getThread().scheduleLocalVoiceInteractionStarted(activity,
3213 voiceInteractor);
3214 long token = Binder.clearCallingIdentity();
3215 try {
3216 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
3217 } finally {
3218 Binder.restoreCallingIdentity(token);
3219 }
3220 // TODO: VI Should we cache the activity so that it's easier to find later
3221 // rather than scan through all the stacks and activities?
3222 } catch (RemoteException re) {
3223 activityToCallback.clearVoiceSessionLocked();
3224 // TODO: VI Should this terminate the voice session?
3225 }
3226 }
3227
3228 private void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
3229 Slog.d(TAG, "<<< startRunningVoiceLocked()");
3230 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
3231 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
3232 boolean wasRunningVoice = mRunningVoice != null;
3233 mRunningVoice = session;
3234 if (!wasRunningVoice) {
3235 mVoiceWakeLock.acquire();
3236 updateSleepIfNeededLocked();
3237 }
3238 }
3239 }
3240
3241 void finishRunningVoiceLocked() {
3242 if (mRunningVoice != null) {
3243 mRunningVoice = null;
3244 mVoiceWakeLock.release();
3245 updateSleepIfNeededLocked();
3246 }
3247 }
3248
3249 @Override
3250 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3251 synchronized (mGlobalLock) {
3252 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3253 if (keepAwake) {
3254 mVoiceWakeLock.acquire();
3255 } else {
3256 mVoiceWakeLock.release();
3257 }
3258 }
3259 }
3260 }
3261
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003262 @Override
3263 public ComponentName getActivityClassForToken(IBinder token) {
3264 synchronized (mGlobalLock) {
3265 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3266 if (r == null) {
3267 return null;
3268 }
3269 return r.intent.getComponent();
3270 }
3271 }
3272
3273 @Override
3274 public String getPackageForToken(IBinder token) {
3275 synchronized (mGlobalLock) {
3276 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3277 if (r == null) {
3278 return null;
3279 }
3280 return r.packageName;
3281 }
3282 }
3283
3284 @Override
3285 public void showLockTaskEscapeMessage(IBinder token) {
3286 synchronized (mGlobalLock) {
3287 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3288 if (r == null) {
3289 return;
3290 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003291 getLockTaskController().showLockTaskToast();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003292 }
3293 }
3294
3295 @Override
3296 public void keyguardGoingAway(int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003297 enforceNotIsolatedCaller("keyguardGoingAway");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003298 final long token = Binder.clearCallingIdentity();
3299 try {
3300 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003301 mKeyguardController.keyguardGoingAway(flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003302 }
3303 } finally {
3304 Binder.restoreCallingIdentity(token);
3305 }
3306 }
3307
3308 /**
3309 * Try to place task to provided position. The final position might be different depending on
3310 * current user and stacks state. The task will be moved to target stack if it's currently in
3311 * different stack.
3312 */
3313 @Override
3314 public void positionTaskInStack(int taskId, int stackId, int position) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003315 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003316 synchronized (mGlobalLock) {
3317 long ident = Binder.clearCallingIdentity();
3318 try {
3319 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
3320 + taskId + " in stackId=" + stackId + " at position=" + position);
3321 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3322 if (task == null) {
3323 throw new IllegalArgumentException("positionTaskInStack: no task for id="
3324 + taskId);
3325 }
3326
3327 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3328
3329 if (stack == null) {
3330 throw new IllegalArgumentException("positionTaskInStack: no stack for id="
3331 + stackId);
3332 }
3333 if (!stack.isActivityTypeStandardOrUndefined()) {
3334 throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
3335 + " the position of task " + taskId + " in/to non-standard stack");
3336 }
3337
3338 // TODO: Have the callers of this API call a separate reparent method if that is
3339 // what they intended to do vs. having this method also do reparenting.
3340 if (task.getStack() == stack) {
3341 // Change position in current stack.
3342 stack.positionChildAt(task, position);
3343 } else {
3344 // Reparent to new stack.
3345 task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
3346 !DEFER_RESUME, "positionTaskInStack");
3347 }
3348 } finally {
3349 Binder.restoreCallingIdentity(ident);
3350 }
3351 }
3352 }
3353
3354 @Override
3355 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
3356 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
3357 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
3358 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
3359 synchronized (mGlobalLock) {
3360 ActivityRecord record = ActivityRecord.isInStackLocked(token);
3361 if (record == null) {
3362 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
3363 + "found for: " + token);
3364 }
3365 record.setSizeConfigurations(horizontalSizeConfiguration,
3366 verticalSizeConfigurations, smallestSizeConfigurations);
3367 }
3368 }
3369
3370 /**
3371 * Dismisses split-screen multi-window mode.
3372 * @param toTop If true the current primary split-screen stack will be placed or left on top.
3373 */
3374 @Override
3375 public void dismissSplitScreenMode(boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003376 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003377 MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
3378 final long ident = Binder.clearCallingIdentity();
3379 try {
3380 synchronized (mGlobalLock) {
3381 final ActivityStack stack =
3382 mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
3383 if (stack == null) {
3384 Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
3385 return;
3386 }
3387
3388 if (toTop) {
3389 // Caller wants the current split-screen primary stack to be the top stack after
3390 // it goes fullscreen, so move it to the front.
3391 stack.moveToFront("dismissSplitScreenMode");
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003392 } else if (mStackSupervisor.isTopDisplayFocusedStack(stack)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003393 // In this case the current split-screen primary stack shouldn't be the top
3394 // stack after it goes fullscreen, but it current has focus, so we move the
3395 // focus to the top-most split-screen secondary stack next to it.
3396 final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
3397 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
3398 if (otherStack != null) {
3399 otherStack.moveToFront("dismissSplitScreenMode_other");
3400 }
3401 }
3402
Evan Rosky10475742018-09-05 19:02:48 -07003403 stack.setWindowingMode(WINDOWING_MODE_UNDEFINED);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003404 }
3405 } finally {
3406 Binder.restoreCallingIdentity(ident);
3407 }
3408 }
3409
3410 /**
3411 * Dismisses Pip
3412 * @param animate True if the dismissal should be animated.
3413 * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
3414 * default animation duration should be used.
3415 */
3416 @Override
3417 public void dismissPip(boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003418 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003419 final long ident = Binder.clearCallingIdentity();
3420 try {
3421 synchronized (mGlobalLock) {
3422 final PinnedActivityStack stack =
3423 mStackSupervisor.getDefaultDisplay().getPinnedStack();
3424 if (stack == null) {
3425 Slog.w(TAG, "dismissPip: pinned stack not found.");
3426 return;
3427 }
3428 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
3429 throw new IllegalArgumentException("Stack: " + stack
3430 + " doesn't support animated resize.");
3431 }
3432 if (animate) {
3433 stack.animateResizePinnedStack(null /* sourceHintBounds */,
3434 null /* destBounds */, animationDuration, false /* fromFullscreen */);
3435 } else {
3436 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
3437 }
3438 }
3439 } finally {
3440 Binder.restoreCallingIdentity(ident);
3441 }
3442 }
3443
3444 @Override
3445 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003446 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003447 synchronized (mGlobalLock) {
3448 mSuppressResizeConfigChanges = suppress;
3449 }
3450 }
3451
3452 /**
3453 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
3454 * animated the stack to the fullscreen, but can also be called if we are relaunching an
3455 * activity and clearing the task at the same time.
3456 */
3457 @Override
3458 // TODO: API should just be about changing windowing modes...
3459 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003460 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003461 "moveTasksToFullscreenStack()");
3462 synchronized (mGlobalLock) {
3463 final long origId = Binder.clearCallingIdentity();
3464 try {
3465 final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
3466 if (stack != null){
3467 if (!stack.isActivityTypeStandardOrUndefined()) {
3468 throw new IllegalArgumentException(
3469 "You can't move tasks from non-standard stacks.");
3470 }
3471 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
3472 }
3473 } finally {
3474 Binder.restoreCallingIdentity(origId);
3475 }
3476 }
3477 }
3478
3479 /**
3480 * Moves the top activity in the input stackId to the pinned stack.
3481 *
3482 * @param stackId Id of stack to move the top activity to pinned stack.
3483 * @param bounds Bounds to use for pinned stack.
3484 *
3485 * @return True if the top activity of the input stack was successfully moved to the pinned
3486 * stack.
3487 */
3488 @Override
3489 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003490 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003491 "moveTopActivityToPinnedStack()");
3492 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003493 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003494 throw new IllegalStateException("moveTopActivityToPinnedStack:"
3495 + "Device doesn't support picture-in-picture mode");
3496 }
3497
3498 long ident = Binder.clearCallingIdentity();
3499 try {
3500 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
3501 } finally {
3502 Binder.restoreCallingIdentity(ident);
3503 }
3504 }
3505 }
3506
3507 @Override
3508 public boolean isInMultiWindowMode(IBinder token) {
3509 final long origId = Binder.clearCallingIdentity();
3510 try {
3511 synchronized (mGlobalLock) {
3512 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3513 if (r == null) {
3514 return false;
3515 }
3516 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
3517 return r.inMultiWindowMode();
3518 }
3519 } finally {
3520 Binder.restoreCallingIdentity(origId);
3521 }
3522 }
3523
3524 @Override
3525 public boolean isInPictureInPictureMode(IBinder token) {
3526 final long origId = Binder.clearCallingIdentity();
3527 try {
3528 synchronized (mGlobalLock) {
3529 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
3530 }
3531 } finally {
3532 Binder.restoreCallingIdentity(origId);
3533 }
3534 }
3535
3536 private boolean isInPictureInPictureMode(ActivityRecord r) {
3537 if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
3538 || r.getStack().isInStackLocked(r) == null) {
3539 return false;
3540 }
3541
3542 // If we are animating to fullscreen then we have already dispatched the PIP mode
3543 // changed, so we should reflect that check here as well.
3544 final PinnedActivityStack stack = r.getStack();
3545 final PinnedStackWindowController windowController = stack.getWindowContainerController();
3546 return !windowController.isAnimatingBoundsToFullscreen();
3547 }
3548
3549 @Override
3550 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
3551 final long origId = Binder.clearCallingIdentity();
3552 try {
3553 synchronized (mGlobalLock) {
3554 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3555 "enterPictureInPictureMode", token, params);
3556
3557 // If the activity is already in picture in picture mode, then just return early
3558 if (isInPictureInPictureMode(r)) {
3559 return true;
3560 }
3561
3562 // Activity supports picture-in-picture, now check that we can enter PiP at this
3563 // point, if it is
3564 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
3565 false /* beforeStopping */)) {
3566 return false;
3567 }
3568
3569 final Runnable enterPipRunnable = () -> {
Wale Ogunwalef276a6f2018-06-15 08:26:07 -07003570 synchronized (mGlobalLock) {
3571 // Only update the saved args from the args that are set
3572 r.pictureInPictureArgs.copyOnlySet(params);
3573 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
3574 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
3575 // Adjust the source bounds by the insets for the transition down
3576 final Rect sourceBounds = new Rect(
3577 r.pictureInPictureArgs.getSourceRectHint());
3578 mStackSupervisor.moveActivityToPinnedStackLocked(
3579 r, sourceBounds, aspectRatio, "enterPictureInPictureMode");
3580 final PinnedActivityStack stack = r.getStack();
3581 stack.setPictureInPictureAspectRatio(aspectRatio);
3582 stack.setPictureInPictureActions(actions);
3583 MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
3584 r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
3585 logPictureInPictureArgs(params);
3586 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003587 };
3588
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003589 if (isKeyguardLocked()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003590 // If the keyguard is showing or occluded, then try and dismiss it before
3591 // entering picture-in-picture (this will prompt the user to authenticate if the
3592 // device is currently locked).
3593 dismissKeyguard(token, new KeyguardDismissCallback() {
3594 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003595 public void onDismissSucceeded() {
3596 mH.post(enterPipRunnable);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003597 }
3598 }, null /* message */);
3599 } else {
3600 // Enter picture in picture immediately otherwise
3601 enterPipRunnable.run();
3602 }
3603 return true;
3604 }
3605 } finally {
3606 Binder.restoreCallingIdentity(origId);
3607 }
3608 }
3609
3610 @Override
3611 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
3612 final long origId = Binder.clearCallingIdentity();
3613 try {
3614 synchronized (mGlobalLock) {
3615 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3616 "setPictureInPictureParams", token, params);
3617
3618 // Only update the saved args from the args that are set
3619 r.pictureInPictureArgs.copyOnlySet(params);
3620 if (r.inPinnedWindowingMode()) {
3621 // If the activity is already in picture-in-picture, update the pinned stack now
3622 // if it is not already expanding to fullscreen. Otherwise, the arguments will
3623 // be used the next time the activity enters PiP
3624 final PinnedActivityStack stack = r.getStack();
3625 if (!stack.isAnimatingBoundsToFullscreen()) {
3626 stack.setPictureInPictureAspectRatio(
3627 r.pictureInPictureArgs.getAspectRatio());
3628 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
3629 }
3630 }
3631 logPictureInPictureArgs(params);
3632 }
3633 } finally {
3634 Binder.restoreCallingIdentity(origId);
3635 }
3636 }
3637
3638 @Override
3639 public int getMaxNumPictureInPictureActions(IBinder token) {
3640 // Currently, this is a static constant, but later, we may change this to be dependent on
3641 // the context of the activity
3642 return 3;
3643 }
3644
3645 private void logPictureInPictureArgs(PictureInPictureParams params) {
3646 if (params.hasSetActions()) {
3647 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
3648 params.getActions().size());
3649 }
3650 if (params.hasSetAspectRatio()) {
3651 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
3652 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
3653 MetricsLogger.action(lm);
3654 }
3655 }
3656
3657 /**
3658 * Checks the state of the system and the activity associated with the given {@param token} to
3659 * verify that picture-in-picture is supported for that activity.
3660 *
3661 * @return the activity record for the given {@param token} if all the checks pass.
3662 */
3663 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
3664 IBinder token, PictureInPictureParams params) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003665 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003666 throw new IllegalStateException(caller
3667 + ": Device doesn't support picture-in-picture mode.");
3668 }
3669
3670 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3671 if (r == null) {
3672 throw new IllegalStateException(caller
3673 + ": Can't find activity for token=" + token);
3674 }
3675
3676 if (!r.supportsPictureInPicture()) {
3677 throw new IllegalStateException(caller
3678 + ": Current activity does not support picture-in-picture.");
3679 }
3680
3681 if (params.hasSetAspectRatio()
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003682 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003683 params.getAspectRatio())) {
3684 final float minAspectRatio = mContext.getResources().getFloat(
3685 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
3686 final float maxAspectRatio = mContext.getResources().getFloat(
3687 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
3688 throw new IllegalArgumentException(String.format(caller
3689 + ": Aspect ratio is too extreme (must be between %f and %f).",
3690 minAspectRatio, maxAspectRatio));
3691 }
3692
3693 // Truncate the number of actions if necessary
3694 params.truncateActions(getMaxNumPictureInPictureActions(token));
3695
3696 return r;
3697 }
3698
3699 @Override
3700 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003701 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003702 synchronized (mGlobalLock) {
3703 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
3704 if (r == null) {
3705 throw new IllegalArgumentException("Activity does not exist; token="
3706 + activityToken);
3707 }
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07003708 return r.getUriPermissionsLocked().getExternalToken();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003709 }
3710 }
3711
3712 @Override
3713 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
3714 Rect tempDockedTaskInsetBounds,
3715 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003716 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003717 long ident = Binder.clearCallingIdentity();
3718 try {
3719 synchronized (mGlobalLock) {
3720 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
3721 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
3722 PRESERVE_WINDOWS);
3723 }
3724 } finally {
3725 Binder.restoreCallingIdentity(ident);
3726 }
3727 }
3728
3729 @Override
3730 public void setSplitScreenResizing(boolean resizing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003731 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003732 final long ident = Binder.clearCallingIdentity();
3733 try {
3734 synchronized (mGlobalLock) {
3735 mStackSupervisor.setSplitScreenResizing(resizing);
3736 }
3737 } finally {
3738 Binder.restoreCallingIdentity(ident);
3739 }
3740 }
3741
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003742 /**
3743 * Check that we have the features required for VR-related API calls, and throw an exception if
3744 * not.
3745 */
3746 void enforceSystemHasVrFeature() {
3747 if (!mContext.getPackageManager().hasSystemFeature(
3748 PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
3749 throw new UnsupportedOperationException("VR mode not supported on this device!");
3750 }
3751 }
3752
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003753 @Override
3754 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003755 enforceSystemHasVrFeature();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003756
3757 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3758
3759 ActivityRecord r;
3760 synchronized (mGlobalLock) {
3761 r = ActivityRecord.isInStackLocked(token);
3762 }
3763
3764 if (r == null) {
3765 throw new IllegalArgumentException();
3766 }
3767
3768 int err;
3769 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
3770 VrManagerInternal.NO_ERROR) {
3771 return err;
3772 }
3773
3774 // Clear the binder calling uid since this path may call moveToTask().
3775 final long callingId = Binder.clearCallingIdentity();
3776 try {
3777 synchronized (mGlobalLock) {
3778 r.requestedVrComponent = (enabled) ? packageName : null;
3779
3780 // Update associated state if this activity is currently focused
Andrii Kulian52d255c2018-07-13 11:32:19 -07003781 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003782 applyUpdateVrModeLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003783 }
3784 return 0;
3785 }
3786 } finally {
3787 Binder.restoreCallingIdentity(callingId);
3788 }
3789 }
3790
3791 @Override
3792 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
3793 Slog.i(TAG, "Activity tried to startLocalVoiceInteraction");
3794 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003795 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003796 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
3797 throw new SecurityException("Only focused activity can call startVoiceInteraction");
3798 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07003799 if (mRunningVoice != null || activity.getTask().voiceSession != null
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003800 || activity.voiceSession != null) {
3801 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
3802 return;
3803 }
3804 if (activity.pendingVoiceInteractionStart) {
3805 Slog.w(TAG, "Pending start of voice interaction already.");
3806 return;
3807 }
3808 activity.pendingVoiceInteractionStart = true;
3809 }
3810 LocalServices.getService(VoiceInteractionManagerInternal.class)
3811 .startLocalVoiceInteraction(callingActivity, options);
3812 }
3813
3814 @Override
3815 public void stopLocalVoiceInteraction(IBinder callingActivity) {
3816 LocalServices.getService(VoiceInteractionManagerInternal.class)
3817 .stopLocalVoiceInteraction(callingActivity);
3818 }
3819
3820 @Override
3821 public boolean supportsLocalVoiceInteraction() {
3822 return LocalServices.getService(VoiceInteractionManagerInternal.class)
3823 .supportsLocalVoiceInteraction();
3824 }
3825
3826 /** Notifies all listeners when the pinned stack animation starts. */
3827 @Override
3828 public void notifyPinnedStackAnimationStarted() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003829 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003830 }
3831
3832 /** Notifies all listeners when the pinned stack animation ends. */
3833 @Override
3834 public void notifyPinnedStackAnimationEnded() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003835 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003836 }
3837
3838 @Override
3839 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003840 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003841 final long ident = Binder.clearCallingIdentity();
3842 try {
3843 synchronized (mGlobalLock) {
3844 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
3845 }
3846 } finally {
3847 Binder.restoreCallingIdentity(ident);
3848 }
3849 }
3850
3851 @Override
3852 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003853 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003854
3855 synchronized (mGlobalLock) {
3856 // Check if display is initialized in AM.
3857 if (!mStackSupervisor.isDisplayAdded(displayId)) {
3858 // Call might come when display is not yet added or has already been removed.
3859 if (DEBUG_CONFIGURATION) {
3860 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
3861 + displayId);
3862 }
3863 return false;
3864 }
3865
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003866 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003867 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003868 values = mWindowManager.computeNewConfiguration(displayId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003869 }
3870
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003871 if (mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003872 // Update OOM levels based on display size.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003873 mAm.mProcessList.applyDisplaySize(mWindowManager);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003874 }
3875
3876 final long origId = Binder.clearCallingIdentity();
3877 try {
3878 if (values != null) {
3879 Settings.System.clearConfiguration(values);
3880 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003881 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003882 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
3883 return mTmpUpdateConfigurationResult.changes != 0;
3884 } finally {
3885 Binder.restoreCallingIdentity(origId);
3886 }
3887 }
3888 }
3889
3890 @Override
3891 public boolean updateConfiguration(Configuration values) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003892 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003893
3894 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003895 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003896 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003897 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003898 }
3899
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003900 if (mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003901 // Update OOM levels based on display size.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003902 mAm.mProcessList.applyDisplaySize(mWindowManager);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003903 }
3904
3905 final long origId = Binder.clearCallingIdentity();
3906 try {
3907 if (values != null) {
3908 Settings.System.clearConfiguration(values);
3909 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003910 updateConfigurationLocked(values, null, false, false /* persistent */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003911 UserHandle.USER_NULL, false /* deferResume */,
3912 mTmpUpdateConfigurationResult);
3913 return mTmpUpdateConfigurationResult.changes != 0;
3914 } finally {
3915 Binder.restoreCallingIdentity(origId);
3916 }
3917 }
3918 }
3919
3920 @Override
3921 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
3922 CharSequence message) {
3923 if (message != null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003924 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003925 Manifest.permission.SHOW_KEYGUARD_MESSAGE, "dismissKeyguard()");
3926 }
3927 final long callingId = Binder.clearCallingIdentity();
3928 try {
3929 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003930 mKeyguardController.dismissKeyguard(token, callback, message);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003931 }
3932 } finally {
3933 Binder.restoreCallingIdentity(callingId);
3934 }
3935 }
3936
3937 @Override
3938 public void cancelTaskWindowTransition(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003939 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003940 "cancelTaskWindowTransition()");
3941 final long ident = Binder.clearCallingIdentity();
3942 try {
3943 synchronized (mGlobalLock) {
3944 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
3945 MATCH_TASK_IN_STACKS_ONLY);
3946 if (task == null) {
3947 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
3948 return;
3949 }
3950 task.cancelWindowTransition();
3951 }
3952 } finally {
3953 Binder.restoreCallingIdentity(ident);
3954 }
3955 }
3956
3957 @Override
3958 public ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003959 enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003960 final long ident = Binder.clearCallingIdentity();
3961 try {
3962 final TaskRecord task;
3963 synchronized (mGlobalLock) {
3964 task = mStackSupervisor.anyTaskForIdLocked(taskId,
3965 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
3966 if (task == null) {
3967 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
3968 return null;
3969 }
3970 }
3971 // Don't call this while holding the lock as this operation might hit the disk.
3972 return task.getSnapshot(reducedResolution);
3973 } finally {
3974 Binder.restoreCallingIdentity(ident);
3975 }
3976 }
3977
3978 @Override
3979 public void setDisablePreviewScreenshots(IBinder token, boolean disable) {
3980 synchronized (mGlobalLock) {
3981 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3982 if (r == null) {
3983 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
3984 + token);
3985 return;
3986 }
3987 final long origId = Binder.clearCallingIdentity();
3988 try {
3989 r.setDisablePreviewScreenshots(disable);
3990 } finally {
3991 Binder.restoreCallingIdentity(origId);
3992 }
3993 }
3994 }
3995
3996 /** Return the user id of the last resumed activity. */
3997 @Override
3998 public @UserIdInt
3999 int getLastResumedActivityUserId() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004000 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004001 Manifest.permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
4002 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07004003 if (mLastResumedActivity == null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004004 return getCurrentUserId();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004005 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004006 return mLastResumedActivity.userId;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004007 }
4008 }
4009
4010 @Override
4011 public void updateLockTaskFeatures(int userId, int flags) {
4012 final int callingUid = Binder.getCallingUid();
4013 if (callingUid != 0 && callingUid != SYSTEM_UID) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004014 mAmInternal.enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004015 "updateLockTaskFeatures()");
4016 }
4017 synchronized (mGlobalLock) {
4018 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
4019 Integer.toHexString(flags));
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07004020 getLockTaskController().updateLockTaskFeatures(userId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004021 }
4022 }
4023
4024 @Override
4025 public void setShowWhenLocked(IBinder token, boolean showWhenLocked) {
4026 synchronized (mGlobalLock) {
4027 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4028 if (r == null) {
4029 return;
4030 }
4031 final long origId = Binder.clearCallingIdentity();
4032 try {
4033 r.setShowWhenLocked(showWhenLocked);
4034 } finally {
4035 Binder.restoreCallingIdentity(origId);
4036 }
4037 }
4038 }
4039
4040 @Override
4041 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) {
4042 synchronized (mGlobalLock) {
4043 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4044 if (r == null) {
4045 return;
4046 }
4047 final long origId = Binder.clearCallingIdentity();
4048 try {
4049 r.setTurnScreenOn(turnScreenOn);
4050 } finally {
4051 Binder.restoreCallingIdentity(origId);
4052 }
4053 }
4054 }
4055
4056 @Override
4057 public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004058 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004059 "registerRemoteAnimations");
4060 definition.setCallingPid(Binder.getCallingPid());
4061 synchronized (mGlobalLock) {
4062 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4063 if (r == null) {
4064 return;
4065 }
4066 final long origId = Binder.clearCallingIdentity();
4067 try {
4068 r.registerRemoteAnimations(definition);
4069 } finally {
4070 Binder.restoreCallingIdentity(origId);
4071 }
4072 }
4073 }
4074
4075 @Override
4076 public void registerRemoteAnimationForNextActivityStart(String packageName,
4077 RemoteAnimationAdapter adapter) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004078 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004079 "registerRemoteAnimationForNextActivityStart");
4080 adapter.setCallingPid(Binder.getCallingPid());
4081 synchronized (mGlobalLock) {
4082 final long origId = Binder.clearCallingIdentity();
4083 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07004084 getActivityStartController().registerRemoteAnimationForNextActivityStart(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004085 packageName, adapter);
4086 } finally {
4087 Binder.restoreCallingIdentity(origId);
4088 }
4089 }
4090 }
4091
4092 /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
4093 @Override
4094 public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
4095 synchronized (mGlobalLock) {
4096 final long origId = Binder.clearCallingIdentity();
4097 try {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004098 mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004099 } finally {
4100 Binder.restoreCallingIdentity(origId);
4101 }
4102 }
4103 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004104
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004105 @Override
4106 public void setVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004107 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004108 synchronized (mGlobalLock) {
4109 synchronized (mAm.mPidsSelfLocked) {
4110 final int pid = Binder.getCallingPid();
4111 final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004112 mVrController.setVrThreadLocked(tid, pid, proc.getWindowProcessController());
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004113 }
4114 }
4115 }
4116
4117 @Override
4118 public void setPersistentVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004119 if (checkCallingPermission(Manifest.permission.RESTRICTED_VR_ACCESS)
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004120 != PERMISSION_GRANTED) {
4121 final String msg = "Permission Denial: setPersistentVrThread() from pid="
4122 + Binder.getCallingPid()
4123 + ", uid=" + Binder.getCallingUid()
4124 + " requires " + Manifest.permission.RESTRICTED_VR_ACCESS;
4125 Slog.w(TAG, msg);
4126 throw new SecurityException(msg);
4127 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004128 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004129 synchronized (mGlobalLock) {
4130 synchronized (mAm.mPidsSelfLocked) {
4131 final int pid = Binder.getCallingPid();
4132 final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
4133 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
4134 }
4135 }
4136 }
4137
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004138 @Override
4139 public void stopAppSwitches() {
4140 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
4141 synchronized (mGlobalLock) {
4142 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME;
4143 mDidAppSwitch = false;
4144 getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
4145 }
4146 }
4147
4148 @Override
4149 public void resumeAppSwitches() {
4150 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
4151 synchronized (mGlobalLock) {
4152 // Note that we don't execute any pending app switches... we will
4153 // let those wait until either the timeout, or the next start
4154 // activity request.
4155 mAppSwitchesAllowedTime = 0;
4156 }
4157 }
4158
4159 void onStartActivitySetDidAppSwitch() {
4160 if (mDidAppSwitch) {
4161 // This is the second allowed switch since we stopped switches, so now just generally
4162 // allow switches. Use case:
4163 // - user presses home (switches disabled, switch to home, mDidAppSwitch now true);
4164 // - user taps a home icon (coming from home so allowed, we hit here and now allow
4165 // anyone to switch again).
4166 mAppSwitchesAllowedTime = 0;
4167 } else {
4168 mDidAppSwitch = true;
4169 }
4170 }
4171
4172 /** @return whether the system should disable UI modes incompatible with VR mode. */
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004173 boolean shouldDisableNonVrUiLocked() {
4174 return mVrController.shouldDisableNonVrUiLocked();
4175 }
4176
Wale Ogunwale53783742018-09-16 10:21:51 -07004177 private void applyUpdateVrModeLocked(ActivityRecord r) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004178 // VR apps are expected to run in a main display. If an app is turning on VR for
4179 // itself, but lives in a dynamic stack, then make sure that it is moved to the main
4180 // fullscreen stack before enabling VR Mode.
4181 // TODO: The goal of this code is to keep the VR app on the main display. When the
4182 // stack implementation changes in the future, keep in mind that the use of the fullscreen
4183 // stack is a means to move the activity to the main display and a moveActivityToDisplay()
4184 // option would be a better choice here.
4185 if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
4186 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
4187 + " to main stack for VR");
4188 final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
4189 WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
4190 moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
4191 }
4192 mH.post(() -> {
4193 if (!mVrController.onVrModeChanged(r)) {
4194 return;
4195 }
4196 synchronized (mGlobalLock) {
4197 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
4198 mWindowManager.disableNonVrUi(disableNonVrUi);
4199 if (disableNonVrUi) {
4200 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
4201 // then remove the pinned stack.
4202 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
4203 }
4204 }
4205 });
4206 }
4207
Wale Ogunwale53783742018-09-16 10:21:51 -07004208 @Override
4209 public int getPackageScreenCompatMode(String packageName) {
4210 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4211 synchronized (mGlobalLock) {
4212 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4213 }
4214 }
4215
4216 @Override
4217 public void setPackageScreenCompatMode(String packageName, int mode) {
4218 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4219 "setPackageScreenCompatMode");
4220 synchronized (mGlobalLock) {
4221 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4222 }
4223 }
4224
4225 @Override
4226 public boolean getPackageAskScreenCompat(String packageName) {
4227 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4228 synchronized (mGlobalLock) {
4229 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4230 }
4231 }
4232
4233 @Override
4234 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4235 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4236 "setPackageAskScreenCompat");
4237 synchronized (mGlobalLock) {
4238 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4239 }
4240 }
4241
Andrii Kulian5f750bc2018-07-17 08:57:23 -07004242 ActivityStack getTopDisplayFocusedStack() {
4243 return mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004244 }
4245
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004246 /** Pokes the task persister. */
4247 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
4248 mRecentTasks.notifyTaskPersisterLocked(task, flush);
4249 }
4250
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004251 void onTopProcChangedLocked(WindowProcessController proc) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004252 mVrController.onTopProcChangedLocked(proc);
4253 }
4254
4255 boolean isKeyguardLocked() {
4256 return mKeyguardController.isKeyguardLocked();
4257 }
4258
4259 boolean isNextTransitionForward() {
4260 int transit = mWindowManager.getPendingAppTransition();
4261 return transit == TRANSIT_ACTIVITY_OPEN
4262 || transit == TRANSIT_TASK_OPEN
4263 || transit == TRANSIT_TASK_TO_FRONT;
4264 }
4265
Wale Ogunwalef6733932018-06-27 05:14:34 -07004266 void dumpSleepStates(PrintWriter pw, boolean testPssMode) {
4267 synchronized (mGlobalLock) {
4268 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
4269 if (mRunningVoice != null) {
4270 pw.println(" mRunningVoice=" + mRunningVoice);
4271 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
4272 }
4273 pw.println(" mSleeping=" + mSleeping);
4274 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + testPssMode);
4275 pw.println(" mVrController=" + mVrController);
4276 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004277 }
4278
Wale Ogunwalef6733932018-06-27 05:14:34 -07004279 void writeSleepStateToProto(ProtoOutputStream proto) {
4280 for (ActivityTaskManagerInternal.SleepToken st : mStackSupervisor.mSleepTokens) {
4281 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS,
4282 st.toString());
4283 }
4284
4285 if (mRunningVoice != null) {
4286 final long vrToken = proto.start(
4287 ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
4288 proto.write(ActivityManagerServiceDumpProcessesProto.Voice.SESSION,
4289 mRunningVoice.toString());
4290 mVoiceWakeLock.writeToProto(
4291 proto, ActivityManagerServiceDumpProcessesProto.Voice.WAKELOCK);
4292 proto.end(vrToken);
4293 }
4294
4295 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
4296 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN,
4297 mShuttingDown);
4298 mVrController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004299 }
4300
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004301 int getCurrentUserId() {
4302 return mAmInternal.getCurrentUserId();
4303 }
4304
4305 private void enforceNotIsolatedCaller(String caller) {
4306 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4307 throw new SecurityException("Isolated process not allowed to call " + caller);
4308 }
4309 }
4310
Wale Ogunwalef6733932018-06-27 05:14:34 -07004311 public Configuration getConfiguration() {
4312 Configuration ci;
4313 synchronized(mGlobalLock) {
Yunfan Chen75157d72018-07-27 14:47:21 +09004314 ci = new Configuration(getGlobalConfigurationForCallingPid());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004315 ci.userSetLocale = false;
4316 }
4317 return ci;
4318 }
4319
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004320 /**
4321 * Current global configuration information. Contains general settings for the entire system,
4322 * also corresponds to the merged configuration of the default display.
4323 */
4324 Configuration getGlobalConfiguration() {
4325 return mStackSupervisor.getConfiguration();
4326 }
4327
4328 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4329 boolean initLocale) {
4330 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
4331 }
4332
4333 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4334 boolean initLocale, boolean deferResume) {
4335 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
4336 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
4337 UserHandle.USER_NULL, deferResume);
4338 }
4339
4340 void updatePersistentConfiguration(Configuration values, @UserIdInt int userId) {
4341 final long origId = Binder.clearCallingIdentity();
4342 try {
4343 synchronized (mGlobalLock) {
4344 updateConfigurationLocked(values, null, false, true, userId,
4345 false /* deferResume */);
4346 }
4347 } finally {
4348 Binder.restoreCallingIdentity(origId);
4349 }
4350 }
4351
4352 void updateUserConfiguration() {
4353 synchronized (mGlobalLock) {
4354 final Configuration configuration = new Configuration(getGlobalConfiguration());
4355 final int currentUserId = mAmInternal.getCurrentUserId();
4356 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
4357 currentUserId, Settings.System.canWrite(mContext));
4358 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
4359 false /* persistent */, currentUserId, false /* deferResume */);
4360 }
4361 }
4362
4363 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4364 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
4365 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
4366 deferResume, null /* result */);
4367 }
4368
4369 /**
4370 * Do either or both things: (1) change the current configuration, and (2)
4371 * make sure the given activity is running with the (now) current
4372 * configuration. Returns true if the activity has been left running, or
4373 * false if <var>starting</var> is being destroyed to match the new
4374 * configuration.
4375 *
4376 * @param userId is only used when persistent parameter is set to true to persist configuration
4377 * for that particular user
4378 */
4379 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4380 boolean initLocale, boolean persistent, int userId, boolean deferResume,
4381 ActivityTaskManagerService.UpdateConfigurationResult result) {
4382 int changes = 0;
4383 boolean kept = true;
4384
4385 if (mWindowManager != null) {
4386 mWindowManager.deferSurfaceLayout();
4387 }
4388 try {
4389 if (values != null) {
4390 changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
4391 deferResume);
4392 }
4393
4394 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4395 } finally {
4396 if (mWindowManager != null) {
4397 mWindowManager.continueSurfaceLayout();
4398 }
4399 }
4400
4401 if (result != null) {
4402 result.changes = changes;
4403 result.activityRelaunched = !kept;
4404 }
4405 return kept;
4406 }
4407
4408 /**
4409 * Returns true if this configuration change is interesting enough to send an
4410 * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
4411 */
4412 private static boolean isSplitConfigurationChange(int configDiff) {
4413 return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
4414 }
4415
4416 /** Update default (global) configuration and notify listeners about changes. */
4417 private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
4418 boolean persistent, int userId, boolean deferResume) {
4419 mTempConfig.setTo(getGlobalConfiguration());
4420 final int changes = mTempConfig.updateFrom(values);
4421 if (changes == 0) {
4422 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
4423 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
4424 // performDisplayOverrideConfigUpdate in order to send the new display configuration
4425 // (even if there are no actual changes) to unfreeze the window.
4426 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
4427 return 0;
4428 }
4429
4430 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
4431 "Updating global configuration to: " + values);
4432
4433 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
4434 StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
4435 values.colorMode,
4436 values.densityDpi,
4437 values.fontScale,
4438 values.hardKeyboardHidden,
4439 values.keyboard,
4440 values.keyboardHidden,
4441 values.mcc,
4442 values.mnc,
4443 values.navigation,
4444 values.navigationHidden,
4445 values.orientation,
4446 values.screenHeightDp,
4447 values.screenLayout,
4448 values.screenWidthDp,
4449 values.smallestScreenWidthDp,
4450 values.touchscreen,
4451 values.uiMode);
4452
4453
4454 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
4455 final LocaleList locales = values.getLocales();
4456 int bestLocaleIndex = 0;
4457 if (locales.size() > 1) {
4458 if (mSupportedSystemLocales == null) {
4459 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
4460 }
4461 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
4462 }
4463 SystemProperties.set("persist.sys.locale",
4464 locales.get(bestLocaleIndex).toLanguageTag());
4465 LocaleList.setDefault(locales, bestLocaleIndex);
4466 mAm.mHandler.sendMessage(mAm.mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
4467 locales.get(bestLocaleIndex)));
4468 }
4469
Yunfan Chen75157d72018-07-27 14:47:21 +09004470 mTempConfig.seq = increaseConfigurationSeqLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004471
4472 // Update stored global config and notify everyone about the change.
4473 mStackSupervisor.onConfigurationChanged(mTempConfig);
4474
4475 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
4476 // TODO(multi-display): Update UsageEvents#Event to include displayId.
4477 mAm.mUsageStatsService.reportConfigurationChange(
4478 mTempConfig, mAmInternal.getCurrentUserId());
4479
4480 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
Wale Ogunwalef6733932018-06-27 05:14:34 -07004481 updateShouldShowDialogsLocked(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004482
4483 AttributeCache ac = AttributeCache.instance();
4484 if (ac != null) {
4485 ac.updateConfiguration(mTempConfig);
4486 }
4487
4488 // Make sure all resources in our process are updated right now, so that anyone who is going
4489 // to retrieve resource values after we return will be sure to get the new ones. This is
4490 // especially important during boot, where the first config change needs to guarantee all
4491 // resources have that config before following boot code is executed.
4492 mAm.mSystemThread.applyConfigurationToResources(mTempConfig);
4493
4494 // We need another copy of global config because we're scheduling some calls instead of
4495 // running them in place. We need to be sure that object we send will be handled unchanged.
4496 final Configuration configCopy = new Configuration(mTempConfig);
4497 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
4498 Message msg = mAm.mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
4499 msg.obj = configCopy;
4500 msg.arg1 = userId;
4501 mAm.mHandler.sendMessage(msg);
4502 }
4503
Yunfan Chen75157d72018-07-27 14:47:21 +09004504 // TODO: Consider using mPidMap to update configurations for processes.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004505 for (int i = mAm.mLruProcesses.size() - 1; i >= 0; i--) {
4506 ProcessRecord app = mAm.mLruProcesses.get(i);
4507 try {
4508 if (app.thread != null) {
4509 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
4510 + app.processName + " new config " + configCopy);
4511 getLifecycleManager().scheduleTransaction(app.thread,
4512 ConfigurationChangeItem.obtain(configCopy));
4513 }
4514 } catch (Exception e) {
4515 Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
4516 }
4517 }
4518
4519 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
4520 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
4521 | Intent.FLAG_RECEIVER_FOREGROUND
4522 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4523 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4524 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4525 UserHandle.USER_ALL);
4526 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
4527 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
4528 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
4529 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
4530 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4531 if (initLocale || !mAm.mProcessesReady) {
4532 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
4533 }
4534 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4535 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4536 UserHandle.USER_ALL);
4537 }
4538
4539 // Send a broadcast to PackageInstallers if the configuration change is interesting
4540 // for the purposes of installing additional splits.
4541 if (!initLocale && isSplitConfigurationChange(changes)) {
4542 intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
4543 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
4544 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
4545
4546 // Typically only app stores will have this permission.
4547 String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES };
4548 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions,
4549 OP_NONE, null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
4550 }
4551
4552 // Override configuration of the default display duplicates global config, so we need to
4553 // update it also. This will also notify WindowManager about changes.
4554 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
4555 DEFAULT_DISPLAY);
4556
4557 return changes;
4558 }
4559
4560 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
4561 boolean deferResume, int displayId) {
4562 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
4563 displayId, null /* result */);
4564 }
4565
4566 /**
4567 * Updates override configuration specific for the selected display. If no config is provided,
4568 * new one will be computed in WM based on current display info.
4569 */
4570 boolean updateDisplayOverrideConfigurationLocked(Configuration values,
4571 ActivityRecord starting, boolean deferResume, int displayId,
4572 ActivityTaskManagerService.UpdateConfigurationResult result) {
4573 int changes = 0;
4574 boolean kept = true;
4575
4576 if (mWindowManager != null) {
4577 mWindowManager.deferSurfaceLayout();
4578 }
4579 try {
4580 if (values != null) {
4581 if (displayId == DEFAULT_DISPLAY) {
4582 // Override configuration of the default display duplicates global config, so
4583 // we're calling global config update instead for default display. It will also
4584 // apply the correct override config.
4585 changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
4586 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
4587 } else {
4588 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
4589 }
4590 }
4591
4592 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4593 } finally {
4594 if (mWindowManager != null) {
4595 mWindowManager.continueSurfaceLayout();
4596 }
4597 }
4598
4599 if (result != null) {
4600 result.changes = changes;
4601 result.activityRelaunched = !kept;
4602 }
4603 return kept;
4604 }
4605
4606 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
4607 int displayId) {
4608 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
4609 final int changes = mTempConfig.updateFrom(values);
4610 if (changes != 0) {
4611 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
4612 + mTempConfig + " for displayId=" + displayId);
4613 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
4614
4615 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
4616 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004617 mAppWarnings.onDensityChanged();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004618
4619 mAm.killAllBackgroundProcessesExcept(N,
4620 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
4621 }
4622 }
4623
4624 // Update the configuration with WM first and check if any of the stacks need to be resized
4625 // due to the configuration change. If so, resize the stacks now and do any relaunches if
4626 // necessary. This way we don't need to relaunch again afterwards in
4627 // ensureActivityConfiguration().
4628 if (mWindowManager != null) {
4629 final int[] resizedStacks =
4630 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
4631 if (resizedStacks != null) {
4632 for (int stackId : resizedStacks) {
4633 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
4634 }
4635 }
4636 }
4637
4638 return changes;
4639 }
4640
Wale Ogunwalef6733932018-06-27 05:14:34 -07004641 private void updateEventDispatchingLocked(boolean booted) {
4642 mWindowManager.setEventDispatching(booted && !mShuttingDown);
4643 }
4644
4645 void enableScreenAfterBoot(boolean booted) {
4646 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4647 SystemClock.uptimeMillis());
4648 mWindowManager.enableScreenAfterBoot();
4649
4650 synchronized (mGlobalLock) {
4651 updateEventDispatchingLocked(booted);
4652 }
4653 }
4654
4655 boolean canShowErrorDialogs() {
4656 return mShowDialogs && !mSleeping && !mShuttingDown
4657 && !mKeyguardController.isKeyguardOrAodShowing(DEFAULT_DISPLAY)
4658 && !hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
Wale Ogunwale86b74462018-07-02 08:42:43 -07004659 mAmInternal.getCurrentUserId())
Wale Ogunwalef6733932018-06-27 05:14:34 -07004660 && !(UserManager.isDeviceInDemoMode(mContext)
Wale Ogunwale86b74462018-07-02 08:42:43 -07004661 && mAmInternal.getCurrentUser().isDemo());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004662 }
4663
Wale Ogunwale906f9c62018-07-23 11:23:44 -07004664 static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
4665 if (r == null || !r.hasProcess()) {
4666 return KEY_DISPATCHING_TIMEOUT_MS;
4667 }
4668 return getInputDispatchingTimeoutLocked(r.app);
4669 }
4670
4671 private static long getInputDispatchingTimeoutLocked(WindowProcessController r) {
4672 if (r != null && (r.isInstrumenting() || r.isUsingWrapper())) {
4673 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS;
4674 }
4675 return KEY_DISPATCHING_TIMEOUT_MS;
4676 }
4677
4678 long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
4679 if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
4680 throw new SecurityException("Requires permission " + FILTER_EVENTS);
4681 }
4682 WindowProcessController proc;
4683 long timeout;
4684 synchronized (mGlobalLock) {
4685 proc = mPidMap.get(pid);
4686 timeout = getInputDispatchingTimeoutLocked(proc);
4687 }
4688
4689 if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
4690 return -1;
4691 }
4692
4693 return timeout;
4694 }
4695
4696 /**
4697 * Handle input dispatching timeouts.
4698 * Returns whether input dispatching should be aborted or not.
4699 */
4700 boolean inputDispatchingTimedOut(final WindowProcessController proc,
4701 final ActivityRecord activity, final ActivityRecord parent,
4702 final boolean aboveSystem, String reason) {
4703 if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
4704 throw new SecurityException("Requires permission " + FILTER_EVENTS);
4705 }
4706
4707 final String annotation;
4708 if (reason == null) {
4709 annotation = "Input dispatching timed out";
4710 } else {
4711 annotation = "Input dispatching timed out (" + reason + ")";
4712 }
4713
4714 if (proc != null) {
4715 synchronized (mGlobalLock) {
4716 if (proc.isDebugging()) {
4717 return false;
4718 }
4719
4720 if (proc.isInstrumenting()) {
4721 Bundle info = new Bundle();
4722 info.putString("shortMsg", "keyDispatchingTimedOut");
4723 info.putString("longMsg", annotation);
4724 mAm.finishInstrumentationLocked(
4725 (ProcessRecord) proc.mOwner, Activity.RESULT_CANCELED, info);
4726 return true;
4727 }
4728 }
4729 mH.post(() -> {
4730 mAm.mAppErrors.appNotResponding(
4731 (ProcessRecord) proc.mOwner, activity, parent, aboveSystem, annotation);
4732 });
4733 }
4734
4735 return true;
4736 }
4737
Wale Ogunwalef6733932018-06-27 05:14:34 -07004738 /**
4739 * Decide based on the configuration whether we should show the ANR,
4740 * crash, etc dialogs. The idea is that if there is no affordance to
4741 * press the on-screen buttons, or the user experience would be more
4742 * greatly impacted than the crash itself, we shouldn't show the dialog.
4743 *
4744 * A thought: SystemUI might also want to get told about this, the Power
4745 * dialog / global actions also might want different behaviors.
4746 */
4747 private void updateShouldShowDialogsLocked(Configuration config) {
4748 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
4749 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
4750 && config.navigation == Configuration.NAVIGATION_NONAV);
4751 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
4752 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
4753 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
4754 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
4755 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
4756 final boolean hideDialogsSet = Settings.Global.getInt(mContext.getContentResolver(),
4757 HIDE_ERROR_DIALOGS, 0) != 0;
4758 mShowDialogs = inputMethodExists && uiModeSupportsDialogs && !hideDialogsSet;
4759 }
4760
4761 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
4762 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
4763 FONT_SCALE, 1.0f, userId);
4764
4765 synchronized (this) {
4766 if (getGlobalConfiguration().fontScale == scaleFactor) {
4767 return;
4768 }
4769
4770 final Configuration configuration
4771 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
4772 configuration.fontScale = scaleFactor;
4773 updatePersistentConfiguration(configuration, userId);
4774 }
4775 }
4776
4777 // Actually is sleeping or shutting down or whatever else in the future
4778 // is an inactive state.
4779 boolean isSleepingOrShuttingDownLocked() {
4780 return isSleepingLocked() || mShuttingDown;
4781 }
4782
4783 boolean isSleepingLocked() {
4784 return mSleeping;
4785 }
4786
Riddle Hsu16567132018-08-16 21:37:47 +08004787 /** Update AMS states when an activity is resumed. */
Wale Ogunwalef6733932018-06-27 05:14:34 -07004788 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
4789 final TaskRecord task = r.getTask();
4790 if (task.isActivityTypeStandard()) {
4791 if (mCurAppTimeTracker != r.appTimeTracker) {
4792 // We are switching app tracking. Complete the current one.
4793 if (mCurAppTimeTracker != null) {
4794 mCurAppTimeTracker.stop();
4795 mH.obtainMessage(
4796 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
4797 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
4798 mCurAppTimeTracker = null;
4799 }
4800 if (r.appTimeTracker != null) {
4801 mCurAppTimeTracker = r.appTimeTracker;
4802 startTimeTrackingFocusedActivityLocked();
4803 }
4804 } else {
4805 startTimeTrackingFocusedActivityLocked();
4806 }
4807 } else {
4808 r.appTimeTracker = null;
4809 }
4810 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
4811 // TODO: Probably not, because we don't want to resume voice on switching
4812 // back to this activity
4813 if (task.voiceInteractor != null) {
4814 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
4815 } else {
4816 finishRunningVoiceLocked();
4817
4818 if (mLastResumedActivity != null) {
4819 final IVoiceInteractionSession session;
4820
4821 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
4822 if (lastResumedActivityTask != null
4823 && lastResumedActivityTask.voiceSession != null) {
4824 session = lastResumedActivityTask.voiceSession;
4825 } else {
4826 session = mLastResumedActivity.voiceSession;
4827 }
4828
4829 if (session != null) {
4830 // We had been in a voice interaction session, but now focused has
4831 // move to something different. Just finish the session, we can't
4832 // return to it and retain the proper state and synchronization with
4833 // the voice interaction service.
4834 finishVoiceTask(session);
4835 }
4836 }
4837 }
4838
4839 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
4840 mAmInternal.sendForegroundProfileChanged(r.userId);
4841 }
4842 updateResumedAppTrace(r);
4843 mLastResumedActivity = r;
4844
Riddle Hsu3026e8d2018-08-03 15:50:53 +08004845 // TODO(b/111361570): Support multiple focused apps in WM
Wale Ogunwalef6733932018-06-27 05:14:34 -07004846 mWindowManager.setFocusedApp(r.appToken, true);
4847
4848 applyUpdateLockStateLocked(r);
4849 applyUpdateVrModeLocked(r);
4850
4851 EventLogTags.writeAmSetResumedActivity(
4852 r == null ? -1 : r.userId,
4853 r == null ? "NULL" : r.shortComponentName,
4854 reason);
4855 }
4856
4857 ActivityTaskManagerInternal.SleepToken acquireSleepToken(String tag, int displayId) {
4858 synchronized (mGlobalLock) {
4859 final ActivityTaskManagerInternal.SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
4860 updateSleepIfNeededLocked();
4861 return token;
4862 }
4863 }
4864
4865 void updateSleepIfNeededLocked() {
4866 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
4867 final boolean wasSleeping = mSleeping;
4868 boolean updateOomAdj = false;
4869
4870 if (!shouldSleep) {
4871 // If wasSleeping is true, we need to wake up activity manager state from when
4872 // we started sleeping. In either case, we need to apply the sleep tokens, which
4873 // will wake up stacks or put them to sleep as appropriate.
4874 if (wasSleeping) {
4875 mSleeping = false;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07004876 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
4877 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__AWAKE);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004878 startTimeTrackingFocusedActivityLocked();
4879 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
4880 mStackSupervisor.comeOutOfSleepIfNeededLocked();
4881 }
4882 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
4883 if (wasSleeping) {
4884 updateOomAdj = true;
4885 }
4886 } else if (!mSleeping && shouldSleep) {
4887 mSleeping = true;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07004888 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
4889 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__ASLEEP);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004890 if (mCurAppTimeTracker != null) {
4891 mCurAppTimeTracker.stop();
4892 }
4893 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
4894 mStackSupervisor.goingToSleepLocked();
4895 updateResumedAppTrace(null /* resumed */);
4896 updateOomAdj = true;
4897 }
4898 if (updateOomAdj) {
4899 mH.post(mAmInternal::updateOomAdj);
4900 }
4901 }
4902
4903 void updateOomAdj() {
4904 mH.post(mAmInternal::updateOomAdj);
4905 }
4906
Wale Ogunwale53783742018-09-16 10:21:51 -07004907 void updateCpuStats() {
4908 mH.post(mAmInternal::updateCpuStats);
4909 }
4910
4911 void updateUsageStats(ActivityRecord component, boolean resumed) {
4912 final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::updateUsageStats,
4913 mAmInternal, component.realActivity, component.app.mUid, component.userId, resumed);
4914 mH.sendMessage(m);
4915 }
4916
4917 void setBooting(boolean booting) {
4918 mAmInternal.setBooting(booting);
4919 }
4920
4921 boolean isBooting() {
4922 return mAmInternal.isBooting();
4923 }
4924
4925 void setBooted(boolean booted) {
4926 mAmInternal.setBooted(booted);
4927 }
4928
4929 boolean isBooted() {
4930 return mAmInternal.isBooted();
4931 }
4932
4933 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
4934 mH.post(() -> {
4935 if (finishBooting) {
4936 mAmInternal.finishBooting();
4937 }
4938 if (enableScreen) {
4939 mInternal.enableScreenAfterBoot(isBooted());
4940 }
4941 });
4942 }
4943
4944 void setHeavyWeightProcess(ActivityRecord root) {
4945 mHeavyWeightProcess = root.app;
4946 final Message m = PooledLambda.obtainMessage(
4947 ActivityTaskManagerService::postHeavyWeightProcessNotification, this,
4948 root.app, root.intent, root.userId);
4949 mH.sendMessage(m);
4950 }
4951
4952 void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
4953 if (mHeavyWeightProcess == null || mHeavyWeightProcess != proc) {
4954 return;
4955 }
4956
4957 mHeavyWeightProcess = null;
4958 final Message m = PooledLambda.obtainMessage(
4959 ActivityTaskManagerService::cancelHeavyWeightProcessNotification, this,
4960 proc.mUserId);
4961 mH.sendMessage(m);
4962 }
4963
4964 private void cancelHeavyWeightProcessNotification(int userId) {
4965 final INotificationManager inm = NotificationManager.getService();
4966 if (inm == null) {
4967 return;
4968 }
4969 try {
4970 inm.cancelNotificationWithTag("android", null,
4971 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, userId);
4972 } catch (RuntimeException e) {
4973 Slog.w(TAG, "Error canceling notification for service", e);
4974 } catch (RemoteException e) {
4975 }
4976
4977 }
4978
4979 private void postHeavyWeightProcessNotification(
4980 WindowProcessController proc, Intent intent, int userId) {
4981 if (proc == null) {
4982 return;
4983 }
4984
4985 final INotificationManager inm = NotificationManager.getService();
4986 if (inm == null) {
4987 return;
4988 }
4989
4990 try {
4991 Context context = mContext.createPackageContext(proc.mInfo.packageName, 0);
4992 String text = mContext.getString(R.string.heavy_weight_notification,
4993 context.getApplicationInfo().loadLabel(context.getPackageManager()));
4994 Notification notification =
4995 new Notification.Builder(context,
4996 SystemNotificationChannels.HEAVY_WEIGHT_APP)
4997 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
4998 .setWhen(0)
4999 .setOngoing(true)
5000 .setTicker(text)
5001 .setColor(mContext.getColor(
5002 com.android.internal.R.color.system_notification_accent_color))
5003 .setContentTitle(text)
5004 .setContentText(
5005 mContext.getText(R.string.heavy_weight_notification_detail))
5006 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
5007 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
5008 new UserHandle(userId)))
5009 .build();
5010 try {
5011 inm.enqueueNotificationWithTag("android", "android", null,
5012 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, notification, userId);
5013 } catch (RuntimeException e) {
5014 Slog.w(TAG, "Error showing notification for heavy-weight app", e);
5015 } catch (RemoteException e) {
5016 }
5017 } catch (PackageManager.NameNotFoundException e) {
5018 Slog.w(TAG, "Unable to create context for heavy notification", e);
5019 }
5020
5021 }
5022
Andrii Kulian52d255c2018-07-13 11:32:19 -07005023 // TODO(b/111541062): Update app time tracking to make it aware of multiple resumed activities
Wale Ogunwalef6733932018-06-27 05:14:34 -07005024 private void startTimeTrackingFocusedActivityLocked() {
Andrii Kulian52d255c2018-07-13 11:32:19 -07005025 final ActivityRecord resumedActivity = mStackSupervisor.getTopResumedActivity();
Wale Ogunwalef6733932018-06-27 05:14:34 -07005026 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
5027 mCurAppTimeTracker.start(resumedActivity.packageName);
5028 }
5029 }
5030
5031 private void updateResumedAppTrace(@Nullable ActivityRecord resumed) {
5032 if (mTracedResumedActivity != null) {
5033 Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER,
5034 constructResumedTraceName(mTracedResumedActivity.packageName), 0);
5035 }
5036 if (resumed != null) {
5037 Trace.asyncTraceBegin(TRACE_TAG_ACTIVITY_MANAGER,
5038 constructResumedTraceName(resumed.packageName), 0);
5039 }
5040 mTracedResumedActivity = resumed;
5041 }
5042
5043 private String constructResumedTraceName(String packageName) {
5044 return "focused app: " + packageName;
5045 }
5046
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005047 /** Helper method that requests bounds from WM and applies them to stack. */
5048 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
5049 final Rect newStackBounds = new Rect();
5050 final ActivityStack stack = mStackSupervisor.getStack(stackId);
5051
5052 // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
5053 if (stack == null) {
5054 final StringWriter writer = new StringWriter();
5055 final PrintWriter printWriter = new PrintWriter(writer);
5056 mStackSupervisor.dumpDisplays(printWriter);
5057 printWriter.flush();
5058
5059 Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
5060 }
5061
5062 stack.getBoundsForNewConfiguration(newStackBounds);
5063 mStackSupervisor.resizeStackLocked(
5064 stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
5065 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
5066 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
5067 }
5068
5069 /** Applies latest configuration and/or visibility updates if needed. */
5070 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
5071 boolean kept = true;
Andrii Kulian5f750bc2018-07-17 08:57:23 -07005072 final ActivityStack mainStack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005073 // mainStack is null during startup.
5074 if (mainStack != null) {
5075 if (changes != 0 && starting == null) {
5076 // If the configuration changed, and the caller is not already
5077 // in the process of starting an activity, then find the top
5078 // activity to check if its configuration needs to change.
5079 starting = mainStack.topRunningActivityLocked();
5080 }
5081
5082 if (starting != null) {
5083 kept = starting.ensureActivityConfiguration(changes,
5084 false /* preserveWindow */);
5085 // And we need to make sure at this point that all other activities
5086 // are made visible with the correct configuration.
5087 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
5088 !PRESERVE_WINDOWS);
5089 }
5090 }
5091
5092 return kept;
5093 }
5094
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005095 void scheduleAppGcsLocked() {
5096 mH.post(() -> mAmInternal.scheduleAppGcs());
5097 }
5098
Wale Ogunwale53783742018-09-16 10:21:51 -07005099 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
5100 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
5101 }
5102
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005103 /**
5104 * Returns the PackageManager. Used by classes hosted by {@link ActivityTaskManagerService}. The
5105 * PackageManager could be unavailable at construction time and therefore needs to be accessed
5106 * on demand.
5107 */
5108 IPackageManager getPackageManager() {
5109 return AppGlobals.getPackageManager();
5110 }
5111
5112 PackageManagerInternal getPackageManagerInternalLocked() {
5113 if (mPmInternal == null) {
5114 mPmInternal = LocalServices.getService(PackageManagerInternal.class);
5115 }
5116 return mPmInternal;
5117 }
5118
Wale Ogunwale008163e2018-07-23 23:11:08 -07005119 AppWarnings getAppWarningsLocked() {
5120 return mAppWarnings;
5121 }
5122
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005123 void logAppTooSlow(WindowProcessController app, long startTime, String msg) {
5124 if (true || Build.IS_USER) {
5125 return;
5126 }
5127
5128 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5129 StrictMode.allowThreadDiskWrites();
5130 try {
5131 File tracesDir = new File("/data/anr");
5132 File tracesFile = null;
5133 try {
5134 tracesFile = File.createTempFile("app_slow", null, tracesDir);
5135
5136 StringBuilder sb = new StringBuilder();
5137 Time tobj = new Time();
5138 tobj.set(System.currentTimeMillis());
5139 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5140 sb.append(": ");
5141 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5142 sb.append(" since ");
5143 sb.append(msg);
5144 FileOutputStream fos = new FileOutputStream(tracesFile);
5145 fos.write(sb.toString().getBytes());
5146 if (app == null) {
5147 fos.write("\n*** No application process!".getBytes());
5148 }
5149 fos.close();
5150 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5151 } catch (IOException e) {
5152 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesFile, e);
5153 return;
5154 }
5155
5156 if (app != null && app.getPid() > 0) {
5157 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5158 firstPids.add(app.getPid());
5159 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, null, null);
5160 }
5161
5162 File lastTracesFile = null;
5163 File curTracesFile = null;
5164 for (int i=9; i>=0; i--) {
5165 String name = String.format(Locale.US, "slow%02d.txt", i);
5166 curTracesFile = new File(tracesDir, name);
5167 if (curTracesFile.exists()) {
5168 if (lastTracesFile != null) {
5169 curTracesFile.renameTo(lastTracesFile);
5170 } else {
5171 curTracesFile.delete();
5172 }
5173 }
5174 lastTracesFile = curTracesFile;
5175 }
5176 tracesFile.renameTo(curTracesFile);
5177 } finally {
5178 StrictMode.setThreadPolicy(oldPolicy);
5179 }
5180 }
5181
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005182 final class H extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005183 static final int REPORT_TIME_TRACKER_MSG = 1;
5184
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005185 public H(Looper looper) {
5186 super(looper, null, true);
5187 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005188
5189 @Override
5190 public void handleMessage(Message msg) {
5191 switch (msg.what) {
5192 case REPORT_TIME_TRACKER_MSG: {
5193 AppTimeTracker tracker = (AppTimeTracker) msg.obj;
5194 tracker.deliverResult(mContext);
5195 } break;
5196 }
5197 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005198 }
5199
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005200 final class UiHandler extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005201 static final int DISMISS_DIALOG_UI_MSG = 1;
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005202
5203 public UiHandler() {
5204 super(com.android.server.UiThread.get().getLooper(), null, true);
5205 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005206
5207 @Override
5208 public void handleMessage(Message msg) {
5209 switch (msg.what) {
5210 case DISMISS_DIALOG_UI_MSG: {
5211 final Dialog d = (Dialog) msg.obj;
5212 d.dismiss();
5213 break;
5214 }
5215 }
5216 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005217 }
5218
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005219 final class LocalService extends ActivityTaskManagerInternal {
5220 @Override
5221 public SleepToken acquireSleepToken(String tag, int displayId) {
5222 Preconditions.checkNotNull(tag);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005223 return ActivityTaskManagerService.this.acquireSleepToken(tag, displayId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005224 }
5225
5226 @Override
5227 public ComponentName getHomeActivityForUser(int userId) {
5228 synchronized (mGlobalLock) {
5229 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
5230 return homeActivity == null ? null : homeActivity.realActivity;
5231 }
5232 }
5233
5234 @Override
5235 public void onLocalVoiceInteractionStarted(IBinder activity,
5236 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
5237 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005238 onLocalVoiceInteractionStartedLocked(activity, voiceSession, voiceInteractor);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005239 }
5240 }
5241
5242 @Override
5243 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
5244 synchronized (mGlobalLock) {
5245 mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
5246 reasons, timestamp);
5247 }
5248 }
5249
5250 @Override
5251 public void notifyAppTransitionFinished() {
5252 synchronized (mGlobalLock) {
5253 mStackSupervisor.notifyAppTransitionDone();
5254 }
5255 }
5256
5257 @Override
5258 public void notifyAppTransitionCancelled() {
5259 synchronized (mGlobalLock) {
5260 mStackSupervisor.notifyAppTransitionDone();
5261 }
5262 }
5263
5264 @Override
5265 public List<IBinder> getTopVisibleActivities() {
5266 synchronized (mGlobalLock) {
5267 return mStackSupervisor.getTopVisibleActivities();
5268 }
5269 }
5270
5271 @Override
5272 public void notifyDockedStackMinimizedChanged(boolean minimized) {
5273 synchronized (mGlobalLock) {
5274 mStackSupervisor.setDockedStackMinimized(minimized);
5275 }
5276 }
5277
5278 @Override
5279 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
5280 Bundle bOptions) {
5281 Preconditions.checkNotNull(intents, "intents");
5282 final String[] resolvedTypes = new String[intents.length];
5283
5284 // UID of the package on user userId.
5285 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
5286 // packageUid may not be initialized.
5287 int packageUid = 0;
5288 final long ident = Binder.clearCallingIdentity();
5289
5290 try {
5291 for (int i = 0; i < intents.length; i++) {
5292 resolvedTypes[i] =
5293 intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
5294 }
5295
5296 packageUid = AppGlobals.getPackageManager().getPackageUid(
5297 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
5298 } catch (RemoteException e) {
5299 // Shouldn't happen.
5300 } finally {
5301 Binder.restoreCallingIdentity(ident);
5302 }
5303
5304 synchronized (mGlobalLock) {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07005305 return getActivityStartController().startActivitiesInPackage(
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005306 packageUid, packageName,
5307 intents, resolvedTypes, null /* resultTo */,
5308 SafeActivityOptions.fromBundle(bOptions), userId,
Michal Karpinski201bc0c2018-07-20 15:32:00 +01005309 false /* validateIncomingUser */, null /* originatingPendingIntent */);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005310 }
5311 }
5312
5313 @Override
5314 public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
5315 Intent intent, Bundle options, int userId) {
5316 return ActivityTaskManagerService.this.startActivityAsUser(
5317 caller, callerPacakge, intent,
5318 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
5319 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
5320 false /*validateIncomingUser*/);
5321 }
5322
5323 @Override
5324 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
5325 synchronized (mGlobalLock) {
5326
5327 // We might change the visibilities here, so prepare an empty app transition which
5328 // might be overridden later if we actually change visibilities.
5329 final boolean wasTransitionSet =
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005330 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005331 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005332 mWindowManager.prepareAppTransition(TRANSIT_NONE,
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005333 false /* alwaysKeepCurrent */);
5334 }
5335 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5336
5337 // If there was a transition set already we don't want to interfere with it as we
5338 // might be starting it too early.
5339 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005340 mWindowManager.executeAppTransition();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005341 }
5342 }
5343 if (callback != null) {
5344 callback.run();
5345 }
5346 }
5347
5348 @Override
5349 public void notifyKeyguardTrustedChanged() {
5350 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005351 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005352 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5353 }
5354 }
5355 }
5356
5357 /**
5358 * Called after virtual display Id is updated by
5359 * {@link com.android.server.vr.Vr2dDisplay} with a specific
5360 * {@param vrVr2dDisplayId}.
5361 */
5362 @Override
5363 public void setVr2dDisplayId(int vr2dDisplayId) {
5364 if (DEBUG_STACK) Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
5365 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005366 mVr2dDisplayId = vr2dDisplayId;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005367 }
5368 }
5369
5370 @Override
5371 public void setFocusedActivity(IBinder token) {
5372 synchronized (mGlobalLock) {
5373 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
5374 if (r == null) {
5375 throw new IllegalArgumentException(
5376 "setFocusedActivity: No activity record matching token=" + token);
5377 }
5378 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
5379 r, "setFocusedActivity")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08005380 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005381 }
5382 }
5383 }
5384
5385 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005386 public void registerScreenObserver(ScreenObserver observer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005387 mScreenObservers.add(observer);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005388 }
5389
5390 @Override
5391 public boolean isCallerRecents(int callingUid) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005392 return getRecentTasks().isCallerRecents(callingUid);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005393 }
5394
5395 @Override
5396 public boolean isRecentsComponentHomeActivity(int userId) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005397 return getRecentTasks().isRecentsComponentHomeActivity(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005398 }
5399
5400 @Override
5401 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
5402 ActivityTaskManagerService.this.cancelRecentsAnimation(restoreHomeStackPosition);
5403 }
5404
5405 @Override
5406 public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005407 ActivityTaskManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005408 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005409
5410 @Override
5411 public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
5412 synchronized (mGlobalLock) {
5413 mActiveVoiceInteractionServiceComponent = component;
5414 }
5415 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005416
5417 @Override
5418 public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
5419 if (!mAmInternal.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
5420 return;
5421 }
5422 synchronized (mGlobalLock) {
5423 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
5424 if (types == null) {
5425 if (uid < 0) {
5426 return;
5427 }
5428 types = new ArrayMap<>();
5429 mAllowAppSwitchUids.put(userId, types);
5430 }
5431 if (uid < 0) {
5432 types.remove(type);
5433 } else {
5434 types.put(type, uid);
5435 }
5436 }
5437 }
5438
5439 @Override
5440 public void onUserStopped(int userId) {
5441 synchronized (mGlobalLock) {
5442 getRecentTasks().unloadUserDataFromMemoryLocked(userId);
5443 mAllowAppSwitchUids.remove(userId);
5444 }
5445 }
5446
5447 @Override
5448 public boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
5449 synchronized (mGlobalLock) {
5450 return ActivityTaskManagerService.this.isGetTasksAllowed(
5451 caller, callingPid, callingUid);
5452 }
5453 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005454
5455 @Override
5456 public void onProcessAdded(WindowProcessController proc) {
5457 synchronized (mGlobalLock) {
5458 mProcessNames.put(proc.mName, proc.mUid, proc);
5459 }
5460 }
5461
5462 @Override
5463 public void onProcessRemoved(String name, int uid) {
5464 synchronized (mGlobalLock) {
5465 mProcessNames.remove(name, uid);
5466 }
5467 }
5468
5469 @Override
5470 public void onCleanUpApplicationRecord(WindowProcessController proc) {
5471 synchronized (mGlobalLock) {
5472 if (proc == mHomeProcess) {
5473 mHomeProcess = null;
5474 }
5475 if (proc == mPreviousProcess) {
5476 mPreviousProcess = null;
5477 }
5478 }
5479 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005480
5481 @Override
5482 public int getTopProcessState() {
5483 synchronized (mGlobalLock) {
5484 return mTopProcessState;
5485 }
5486 }
5487
5488 @Override
Wale Ogunwale53783742018-09-16 10:21:51 -07005489 public boolean isHeavyWeightProcess(WindowProcessController proc) {
5490 synchronized (mGlobalLock) {
5491 return proc == mHeavyWeightProcess;
5492 }
5493 }
5494
5495 @Override
5496 public void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
5497 synchronized (mGlobalLock) {
5498 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(proc);
5499 }
5500 }
5501
5502 @Override
5503 public void finishHeavyWeightApp() {
5504 synchronized (mGlobalLock) {
5505 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(
5506 mHeavyWeightProcess);
5507 }
5508 }
5509
5510 @Override
Wale Ogunwalef6733932018-06-27 05:14:34 -07005511 public boolean isSleeping() {
5512 synchronized (mGlobalLock) {
5513 return isSleepingLocked();
5514 }
5515 }
5516
5517 @Override
5518 public boolean isShuttingDown() {
5519 synchronized (mGlobalLock) {
5520 return mShuttingDown;
5521 }
5522 }
5523
5524 @Override
5525 public boolean shuttingDown(boolean booted, int timeout) {
5526 synchronized (mGlobalLock) {
5527 mShuttingDown = true;
5528 mStackSupervisor.prepareForShutdownLocked();
5529 updateEventDispatchingLocked(booted);
5530 return mStackSupervisor.shutdownLocked(timeout);
5531 }
5532 }
5533
5534 @Override
5535 public void enableScreenAfterBoot(boolean booted) {
5536 synchronized (mGlobalLock) {
5537 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5538 SystemClock.uptimeMillis());
5539 mWindowManager.enableScreenAfterBoot();
5540 updateEventDispatchingLocked(booted);
5541 }
5542 }
5543
5544 @Override
5545 public boolean showStrictModeViolationDialog() {
5546 synchronized (mGlobalLock) {
5547 return mShowDialogs && !mSleeping && !mShuttingDown;
5548 }
5549 }
5550
5551 @Override
5552 public void showSystemReadyErrorDialogsIfNeeded() {
5553 synchronized (mGlobalLock) {
5554 try {
5555 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
5556 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
5557 + " data partition or your device will be unstable.");
5558 mUiHandler.post(() -> {
5559 if (mShowDialogs) {
5560 AlertDialog d = new BaseErrorDialog(mUiContext);
5561 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5562 d.setCancelable(false);
5563 d.setTitle(mUiContext.getText(R.string.android_system_label));
5564 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
5565 d.setButton(DialogInterface.BUTTON_POSITIVE,
5566 mUiContext.getText(R.string.ok),
5567 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5568 d.show();
5569 }
5570 });
5571 }
5572 } catch (RemoteException e) {
5573 }
5574
5575 if (!Build.isBuildConsistent()) {
5576 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
5577 mUiHandler.post(() -> {
5578 if (mShowDialogs) {
5579 AlertDialog d = new BaseErrorDialog(mUiContext);
5580 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5581 d.setCancelable(false);
5582 d.setTitle(mUiContext.getText(R.string.android_system_label));
5583 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
5584 d.setButton(DialogInterface.BUTTON_POSITIVE,
5585 mUiContext.getText(R.string.ok),
5586 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5587 d.show();
5588 }
5589 });
5590 }
5591 }
5592 }
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005593
5594 @Override
5595 public long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason) {
5596 synchronized (mGlobalLock) {
5597 return ActivityTaskManagerService.this.inputDispatchingTimedOut(
5598 pid, aboveSystem, reason);
5599 }
5600 }
5601
5602 @Override
5603 public void onProcessMapped(int pid, WindowProcessController proc) {
5604 synchronized (mGlobalLock) {
5605 mPidMap.put(pid, proc);
5606 }
5607 }
5608
5609 @Override
5610 public void onProcessUnMapped(int pid) {
5611 synchronized (mGlobalLock) {
5612 mPidMap.remove(pid);
5613 }
5614 }
Wale Ogunwale008163e2018-07-23 23:11:08 -07005615
5616 @Override
5617 public void onPackageDataCleared(String name) {
5618 synchronized (mGlobalLock) {
Wale Ogunwale53783742018-09-16 10:21:51 -07005619 mCompatModePackages.handlePackageDataClearedLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07005620 mAppWarnings.onPackageDataCleared(name);
5621 }
5622 }
5623
5624 @Override
5625 public void onPackageUninstalled(String name) {
5626 synchronized (mGlobalLock) {
5627 mAppWarnings.onPackageUninstalled(name);
Wale Ogunwale53783742018-09-16 10:21:51 -07005628 mCompatModePackages.handlePackageUninstalledLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07005629 }
5630 }
Wale Ogunwale53783742018-09-16 10:21:51 -07005631
5632 @Override
5633 public void onPackageAdded(String name, boolean replacing) {
5634 synchronized (mGlobalLock) {
5635 mCompatModePackages.handlePackageAddedLocked(name, replacing);
5636 }
5637 }
5638
5639 @Override
5640 public CompatibilityInfo compatibilityInfoForPackage(ApplicationInfo ai) {
5641 synchronized (mGlobalLock) {
5642 return compatibilityInfoForPackageLocked(ai);
5643 }
5644 }
5645
Yunfan Chen75157d72018-07-27 14:47:21 +09005646 /**
5647 * Set the corresponding display information for the process global configuration. To be
5648 * called when we need to show IME on a different display.
5649 *
5650 * @param pid The process id associated with the IME window.
5651 * @param displayId The ID of the display showing the IME.
5652 */
5653 @Override
5654 public void onImeWindowSetOnDisplay(int pid, int displayId) {
5655 if (pid == MY_PID || pid < 0) {
5656 if (DEBUG_CONFIGURATION) {
5657 Slog.w(TAG,
5658 "Trying to update display configuration for system/invalid process.");
5659 }
5660 return;
5661 }
5662 mH.post(() -> {
5663 synchronized (mGlobalLock) {
5664 // Check if display is initialized in AM.
5665 if (!mStackSupervisor.isDisplayAdded(displayId)) {
5666 // Call come when display is not yet added or has already been removed.
5667 if (DEBUG_CONFIGURATION) {
5668 Slog.w(TAG, "Trying to update display configuration for non-existing "
5669 + "displayId=" + displayId);
5670 }
5671 return;
5672 }
5673 final WindowProcessController imeProcess = mPidMap.get(pid);
5674 if (imeProcess == null) {
5675 if (DEBUG_CONFIGURATION) {
5676 Slog.w(TAG, "Trying to update display configuration for invalid pid: "
5677 + pid);
5678 }
5679 return;
5680 }
5681 // Fetch the current override configuration of the display and set it to the
5682 // process global configuration.
5683 imeProcess.onConfigurationChanged(
5684 mStackSupervisor.getDisplayOverrideConfiguration(displayId));
5685 }
5686 });
5687 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005688 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07005689}