blob: fa7f0cbeefd77131ea96bafbedb76f798470a58d [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;
Evan Rosky4505b352018-09-06 11:20:40 -0700152import android.content.pm.IPackageManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700153import android.content.pm.PackageManager;
Evan Rosky4505b352018-09-06 11:20:40 -0700154import android.content.pm.PackageManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700155import android.content.pm.ParceledListSlice;
156import android.content.pm.ResolveInfo;
Wale Ogunwale53783742018-09-16 10:21:51 -0700157import android.content.res.CompatibilityInfo;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700158import android.content.res.Configuration;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700159import android.content.res.Resources;
Evan Rosky4505b352018-09-06 11:20:40 -0700160import android.database.ContentObserver;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700161import android.graphics.Bitmap;
162import android.graphics.Point;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700163import android.graphics.Rect;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700164import android.metrics.LogMaker;
165import android.net.Uri;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700166import android.os.Binder;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700167import android.os.Build;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700168import android.os.Bundle;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700169import android.os.FileUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700170import android.os.Handler;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700171import android.os.IBinder;
Evan Rosky4505b352018-09-06 11:20:40 -0700172import android.os.IUserManager;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700173import android.os.LocaleList;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700174import android.os.Looper;
175import android.os.Message;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700176import android.os.PersistableBundle;
Evan Rosky4505b352018-09-06 11:20:40 -0700177import android.os.PowerManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700178import android.os.RemoteException;
Evan Rosky4505b352018-09-06 11:20:40 -0700179import android.os.ServiceManager;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700180import android.os.StrictMode;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700181import android.os.SystemClock;
182import android.os.SystemProperties;
Evan Rosky4505b352018-09-06 11:20:40 -0700183import android.os.Trace;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700184import android.os.UpdateLock;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700185import android.os.UserHandle;
Evan Rosky4505b352018-09-06 11:20:40 -0700186import android.os.UserManager;
187import android.os.WorkSource;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700188import android.provider.Settings;
189import android.service.voice.IVoiceInteractionSession;
190import android.service.voice.VoiceInteractionManagerInternal;
191import android.telecom.TelecomManager;
192import android.text.TextUtils;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700193import android.text.format.Time;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700194import android.util.ArrayMap;
195import android.util.EventLog;
196import android.util.Log;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700197import android.util.Slog;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700198import android.util.SparseArray;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700199import android.util.SparseIntArray;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700200import android.util.StatsLog;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700201import android.util.TimeUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700202import android.util.proto.ProtoOutputStream;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700203import android.view.IRecentsAnimationRunner;
204import android.view.RemoteAnimationAdapter;
205import android.view.RemoteAnimationDefinition;
Evan Rosky4505b352018-09-06 11:20:40 -0700206import android.view.WindowManager;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700207
Evan Rosky4505b352018-09-06 11:20:40 -0700208import com.android.internal.R;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700209import com.android.internal.annotations.VisibleForTesting;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700210import com.android.internal.app.AssistUtils;
Evan Rosky4505b352018-09-06 11:20:40 -0700211import com.android.internal.app.IAppOpsService;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700212import com.android.internal.app.IVoiceInteractor;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700213import com.android.internal.app.ProcessMap;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700214import com.android.internal.logging.MetricsLogger;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700215import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Wale Ogunwale53783742018-09-16 10:21:51 -0700216import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
217import com.android.internal.notification.SystemNotificationChannels;
Evan Rosky4505b352018-09-06 11:20:40 -0700218import com.android.internal.os.logging.MetricsLoggerWrapper;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700219import com.android.internal.policy.IKeyguardDismissCallback;
220import com.android.internal.policy.KeyguardDismissCallback;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700221import com.android.internal.util.Preconditions;
Wale Ogunwale53783742018-09-16 10:21:51 -0700222import com.android.internal.util.function.pooled.PooledLambda;
Evan Rosky4505b352018-09-06 11:20:40 -0700223import com.android.server.AppOpsService;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700224import com.android.server.AttributeCache;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700225import com.android.server.LocalServices;
226import com.android.server.SystemService;
Evan Rosky4505b352018-09-06 11:20:40 -0700227import com.android.server.SystemServiceManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700228import com.android.server.Watchdog;
Evan Rosky4505b352018-09-06 11:20:40 -0700229import com.android.server.pm.UserManagerService;
230import com.android.server.uri.UriGrantsManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700231import com.android.server.vr.VrManagerInternal;
Evan Rosky4505b352018-09-06 11:20:40 -0700232import com.android.server.wm.ActivityTaskManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700233import com.android.server.wm.PinnedStackWindowController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700234import com.android.server.wm.WindowManagerService;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700235
236import java.io.File;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700237import java.io.FileOutputStream;
238import java.io.IOException;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700239import java.io.PrintWriter;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700240import java.io.StringWriter;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700241import java.util.ArrayList;
242import java.util.List;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700243import java.util.Locale;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700244
245/**
246 * System service for managing activities and their containers (task, stacks, displays,... ).
247 *
248 * {@hide}
249 */
250public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
251 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityTaskManagerService" : TAG_AM;
252 private static final String TAG_STACK = TAG + POSTFIX_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700253 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
254 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
255 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
256 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
257 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700258 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700259
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700260 // How long we wait until we timeout on key dispatching.
261 private static final int KEY_DISPATCHING_TIMEOUT_MS = 5 * 1000;
262 // How long we wait until we timeout on key dispatching during instrumentation.
263 private static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS = 60 * 1000;
264
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700265 Context mContext;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700266 /**
267 * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
268 * change at runtime. Use mContext for non-UI purposes.
269 */
270 final Context mUiContext;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700271 H mH;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700272 UiHandler mUiHandler;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700273 ActivityManagerService mAm;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700274 ActivityManagerInternal mAmInternal;
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700275 UriGrantsManagerInternal mUgmInternal;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700276 private PackageManagerInternal mPmInternal;
Wale Ogunwale53783742018-09-16 10:21:51 -0700277 private ActivityTaskManagerInternal mInternal;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700278 /* Global service lock used by the package the owns this service. */
279 Object mGlobalLock;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700280 ActivityStackSupervisor mStackSupervisor;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700281 WindowManagerService mWindowManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700282 private UserManagerService mUserManager;
283 private AppOpsService mAppOpsService;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700284 /** All processes currently running that might have a window organized by name. */
285 final ProcessMap<WindowProcessController> mProcessNames = new ProcessMap<>();
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700286 /** All processes we currently have running mapped by pid */
287 final SparseArray<WindowProcessController> mPidMap = new SparseArray<>();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700288 /** This is the process holding what we currently consider to be the "home" activity. */
289 WindowProcessController mHomeProcess;
Wale Ogunwale53783742018-09-16 10:21:51 -0700290 /** The currently running heavy-weight process, if any. */
291 WindowProcessController mHeavyWeightProcess = null;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700292 /**
293 * This is the process holding the activity the user last visited that is in a different process
294 * from the one they are currently in.
295 */
296 WindowProcessController mPreviousProcess;
297 /** The time at which the previous process was last visible. */
298 long mPreviousProcessVisibleTime;
299
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700300 /** List of intents that were used to start the most recent tasks. */
301 private RecentTasks mRecentTasks;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700302 /** State of external calls telling us if the device is awake or asleep. */
303 private boolean mKeyguardShown = false;
304
305 // Wrapper around VoiceInteractionServiceManager
306 private AssistUtils mAssistUtils;
307
308 // VoiceInteraction session ID that changes for each new request except when
309 // being called for multi-window assist in a single session.
310 private int mViSessionId = 1000;
311
312 // How long to wait in getAssistContextExtras for the activity and foreground services
313 // to respond with the result.
314 private static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
315
316 // How long top wait when going through the modern assist (which doesn't need to block
317 // on getting this result before starting to launch its UI).
318 private static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
319
320 // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
321 private static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
322
323 private final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
324
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700325 // Keeps track of the active voice interaction service component, notified from
326 // VoiceInteractionManagerService
327 ComponentName mActiveVoiceInteractionServiceComponent;
328
329 private VrController mVrController;
330 KeyguardController mKeyguardController;
331 private final ClientLifecycleManager mLifecycleManager;
332 private TaskChangeNotificationController mTaskChangeNotificationController;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700333 /** The controller for all operations related to locktask. */
334 private LockTaskController mLockTaskController;
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700335 private ActivityStartController mActivityStartController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700336
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700337 boolean mSuppressResizeConfigChanges;
338
339 private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
340 new UpdateConfigurationResult();
341
342 static final class UpdateConfigurationResult {
343 // Configuration changes that were updated.
344 int changes;
345 // If the activity was relaunched to match the new configuration.
346 boolean activityRelaunched;
347
348 void reset() {
349 changes = 0;
350 activityRelaunched = false;
351 }
352 }
353
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700354 /** Current sequencing integer of the configuration, for skipping old configurations. */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700355 private int mConfigurationSeq;
356 // To cache the list of supported system locales
357 private String[] mSupportedSystemLocales = null;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700358
359 /**
360 * Temp object used when global and/or display override configuration is updated. It is also
361 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
362 * anyone...
363 */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700364 private Configuration mTempConfig = new Configuration();
365
Wale Ogunwalef6733932018-06-27 05:14:34 -0700366 /** Temporary to avoid allocations. */
367 final StringBuilder mStringBuilder = new StringBuilder(256);
368
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700369 // Amount of time after a call to stopAppSwitches() during which we will
370 // prevent further untrusted switches from happening.
371 private static final long APP_SWITCH_DELAY_TIME = 5 * 1000;
372
373 /**
374 * The time at which we will allow normal application switches again,
375 * after a call to {@link #stopAppSwitches()}.
376 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700377 private long mAppSwitchesAllowedTime;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700378 /**
379 * This is set to true after the first switch after mAppSwitchesAllowedTime
380 * is set; any switches after that will clear the time.
381 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700382 private boolean mDidAppSwitch;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700383
384 IActivityController mController = null;
385 boolean mControllerIsAMonkey = false;
386
387 /**
388 * Used to retain an update lock when the foreground activity is in
389 * immersive mode.
390 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700391 private final UpdateLock mUpdateLock = new UpdateLock("immersive");
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700392
393 /**
394 * Packages that are being allowed to perform unrestricted app switches. Mapping is
395 * User -> Type -> uid.
396 */
397 final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
398
399 /** The dimensions of the thumbnails in the Recents UI. */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700400 private int mThumbnailWidth;
401 private int mThumbnailHeight;
402 private float mFullscreenThumbnailScale;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700403
404 /**
405 * Flag that indicates if multi-window is enabled.
406 *
407 * For any particular form of multi-window to be enabled, generic multi-window must be enabled
408 * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
409 * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
410 * At least one of the forms of multi-window must be enabled in order for this flag to be
411 * initialized to 'true'.
412 *
413 * @see #mSupportsSplitScreenMultiWindow
414 * @see #mSupportsFreeformWindowManagement
415 * @see #mSupportsPictureInPicture
416 * @see #mSupportsMultiDisplay
417 */
418 boolean mSupportsMultiWindow;
419 boolean mSupportsSplitScreenMultiWindow;
420 boolean mSupportsFreeformWindowManagement;
421 boolean mSupportsPictureInPicture;
422 boolean mSupportsMultiDisplay;
423 boolean mForceResizableActivities;
424
425 final List<ActivityTaskManagerInternal.ScreenObserver> mScreenObservers = new ArrayList<>();
426
427 // VR Vr2d Display Id.
428 int mVr2dDisplayId = INVALID_DISPLAY;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700429
Wale Ogunwalef6733932018-06-27 05:14:34 -0700430 /**
431 * Set while we are wanting to sleep, to prevent any
432 * activities from being started/resumed.
433 *
434 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
435 *
436 * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
437 * while in the sleep state until there is a pending transition out of sleep, in which case
438 * mSleeping is set to false, and remains false while awake.
439 *
440 * Whether mSleeping can quickly toggled between true/false without the device actually
441 * display changing states is undefined.
442 */
443 private boolean mSleeping = false;
444
445 /**
446 * The process state used for processes that are running the top activities.
447 * This changes between TOP and TOP_SLEEPING to following mSleeping.
448 */
449 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
450
451 // Whether we should show our dialogs (ANR, crash, etc) or just perform their default action
452 // automatically. Important for devices without direct input devices.
453 private boolean mShowDialogs = true;
454
455 /** Set if we are shutting down the system, similar to sleeping. */
456 boolean mShuttingDown = false;
457
458 /**
459 * We want to hold a wake lock while running a voice interaction session, since
460 * this may happen with the screen off and we need to keep the CPU running to
461 * be able to continue to interact with the user.
462 */
463 PowerManager.WakeLock mVoiceWakeLock;
464
465 /**
466 * Set while we are running a voice interaction. This overrides sleeping while it is active.
467 */
468 IVoiceInteractionSession mRunningVoice;
469
470 /**
471 * The last resumed activity. This is identical to the current resumed activity most
472 * of the time but could be different when we're pausing one activity before we resume
473 * another activity.
474 */
475 ActivityRecord mLastResumedActivity;
476
477 /**
478 * The activity that is currently being traced as the active resumed activity.
479 *
480 * @see #updateResumedAppTrace
481 */
482 private @Nullable ActivityRecord mTracedResumedActivity;
483
484 /** If non-null, we are tracking the time the user spends in the currently focused app. */
485 AppTimeTracker mCurAppTimeTracker;
486
Wale Ogunwale008163e2018-07-23 23:11:08 -0700487 private AppWarnings mAppWarnings;
488
Wale Ogunwale53783742018-09-16 10:21:51 -0700489 /**
490 * Packages that the user has asked to have run in screen size
491 * compatibility mode instead of filling the screen.
492 */
493 CompatModePackages mCompatModePackages;
494
Wale Ogunwalef6733932018-06-27 05:14:34 -0700495 private FontScaleSettingObserver mFontScaleSettingObserver;
496
497 private final class FontScaleSettingObserver extends ContentObserver {
498 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
499 private final Uri mHideErrorDialogsUri = Settings.Global.getUriFor(HIDE_ERROR_DIALOGS);
500
501 public FontScaleSettingObserver() {
502 super(mH);
503 final ContentResolver resolver = mContext.getContentResolver();
504 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
505 resolver.registerContentObserver(mHideErrorDialogsUri, false, this,
506 UserHandle.USER_ALL);
507 }
508
509 @Override
510 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
511 if (mFontScaleUri.equals(uri)) {
512 updateFontScaleIfNeeded(userId);
513 } else if (mHideErrorDialogsUri.equals(uri)) {
514 synchronized (mGlobalLock) {
515 updateShouldShowDialogsLocked(getGlobalConfiguration());
516 }
517 }
518 }
519 }
520
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700521 ActivityTaskManagerService(Context context) {
522 mContext = context;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700523 mUiContext = ActivityThread.currentActivityThread().getSystemUiContext();
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700524 mLifecycleManager = new ClientLifecycleManager();
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700525 }
526
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700527 void onSystemReady() {
528 mAssistUtils = new AssistUtils(mContext);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700529 mVrController.onSystemReady();
530 mRecentTasks.onSystemReadyLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700531 }
532
Wale Ogunwalef6733932018-06-27 05:14:34 -0700533 void onInitPowerManagement() {
534 mStackSupervisor.initPowerManagement();
535 final PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
536 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
537 mVoiceWakeLock.setReferenceCounted(false);
538 }
539
540 void installSystemProviders() {
541 mFontScaleSettingObserver = new FontScaleSettingObserver();
542 }
543
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700544 void retrieveSettings(ContentResolver resolver) {
545 final boolean freeformWindowManagement =
546 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
547 || Settings.Global.getInt(
548 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
549
550 final boolean supportsMultiWindow = ActivityTaskManager.supportsMultiWindow(mContext);
551 final boolean supportsPictureInPicture = supportsMultiWindow &&
552 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
553 final boolean supportsSplitScreenMultiWindow =
554 ActivityTaskManager.supportsSplitScreenMultiWindow(mContext);
555 final boolean supportsMultiDisplay = mContext.getPackageManager()
556 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
557 final boolean alwaysFinishActivities =
558 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
559 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
560 final boolean forceResizable = Settings.Global.getInt(
561 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
Garfield Tane0846042018-07-26 13:42:04 -0700562 final boolean isPc = mContext.getPackageManager().hasSystemFeature(FEATURE_PC);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700563
564 // Transfer any global setting for forcing RTL layout, into a System Property
565 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
566
567 final Configuration configuration = new Configuration();
568 Settings.System.getConfiguration(resolver, configuration);
569 if (forceRtl) {
570 // This will take care of setting the correct layout direction flags
571 configuration.setLayoutDirection(configuration.locale);
572 }
573
574 synchronized (mGlobalLock) {
575 mForceResizableActivities = forceResizable;
576 final boolean multiWindowFormEnabled = freeformWindowManagement
577 || supportsSplitScreenMultiWindow
578 || supportsPictureInPicture
579 || supportsMultiDisplay;
580 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
581 mSupportsMultiWindow = true;
582 mSupportsFreeformWindowManagement = freeformWindowManagement;
583 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
584 mSupportsPictureInPicture = supportsPictureInPicture;
585 mSupportsMultiDisplay = supportsMultiDisplay;
586 } else {
587 mSupportsMultiWindow = false;
588 mSupportsFreeformWindowManagement = false;
589 mSupportsSplitScreenMultiWindow = false;
590 mSupportsPictureInPicture = false;
591 mSupportsMultiDisplay = false;
592 }
593 mWindowManager.setForceResizableTasks(mForceResizableActivities);
594 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
Garfield Tane0846042018-07-26 13:42:04 -0700595 mWindowManager.setSupportsFreeformWindowManagement(mSupportsFreeformWindowManagement);
596 mWindowManager.setIsPc(isPc);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700597 // This happens before any activities are started, so we can change global configuration
598 // in-place.
599 updateConfigurationLocked(configuration, null, true);
600 final Configuration globalConfig = getGlobalConfiguration();
601 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
602
603 // Load resources only after the current configuration has been set.
604 final Resources res = mContext.getResources();
605 mThumbnailWidth = res.getDimensionPixelSize(
606 com.android.internal.R.dimen.thumbnail_width);
607 mThumbnailHeight = res.getDimensionPixelSize(
608 com.android.internal.R.dimen.thumbnail_height);
609
610 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
611 mFullscreenThumbnailScale = (float) res
612 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
613 (float) globalConfig.screenWidthDp;
614 } else {
615 mFullscreenThumbnailScale = res.getFraction(
616 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
617 }
618 }
619 }
620
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700621 // TODO: Will be converted to WM lock once transition is complete.
622 void setActivityManagerService(ActivityManagerService am) {
623 mAm = am;
624 mGlobalLock = mAm;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700625 mH = new H(mAm.mHandlerThread.getLooper());
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700626 mUiHandler = new UiHandler();
Wale Ogunwale53783742018-09-16 10:21:51 -0700627 final File systemDir = SystemServiceManager.ensureSystemDir();
628 mAppWarnings = new AppWarnings(this, mUiContext, mH, mUiHandler, systemDir);
629 mCompatModePackages = new CompatModePackages(this, systemDir, mH);
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700630
631 mTempConfig.setToDefaults();
632 mTempConfig.setLocales(LocaleList.getDefault());
633 mConfigurationSeq = mTempConfig.seq = 1;
634 mStackSupervisor = createStackSupervisor();
635 mStackSupervisor.onConfigurationChanged(mTempConfig);
636
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700637 mTaskChangeNotificationController =
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700638 new TaskChangeNotificationController(mGlobalLock, mStackSupervisor, mH);
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700639 mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mH);
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700640 mActivityStartController = new ActivityStartController(this);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700641 mRecentTasks = createRecentTasks();
642 mStackSupervisor.setRecentTasks(mRecentTasks);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700643 mVrController = new VrController(mGlobalLock);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700644 mKeyguardController = mStackSupervisor.getKeyguardController();
645 }
646
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700647 void onActivityManagerInternalAdded() {
648 mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700649 mUgmInternal = LocalServices.getService(UriGrantsManagerInternal.class);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700650 }
651
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700652 protected ActivityStackSupervisor createStackSupervisor() {
653 final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mH.getLooper());
654 supervisor.initialize();
655 return supervisor;
656 }
657
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700658 void setWindowManager(WindowManagerService wm) {
659 mWindowManager = wm;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700660 mLockTaskController.setWindowManager(wm);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700661 }
662
Wale Ogunwalef6733932018-06-27 05:14:34 -0700663 UserManagerService getUserManager() {
664 if (mUserManager == null) {
665 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
666 mUserManager = (UserManagerService) IUserManager.Stub.asInterface(b);
667 }
668 return mUserManager;
669 }
670
671 AppOpsService getAppOpsService() {
672 if (mAppOpsService == null) {
673 IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
674 mAppOpsService = (AppOpsService) IAppOpsService.Stub.asInterface(b);
675 }
676 return mAppOpsService;
677 }
678
679 boolean hasUserRestriction(String restriction, int userId) {
680 return getUserManager().hasUserRestriction(restriction, userId);
681 }
682
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700683 protected RecentTasks createRecentTasks() {
684 return new RecentTasks(this, mStackSupervisor);
685 }
686
687 RecentTasks getRecentTasks() {
688 return mRecentTasks;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700689 }
690
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700691 ClientLifecycleManager getLifecycleManager() {
692 return mLifecycleManager;
693 }
694
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700695 ActivityStartController getActivityStartController() {
696 return mActivityStartController;
697 }
698
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700699 TaskChangeNotificationController getTaskChangeNotificationController() {
700 return mTaskChangeNotificationController;
701 }
702
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700703 LockTaskController getLockTaskController() {
704 return mLockTaskController;
705 }
706
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700707 private void start() {
Wale Ogunwale53783742018-09-16 10:21:51 -0700708 mInternal = new LocalService();
709 LocalServices.addService(ActivityTaskManagerInternal.class, mInternal);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700710 }
711
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700712 public static final class Lifecycle extends SystemService {
713 private final ActivityTaskManagerService mService;
714
715 public Lifecycle(Context context) {
716 super(context);
717 mService = new ActivityTaskManagerService(context);
718 }
719
720 @Override
721 public void onStart() {
722 publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700723 mService.start();
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700724 }
725
726 public ActivityTaskManagerService getService() {
727 return mService;
728 }
729 }
730
731 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700732 public final int startActivity(IApplicationThread caller, String callingPackage,
733 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
734 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
735 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
736 resultWho, requestCode, startFlags, profilerInfo, bOptions,
737 UserHandle.getCallingUserId());
738 }
739
740 @Override
741 public final int startActivities(IApplicationThread caller, String callingPackage,
742 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
743 int userId) {
744 final String reason = "startActivities";
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700745 enforceNotIsolatedCaller(reason);
746 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, reason);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700747 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700748 return getActivityStartController().startActivities(caller, -1, callingPackage, intents,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100749 resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId, reason,
750 null /* originatingPendingIntent */);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700751 }
752
753 @Override
754 public int startActivityAsUser(IApplicationThread caller, String callingPackage,
755 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
756 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
757 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
758 resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
759 true /*validateIncomingUser*/);
760 }
761
762 int startActivityAsUser(IApplicationThread caller, String callingPackage,
763 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
764 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
765 boolean validateIncomingUser) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700766 enforceNotIsolatedCaller("startActivityAsUser");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700767
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700768 userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700769 Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
770
771 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700772 return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700773 .setCaller(caller)
774 .setCallingPackage(callingPackage)
775 .setResolvedType(resolvedType)
776 .setResultTo(resultTo)
777 .setResultWho(resultWho)
778 .setRequestCode(requestCode)
779 .setStartFlags(startFlags)
780 .setProfilerInfo(profilerInfo)
781 .setActivityOptions(bOptions)
782 .setMayWait(userId)
783 .execute();
784
785 }
786
787 @Override
788 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
789 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700790 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions) {
791 enforceNotIsolatedCaller("startActivityIntentSender");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700792 // Refuse possible leaked file descriptors
793 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
794 throw new IllegalArgumentException("File descriptors passed in Intent");
795 }
796
797 if (!(target instanceof PendingIntentRecord)) {
798 throw new IllegalArgumentException("Bad PendingIntent object");
799 }
800
801 PendingIntentRecord pir = (PendingIntentRecord)target;
802
803 synchronized (mGlobalLock) {
804 // If this is coming from the currently resumed activity, it is
805 // effectively saying that app switches are allowed at this point.
Andrii Kulian5f750bc2018-07-17 08:57:23 -0700806 final ActivityStack stack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700807 if (stack.mResumedActivity != null &&
808 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700809 mAppSwitchesAllowedTime = 0;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700810 }
811 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700812 return pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700813 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700814 }
815
816 @Override
817 public boolean startNextMatchingActivity(IBinder callingActivity, Intent intent,
818 Bundle bOptions) {
819 // Refuse possible leaked file descriptors
820 if (intent != null && intent.hasFileDescriptors()) {
821 throw new IllegalArgumentException("File descriptors passed in Intent");
822 }
823 SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
824
825 synchronized (mGlobalLock) {
826 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
827 if (r == null) {
828 SafeActivityOptions.abort(options);
829 return false;
830 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700831 if (!r.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700832 // The caller is not running... d'oh!
833 SafeActivityOptions.abort(options);
834 return false;
835 }
836 intent = new Intent(intent);
837 // The caller is not allowed to change the data.
838 intent.setDataAndType(r.intent.getData(), r.intent.getType());
839 // And we are resetting to find the next component...
840 intent.setComponent(null);
841
842 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
843
844 ActivityInfo aInfo = null;
845 try {
846 List<ResolveInfo> resolves =
847 AppGlobals.getPackageManager().queryIntentActivities(
848 intent, r.resolvedType,
849 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
850 UserHandle.getCallingUserId()).getList();
851
852 // Look for the original activity in the list...
853 final int N = resolves != null ? resolves.size() : 0;
854 for (int i=0; i<N; i++) {
855 ResolveInfo rInfo = resolves.get(i);
856 if (rInfo.activityInfo.packageName.equals(r.packageName)
857 && rInfo.activityInfo.name.equals(r.info.name)) {
858 // We found the current one... the next matching is
859 // after it.
860 i++;
861 if (i<N) {
862 aInfo = resolves.get(i).activityInfo;
863 }
864 if (debug) {
865 Slog.v(TAG, "Next matching activity: found current " + r.packageName
866 + "/" + r.info.name);
867 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
868 ? "null" : aInfo.packageName + "/" + aInfo.name));
869 }
870 break;
871 }
872 }
873 } catch (RemoteException e) {
874 }
875
876 if (aInfo == null) {
877 // Nobody who is next!
878 SafeActivityOptions.abort(options);
879 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
880 return false;
881 }
882
883 intent.setComponent(new ComponentName(
884 aInfo.applicationInfo.packageName, aInfo.name));
885 intent.setFlags(intent.getFlags()&~(
886 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
887 Intent.FLAG_ACTIVITY_CLEAR_TOP|
888 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
889 FLAG_ACTIVITY_NEW_TASK));
890
891 // Okay now we need to start the new activity, replacing the currently running activity.
892 // This is a little tricky because we want to start the new one as if the current one is
893 // finished, but not finish the current one first so that there is no flicker.
894 // And thus...
895 final boolean wasFinishing = r.finishing;
896 r.finishing = true;
897
898 // Propagate reply information over to the new activity.
899 final ActivityRecord resultTo = r.resultTo;
900 final String resultWho = r.resultWho;
901 final int requestCode = r.requestCode;
902 r.resultTo = null;
903 if (resultTo != null) {
904 resultTo.removeResultsLocked(r, resultWho, requestCode);
905 }
906
907 final long origId = Binder.clearCallingIdentity();
908 // TODO(b/64750076): Check if calling pid should really be -1.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700909 final int res = getActivityStartController()
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700910 .obtainStarter(intent, "startNextMatchingActivity")
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700911 .setCaller(r.app.getThread())
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700912 .setResolvedType(r.resolvedType)
913 .setActivityInfo(aInfo)
914 .setResultTo(resultTo != null ? resultTo.appToken : null)
915 .setResultWho(resultWho)
916 .setRequestCode(requestCode)
917 .setCallingPid(-1)
918 .setCallingUid(r.launchedFromUid)
919 .setCallingPackage(r.launchedFromPackage)
920 .setRealCallingPid(-1)
921 .setRealCallingUid(r.launchedFromUid)
922 .setActivityOptions(options)
923 .execute();
924 Binder.restoreCallingIdentity(origId);
925
926 r.finishing = wasFinishing;
927 if (res != ActivityManager.START_SUCCESS) {
928 return false;
929 }
930 return true;
931 }
932 }
933
934 @Override
935 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
936 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
937 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
938 final WaitResult res = new WaitResult();
939 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700940 enforceNotIsolatedCaller("startActivityAndWait");
941 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
942 userId, "startActivityAndWait");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700943 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700944 getActivityStartController().obtainStarter(intent, "startActivityAndWait")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700945 .setCaller(caller)
946 .setCallingPackage(callingPackage)
947 .setResolvedType(resolvedType)
948 .setResultTo(resultTo)
949 .setResultWho(resultWho)
950 .setRequestCode(requestCode)
951 .setStartFlags(startFlags)
952 .setActivityOptions(bOptions)
953 .setMayWait(userId)
954 .setProfilerInfo(profilerInfo)
955 .setWaitResult(res)
956 .execute();
957 }
958 return res;
959 }
960
961 @Override
962 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
963 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
964 int startFlags, Configuration config, Bundle bOptions, int userId) {
965 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700966 enforceNotIsolatedCaller("startActivityWithConfig");
967 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
968 "startActivityWithConfig");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700969 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700970 return getActivityStartController().obtainStarter(intent, "startActivityWithConfig")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700971 .setCaller(caller)
972 .setCallingPackage(callingPackage)
973 .setResolvedType(resolvedType)
974 .setResultTo(resultTo)
975 .setResultWho(resultWho)
976 .setRequestCode(requestCode)
977 .setStartFlags(startFlags)
978 .setGlobalConfiguration(config)
979 .setActivityOptions(bOptions)
980 .setMayWait(userId)
981 .execute();
982 }
983 }
984
985 @Override
986 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
987 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
988 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
989 int userId) {
990
991 // This is very dangerous -- it allows you to perform a start activity (including
992 // permission grants) as any app that may launch one of your own activities. So
993 // we will only allow this to be done from activities that are part of the core framework,
994 // and then only when they are running as the system.
995 final ActivityRecord sourceRecord;
996 final int targetUid;
997 final String targetPackage;
998 final boolean isResolver;
999 synchronized (mGlobalLock) {
1000 if (resultTo == null) {
1001 throw new SecurityException("Must be called from an activity");
1002 }
1003 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
1004 if (sourceRecord == null) {
1005 throw new SecurityException("Called with bad activity token: " + resultTo);
1006 }
1007 if (!sourceRecord.info.packageName.equals("android")) {
1008 throw new SecurityException(
1009 "Must be called from an activity that is declared in the android package");
1010 }
1011 if (sourceRecord.app == null) {
1012 throw new SecurityException("Called without a process attached to activity");
1013 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001014 if (UserHandle.getAppId(sourceRecord.app.mUid) != SYSTEM_UID) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001015 // This is still okay, as long as this activity is running under the
1016 // uid of the original calling activity.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001017 if (sourceRecord.app.mUid != sourceRecord.launchedFromUid) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001018 throw new SecurityException(
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001019 "Calling activity in uid " + sourceRecord.app.mUid
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001020 + " must be system uid or original calling uid "
1021 + sourceRecord.launchedFromUid);
1022 }
1023 }
1024 if (ignoreTargetSecurity) {
1025 if (intent.getComponent() == null) {
1026 throw new SecurityException(
1027 "Component must be specified with ignoreTargetSecurity");
1028 }
1029 if (intent.getSelector() != null) {
1030 throw new SecurityException(
1031 "Selector not allowed with ignoreTargetSecurity");
1032 }
1033 }
1034 targetUid = sourceRecord.launchedFromUid;
1035 targetPackage = sourceRecord.launchedFromPackage;
1036 isResolver = sourceRecord.isResolverOrChildActivity();
1037 }
1038
1039 if (userId == UserHandle.USER_NULL) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001040 userId = UserHandle.getUserId(sourceRecord.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001041 }
1042
1043 // TODO: Switch to user app stacks here.
1044 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001045 return getActivityStartController().obtainStarter(intent, "startActivityAsCaller")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001046 .setCallingUid(targetUid)
1047 .setCallingPackage(targetPackage)
1048 .setResolvedType(resolvedType)
1049 .setResultTo(resultTo)
1050 .setResultWho(resultWho)
1051 .setRequestCode(requestCode)
1052 .setStartFlags(startFlags)
1053 .setActivityOptions(bOptions)
1054 .setMayWait(userId)
1055 .setIgnoreTargetSecurity(ignoreTargetSecurity)
1056 .setFilterCallingUid(isResolver ? 0 /* system */ : targetUid)
1057 .execute();
1058 } catch (SecurityException e) {
1059 // XXX need to figure out how to propagate to original app.
1060 // A SecurityException here is generally actually a fault of the original
1061 // calling activity (such as a fairly granting permissions), so propagate it
1062 // back to them.
1063 /*
1064 StringBuilder msg = new StringBuilder();
1065 msg.append("While launching");
1066 msg.append(intent.toString());
1067 msg.append(": ");
1068 msg.append(e.getMessage());
1069 */
1070 throw e;
1071 }
1072 }
1073
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001074 int handleIncomingUser(int callingPid, int callingUid, int userId, String name) {
1075 return mAmInternal.handleIncomingUser(callingPid, callingUid, userId, false /* allowAll */,
1076 ALLOW_FULL_ONLY, name, null /* callerPackage */);
1077 }
1078
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001079 @Override
1080 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
1081 Intent intent, String resolvedType, IVoiceInteractionSession session,
1082 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
1083 Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001084 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001085 if (session == null || interactor == null) {
1086 throw new NullPointerException("null session or interactor");
1087 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001088 userId = handleIncomingUser(callingPid, callingUid, userId, "startVoiceActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001089 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001090 return getActivityStartController().obtainStarter(intent, "startVoiceActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001091 .setCallingUid(callingUid)
1092 .setCallingPackage(callingPackage)
1093 .setResolvedType(resolvedType)
1094 .setVoiceSession(session)
1095 .setVoiceInteractor(interactor)
1096 .setStartFlags(startFlags)
1097 .setProfilerInfo(profilerInfo)
1098 .setActivityOptions(bOptions)
1099 .setMayWait(userId)
1100 .execute();
1101 }
1102
1103 @Override
1104 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
1105 Intent intent, String resolvedType, Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001106 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
1107 userId = handleIncomingUser(callingPid, callingUid, userId, "startAssistantActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001108
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001109 return getActivityStartController().obtainStarter(intent, "startAssistantActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001110 .setCallingUid(callingUid)
1111 .setCallingPackage(callingPackage)
1112 .setResolvedType(resolvedType)
1113 .setActivityOptions(bOptions)
1114 .setMayWait(userId)
1115 .execute();
1116 }
1117
1118 @Override
1119 public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
1120 IRecentsAnimationRunner recentsAnimationRunner) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001121 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001122 final int callingPid = Binder.getCallingPid();
1123 final long origId = Binder.clearCallingIdentity();
1124 try {
1125 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07001126 final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
1127 final int recentsUid = mRecentTasks.getRecentsComponentUid();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001128
1129 // Start a new recents animation
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001130 final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
1131 getActivityStartController(), mWindowManager, callingPid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001132 anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
1133 recentsUid, assistDataReceiver);
1134 }
1135 } finally {
1136 Binder.restoreCallingIdentity(origId);
1137 }
1138 }
1139
1140 @Override
1141 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001142 enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001143 "startActivityFromRecents()");
1144
1145 final int callingPid = Binder.getCallingPid();
1146 final int callingUid = Binder.getCallingUid();
1147 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(bOptions);
1148 final long origId = Binder.clearCallingIdentity();
1149 try {
1150 synchronized (mGlobalLock) {
1151 return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
1152 safeOptions);
1153 }
1154 } finally {
1155 Binder.restoreCallingIdentity(origId);
1156 }
1157 }
1158
1159 /**
1160 * This is the internal entry point for handling Activity.finish().
1161 *
1162 * @param token The Binder token referencing the Activity we want to finish.
1163 * @param resultCode Result code, if any, from this Activity.
1164 * @param resultData Result data (Intent), if any, from this Activity.
1165 * @param finishTask Whether to finish the task associated with this Activity.
1166 *
1167 * @return Returns true if the activity successfully finished, or false if it is still running.
1168 */
1169 @Override
1170 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
1171 int finishTask) {
1172 // Refuse possible leaked file descriptors
1173 if (resultData != null && resultData.hasFileDescriptors()) {
1174 throw new IllegalArgumentException("File descriptors passed in Intent");
1175 }
1176
1177 synchronized (mGlobalLock) {
1178 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1179 if (r == null) {
1180 return true;
1181 }
1182 // Keep track of the root activity of the task before we finish it
1183 TaskRecord tr = r.getTask();
1184 ActivityRecord rootR = tr.getRootActivity();
1185 if (rootR == null) {
1186 Slog.w(TAG, "Finishing task with all activities already finished");
1187 }
1188 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
1189 // finish.
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001190 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001191 return false;
1192 }
1193
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001194 // TODO: There is a dup. of this block of code in ActivityStack.navigateUpToLocked
1195 // We should consolidate.
1196 if (mController != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001197 // Find the first activity that is not finishing.
1198 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
1199 if (next != null) {
1200 // ask watcher if this is allowed
1201 boolean resumeOK = true;
1202 try {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001203 resumeOK = mController.activityResuming(next.packageName);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001204 } catch (RemoteException e) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001205 mController = null;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001206 Watchdog.getInstance().setActivityController(null);
1207 }
1208
1209 if (!resumeOK) {
1210 Slog.i(TAG, "Not finishing activity because controller resumed");
1211 return false;
1212 }
1213 }
1214 }
1215 final long origId = Binder.clearCallingIdentity();
1216 try {
1217 boolean res;
1218 final boolean finishWithRootActivity =
1219 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
1220 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
1221 || (finishWithRootActivity && r == rootR)) {
1222 // If requested, remove the task that is associated to this activity only if it
1223 // was the root activity in the task. The result code and data is ignored
1224 // because we don't support returning them across task boundaries. Also, to
1225 // keep backwards compatibility we remove the task from recents when finishing
1226 // task with root activity.
1227 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
1228 finishWithRootActivity, "finish-activity");
1229 if (!res) {
1230 Slog.i(TAG, "Removing task failed to finish activity");
1231 }
Garfield Tan2746ab52018-07-25 12:33:01 -07001232 // Explicitly dismissing the activity so reset its relaunch flag.
1233 r.mRelaunchReason = ActivityRecord.RELAUNCH_REASON_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001234 } else {
1235 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
1236 resultData, "app-request", true);
1237 if (!res) {
1238 Slog.i(TAG, "Failed to finish by app-request");
1239 }
1240 }
1241 return res;
1242 } finally {
1243 Binder.restoreCallingIdentity(origId);
1244 }
1245 }
1246 }
1247
1248 @Override
1249 public boolean finishActivityAffinity(IBinder token) {
1250 synchronized (mGlobalLock) {
1251 final long origId = Binder.clearCallingIdentity();
1252 try {
1253 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1254 if (r == null) {
1255 return false;
1256 }
1257
1258 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
1259 // can finish.
1260 final TaskRecord task = r.getTask();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001261 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001262 return false;
1263 }
1264 return task.getStack().finishActivityAffinityLocked(r);
1265 } finally {
1266 Binder.restoreCallingIdentity(origId);
1267 }
1268 }
1269 }
1270
1271 @Override
1272 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
1273 final long origId = Binder.clearCallingIdentity();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001274 try {
1275 WindowProcessController proc = null;
1276 synchronized (mGlobalLock) {
1277 ActivityStack stack = ActivityRecord.getStackLocked(token);
1278 if (stack == null) {
1279 return;
1280 }
1281 final ActivityRecord r = mStackSupervisor.activityIdleInternalLocked(token,
1282 false /* fromTimeout */, false /* processPausingActivities */, config);
1283 if (r != null) {
1284 proc = r.app;
1285 }
1286 if (stopProfiling && proc != null) {
1287 proc.clearProfilerIfNeeded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001288 }
1289 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001290 } finally {
1291 Binder.restoreCallingIdentity(origId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001292 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001293 }
1294
1295 @Override
1296 public final void activityResumed(IBinder token) {
1297 final long origId = Binder.clearCallingIdentity();
1298 synchronized (mGlobalLock) {
1299 ActivityRecord.activityResumedLocked(token);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001300 mWindowManager.notifyAppResumedFinished(token);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001301 }
1302 Binder.restoreCallingIdentity(origId);
1303 }
1304
1305 @Override
1306 public final void activityPaused(IBinder token) {
1307 final long origId = Binder.clearCallingIdentity();
1308 synchronized (mGlobalLock) {
1309 ActivityStack stack = ActivityRecord.getStackLocked(token);
1310 if (stack != null) {
1311 stack.activityPausedLocked(token, false);
1312 }
1313 }
1314 Binder.restoreCallingIdentity(origId);
1315 }
1316
1317 @Override
1318 public final void activityStopped(IBinder token, Bundle icicle,
1319 PersistableBundle persistentState, CharSequence description) {
1320 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
1321
1322 // Refuse possible leaked file descriptors
1323 if (icicle != null && icicle.hasFileDescriptors()) {
1324 throw new IllegalArgumentException("File descriptors passed in Bundle");
1325 }
1326
1327 final long origId = Binder.clearCallingIdentity();
1328
1329 synchronized (mGlobalLock) {
1330 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1331 if (r != null) {
1332 r.activityStoppedLocked(icicle, persistentState, description);
1333 }
1334 }
1335
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001336 mAmInternal.trimApplications();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001337
1338 Binder.restoreCallingIdentity(origId);
1339 }
1340
1341 @Override
1342 public final void activityDestroyed(IBinder token) {
1343 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
1344 synchronized (mGlobalLock) {
1345 ActivityStack stack = ActivityRecord.getStackLocked(token);
1346 if (stack != null) {
1347 stack.activityDestroyedLocked(token, "activityDestroyed");
1348 }
1349 }
1350 }
1351
1352 @Override
1353 public final void activityRelaunched(IBinder token) {
1354 final long origId = Binder.clearCallingIdentity();
1355 synchronized (mGlobalLock) {
1356 mStackSupervisor.activityRelaunchedLocked(token);
1357 }
1358 Binder.restoreCallingIdentity(origId);
1359 }
1360
1361 public final void activitySlept(IBinder token) {
1362 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
1363
1364 final long origId = Binder.clearCallingIdentity();
1365
1366 synchronized (mGlobalLock) {
1367 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1368 if (r != null) {
1369 mStackSupervisor.activitySleptLocked(r);
1370 }
1371 }
1372
1373 Binder.restoreCallingIdentity(origId);
1374 }
1375
1376 @Override
1377 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
1378 synchronized (mGlobalLock) {
1379 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1380 if (r == null) {
1381 return;
1382 }
1383 final long origId = Binder.clearCallingIdentity();
1384 try {
1385 r.setRequestedOrientation(requestedOrientation);
1386 } finally {
1387 Binder.restoreCallingIdentity(origId);
1388 }
1389 }
1390 }
1391
1392 @Override
1393 public int getRequestedOrientation(IBinder token) {
1394 synchronized (mGlobalLock) {
1395 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1396 if (r == null) {
1397 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
1398 }
1399 return r.getRequestedOrientation();
1400 }
1401 }
1402
1403 @Override
1404 public void setImmersive(IBinder token, boolean immersive) {
1405 synchronized (mGlobalLock) {
1406 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1407 if (r == null) {
1408 throw new IllegalArgumentException();
1409 }
1410 r.immersive = immersive;
1411
1412 // update associated state if we're frontmost
Andrii Kulian52d255c2018-07-13 11:32:19 -07001413 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001414 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001415 applyUpdateLockStateLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001416 }
1417 }
1418 }
1419
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001420 void applyUpdateLockStateLocked(ActivityRecord r) {
1421 // Modifications to the UpdateLock state are done on our handler, outside
1422 // the activity manager's locks. The new state is determined based on the
1423 // state *now* of the relevant activity record. The object is passed to
1424 // the handler solely for logging detail, not to be consulted/modified.
1425 final boolean nextState = r != null && r.immersive;
1426 mH.post(() -> {
1427 if (mUpdateLock.isHeld() != nextState) {
1428 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1429 "Applying new update lock state '" + nextState + "' for " + r);
1430 if (nextState) {
1431 mUpdateLock.acquire();
1432 } else {
1433 mUpdateLock.release();
1434 }
1435 }
1436 });
1437 }
1438
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001439 @Override
1440 public boolean isImmersive(IBinder token) {
1441 synchronized (mGlobalLock) {
1442 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1443 if (r == null) {
1444 throw new IllegalArgumentException();
1445 }
1446 return r.immersive;
1447 }
1448 }
1449
1450 @Override
1451 public boolean isTopActivityImmersive() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001452 enforceNotIsolatedCaller("isTopActivityImmersive");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001453 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001454 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001455 return (r != null) ? r.immersive : false;
1456 }
1457 }
1458
1459 @Override
1460 public void overridePendingTransition(IBinder token, String packageName,
1461 int enterAnim, int exitAnim) {
1462 synchronized (mGlobalLock) {
1463 ActivityRecord self = ActivityRecord.isInStackLocked(token);
1464 if (self == null) {
1465 return;
1466 }
1467
1468 final long origId = Binder.clearCallingIdentity();
1469
1470 if (self.isState(
1471 ActivityStack.ActivityState.RESUMED, ActivityStack.ActivityState.PAUSING)) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001472 mWindowManager.overridePendingAppTransition(packageName,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001473 enterAnim, exitAnim, null);
1474 }
1475
1476 Binder.restoreCallingIdentity(origId);
1477 }
1478 }
1479
1480 @Override
1481 public int getFrontActivityScreenCompatMode() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001482 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001483 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001484 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001485 if (r == null) {
1486 return ActivityManager.COMPAT_MODE_UNKNOWN;
1487 }
Wale Ogunwale53783742018-09-16 10:21:51 -07001488 return mCompatModePackages.computeCompatModeLocked(r.info.applicationInfo);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001489 }
1490 }
1491
1492 @Override
1493 public void setFrontActivityScreenCompatMode(int mode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001494 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001495 "setFrontActivityScreenCompatMode");
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001496 ApplicationInfo ai;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001497 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001498 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001499 if (r == null) {
1500 Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity");
1501 return;
1502 }
1503 ai = r.info.applicationInfo;
Wale Ogunwale53783742018-09-16 10:21:51 -07001504 mCompatModePackages.setPackageScreenCompatModeLocked(ai, mode);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001505 }
1506 }
1507
1508 @Override
1509 public int getLaunchedFromUid(IBinder activityToken) {
1510 ActivityRecord srec;
1511 synchronized (mGlobalLock) {
1512 srec = ActivityRecord.forTokenLocked(activityToken);
1513 }
1514 if (srec == null) {
1515 return -1;
1516 }
1517 return srec.launchedFromUid;
1518 }
1519
1520 @Override
1521 public String getLaunchedFromPackage(IBinder activityToken) {
1522 ActivityRecord srec;
1523 synchronized (mGlobalLock) {
1524 srec = ActivityRecord.forTokenLocked(activityToken);
1525 }
1526 if (srec == null) {
1527 return null;
1528 }
1529 return srec.launchedFromPackage;
1530 }
1531
1532 @Override
1533 public boolean convertFromTranslucent(IBinder token) {
1534 final long origId = Binder.clearCallingIdentity();
1535 try {
1536 synchronized (mGlobalLock) {
1537 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1538 if (r == null) {
1539 return false;
1540 }
1541 final boolean translucentChanged = r.changeWindowTranslucency(true);
1542 if (translucentChanged) {
1543 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
1544 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001545 mWindowManager.setAppFullscreen(token, true);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001546 return translucentChanged;
1547 }
1548 } finally {
1549 Binder.restoreCallingIdentity(origId);
1550 }
1551 }
1552
1553 @Override
1554 public boolean convertToTranslucent(IBinder token, Bundle options) {
1555 SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
1556 final long origId = Binder.clearCallingIdentity();
1557 try {
1558 synchronized (mGlobalLock) {
1559 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1560 if (r == null) {
1561 return false;
1562 }
1563 final TaskRecord task = r.getTask();
1564 int index = task.mActivities.lastIndexOf(r);
1565 if (index > 0) {
1566 ActivityRecord under = task.mActivities.get(index - 1);
1567 under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
1568 }
1569 final boolean translucentChanged = r.changeWindowTranslucency(false);
1570 if (translucentChanged) {
1571 r.getStack().convertActivityToTranslucent(r);
1572 }
1573 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001574 mWindowManager.setAppFullscreen(token, false);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001575 return translucentChanged;
1576 }
1577 } finally {
1578 Binder.restoreCallingIdentity(origId);
1579 }
1580 }
1581
1582 @Override
1583 public void notifyActivityDrawn(IBinder token) {
1584 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
1585 synchronized (mGlobalLock) {
1586 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
1587 if (r != null) {
1588 r.getStack().notifyActivityDrawnLocked(r);
1589 }
1590 }
1591 }
1592
1593 @Override
1594 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
1595 synchronized (mGlobalLock) {
1596 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1597 if (r == null) {
1598 return;
1599 }
1600 r.reportFullyDrawnLocked(restoredFromBundle);
1601 }
1602 }
1603
1604 @Override
1605 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
1606 synchronized (mGlobalLock) {
1607 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
1608 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
1609 return stack.mDisplayId;
1610 }
1611 return DEFAULT_DISPLAY;
1612 }
1613 }
1614
1615 @Override
1616 public ActivityManager.StackInfo getFocusedStackInfo() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001617 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001618 long ident = Binder.clearCallingIdentity();
1619 try {
1620 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001621 ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001622 if (focusedStack != null) {
1623 return mStackSupervisor.getStackInfo(focusedStack.mStackId);
1624 }
1625 return null;
1626 }
1627 } finally {
1628 Binder.restoreCallingIdentity(ident);
1629 }
1630 }
1631
1632 @Override
1633 public void setFocusedStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001634 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001635 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
1636 final long callingId = Binder.clearCallingIdentity();
1637 try {
1638 synchronized (mGlobalLock) {
1639 final ActivityStack stack = mStackSupervisor.getStack(stackId);
1640 if (stack == null) {
1641 Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
1642 return;
1643 }
1644 final ActivityRecord r = stack.topRunningActivityLocked();
1645 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
1646 r, "setFocusedStack")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08001647 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001648 }
1649 }
1650 } finally {
1651 Binder.restoreCallingIdentity(callingId);
1652 }
1653 }
1654
1655 @Override
1656 public void setFocusedTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001657 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001658 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
1659 final long callingId = Binder.clearCallingIdentity();
1660 try {
1661 synchronized (mGlobalLock) {
1662 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1663 if (task == null) {
1664 return;
1665 }
1666 final ActivityRecord r = task.topRunningActivityLocked();
1667 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08001668 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001669 }
1670 }
1671 } finally {
1672 Binder.restoreCallingIdentity(callingId);
1673 }
1674 }
1675
1676 @Override
1677 public boolean removeTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001678 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001679 synchronized (mGlobalLock) {
1680 final long ident = Binder.clearCallingIdentity();
1681 try {
1682 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
1683 "remove-task");
1684 } finally {
1685 Binder.restoreCallingIdentity(ident);
1686 }
1687 }
1688 }
1689
1690 @Override
Winson Chunge6439102018-07-30 15:48:01 -07001691 public void removeAllVisibleRecentTasks() {
1692 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeAllVisibleRecentTasks()");
1693 synchronized (mGlobalLock) {
1694 final long ident = Binder.clearCallingIdentity();
1695 try {
1696 getRecentTasks().removeAllVisibleTasks();
1697 } finally {
1698 Binder.restoreCallingIdentity(ident);
1699 }
1700 }
1701 }
1702
1703 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001704 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
1705 synchronized (mGlobalLock) {
1706 final ActivityRecord srec = ActivityRecord.forTokenLocked(token);
1707 if (srec != null) {
1708 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
1709 }
1710 }
1711 return false;
1712 }
1713
1714 @Override
1715 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
1716 Intent resultData) {
1717
1718 synchronized (mGlobalLock) {
1719 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
1720 if (r != null) {
1721 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
1722 }
1723 return false;
1724 }
1725 }
1726
1727 /**
1728 * Attempts to move a task backwards in z-order (the order of activities within the task is
1729 * unchanged).
1730 *
1731 * There are several possible results of this call:
1732 * - if the task is locked, then we will show the lock toast
1733 * - if there is a task behind the provided task, then that task is made visible and resumed as
1734 * this task is moved to the back
1735 * - otherwise, if there are no other tasks in the stack:
1736 * - if this task is in the pinned stack, then we remove the stack completely, which will
1737 * have the effect of moving the task to the top or bottom of the fullscreen stack
1738 * (depending on whether it is visible)
1739 * - otherwise, we simply return home and hide this task
1740 *
1741 * @param token A reference to the activity we wish to move
1742 * @param nonRoot If false then this only works if the activity is the root
1743 * of a task; if true it will work for any activity in a task.
1744 * @return Returns true if the move completed, false if not.
1745 */
1746 @Override
1747 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001748 enforceNotIsolatedCaller("moveActivityTaskToBack");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001749 synchronized (mGlobalLock) {
1750 final long origId = Binder.clearCallingIdentity();
1751 try {
1752 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
1753 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1754 if (task != null) {
1755 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
1756 }
1757 } finally {
1758 Binder.restoreCallingIdentity(origId);
1759 }
1760 }
1761 return false;
1762 }
1763
1764 @Override
1765 public Rect getTaskBounds(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001766 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001767 long ident = Binder.clearCallingIdentity();
1768 Rect rect = new Rect();
1769 try {
1770 synchronized (mGlobalLock) {
1771 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
1772 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1773 if (task == null) {
1774 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
1775 return rect;
1776 }
1777 if (task.getStack() != null) {
1778 // Return the bounds from window manager since it will be adjusted for various
1779 // things like the presense of a docked stack for tasks that aren't resizeable.
1780 task.getWindowContainerBounds(rect);
1781 } else {
1782 // Task isn't in window manager yet since it isn't associated with a stack.
1783 // Return the persist value from activity manager
1784 if (!task.matchParentBounds()) {
1785 rect.set(task.getBounds());
1786 } else if (task.mLastNonFullscreenBounds != null) {
1787 rect.set(task.mLastNonFullscreenBounds);
1788 }
1789 }
1790 }
1791 } finally {
1792 Binder.restoreCallingIdentity(ident);
1793 }
1794 return rect;
1795 }
1796
1797 @Override
1798 public ActivityManager.TaskDescription getTaskDescription(int id) {
1799 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001800 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001801 MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
1802 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
1803 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1804 if (tr != null) {
1805 return tr.lastTaskDescription;
1806 }
1807 }
1808 return null;
1809 }
1810
1811 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001812 public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
1813 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
1814 setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
1815 toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
1816 return;
1817 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001818 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001819 synchronized (mGlobalLock) {
1820 final long ident = Binder.clearCallingIdentity();
1821 try {
1822 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1823 if (task == null) {
1824 Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
1825 return;
1826 }
1827
1828 if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
1829 + " to windowingMode=" + windowingMode + " toTop=" + toTop);
1830
1831 if (!task.isActivityTypeStandardOrUndefined()) {
1832 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
1833 + " non-standard task " + taskId + " to windowing mode="
1834 + windowingMode);
1835 }
1836
1837 final ActivityStack stack = task.getStack();
1838 if (toTop) {
1839 stack.moveToFront("setTaskWindowingMode", task);
1840 }
1841 stack.setWindowingMode(windowingMode);
1842 } finally {
1843 Binder.restoreCallingIdentity(ident);
1844 }
1845 }
1846 }
1847
1848 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001849 public String getCallingPackage(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001850 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001851 ActivityRecord r = getCallingRecordLocked(token);
1852 return r != null ? r.info.packageName : null;
1853 }
1854 }
1855
1856 @Override
1857 public ComponentName getCallingActivity(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001858 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001859 ActivityRecord r = getCallingRecordLocked(token);
1860 return r != null ? r.intent.getComponent() : null;
1861 }
1862 }
1863
1864 private ActivityRecord getCallingRecordLocked(IBinder token) {
1865 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1866 if (r == null) {
1867 return null;
1868 }
1869 return r.resultTo;
1870 }
1871
1872 @Override
1873 public void unhandledBack() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001874 mAmInternal.enforceCallingPermission(android.Manifest.permission.FORCE_BACK, "unhandledBack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001875
1876 synchronized (mGlobalLock) {
1877 final long origId = Binder.clearCallingIdentity();
1878 try {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001879 getTopDisplayFocusedStack().unhandledBackLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001880 } finally {
1881 Binder.restoreCallingIdentity(origId);
1882 }
1883 }
1884 }
1885
1886 /**
1887 * TODO: Add mController hook
1888 */
1889 @Override
1890 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001891 mAmInternal.enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001892
1893 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
1894 synchronized (mGlobalLock) {
1895 moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
1896 false /* fromRecents */);
1897 }
1898 }
1899
1900 void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
1901 boolean fromRecents) {
1902
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001903 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001904 Binder.getCallingUid(), -1, -1, "Task to front")) {
1905 SafeActivityOptions.abort(options);
1906 return;
1907 }
1908 final long origId = Binder.clearCallingIdentity();
1909 try {
1910 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1911 if (task == null) {
1912 Slog.d(TAG, "Could not find task for id: "+ taskId);
1913 return;
1914 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001915 if (getLockTaskController().isLockTaskModeViolation(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001916 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
1917 return;
1918 }
1919 ActivityOptions realOptions = options != null
1920 ? options.getOptions(mStackSupervisor)
1921 : null;
1922 mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
1923 false /* forceNonResizable */);
1924
1925 final ActivityRecord topActivity = task.getTopActivity();
1926 if (topActivity != null) {
1927
1928 // We are reshowing a task, use a starting window to hide the initial draw delay
1929 // so the transition can start earlier.
1930 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
1931 true /* taskSwitch */, fromRecents);
1932 }
1933 } finally {
1934 Binder.restoreCallingIdentity(origId);
1935 }
1936 SafeActivityOptions.abort(options);
1937 }
1938
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001939 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
1940 int callingPid, int callingUid, String name) {
1941 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
1942 return true;
1943 }
1944
1945 if (getRecentTasks().isCallerRecents(sourceUid)) {
1946 return true;
1947 }
1948
1949 int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
1950 if (perm == PackageManager.PERMISSION_GRANTED) {
1951 return true;
1952 }
1953 if (checkAllowAppSwitchUid(sourceUid)) {
1954 return true;
1955 }
1956
1957 // If the actual IPC caller is different from the logical source, then
1958 // also see if they are allowed to control app switches.
1959 if (callingUid != -1 && callingUid != sourceUid) {
1960 perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
1961 if (perm == PackageManager.PERMISSION_GRANTED) {
1962 return true;
1963 }
1964 if (checkAllowAppSwitchUid(callingUid)) {
1965 return true;
1966 }
1967 }
1968
1969 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
1970 return false;
1971 }
1972
1973 private boolean checkAllowAppSwitchUid(int uid) {
1974 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
1975 if (types != null) {
1976 for (int i = types.size() - 1; i >= 0; i--) {
1977 if (types.valueAt(i).intValue() == uid) {
1978 return true;
1979 }
1980 }
1981 }
1982 return false;
1983 }
1984
1985 @Override
1986 public void setActivityController(IActivityController controller, boolean imAMonkey) {
1987 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
1988 "setActivityController()");
1989 synchronized (mGlobalLock) {
1990 mController = controller;
1991 mControllerIsAMonkey = imAMonkey;
1992 Watchdog.getInstance().setActivityController(controller);
1993 }
1994 }
1995
1996 boolean isControllerAMonkey() {
1997 synchronized (mGlobalLock) {
1998 return mController != null && mControllerIsAMonkey;
1999 }
2000 }
2001
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002002 @Override
2003 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
2004 synchronized (mGlobalLock) {
2005 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
2006 }
2007 }
2008
2009 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002010 public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum) {
2011 return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
2012 }
2013
2014 @Override
2015 public List<ActivityManager.RunningTaskInfo> getFilteredTasks(int maxNum,
2016 @WindowConfiguration.ActivityType int ignoreActivityType,
2017 @WindowConfiguration.WindowingMode int ignoreWindowingMode) {
2018 final int callingUid = Binder.getCallingUid();
2019 ArrayList<ActivityManager.RunningTaskInfo> list = new ArrayList<>();
2020
2021 synchronized (mGlobalLock) {
2022 if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
2023
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002024 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002025 callingUid);
2026 mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
2027 ignoreWindowingMode, callingUid, allowed);
2028 }
2029
2030 return list;
2031 }
2032
2033 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002034 public final void finishSubActivity(IBinder token, String resultWho, int requestCode) {
2035 synchronized (mGlobalLock) {
2036 final long origId = Binder.clearCallingIdentity();
2037 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2038 if (r != null) {
2039 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
2040 }
2041 Binder.restoreCallingIdentity(origId);
2042 }
2043 }
2044
2045 @Override
2046 public boolean willActivityBeVisible(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002047 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002048 ActivityStack stack = ActivityRecord.getStackLocked(token);
2049 if (stack != null) {
2050 return stack.willActivityBeVisibleLocked(token);
2051 }
2052 return false;
2053 }
2054 }
2055
2056 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002057 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002058 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002059 synchronized (mGlobalLock) {
2060 final long ident = Binder.clearCallingIdentity();
2061 try {
2062 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2063 if (task == null) {
2064 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
2065 return;
2066 }
2067
2068 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
2069 + " to stackId=" + stackId + " toTop=" + toTop);
2070
2071 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2072 if (stack == null) {
2073 throw new IllegalStateException(
2074 "moveTaskToStack: No stack for stackId=" + stackId);
2075 }
2076 if (!stack.isActivityTypeStandardOrUndefined()) {
2077 throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
2078 + taskId + " to stack " + stackId);
2079 }
2080 if (stack.inSplitScreenPrimaryWindowingMode()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002081 mWindowManager.setDockedStackCreateState(
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002082 SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
2083 }
2084 task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
2085 "moveTaskToStack");
2086 } finally {
2087 Binder.restoreCallingIdentity(ident);
2088 }
2089 }
2090 }
2091
2092 @Override
2093 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
2094 boolean preserveWindows, boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002095 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002096
2097 final long ident = Binder.clearCallingIdentity();
2098 try {
2099 synchronized (mGlobalLock) {
2100 if (animate) {
2101 final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
2102 if (stack == null) {
2103 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2104 return;
2105 }
2106 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
2107 throw new IllegalArgumentException("Stack: " + stackId
2108 + " doesn't support animated resize.");
2109 }
2110 stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
2111 animationDuration, false /* fromFullscreen */);
2112 } else {
2113 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2114 if (stack == null) {
2115 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2116 return;
2117 }
2118 mStackSupervisor.resizeStackLocked(stack, destBounds,
2119 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
2120 preserveWindows, allowResizeInDockedMode, !DEFER_RESUME);
2121 }
2122 }
2123 } finally {
2124 Binder.restoreCallingIdentity(ident);
2125 }
2126 }
2127
2128 /**
2129 * Moves the specified task to the primary-split-screen stack.
2130 *
2131 * @param taskId Id of task to move.
2132 * @param createMode The mode the primary split screen stack should be created in if it doesn't
2133 * exist already. See
2134 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
2135 * and
2136 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
2137 * @param toTop If the task and stack should be moved to the top.
2138 * @param animate Whether we should play an animation for the moving the task.
2139 * @param initialBounds If the primary stack gets created, it will use these bounds for the
2140 * stack. Pass {@code null} to use default bounds.
2141 * @param showRecents If the recents activity should be shown on the other side of the task
2142 * going into split-screen mode.
2143 */
2144 @Override
2145 public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode,
2146 boolean toTop, boolean animate, Rect initialBounds, boolean showRecents) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002147 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002148 "setTaskWindowingModeSplitScreenPrimary()");
2149 synchronized (mGlobalLock) {
2150 final long ident = Binder.clearCallingIdentity();
2151 try {
2152 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2153 if (task == null) {
2154 Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
2155 return false;
2156 }
2157 if (DEBUG_STACK) Slog.d(TAG_STACK,
2158 "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
2159 + " to createMode=" + createMode + " toTop=" + toTop);
2160 if (!task.isActivityTypeStandardOrUndefined()) {
2161 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
2162 + " non-standard task " + taskId + " to split-screen windowing mode");
2163 }
2164
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002165 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002166 final int windowingMode = task.getWindowingMode();
2167 final ActivityStack stack = task.getStack();
2168 if (toTop) {
2169 stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
2170 }
2171 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
2172 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */);
2173 return windowingMode != task.getWindowingMode();
2174 } finally {
2175 Binder.restoreCallingIdentity(ident);
2176 }
2177 }
2178 }
2179
2180 /**
2181 * Removes stacks in the input windowing modes from the system if they are of activity type
2182 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
2183 */
2184 @Override
2185 public void removeStacksInWindowingModes(int[] windowingModes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002186 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002187 "removeStacksInWindowingModes()");
2188
2189 synchronized (mGlobalLock) {
2190 final long ident = Binder.clearCallingIdentity();
2191 try {
2192 mStackSupervisor.removeStacksInWindowingModes(windowingModes);
2193 } finally {
2194 Binder.restoreCallingIdentity(ident);
2195 }
2196 }
2197 }
2198
2199 @Override
2200 public void removeStacksWithActivityTypes(int[] activityTypes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002201 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002202 "removeStacksWithActivityTypes()");
2203
2204 synchronized (mGlobalLock) {
2205 final long ident = Binder.clearCallingIdentity();
2206 try {
2207 mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
2208 } finally {
2209 Binder.restoreCallingIdentity(ident);
2210 }
2211 }
2212 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002213
2214 @Override
2215 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
2216 int userId) {
2217 final int callingUid = Binder.getCallingUid();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002218 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, "getRecentTasks");
2219 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002220 callingUid);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002221 final boolean detailed = checkGetTasksPermission(
2222 android.Manifest.permission.GET_DETAILED_TASKS, Binder.getCallingPid(),
2223 UserHandle.getAppId(callingUid))
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002224 == PackageManager.PERMISSION_GRANTED;
2225
2226 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002227 return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002228 callingUid);
2229 }
2230 }
2231
2232 @Override
2233 public List<ActivityManager.StackInfo> getAllStackInfos() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002234 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002235 long ident = Binder.clearCallingIdentity();
2236 try {
2237 synchronized (mGlobalLock) {
2238 return mStackSupervisor.getAllStackInfosLocked();
2239 }
2240 } finally {
2241 Binder.restoreCallingIdentity(ident);
2242 }
2243 }
2244
2245 @Override
2246 public ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002247 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002248 long ident = Binder.clearCallingIdentity();
2249 try {
2250 synchronized (mGlobalLock) {
2251 return mStackSupervisor.getStackInfo(windowingMode, activityType);
2252 }
2253 } finally {
2254 Binder.restoreCallingIdentity(ident);
2255 }
2256 }
2257
2258 @Override
2259 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002260 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002261 final long callingUid = Binder.getCallingUid();
2262 final long origId = Binder.clearCallingIdentity();
2263 try {
2264 synchronized (mGlobalLock) {
2265 // Cancel the recents animation synchronously (do not hold the WM lock)
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002266 mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002267 ? REORDER_MOVE_TO_ORIGINAL_POSITION
2268 : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
2269 }
2270 } finally {
2271 Binder.restoreCallingIdentity(origId);
2272 }
2273 }
2274
2275 @Override
2276 public void startLockTaskModeByToken(IBinder token) {
2277 synchronized (mGlobalLock) {
2278 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2279 if (r == null) {
2280 return;
2281 }
2282 startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
2283 }
2284 }
2285
2286 @Override
2287 public void startSystemLockTaskMode(int taskId) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002288 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002289 // This makes inner call to look as if it was initiated by system.
2290 long ident = Binder.clearCallingIdentity();
2291 try {
2292 synchronized (mGlobalLock) {
2293 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2294
2295 // When starting lock task mode the stack must be in front and focused
2296 task.getStack().moveToFront("startSystemLockTaskMode");
2297 startLockTaskModeLocked(task, true /* isSystemCaller */);
2298 }
2299 } finally {
2300 Binder.restoreCallingIdentity(ident);
2301 }
2302 }
2303
2304 @Override
2305 public void stopLockTaskModeByToken(IBinder token) {
2306 synchronized (mGlobalLock) {
2307 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2308 if (r == null) {
2309 return;
2310 }
2311 stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
2312 }
2313 }
2314
2315 /**
2316 * This API should be called by SystemUI only when user perform certain action to dismiss
2317 * lock task mode. We should only dismiss pinned lock task mode in this case.
2318 */
2319 @Override
2320 public void stopSystemLockTaskMode() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002321 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002322 stopLockTaskModeInternal(null, true /* isSystemCaller */);
2323 }
2324
2325 private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
2326 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
2327 if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
2328 return;
2329 }
2330
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002331 final ActivityStack stack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002332 if (stack == null || task != stack.topTask()) {
2333 throw new IllegalArgumentException("Invalid task, not in foreground");
2334 }
2335
2336 // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
2337 // system or a specific app.
2338 // * System-initiated requests will only start the pinned mode (screen pinning)
2339 // * App-initiated requests
2340 // - will put the device in fully locked mode (LockTask), if the app is whitelisted
2341 // - will start the pinned mode, otherwise
2342 final int callingUid = Binder.getCallingUid();
2343 long ident = Binder.clearCallingIdentity();
2344 try {
2345 // When a task is locked, dismiss the pinned stack if it exists
2346 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2347
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002348 getLockTaskController().startLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002349 } finally {
2350 Binder.restoreCallingIdentity(ident);
2351 }
2352 }
2353
2354 private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
2355 final int callingUid = Binder.getCallingUid();
2356 long ident = Binder.clearCallingIdentity();
2357 try {
2358 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002359 getLockTaskController().stopLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002360 }
2361 // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
2362 // task and jumping straight into a call in the case of emergency call back.
2363 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
2364 if (tm != null) {
2365 tm.showInCallScreen(false);
2366 }
2367 } finally {
2368 Binder.restoreCallingIdentity(ident);
2369 }
2370 }
2371
2372 @Override
2373 public boolean isInLockTaskMode() {
2374 return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
2375 }
2376
2377 @Override
2378 public int getLockTaskModeState() {
2379 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002380 return getLockTaskController().getLockTaskModeState();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002381 }
2382 }
2383
2384 @Override
2385 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
2386 synchronized (mGlobalLock) {
2387 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2388 if (r != null) {
2389 r.setTaskDescription(td);
2390 final TaskRecord task = r.getTask();
2391 task.updateTaskDescription();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002392 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002393 }
2394 }
2395 }
2396
2397 @Override
2398 public Bundle getActivityOptions(IBinder token) {
2399 final long origId = Binder.clearCallingIdentity();
2400 try {
2401 synchronized (mGlobalLock) {
2402 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
2403 if (r != null) {
2404 final ActivityOptions activityOptions = r.takeOptionsLocked();
2405 return activityOptions == null ? null : activityOptions.toBundle();
2406 }
2407 return null;
2408 }
2409 } finally {
2410 Binder.restoreCallingIdentity(origId);
2411 }
2412 }
2413
2414 @Override
2415 public List<IBinder> getAppTasks(String callingPackage) {
2416 int callingUid = Binder.getCallingUid();
2417 long ident = Binder.clearCallingIdentity();
2418 try {
2419 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002420 return mRecentTasks.getAppTasksList(callingUid, callingPackage);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002421 }
2422 } finally {
2423 Binder.restoreCallingIdentity(ident);
2424 }
2425 }
2426
2427 @Override
2428 public void finishVoiceTask(IVoiceInteractionSession session) {
2429 synchronized (mGlobalLock) {
2430 final long origId = Binder.clearCallingIdentity();
2431 try {
2432 // TODO: VI Consider treating local voice interactions and voice tasks
2433 // differently here
2434 mStackSupervisor.finishVoiceTask(session);
2435 } finally {
2436 Binder.restoreCallingIdentity(origId);
2437 }
2438 }
2439
2440 }
2441
2442 @Override
2443 public boolean isTopOfTask(IBinder token) {
2444 synchronized (mGlobalLock) {
2445 ActivityRecord r = ActivityRecord.isInStackLocked(token);
Riddle Hsu66b74a82018-07-26 00:20:12 +08002446 return r != null && r.getTask().getTopActivity() == r;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002447 }
2448 }
2449
2450 @Override
2451 public void notifyLaunchTaskBehindComplete(IBinder token) {
2452 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
2453 }
2454
2455 @Override
2456 public void notifyEnterAnimationComplete(IBinder token) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002457 mH.post(() -> {
2458 synchronized (mGlobalLock) {
2459 ActivityRecord r = ActivityRecord.forTokenLocked(token);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002460 if (r != null && r.attachedToProcess()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002461 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002462 r.app.getThread().scheduleEnterAnimationComplete(r.appToken);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002463 } catch (RemoteException e) {
2464 }
2465 }
2466 }
2467
2468 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002469 }
2470
2471 /** Called from an app when assist data is ready. */
2472 @Override
2473 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
2474 AssistContent content, Uri referrer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002475 PendingAssistExtras pae = (PendingAssistExtras) token;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002476 synchronized (pae) {
2477 pae.result = extras;
2478 pae.structure = structure;
2479 pae.content = content;
2480 if (referrer != null) {
2481 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
2482 }
2483 if (structure != null) {
2484 structure.setHomeActivity(pae.isHome);
2485 }
2486 pae.haveResult = true;
2487 pae.notifyAll();
2488 if (pae.intent == null && pae.receiver == null) {
2489 // Caller is just waiting for the result.
2490 return;
2491 }
2492 }
2493 // We are now ready to launch the assist activity.
2494 IAssistDataReceiver sendReceiver = null;
2495 Bundle sendBundle = null;
2496 synchronized (mGlobalLock) {
2497 buildAssistBundleLocked(pae, extras);
2498 boolean exists = mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002499 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002500 if (!exists) {
2501 // Timed out.
2502 return;
2503 }
2504
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002505 if ((sendReceiver = pae.receiver) != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002506 // Caller wants result sent back to them.
2507 sendBundle = new Bundle();
2508 sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
2509 sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
2510 sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
2511 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
2512 }
2513 }
2514 if (sendReceiver != null) {
2515 try {
2516 sendReceiver.onHandleAssistData(sendBundle);
2517 } catch (RemoteException e) {
2518 }
2519 return;
2520 }
2521
2522 final long ident = Binder.clearCallingIdentity();
2523 try {
2524 if (TextUtils.equals(pae.intent.getAction(),
2525 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
2526 pae.intent.putExtras(pae.extras);
2527 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
2528 } else {
2529 pae.intent.replaceExtras(pae.extras);
2530 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
2531 | Intent.FLAG_ACTIVITY_SINGLE_TOP
2532 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002533 mAmInternal.closeSystemDialogs("assist");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002534
2535 try {
2536 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
2537 } catch (ActivityNotFoundException e) {
2538 Slog.w(TAG, "No activity to handle assist action.", e);
2539 }
2540 }
2541 } finally {
2542 Binder.restoreCallingIdentity(ident);
2543 }
2544 }
2545
2546 @Override
2547 public int addAppTask(IBinder activityToken, Intent intent,
2548 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
2549 final int callingUid = Binder.getCallingUid();
2550 final long callingIdent = Binder.clearCallingIdentity();
2551
2552 try {
2553 synchronized (mGlobalLock) {
2554 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
2555 if (r == null) {
2556 throw new IllegalArgumentException("Activity does not exist; token="
2557 + activityToken);
2558 }
2559 ComponentName comp = intent.getComponent();
2560 if (comp == null) {
2561 throw new IllegalArgumentException("Intent " + intent
2562 + " must specify explicit component");
2563 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002564 if (thumbnail.getWidth() != mThumbnailWidth
2565 || thumbnail.getHeight() != mThumbnailHeight) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002566 throw new IllegalArgumentException("Bad thumbnail size: got "
2567 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002568 + mThumbnailWidth + "x" + mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002569 }
2570 if (intent.getSelector() != null) {
2571 intent.setSelector(null);
2572 }
2573 if (intent.getSourceBounds() != null) {
2574 intent.setSourceBounds(null);
2575 }
2576 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
2577 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
2578 // The caller has added this as an auto-remove task... that makes no
2579 // sense, so turn off auto-remove.
2580 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
2581 }
2582 }
2583 final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
2584 STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
2585 if (ainfo.applicationInfo.uid != callingUid) {
2586 throw new SecurityException(
2587 "Can't add task for another application: target uid="
2588 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
2589 }
2590
2591 final ActivityStack stack = r.getStack();
2592 final TaskRecord task = stack.createTaskRecord(
2593 mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent,
2594 null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002595 if (!mRecentTasks.addToBottom(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002596 // The app has too many tasks already and we can't add any more
2597 stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
2598 return INVALID_TASK_ID;
2599 }
2600 task.lastTaskDescription.copyFrom(description);
2601
2602 // TODO: Send the thumbnail to WM to store it.
2603
2604 return task.taskId;
2605 }
2606 } finally {
2607 Binder.restoreCallingIdentity(callingIdent);
2608 }
2609 }
2610
2611 @Override
2612 public Point getAppTaskThumbnailSize() {
2613 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002614 return new Point(mThumbnailWidth, mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002615 }
2616 }
2617
2618 @Override
2619 public void setTaskResizeable(int taskId, int resizeableMode) {
2620 synchronized (mGlobalLock) {
2621 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
2622 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
2623 if (task == null) {
2624 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
2625 return;
2626 }
2627 task.setResizeMode(resizeableMode);
2628 }
2629 }
2630
2631 @Override
2632 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002633 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002634 long ident = Binder.clearCallingIdentity();
2635 try {
2636 synchronized (mGlobalLock) {
2637 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2638 if (task == null) {
2639 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
2640 return;
2641 }
2642 // Place the task in the right stack if it isn't there already based on
2643 // the requested bounds.
2644 // The stack transition logic is:
2645 // - a null bounds on a freeform task moves that task to fullscreen
2646 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
2647 // that task to freeform
2648 // - otherwise the task is not moved
2649 ActivityStack stack = task.getStack();
2650 if (!task.getWindowConfiguration().canResizeTask()) {
2651 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
2652 }
2653 if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
2654 stack = stack.getDisplay().getOrCreateStack(
2655 WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
2656 } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
2657 stack = stack.getDisplay().getOrCreateStack(
2658 WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
2659 }
2660
2661 // Reparent the task to the right stack if necessary
2662 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
2663 if (stack != task.getStack()) {
2664 // Defer resume until the task is resized below
2665 task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
2666 DEFER_RESUME, "resizeTask");
2667 preserveWindow = false;
2668 }
2669
2670 // After reparenting (which only resizes the task to the stack bounds), resize the
2671 // task to the actual bounds provided
2672 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
2673 }
2674 } finally {
2675 Binder.restoreCallingIdentity(ident);
2676 }
2677 }
2678
2679 @Override
2680 public boolean releaseActivityInstance(IBinder token) {
2681 synchronized (mGlobalLock) {
2682 final long origId = Binder.clearCallingIdentity();
2683 try {
2684 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2685 if (r == null) {
2686 return false;
2687 }
2688 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
2689 } finally {
2690 Binder.restoreCallingIdentity(origId);
2691 }
2692 }
2693 }
2694
2695 @Override
2696 public void releaseSomeActivities(IApplicationThread appInt) {
2697 synchronized (mGlobalLock) {
2698 final long origId = Binder.clearCallingIdentity();
2699 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002700 WindowProcessController app =
2701 mAm.getRecordForAppLocked(appInt).getWindowProcessController();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002702 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
2703 } finally {
2704 Binder.restoreCallingIdentity(origId);
2705 }
2706 }
2707 }
2708
2709 @Override
2710 public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
2711 int secondaryDisplayShowing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002712 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002713 != PackageManager.PERMISSION_GRANTED) {
2714 throw new SecurityException("Requires permission "
2715 + android.Manifest.permission.DEVICE_POWER);
2716 }
2717
2718 synchronized (mGlobalLock) {
2719 long ident = Binder.clearCallingIdentity();
2720 if (mKeyguardShown != keyguardShowing) {
2721 mKeyguardShown = keyguardShowing;
2722 reportCurKeyguardUsageEventLocked(keyguardShowing);
2723 }
2724 try {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002725 mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002726 secondaryDisplayShowing);
2727 } finally {
2728 Binder.restoreCallingIdentity(ident);
2729 }
2730 }
2731
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002732 mH.post(() -> {
2733 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2734 mScreenObservers.get(i).onKeyguardStateChanged(keyguardShowing);
2735 }
2736 });
2737 }
2738
2739 void onScreenAwakeChanged(boolean isAwake) {
2740 mH.post(() -> {
2741 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2742 mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2743 }
2744 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002745 }
2746
2747 @Override
2748 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002749 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
2750 userId, "getTaskDescriptionIcon");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002751
2752 final File passedIconFile = new File(filePath);
2753 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
2754 passedIconFile.getName());
2755 if (!legitIconFile.getPath().equals(filePath)
2756 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
2757 throw new IllegalArgumentException("Bad file path: " + filePath
2758 + " passed for userId " + userId);
2759 }
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002760 return mRecentTasks.getTaskDescriptionIcon(filePath);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002761 }
2762
2763 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002764 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002765 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
2766 final ActivityOptions activityOptions = safeOptions != null
2767 ? safeOptions.getOptions(mStackSupervisor)
2768 : null;
2769 if (activityOptions == null
2770 || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
2771 || activityOptions.getCustomInPlaceResId() == 0) {
2772 throw new IllegalArgumentException("Expected in-place ActivityOption " +
2773 "with valid animation");
2774 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002775 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
2776 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002777 activityOptions.getCustomInPlaceResId());
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002778 mWindowManager.executeAppTransition();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002779 }
2780
2781 @Override
2782 public void removeStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002783 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002784 synchronized (mGlobalLock) {
2785 final long ident = Binder.clearCallingIdentity();
2786 try {
2787 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2788 if (stack == null) {
2789 Slog.w(TAG, "removeStack: No stack with id=" + stackId);
2790 return;
2791 }
2792 if (!stack.isActivityTypeStandardOrUndefined()) {
2793 throw new IllegalArgumentException(
2794 "Removing non-standard stack is not allowed.");
2795 }
2796 mStackSupervisor.removeStack(stack);
2797 } finally {
2798 Binder.restoreCallingIdentity(ident);
2799 }
2800 }
2801 }
2802
2803 @Override
2804 public void moveStackToDisplay(int stackId, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002805 mAmInternal.enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002806
2807 synchronized (mGlobalLock) {
2808 final long ident = Binder.clearCallingIdentity();
2809 try {
2810 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
2811 + " to displayId=" + displayId);
2812 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
2813 } finally {
2814 Binder.restoreCallingIdentity(ident);
2815 }
2816 }
2817 }
2818
2819 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002820 public void exitFreeformMode(IBinder token) {
2821 synchronized (mGlobalLock) {
2822 long ident = Binder.clearCallingIdentity();
2823 try {
2824 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2825 if (r == null) {
2826 throw new IllegalArgumentException(
2827 "exitFreeformMode: No activity record matching token=" + token);
2828 }
2829
2830 final ActivityStack stack = r.getStack();
2831 if (stack == null || !stack.inFreeformWindowingMode()) {
2832 throw new IllegalStateException(
2833 "exitFreeformMode: You can only go fullscreen from freeform.");
2834 }
2835
2836 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
2837 } finally {
2838 Binder.restoreCallingIdentity(ident);
2839 }
2840 }
2841 }
2842
2843 /** Sets the task stack listener that gets callbacks when a task stack changes. */
2844 @Override
2845 public void registerTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002846 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002847 "registerTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002848 mTaskChangeNotificationController.registerTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002849 }
2850
2851 /** Unregister a task stack listener so that it stops receiving callbacks. */
2852 @Override
2853 public void unregisterTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002854 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002855 "unregisterTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002856 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002857 }
2858
2859 private void reportCurKeyguardUsageEventLocked(boolean keyguardShowing) {
2860 mAm.reportGlobalUsageEventLocked(keyguardShowing
2861 ? UsageEvents.Event.KEYGUARD_SHOWN
2862 : UsageEvents.Event.KEYGUARD_HIDDEN);
2863 }
2864
2865 @Override
2866 public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
2867 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
2868 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
2869 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
2870 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
2871 }
2872
2873 @Override
2874 public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
2875 IBinder activityToken, int flags) {
2876 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
2877 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
2878 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
2879 }
2880
2881 @Override
2882 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
2883 Bundle args) {
2884 return enqueueAssistContext(requestType, intent, hint, null, null, null,
2885 true /* focused */, true /* newSessionId */, userHandle, args,
2886 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
2887 }
2888
2889 @Override
2890 public Bundle getAssistContextExtras(int requestType) {
2891 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
2892 null, null, true /* focused */, true /* newSessionId */,
2893 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
2894 if (pae == null) {
2895 return null;
2896 }
2897 synchronized (pae) {
2898 while (!pae.haveResult) {
2899 try {
2900 pae.wait();
2901 } catch (InterruptedException e) {
2902 }
2903 }
2904 }
2905 synchronized (mGlobalLock) {
2906 buildAssistBundleLocked(pae, pae.result);
2907 mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002908 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002909 }
2910 return pae.extras;
2911 }
2912
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002913 /**
2914 * Binder IPC calls go through the public entry point.
2915 * This can be called with or without the global lock held.
2916 */
2917 private static int checkCallingPermission(String permission) {
2918 return checkPermission(
2919 permission, Binder.getCallingPid(), UserHandle.getAppId(Binder.getCallingUid()));
2920 }
2921
2922 /** This can be called with or without the global lock held. */
2923 void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
2924 if (!getRecentTasks().isCallerRecents(Binder.getCallingUid())) {
2925 mAmInternal.enforceCallingPermission(permission, func);
2926 }
2927 }
2928
2929 @VisibleForTesting
2930 int checkGetTasksPermission(String permission, int pid, int uid) {
2931 return checkPermission(permission, pid, uid);
2932 }
2933
2934 static int checkPermission(String permission, int pid, int uid) {
2935 if (permission == null) {
2936 return PackageManager.PERMISSION_DENIED;
2937 }
2938 return checkComponentPermission(permission, pid, uid, -1, true);
2939 }
2940
2941 boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
2942 if (getRecentTasks().isCallerRecents(callingUid)) {
2943 // Always allow the recents component to get tasks
2944 return true;
2945 }
2946
2947 boolean allowed = checkGetTasksPermission(android.Manifest.permission.REAL_GET_TASKS,
2948 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
2949 if (!allowed) {
2950 if (checkGetTasksPermission(android.Manifest.permission.GET_TASKS,
2951 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
2952 // Temporary compatibility: some existing apps on the system image may
2953 // still be requesting the old permission and not switched to the new
2954 // one; if so, we'll still allow them full access. This means we need
2955 // to see if they are holding the old permission and are a system app.
2956 try {
2957 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
2958 allowed = true;
2959 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
2960 + " is using old GET_TASKS but privileged; allowing");
2961 }
2962 } catch (RemoteException e) {
2963 }
2964 }
2965 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
2966 + " does not hold REAL_GET_TASKS; limiting output");
2967 }
2968 return allowed;
2969 }
2970
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002971 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
2972 IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
2973 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
2974 int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002975 mAmInternal.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002976 "enqueueAssistContext()");
2977
2978 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002979 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002980 if (activity == null) {
2981 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
2982 return null;
2983 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002984 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002985 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
2986 return null;
2987 }
2988 if (focused) {
2989 if (activityToken != null) {
2990 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
2991 if (activity != caller) {
2992 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
2993 + " is not current top " + activity);
2994 return null;
2995 }
2996 }
2997 } else {
2998 activity = ActivityRecord.forTokenLocked(activityToken);
2999 if (activity == null) {
3000 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
3001 + " couldn't be found");
3002 return null;
3003 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003004 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003005 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
3006 return null;
3007 }
3008 }
3009
3010 PendingAssistExtras pae;
3011 Bundle extras = new Bundle();
3012 if (args != null) {
3013 extras.putAll(args);
3014 }
3015 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003016 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003017
3018 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
3019 userHandle);
3020 pae.isHome = activity.isActivityTypeHome();
3021
3022 // Increment the sessionId if necessary
3023 if (newSessionId) {
3024 mViSessionId++;
3025 }
3026 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003027 activity.app.getThread().requestAssistContextExtras(activity.appToken, pae,
3028 requestType, mViSessionId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003029 mPendingAssistExtras.add(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003030 mUiHandler.postDelayed(pae, timeout);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003031 } catch (RemoteException e) {
3032 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
3033 return null;
3034 }
3035 return pae;
3036 }
3037 }
3038
3039 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
3040 if (result != null) {
3041 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
3042 }
3043 if (pae.hint != null) {
3044 pae.extras.putBoolean(pae.hint, true);
3045 }
3046 }
3047
3048 private void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
3049 IAssistDataReceiver receiver;
3050 synchronized (mGlobalLock) {
3051 mPendingAssistExtras.remove(pae);
3052 receiver = pae.receiver;
3053 }
3054 if (receiver != null) {
3055 // Caller wants result sent back to them.
3056 Bundle sendBundle = new Bundle();
3057 // At least return the receiver extras
3058 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
3059 try {
3060 pae.receiver.onHandleAssistData(sendBundle);
3061 } catch (RemoteException e) {
3062 }
3063 }
3064 }
3065
3066 public class PendingAssistExtras extends Binder implements Runnable {
3067 public final ActivityRecord activity;
3068 public boolean isHome;
3069 public final Bundle extras;
3070 public final Intent intent;
3071 public final String hint;
3072 public final IAssistDataReceiver receiver;
3073 public final int userHandle;
3074 public boolean haveResult = false;
3075 public Bundle result = null;
3076 public AssistStructure structure = null;
3077 public AssistContent content = null;
3078 public Bundle receiverExtras;
3079
3080 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
3081 String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
3082 int _userHandle) {
3083 activity = _activity;
3084 extras = _extras;
3085 intent = _intent;
3086 hint = _hint;
3087 receiver = _receiver;
3088 receiverExtras = _receiverExtras;
3089 userHandle = _userHandle;
3090 }
3091
3092 @Override
3093 public void run() {
3094 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
3095 synchronized (this) {
3096 haveResult = true;
3097 notifyAll();
3098 }
3099 pendingAssistExtrasTimedOut(this);
3100 }
3101 }
3102
3103 @Override
3104 public boolean isAssistDataAllowedOnCurrentActivity() {
3105 int userId;
3106 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003107 final ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003108 if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
3109 return false;
3110 }
3111
3112 final ActivityRecord activity = focusedStack.getTopActivity();
3113 if (activity == null) {
3114 return false;
3115 }
3116 userId = activity.userId;
3117 }
3118 return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
3119 }
3120
3121 @Override
3122 public boolean showAssistFromActivity(IBinder token, Bundle args) {
3123 long ident = Binder.clearCallingIdentity();
3124 try {
3125 synchronized (mGlobalLock) {
3126 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003127 ActivityRecord top = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003128 if (top != caller) {
3129 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3130 + " is not current top " + top);
3131 return false;
3132 }
3133 if (!top.nowVisible) {
3134 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3135 + " is not visible");
3136 return false;
3137 }
3138 }
3139 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
3140 token);
3141 } finally {
3142 Binder.restoreCallingIdentity(ident);
3143 }
3144 }
3145
3146 @Override
3147 public boolean isRootVoiceInteraction(IBinder token) {
3148 synchronized (mGlobalLock) {
3149 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3150 if (r == null) {
3151 return false;
3152 }
3153 return r.rootVoiceInteraction;
3154 }
3155 }
3156
Wale Ogunwalef6733932018-06-27 05:14:34 -07003157 private void onLocalVoiceInteractionStartedLocked(IBinder activity,
3158 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
3159 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
3160 if (activityToCallback == null) return;
3161 activityToCallback.setVoiceSessionLocked(voiceSession);
3162
3163 // Inform the activity
3164 try {
3165 activityToCallback.app.getThread().scheduleLocalVoiceInteractionStarted(activity,
3166 voiceInteractor);
3167 long token = Binder.clearCallingIdentity();
3168 try {
3169 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
3170 } finally {
3171 Binder.restoreCallingIdentity(token);
3172 }
3173 // TODO: VI Should we cache the activity so that it's easier to find later
3174 // rather than scan through all the stacks and activities?
3175 } catch (RemoteException re) {
3176 activityToCallback.clearVoiceSessionLocked();
3177 // TODO: VI Should this terminate the voice session?
3178 }
3179 }
3180
3181 private void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
3182 Slog.d(TAG, "<<< startRunningVoiceLocked()");
3183 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
3184 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
3185 boolean wasRunningVoice = mRunningVoice != null;
3186 mRunningVoice = session;
3187 if (!wasRunningVoice) {
3188 mVoiceWakeLock.acquire();
3189 updateSleepIfNeededLocked();
3190 }
3191 }
3192 }
3193
3194 void finishRunningVoiceLocked() {
3195 if (mRunningVoice != null) {
3196 mRunningVoice = null;
3197 mVoiceWakeLock.release();
3198 updateSleepIfNeededLocked();
3199 }
3200 }
3201
3202 @Override
3203 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3204 synchronized (mGlobalLock) {
3205 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3206 if (keepAwake) {
3207 mVoiceWakeLock.acquire();
3208 } else {
3209 mVoiceWakeLock.release();
3210 }
3211 }
3212 }
3213 }
3214
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003215 @Override
3216 public ComponentName getActivityClassForToken(IBinder token) {
3217 synchronized (mGlobalLock) {
3218 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3219 if (r == null) {
3220 return null;
3221 }
3222 return r.intent.getComponent();
3223 }
3224 }
3225
3226 @Override
3227 public String getPackageForToken(IBinder token) {
3228 synchronized (mGlobalLock) {
3229 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3230 if (r == null) {
3231 return null;
3232 }
3233 return r.packageName;
3234 }
3235 }
3236
3237 @Override
3238 public void showLockTaskEscapeMessage(IBinder token) {
3239 synchronized (mGlobalLock) {
3240 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3241 if (r == null) {
3242 return;
3243 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003244 getLockTaskController().showLockTaskToast();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003245 }
3246 }
3247
3248 @Override
3249 public void keyguardGoingAway(int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003250 enforceNotIsolatedCaller("keyguardGoingAway");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003251 final long token = Binder.clearCallingIdentity();
3252 try {
3253 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003254 mKeyguardController.keyguardGoingAway(flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003255 }
3256 } finally {
3257 Binder.restoreCallingIdentity(token);
3258 }
3259 }
3260
3261 /**
3262 * Try to place task to provided position. The final position might be different depending on
3263 * current user and stacks state. The task will be moved to target stack if it's currently in
3264 * different stack.
3265 */
3266 @Override
3267 public void positionTaskInStack(int taskId, int stackId, int position) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003268 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003269 synchronized (mGlobalLock) {
3270 long ident = Binder.clearCallingIdentity();
3271 try {
3272 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
3273 + taskId + " in stackId=" + stackId + " at position=" + position);
3274 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3275 if (task == null) {
3276 throw new IllegalArgumentException("positionTaskInStack: no task for id="
3277 + taskId);
3278 }
3279
3280 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3281
3282 if (stack == null) {
3283 throw new IllegalArgumentException("positionTaskInStack: no stack for id="
3284 + stackId);
3285 }
3286 if (!stack.isActivityTypeStandardOrUndefined()) {
3287 throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
3288 + " the position of task " + taskId + " in/to non-standard stack");
3289 }
3290
3291 // TODO: Have the callers of this API call a separate reparent method if that is
3292 // what they intended to do vs. having this method also do reparenting.
3293 if (task.getStack() == stack) {
3294 // Change position in current stack.
3295 stack.positionChildAt(task, position);
3296 } else {
3297 // Reparent to new stack.
3298 task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
3299 !DEFER_RESUME, "positionTaskInStack");
3300 }
3301 } finally {
3302 Binder.restoreCallingIdentity(ident);
3303 }
3304 }
3305 }
3306
3307 @Override
3308 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
3309 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
3310 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
3311 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
3312 synchronized (mGlobalLock) {
3313 ActivityRecord record = ActivityRecord.isInStackLocked(token);
3314 if (record == null) {
3315 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
3316 + "found for: " + token);
3317 }
3318 record.setSizeConfigurations(horizontalSizeConfiguration,
3319 verticalSizeConfigurations, smallestSizeConfigurations);
3320 }
3321 }
3322
3323 /**
3324 * Dismisses split-screen multi-window mode.
3325 * @param toTop If true the current primary split-screen stack will be placed or left on top.
3326 */
3327 @Override
3328 public void dismissSplitScreenMode(boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003329 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003330 MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
3331 final long ident = Binder.clearCallingIdentity();
3332 try {
3333 synchronized (mGlobalLock) {
3334 final ActivityStack stack =
3335 mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
3336 if (stack == null) {
3337 Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
3338 return;
3339 }
3340
3341 if (toTop) {
3342 // Caller wants the current split-screen primary stack to be the top stack after
3343 // it goes fullscreen, so move it to the front.
3344 stack.moveToFront("dismissSplitScreenMode");
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003345 } else if (mStackSupervisor.isTopDisplayFocusedStack(stack)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003346 // In this case the current split-screen primary stack shouldn't be the top
3347 // stack after it goes fullscreen, but it current has focus, so we move the
3348 // focus to the top-most split-screen secondary stack next to it.
3349 final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
3350 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
3351 if (otherStack != null) {
3352 otherStack.moveToFront("dismissSplitScreenMode_other");
3353 }
3354 }
3355
Evan Rosky10475742018-09-05 19:02:48 -07003356 stack.setWindowingMode(WINDOWING_MODE_UNDEFINED);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003357 }
3358 } finally {
3359 Binder.restoreCallingIdentity(ident);
3360 }
3361 }
3362
3363 /**
3364 * Dismisses Pip
3365 * @param animate True if the dismissal should be animated.
3366 * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
3367 * default animation duration should be used.
3368 */
3369 @Override
3370 public void dismissPip(boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003371 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003372 final long ident = Binder.clearCallingIdentity();
3373 try {
3374 synchronized (mGlobalLock) {
3375 final PinnedActivityStack stack =
3376 mStackSupervisor.getDefaultDisplay().getPinnedStack();
3377 if (stack == null) {
3378 Slog.w(TAG, "dismissPip: pinned stack not found.");
3379 return;
3380 }
3381 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
3382 throw new IllegalArgumentException("Stack: " + stack
3383 + " doesn't support animated resize.");
3384 }
3385 if (animate) {
3386 stack.animateResizePinnedStack(null /* sourceHintBounds */,
3387 null /* destBounds */, animationDuration, false /* fromFullscreen */);
3388 } else {
3389 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
3390 }
3391 }
3392 } finally {
3393 Binder.restoreCallingIdentity(ident);
3394 }
3395 }
3396
3397 @Override
3398 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003399 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003400 synchronized (mGlobalLock) {
3401 mSuppressResizeConfigChanges = suppress;
3402 }
3403 }
3404
3405 /**
3406 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
3407 * animated the stack to the fullscreen, but can also be called if we are relaunching an
3408 * activity and clearing the task at the same time.
3409 */
3410 @Override
3411 // TODO: API should just be about changing windowing modes...
3412 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003413 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003414 "moveTasksToFullscreenStack()");
3415 synchronized (mGlobalLock) {
3416 final long origId = Binder.clearCallingIdentity();
3417 try {
3418 final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
3419 if (stack != null){
3420 if (!stack.isActivityTypeStandardOrUndefined()) {
3421 throw new IllegalArgumentException(
3422 "You can't move tasks from non-standard stacks.");
3423 }
3424 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
3425 }
3426 } finally {
3427 Binder.restoreCallingIdentity(origId);
3428 }
3429 }
3430 }
3431
3432 /**
3433 * Moves the top activity in the input stackId to the pinned stack.
3434 *
3435 * @param stackId Id of stack to move the top activity to pinned stack.
3436 * @param bounds Bounds to use for pinned stack.
3437 *
3438 * @return True if the top activity of the input stack was successfully moved to the pinned
3439 * stack.
3440 */
3441 @Override
3442 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003443 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003444 "moveTopActivityToPinnedStack()");
3445 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003446 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003447 throw new IllegalStateException("moveTopActivityToPinnedStack:"
3448 + "Device doesn't support picture-in-picture mode");
3449 }
3450
3451 long ident = Binder.clearCallingIdentity();
3452 try {
3453 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
3454 } finally {
3455 Binder.restoreCallingIdentity(ident);
3456 }
3457 }
3458 }
3459
3460 @Override
3461 public boolean isInMultiWindowMode(IBinder token) {
3462 final long origId = Binder.clearCallingIdentity();
3463 try {
3464 synchronized (mGlobalLock) {
3465 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3466 if (r == null) {
3467 return false;
3468 }
3469 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
3470 return r.inMultiWindowMode();
3471 }
3472 } finally {
3473 Binder.restoreCallingIdentity(origId);
3474 }
3475 }
3476
3477 @Override
3478 public boolean isInPictureInPictureMode(IBinder token) {
3479 final long origId = Binder.clearCallingIdentity();
3480 try {
3481 synchronized (mGlobalLock) {
3482 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
3483 }
3484 } finally {
3485 Binder.restoreCallingIdentity(origId);
3486 }
3487 }
3488
3489 private boolean isInPictureInPictureMode(ActivityRecord r) {
3490 if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
3491 || r.getStack().isInStackLocked(r) == null) {
3492 return false;
3493 }
3494
3495 // If we are animating to fullscreen then we have already dispatched the PIP mode
3496 // changed, so we should reflect that check here as well.
3497 final PinnedActivityStack stack = r.getStack();
3498 final PinnedStackWindowController windowController = stack.getWindowContainerController();
3499 return !windowController.isAnimatingBoundsToFullscreen();
3500 }
3501
3502 @Override
3503 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
3504 final long origId = Binder.clearCallingIdentity();
3505 try {
3506 synchronized (mGlobalLock) {
3507 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3508 "enterPictureInPictureMode", token, params);
3509
3510 // If the activity is already in picture in picture mode, then just return early
3511 if (isInPictureInPictureMode(r)) {
3512 return true;
3513 }
3514
3515 // Activity supports picture-in-picture, now check that we can enter PiP at this
3516 // point, if it is
3517 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
3518 false /* beforeStopping */)) {
3519 return false;
3520 }
3521
3522 final Runnable enterPipRunnable = () -> {
Wale Ogunwalef276a6f2018-06-15 08:26:07 -07003523 synchronized (mGlobalLock) {
3524 // Only update the saved args from the args that are set
3525 r.pictureInPictureArgs.copyOnlySet(params);
3526 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
3527 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
3528 // Adjust the source bounds by the insets for the transition down
3529 final Rect sourceBounds = new Rect(
3530 r.pictureInPictureArgs.getSourceRectHint());
3531 mStackSupervisor.moveActivityToPinnedStackLocked(
3532 r, sourceBounds, aspectRatio, "enterPictureInPictureMode");
3533 final PinnedActivityStack stack = r.getStack();
3534 stack.setPictureInPictureAspectRatio(aspectRatio);
3535 stack.setPictureInPictureActions(actions);
3536 MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
3537 r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
3538 logPictureInPictureArgs(params);
3539 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003540 };
3541
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003542 if (isKeyguardLocked()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003543 // If the keyguard is showing or occluded, then try and dismiss it before
3544 // entering picture-in-picture (this will prompt the user to authenticate if the
3545 // device is currently locked).
3546 dismissKeyguard(token, new KeyguardDismissCallback() {
3547 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003548 public void onDismissSucceeded() {
3549 mH.post(enterPipRunnable);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003550 }
3551 }, null /* message */);
3552 } else {
3553 // Enter picture in picture immediately otherwise
3554 enterPipRunnable.run();
3555 }
3556 return true;
3557 }
3558 } finally {
3559 Binder.restoreCallingIdentity(origId);
3560 }
3561 }
3562
3563 @Override
3564 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
3565 final long origId = Binder.clearCallingIdentity();
3566 try {
3567 synchronized (mGlobalLock) {
3568 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3569 "setPictureInPictureParams", token, params);
3570
3571 // Only update the saved args from the args that are set
3572 r.pictureInPictureArgs.copyOnlySet(params);
3573 if (r.inPinnedWindowingMode()) {
3574 // If the activity is already in picture-in-picture, update the pinned stack now
3575 // if it is not already expanding to fullscreen. Otherwise, the arguments will
3576 // be used the next time the activity enters PiP
3577 final PinnedActivityStack stack = r.getStack();
3578 if (!stack.isAnimatingBoundsToFullscreen()) {
3579 stack.setPictureInPictureAspectRatio(
3580 r.pictureInPictureArgs.getAspectRatio());
3581 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
3582 }
3583 }
3584 logPictureInPictureArgs(params);
3585 }
3586 } finally {
3587 Binder.restoreCallingIdentity(origId);
3588 }
3589 }
3590
3591 @Override
3592 public int getMaxNumPictureInPictureActions(IBinder token) {
3593 // Currently, this is a static constant, but later, we may change this to be dependent on
3594 // the context of the activity
3595 return 3;
3596 }
3597
3598 private void logPictureInPictureArgs(PictureInPictureParams params) {
3599 if (params.hasSetActions()) {
3600 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
3601 params.getActions().size());
3602 }
3603 if (params.hasSetAspectRatio()) {
3604 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
3605 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
3606 MetricsLogger.action(lm);
3607 }
3608 }
3609
3610 /**
3611 * Checks the state of the system and the activity associated with the given {@param token} to
3612 * verify that picture-in-picture is supported for that activity.
3613 *
3614 * @return the activity record for the given {@param token} if all the checks pass.
3615 */
3616 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
3617 IBinder token, PictureInPictureParams params) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003618 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003619 throw new IllegalStateException(caller
3620 + ": Device doesn't support picture-in-picture mode.");
3621 }
3622
3623 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3624 if (r == null) {
3625 throw new IllegalStateException(caller
3626 + ": Can't find activity for token=" + token);
3627 }
3628
3629 if (!r.supportsPictureInPicture()) {
3630 throw new IllegalStateException(caller
3631 + ": Current activity does not support picture-in-picture.");
3632 }
3633
3634 if (params.hasSetAspectRatio()
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003635 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003636 params.getAspectRatio())) {
3637 final float minAspectRatio = mContext.getResources().getFloat(
3638 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
3639 final float maxAspectRatio = mContext.getResources().getFloat(
3640 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
3641 throw new IllegalArgumentException(String.format(caller
3642 + ": Aspect ratio is too extreme (must be between %f and %f).",
3643 minAspectRatio, maxAspectRatio));
3644 }
3645
3646 // Truncate the number of actions if necessary
3647 params.truncateActions(getMaxNumPictureInPictureActions(token));
3648
3649 return r;
3650 }
3651
3652 @Override
3653 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003654 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003655 synchronized (mGlobalLock) {
3656 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
3657 if (r == null) {
3658 throw new IllegalArgumentException("Activity does not exist; token="
3659 + activityToken);
3660 }
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07003661 return r.getUriPermissionsLocked().getExternalToken();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003662 }
3663 }
3664
3665 @Override
3666 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
3667 Rect tempDockedTaskInsetBounds,
3668 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003669 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003670 long ident = Binder.clearCallingIdentity();
3671 try {
3672 synchronized (mGlobalLock) {
3673 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
3674 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
3675 PRESERVE_WINDOWS);
3676 }
3677 } finally {
3678 Binder.restoreCallingIdentity(ident);
3679 }
3680 }
3681
3682 @Override
3683 public void setSplitScreenResizing(boolean resizing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003684 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003685 final long ident = Binder.clearCallingIdentity();
3686 try {
3687 synchronized (mGlobalLock) {
3688 mStackSupervisor.setSplitScreenResizing(resizing);
3689 }
3690 } finally {
3691 Binder.restoreCallingIdentity(ident);
3692 }
3693 }
3694
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003695 /**
3696 * Check that we have the features required for VR-related API calls, and throw an exception if
3697 * not.
3698 */
3699 void enforceSystemHasVrFeature() {
3700 if (!mContext.getPackageManager().hasSystemFeature(
3701 PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
3702 throw new UnsupportedOperationException("VR mode not supported on this device!");
3703 }
3704 }
3705
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003706 @Override
3707 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003708 enforceSystemHasVrFeature();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003709
3710 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3711
3712 ActivityRecord r;
3713 synchronized (mGlobalLock) {
3714 r = ActivityRecord.isInStackLocked(token);
3715 }
3716
3717 if (r == null) {
3718 throw new IllegalArgumentException();
3719 }
3720
3721 int err;
3722 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
3723 VrManagerInternal.NO_ERROR) {
3724 return err;
3725 }
3726
3727 // Clear the binder calling uid since this path may call moveToTask().
3728 final long callingId = Binder.clearCallingIdentity();
3729 try {
3730 synchronized (mGlobalLock) {
3731 r.requestedVrComponent = (enabled) ? packageName : null;
3732
3733 // Update associated state if this activity is currently focused
Andrii Kulian52d255c2018-07-13 11:32:19 -07003734 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003735 applyUpdateVrModeLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003736 }
3737 return 0;
3738 }
3739 } finally {
3740 Binder.restoreCallingIdentity(callingId);
3741 }
3742 }
3743
3744 @Override
3745 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
3746 Slog.i(TAG, "Activity tried to startLocalVoiceInteraction");
3747 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003748 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003749 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
3750 throw new SecurityException("Only focused activity can call startVoiceInteraction");
3751 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07003752 if (mRunningVoice != null || activity.getTask().voiceSession != null
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003753 || activity.voiceSession != null) {
3754 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
3755 return;
3756 }
3757 if (activity.pendingVoiceInteractionStart) {
3758 Slog.w(TAG, "Pending start of voice interaction already.");
3759 return;
3760 }
3761 activity.pendingVoiceInteractionStart = true;
3762 }
3763 LocalServices.getService(VoiceInteractionManagerInternal.class)
3764 .startLocalVoiceInteraction(callingActivity, options);
3765 }
3766
3767 @Override
3768 public void stopLocalVoiceInteraction(IBinder callingActivity) {
3769 LocalServices.getService(VoiceInteractionManagerInternal.class)
3770 .stopLocalVoiceInteraction(callingActivity);
3771 }
3772
3773 @Override
3774 public boolean supportsLocalVoiceInteraction() {
3775 return LocalServices.getService(VoiceInteractionManagerInternal.class)
3776 .supportsLocalVoiceInteraction();
3777 }
3778
3779 /** Notifies all listeners when the pinned stack animation starts. */
3780 @Override
3781 public void notifyPinnedStackAnimationStarted() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003782 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003783 }
3784
3785 /** Notifies all listeners when the pinned stack animation ends. */
3786 @Override
3787 public void notifyPinnedStackAnimationEnded() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003788 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003789 }
3790
3791 @Override
3792 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003793 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003794 final long ident = Binder.clearCallingIdentity();
3795 try {
3796 synchronized (mGlobalLock) {
3797 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
3798 }
3799 } finally {
3800 Binder.restoreCallingIdentity(ident);
3801 }
3802 }
3803
3804 @Override
3805 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003806 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003807
3808 synchronized (mGlobalLock) {
3809 // Check if display is initialized in AM.
3810 if (!mStackSupervisor.isDisplayAdded(displayId)) {
3811 // Call might come when display is not yet added or has already been removed.
3812 if (DEBUG_CONFIGURATION) {
3813 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
3814 + displayId);
3815 }
3816 return false;
3817 }
3818
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003819 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003820 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003821 values = mWindowManager.computeNewConfiguration(displayId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003822 }
3823
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003824 if (mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003825 // Update OOM levels based on display size.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003826 mAm.mProcessList.applyDisplaySize(mWindowManager);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003827 }
3828
3829 final long origId = Binder.clearCallingIdentity();
3830 try {
3831 if (values != null) {
3832 Settings.System.clearConfiguration(values);
3833 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003834 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003835 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
3836 return mTmpUpdateConfigurationResult.changes != 0;
3837 } finally {
3838 Binder.restoreCallingIdentity(origId);
3839 }
3840 }
3841 }
3842
3843 @Override
3844 public boolean updateConfiguration(Configuration values) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003845 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003846
3847 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003848 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003849 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003850 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003851 }
3852
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003853 if (mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003854 // Update OOM levels based on display size.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003855 mAm.mProcessList.applyDisplaySize(mWindowManager);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003856 }
3857
3858 final long origId = Binder.clearCallingIdentity();
3859 try {
3860 if (values != null) {
3861 Settings.System.clearConfiguration(values);
3862 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003863 updateConfigurationLocked(values, null, false, false /* persistent */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003864 UserHandle.USER_NULL, false /* deferResume */,
3865 mTmpUpdateConfigurationResult);
3866 return mTmpUpdateConfigurationResult.changes != 0;
3867 } finally {
3868 Binder.restoreCallingIdentity(origId);
3869 }
3870 }
3871 }
3872
3873 @Override
3874 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
3875 CharSequence message) {
3876 if (message != null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003877 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003878 Manifest.permission.SHOW_KEYGUARD_MESSAGE, "dismissKeyguard()");
3879 }
3880 final long callingId = Binder.clearCallingIdentity();
3881 try {
3882 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003883 mKeyguardController.dismissKeyguard(token, callback, message);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003884 }
3885 } finally {
3886 Binder.restoreCallingIdentity(callingId);
3887 }
3888 }
3889
3890 @Override
3891 public void cancelTaskWindowTransition(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003892 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003893 "cancelTaskWindowTransition()");
3894 final long ident = Binder.clearCallingIdentity();
3895 try {
3896 synchronized (mGlobalLock) {
3897 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
3898 MATCH_TASK_IN_STACKS_ONLY);
3899 if (task == null) {
3900 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
3901 return;
3902 }
3903 task.cancelWindowTransition();
3904 }
3905 } finally {
3906 Binder.restoreCallingIdentity(ident);
3907 }
3908 }
3909
3910 @Override
3911 public ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003912 enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003913 final long ident = Binder.clearCallingIdentity();
3914 try {
3915 final TaskRecord task;
3916 synchronized (mGlobalLock) {
3917 task = mStackSupervisor.anyTaskForIdLocked(taskId,
3918 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
3919 if (task == null) {
3920 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
3921 return null;
3922 }
3923 }
3924 // Don't call this while holding the lock as this operation might hit the disk.
3925 return task.getSnapshot(reducedResolution);
3926 } finally {
3927 Binder.restoreCallingIdentity(ident);
3928 }
3929 }
3930
3931 @Override
3932 public void setDisablePreviewScreenshots(IBinder token, boolean disable) {
3933 synchronized (mGlobalLock) {
3934 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3935 if (r == null) {
3936 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
3937 + token);
3938 return;
3939 }
3940 final long origId = Binder.clearCallingIdentity();
3941 try {
3942 r.setDisablePreviewScreenshots(disable);
3943 } finally {
3944 Binder.restoreCallingIdentity(origId);
3945 }
3946 }
3947 }
3948
3949 /** Return the user id of the last resumed activity. */
3950 @Override
3951 public @UserIdInt
3952 int getLastResumedActivityUserId() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003953 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003954 Manifest.permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
3955 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07003956 if (mLastResumedActivity == null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003957 return getCurrentUserId();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003958 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07003959 return mLastResumedActivity.userId;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003960 }
3961 }
3962
3963 @Override
3964 public void updateLockTaskFeatures(int userId, int flags) {
3965 final int callingUid = Binder.getCallingUid();
3966 if (callingUid != 0 && callingUid != SYSTEM_UID) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003967 mAmInternal.enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003968 "updateLockTaskFeatures()");
3969 }
3970 synchronized (mGlobalLock) {
3971 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
3972 Integer.toHexString(flags));
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003973 getLockTaskController().updateLockTaskFeatures(userId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003974 }
3975 }
3976
3977 @Override
3978 public void setShowWhenLocked(IBinder token, boolean showWhenLocked) {
3979 synchronized (mGlobalLock) {
3980 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3981 if (r == null) {
3982 return;
3983 }
3984 final long origId = Binder.clearCallingIdentity();
3985 try {
3986 r.setShowWhenLocked(showWhenLocked);
3987 } finally {
3988 Binder.restoreCallingIdentity(origId);
3989 }
3990 }
3991 }
3992
3993 @Override
3994 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) {
3995 synchronized (mGlobalLock) {
3996 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3997 if (r == null) {
3998 return;
3999 }
4000 final long origId = Binder.clearCallingIdentity();
4001 try {
4002 r.setTurnScreenOn(turnScreenOn);
4003 } finally {
4004 Binder.restoreCallingIdentity(origId);
4005 }
4006 }
4007 }
4008
4009 @Override
4010 public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004011 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004012 "registerRemoteAnimations");
4013 definition.setCallingPid(Binder.getCallingPid());
4014 synchronized (mGlobalLock) {
4015 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4016 if (r == null) {
4017 return;
4018 }
4019 final long origId = Binder.clearCallingIdentity();
4020 try {
4021 r.registerRemoteAnimations(definition);
4022 } finally {
4023 Binder.restoreCallingIdentity(origId);
4024 }
4025 }
4026 }
4027
4028 @Override
4029 public void registerRemoteAnimationForNextActivityStart(String packageName,
4030 RemoteAnimationAdapter adapter) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004031 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004032 "registerRemoteAnimationForNextActivityStart");
4033 adapter.setCallingPid(Binder.getCallingPid());
4034 synchronized (mGlobalLock) {
4035 final long origId = Binder.clearCallingIdentity();
4036 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07004037 getActivityStartController().registerRemoteAnimationForNextActivityStart(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004038 packageName, adapter);
4039 } finally {
4040 Binder.restoreCallingIdentity(origId);
4041 }
4042 }
4043 }
4044
4045 /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
4046 @Override
4047 public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
4048 synchronized (mGlobalLock) {
4049 final long origId = Binder.clearCallingIdentity();
4050 try {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004051 mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004052 } finally {
4053 Binder.restoreCallingIdentity(origId);
4054 }
4055 }
4056 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004057
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004058 @Override
4059 public void setVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004060 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004061 synchronized (mGlobalLock) {
4062 synchronized (mAm.mPidsSelfLocked) {
4063 final int pid = Binder.getCallingPid();
4064 final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004065 mVrController.setVrThreadLocked(tid, pid, proc.getWindowProcessController());
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004066 }
4067 }
4068 }
4069
4070 @Override
4071 public void setPersistentVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004072 if (checkCallingPermission(Manifest.permission.RESTRICTED_VR_ACCESS)
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004073 != PERMISSION_GRANTED) {
4074 final String msg = "Permission Denial: setPersistentVrThread() from pid="
4075 + Binder.getCallingPid()
4076 + ", uid=" + Binder.getCallingUid()
4077 + " requires " + Manifest.permission.RESTRICTED_VR_ACCESS;
4078 Slog.w(TAG, msg);
4079 throw new SecurityException(msg);
4080 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004081 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004082 synchronized (mGlobalLock) {
4083 synchronized (mAm.mPidsSelfLocked) {
4084 final int pid = Binder.getCallingPid();
4085 final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
4086 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
4087 }
4088 }
4089 }
4090
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004091 @Override
4092 public void stopAppSwitches() {
4093 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
4094 synchronized (mGlobalLock) {
4095 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME;
4096 mDidAppSwitch = false;
4097 getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
4098 }
4099 }
4100
4101 @Override
4102 public void resumeAppSwitches() {
4103 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
4104 synchronized (mGlobalLock) {
4105 // Note that we don't execute any pending app switches... we will
4106 // let those wait until either the timeout, or the next start
4107 // activity request.
4108 mAppSwitchesAllowedTime = 0;
4109 }
4110 }
4111
4112 void onStartActivitySetDidAppSwitch() {
4113 if (mDidAppSwitch) {
4114 // This is the second allowed switch since we stopped switches, so now just generally
4115 // allow switches. Use case:
4116 // - user presses home (switches disabled, switch to home, mDidAppSwitch now true);
4117 // - user taps a home icon (coming from home so allowed, we hit here and now allow
4118 // anyone to switch again).
4119 mAppSwitchesAllowedTime = 0;
4120 } else {
4121 mDidAppSwitch = true;
4122 }
4123 }
4124
4125 /** @return whether the system should disable UI modes incompatible with VR mode. */
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004126 boolean shouldDisableNonVrUiLocked() {
4127 return mVrController.shouldDisableNonVrUiLocked();
4128 }
4129
Wale Ogunwale53783742018-09-16 10:21:51 -07004130 private void applyUpdateVrModeLocked(ActivityRecord r) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004131 // VR apps are expected to run in a main display. If an app is turning on VR for
4132 // itself, but lives in a dynamic stack, then make sure that it is moved to the main
4133 // fullscreen stack before enabling VR Mode.
4134 // TODO: The goal of this code is to keep the VR app on the main display. When the
4135 // stack implementation changes in the future, keep in mind that the use of the fullscreen
4136 // stack is a means to move the activity to the main display and a moveActivityToDisplay()
4137 // option would be a better choice here.
4138 if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
4139 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
4140 + " to main stack for VR");
4141 final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
4142 WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
4143 moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
4144 }
4145 mH.post(() -> {
4146 if (!mVrController.onVrModeChanged(r)) {
4147 return;
4148 }
4149 synchronized (mGlobalLock) {
4150 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
4151 mWindowManager.disableNonVrUi(disableNonVrUi);
4152 if (disableNonVrUi) {
4153 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
4154 // then remove the pinned stack.
4155 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
4156 }
4157 }
4158 });
4159 }
4160
Wale Ogunwale53783742018-09-16 10:21:51 -07004161 @Override
4162 public int getPackageScreenCompatMode(String packageName) {
4163 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4164 synchronized (mGlobalLock) {
4165 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4166 }
4167 }
4168
4169 @Override
4170 public void setPackageScreenCompatMode(String packageName, int mode) {
4171 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4172 "setPackageScreenCompatMode");
4173 synchronized (mGlobalLock) {
4174 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4175 }
4176 }
4177
4178 @Override
4179 public boolean getPackageAskScreenCompat(String packageName) {
4180 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4181 synchronized (mGlobalLock) {
4182 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4183 }
4184 }
4185
4186 @Override
4187 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4188 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4189 "setPackageAskScreenCompat");
4190 synchronized (mGlobalLock) {
4191 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4192 }
4193 }
4194
Andrii Kulian5f750bc2018-07-17 08:57:23 -07004195 ActivityStack getTopDisplayFocusedStack() {
4196 return mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004197 }
4198
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004199 /** Pokes the task persister. */
4200 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
4201 mRecentTasks.notifyTaskPersisterLocked(task, flush);
4202 }
4203
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004204 void onTopProcChangedLocked(WindowProcessController proc) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004205 mVrController.onTopProcChangedLocked(proc);
4206 }
4207
4208 boolean isKeyguardLocked() {
4209 return mKeyguardController.isKeyguardLocked();
4210 }
4211
4212 boolean isNextTransitionForward() {
4213 int transit = mWindowManager.getPendingAppTransition();
4214 return transit == TRANSIT_ACTIVITY_OPEN
4215 || transit == TRANSIT_TASK_OPEN
4216 || transit == TRANSIT_TASK_TO_FRONT;
4217 }
4218
Wale Ogunwalef6733932018-06-27 05:14:34 -07004219 void dumpSleepStates(PrintWriter pw, boolean testPssMode) {
4220 synchronized (mGlobalLock) {
4221 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
4222 if (mRunningVoice != null) {
4223 pw.println(" mRunningVoice=" + mRunningVoice);
4224 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
4225 }
4226 pw.println(" mSleeping=" + mSleeping);
4227 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + testPssMode);
4228 pw.println(" mVrController=" + mVrController);
4229 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004230 }
4231
Wale Ogunwalef6733932018-06-27 05:14:34 -07004232 void writeSleepStateToProto(ProtoOutputStream proto) {
4233 for (ActivityTaskManagerInternal.SleepToken st : mStackSupervisor.mSleepTokens) {
4234 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS,
4235 st.toString());
4236 }
4237
4238 if (mRunningVoice != null) {
4239 final long vrToken = proto.start(
4240 ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
4241 proto.write(ActivityManagerServiceDumpProcessesProto.Voice.SESSION,
4242 mRunningVoice.toString());
4243 mVoiceWakeLock.writeToProto(
4244 proto, ActivityManagerServiceDumpProcessesProto.Voice.WAKELOCK);
4245 proto.end(vrToken);
4246 }
4247
4248 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
4249 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN,
4250 mShuttingDown);
4251 mVrController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004252 }
4253
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004254 int getCurrentUserId() {
4255 return mAmInternal.getCurrentUserId();
4256 }
4257
4258 private void enforceNotIsolatedCaller(String caller) {
4259 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4260 throw new SecurityException("Isolated process not allowed to call " + caller);
4261 }
4262 }
4263
Wale Ogunwalef6733932018-06-27 05:14:34 -07004264 public Configuration getConfiguration() {
4265 Configuration ci;
4266 synchronized(mGlobalLock) {
4267 ci = new Configuration(getGlobalConfiguration());
4268 ci.userSetLocale = false;
4269 }
4270 return ci;
4271 }
4272
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004273 /**
4274 * Current global configuration information. Contains general settings for the entire system,
4275 * also corresponds to the merged configuration of the default display.
4276 */
4277 Configuration getGlobalConfiguration() {
4278 return mStackSupervisor.getConfiguration();
4279 }
4280
4281 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4282 boolean initLocale) {
4283 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
4284 }
4285
4286 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4287 boolean initLocale, boolean deferResume) {
4288 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
4289 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
4290 UserHandle.USER_NULL, deferResume);
4291 }
4292
4293 void updatePersistentConfiguration(Configuration values, @UserIdInt int userId) {
4294 final long origId = Binder.clearCallingIdentity();
4295 try {
4296 synchronized (mGlobalLock) {
4297 updateConfigurationLocked(values, null, false, true, userId,
4298 false /* deferResume */);
4299 }
4300 } finally {
4301 Binder.restoreCallingIdentity(origId);
4302 }
4303 }
4304
4305 void updateUserConfiguration() {
4306 synchronized (mGlobalLock) {
4307 final Configuration configuration = new Configuration(getGlobalConfiguration());
4308 final int currentUserId = mAmInternal.getCurrentUserId();
4309 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
4310 currentUserId, Settings.System.canWrite(mContext));
4311 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
4312 false /* persistent */, currentUserId, false /* deferResume */);
4313 }
4314 }
4315
4316 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4317 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
4318 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
4319 deferResume, null /* result */);
4320 }
4321
4322 /**
4323 * Do either or both things: (1) change the current configuration, and (2)
4324 * make sure the given activity is running with the (now) current
4325 * configuration. Returns true if the activity has been left running, or
4326 * false if <var>starting</var> is being destroyed to match the new
4327 * configuration.
4328 *
4329 * @param userId is only used when persistent parameter is set to true to persist configuration
4330 * for that particular user
4331 */
4332 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4333 boolean initLocale, boolean persistent, int userId, boolean deferResume,
4334 ActivityTaskManagerService.UpdateConfigurationResult result) {
4335 int changes = 0;
4336 boolean kept = true;
4337
4338 if (mWindowManager != null) {
4339 mWindowManager.deferSurfaceLayout();
4340 }
4341 try {
4342 if (values != null) {
4343 changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
4344 deferResume);
4345 }
4346
4347 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4348 } finally {
4349 if (mWindowManager != null) {
4350 mWindowManager.continueSurfaceLayout();
4351 }
4352 }
4353
4354 if (result != null) {
4355 result.changes = changes;
4356 result.activityRelaunched = !kept;
4357 }
4358 return kept;
4359 }
4360
4361 /**
4362 * Returns true if this configuration change is interesting enough to send an
4363 * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
4364 */
4365 private static boolean isSplitConfigurationChange(int configDiff) {
4366 return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
4367 }
4368
4369 /** Update default (global) configuration and notify listeners about changes. */
4370 private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
4371 boolean persistent, int userId, boolean deferResume) {
4372 mTempConfig.setTo(getGlobalConfiguration());
4373 final int changes = mTempConfig.updateFrom(values);
4374 if (changes == 0) {
4375 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
4376 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
4377 // performDisplayOverrideConfigUpdate in order to send the new display configuration
4378 // (even if there are no actual changes) to unfreeze the window.
4379 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
4380 return 0;
4381 }
4382
4383 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
4384 "Updating global configuration to: " + values);
4385
4386 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
4387 StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
4388 values.colorMode,
4389 values.densityDpi,
4390 values.fontScale,
4391 values.hardKeyboardHidden,
4392 values.keyboard,
4393 values.keyboardHidden,
4394 values.mcc,
4395 values.mnc,
4396 values.navigation,
4397 values.navigationHidden,
4398 values.orientation,
4399 values.screenHeightDp,
4400 values.screenLayout,
4401 values.screenWidthDp,
4402 values.smallestScreenWidthDp,
4403 values.touchscreen,
4404 values.uiMode);
4405
4406
4407 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
4408 final LocaleList locales = values.getLocales();
4409 int bestLocaleIndex = 0;
4410 if (locales.size() > 1) {
4411 if (mSupportedSystemLocales == null) {
4412 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
4413 }
4414 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
4415 }
4416 SystemProperties.set("persist.sys.locale",
4417 locales.get(bestLocaleIndex).toLanguageTag());
4418 LocaleList.setDefault(locales, bestLocaleIndex);
4419 mAm.mHandler.sendMessage(mAm.mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
4420 locales.get(bestLocaleIndex)));
4421 }
4422
4423 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
4424 mTempConfig.seq = mConfigurationSeq;
4425
4426 // Update stored global config and notify everyone about the change.
4427 mStackSupervisor.onConfigurationChanged(mTempConfig);
4428
4429 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
4430 // TODO(multi-display): Update UsageEvents#Event to include displayId.
4431 mAm.mUsageStatsService.reportConfigurationChange(
4432 mTempConfig, mAmInternal.getCurrentUserId());
4433
4434 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
Wale Ogunwalef6733932018-06-27 05:14:34 -07004435 updateShouldShowDialogsLocked(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004436
4437 AttributeCache ac = AttributeCache.instance();
4438 if (ac != null) {
4439 ac.updateConfiguration(mTempConfig);
4440 }
4441
4442 // Make sure all resources in our process are updated right now, so that anyone who is going
4443 // to retrieve resource values after we return will be sure to get the new ones. This is
4444 // especially important during boot, where the first config change needs to guarantee all
4445 // resources have that config before following boot code is executed.
4446 mAm.mSystemThread.applyConfigurationToResources(mTempConfig);
4447
4448 // We need another copy of global config because we're scheduling some calls instead of
4449 // running them in place. We need to be sure that object we send will be handled unchanged.
4450 final Configuration configCopy = new Configuration(mTempConfig);
4451 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
4452 Message msg = mAm.mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
4453 msg.obj = configCopy;
4454 msg.arg1 = userId;
4455 mAm.mHandler.sendMessage(msg);
4456 }
4457
4458 for (int i = mAm.mLruProcesses.size() - 1; i >= 0; i--) {
4459 ProcessRecord app = mAm.mLruProcesses.get(i);
4460 try {
4461 if (app.thread != null) {
4462 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
4463 + app.processName + " new config " + configCopy);
4464 getLifecycleManager().scheduleTransaction(app.thread,
4465 ConfigurationChangeItem.obtain(configCopy));
4466 }
4467 } catch (Exception e) {
4468 Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
4469 }
4470 }
4471
4472 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
4473 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
4474 | Intent.FLAG_RECEIVER_FOREGROUND
4475 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4476 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4477 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4478 UserHandle.USER_ALL);
4479 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
4480 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
4481 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
4482 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
4483 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4484 if (initLocale || !mAm.mProcessesReady) {
4485 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
4486 }
4487 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4488 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4489 UserHandle.USER_ALL);
4490 }
4491
4492 // Send a broadcast to PackageInstallers if the configuration change is interesting
4493 // for the purposes of installing additional splits.
4494 if (!initLocale && isSplitConfigurationChange(changes)) {
4495 intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
4496 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
4497 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
4498
4499 // Typically only app stores will have this permission.
4500 String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES };
4501 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions,
4502 OP_NONE, null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
4503 }
4504
4505 // Override configuration of the default display duplicates global config, so we need to
4506 // update it also. This will also notify WindowManager about changes.
4507 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
4508 DEFAULT_DISPLAY);
4509
4510 return changes;
4511 }
4512
4513 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
4514 boolean deferResume, int displayId) {
4515 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
4516 displayId, null /* result */);
4517 }
4518
4519 /**
4520 * Updates override configuration specific for the selected display. If no config is provided,
4521 * new one will be computed in WM based on current display info.
4522 */
4523 boolean updateDisplayOverrideConfigurationLocked(Configuration values,
4524 ActivityRecord starting, boolean deferResume, int displayId,
4525 ActivityTaskManagerService.UpdateConfigurationResult result) {
4526 int changes = 0;
4527 boolean kept = true;
4528
4529 if (mWindowManager != null) {
4530 mWindowManager.deferSurfaceLayout();
4531 }
4532 try {
4533 if (values != null) {
4534 if (displayId == DEFAULT_DISPLAY) {
4535 // Override configuration of the default display duplicates global config, so
4536 // we're calling global config update instead for default display. It will also
4537 // apply the correct override config.
4538 changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
4539 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
4540 } else {
4541 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
4542 }
4543 }
4544
4545 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4546 } finally {
4547 if (mWindowManager != null) {
4548 mWindowManager.continueSurfaceLayout();
4549 }
4550 }
4551
4552 if (result != null) {
4553 result.changes = changes;
4554 result.activityRelaunched = !kept;
4555 }
4556 return kept;
4557 }
4558
4559 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
4560 int displayId) {
4561 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
4562 final int changes = mTempConfig.updateFrom(values);
4563 if (changes != 0) {
4564 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
4565 + mTempConfig + " for displayId=" + displayId);
4566 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
4567
4568 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
4569 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004570 mAppWarnings.onDensityChanged();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004571
4572 mAm.killAllBackgroundProcessesExcept(N,
4573 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
4574 }
4575 }
4576
4577 // Update the configuration with WM first and check if any of the stacks need to be resized
4578 // due to the configuration change. If so, resize the stacks now and do any relaunches if
4579 // necessary. This way we don't need to relaunch again afterwards in
4580 // ensureActivityConfiguration().
4581 if (mWindowManager != null) {
4582 final int[] resizedStacks =
4583 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
4584 if (resizedStacks != null) {
4585 for (int stackId : resizedStacks) {
4586 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
4587 }
4588 }
4589 }
4590
4591 return changes;
4592 }
4593
Wale Ogunwalef6733932018-06-27 05:14:34 -07004594 private void updateEventDispatchingLocked(boolean booted) {
4595 mWindowManager.setEventDispatching(booted && !mShuttingDown);
4596 }
4597
4598 void enableScreenAfterBoot(boolean booted) {
4599 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4600 SystemClock.uptimeMillis());
4601 mWindowManager.enableScreenAfterBoot();
4602
4603 synchronized (mGlobalLock) {
4604 updateEventDispatchingLocked(booted);
4605 }
4606 }
4607
4608 boolean canShowErrorDialogs() {
4609 return mShowDialogs && !mSleeping && !mShuttingDown
4610 && !mKeyguardController.isKeyguardOrAodShowing(DEFAULT_DISPLAY)
4611 && !hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
Wale Ogunwale86b74462018-07-02 08:42:43 -07004612 mAmInternal.getCurrentUserId())
Wale Ogunwalef6733932018-06-27 05:14:34 -07004613 && !(UserManager.isDeviceInDemoMode(mContext)
Wale Ogunwale86b74462018-07-02 08:42:43 -07004614 && mAmInternal.getCurrentUser().isDemo());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004615 }
4616
Wale Ogunwale906f9c62018-07-23 11:23:44 -07004617 static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
4618 if (r == null || !r.hasProcess()) {
4619 return KEY_DISPATCHING_TIMEOUT_MS;
4620 }
4621 return getInputDispatchingTimeoutLocked(r.app);
4622 }
4623
4624 private static long getInputDispatchingTimeoutLocked(WindowProcessController r) {
4625 if (r != null && (r.isInstrumenting() || r.isUsingWrapper())) {
4626 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS;
4627 }
4628 return KEY_DISPATCHING_TIMEOUT_MS;
4629 }
4630
4631 long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
4632 if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
4633 throw new SecurityException("Requires permission " + FILTER_EVENTS);
4634 }
4635 WindowProcessController proc;
4636 long timeout;
4637 synchronized (mGlobalLock) {
4638 proc = mPidMap.get(pid);
4639 timeout = getInputDispatchingTimeoutLocked(proc);
4640 }
4641
4642 if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
4643 return -1;
4644 }
4645
4646 return timeout;
4647 }
4648
4649 /**
4650 * Handle input dispatching timeouts.
4651 * Returns whether input dispatching should be aborted or not.
4652 */
4653 boolean inputDispatchingTimedOut(final WindowProcessController proc,
4654 final ActivityRecord activity, final ActivityRecord parent,
4655 final boolean aboveSystem, String reason) {
4656 if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
4657 throw new SecurityException("Requires permission " + FILTER_EVENTS);
4658 }
4659
4660 final String annotation;
4661 if (reason == null) {
4662 annotation = "Input dispatching timed out";
4663 } else {
4664 annotation = "Input dispatching timed out (" + reason + ")";
4665 }
4666
4667 if (proc != null) {
4668 synchronized (mGlobalLock) {
4669 if (proc.isDebugging()) {
4670 return false;
4671 }
4672
4673 if (proc.isInstrumenting()) {
4674 Bundle info = new Bundle();
4675 info.putString("shortMsg", "keyDispatchingTimedOut");
4676 info.putString("longMsg", annotation);
4677 mAm.finishInstrumentationLocked(
4678 (ProcessRecord) proc.mOwner, Activity.RESULT_CANCELED, info);
4679 return true;
4680 }
4681 }
4682 mH.post(() -> {
4683 mAm.mAppErrors.appNotResponding(
4684 (ProcessRecord) proc.mOwner, activity, parent, aboveSystem, annotation);
4685 });
4686 }
4687
4688 return true;
4689 }
4690
Wale Ogunwalef6733932018-06-27 05:14:34 -07004691 /**
4692 * Decide based on the configuration whether we should show the ANR,
4693 * crash, etc dialogs. The idea is that if there is no affordance to
4694 * press the on-screen buttons, or the user experience would be more
4695 * greatly impacted than the crash itself, we shouldn't show the dialog.
4696 *
4697 * A thought: SystemUI might also want to get told about this, the Power
4698 * dialog / global actions also might want different behaviors.
4699 */
4700 private void updateShouldShowDialogsLocked(Configuration config) {
4701 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
4702 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
4703 && config.navigation == Configuration.NAVIGATION_NONAV);
4704 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
4705 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
4706 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
4707 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
4708 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
4709 final boolean hideDialogsSet = Settings.Global.getInt(mContext.getContentResolver(),
4710 HIDE_ERROR_DIALOGS, 0) != 0;
4711 mShowDialogs = inputMethodExists && uiModeSupportsDialogs && !hideDialogsSet;
4712 }
4713
4714 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
4715 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
4716 FONT_SCALE, 1.0f, userId);
4717
4718 synchronized (this) {
4719 if (getGlobalConfiguration().fontScale == scaleFactor) {
4720 return;
4721 }
4722
4723 final Configuration configuration
4724 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
4725 configuration.fontScale = scaleFactor;
4726 updatePersistentConfiguration(configuration, userId);
4727 }
4728 }
4729
4730 // Actually is sleeping or shutting down or whatever else in the future
4731 // is an inactive state.
4732 boolean isSleepingOrShuttingDownLocked() {
4733 return isSleepingLocked() || mShuttingDown;
4734 }
4735
4736 boolean isSleepingLocked() {
4737 return mSleeping;
4738 }
4739
4740 /**
4741 * Update AMS states when an activity is resumed. This should only be called by
4742 * {@link ActivityStack#onActivityStateChanged(
4743 * ActivityRecord, ActivityStack.ActivityState, String)} when an activity is resumed.
4744 */
4745 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
4746 final TaskRecord task = r.getTask();
4747 if (task.isActivityTypeStandard()) {
4748 if (mCurAppTimeTracker != r.appTimeTracker) {
4749 // We are switching app tracking. Complete the current one.
4750 if (mCurAppTimeTracker != null) {
4751 mCurAppTimeTracker.stop();
4752 mH.obtainMessage(
4753 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
4754 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
4755 mCurAppTimeTracker = null;
4756 }
4757 if (r.appTimeTracker != null) {
4758 mCurAppTimeTracker = r.appTimeTracker;
4759 startTimeTrackingFocusedActivityLocked();
4760 }
4761 } else {
4762 startTimeTrackingFocusedActivityLocked();
4763 }
4764 } else {
4765 r.appTimeTracker = null;
4766 }
4767 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
4768 // TODO: Probably not, because we don't want to resume voice on switching
4769 // back to this activity
4770 if (task.voiceInteractor != null) {
4771 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
4772 } else {
4773 finishRunningVoiceLocked();
4774
4775 if (mLastResumedActivity != null) {
4776 final IVoiceInteractionSession session;
4777
4778 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
4779 if (lastResumedActivityTask != null
4780 && lastResumedActivityTask.voiceSession != null) {
4781 session = lastResumedActivityTask.voiceSession;
4782 } else {
4783 session = mLastResumedActivity.voiceSession;
4784 }
4785
4786 if (session != null) {
4787 // We had been in a voice interaction session, but now focused has
4788 // move to something different. Just finish the session, we can't
4789 // return to it and retain the proper state and synchronization with
4790 // the voice interaction service.
4791 finishVoiceTask(session);
4792 }
4793 }
4794 }
4795
4796 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
4797 mAmInternal.sendForegroundProfileChanged(r.userId);
4798 }
4799 updateResumedAppTrace(r);
4800 mLastResumedActivity = r;
4801
Riddle Hsu3026e8d2018-08-03 15:50:53 +08004802 // TODO(b/111361570): Support multiple focused apps in WM
Wale Ogunwalef6733932018-06-27 05:14:34 -07004803 mWindowManager.setFocusedApp(r.appToken, true);
4804
4805 applyUpdateLockStateLocked(r);
4806 applyUpdateVrModeLocked(r);
4807
4808 EventLogTags.writeAmSetResumedActivity(
4809 r == null ? -1 : r.userId,
4810 r == null ? "NULL" : r.shortComponentName,
4811 reason);
4812 }
4813
4814 ActivityTaskManagerInternal.SleepToken acquireSleepToken(String tag, int displayId) {
4815 synchronized (mGlobalLock) {
4816 final ActivityTaskManagerInternal.SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
4817 updateSleepIfNeededLocked();
4818 return token;
4819 }
4820 }
4821
4822 void updateSleepIfNeededLocked() {
4823 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
4824 final boolean wasSleeping = mSleeping;
4825 boolean updateOomAdj = false;
4826
4827 if (!shouldSleep) {
4828 // If wasSleeping is true, we need to wake up activity manager state from when
4829 // we started sleeping. In either case, we need to apply the sleep tokens, which
4830 // will wake up stacks or put them to sleep as appropriate.
4831 if (wasSleeping) {
4832 mSleeping = false;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07004833 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
4834 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__AWAKE);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004835 startTimeTrackingFocusedActivityLocked();
4836 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
4837 mStackSupervisor.comeOutOfSleepIfNeededLocked();
4838 }
4839 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
4840 if (wasSleeping) {
4841 updateOomAdj = true;
4842 }
4843 } else if (!mSleeping && shouldSleep) {
4844 mSleeping = true;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07004845 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
4846 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__ASLEEP);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004847 if (mCurAppTimeTracker != null) {
4848 mCurAppTimeTracker.stop();
4849 }
4850 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
4851 mStackSupervisor.goingToSleepLocked();
4852 updateResumedAppTrace(null /* resumed */);
4853 updateOomAdj = true;
4854 }
4855 if (updateOomAdj) {
4856 mH.post(mAmInternal::updateOomAdj);
4857 }
4858 }
4859
4860 void updateOomAdj() {
4861 mH.post(mAmInternal::updateOomAdj);
4862 }
4863
Wale Ogunwale53783742018-09-16 10:21:51 -07004864 void updateCpuStats() {
4865 mH.post(mAmInternal::updateCpuStats);
4866 }
4867
4868 void updateUsageStats(ActivityRecord component, boolean resumed) {
4869 final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::updateUsageStats,
4870 mAmInternal, component.realActivity, component.app.mUid, component.userId, resumed);
4871 mH.sendMessage(m);
4872 }
4873
4874 void setBooting(boolean booting) {
4875 mAmInternal.setBooting(booting);
4876 }
4877
4878 boolean isBooting() {
4879 return mAmInternal.isBooting();
4880 }
4881
4882 void setBooted(boolean booted) {
4883 mAmInternal.setBooted(booted);
4884 }
4885
4886 boolean isBooted() {
4887 return mAmInternal.isBooted();
4888 }
4889
4890 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
4891 mH.post(() -> {
4892 if (finishBooting) {
4893 mAmInternal.finishBooting();
4894 }
4895 if (enableScreen) {
4896 mInternal.enableScreenAfterBoot(isBooted());
4897 }
4898 });
4899 }
4900
4901 void setHeavyWeightProcess(ActivityRecord root) {
4902 mHeavyWeightProcess = root.app;
4903 final Message m = PooledLambda.obtainMessage(
4904 ActivityTaskManagerService::postHeavyWeightProcessNotification, this,
4905 root.app, root.intent, root.userId);
4906 mH.sendMessage(m);
4907 }
4908
4909 void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
4910 if (mHeavyWeightProcess == null || mHeavyWeightProcess != proc) {
4911 return;
4912 }
4913
4914 mHeavyWeightProcess = null;
4915 final Message m = PooledLambda.obtainMessage(
4916 ActivityTaskManagerService::cancelHeavyWeightProcessNotification, this,
4917 proc.mUserId);
4918 mH.sendMessage(m);
4919 }
4920
4921 private void cancelHeavyWeightProcessNotification(int userId) {
4922 final INotificationManager inm = NotificationManager.getService();
4923 if (inm == null) {
4924 return;
4925 }
4926 try {
4927 inm.cancelNotificationWithTag("android", null,
4928 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, userId);
4929 } catch (RuntimeException e) {
4930 Slog.w(TAG, "Error canceling notification for service", e);
4931 } catch (RemoteException e) {
4932 }
4933
4934 }
4935
4936 private void postHeavyWeightProcessNotification(
4937 WindowProcessController proc, Intent intent, int userId) {
4938 if (proc == null) {
4939 return;
4940 }
4941
4942 final INotificationManager inm = NotificationManager.getService();
4943 if (inm == null) {
4944 return;
4945 }
4946
4947 try {
4948 Context context = mContext.createPackageContext(proc.mInfo.packageName, 0);
4949 String text = mContext.getString(R.string.heavy_weight_notification,
4950 context.getApplicationInfo().loadLabel(context.getPackageManager()));
4951 Notification notification =
4952 new Notification.Builder(context,
4953 SystemNotificationChannels.HEAVY_WEIGHT_APP)
4954 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
4955 .setWhen(0)
4956 .setOngoing(true)
4957 .setTicker(text)
4958 .setColor(mContext.getColor(
4959 com.android.internal.R.color.system_notification_accent_color))
4960 .setContentTitle(text)
4961 .setContentText(
4962 mContext.getText(R.string.heavy_weight_notification_detail))
4963 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
4964 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
4965 new UserHandle(userId)))
4966 .build();
4967 try {
4968 inm.enqueueNotificationWithTag("android", "android", null,
4969 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, notification, userId);
4970 } catch (RuntimeException e) {
4971 Slog.w(TAG, "Error showing notification for heavy-weight app", e);
4972 } catch (RemoteException e) {
4973 }
4974 } catch (PackageManager.NameNotFoundException e) {
4975 Slog.w(TAG, "Unable to create context for heavy notification", e);
4976 }
4977
4978 }
4979
Andrii Kulian52d255c2018-07-13 11:32:19 -07004980 // TODO(b/111541062): Update app time tracking to make it aware of multiple resumed activities
Wale Ogunwalef6733932018-06-27 05:14:34 -07004981 private void startTimeTrackingFocusedActivityLocked() {
Andrii Kulian52d255c2018-07-13 11:32:19 -07004982 final ActivityRecord resumedActivity = mStackSupervisor.getTopResumedActivity();
Wale Ogunwalef6733932018-06-27 05:14:34 -07004983 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
4984 mCurAppTimeTracker.start(resumedActivity.packageName);
4985 }
4986 }
4987
4988 private void updateResumedAppTrace(@Nullable ActivityRecord resumed) {
4989 if (mTracedResumedActivity != null) {
4990 Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER,
4991 constructResumedTraceName(mTracedResumedActivity.packageName), 0);
4992 }
4993 if (resumed != null) {
4994 Trace.asyncTraceBegin(TRACE_TAG_ACTIVITY_MANAGER,
4995 constructResumedTraceName(resumed.packageName), 0);
4996 }
4997 mTracedResumedActivity = resumed;
4998 }
4999
5000 private String constructResumedTraceName(String packageName) {
5001 return "focused app: " + packageName;
5002 }
5003
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005004 /** Helper method that requests bounds from WM and applies them to stack. */
5005 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
5006 final Rect newStackBounds = new Rect();
5007 final ActivityStack stack = mStackSupervisor.getStack(stackId);
5008
5009 // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
5010 if (stack == null) {
5011 final StringWriter writer = new StringWriter();
5012 final PrintWriter printWriter = new PrintWriter(writer);
5013 mStackSupervisor.dumpDisplays(printWriter);
5014 printWriter.flush();
5015
5016 Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
5017 }
5018
5019 stack.getBoundsForNewConfiguration(newStackBounds);
5020 mStackSupervisor.resizeStackLocked(
5021 stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
5022 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
5023 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
5024 }
5025
5026 /** Applies latest configuration and/or visibility updates if needed. */
5027 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
5028 boolean kept = true;
Andrii Kulian5f750bc2018-07-17 08:57:23 -07005029 final ActivityStack mainStack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005030 // mainStack is null during startup.
5031 if (mainStack != null) {
5032 if (changes != 0 && starting == null) {
5033 // If the configuration changed, and the caller is not already
5034 // in the process of starting an activity, then find the top
5035 // activity to check if its configuration needs to change.
5036 starting = mainStack.topRunningActivityLocked();
5037 }
5038
5039 if (starting != null) {
5040 kept = starting.ensureActivityConfiguration(changes,
5041 false /* preserveWindow */);
5042 // And we need to make sure at this point that all other activities
5043 // are made visible with the correct configuration.
5044 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
5045 !PRESERVE_WINDOWS);
5046 }
5047 }
5048
5049 return kept;
5050 }
5051
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005052 void scheduleAppGcsLocked() {
5053 mH.post(() -> mAmInternal.scheduleAppGcs());
5054 }
5055
Wale Ogunwale53783742018-09-16 10:21:51 -07005056 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
5057 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
5058 }
5059
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005060 /**
5061 * Returns the PackageManager. Used by classes hosted by {@link ActivityTaskManagerService}. The
5062 * PackageManager could be unavailable at construction time and therefore needs to be accessed
5063 * on demand.
5064 */
5065 IPackageManager getPackageManager() {
5066 return AppGlobals.getPackageManager();
5067 }
5068
5069 PackageManagerInternal getPackageManagerInternalLocked() {
5070 if (mPmInternal == null) {
5071 mPmInternal = LocalServices.getService(PackageManagerInternal.class);
5072 }
5073 return mPmInternal;
5074 }
5075
Wale Ogunwale008163e2018-07-23 23:11:08 -07005076 AppWarnings getAppWarningsLocked() {
5077 return mAppWarnings;
5078 }
5079
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005080 void logAppTooSlow(WindowProcessController app, long startTime, String msg) {
5081 if (true || Build.IS_USER) {
5082 return;
5083 }
5084
5085 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5086 StrictMode.allowThreadDiskWrites();
5087 try {
5088 File tracesDir = new File("/data/anr");
5089 File tracesFile = null;
5090 try {
5091 tracesFile = File.createTempFile("app_slow", null, tracesDir);
5092
5093 StringBuilder sb = new StringBuilder();
5094 Time tobj = new Time();
5095 tobj.set(System.currentTimeMillis());
5096 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5097 sb.append(": ");
5098 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5099 sb.append(" since ");
5100 sb.append(msg);
5101 FileOutputStream fos = new FileOutputStream(tracesFile);
5102 fos.write(sb.toString().getBytes());
5103 if (app == null) {
5104 fos.write("\n*** No application process!".getBytes());
5105 }
5106 fos.close();
5107 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5108 } catch (IOException e) {
5109 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesFile, e);
5110 return;
5111 }
5112
5113 if (app != null && app.getPid() > 0) {
5114 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5115 firstPids.add(app.getPid());
5116 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, null, null);
5117 }
5118
5119 File lastTracesFile = null;
5120 File curTracesFile = null;
5121 for (int i=9; i>=0; i--) {
5122 String name = String.format(Locale.US, "slow%02d.txt", i);
5123 curTracesFile = new File(tracesDir, name);
5124 if (curTracesFile.exists()) {
5125 if (lastTracesFile != null) {
5126 curTracesFile.renameTo(lastTracesFile);
5127 } else {
5128 curTracesFile.delete();
5129 }
5130 }
5131 lastTracesFile = curTracesFile;
5132 }
5133 tracesFile.renameTo(curTracesFile);
5134 } finally {
5135 StrictMode.setThreadPolicy(oldPolicy);
5136 }
5137 }
5138
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005139 final class H extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005140 static final int REPORT_TIME_TRACKER_MSG = 1;
5141
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005142 public H(Looper looper) {
5143 super(looper, null, true);
5144 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005145
5146 @Override
5147 public void handleMessage(Message msg) {
5148 switch (msg.what) {
5149 case REPORT_TIME_TRACKER_MSG: {
5150 AppTimeTracker tracker = (AppTimeTracker) msg.obj;
5151 tracker.deliverResult(mContext);
5152 } break;
5153 }
5154 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005155 }
5156
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005157 final class UiHandler extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005158 static final int DISMISS_DIALOG_UI_MSG = 1;
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005159
5160 public UiHandler() {
5161 super(com.android.server.UiThread.get().getLooper(), null, true);
5162 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005163
5164 @Override
5165 public void handleMessage(Message msg) {
5166 switch (msg.what) {
5167 case DISMISS_DIALOG_UI_MSG: {
5168 final Dialog d = (Dialog) msg.obj;
5169 d.dismiss();
5170 break;
5171 }
5172 }
5173 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005174 }
5175
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005176 final class LocalService extends ActivityTaskManagerInternal {
5177 @Override
5178 public SleepToken acquireSleepToken(String tag, int displayId) {
5179 Preconditions.checkNotNull(tag);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005180 return ActivityTaskManagerService.this.acquireSleepToken(tag, displayId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005181 }
5182
5183 @Override
5184 public ComponentName getHomeActivityForUser(int userId) {
5185 synchronized (mGlobalLock) {
5186 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
5187 return homeActivity == null ? null : homeActivity.realActivity;
5188 }
5189 }
5190
5191 @Override
5192 public void onLocalVoiceInteractionStarted(IBinder activity,
5193 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
5194 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005195 onLocalVoiceInteractionStartedLocked(activity, voiceSession, voiceInteractor);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005196 }
5197 }
5198
5199 @Override
5200 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
5201 synchronized (mGlobalLock) {
5202 mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
5203 reasons, timestamp);
5204 }
5205 }
5206
5207 @Override
5208 public void notifyAppTransitionFinished() {
5209 synchronized (mGlobalLock) {
5210 mStackSupervisor.notifyAppTransitionDone();
5211 }
5212 }
5213
5214 @Override
5215 public void notifyAppTransitionCancelled() {
5216 synchronized (mGlobalLock) {
5217 mStackSupervisor.notifyAppTransitionDone();
5218 }
5219 }
5220
5221 @Override
5222 public List<IBinder> getTopVisibleActivities() {
5223 synchronized (mGlobalLock) {
5224 return mStackSupervisor.getTopVisibleActivities();
5225 }
5226 }
5227
5228 @Override
5229 public void notifyDockedStackMinimizedChanged(boolean minimized) {
5230 synchronized (mGlobalLock) {
5231 mStackSupervisor.setDockedStackMinimized(minimized);
5232 }
5233 }
5234
5235 @Override
5236 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
5237 Bundle bOptions) {
5238 Preconditions.checkNotNull(intents, "intents");
5239 final String[] resolvedTypes = new String[intents.length];
5240
5241 // UID of the package on user userId.
5242 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
5243 // packageUid may not be initialized.
5244 int packageUid = 0;
5245 final long ident = Binder.clearCallingIdentity();
5246
5247 try {
5248 for (int i = 0; i < intents.length; i++) {
5249 resolvedTypes[i] =
5250 intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
5251 }
5252
5253 packageUid = AppGlobals.getPackageManager().getPackageUid(
5254 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
5255 } catch (RemoteException e) {
5256 // Shouldn't happen.
5257 } finally {
5258 Binder.restoreCallingIdentity(ident);
5259 }
5260
5261 synchronized (mGlobalLock) {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07005262 return getActivityStartController().startActivitiesInPackage(
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005263 packageUid, packageName,
5264 intents, resolvedTypes, null /* resultTo */,
5265 SafeActivityOptions.fromBundle(bOptions), userId,
Michal Karpinski201bc0c2018-07-20 15:32:00 +01005266 false /* validateIncomingUser */, null /* originatingPendingIntent */);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005267 }
5268 }
5269
5270 @Override
5271 public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
5272 Intent intent, Bundle options, int userId) {
5273 return ActivityTaskManagerService.this.startActivityAsUser(
5274 caller, callerPacakge, intent,
5275 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
5276 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
5277 false /*validateIncomingUser*/);
5278 }
5279
5280 @Override
5281 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
5282 synchronized (mGlobalLock) {
5283
5284 // We might change the visibilities here, so prepare an empty app transition which
5285 // might be overridden later if we actually change visibilities.
5286 final boolean wasTransitionSet =
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005287 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005288 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005289 mWindowManager.prepareAppTransition(TRANSIT_NONE,
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005290 false /* alwaysKeepCurrent */);
5291 }
5292 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5293
5294 // If there was a transition set already we don't want to interfere with it as we
5295 // might be starting it too early.
5296 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005297 mWindowManager.executeAppTransition();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005298 }
5299 }
5300 if (callback != null) {
5301 callback.run();
5302 }
5303 }
5304
5305 @Override
5306 public void notifyKeyguardTrustedChanged() {
5307 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005308 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005309 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5310 }
5311 }
5312 }
5313
5314 /**
5315 * Called after virtual display Id is updated by
5316 * {@link com.android.server.vr.Vr2dDisplay} with a specific
5317 * {@param vrVr2dDisplayId}.
5318 */
5319 @Override
5320 public void setVr2dDisplayId(int vr2dDisplayId) {
5321 if (DEBUG_STACK) Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
5322 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005323 mVr2dDisplayId = vr2dDisplayId;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005324 }
5325 }
5326
5327 @Override
5328 public void setFocusedActivity(IBinder token) {
5329 synchronized (mGlobalLock) {
5330 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
5331 if (r == null) {
5332 throw new IllegalArgumentException(
5333 "setFocusedActivity: No activity record matching token=" + token);
5334 }
5335 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
5336 r, "setFocusedActivity")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08005337 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005338 }
5339 }
5340 }
5341
5342 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005343 public void registerScreenObserver(ScreenObserver observer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005344 mScreenObservers.add(observer);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005345 }
5346
5347 @Override
5348 public boolean isCallerRecents(int callingUid) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005349 return getRecentTasks().isCallerRecents(callingUid);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005350 }
5351
5352 @Override
5353 public boolean isRecentsComponentHomeActivity(int userId) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005354 return getRecentTasks().isRecentsComponentHomeActivity(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005355 }
5356
5357 @Override
5358 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
5359 ActivityTaskManagerService.this.cancelRecentsAnimation(restoreHomeStackPosition);
5360 }
5361
5362 @Override
5363 public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005364 ActivityTaskManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005365 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005366
5367 @Override
5368 public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
5369 synchronized (mGlobalLock) {
5370 mActiveVoiceInteractionServiceComponent = component;
5371 }
5372 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005373
5374 @Override
5375 public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
5376 if (!mAmInternal.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
5377 return;
5378 }
5379 synchronized (mGlobalLock) {
5380 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
5381 if (types == null) {
5382 if (uid < 0) {
5383 return;
5384 }
5385 types = new ArrayMap<>();
5386 mAllowAppSwitchUids.put(userId, types);
5387 }
5388 if (uid < 0) {
5389 types.remove(type);
5390 } else {
5391 types.put(type, uid);
5392 }
5393 }
5394 }
5395
5396 @Override
5397 public void onUserStopped(int userId) {
5398 synchronized (mGlobalLock) {
5399 getRecentTasks().unloadUserDataFromMemoryLocked(userId);
5400 mAllowAppSwitchUids.remove(userId);
5401 }
5402 }
5403
5404 @Override
5405 public boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
5406 synchronized (mGlobalLock) {
5407 return ActivityTaskManagerService.this.isGetTasksAllowed(
5408 caller, callingPid, callingUid);
5409 }
5410 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005411
5412 @Override
5413 public void onProcessAdded(WindowProcessController proc) {
5414 synchronized (mGlobalLock) {
5415 mProcessNames.put(proc.mName, proc.mUid, proc);
5416 }
5417 }
5418
5419 @Override
5420 public void onProcessRemoved(String name, int uid) {
5421 synchronized (mGlobalLock) {
5422 mProcessNames.remove(name, uid);
5423 }
5424 }
5425
5426 @Override
5427 public void onCleanUpApplicationRecord(WindowProcessController proc) {
5428 synchronized (mGlobalLock) {
5429 if (proc == mHomeProcess) {
5430 mHomeProcess = null;
5431 }
5432 if (proc == mPreviousProcess) {
5433 mPreviousProcess = null;
5434 }
5435 }
5436 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005437
5438 @Override
5439 public int getTopProcessState() {
5440 synchronized (mGlobalLock) {
5441 return mTopProcessState;
5442 }
5443 }
5444
5445 @Override
Wale Ogunwale53783742018-09-16 10:21:51 -07005446 public boolean isHeavyWeightProcess(WindowProcessController proc) {
5447 synchronized (mGlobalLock) {
5448 return proc == mHeavyWeightProcess;
5449 }
5450 }
5451
5452 @Override
5453 public void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
5454 synchronized (mGlobalLock) {
5455 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(proc);
5456 }
5457 }
5458
5459 @Override
5460 public void finishHeavyWeightApp() {
5461 synchronized (mGlobalLock) {
5462 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(
5463 mHeavyWeightProcess);
5464 }
5465 }
5466
5467 @Override
Wale Ogunwalef6733932018-06-27 05:14:34 -07005468 public boolean isSleeping() {
5469 synchronized (mGlobalLock) {
5470 return isSleepingLocked();
5471 }
5472 }
5473
5474 @Override
5475 public boolean isShuttingDown() {
5476 synchronized (mGlobalLock) {
5477 return mShuttingDown;
5478 }
5479 }
5480
5481 @Override
5482 public boolean shuttingDown(boolean booted, int timeout) {
5483 synchronized (mGlobalLock) {
5484 mShuttingDown = true;
5485 mStackSupervisor.prepareForShutdownLocked();
5486 updateEventDispatchingLocked(booted);
5487 return mStackSupervisor.shutdownLocked(timeout);
5488 }
5489 }
5490
5491 @Override
5492 public void enableScreenAfterBoot(boolean booted) {
5493 synchronized (mGlobalLock) {
5494 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5495 SystemClock.uptimeMillis());
5496 mWindowManager.enableScreenAfterBoot();
5497 updateEventDispatchingLocked(booted);
5498 }
5499 }
5500
5501 @Override
5502 public boolean showStrictModeViolationDialog() {
5503 synchronized (mGlobalLock) {
5504 return mShowDialogs && !mSleeping && !mShuttingDown;
5505 }
5506 }
5507
5508 @Override
5509 public void showSystemReadyErrorDialogsIfNeeded() {
5510 synchronized (mGlobalLock) {
5511 try {
5512 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
5513 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
5514 + " data partition or your device will be unstable.");
5515 mUiHandler.post(() -> {
5516 if (mShowDialogs) {
5517 AlertDialog d = new BaseErrorDialog(mUiContext);
5518 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5519 d.setCancelable(false);
5520 d.setTitle(mUiContext.getText(R.string.android_system_label));
5521 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
5522 d.setButton(DialogInterface.BUTTON_POSITIVE,
5523 mUiContext.getText(R.string.ok),
5524 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5525 d.show();
5526 }
5527 });
5528 }
5529 } catch (RemoteException e) {
5530 }
5531
5532 if (!Build.isBuildConsistent()) {
5533 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
5534 mUiHandler.post(() -> {
5535 if (mShowDialogs) {
5536 AlertDialog d = new BaseErrorDialog(mUiContext);
5537 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5538 d.setCancelable(false);
5539 d.setTitle(mUiContext.getText(R.string.android_system_label));
5540 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
5541 d.setButton(DialogInterface.BUTTON_POSITIVE,
5542 mUiContext.getText(R.string.ok),
5543 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5544 d.show();
5545 }
5546 });
5547 }
5548 }
5549 }
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005550
5551 @Override
5552 public long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason) {
5553 synchronized (mGlobalLock) {
5554 return ActivityTaskManagerService.this.inputDispatchingTimedOut(
5555 pid, aboveSystem, reason);
5556 }
5557 }
5558
5559 @Override
5560 public void onProcessMapped(int pid, WindowProcessController proc) {
5561 synchronized (mGlobalLock) {
5562 mPidMap.put(pid, proc);
5563 }
5564 }
5565
5566 @Override
5567 public void onProcessUnMapped(int pid) {
5568 synchronized (mGlobalLock) {
5569 mPidMap.remove(pid);
5570 }
5571 }
Wale Ogunwale008163e2018-07-23 23:11:08 -07005572
5573 @Override
5574 public void onPackageDataCleared(String name) {
5575 synchronized (mGlobalLock) {
Wale Ogunwale53783742018-09-16 10:21:51 -07005576 mCompatModePackages.handlePackageDataClearedLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07005577 mAppWarnings.onPackageDataCleared(name);
5578 }
5579 }
5580
5581 @Override
5582 public void onPackageUninstalled(String name) {
5583 synchronized (mGlobalLock) {
5584 mAppWarnings.onPackageUninstalled(name);
Wale Ogunwale53783742018-09-16 10:21:51 -07005585 mCompatModePackages.handlePackageUninstalledLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07005586 }
5587 }
Wale Ogunwale53783742018-09-16 10:21:51 -07005588
5589 @Override
5590 public void onPackageAdded(String name, boolean replacing) {
5591 synchronized (mGlobalLock) {
5592 mCompatModePackages.handlePackageAddedLocked(name, replacing);
5593 }
5594 }
5595
5596 @Override
5597 public CompatibilityInfo compatibilityInfoForPackage(ApplicationInfo ai) {
5598 synchronized (mGlobalLock) {
5599 return compatibilityInfoForPackageLocked(ai);
5600 }
5601 }
5602
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005603 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07005604}