blob: 4dc28510c5ec7eba26d30fe8203ec12043fb75bc [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);
1959 return;
1960 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001961 if (getLockTaskController().isLockTaskModeViolation(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001962 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
1963 return;
1964 }
1965 ActivityOptions realOptions = options != null
1966 ? options.getOptions(mStackSupervisor)
1967 : null;
1968 mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
1969 false /* forceNonResizable */);
1970
1971 final ActivityRecord topActivity = task.getTopActivity();
1972 if (topActivity != null) {
1973
1974 // We are reshowing a task, use a starting window to hide the initial draw delay
1975 // so the transition can start earlier.
1976 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
1977 true /* taskSwitch */, fromRecents);
1978 }
1979 } finally {
1980 Binder.restoreCallingIdentity(origId);
1981 }
1982 SafeActivityOptions.abort(options);
1983 }
1984
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001985 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
1986 int callingPid, int callingUid, String name) {
1987 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
1988 return true;
1989 }
1990
1991 if (getRecentTasks().isCallerRecents(sourceUid)) {
1992 return true;
1993 }
1994
1995 int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
1996 if (perm == PackageManager.PERMISSION_GRANTED) {
1997 return true;
1998 }
1999 if (checkAllowAppSwitchUid(sourceUid)) {
2000 return true;
2001 }
2002
2003 // If the actual IPC caller is different from the logical source, then
2004 // also see if they are allowed to control app switches.
2005 if (callingUid != -1 && callingUid != sourceUid) {
2006 perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
2007 if (perm == PackageManager.PERMISSION_GRANTED) {
2008 return true;
2009 }
2010 if (checkAllowAppSwitchUid(callingUid)) {
2011 return true;
2012 }
2013 }
2014
2015 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
2016 return false;
2017 }
2018
2019 private boolean checkAllowAppSwitchUid(int uid) {
2020 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
2021 if (types != null) {
2022 for (int i = types.size() - 1; i >= 0; i--) {
2023 if (types.valueAt(i).intValue() == uid) {
2024 return true;
2025 }
2026 }
2027 }
2028 return false;
2029 }
2030
2031 @Override
2032 public void setActivityController(IActivityController controller, boolean imAMonkey) {
2033 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
2034 "setActivityController()");
2035 synchronized (mGlobalLock) {
2036 mController = controller;
2037 mControllerIsAMonkey = imAMonkey;
2038 Watchdog.getInstance().setActivityController(controller);
2039 }
2040 }
2041
2042 boolean isControllerAMonkey() {
2043 synchronized (mGlobalLock) {
2044 return mController != null && mControllerIsAMonkey;
2045 }
2046 }
2047
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002048 @Override
2049 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
2050 synchronized (mGlobalLock) {
2051 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
2052 }
2053 }
2054
2055 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002056 public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum) {
2057 return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
2058 }
2059
2060 @Override
2061 public List<ActivityManager.RunningTaskInfo> getFilteredTasks(int maxNum,
2062 @WindowConfiguration.ActivityType int ignoreActivityType,
2063 @WindowConfiguration.WindowingMode int ignoreWindowingMode) {
2064 final int callingUid = Binder.getCallingUid();
2065 ArrayList<ActivityManager.RunningTaskInfo> list = new ArrayList<>();
2066
2067 synchronized (mGlobalLock) {
2068 if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
2069
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002070 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002071 callingUid);
2072 mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
2073 ignoreWindowingMode, callingUid, allowed);
2074 }
2075
2076 return list;
2077 }
2078
2079 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002080 public final void finishSubActivity(IBinder token, String resultWho, int requestCode) {
2081 synchronized (mGlobalLock) {
2082 final long origId = Binder.clearCallingIdentity();
2083 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2084 if (r != null) {
2085 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
2086 }
2087 Binder.restoreCallingIdentity(origId);
2088 }
2089 }
2090
2091 @Override
2092 public boolean willActivityBeVisible(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002093 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002094 ActivityStack stack = ActivityRecord.getStackLocked(token);
2095 if (stack != null) {
2096 return stack.willActivityBeVisibleLocked(token);
2097 }
2098 return false;
2099 }
2100 }
2101
2102 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002103 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002104 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002105 synchronized (mGlobalLock) {
2106 final long ident = Binder.clearCallingIdentity();
2107 try {
2108 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2109 if (task == null) {
2110 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
2111 return;
2112 }
2113
2114 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
2115 + " to stackId=" + stackId + " toTop=" + toTop);
2116
2117 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2118 if (stack == null) {
2119 throw new IllegalStateException(
2120 "moveTaskToStack: No stack for stackId=" + stackId);
2121 }
2122 if (!stack.isActivityTypeStandardOrUndefined()) {
2123 throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
2124 + taskId + " to stack " + stackId);
2125 }
2126 if (stack.inSplitScreenPrimaryWindowingMode()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002127 mWindowManager.setDockedStackCreateState(
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002128 SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
2129 }
2130 task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
2131 "moveTaskToStack");
2132 } finally {
2133 Binder.restoreCallingIdentity(ident);
2134 }
2135 }
2136 }
2137
2138 @Override
2139 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
2140 boolean preserveWindows, boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002141 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002142
2143 final long ident = Binder.clearCallingIdentity();
2144 try {
2145 synchronized (mGlobalLock) {
2146 if (animate) {
2147 final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
2148 if (stack == null) {
2149 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2150 return;
2151 }
2152 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
2153 throw new IllegalArgumentException("Stack: " + stackId
2154 + " doesn't support animated resize.");
2155 }
2156 stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
2157 animationDuration, false /* fromFullscreen */);
2158 } else {
2159 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2160 if (stack == null) {
2161 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2162 return;
2163 }
2164 mStackSupervisor.resizeStackLocked(stack, destBounds,
2165 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
2166 preserveWindows, allowResizeInDockedMode, !DEFER_RESUME);
2167 }
2168 }
2169 } finally {
2170 Binder.restoreCallingIdentity(ident);
2171 }
2172 }
2173
2174 /**
2175 * Moves the specified task to the primary-split-screen stack.
2176 *
2177 * @param taskId Id of task to move.
2178 * @param createMode The mode the primary split screen stack should be created in if it doesn't
2179 * exist already. See
2180 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
2181 * and
2182 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
2183 * @param toTop If the task and stack should be moved to the top.
2184 * @param animate Whether we should play an animation for the moving the task.
2185 * @param initialBounds If the primary stack gets created, it will use these bounds for the
2186 * stack. Pass {@code null} to use default bounds.
2187 * @param showRecents If the recents activity should be shown on the other side of the task
2188 * going into split-screen mode.
2189 */
2190 @Override
2191 public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode,
2192 boolean toTop, boolean animate, Rect initialBounds, boolean showRecents) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002193 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002194 "setTaskWindowingModeSplitScreenPrimary()");
2195 synchronized (mGlobalLock) {
2196 final long ident = Binder.clearCallingIdentity();
2197 try {
2198 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2199 if (task == null) {
2200 Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
2201 return false;
2202 }
2203 if (DEBUG_STACK) Slog.d(TAG_STACK,
2204 "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
2205 + " to createMode=" + createMode + " toTop=" + toTop);
2206 if (!task.isActivityTypeStandardOrUndefined()) {
2207 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
2208 + " non-standard task " + taskId + " to split-screen windowing mode");
2209 }
2210
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002211 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002212 final int windowingMode = task.getWindowingMode();
2213 final ActivityStack stack = task.getStack();
2214 if (toTop) {
2215 stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
2216 }
2217 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
2218 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */);
2219 return windowingMode != task.getWindowingMode();
2220 } finally {
2221 Binder.restoreCallingIdentity(ident);
2222 }
2223 }
2224 }
2225
2226 /**
2227 * Removes stacks in the input windowing modes from the system if they are of activity type
2228 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
2229 */
2230 @Override
2231 public void removeStacksInWindowingModes(int[] windowingModes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002232 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002233 "removeStacksInWindowingModes()");
2234
2235 synchronized (mGlobalLock) {
2236 final long ident = Binder.clearCallingIdentity();
2237 try {
2238 mStackSupervisor.removeStacksInWindowingModes(windowingModes);
2239 } finally {
2240 Binder.restoreCallingIdentity(ident);
2241 }
2242 }
2243 }
2244
2245 @Override
2246 public void removeStacksWithActivityTypes(int[] activityTypes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002247 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002248 "removeStacksWithActivityTypes()");
2249
2250 synchronized (mGlobalLock) {
2251 final long ident = Binder.clearCallingIdentity();
2252 try {
2253 mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
2254 } finally {
2255 Binder.restoreCallingIdentity(ident);
2256 }
2257 }
2258 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002259
2260 @Override
2261 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
2262 int userId) {
2263 final int callingUid = Binder.getCallingUid();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002264 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, "getRecentTasks");
2265 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002266 callingUid);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002267 final boolean detailed = checkGetTasksPermission(
2268 android.Manifest.permission.GET_DETAILED_TASKS, Binder.getCallingPid(),
2269 UserHandle.getAppId(callingUid))
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002270 == PackageManager.PERMISSION_GRANTED;
2271
2272 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002273 return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002274 callingUid);
2275 }
2276 }
2277
2278 @Override
2279 public List<ActivityManager.StackInfo> getAllStackInfos() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002280 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002281 long ident = Binder.clearCallingIdentity();
2282 try {
2283 synchronized (mGlobalLock) {
2284 return mStackSupervisor.getAllStackInfosLocked();
2285 }
2286 } finally {
2287 Binder.restoreCallingIdentity(ident);
2288 }
2289 }
2290
2291 @Override
2292 public ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002293 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002294 long ident = Binder.clearCallingIdentity();
2295 try {
2296 synchronized (mGlobalLock) {
2297 return mStackSupervisor.getStackInfo(windowingMode, activityType);
2298 }
2299 } finally {
2300 Binder.restoreCallingIdentity(ident);
2301 }
2302 }
2303
2304 @Override
2305 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002306 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002307 final long callingUid = Binder.getCallingUid();
2308 final long origId = Binder.clearCallingIdentity();
2309 try {
2310 synchronized (mGlobalLock) {
2311 // Cancel the recents animation synchronously (do not hold the WM lock)
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002312 mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002313 ? REORDER_MOVE_TO_ORIGINAL_POSITION
2314 : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
2315 }
2316 } finally {
2317 Binder.restoreCallingIdentity(origId);
2318 }
2319 }
2320
2321 @Override
2322 public void startLockTaskModeByToken(IBinder token) {
2323 synchronized (mGlobalLock) {
2324 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2325 if (r == null) {
2326 return;
2327 }
2328 startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
2329 }
2330 }
2331
2332 @Override
2333 public void startSystemLockTaskMode(int taskId) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002334 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002335 // This makes inner call to look as if it was initiated by system.
2336 long ident = Binder.clearCallingIdentity();
2337 try {
2338 synchronized (mGlobalLock) {
2339 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2340
2341 // When starting lock task mode the stack must be in front and focused
2342 task.getStack().moveToFront("startSystemLockTaskMode");
2343 startLockTaskModeLocked(task, true /* isSystemCaller */);
2344 }
2345 } finally {
2346 Binder.restoreCallingIdentity(ident);
2347 }
2348 }
2349
2350 @Override
2351 public void stopLockTaskModeByToken(IBinder token) {
2352 synchronized (mGlobalLock) {
2353 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2354 if (r == null) {
2355 return;
2356 }
2357 stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
2358 }
2359 }
2360
2361 /**
2362 * This API should be called by SystemUI only when user perform certain action to dismiss
2363 * lock task mode. We should only dismiss pinned lock task mode in this case.
2364 */
2365 @Override
2366 public void stopSystemLockTaskMode() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002367 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002368 stopLockTaskModeInternal(null, true /* isSystemCaller */);
2369 }
2370
2371 private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
2372 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
2373 if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
2374 return;
2375 }
2376
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002377 final ActivityStack stack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002378 if (stack == null || task != stack.topTask()) {
2379 throw new IllegalArgumentException("Invalid task, not in foreground");
2380 }
2381
2382 // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
2383 // system or a specific app.
2384 // * System-initiated requests will only start the pinned mode (screen pinning)
2385 // * App-initiated requests
2386 // - will put the device in fully locked mode (LockTask), if the app is whitelisted
2387 // - will start the pinned mode, otherwise
2388 final int callingUid = Binder.getCallingUid();
2389 long ident = Binder.clearCallingIdentity();
2390 try {
2391 // When a task is locked, dismiss the pinned stack if it exists
2392 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2393
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002394 getLockTaskController().startLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002395 } finally {
2396 Binder.restoreCallingIdentity(ident);
2397 }
2398 }
2399
2400 private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
2401 final int callingUid = Binder.getCallingUid();
2402 long ident = Binder.clearCallingIdentity();
2403 try {
2404 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002405 getLockTaskController().stopLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002406 }
2407 // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
2408 // task and jumping straight into a call in the case of emergency call back.
2409 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
2410 if (tm != null) {
2411 tm.showInCallScreen(false);
2412 }
2413 } finally {
2414 Binder.restoreCallingIdentity(ident);
2415 }
2416 }
2417
2418 @Override
2419 public boolean isInLockTaskMode() {
2420 return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
2421 }
2422
2423 @Override
2424 public int getLockTaskModeState() {
2425 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002426 return getLockTaskController().getLockTaskModeState();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002427 }
2428 }
2429
2430 @Override
2431 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
2432 synchronized (mGlobalLock) {
2433 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2434 if (r != null) {
2435 r.setTaskDescription(td);
2436 final TaskRecord task = r.getTask();
2437 task.updateTaskDescription();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002438 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002439 }
2440 }
2441 }
2442
2443 @Override
2444 public Bundle getActivityOptions(IBinder token) {
2445 final long origId = Binder.clearCallingIdentity();
2446 try {
2447 synchronized (mGlobalLock) {
2448 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
2449 if (r != null) {
2450 final ActivityOptions activityOptions = r.takeOptionsLocked();
2451 return activityOptions == null ? null : activityOptions.toBundle();
2452 }
2453 return null;
2454 }
2455 } finally {
2456 Binder.restoreCallingIdentity(origId);
2457 }
2458 }
2459
2460 @Override
2461 public List<IBinder> getAppTasks(String callingPackage) {
2462 int callingUid = Binder.getCallingUid();
2463 long ident = Binder.clearCallingIdentity();
2464 try {
2465 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002466 return mRecentTasks.getAppTasksList(callingUid, callingPackage);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002467 }
2468 } finally {
2469 Binder.restoreCallingIdentity(ident);
2470 }
2471 }
2472
2473 @Override
2474 public void finishVoiceTask(IVoiceInteractionSession session) {
2475 synchronized (mGlobalLock) {
2476 final long origId = Binder.clearCallingIdentity();
2477 try {
2478 // TODO: VI Consider treating local voice interactions and voice tasks
2479 // differently here
2480 mStackSupervisor.finishVoiceTask(session);
2481 } finally {
2482 Binder.restoreCallingIdentity(origId);
2483 }
2484 }
2485
2486 }
2487
2488 @Override
2489 public boolean isTopOfTask(IBinder token) {
2490 synchronized (mGlobalLock) {
2491 ActivityRecord r = ActivityRecord.isInStackLocked(token);
Riddle Hsu66b74a82018-07-26 00:20:12 +08002492 return r != null && r.getTask().getTopActivity() == r;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002493 }
2494 }
2495
2496 @Override
2497 public void notifyLaunchTaskBehindComplete(IBinder token) {
2498 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
2499 }
2500
2501 @Override
2502 public void notifyEnterAnimationComplete(IBinder token) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002503 mH.post(() -> {
2504 synchronized (mGlobalLock) {
2505 ActivityRecord r = ActivityRecord.forTokenLocked(token);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002506 if (r != null && r.attachedToProcess()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002507 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002508 r.app.getThread().scheduleEnterAnimationComplete(r.appToken);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002509 } catch (RemoteException e) {
2510 }
2511 }
2512 }
2513
2514 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002515 }
2516
2517 /** Called from an app when assist data is ready. */
2518 @Override
2519 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
2520 AssistContent content, Uri referrer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002521 PendingAssistExtras pae = (PendingAssistExtras) token;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002522 synchronized (pae) {
2523 pae.result = extras;
2524 pae.structure = structure;
2525 pae.content = content;
2526 if (referrer != null) {
2527 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
2528 }
2529 if (structure != null) {
2530 structure.setHomeActivity(pae.isHome);
2531 }
2532 pae.haveResult = true;
2533 pae.notifyAll();
2534 if (pae.intent == null && pae.receiver == null) {
2535 // Caller is just waiting for the result.
2536 return;
2537 }
2538 }
2539 // We are now ready to launch the assist activity.
2540 IAssistDataReceiver sendReceiver = null;
2541 Bundle sendBundle = null;
2542 synchronized (mGlobalLock) {
2543 buildAssistBundleLocked(pae, extras);
2544 boolean exists = mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002545 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002546 if (!exists) {
2547 // Timed out.
2548 return;
2549 }
2550
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002551 if ((sendReceiver = pae.receiver) != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002552 // Caller wants result sent back to them.
2553 sendBundle = new Bundle();
2554 sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
2555 sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
2556 sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
2557 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
2558 }
2559 }
2560 if (sendReceiver != null) {
2561 try {
2562 sendReceiver.onHandleAssistData(sendBundle);
2563 } catch (RemoteException e) {
2564 }
2565 return;
2566 }
2567
2568 final long ident = Binder.clearCallingIdentity();
2569 try {
2570 if (TextUtils.equals(pae.intent.getAction(),
2571 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
2572 pae.intent.putExtras(pae.extras);
2573 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
2574 } else {
2575 pae.intent.replaceExtras(pae.extras);
2576 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
2577 | Intent.FLAG_ACTIVITY_SINGLE_TOP
2578 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002579 mAmInternal.closeSystemDialogs("assist");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002580
2581 try {
2582 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
2583 } catch (ActivityNotFoundException e) {
2584 Slog.w(TAG, "No activity to handle assist action.", e);
2585 }
2586 }
2587 } finally {
2588 Binder.restoreCallingIdentity(ident);
2589 }
2590 }
2591
2592 @Override
2593 public int addAppTask(IBinder activityToken, Intent intent,
2594 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
2595 final int callingUid = Binder.getCallingUid();
2596 final long callingIdent = Binder.clearCallingIdentity();
2597
2598 try {
2599 synchronized (mGlobalLock) {
2600 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
2601 if (r == null) {
2602 throw new IllegalArgumentException("Activity does not exist; token="
2603 + activityToken);
2604 }
2605 ComponentName comp = intent.getComponent();
2606 if (comp == null) {
2607 throw new IllegalArgumentException("Intent " + intent
2608 + " must specify explicit component");
2609 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002610 if (thumbnail.getWidth() != mThumbnailWidth
2611 || thumbnail.getHeight() != mThumbnailHeight) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002612 throw new IllegalArgumentException("Bad thumbnail size: got "
2613 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002614 + mThumbnailWidth + "x" + mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002615 }
2616 if (intent.getSelector() != null) {
2617 intent.setSelector(null);
2618 }
2619 if (intent.getSourceBounds() != null) {
2620 intent.setSourceBounds(null);
2621 }
2622 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
2623 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
2624 // The caller has added this as an auto-remove task... that makes no
2625 // sense, so turn off auto-remove.
2626 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
2627 }
2628 }
2629 final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
2630 STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
2631 if (ainfo.applicationInfo.uid != callingUid) {
2632 throw new SecurityException(
2633 "Can't add task for another application: target uid="
2634 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
2635 }
2636
2637 final ActivityStack stack = r.getStack();
2638 final TaskRecord task = stack.createTaskRecord(
2639 mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent,
2640 null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002641 if (!mRecentTasks.addToBottom(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002642 // The app has too many tasks already and we can't add any more
2643 stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
2644 return INVALID_TASK_ID;
2645 }
2646 task.lastTaskDescription.copyFrom(description);
2647
2648 // TODO: Send the thumbnail to WM to store it.
2649
2650 return task.taskId;
2651 }
2652 } finally {
2653 Binder.restoreCallingIdentity(callingIdent);
2654 }
2655 }
2656
2657 @Override
2658 public Point getAppTaskThumbnailSize() {
2659 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002660 return new Point(mThumbnailWidth, mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002661 }
2662 }
2663
2664 @Override
2665 public void setTaskResizeable(int taskId, int resizeableMode) {
2666 synchronized (mGlobalLock) {
2667 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
2668 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
2669 if (task == null) {
2670 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
2671 return;
2672 }
2673 task.setResizeMode(resizeableMode);
2674 }
2675 }
2676
2677 @Override
2678 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002679 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002680 long ident = Binder.clearCallingIdentity();
2681 try {
2682 synchronized (mGlobalLock) {
2683 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2684 if (task == null) {
2685 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
2686 return;
2687 }
2688 // Place the task in the right stack if it isn't there already based on
2689 // the requested bounds.
2690 // The stack transition logic is:
2691 // - a null bounds on a freeform task moves that task to fullscreen
2692 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
2693 // that task to freeform
2694 // - otherwise the task is not moved
2695 ActivityStack stack = task.getStack();
2696 if (!task.getWindowConfiguration().canResizeTask()) {
2697 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
2698 }
2699 if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
2700 stack = stack.getDisplay().getOrCreateStack(
2701 WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
2702 } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
2703 stack = stack.getDisplay().getOrCreateStack(
2704 WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
2705 }
2706
2707 // Reparent the task to the right stack if necessary
2708 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
2709 if (stack != task.getStack()) {
2710 // Defer resume until the task is resized below
2711 task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
2712 DEFER_RESUME, "resizeTask");
2713 preserveWindow = false;
2714 }
2715
2716 // After reparenting (which only resizes the task to the stack bounds), resize the
2717 // task to the actual bounds provided
2718 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
2719 }
2720 } finally {
2721 Binder.restoreCallingIdentity(ident);
2722 }
2723 }
2724
2725 @Override
2726 public boolean releaseActivityInstance(IBinder token) {
2727 synchronized (mGlobalLock) {
2728 final long origId = Binder.clearCallingIdentity();
2729 try {
2730 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2731 if (r == null) {
2732 return false;
2733 }
2734 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
2735 } finally {
2736 Binder.restoreCallingIdentity(origId);
2737 }
2738 }
2739 }
2740
2741 @Override
2742 public void releaseSomeActivities(IApplicationThread appInt) {
2743 synchronized (mGlobalLock) {
2744 final long origId = Binder.clearCallingIdentity();
2745 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002746 WindowProcessController app =
2747 mAm.getRecordForAppLocked(appInt).getWindowProcessController();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002748 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
2749 } finally {
2750 Binder.restoreCallingIdentity(origId);
2751 }
2752 }
2753 }
2754
2755 @Override
2756 public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
2757 int secondaryDisplayShowing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002758 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002759 != PackageManager.PERMISSION_GRANTED) {
2760 throw new SecurityException("Requires permission "
2761 + android.Manifest.permission.DEVICE_POWER);
2762 }
2763
2764 synchronized (mGlobalLock) {
2765 long ident = Binder.clearCallingIdentity();
2766 if (mKeyguardShown != keyguardShowing) {
2767 mKeyguardShown = keyguardShowing;
2768 reportCurKeyguardUsageEventLocked(keyguardShowing);
2769 }
2770 try {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002771 mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002772 secondaryDisplayShowing);
2773 } finally {
2774 Binder.restoreCallingIdentity(ident);
2775 }
2776 }
2777
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002778 mH.post(() -> {
2779 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2780 mScreenObservers.get(i).onKeyguardStateChanged(keyguardShowing);
2781 }
2782 });
2783 }
2784
2785 void onScreenAwakeChanged(boolean isAwake) {
2786 mH.post(() -> {
2787 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2788 mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2789 }
2790 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002791 }
2792
2793 @Override
2794 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002795 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
2796 userId, "getTaskDescriptionIcon");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002797
2798 final File passedIconFile = new File(filePath);
2799 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
2800 passedIconFile.getName());
2801 if (!legitIconFile.getPath().equals(filePath)
2802 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
2803 throw new IllegalArgumentException("Bad file path: " + filePath
2804 + " passed for userId " + userId);
2805 }
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002806 return mRecentTasks.getTaskDescriptionIcon(filePath);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002807 }
2808
2809 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002810 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002811 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
2812 final ActivityOptions activityOptions = safeOptions != null
2813 ? safeOptions.getOptions(mStackSupervisor)
2814 : null;
2815 if (activityOptions == null
2816 || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
2817 || activityOptions.getCustomInPlaceResId() == 0) {
2818 throw new IllegalArgumentException("Expected in-place ActivityOption " +
2819 "with valid animation");
2820 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002821 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
2822 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002823 activityOptions.getCustomInPlaceResId());
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002824 mWindowManager.executeAppTransition();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002825 }
2826
2827 @Override
2828 public void removeStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002829 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002830 synchronized (mGlobalLock) {
2831 final long ident = Binder.clearCallingIdentity();
2832 try {
2833 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2834 if (stack == null) {
2835 Slog.w(TAG, "removeStack: No stack with id=" + stackId);
2836 return;
2837 }
2838 if (!stack.isActivityTypeStandardOrUndefined()) {
2839 throw new IllegalArgumentException(
2840 "Removing non-standard stack is not allowed.");
2841 }
2842 mStackSupervisor.removeStack(stack);
2843 } finally {
2844 Binder.restoreCallingIdentity(ident);
2845 }
2846 }
2847 }
2848
2849 @Override
2850 public void moveStackToDisplay(int stackId, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002851 mAmInternal.enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002852
2853 synchronized (mGlobalLock) {
2854 final long ident = Binder.clearCallingIdentity();
2855 try {
2856 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
2857 + " to displayId=" + displayId);
2858 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
2859 } finally {
2860 Binder.restoreCallingIdentity(ident);
2861 }
2862 }
2863 }
2864
2865 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002866 public void exitFreeformMode(IBinder token) {
2867 synchronized (mGlobalLock) {
2868 long ident = Binder.clearCallingIdentity();
2869 try {
2870 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2871 if (r == null) {
2872 throw new IllegalArgumentException(
2873 "exitFreeformMode: No activity record matching token=" + token);
2874 }
2875
2876 final ActivityStack stack = r.getStack();
2877 if (stack == null || !stack.inFreeformWindowingMode()) {
2878 throw new IllegalStateException(
2879 "exitFreeformMode: You can only go fullscreen from freeform.");
2880 }
2881
2882 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
2883 } finally {
2884 Binder.restoreCallingIdentity(ident);
2885 }
2886 }
2887 }
2888
2889 /** Sets the task stack listener that gets callbacks when a task stack changes. */
2890 @Override
2891 public void registerTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002892 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002893 "registerTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002894 mTaskChangeNotificationController.registerTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002895 }
2896
2897 /** Unregister a task stack listener so that it stops receiving callbacks. */
2898 @Override
2899 public void unregisterTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002900 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002901 "unregisterTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002902 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002903 }
2904
2905 private void reportCurKeyguardUsageEventLocked(boolean keyguardShowing) {
2906 mAm.reportGlobalUsageEventLocked(keyguardShowing
2907 ? UsageEvents.Event.KEYGUARD_SHOWN
2908 : UsageEvents.Event.KEYGUARD_HIDDEN);
2909 }
2910
2911 @Override
2912 public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
2913 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
2914 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
2915 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
2916 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
2917 }
2918
2919 @Override
2920 public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
2921 IBinder activityToken, int flags) {
2922 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
2923 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
2924 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
2925 }
2926
2927 @Override
2928 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
2929 Bundle args) {
2930 return enqueueAssistContext(requestType, intent, hint, null, null, null,
2931 true /* focused */, true /* newSessionId */, userHandle, args,
2932 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
2933 }
2934
2935 @Override
2936 public Bundle getAssistContextExtras(int requestType) {
2937 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
2938 null, null, true /* focused */, true /* newSessionId */,
2939 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
2940 if (pae == null) {
2941 return null;
2942 }
2943 synchronized (pae) {
2944 while (!pae.haveResult) {
2945 try {
2946 pae.wait();
2947 } catch (InterruptedException e) {
2948 }
2949 }
2950 }
2951 synchronized (mGlobalLock) {
2952 buildAssistBundleLocked(pae, pae.result);
2953 mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002954 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002955 }
2956 return pae.extras;
2957 }
2958
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002959 /**
2960 * Binder IPC calls go through the public entry point.
2961 * This can be called with or without the global lock held.
2962 */
2963 private static int checkCallingPermission(String permission) {
2964 return checkPermission(
2965 permission, Binder.getCallingPid(), UserHandle.getAppId(Binder.getCallingUid()));
2966 }
2967
2968 /** This can be called with or without the global lock held. */
2969 void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
2970 if (!getRecentTasks().isCallerRecents(Binder.getCallingUid())) {
2971 mAmInternal.enforceCallingPermission(permission, func);
2972 }
2973 }
2974
2975 @VisibleForTesting
2976 int checkGetTasksPermission(String permission, int pid, int uid) {
2977 return checkPermission(permission, pid, uid);
2978 }
2979
2980 static int checkPermission(String permission, int pid, int uid) {
2981 if (permission == null) {
2982 return PackageManager.PERMISSION_DENIED;
2983 }
2984 return checkComponentPermission(permission, pid, uid, -1, true);
2985 }
2986
2987 boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
2988 if (getRecentTasks().isCallerRecents(callingUid)) {
2989 // Always allow the recents component to get tasks
2990 return true;
2991 }
2992
2993 boolean allowed = checkGetTasksPermission(android.Manifest.permission.REAL_GET_TASKS,
2994 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
2995 if (!allowed) {
2996 if (checkGetTasksPermission(android.Manifest.permission.GET_TASKS,
2997 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
2998 // Temporary compatibility: some existing apps on the system image may
2999 // still be requesting the old permission and not switched to the new
3000 // one; if so, we'll still allow them full access. This means we need
3001 // to see if they are holding the old permission and are a system app.
3002 try {
3003 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
3004 allowed = true;
3005 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
3006 + " is using old GET_TASKS but privileged; allowing");
3007 }
3008 } catch (RemoteException e) {
3009 }
3010 }
3011 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
3012 + " does not hold REAL_GET_TASKS; limiting output");
3013 }
3014 return allowed;
3015 }
3016
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003017 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
3018 IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
3019 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
3020 int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003021 mAmInternal.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003022 "enqueueAssistContext()");
3023
3024 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003025 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003026 if (activity == null) {
3027 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
3028 return null;
3029 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003030 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003031 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
3032 return null;
3033 }
3034 if (focused) {
3035 if (activityToken != null) {
3036 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
3037 if (activity != caller) {
3038 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
3039 + " is not current top " + activity);
3040 return null;
3041 }
3042 }
3043 } else {
3044 activity = ActivityRecord.forTokenLocked(activityToken);
3045 if (activity == null) {
3046 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
3047 + " couldn't be found");
3048 return null;
3049 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003050 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003051 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
3052 return null;
3053 }
3054 }
3055
3056 PendingAssistExtras pae;
3057 Bundle extras = new Bundle();
3058 if (args != null) {
3059 extras.putAll(args);
3060 }
3061 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003062 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003063
3064 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
3065 userHandle);
3066 pae.isHome = activity.isActivityTypeHome();
3067
3068 // Increment the sessionId if necessary
3069 if (newSessionId) {
3070 mViSessionId++;
3071 }
3072 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003073 activity.app.getThread().requestAssistContextExtras(activity.appToken, pae,
3074 requestType, mViSessionId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003075 mPendingAssistExtras.add(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003076 mUiHandler.postDelayed(pae, timeout);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003077 } catch (RemoteException e) {
3078 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
3079 return null;
3080 }
3081 return pae;
3082 }
3083 }
3084
3085 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
3086 if (result != null) {
3087 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
3088 }
3089 if (pae.hint != null) {
3090 pae.extras.putBoolean(pae.hint, true);
3091 }
3092 }
3093
3094 private void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
3095 IAssistDataReceiver receiver;
3096 synchronized (mGlobalLock) {
3097 mPendingAssistExtras.remove(pae);
3098 receiver = pae.receiver;
3099 }
3100 if (receiver != null) {
3101 // Caller wants result sent back to them.
3102 Bundle sendBundle = new Bundle();
3103 // At least return the receiver extras
3104 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
3105 try {
3106 pae.receiver.onHandleAssistData(sendBundle);
3107 } catch (RemoteException e) {
3108 }
3109 }
3110 }
3111
3112 public class PendingAssistExtras extends Binder implements Runnable {
3113 public final ActivityRecord activity;
3114 public boolean isHome;
3115 public final Bundle extras;
3116 public final Intent intent;
3117 public final String hint;
3118 public final IAssistDataReceiver receiver;
3119 public final int userHandle;
3120 public boolean haveResult = false;
3121 public Bundle result = null;
3122 public AssistStructure structure = null;
3123 public AssistContent content = null;
3124 public Bundle receiverExtras;
3125
3126 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
3127 String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
3128 int _userHandle) {
3129 activity = _activity;
3130 extras = _extras;
3131 intent = _intent;
3132 hint = _hint;
3133 receiver = _receiver;
3134 receiverExtras = _receiverExtras;
3135 userHandle = _userHandle;
3136 }
3137
3138 @Override
3139 public void run() {
3140 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
3141 synchronized (this) {
3142 haveResult = true;
3143 notifyAll();
3144 }
3145 pendingAssistExtrasTimedOut(this);
3146 }
3147 }
3148
3149 @Override
3150 public boolean isAssistDataAllowedOnCurrentActivity() {
3151 int userId;
3152 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003153 final ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003154 if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
3155 return false;
3156 }
3157
3158 final ActivityRecord activity = focusedStack.getTopActivity();
3159 if (activity == null) {
3160 return false;
3161 }
3162 userId = activity.userId;
3163 }
3164 return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
3165 }
3166
3167 @Override
3168 public boolean showAssistFromActivity(IBinder token, Bundle args) {
3169 long ident = Binder.clearCallingIdentity();
3170 try {
3171 synchronized (mGlobalLock) {
3172 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003173 ActivityRecord top = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003174 if (top != caller) {
3175 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3176 + " is not current top " + top);
3177 return false;
3178 }
3179 if (!top.nowVisible) {
3180 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3181 + " is not visible");
3182 return false;
3183 }
3184 }
3185 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
3186 token);
3187 } finally {
3188 Binder.restoreCallingIdentity(ident);
3189 }
3190 }
3191
3192 @Override
3193 public boolean isRootVoiceInteraction(IBinder token) {
3194 synchronized (mGlobalLock) {
3195 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3196 if (r == null) {
3197 return false;
3198 }
3199 return r.rootVoiceInteraction;
3200 }
3201 }
3202
Wale Ogunwalef6733932018-06-27 05:14:34 -07003203 private void onLocalVoiceInteractionStartedLocked(IBinder activity,
3204 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
3205 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
3206 if (activityToCallback == null) return;
3207 activityToCallback.setVoiceSessionLocked(voiceSession);
3208
3209 // Inform the activity
3210 try {
3211 activityToCallback.app.getThread().scheduleLocalVoiceInteractionStarted(activity,
3212 voiceInteractor);
3213 long token = Binder.clearCallingIdentity();
3214 try {
3215 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
3216 } finally {
3217 Binder.restoreCallingIdentity(token);
3218 }
3219 // TODO: VI Should we cache the activity so that it's easier to find later
3220 // rather than scan through all the stacks and activities?
3221 } catch (RemoteException re) {
3222 activityToCallback.clearVoiceSessionLocked();
3223 // TODO: VI Should this terminate the voice session?
3224 }
3225 }
3226
3227 private void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
3228 Slog.d(TAG, "<<< startRunningVoiceLocked()");
3229 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
3230 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
3231 boolean wasRunningVoice = mRunningVoice != null;
3232 mRunningVoice = session;
3233 if (!wasRunningVoice) {
3234 mVoiceWakeLock.acquire();
3235 updateSleepIfNeededLocked();
3236 }
3237 }
3238 }
3239
3240 void finishRunningVoiceLocked() {
3241 if (mRunningVoice != null) {
3242 mRunningVoice = null;
3243 mVoiceWakeLock.release();
3244 updateSleepIfNeededLocked();
3245 }
3246 }
3247
3248 @Override
3249 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3250 synchronized (mGlobalLock) {
3251 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3252 if (keepAwake) {
3253 mVoiceWakeLock.acquire();
3254 } else {
3255 mVoiceWakeLock.release();
3256 }
3257 }
3258 }
3259 }
3260
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003261 @Override
3262 public ComponentName getActivityClassForToken(IBinder token) {
3263 synchronized (mGlobalLock) {
3264 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3265 if (r == null) {
3266 return null;
3267 }
3268 return r.intent.getComponent();
3269 }
3270 }
3271
3272 @Override
3273 public String getPackageForToken(IBinder token) {
3274 synchronized (mGlobalLock) {
3275 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3276 if (r == null) {
3277 return null;
3278 }
3279 return r.packageName;
3280 }
3281 }
3282
3283 @Override
3284 public void showLockTaskEscapeMessage(IBinder token) {
3285 synchronized (mGlobalLock) {
3286 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3287 if (r == null) {
3288 return;
3289 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003290 getLockTaskController().showLockTaskToast();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003291 }
3292 }
3293
3294 @Override
3295 public void keyguardGoingAway(int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003296 enforceNotIsolatedCaller("keyguardGoingAway");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003297 final long token = Binder.clearCallingIdentity();
3298 try {
3299 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003300 mKeyguardController.keyguardGoingAway(flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003301 }
3302 } finally {
3303 Binder.restoreCallingIdentity(token);
3304 }
3305 }
3306
3307 /**
3308 * Try to place task to provided position. The final position might be different depending on
3309 * current user and stacks state. The task will be moved to target stack if it's currently in
3310 * different stack.
3311 */
3312 @Override
3313 public void positionTaskInStack(int taskId, int stackId, int position) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003314 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003315 synchronized (mGlobalLock) {
3316 long ident = Binder.clearCallingIdentity();
3317 try {
3318 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
3319 + taskId + " in stackId=" + stackId + " at position=" + position);
3320 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3321 if (task == null) {
3322 throw new IllegalArgumentException("positionTaskInStack: no task for id="
3323 + taskId);
3324 }
3325
3326 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3327
3328 if (stack == null) {
3329 throw new IllegalArgumentException("positionTaskInStack: no stack for id="
3330 + stackId);
3331 }
3332 if (!stack.isActivityTypeStandardOrUndefined()) {
3333 throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
3334 + " the position of task " + taskId + " in/to non-standard stack");
3335 }
3336
3337 // TODO: Have the callers of this API call a separate reparent method if that is
3338 // what they intended to do vs. having this method also do reparenting.
3339 if (task.getStack() == stack) {
3340 // Change position in current stack.
3341 stack.positionChildAt(task, position);
3342 } else {
3343 // Reparent to new stack.
3344 task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
3345 !DEFER_RESUME, "positionTaskInStack");
3346 }
3347 } finally {
3348 Binder.restoreCallingIdentity(ident);
3349 }
3350 }
3351 }
3352
3353 @Override
3354 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
3355 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
3356 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
3357 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
3358 synchronized (mGlobalLock) {
3359 ActivityRecord record = ActivityRecord.isInStackLocked(token);
3360 if (record == null) {
3361 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
3362 + "found for: " + token);
3363 }
3364 record.setSizeConfigurations(horizontalSizeConfiguration,
3365 verticalSizeConfigurations, smallestSizeConfigurations);
3366 }
3367 }
3368
3369 /**
3370 * Dismisses split-screen multi-window mode.
3371 * @param toTop If true the current primary split-screen stack will be placed or left on top.
3372 */
3373 @Override
3374 public void dismissSplitScreenMode(boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003375 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003376 MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
3377 final long ident = Binder.clearCallingIdentity();
3378 try {
3379 synchronized (mGlobalLock) {
3380 final ActivityStack stack =
3381 mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
3382 if (stack == null) {
3383 Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
3384 return;
3385 }
3386
3387 if (toTop) {
3388 // Caller wants the current split-screen primary stack to be the top stack after
3389 // it goes fullscreen, so move it to the front.
3390 stack.moveToFront("dismissSplitScreenMode");
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003391 } else if (mStackSupervisor.isTopDisplayFocusedStack(stack)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003392 // In this case the current split-screen primary stack shouldn't be the top
3393 // stack after it goes fullscreen, but it current has focus, so we move the
3394 // focus to the top-most split-screen secondary stack next to it.
3395 final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
3396 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
3397 if (otherStack != null) {
3398 otherStack.moveToFront("dismissSplitScreenMode_other");
3399 }
3400 }
3401
Evan Rosky10475742018-09-05 19:02:48 -07003402 stack.setWindowingMode(WINDOWING_MODE_UNDEFINED);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003403 }
3404 } finally {
3405 Binder.restoreCallingIdentity(ident);
3406 }
3407 }
3408
3409 /**
3410 * Dismisses Pip
3411 * @param animate True if the dismissal should be animated.
3412 * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
3413 * default animation duration should be used.
3414 */
3415 @Override
3416 public void dismissPip(boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003417 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003418 final long ident = Binder.clearCallingIdentity();
3419 try {
3420 synchronized (mGlobalLock) {
3421 final PinnedActivityStack stack =
3422 mStackSupervisor.getDefaultDisplay().getPinnedStack();
3423 if (stack == null) {
3424 Slog.w(TAG, "dismissPip: pinned stack not found.");
3425 return;
3426 }
3427 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
3428 throw new IllegalArgumentException("Stack: " + stack
3429 + " doesn't support animated resize.");
3430 }
3431 if (animate) {
3432 stack.animateResizePinnedStack(null /* sourceHintBounds */,
3433 null /* destBounds */, animationDuration, false /* fromFullscreen */);
3434 } else {
3435 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
3436 }
3437 }
3438 } finally {
3439 Binder.restoreCallingIdentity(ident);
3440 }
3441 }
3442
3443 @Override
3444 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003445 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003446 synchronized (mGlobalLock) {
3447 mSuppressResizeConfigChanges = suppress;
3448 }
3449 }
3450
3451 /**
3452 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
3453 * animated the stack to the fullscreen, but can also be called if we are relaunching an
3454 * activity and clearing the task at the same time.
3455 */
3456 @Override
3457 // TODO: API should just be about changing windowing modes...
3458 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003459 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003460 "moveTasksToFullscreenStack()");
3461 synchronized (mGlobalLock) {
3462 final long origId = Binder.clearCallingIdentity();
3463 try {
3464 final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
3465 if (stack != null){
3466 if (!stack.isActivityTypeStandardOrUndefined()) {
3467 throw new IllegalArgumentException(
3468 "You can't move tasks from non-standard stacks.");
3469 }
3470 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
3471 }
3472 } finally {
3473 Binder.restoreCallingIdentity(origId);
3474 }
3475 }
3476 }
3477
3478 /**
3479 * Moves the top activity in the input stackId to the pinned stack.
3480 *
3481 * @param stackId Id of stack to move the top activity to pinned stack.
3482 * @param bounds Bounds to use for pinned stack.
3483 *
3484 * @return True if the top activity of the input stack was successfully moved to the pinned
3485 * stack.
3486 */
3487 @Override
3488 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003489 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003490 "moveTopActivityToPinnedStack()");
3491 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003492 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003493 throw new IllegalStateException("moveTopActivityToPinnedStack:"
3494 + "Device doesn't support picture-in-picture mode");
3495 }
3496
3497 long ident = Binder.clearCallingIdentity();
3498 try {
3499 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
3500 } finally {
3501 Binder.restoreCallingIdentity(ident);
3502 }
3503 }
3504 }
3505
3506 @Override
3507 public boolean isInMultiWindowMode(IBinder token) {
3508 final long origId = Binder.clearCallingIdentity();
3509 try {
3510 synchronized (mGlobalLock) {
3511 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3512 if (r == null) {
3513 return false;
3514 }
3515 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
3516 return r.inMultiWindowMode();
3517 }
3518 } finally {
3519 Binder.restoreCallingIdentity(origId);
3520 }
3521 }
3522
3523 @Override
3524 public boolean isInPictureInPictureMode(IBinder token) {
3525 final long origId = Binder.clearCallingIdentity();
3526 try {
3527 synchronized (mGlobalLock) {
3528 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
3529 }
3530 } finally {
3531 Binder.restoreCallingIdentity(origId);
3532 }
3533 }
3534
3535 private boolean isInPictureInPictureMode(ActivityRecord r) {
3536 if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
3537 || r.getStack().isInStackLocked(r) == null) {
3538 return false;
3539 }
3540
3541 // If we are animating to fullscreen then we have already dispatched the PIP mode
3542 // changed, so we should reflect that check here as well.
3543 final PinnedActivityStack stack = r.getStack();
3544 final PinnedStackWindowController windowController = stack.getWindowContainerController();
3545 return !windowController.isAnimatingBoundsToFullscreen();
3546 }
3547
3548 @Override
3549 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
3550 final long origId = Binder.clearCallingIdentity();
3551 try {
3552 synchronized (mGlobalLock) {
3553 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3554 "enterPictureInPictureMode", token, params);
3555
3556 // If the activity is already in picture in picture mode, then just return early
3557 if (isInPictureInPictureMode(r)) {
3558 return true;
3559 }
3560
3561 // Activity supports picture-in-picture, now check that we can enter PiP at this
3562 // point, if it is
3563 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
3564 false /* beforeStopping */)) {
3565 return false;
3566 }
3567
3568 final Runnable enterPipRunnable = () -> {
Wale Ogunwalef276a6f2018-06-15 08:26:07 -07003569 synchronized (mGlobalLock) {
3570 // Only update the saved args from the args that are set
3571 r.pictureInPictureArgs.copyOnlySet(params);
3572 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
3573 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
3574 // Adjust the source bounds by the insets for the transition down
3575 final Rect sourceBounds = new Rect(
3576 r.pictureInPictureArgs.getSourceRectHint());
3577 mStackSupervisor.moveActivityToPinnedStackLocked(
3578 r, sourceBounds, aspectRatio, "enterPictureInPictureMode");
3579 final PinnedActivityStack stack = r.getStack();
3580 stack.setPictureInPictureAspectRatio(aspectRatio);
3581 stack.setPictureInPictureActions(actions);
3582 MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
3583 r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
3584 logPictureInPictureArgs(params);
3585 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003586 };
3587
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003588 if (isKeyguardLocked()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003589 // If the keyguard is showing or occluded, then try and dismiss it before
3590 // entering picture-in-picture (this will prompt the user to authenticate if the
3591 // device is currently locked).
3592 dismissKeyguard(token, new KeyguardDismissCallback() {
3593 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003594 public void onDismissSucceeded() {
3595 mH.post(enterPipRunnable);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003596 }
3597 }, null /* message */);
3598 } else {
3599 // Enter picture in picture immediately otherwise
3600 enterPipRunnable.run();
3601 }
3602 return true;
3603 }
3604 } finally {
3605 Binder.restoreCallingIdentity(origId);
3606 }
3607 }
3608
3609 @Override
3610 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
3611 final long origId = Binder.clearCallingIdentity();
3612 try {
3613 synchronized (mGlobalLock) {
3614 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3615 "setPictureInPictureParams", token, params);
3616
3617 // Only update the saved args from the args that are set
3618 r.pictureInPictureArgs.copyOnlySet(params);
3619 if (r.inPinnedWindowingMode()) {
3620 // If the activity is already in picture-in-picture, update the pinned stack now
3621 // if it is not already expanding to fullscreen. Otherwise, the arguments will
3622 // be used the next time the activity enters PiP
3623 final PinnedActivityStack stack = r.getStack();
3624 if (!stack.isAnimatingBoundsToFullscreen()) {
3625 stack.setPictureInPictureAspectRatio(
3626 r.pictureInPictureArgs.getAspectRatio());
3627 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
3628 }
3629 }
3630 logPictureInPictureArgs(params);
3631 }
3632 } finally {
3633 Binder.restoreCallingIdentity(origId);
3634 }
3635 }
3636
3637 @Override
3638 public int getMaxNumPictureInPictureActions(IBinder token) {
3639 // Currently, this is a static constant, but later, we may change this to be dependent on
3640 // the context of the activity
3641 return 3;
3642 }
3643
3644 private void logPictureInPictureArgs(PictureInPictureParams params) {
3645 if (params.hasSetActions()) {
3646 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
3647 params.getActions().size());
3648 }
3649 if (params.hasSetAspectRatio()) {
3650 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
3651 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
3652 MetricsLogger.action(lm);
3653 }
3654 }
3655
3656 /**
3657 * Checks the state of the system and the activity associated with the given {@param token} to
3658 * verify that picture-in-picture is supported for that activity.
3659 *
3660 * @return the activity record for the given {@param token} if all the checks pass.
3661 */
3662 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
3663 IBinder token, PictureInPictureParams params) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003664 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003665 throw new IllegalStateException(caller
3666 + ": Device doesn't support picture-in-picture mode.");
3667 }
3668
3669 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3670 if (r == null) {
3671 throw new IllegalStateException(caller
3672 + ": Can't find activity for token=" + token);
3673 }
3674
3675 if (!r.supportsPictureInPicture()) {
3676 throw new IllegalStateException(caller
3677 + ": Current activity does not support picture-in-picture.");
3678 }
3679
3680 if (params.hasSetAspectRatio()
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003681 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003682 params.getAspectRatio())) {
3683 final float minAspectRatio = mContext.getResources().getFloat(
3684 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
3685 final float maxAspectRatio = mContext.getResources().getFloat(
3686 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
3687 throw new IllegalArgumentException(String.format(caller
3688 + ": Aspect ratio is too extreme (must be between %f and %f).",
3689 minAspectRatio, maxAspectRatio));
3690 }
3691
3692 // Truncate the number of actions if necessary
3693 params.truncateActions(getMaxNumPictureInPictureActions(token));
3694
3695 return r;
3696 }
3697
3698 @Override
3699 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003700 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003701 synchronized (mGlobalLock) {
3702 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
3703 if (r == null) {
3704 throw new IllegalArgumentException("Activity does not exist; token="
3705 + activityToken);
3706 }
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07003707 return r.getUriPermissionsLocked().getExternalToken();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003708 }
3709 }
3710
3711 @Override
3712 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
3713 Rect tempDockedTaskInsetBounds,
3714 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003715 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003716 long ident = Binder.clearCallingIdentity();
3717 try {
3718 synchronized (mGlobalLock) {
3719 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
3720 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
3721 PRESERVE_WINDOWS);
3722 }
3723 } finally {
3724 Binder.restoreCallingIdentity(ident);
3725 }
3726 }
3727
3728 @Override
3729 public void setSplitScreenResizing(boolean resizing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003730 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003731 final long ident = Binder.clearCallingIdentity();
3732 try {
3733 synchronized (mGlobalLock) {
3734 mStackSupervisor.setSplitScreenResizing(resizing);
3735 }
3736 } finally {
3737 Binder.restoreCallingIdentity(ident);
3738 }
3739 }
3740
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003741 /**
3742 * Check that we have the features required for VR-related API calls, and throw an exception if
3743 * not.
3744 */
3745 void enforceSystemHasVrFeature() {
3746 if (!mContext.getPackageManager().hasSystemFeature(
3747 PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
3748 throw new UnsupportedOperationException("VR mode not supported on this device!");
3749 }
3750 }
3751
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003752 @Override
3753 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003754 enforceSystemHasVrFeature();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003755
3756 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3757
3758 ActivityRecord r;
3759 synchronized (mGlobalLock) {
3760 r = ActivityRecord.isInStackLocked(token);
3761 }
3762
3763 if (r == null) {
3764 throw new IllegalArgumentException();
3765 }
3766
3767 int err;
3768 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
3769 VrManagerInternal.NO_ERROR) {
3770 return err;
3771 }
3772
3773 // Clear the binder calling uid since this path may call moveToTask().
3774 final long callingId = Binder.clearCallingIdentity();
3775 try {
3776 synchronized (mGlobalLock) {
3777 r.requestedVrComponent = (enabled) ? packageName : null;
3778
3779 // Update associated state if this activity is currently focused
Andrii Kulian52d255c2018-07-13 11:32:19 -07003780 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003781 applyUpdateVrModeLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003782 }
3783 return 0;
3784 }
3785 } finally {
3786 Binder.restoreCallingIdentity(callingId);
3787 }
3788 }
3789
3790 @Override
3791 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
3792 Slog.i(TAG, "Activity tried to startLocalVoiceInteraction");
3793 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003794 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003795 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
3796 throw new SecurityException("Only focused activity can call startVoiceInteraction");
3797 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07003798 if (mRunningVoice != null || activity.getTask().voiceSession != null
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003799 || activity.voiceSession != null) {
3800 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
3801 return;
3802 }
3803 if (activity.pendingVoiceInteractionStart) {
3804 Slog.w(TAG, "Pending start of voice interaction already.");
3805 return;
3806 }
3807 activity.pendingVoiceInteractionStart = true;
3808 }
3809 LocalServices.getService(VoiceInteractionManagerInternal.class)
3810 .startLocalVoiceInteraction(callingActivity, options);
3811 }
3812
3813 @Override
3814 public void stopLocalVoiceInteraction(IBinder callingActivity) {
3815 LocalServices.getService(VoiceInteractionManagerInternal.class)
3816 .stopLocalVoiceInteraction(callingActivity);
3817 }
3818
3819 @Override
3820 public boolean supportsLocalVoiceInteraction() {
3821 return LocalServices.getService(VoiceInteractionManagerInternal.class)
3822 .supportsLocalVoiceInteraction();
3823 }
3824
3825 /** Notifies all listeners when the pinned stack animation starts. */
3826 @Override
3827 public void notifyPinnedStackAnimationStarted() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003828 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003829 }
3830
3831 /** Notifies all listeners when the pinned stack animation ends. */
3832 @Override
3833 public void notifyPinnedStackAnimationEnded() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003834 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003835 }
3836
3837 @Override
3838 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003839 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003840 final long ident = Binder.clearCallingIdentity();
3841 try {
3842 synchronized (mGlobalLock) {
3843 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
3844 }
3845 } finally {
3846 Binder.restoreCallingIdentity(ident);
3847 }
3848 }
3849
3850 @Override
3851 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003852 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003853
3854 synchronized (mGlobalLock) {
3855 // Check if display is initialized in AM.
3856 if (!mStackSupervisor.isDisplayAdded(displayId)) {
3857 // Call might come when display is not yet added or has already been removed.
3858 if (DEBUG_CONFIGURATION) {
3859 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
3860 + displayId);
3861 }
3862 return false;
3863 }
3864
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003865 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003866 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003867 values = mWindowManager.computeNewConfiguration(displayId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003868 }
3869
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003870 if (mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003871 // Update OOM levels based on display size.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003872 mAm.mProcessList.applyDisplaySize(mWindowManager);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003873 }
3874
3875 final long origId = Binder.clearCallingIdentity();
3876 try {
3877 if (values != null) {
3878 Settings.System.clearConfiguration(values);
3879 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003880 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003881 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
3882 return mTmpUpdateConfigurationResult.changes != 0;
3883 } finally {
3884 Binder.restoreCallingIdentity(origId);
3885 }
3886 }
3887 }
3888
3889 @Override
3890 public boolean updateConfiguration(Configuration values) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003891 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003892
3893 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003894 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003895 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003896 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003897 }
3898
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003899 if (mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003900 // Update OOM levels based on display size.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003901 mAm.mProcessList.applyDisplaySize(mWindowManager);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003902 }
3903
3904 final long origId = Binder.clearCallingIdentity();
3905 try {
3906 if (values != null) {
3907 Settings.System.clearConfiguration(values);
3908 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003909 updateConfigurationLocked(values, null, false, false /* persistent */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003910 UserHandle.USER_NULL, false /* deferResume */,
3911 mTmpUpdateConfigurationResult);
3912 return mTmpUpdateConfigurationResult.changes != 0;
3913 } finally {
3914 Binder.restoreCallingIdentity(origId);
3915 }
3916 }
3917 }
3918
3919 @Override
3920 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
3921 CharSequence message) {
3922 if (message != null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003923 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003924 Manifest.permission.SHOW_KEYGUARD_MESSAGE, "dismissKeyguard()");
3925 }
3926 final long callingId = Binder.clearCallingIdentity();
3927 try {
3928 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003929 mKeyguardController.dismissKeyguard(token, callback, message);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003930 }
3931 } finally {
3932 Binder.restoreCallingIdentity(callingId);
3933 }
3934 }
3935
3936 @Override
3937 public void cancelTaskWindowTransition(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003938 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003939 "cancelTaskWindowTransition()");
3940 final long ident = Binder.clearCallingIdentity();
3941 try {
3942 synchronized (mGlobalLock) {
3943 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
3944 MATCH_TASK_IN_STACKS_ONLY);
3945 if (task == null) {
3946 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
3947 return;
3948 }
3949 task.cancelWindowTransition();
3950 }
3951 } finally {
3952 Binder.restoreCallingIdentity(ident);
3953 }
3954 }
3955
3956 @Override
3957 public ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003958 enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003959 final long ident = Binder.clearCallingIdentity();
3960 try {
3961 final TaskRecord task;
3962 synchronized (mGlobalLock) {
3963 task = mStackSupervisor.anyTaskForIdLocked(taskId,
3964 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
3965 if (task == null) {
3966 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
3967 return null;
3968 }
3969 }
3970 // Don't call this while holding the lock as this operation might hit the disk.
3971 return task.getSnapshot(reducedResolution);
3972 } finally {
3973 Binder.restoreCallingIdentity(ident);
3974 }
3975 }
3976
3977 @Override
3978 public void setDisablePreviewScreenshots(IBinder token, boolean disable) {
3979 synchronized (mGlobalLock) {
3980 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3981 if (r == null) {
3982 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
3983 + token);
3984 return;
3985 }
3986 final long origId = Binder.clearCallingIdentity();
3987 try {
3988 r.setDisablePreviewScreenshots(disable);
3989 } finally {
3990 Binder.restoreCallingIdentity(origId);
3991 }
3992 }
3993 }
3994
3995 /** Return the user id of the last resumed activity. */
3996 @Override
3997 public @UserIdInt
3998 int getLastResumedActivityUserId() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003999 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004000 Manifest.permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
4001 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07004002 if (mLastResumedActivity == null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004003 return getCurrentUserId();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004004 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004005 return mLastResumedActivity.userId;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004006 }
4007 }
4008
4009 @Override
4010 public void updateLockTaskFeatures(int userId, int flags) {
4011 final int callingUid = Binder.getCallingUid();
4012 if (callingUid != 0 && callingUid != SYSTEM_UID) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004013 mAmInternal.enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004014 "updateLockTaskFeatures()");
4015 }
4016 synchronized (mGlobalLock) {
4017 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
4018 Integer.toHexString(flags));
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07004019 getLockTaskController().updateLockTaskFeatures(userId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004020 }
4021 }
4022
4023 @Override
4024 public void setShowWhenLocked(IBinder token, boolean showWhenLocked) {
4025 synchronized (mGlobalLock) {
4026 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4027 if (r == null) {
4028 return;
4029 }
4030 final long origId = Binder.clearCallingIdentity();
4031 try {
4032 r.setShowWhenLocked(showWhenLocked);
4033 } finally {
4034 Binder.restoreCallingIdentity(origId);
4035 }
4036 }
4037 }
4038
4039 @Override
4040 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) {
4041 synchronized (mGlobalLock) {
4042 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4043 if (r == null) {
4044 return;
4045 }
4046 final long origId = Binder.clearCallingIdentity();
4047 try {
4048 r.setTurnScreenOn(turnScreenOn);
4049 } finally {
4050 Binder.restoreCallingIdentity(origId);
4051 }
4052 }
4053 }
4054
4055 @Override
4056 public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004057 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004058 "registerRemoteAnimations");
4059 definition.setCallingPid(Binder.getCallingPid());
4060 synchronized (mGlobalLock) {
4061 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4062 if (r == null) {
4063 return;
4064 }
4065 final long origId = Binder.clearCallingIdentity();
4066 try {
4067 r.registerRemoteAnimations(definition);
4068 } finally {
4069 Binder.restoreCallingIdentity(origId);
4070 }
4071 }
4072 }
4073
4074 @Override
4075 public void registerRemoteAnimationForNextActivityStart(String packageName,
4076 RemoteAnimationAdapter adapter) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004077 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004078 "registerRemoteAnimationForNextActivityStart");
4079 adapter.setCallingPid(Binder.getCallingPid());
4080 synchronized (mGlobalLock) {
4081 final long origId = Binder.clearCallingIdentity();
4082 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07004083 getActivityStartController().registerRemoteAnimationForNextActivityStart(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004084 packageName, adapter);
4085 } finally {
4086 Binder.restoreCallingIdentity(origId);
4087 }
4088 }
4089 }
4090
4091 /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
4092 @Override
4093 public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
4094 synchronized (mGlobalLock) {
4095 final long origId = Binder.clearCallingIdentity();
4096 try {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004097 mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004098 } finally {
4099 Binder.restoreCallingIdentity(origId);
4100 }
4101 }
4102 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004103
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004104 @Override
4105 public void setVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004106 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004107 synchronized (mGlobalLock) {
4108 synchronized (mAm.mPidsSelfLocked) {
4109 final int pid = Binder.getCallingPid();
4110 final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004111 mVrController.setVrThreadLocked(tid, pid, proc.getWindowProcessController());
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004112 }
4113 }
4114 }
4115
4116 @Override
4117 public void setPersistentVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004118 if (checkCallingPermission(Manifest.permission.RESTRICTED_VR_ACCESS)
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004119 != PERMISSION_GRANTED) {
4120 final String msg = "Permission Denial: setPersistentVrThread() from pid="
4121 + Binder.getCallingPid()
4122 + ", uid=" + Binder.getCallingUid()
4123 + " requires " + Manifest.permission.RESTRICTED_VR_ACCESS;
4124 Slog.w(TAG, msg);
4125 throw new SecurityException(msg);
4126 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004127 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004128 synchronized (mGlobalLock) {
4129 synchronized (mAm.mPidsSelfLocked) {
4130 final int pid = Binder.getCallingPid();
4131 final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
4132 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
4133 }
4134 }
4135 }
4136
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004137 @Override
4138 public void stopAppSwitches() {
4139 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
4140 synchronized (mGlobalLock) {
4141 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME;
4142 mDidAppSwitch = false;
4143 getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
4144 }
4145 }
4146
4147 @Override
4148 public void resumeAppSwitches() {
4149 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
4150 synchronized (mGlobalLock) {
4151 // Note that we don't execute any pending app switches... we will
4152 // let those wait until either the timeout, or the next start
4153 // activity request.
4154 mAppSwitchesAllowedTime = 0;
4155 }
4156 }
4157
4158 void onStartActivitySetDidAppSwitch() {
4159 if (mDidAppSwitch) {
4160 // This is the second allowed switch since we stopped switches, so now just generally
4161 // allow switches. Use case:
4162 // - user presses home (switches disabled, switch to home, mDidAppSwitch now true);
4163 // - user taps a home icon (coming from home so allowed, we hit here and now allow
4164 // anyone to switch again).
4165 mAppSwitchesAllowedTime = 0;
4166 } else {
4167 mDidAppSwitch = true;
4168 }
4169 }
4170
4171 /** @return whether the system should disable UI modes incompatible with VR mode. */
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004172 boolean shouldDisableNonVrUiLocked() {
4173 return mVrController.shouldDisableNonVrUiLocked();
4174 }
4175
Wale Ogunwale53783742018-09-16 10:21:51 -07004176 private void applyUpdateVrModeLocked(ActivityRecord r) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004177 // VR apps are expected to run in a main display. If an app is turning on VR for
4178 // itself, but lives in a dynamic stack, then make sure that it is moved to the main
4179 // fullscreen stack before enabling VR Mode.
4180 // TODO: The goal of this code is to keep the VR app on the main display. When the
4181 // stack implementation changes in the future, keep in mind that the use of the fullscreen
4182 // stack is a means to move the activity to the main display and a moveActivityToDisplay()
4183 // option would be a better choice here.
4184 if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
4185 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
4186 + " to main stack for VR");
4187 final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
4188 WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
4189 moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
4190 }
4191 mH.post(() -> {
4192 if (!mVrController.onVrModeChanged(r)) {
4193 return;
4194 }
4195 synchronized (mGlobalLock) {
4196 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
4197 mWindowManager.disableNonVrUi(disableNonVrUi);
4198 if (disableNonVrUi) {
4199 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
4200 // then remove the pinned stack.
4201 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
4202 }
4203 }
4204 });
4205 }
4206
Wale Ogunwale53783742018-09-16 10:21:51 -07004207 @Override
4208 public int getPackageScreenCompatMode(String packageName) {
4209 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4210 synchronized (mGlobalLock) {
4211 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4212 }
4213 }
4214
4215 @Override
4216 public void setPackageScreenCompatMode(String packageName, int mode) {
4217 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4218 "setPackageScreenCompatMode");
4219 synchronized (mGlobalLock) {
4220 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4221 }
4222 }
4223
4224 @Override
4225 public boolean getPackageAskScreenCompat(String packageName) {
4226 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4227 synchronized (mGlobalLock) {
4228 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4229 }
4230 }
4231
4232 @Override
4233 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4234 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4235 "setPackageAskScreenCompat");
4236 synchronized (mGlobalLock) {
4237 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4238 }
4239 }
4240
Andrii Kulian5f750bc2018-07-17 08:57:23 -07004241 ActivityStack getTopDisplayFocusedStack() {
4242 return mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004243 }
4244
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004245 /** Pokes the task persister. */
4246 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
4247 mRecentTasks.notifyTaskPersisterLocked(task, flush);
4248 }
4249
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004250 void onTopProcChangedLocked(WindowProcessController proc) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004251 mVrController.onTopProcChangedLocked(proc);
4252 }
4253
4254 boolean isKeyguardLocked() {
4255 return mKeyguardController.isKeyguardLocked();
4256 }
4257
4258 boolean isNextTransitionForward() {
4259 int transit = mWindowManager.getPendingAppTransition();
4260 return transit == TRANSIT_ACTIVITY_OPEN
4261 || transit == TRANSIT_TASK_OPEN
4262 || transit == TRANSIT_TASK_TO_FRONT;
4263 }
4264
Wale Ogunwalef6733932018-06-27 05:14:34 -07004265 void dumpSleepStates(PrintWriter pw, boolean testPssMode) {
4266 synchronized (mGlobalLock) {
4267 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
4268 if (mRunningVoice != null) {
4269 pw.println(" mRunningVoice=" + mRunningVoice);
4270 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
4271 }
4272 pw.println(" mSleeping=" + mSleeping);
4273 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + testPssMode);
4274 pw.println(" mVrController=" + mVrController);
4275 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004276 }
4277
Wale Ogunwalef6733932018-06-27 05:14:34 -07004278 void writeSleepStateToProto(ProtoOutputStream proto) {
4279 for (ActivityTaskManagerInternal.SleepToken st : mStackSupervisor.mSleepTokens) {
4280 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS,
4281 st.toString());
4282 }
4283
4284 if (mRunningVoice != null) {
4285 final long vrToken = proto.start(
4286 ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
4287 proto.write(ActivityManagerServiceDumpProcessesProto.Voice.SESSION,
4288 mRunningVoice.toString());
4289 mVoiceWakeLock.writeToProto(
4290 proto, ActivityManagerServiceDumpProcessesProto.Voice.WAKELOCK);
4291 proto.end(vrToken);
4292 }
4293
4294 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
4295 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN,
4296 mShuttingDown);
4297 mVrController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004298 }
4299
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004300 int getCurrentUserId() {
4301 return mAmInternal.getCurrentUserId();
4302 }
4303
4304 private void enforceNotIsolatedCaller(String caller) {
4305 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4306 throw new SecurityException("Isolated process not allowed to call " + caller);
4307 }
4308 }
4309
Wale Ogunwalef6733932018-06-27 05:14:34 -07004310 public Configuration getConfiguration() {
4311 Configuration ci;
4312 synchronized(mGlobalLock) {
Yunfan Chen75157d72018-07-27 14:47:21 +09004313 ci = new Configuration(getGlobalConfigurationForCallingPid());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004314 ci.userSetLocale = false;
4315 }
4316 return ci;
4317 }
4318
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004319 /**
4320 * Current global configuration information. Contains general settings for the entire system,
4321 * also corresponds to the merged configuration of the default display.
4322 */
4323 Configuration getGlobalConfiguration() {
4324 return mStackSupervisor.getConfiguration();
4325 }
4326
4327 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4328 boolean initLocale) {
4329 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
4330 }
4331
4332 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4333 boolean initLocale, boolean deferResume) {
4334 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
4335 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
4336 UserHandle.USER_NULL, deferResume);
4337 }
4338
4339 void updatePersistentConfiguration(Configuration values, @UserIdInt int userId) {
4340 final long origId = Binder.clearCallingIdentity();
4341 try {
4342 synchronized (mGlobalLock) {
4343 updateConfigurationLocked(values, null, false, true, userId,
4344 false /* deferResume */);
4345 }
4346 } finally {
4347 Binder.restoreCallingIdentity(origId);
4348 }
4349 }
4350
4351 void updateUserConfiguration() {
4352 synchronized (mGlobalLock) {
4353 final Configuration configuration = new Configuration(getGlobalConfiguration());
4354 final int currentUserId = mAmInternal.getCurrentUserId();
4355 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
4356 currentUserId, Settings.System.canWrite(mContext));
4357 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
4358 false /* persistent */, currentUserId, false /* deferResume */);
4359 }
4360 }
4361
4362 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4363 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
4364 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
4365 deferResume, null /* result */);
4366 }
4367
4368 /**
4369 * Do either or both things: (1) change the current configuration, and (2)
4370 * make sure the given activity is running with the (now) current
4371 * configuration. Returns true if the activity has been left running, or
4372 * false if <var>starting</var> is being destroyed to match the new
4373 * configuration.
4374 *
4375 * @param userId is only used when persistent parameter is set to true to persist configuration
4376 * for that particular user
4377 */
4378 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4379 boolean initLocale, boolean persistent, int userId, boolean deferResume,
4380 ActivityTaskManagerService.UpdateConfigurationResult result) {
4381 int changes = 0;
4382 boolean kept = true;
4383
4384 if (mWindowManager != null) {
4385 mWindowManager.deferSurfaceLayout();
4386 }
4387 try {
4388 if (values != null) {
4389 changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
4390 deferResume);
4391 }
4392
4393 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4394 } finally {
4395 if (mWindowManager != null) {
4396 mWindowManager.continueSurfaceLayout();
4397 }
4398 }
4399
4400 if (result != null) {
4401 result.changes = changes;
4402 result.activityRelaunched = !kept;
4403 }
4404 return kept;
4405 }
4406
4407 /**
4408 * Returns true if this configuration change is interesting enough to send an
4409 * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
4410 */
4411 private static boolean isSplitConfigurationChange(int configDiff) {
4412 return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
4413 }
4414
4415 /** Update default (global) configuration and notify listeners about changes. */
4416 private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
4417 boolean persistent, int userId, boolean deferResume) {
4418 mTempConfig.setTo(getGlobalConfiguration());
4419 final int changes = mTempConfig.updateFrom(values);
4420 if (changes == 0) {
4421 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
4422 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
4423 // performDisplayOverrideConfigUpdate in order to send the new display configuration
4424 // (even if there are no actual changes) to unfreeze the window.
4425 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
4426 return 0;
4427 }
4428
4429 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
4430 "Updating global configuration to: " + values);
4431
4432 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
4433 StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
4434 values.colorMode,
4435 values.densityDpi,
4436 values.fontScale,
4437 values.hardKeyboardHidden,
4438 values.keyboard,
4439 values.keyboardHidden,
4440 values.mcc,
4441 values.mnc,
4442 values.navigation,
4443 values.navigationHidden,
4444 values.orientation,
4445 values.screenHeightDp,
4446 values.screenLayout,
4447 values.screenWidthDp,
4448 values.smallestScreenWidthDp,
4449 values.touchscreen,
4450 values.uiMode);
4451
4452
4453 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
4454 final LocaleList locales = values.getLocales();
4455 int bestLocaleIndex = 0;
4456 if (locales.size() > 1) {
4457 if (mSupportedSystemLocales == null) {
4458 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
4459 }
4460 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
4461 }
4462 SystemProperties.set("persist.sys.locale",
4463 locales.get(bestLocaleIndex).toLanguageTag());
4464 LocaleList.setDefault(locales, bestLocaleIndex);
4465 mAm.mHandler.sendMessage(mAm.mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
4466 locales.get(bestLocaleIndex)));
4467 }
4468
Yunfan Chen75157d72018-07-27 14:47:21 +09004469 mTempConfig.seq = increaseConfigurationSeqLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004470
4471 // Update stored global config and notify everyone about the change.
4472 mStackSupervisor.onConfigurationChanged(mTempConfig);
4473
4474 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
4475 // TODO(multi-display): Update UsageEvents#Event to include displayId.
4476 mAm.mUsageStatsService.reportConfigurationChange(
4477 mTempConfig, mAmInternal.getCurrentUserId());
4478
4479 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
Wale Ogunwalef6733932018-06-27 05:14:34 -07004480 updateShouldShowDialogsLocked(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004481
4482 AttributeCache ac = AttributeCache.instance();
4483 if (ac != null) {
4484 ac.updateConfiguration(mTempConfig);
4485 }
4486
4487 // Make sure all resources in our process are updated right now, so that anyone who is going
4488 // to retrieve resource values after we return will be sure to get the new ones. This is
4489 // especially important during boot, where the first config change needs to guarantee all
4490 // resources have that config before following boot code is executed.
4491 mAm.mSystemThread.applyConfigurationToResources(mTempConfig);
4492
4493 // We need another copy of global config because we're scheduling some calls instead of
4494 // running them in place. We need to be sure that object we send will be handled unchanged.
4495 final Configuration configCopy = new Configuration(mTempConfig);
4496 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
4497 Message msg = mAm.mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
4498 msg.obj = configCopy;
4499 msg.arg1 = userId;
4500 mAm.mHandler.sendMessage(msg);
4501 }
4502
Yunfan Chen75157d72018-07-27 14:47:21 +09004503 // TODO: Consider using mPidMap to update configurations for processes.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004504 for (int i = mAm.mLruProcesses.size() - 1; i >= 0; i--) {
4505 ProcessRecord app = mAm.mLruProcesses.get(i);
4506 try {
4507 if (app.thread != null) {
4508 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
4509 + app.processName + " new config " + configCopy);
4510 getLifecycleManager().scheduleTransaction(app.thread,
4511 ConfigurationChangeItem.obtain(configCopy));
4512 }
4513 } catch (Exception e) {
4514 Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
4515 }
4516 }
4517
4518 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
4519 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
4520 | Intent.FLAG_RECEIVER_FOREGROUND
4521 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4522 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4523 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4524 UserHandle.USER_ALL);
4525 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
4526 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
4527 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
4528 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
4529 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4530 if (initLocale || !mAm.mProcessesReady) {
4531 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
4532 }
4533 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4534 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4535 UserHandle.USER_ALL);
4536 }
4537
4538 // Send a broadcast to PackageInstallers if the configuration change is interesting
4539 // for the purposes of installing additional splits.
4540 if (!initLocale && isSplitConfigurationChange(changes)) {
4541 intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
4542 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
4543 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
4544
4545 // Typically only app stores will have this permission.
4546 String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES };
4547 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions,
4548 OP_NONE, null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
4549 }
4550
4551 // Override configuration of the default display duplicates global config, so we need to
4552 // update it also. This will also notify WindowManager about changes.
4553 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
4554 DEFAULT_DISPLAY);
4555
4556 return changes;
4557 }
4558
4559 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
4560 boolean deferResume, int displayId) {
4561 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
4562 displayId, null /* result */);
4563 }
4564
4565 /**
4566 * Updates override configuration specific for the selected display. If no config is provided,
4567 * new one will be computed in WM based on current display info.
4568 */
4569 boolean updateDisplayOverrideConfigurationLocked(Configuration values,
4570 ActivityRecord starting, boolean deferResume, int displayId,
4571 ActivityTaskManagerService.UpdateConfigurationResult result) {
4572 int changes = 0;
4573 boolean kept = true;
4574
4575 if (mWindowManager != null) {
4576 mWindowManager.deferSurfaceLayout();
4577 }
4578 try {
4579 if (values != null) {
4580 if (displayId == DEFAULT_DISPLAY) {
4581 // Override configuration of the default display duplicates global config, so
4582 // we're calling global config update instead for default display. It will also
4583 // apply the correct override config.
4584 changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
4585 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
4586 } else {
4587 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
4588 }
4589 }
4590
4591 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4592 } finally {
4593 if (mWindowManager != null) {
4594 mWindowManager.continueSurfaceLayout();
4595 }
4596 }
4597
4598 if (result != null) {
4599 result.changes = changes;
4600 result.activityRelaunched = !kept;
4601 }
4602 return kept;
4603 }
4604
4605 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
4606 int displayId) {
4607 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
4608 final int changes = mTempConfig.updateFrom(values);
4609 if (changes != 0) {
4610 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
4611 + mTempConfig + " for displayId=" + displayId);
4612 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
4613
4614 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
4615 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004616 mAppWarnings.onDensityChanged();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004617
4618 mAm.killAllBackgroundProcessesExcept(N,
4619 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
4620 }
4621 }
4622
4623 // Update the configuration with WM first and check if any of the stacks need to be resized
4624 // due to the configuration change. If so, resize the stacks now and do any relaunches if
4625 // necessary. This way we don't need to relaunch again afterwards in
4626 // ensureActivityConfiguration().
4627 if (mWindowManager != null) {
4628 final int[] resizedStacks =
4629 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
4630 if (resizedStacks != null) {
4631 for (int stackId : resizedStacks) {
4632 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
4633 }
4634 }
4635 }
4636
4637 return changes;
4638 }
4639
Wale Ogunwalef6733932018-06-27 05:14:34 -07004640 private void updateEventDispatchingLocked(boolean booted) {
4641 mWindowManager.setEventDispatching(booted && !mShuttingDown);
4642 }
4643
4644 void enableScreenAfterBoot(boolean booted) {
4645 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4646 SystemClock.uptimeMillis());
4647 mWindowManager.enableScreenAfterBoot();
4648
4649 synchronized (mGlobalLock) {
4650 updateEventDispatchingLocked(booted);
4651 }
4652 }
4653
4654 boolean canShowErrorDialogs() {
4655 return mShowDialogs && !mSleeping && !mShuttingDown
4656 && !mKeyguardController.isKeyguardOrAodShowing(DEFAULT_DISPLAY)
4657 && !hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
Wale Ogunwale86b74462018-07-02 08:42:43 -07004658 mAmInternal.getCurrentUserId())
Wale Ogunwalef6733932018-06-27 05:14:34 -07004659 && !(UserManager.isDeviceInDemoMode(mContext)
Wale Ogunwale86b74462018-07-02 08:42:43 -07004660 && mAmInternal.getCurrentUser().isDemo());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004661 }
4662
Wale Ogunwale906f9c62018-07-23 11:23:44 -07004663 static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
4664 if (r == null || !r.hasProcess()) {
4665 return KEY_DISPATCHING_TIMEOUT_MS;
4666 }
4667 return getInputDispatchingTimeoutLocked(r.app);
4668 }
4669
4670 private static long getInputDispatchingTimeoutLocked(WindowProcessController r) {
4671 if (r != null && (r.isInstrumenting() || r.isUsingWrapper())) {
4672 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS;
4673 }
4674 return KEY_DISPATCHING_TIMEOUT_MS;
4675 }
4676
4677 long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
4678 if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
4679 throw new SecurityException("Requires permission " + FILTER_EVENTS);
4680 }
4681 WindowProcessController proc;
4682 long timeout;
4683 synchronized (mGlobalLock) {
4684 proc = mPidMap.get(pid);
4685 timeout = getInputDispatchingTimeoutLocked(proc);
4686 }
4687
4688 if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
4689 return -1;
4690 }
4691
4692 return timeout;
4693 }
4694
4695 /**
4696 * Handle input dispatching timeouts.
4697 * Returns whether input dispatching should be aborted or not.
4698 */
4699 boolean inputDispatchingTimedOut(final WindowProcessController proc,
4700 final ActivityRecord activity, final ActivityRecord parent,
4701 final boolean aboveSystem, String reason) {
4702 if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
4703 throw new SecurityException("Requires permission " + FILTER_EVENTS);
4704 }
4705
4706 final String annotation;
4707 if (reason == null) {
4708 annotation = "Input dispatching timed out";
4709 } else {
4710 annotation = "Input dispatching timed out (" + reason + ")";
4711 }
4712
4713 if (proc != null) {
4714 synchronized (mGlobalLock) {
4715 if (proc.isDebugging()) {
4716 return false;
4717 }
4718
4719 if (proc.isInstrumenting()) {
4720 Bundle info = new Bundle();
4721 info.putString("shortMsg", "keyDispatchingTimedOut");
4722 info.putString("longMsg", annotation);
4723 mAm.finishInstrumentationLocked(
4724 (ProcessRecord) proc.mOwner, Activity.RESULT_CANCELED, info);
4725 return true;
4726 }
4727 }
4728 mH.post(() -> {
4729 mAm.mAppErrors.appNotResponding(
4730 (ProcessRecord) proc.mOwner, activity, parent, aboveSystem, annotation);
4731 });
4732 }
4733
4734 return true;
4735 }
4736
Wale Ogunwalef6733932018-06-27 05:14:34 -07004737 /**
4738 * Decide based on the configuration whether we should show the ANR,
4739 * crash, etc dialogs. The idea is that if there is no affordance to
4740 * press the on-screen buttons, or the user experience would be more
4741 * greatly impacted than the crash itself, we shouldn't show the dialog.
4742 *
4743 * A thought: SystemUI might also want to get told about this, the Power
4744 * dialog / global actions also might want different behaviors.
4745 */
4746 private void updateShouldShowDialogsLocked(Configuration config) {
4747 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
4748 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
4749 && config.navigation == Configuration.NAVIGATION_NONAV);
4750 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
4751 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
4752 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
4753 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
4754 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
4755 final boolean hideDialogsSet = Settings.Global.getInt(mContext.getContentResolver(),
4756 HIDE_ERROR_DIALOGS, 0) != 0;
4757 mShowDialogs = inputMethodExists && uiModeSupportsDialogs && !hideDialogsSet;
4758 }
4759
4760 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
4761 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
4762 FONT_SCALE, 1.0f, userId);
4763
4764 synchronized (this) {
4765 if (getGlobalConfiguration().fontScale == scaleFactor) {
4766 return;
4767 }
4768
4769 final Configuration configuration
4770 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
4771 configuration.fontScale = scaleFactor;
4772 updatePersistentConfiguration(configuration, userId);
4773 }
4774 }
4775
4776 // Actually is sleeping or shutting down or whatever else in the future
4777 // is an inactive state.
4778 boolean isSleepingOrShuttingDownLocked() {
4779 return isSleepingLocked() || mShuttingDown;
4780 }
4781
4782 boolean isSleepingLocked() {
4783 return mSleeping;
4784 }
4785
Riddle Hsu16567132018-08-16 21:37:47 +08004786 /** Update AMS states when an activity is resumed. */
Wale Ogunwalef6733932018-06-27 05:14:34 -07004787 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
4788 final TaskRecord task = r.getTask();
4789 if (task.isActivityTypeStandard()) {
4790 if (mCurAppTimeTracker != r.appTimeTracker) {
4791 // We are switching app tracking. Complete the current one.
4792 if (mCurAppTimeTracker != null) {
4793 mCurAppTimeTracker.stop();
4794 mH.obtainMessage(
4795 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
4796 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
4797 mCurAppTimeTracker = null;
4798 }
4799 if (r.appTimeTracker != null) {
4800 mCurAppTimeTracker = r.appTimeTracker;
4801 startTimeTrackingFocusedActivityLocked();
4802 }
4803 } else {
4804 startTimeTrackingFocusedActivityLocked();
4805 }
4806 } else {
4807 r.appTimeTracker = null;
4808 }
4809 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
4810 // TODO: Probably not, because we don't want to resume voice on switching
4811 // back to this activity
4812 if (task.voiceInteractor != null) {
4813 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
4814 } else {
4815 finishRunningVoiceLocked();
4816
4817 if (mLastResumedActivity != null) {
4818 final IVoiceInteractionSession session;
4819
4820 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
4821 if (lastResumedActivityTask != null
4822 && lastResumedActivityTask.voiceSession != null) {
4823 session = lastResumedActivityTask.voiceSession;
4824 } else {
4825 session = mLastResumedActivity.voiceSession;
4826 }
4827
4828 if (session != null) {
4829 // We had been in a voice interaction session, but now focused has
4830 // move to something different. Just finish the session, we can't
4831 // return to it and retain the proper state and synchronization with
4832 // the voice interaction service.
4833 finishVoiceTask(session);
4834 }
4835 }
4836 }
4837
4838 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
4839 mAmInternal.sendForegroundProfileChanged(r.userId);
4840 }
4841 updateResumedAppTrace(r);
4842 mLastResumedActivity = r;
4843
Riddle Hsu3026e8d2018-08-03 15:50:53 +08004844 // TODO(b/111361570): Support multiple focused apps in WM
Wale Ogunwalef6733932018-06-27 05:14:34 -07004845 mWindowManager.setFocusedApp(r.appToken, true);
4846
4847 applyUpdateLockStateLocked(r);
4848 applyUpdateVrModeLocked(r);
4849
4850 EventLogTags.writeAmSetResumedActivity(
4851 r == null ? -1 : r.userId,
4852 r == null ? "NULL" : r.shortComponentName,
4853 reason);
4854 }
4855
4856 ActivityTaskManagerInternal.SleepToken acquireSleepToken(String tag, int displayId) {
4857 synchronized (mGlobalLock) {
4858 final ActivityTaskManagerInternal.SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
4859 updateSleepIfNeededLocked();
4860 return token;
4861 }
4862 }
4863
4864 void updateSleepIfNeededLocked() {
4865 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
4866 final boolean wasSleeping = mSleeping;
4867 boolean updateOomAdj = false;
4868
4869 if (!shouldSleep) {
4870 // If wasSleeping is true, we need to wake up activity manager state from when
4871 // we started sleeping. In either case, we need to apply the sleep tokens, which
4872 // will wake up stacks or put them to sleep as appropriate.
4873 if (wasSleeping) {
4874 mSleeping = false;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07004875 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
4876 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__AWAKE);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004877 startTimeTrackingFocusedActivityLocked();
4878 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
4879 mStackSupervisor.comeOutOfSleepIfNeededLocked();
4880 }
4881 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
4882 if (wasSleeping) {
4883 updateOomAdj = true;
4884 }
4885 } else if (!mSleeping && shouldSleep) {
4886 mSleeping = true;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07004887 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
4888 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__ASLEEP);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004889 if (mCurAppTimeTracker != null) {
4890 mCurAppTimeTracker.stop();
4891 }
4892 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
4893 mStackSupervisor.goingToSleepLocked();
4894 updateResumedAppTrace(null /* resumed */);
4895 updateOomAdj = true;
4896 }
4897 if (updateOomAdj) {
4898 mH.post(mAmInternal::updateOomAdj);
4899 }
4900 }
4901
4902 void updateOomAdj() {
4903 mH.post(mAmInternal::updateOomAdj);
4904 }
4905
Wale Ogunwale53783742018-09-16 10:21:51 -07004906 void updateCpuStats() {
4907 mH.post(mAmInternal::updateCpuStats);
4908 }
4909
4910 void updateUsageStats(ActivityRecord component, boolean resumed) {
4911 final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::updateUsageStats,
4912 mAmInternal, component.realActivity, component.app.mUid, component.userId, resumed);
4913 mH.sendMessage(m);
4914 }
4915
4916 void setBooting(boolean booting) {
4917 mAmInternal.setBooting(booting);
4918 }
4919
4920 boolean isBooting() {
4921 return mAmInternal.isBooting();
4922 }
4923
4924 void setBooted(boolean booted) {
4925 mAmInternal.setBooted(booted);
4926 }
4927
4928 boolean isBooted() {
4929 return mAmInternal.isBooted();
4930 }
4931
4932 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
4933 mH.post(() -> {
4934 if (finishBooting) {
4935 mAmInternal.finishBooting();
4936 }
4937 if (enableScreen) {
4938 mInternal.enableScreenAfterBoot(isBooted());
4939 }
4940 });
4941 }
4942
4943 void setHeavyWeightProcess(ActivityRecord root) {
4944 mHeavyWeightProcess = root.app;
4945 final Message m = PooledLambda.obtainMessage(
4946 ActivityTaskManagerService::postHeavyWeightProcessNotification, this,
4947 root.app, root.intent, root.userId);
4948 mH.sendMessage(m);
4949 }
4950
4951 void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
4952 if (mHeavyWeightProcess == null || mHeavyWeightProcess != proc) {
4953 return;
4954 }
4955
4956 mHeavyWeightProcess = null;
4957 final Message m = PooledLambda.obtainMessage(
4958 ActivityTaskManagerService::cancelHeavyWeightProcessNotification, this,
4959 proc.mUserId);
4960 mH.sendMessage(m);
4961 }
4962
4963 private void cancelHeavyWeightProcessNotification(int userId) {
4964 final INotificationManager inm = NotificationManager.getService();
4965 if (inm == null) {
4966 return;
4967 }
4968 try {
4969 inm.cancelNotificationWithTag("android", null,
4970 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, userId);
4971 } catch (RuntimeException e) {
4972 Slog.w(TAG, "Error canceling notification for service", e);
4973 } catch (RemoteException e) {
4974 }
4975
4976 }
4977
4978 private void postHeavyWeightProcessNotification(
4979 WindowProcessController proc, Intent intent, int userId) {
4980 if (proc == null) {
4981 return;
4982 }
4983
4984 final INotificationManager inm = NotificationManager.getService();
4985 if (inm == null) {
4986 return;
4987 }
4988
4989 try {
4990 Context context = mContext.createPackageContext(proc.mInfo.packageName, 0);
4991 String text = mContext.getString(R.string.heavy_weight_notification,
4992 context.getApplicationInfo().loadLabel(context.getPackageManager()));
4993 Notification notification =
4994 new Notification.Builder(context,
4995 SystemNotificationChannels.HEAVY_WEIGHT_APP)
4996 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
4997 .setWhen(0)
4998 .setOngoing(true)
4999 .setTicker(text)
5000 .setColor(mContext.getColor(
5001 com.android.internal.R.color.system_notification_accent_color))
5002 .setContentTitle(text)
5003 .setContentText(
5004 mContext.getText(R.string.heavy_weight_notification_detail))
5005 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
5006 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
5007 new UserHandle(userId)))
5008 .build();
5009 try {
5010 inm.enqueueNotificationWithTag("android", "android", null,
5011 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, notification, userId);
5012 } catch (RuntimeException e) {
5013 Slog.w(TAG, "Error showing notification for heavy-weight app", e);
5014 } catch (RemoteException e) {
5015 }
5016 } catch (PackageManager.NameNotFoundException e) {
5017 Slog.w(TAG, "Unable to create context for heavy notification", e);
5018 }
5019
5020 }
5021
Andrii Kulian52d255c2018-07-13 11:32:19 -07005022 // TODO(b/111541062): Update app time tracking to make it aware of multiple resumed activities
Wale Ogunwalef6733932018-06-27 05:14:34 -07005023 private void startTimeTrackingFocusedActivityLocked() {
Andrii Kulian52d255c2018-07-13 11:32:19 -07005024 final ActivityRecord resumedActivity = mStackSupervisor.getTopResumedActivity();
Wale Ogunwalef6733932018-06-27 05:14:34 -07005025 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
5026 mCurAppTimeTracker.start(resumedActivity.packageName);
5027 }
5028 }
5029
5030 private void updateResumedAppTrace(@Nullable ActivityRecord resumed) {
5031 if (mTracedResumedActivity != null) {
5032 Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER,
5033 constructResumedTraceName(mTracedResumedActivity.packageName), 0);
5034 }
5035 if (resumed != null) {
5036 Trace.asyncTraceBegin(TRACE_TAG_ACTIVITY_MANAGER,
5037 constructResumedTraceName(resumed.packageName), 0);
5038 }
5039 mTracedResumedActivity = resumed;
5040 }
5041
5042 private String constructResumedTraceName(String packageName) {
5043 return "focused app: " + packageName;
5044 }
5045
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005046 /** Helper method that requests bounds from WM and applies them to stack. */
5047 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
5048 final Rect newStackBounds = new Rect();
5049 final ActivityStack stack = mStackSupervisor.getStack(stackId);
5050
5051 // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
5052 if (stack == null) {
5053 final StringWriter writer = new StringWriter();
5054 final PrintWriter printWriter = new PrintWriter(writer);
5055 mStackSupervisor.dumpDisplays(printWriter);
5056 printWriter.flush();
5057
5058 Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
5059 }
5060
5061 stack.getBoundsForNewConfiguration(newStackBounds);
5062 mStackSupervisor.resizeStackLocked(
5063 stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
5064 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
5065 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
5066 }
5067
5068 /** Applies latest configuration and/or visibility updates if needed. */
5069 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
5070 boolean kept = true;
Andrii Kulian5f750bc2018-07-17 08:57:23 -07005071 final ActivityStack mainStack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005072 // mainStack is null during startup.
5073 if (mainStack != null) {
5074 if (changes != 0 && starting == null) {
5075 // If the configuration changed, and the caller is not already
5076 // in the process of starting an activity, then find the top
5077 // activity to check if its configuration needs to change.
5078 starting = mainStack.topRunningActivityLocked();
5079 }
5080
5081 if (starting != null) {
5082 kept = starting.ensureActivityConfiguration(changes,
5083 false /* preserveWindow */);
5084 // And we need to make sure at this point that all other activities
5085 // are made visible with the correct configuration.
5086 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
5087 !PRESERVE_WINDOWS);
5088 }
5089 }
5090
5091 return kept;
5092 }
5093
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005094 void scheduleAppGcsLocked() {
5095 mH.post(() -> mAmInternal.scheduleAppGcs());
5096 }
5097
Wale Ogunwale53783742018-09-16 10:21:51 -07005098 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
5099 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
5100 }
5101
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005102 /**
5103 * Returns the PackageManager. Used by classes hosted by {@link ActivityTaskManagerService}. The
5104 * PackageManager could be unavailable at construction time and therefore needs to be accessed
5105 * on demand.
5106 */
5107 IPackageManager getPackageManager() {
5108 return AppGlobals.getPackageManager();
5109 }
5110
5111 PackageManagerInternal getPackageManagerInternalLocked() {
5112 if (mPmInternal == null) {
5113 mPmInternal = LocalServices.getService(PackageManagerInternal.class);
5114 }
5115 return mPmInternal;
5116 }
5117
Wale Ogunwale008163e2018-07-23 23:11:08 -07005118 AppWarnings getAppWarningsLocked() {
5119 return mAppWarnings;
5120 }
5121
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005122 void logAppTooSlow(WindowProcessController app, long startTime, String msg) {
5123 if (true || Build.IS_USER) {
5124 return;
5125 }
5126
5127 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5128 StrictMode.allowThreadDiskWrites();
5129 try {
5130 File tracesDir = new File("/data/anr");
5131 File tracesFile = null;
5132 try {
5133 tracesFile = File.createTempFile("app_slow", null, tracesDir);
5134
5135 StringBuilder sb = new StringBuilder();
5136 Time tobj = new Time();
5137 tobj.set(System.currentTimeMillis());
5138 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5139 sb.append(": ");
5140 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5141 sb.append(" since ");
5142 sb.append(msg);
5143 FileOutputStream fos = new FileOutputStream(tracesFile);
5144 fos.write(sb.toString().getBytes());
5145 if (app == null) {
5146 fos.write("\n*** No application process!".getBytes());
5147 }
5148 fos.close();
5149 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5150 } catch (IOException e) {
5151 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesFile, e);
5152 return;
5153 }
5154
5155 if (app != null && app.getPid() > 0) {
5156 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5157 firstPids.add(app.getPid());
5158 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, null, null);
5159 }
5160
5161 File lastTracesFile = null;
5162 File curTracesFile = null;
5163 for (int i=9; i>=0; i--) {
5164 String name = String.format(Locale.US, "slow%02d.txt", i);
5165 curTracesFile = new File(tracesDir, name);
5166 if (curTracesFile.exists()) {
5167 if (lastTracesFile != null) {
5168 curTracesFile.renameTo(lastTracesFile);
5169 } else {
5170 curTracesFile.delete();
5171 }
5172 }
5173 lastTracesFile = curTracesFile;
5174 }
5175 tracesFile.renameTo(curTracesFile);
5176 } finally {
5177 StrictMode.setThreadPolicy(oldPolicy);
5178 }
5179 }
5180
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005181 final class H extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005182 static final int REPORT_TIME_TRACKER_MSG = 1;
5183
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005184 public H(Looper looper) {
5185 super(looper, null, true);
5186 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005187
5188 @Override
5189 public void handleMessage(Message msg) {
5190 switch (msg.what) {
5191 case REPORT_TIME_TRACKER_MSG: {
5192 AppTimeTracker tracker = (AppTimeTracker) msg.obj;
5193 tracker.deliverResult(mContext);
5194 } break;
5195 }
5196 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005197 }
5198
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005199 final class UiHandler extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005200 static final int DISMISS_DIALOG_UI_MSG = 1;
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005201
5202 public UiHandler() {
5203 super(com.android.server.UiThread.get().getLooper(), null, true);
5204 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005205
5206 @Override
5207 public void handleMessage(Message msg) {
5208 switch (msg.what) {
5209 case DISMISS_DIALOG_UI_MSG: {
5210 final Dialog d = (Dialog) msg.obj;
5211 d.dismiss();
5212 break;
5213 }
5214 }
5215 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005216 }
5217
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005218 final class LocalService extends ActivityTaskManagerInternal {
5219 @Override
5220 public SleepToken acquireSleepToken(String tag, int displayId) {
5221 Preconditions.checkNotNull(tag);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005222 return ActivityTaskManagerService.this.acquireSleepToken(tag, displayId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005223 }
5224
5225 @Override
5226 public ComponentName getHomeActivityForUser(int userId) {
5227 synchronized (mGlobalLock) {
5228 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
5229 return homeActivity == null ? null : homeActivity.realActivity;
5230 }
5231 }
5232
5233 @Override
5234 public void onLocalVoiceInteractionStarted(IBinder activity,
5235 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
5236 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005237 onLocalVoiceInteractionStartedLocked(activity, voiceSession, voiceInteractor);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005238 }
5239 }
5240
5241 @Override
5242 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
5243 synchronized (mGlobalLock) {
5244 mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
5245 reasons, timestamp);
5246 }
5247 }
5248
5249 @Override
5250 public void notifyAppTransitionFinished() {
5251 synchronized (mGlobalLock) {
5252 mStackSupervisor.notifyAppTransitionDone();
5253 }
5254 }
5255
5256 @Override
5257 public void notifyAppTransitionCancelled() {
5258 synchronized (mGlobalLock) {
5259 mStackSupervisor.notifyAppTransitionDone();
5260 }
5261 }
5262
5263 @Override
5264 public List<IBinder> getTopVisibleActivities() {
5265 synchronized (mGlobalLock) {
5266 return mStackSupervisor.getTopVisibleActivities();
5267 }
5268 }
5269
5270 @Override
5271 public void notifyDockedStackMinimizedChanged(boolean minimized) {
5272 synchronized (mGlobalLock) {
5273 mStackSupervisor.setDockedStackMinimized(minimized);
5274 }
5275 }
5276
5277 @Override
5278 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
5279 Bundle bOptions) {
5280 Preconditions.checkNotNull(intents, "intents");
5281 final String[] resolvedTypes = new String[intents.length];
5282
5283 // UID of the package on user userId.
5284 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
5285 // packageUid may not be initialized.
5286 int packageUid = 0;
5287 final long ident = Binder.clearCallingIdentity();
5288
5289 try {
5290 for (int i = 0; i < intents.length; i++) {
5291 resolvedTypes[i] =
5292 intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
5293 }
5294
5295 packageUid = AppGlobals.getPackageManager().getPackageUid(
5296 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
5297 } catch (RemoteException e) {
5298 // Shouldn't happen.
5299 } finally {
5300 Binder.restoreCallingIdentity(ident);
5301 }
5302
5303 synchronized (mGlobalLock) {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07005304 return getActivityStartController().startActivitiesInPackage(
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005305 packageUid, packageName,
5306 intents, resolvedTypes, null /* resultTo */,
5307 SafeActivityOptions.fromBundle(bOptions), userId,
Michal Karpinski201bc0c2018-07-20 15:32:00 +01005308 false /* validateIncomingUser */, null /* originatingPendingIntent */);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005309 }
5310 }
5311
5312 @Override
5313 public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
5314 Intent intent, Bundle options, int userId) {
5315 return ActivityTaskManagerService.this.startActivityAsUser(
5316 caller, callerPacakge, intent,
5317 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
5318 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
5319 false /*validateIncomingUser*/);
5320 }
5321
5322 @Override
5323 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
5324 synchronized (mGlobalLock) {
5325
5326 // We might change the visibilities here, so prepare an empty app transition which
5327 // might be overridden later if we actually change visibilities.
5328 final boolean wasTransitionSet =
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005329 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005330 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005331 mWindowManager.prepareAppTransition(TRANSIT_NONE,
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005332 false /* alwaysKeepCurrent */);
5333 }
5334 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5335
5336 // If there was a transition set already we don't want to interfere with it as we
5337 // might be starting it too early.
5338 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005339 mWindowManager.executeAppTransition();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005340 }
5341 }
5342 if (callback != null) {
5343 callback.run();
5344 }
5345 }
5346
5347 @Override
5348 public void notifyKeyguardTrustedChanged() {
5349 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005350 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005351 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5352 }
5353 }
5354 }
5355
5356 /**
5357 * Called after virtual display Id is updated by
5358 * {@link com.android.server.vr.Vr2dDisplay} with a specific
5359 * {@param vrVr2dDisplayId}.
5360 */
5361 @Override
5362 public void setVr2dDisplayId(int vr2dDisplayId) {
5363 if (DEBUG_STACK) Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
5364 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005365 mVr2dDisplayId = vr2dDisplayId;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005366 }
5367 }
5368
5369 @Override
5370 public void setFocusedActivity(IBinder token) {
5371 synchronized (mGlobalLock) {
5372 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
5373 if (r == null) {
5374 throw new IllegalArgumentException(
5375 "setFocusedActivity: No activity record matching token=" + token);
5376 }
5377 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
5378 r, "setFocusedActivity")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08005379 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005380 }
5381 }
5382 }
5383
5384 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005385 public void registerScreenObserver(ScreenObserver observer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005386 mScreenObservers.add(observer);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005387 }
5388
5389 @Override
5390 public boolean isCallerRecents(int callingUid) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005391 return getRecentTasks().isCallerRecents(callingUid);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005392 }
5393
5394 @Override
5395 public boolean isRecentsComponentHomeActivity(int userId) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005396 return getRecentTasks().isRecentsComponentHomeActivity(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005397 }
5398
5399 @Override
5400 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
5401 ActivityTaskManagerService.this.cancelRecentsAnimation(restoreHomeStackPosition);
5402 }
5403
5404 @Override
5405 public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005406 ActivityTaskManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005407 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005408
5409 @Override
5410 public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
5411 synchronized (mGlobalLock) {
5412 mActiveVoiceInteractionServiceComponent = component;
5413 }
5414 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005415
5416 @Override
5417 public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
5418 if (!mAmInternal.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
5419 return;
5420 }
5421 synchronized (mGlobalLock) {
5422 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
5423 if (types == null) {
5424 if (uid < 0) {
5425 return;
5426 }
5427 types = new ArrayMap<>();
5428 mAllowAppSwitchUids.put(userId, types);
5429 }
5430 if (uid < 0) {
5431 types.remove(type);
5432 } else {
5433 types.put(type, uid);
5434 }
5435 }
5436 }
5437
5438 @Override
5439 public void onUserStopped(int userId) {
5440 synchronized (mGlobalLock) {
5441 getRecentTasks().unloadUserDataFromMemoryLocked(userId);
5442 mAllowAppSwitchUids.remove(userId);
5443 }
5444 }
5445
5446 @Override
5447 public boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
5448 synchronized (mGlobalLock) {
5449 return ActivityTaskManagerService.this.isGetTasksAllowed(
5450 caller, callingPid, callingUid);
5451 }
5452 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005453
5454 @Override
5455 public void onProcessAdded(WindowProcessController proc) {
5456 synchronized (mGlobalLock) {
5457 mProcessNames.put(proc.mName, proc.mUid, proc);
5458 }
5459 }
5460
5461 @Override
5462 public void onProcessRemoved(String name, int uid) {
5463 synchronized (mGlobalLock) {
5464 mProcessNames.remove(name, uid);
5465 }
5466 }
5467
5468 @Override
5469 public void onCleanUpApplicationRecord(WindowProcessController proc) {
5470 synchronized (mGlobalLock) {
5471 if (proc == mHomeProcess) {
5472 mHomeProcess = null;
5473 }
5474 if (proc == mPreviousProcess) {
5475 mPreviousProcess = null;
5476 }
5477 }
5478 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005479
5480 @Override
5481 public int getTopProcessState() {
5482 synchronized (mGlobalLock) {
5483 return mTopProcessState;
5484 }
5485 }
5486
5487 @Override
Wale Ogunwale53783742018-09-16 10:21:51 -07005488 public boolean isHeavyWeightProcess(WindowProcessController proc) {
5489 synchronized (mGlobalLock) {
5490 return proc == mHeavyWeightProcess;
5491 }
5492 }
5493
5494 @Override
5495 public void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
5496 synchronized (mGlobalLock) {
5497 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(proc);
5498 }
5499 }
5500
5501 @Override
5502 public void finishHeavyWeightApp() {
5503 synchronized (mGlobalLock) {
5504 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(
5505 mHeavyWeightProcess);
5506 }
5507 }
5508
5509 @Override
Wale Ogunwalef6733932018-06-27 05:14:34 -07005510 public boolean isSleeping() {
5511 synchronized (mGlobalLock) {
5512 return isSleepingLocked();
5513 }
5514 }
5515
5516 @Override
5517 public boolean isShuttingDown() {
5518 synchronized (mGlobalLock) {
5519 return mShuttingDown;
5520 }
5521 }
5522
5523 @Override
5524 public boolean shuttingDown(boolean booted, int timeout) {
5525 synchronized (mGlobalLock) {
5526 mShuttingDown = true;
5527 mStackSupervisor.prepareForShutdownLocked();
5528 updateEventDispatchingLocked(booted);
5529 return mStackSupervisor.shutdownLocked(timeout);
5530 }
5531 }
5532
5533 @Override
5534 public void enableScreenAfterBoot(boolean booted) {
5535 synchronized (mGlobalLock) {
5536 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5537 SystemClock.uptimeMillis());
5538 mWindowManager.enableScreenAfterBoot();
5539 updateEventDispatchingLocked(booted);
5540 }
5541 }
5542
5543 @Override
5544 public boolean showStrictModeViolationDialog() {
5545 synchronized (mGlobalLock) {
5546 return mShowDialogs && !mSleeping && !mShuttingDown;
5547 }
5548 }
5549
5550 @Override
5551 public void showSystemReadyErrorDialogsIfNeeded() {
5552 synchronized (mGlobalLock) {
5553 try {
5554 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
5555 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
5556 + " data partition or your device will be unstable.");
5557 mUiHandler.post(() -> {
5558 if (mShowDialogs) {
5559 AlertDialog d = new BaseErrorDialog(mUiContext);
5560 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5561 d.setCancelable(false);
5562 d.setTitle(mUiContext.getText(R.string.android_system_label));
5563 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
5564 d.setButton(DialogInterface.BUTTON_POSITIVE,
5565 mUiContext.getText(R.string.ok),
5566 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5567 d.show();
5568 }
5569 });
5570 }
5571 } catch (RemoteException e) {
5572 }
5573
5574 if (!Build.isBuildConsistent()) {
5575 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
5576 mUiHandler.post(() -> {
5577 if (mShowDialogs) {
5578 AlertDialog d = new BaseErrorDialog(mUiContext);
5579 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5580 d.setCancelable(false);
5581 d.setTitle(mUiContext.getText(R.string.android_system_label));
5582 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
5583 d.setButton(DialogInterface.BUTTON_POSITIVE,
5584 mUiContext.getText(R.string.ok),
5585 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5586 d.show();
5587 }
5588 });
5589 }
5590 }
5591 }
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005592
5593 @Override
5594 public long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason) {
5595 synchronized (mGlobalLock) {
5596 return ActivityTaskManagerService.this.inputDispatchingTimedOut(
5597 pid, aboveSystem, reason);
5598 }
5599 }
5600
5601 @Override
5602 public void onProcessMapped(int pid, WindowProcessController proc) {
5603 synchronized (mGlobalLock) {
5604 mPidMap.put(pid, proc);
5605 }
5606 }
5607
5608 @Override
5609 public void onProcessUnMapped(int pid) {
5610 synchronized (mGlobalLock) {
5611 mPidMap.remove(pid);
5612 }
5613 }
Wale Ogunwale008163e2018-07-23 23:11:08 -07005614
5615 @Override
5616 public void onPackageDataCleared(String name) {
5617 synchronized (mGlobalLock) {
Wale Ogunwale53783742018-09-16 10:21:51 -07005618 mCompatModePackages.handlePackageDataClearedLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07005619 mAppWarnings.onPackageDataCleared(name);
5620 }
5621 }
5622
5623 @Override
5624 public void onPackageUninstalled(String name) {
5625 synchronized (mGlobalLock) {
5626 mAppWarnings.onPackageUninstalled(name);
Wale Ogunwale53783742018-09-16 10:21:51 -07005627 mCompatModePackages.handlePackageUninstalledLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07005628 }
5629 }
Wale Ogunwale53783742018-09-16 10:21:51 -07005630
5631 @Override
5632 public void onPackageAdded(String name, boolean replacing) {
5633 synchronized (mGlobalLock) {
5634 mCompatModePackages.handlePackageAddedLocked(name, replacing);
5635 }
5636 }
5637
5638 @Override
5639 public CompatibilityInfo compatibilityInfoForPackage(ApplicationInfo ai) {
5640 synchronized (mGlobalLock) {
5641 return compatibilityInfoForPackageLocked(ai);
5642 }
5643 }
5644
Yunfan Chen75157d72018-07-27 14:47:21 +09005645 /**
5646 * Set the corresponding display information for the process global configuration. To be
5647 * called when we need to show IME on a different display.
5648 *
5649 * @param pid The process id associated with the IME window.
5650 * @param displayId The ID of the display showing the IME.
5651 */
5652 @Override
5653 public void onImeWindowSetOnDisplay(int pid, int displayId) {
5654 if (pid == MY_PID || pid < 0) {
5655 if (DEBUG_CONFIGURATION) {
5656 Slog.w(TAG,
5657 "Trying to update display configuration for system/invalid process.");
5658 }
5659 return;
5660 }
5661 mH.post(() -> {
5662 synchronized (mGlobalLock) {
5663 // Check if display is initialized in AM.
5664 if (!mStackSupervisor.isDisplayAdded(displayId)) {
5665 // Call come when display is not yet added or has already been removed.
5666 if (DEBUG_CONFIGURATION) {
5667 Slog.w(TAG, "Trying to update display configuration for non-existing "
5668 + "displayId=" + displayId);
5669 }
5670 return;
5671 }
5672 final WindowProcessController imeProcess = mPidMap.get(pid);
5673 if (imeProcess == null) {
5674 if (DEBUG_CONFIGURATION) {
5675 Slog.w(TAG, "Trying to update display configuration for invalid pid: "
5676 + pid);
5677 }
5678 return;
5679 }
5680 // Fetch the current override configuration of the display and set it to the
5681 // process global configuration.
5682 imeProcess.onConfigurationChanged(
5683 mStackSupervisor.getDisplayOverrideConfiguration(displayId));
5684 }
5685 });
5686 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005687 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07005688}