blob: b4f062d7fe60312309fbd7032c4f30a6233b94d5 [file] [log] [blame]
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.server.am;
18
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070019import static android.Manifest.permission.BIND_VOICE_INTERACTION;
20import static android.Manifest.permission.CHANGE_CONFIGURATION;
21import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
Wale Ogunwale906f9c62018-07-23 11:23:44 -070022import static android.Manifest.permission.FILTER_EVENTS;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070023import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070024import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070025import static android.Manifest.permission.READ_FRAME_BUFFER;
26import static android.Manifest.permission.REMOVE_TASKS;
27import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070028import static android.Manifest.permission.STOP_APP_SWITCHES;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070029import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
Evan Rosky4505b352018-09-06 11:20:40 -070030import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070031import static android.app.ActivityTaskManager.RESIZE_MODE_PRESERVE_WINDOW;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070032import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070033import static android.app.AppOpsManager.OP_NONE;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070034import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070035import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
36import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070037import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
38import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070039import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070040import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070041import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070042import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
43import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
Evan Rosky4505b352018-09-06 11:20:40 -070044import static android.content.pm.PackageManager.FEATURE_PC;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070045import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070046import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070047import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
48import static android.os.Build.VERSION_CODES.N;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070049import static android.os.Process.SYSTEM_UID;
Evan Rosky4505b352018-09-06 11:20:40 -070050import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070051import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
52import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
53import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
54import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
Evan Rosky4505b352018-09-06 11:20:40 -070055import static android.provider.Settings.Global.HIDE_ERROR_DIALOGS;
56import static android.provider.Settings.System.FONT_SCALE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070057import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
58import static android.view.Display.DEFAULT_DISPLAY;
59import static android.view.Display.INVALID_DISPLAY;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070060import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
Wale Ogunwale6767eae2018-05-03 15:52:51 -070061import static android.view.WindowManager.TRANSIT_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070062import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070063import static android.view.WindowManager.TRANSIT_TASK_OPEN;
64import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
Evan Rosky4505b352018-09-06 11:20:40 -070065
Wale Ogunwale65ebd952018-04-25 15:41:44 -070066import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070067import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
68import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
69import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
70import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070071import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070072import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070073import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070074import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070075import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070076import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
77import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
78import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070079import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070080import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
81import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070082import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
83import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
84import static com.android.server.am.ActivityManagerService.ANIMATE;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070085import static com.android.server.am.ActivityManagerService.MY_PID;
86import static com.android.server.am.ActivityManagerService.SEND_LOCALE_TO_MOUNT_DAEMON_MSG;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070087import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070088import static com.android.server.am.ActivityManagerService.UPDATE_CONFIGURATION_MSG;
89import static com.android.server.am.ActivityManagerService.checkComponentPermission;
Evan Rosky4505b352018-09-06 11:20:40 -070090import static com.android.server.am.ActivityManagerService.dumpStackTraces;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070091import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070092import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070093import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
94import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
95import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
96import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
97import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
Evan Rosky4505b352018-09-06 11:20:40 -070098import static com.android.server.am.ActivityTaskManagerService.H.REPORT_TIME_TRACKER_MSG;
99import static com.android.server.am.ActivityTaskManagerService.UiHandler.DISMISS_DIALOG_UI_MSG;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700100import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
101import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700102import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700103import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
Evan Rosky4505b352018-09-06 11:20:40 -0700104import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT;
105import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_DATA;
106import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
107import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700108import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
109import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700110
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700111import android.Manifest;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700112import android.annotation.NonNull;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700113import android.annotation.Nullable;
114import android.annotation.UserIdInt;
115import android.app.Activity;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700116import android.app.ActivityManager;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700117import android.app.ActivityManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700118import android.app.ActivityOptions;
119import android.app.ActivityTaskManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700120import android.app.ActivityThread;
121import android.app.AlertDialog;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700122import android.app.AppGlobals;
Evan Rosky4505b352018-09-06 11:20:40 -0700123import android.app.Dialog;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700124import android.app.IActivityController;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700125import android.app.IActivityTaskManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700126import android.app.IApplicationThread;
127import android.app.IAssistDataReceiver;
Wale Ogunwale53783742018-09-16 10:21:51 -0700128import android.app.INotificationManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700129import android.app.ITaskStackListener;
Wale Ogunwale53783742018-09-16 10:21:51 -0700130import android.app.Notification;
131import android.app.NotificationManager;
132import android.app.PendingIntent;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700133import android.app.PictureInPictureParams;
134import android.app.ProfilerInfo;
135import android.app.RemoteAction;
136import android.app.WaitResult;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700137import android.app.WindowConfiguration;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700138import android.app.admin.DevicePolicyCache;
139import android.app.assist.AssistContent;
140import android.app.assist.AssistStructure;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700141import android.app.servertransaction.ConfigurationChangeItem;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700142import android.app.usage.UsageEvents;
143import android.content.ActivityNotFoundException;
144import android.content.ComponentName;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700145import android.content.ContentResolver;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700146import android.content.Context;
Evan Rosky4505b352018-09-06 11:20:40 -0700147import android.content.DialogInterface;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700148import android.content.IIntentSender;
149import android.content.Intent;
150import android.content.pm.ActivityInfo;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700151import android.content.pm.ApplicationInfo;
Yunfan Chen75157d72018-07-27 14:47:21 +0900152import android.content.pm.ConfigurationInfo;
Evan Rosky4505b352018-09-06 11:20:40 -0700153import android.content.pm.IPackageManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700154import android.content.pm.PackageManager;
Evan Rosky4505b352018-09-06 11:20:40 -0700155import android.content.pm.PackageManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700156import android.content.pm.ParceledListSlice;
157import android.content.pm.ResolveInfo;
Wale Ogunwale53783742018-09-16 10:21:51 -0700158import android.content.res.CompatibilityInfo;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700159import android.content.res.Configuration;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700160import android.content.res.Resources;
Evan Rosky4505b352018-09-06 11:20:40 -0700161import android.database.ContentObserver;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700162import android.graphics.Bitmap;
163import android.graphics.Point;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700164import android.graphics.Rect;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700165import android.metrics.LogMaker;
166import android.net.Uri;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700167import android.os.Binder;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700168import android.os.Build;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700169import android.os.Bundle;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700170import android.os.FileUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700171import android.os.Handler;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700172import android.os.IBinder;
Evan Rosky4505b352018-09-06 11:20:40 -0700173import android.os.IUserManager;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700174import android.os.LocaleList;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700175import android.os.Looper;
176import android.os.Message;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700177import android.os.PersistableBundle;
Evan Rosky4505b352018-09-06 11:20:40 -0700178import android.os.PowerManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700179import android.os.RemoteException;
Evan Rosky4505b352018-09-06 11:20:40 -0700180import android.os.ServiceManager;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700181import android.os.StrictMode;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700182import android.os.SystemClock;
183import android.os.SystemProperties;
Evan Rosky4505b352018-09-06 11:20:40 -0700184import android.os.Trace;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700185import android.os.UpdateLock;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700186import android.os.UserHandle;
Evan Rosky4505b352018-09-06 11:20:40 -0700187import android.os.UserManager;
188import android.os.WorkSource;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700189import android.provider.Settings;
190import android.service.voice.IVoiceInteractionSession;
191import android.service.voice.VoiceInteractionManagerInternal;
192import android.telecom.TelecomManager;
193import android.text.TextUtils;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700194import android.text.format.Time;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700195import android.util.ArrayMap;
196import android.util.EventLog;
197import android.util.Log;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700198import android.util.Slog;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700199import android.util.SparseArray;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700200import android.util.SparseIntArray;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700201import android.util.StatsLog;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700202import android.util.TimeUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700203import android.util.proto.ProtoOutputStream;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700204import android.view.IRecentsAnimationRunner;
205import android.view.RemoteAnimationAdapter;
206import android.view.RemoteAnimationDefinition;
Evan Rosky4505b352018-09-06 11:20:40 -0700207import android.view.WindowManager;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700208
Evan Rosky4505b352018-09-06 11:20:40 -0700209import com.android.internal.R;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700210import com.android.internal.annotations.VisibleForTesting;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700211import com.android.internal.app.AssistUtils;
Evan Rosky4505b352018-09-06 11:20:40 -0700212import com.android.internal.app.IAppOpsService;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700213import com.android.internal.app.IVoiceInteractor;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700214import com.android.internal.app.ProcessMap;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700215import com.android.internal.logging.MetricsLogger;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700216import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Wale Ogunwale53783742018-09-16 10:21:51 -0700217import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
218import com.android.internal.notification.SystemNotificationChannels;
Evan Rosky4505b352018-09-06 11:20:40 -0700219import com.android.internal.os.logging.MetricsLoggerWrapper;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700220import com.android.internal.policy.IKeyguardDismissCallback;
221import com.android.internal.policy.KeyguardDismissCallback;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700222import com.android.internal.util.Preconditions;
Wale Ogunwale53783742018-09-16 10:21:51 -0700223import com.android.internal.util.function.pooled.PooledLambda;
Evan Rosky4505b352018-09-06 11:20:40 -0700224import com.android.server.AppOpsService;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700225import com.android.server.AttributeCache;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700226import com.android.server.LocalServices;
227import com.android.server.SystemService;
Evan Rosky4505b352018-09-06 11:20:40 -0700228import com.android.server.SystemServiceManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700229import com.android.server.Watchdog;
Evan Rosky4505b352018-09-06 11:20:40 -0700230import com.android.server.pm.UserManagerService;
231import com.android.server.uri.UriGrantsManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700232import com.android.server.vr.VrManagerInternal;
Evan Rosky4505b352018-09-06 11:20:40 -0700233import com.android.server.wm.ActivityTaskManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700234import com.android.server.wm.PinnedStackWindowController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700235import com.android.server.wm.WindowManagerService;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700236
237import java.io.File;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700238import java.io.FileOutputStream;
239import java.io.IOException;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700240import java.io.PrintWriter;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700241import java.io.StringWriter;
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700242import java.lang.ref.WeakReference;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700243import java.util.ArrayList;
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700244import java.util.HashSet;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700245import java.util.List;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700246import java.util.Locale;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700247
248/**
249 * System service for managing activities and their containers (task, stacks, displays,... ).
250 *
251 * {@hide}
252 */
253public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
254 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityTaskManagerService" : TAG_AM;
255 private static final String TAG_STACK = TAG + POSTFIX_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700256 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
257 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
258 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
259 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
260 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700261 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700262
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700263 // How long we wait until we timeout on key dispatching.
264 private static final int KEY_DISPATCHING_TIMEOUT_MS = 5 * 1000;
265 // How long we wait until we timeout on key dispatching during instrumentation.
266 private static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS = 60 * 1000;
267
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700268 Context mContext;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700269 /**
270 * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
271 * change at runtime. Use mContext for non-UI purposes.
272 */
273 final Context mUiContext;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700274 H mH;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700275 UiHandler mUiHandler;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700276 ActivityManagerService mAm;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700277 ActivityManagerInternal mAmInternal;
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700278 UriGrantsManagerInternal mUgmInternal;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700279 private PackageManagerInternal mPmInternal;
Wale Ogunwale53783742018-09-16 10:21:51 -0700280 private ActivityTaskManagerInternal mInternal;
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700281 PendingIntentController mPendingIntentController;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700282 /* Global service lock used by the package the owns this service. */
283 Object mGlobalLock;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700284 ActivityStackSupervisor mStackSupervisor;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700285 WindowManagerService mWindowManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700286 private UserManagerService mUserManager;
287 private AppOpsService mAppOpsService;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700288 /** All processes currently running that might have a window organized by name. */
289 final ProcessMap<WindowProcessController> mProcessNames = new ProcessMap<>();
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700290 /** All processes we currently have running mapped by pid */
291 final SparseArray<WindowProcessController> mPidMap = new SparseArray<>();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700292 /** This is the process holding what we currently consider to be the "home" activity. */
293 WindowProcessController mHomeProcess;
Wale Ogunwale53783742018-09-16 10:21:51 -0700294 /** The currently running heavy-weight process, if any. */
295 WindowProcessController mHeavyWeightProcess = null;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700296 /**
297 * This is the process holding the activity the user last visited that is in a different process
298 * from the one they are currently in.
299 */
300 WindowProcessController mPreviousProcess;
301 /** The time at which the previous process was last visible. */
302 long mPreviousProcessVisibleTime;
303
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700304 /** List of intents that were used to start the most recent tasks. */
305 private RecentTasks mRecentTasks;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700306 /** State of external calls telling us if the device is awake or asleep. */
307 private boolean mKeyguardShown = false;
308
309 // Wrapper around VoiceInteractionServiceManager
310 private AssistUtils mAssistUtils;
311
312 // VoiceInteraction session ID that changes for each new request except when
313 // being called for multi-window assist in a single session.
314 private int mViSessionId = 1000;
315
316 // How long to wait in getAssistContextExtras for the activity and foreground services
317 // to respond with the result.
318 private static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
319
320 // How long top wait when going through the modern assist (which doesn't need to block
321 // on getting this result before starting to launch its UI).
322 private static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
323
324 // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
325 private static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
326
327 private final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
328
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700329 // Keeps track of the active voice interaction service component, notified from
330 // VoiceInteractionManagerService
331 ComponentName mActiveVoiceInteractionServiceComponent;
332
333 private VrController mVrController;
334 KeyguardController mKeyguardController;
335 private final ClientLifecycleManager mLifecycleManager;
336 private TaskChangeNotificationController mTaskChangeNotificationController;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700337 /** The controller for all operations related to locktask. */
338 private LockTaskController mLockTaskController;
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700339 private ActivityStartController mActivityStartController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700340
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700341 boolean mSuppressResizeConfigChanges;
342
343 private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
344 new UpdateConfigurationResult();
345
346 static final class UpdateConfigurationResult {
347 // Configuration changes that were updated.
348 int changes;
349 // If the activity was relaunched to match the new configuration.
350 boolean activityRelaunched;
351
352 void reset() {
353 changes = 0;
354 activityRelaunched = false;
355 }
356 }
357
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700358 /** Current sequencing integer of the configuration, for skipping old configurations. */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700359 private int mConfigurationSeq;
360 // To cache the list of supported system locales
361 private String[] mSupportedSystemLocales = null;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700362
363 /**
364 * Temp object used when global and/or display override configuration is updated. It is also
365 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
366 * anyone...
367 */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700368 private Configuration mTempConfig = new Configuration();
369
Wale Ogunwalef6733932018-06-27 05:14:34 -0700370 /** Temporary to avoid allocations. */
371 final StringBuilder mStringBuilder = new StringBuilder(256);
372
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700373 // Amount of time after a call to stopAppSwitches() during which we will
374 // prevent further untrusted switches from happening.
375 private static final long APP_SWITCH_DELAY_TIME = 5 * 1000;
376
377 /**
378 * The time at which we will allow normal application switches again,
379 * after a call to {@link #stopAppSwitches()}.
380 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700381 private long mAppSwitchesAllowedTime;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700382 /**
383 * This is set to true after the first switch after mAppSwitchesAllowedTime
384 * is set; any switches after that will clear the time.
385 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700386 private boolean mDidAppSwitch;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700387
388 IActivityController mController = null;
389 boolean mControllerIsAMonkey = false;
390
391 /**
392 * Used to retain an update lock when the foreground activity is in
393 * immersive mode.
394 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700395 private final UpdateLock mUpdateLock = new UpdateLock("immersive");
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700396
397 /**
398 * Packages that are being allowed to perform unrestricted app switches. Mapping is
399 * User -> Type -> uid.
400 */
401 final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
402
403 /** The dimensions of the thumbnails in the Recents UI. */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700404 private int mThumbnailWidth;
405 private int mThumbnailHeight;
406 private float mFullscreenThumbnailScale;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700407
408 /**
409 * Flag that indicates if multi-window is enabled.
410 *
411 * For any particular form of multi-window to be enabled, generic multi-window must be enabled
412 * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
413 * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
414 * At least one of the forms of multi-window must be enabled in order for this flag to be
415 * initialized to 'true'.
416 *
417 * @see #mSupportsSplitScreenMultiWindow
418 * @see #mSupportsFreeformWindowManagement
419 * @see #mSupportsPictureInPicture
420 * @see #mSupportsMultiDisplay
421 */
422 boolean mSupportsMultiWindow;
423 boolean mSupportsSplitScreenMultiWindow;
424 boolean mSupportsFreeformWindowManagement;
425 boolean mSupportsPictureInPicture;
426 boolean mSupportsMultiDisplay;
427 boolean mForceResizableActivities;
428
429 final List<ActivityTaskManagerInternal.ScreenObserver> mScreenObservers = new ArrayList<>();
430
431 // VR Vr2d Display Id.
432 int mVr2dDisplayId = INVALID_DISPLAY;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700433
Wale Ogunwalef6733932018-06-27 05:14:34 -0700434 /**
435 * Set while we are wanting to sleep, to prevent any
436 * activities from being started/resumed.
437 *
438 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
439 *
440 * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
441 * while in the sleep state until there is a pending transition out of sleep, in which case
442 * mSleeping is set to false, and remains false while awake.
443 *
444 * Whether mSleeping can quickly toggled between true/false without the device actually
445 * display changing states is undefined.
446 */
447 private boolean mSleeping = false;
448
449 /**
450 * The process state used for processes that are running the top activities.
451 * This changes between TOP and TOP_SLEEPING to following mSleeping.
452 */
453 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
454
455 // Whether we should show our dialogs (ANR, crash, etc) or just perform their default action
456 // automatically. Important for devices without direct input devices.
457 private boolean mShowDialogs = true;
458
459 /** Set if we are shutting down the system, similar to sleeping. */
460 boolean mShuttingDown = false;
461
462 /**
463 * We want to hold a wake lock while running a voice interaction session, since
464 * this may happen with the screen off and we need to keep the CPU running to
465 * be able to continue to interact with the user.
466 */
467 PowerManager.WakeLock mVoiceWakeLock;
468
469 /**
470 * Set while we are running a voice interaction. This overrides sleeping while it is active.
471 */
472 IVoiceInteractionSession mRunningVoice;
473
474 /**
475 * The last resumed activity. This is identical to the current resumed activity most
476 * of the time but could be different when we're pausing one activity before we resume
477 * another activity.
478 */
479 ActivityRecord mLastResumedActivity;
480
481 /**
482 * The activity that is currently being traced as the active resumed activity.
483 *
484 * @see #updateResumedAppTrace
485 */
486 private @Nullable ActivityRecord mTracedResumedActivity;
487
488 /** If non-null, we are tracking the time the user spends in the currently focused app. */
489 AppTimeTracker mCurAppTimeTracker;
490
Wale Ogunwale008163e2018-07-23 23:11:08 -0700491 private AppWarnings mAppWarnings;
492
Wale Ogunwale53783742018-09-16 10:21:51 -0700493 /**
494 * Packages that the user has asked to have run in screen size
495 * compatibility mode instead of filling the screen.
496 */
497 CompatModePackages mCompatModePackages;
498
Wale Ogunwalef6733932018-06-27 05:14:34 -0700499 private FontScaleSettingObserver mFontScaleSettingObserver;
500
501 private final class FontScaleSettingObserver extends ContentObserver {
502 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
503 private final Uri mHideErrorDialogsUri = Settings.Global.getUriFor(HIDE_ERROR_DIALOGS);
504
505 public FontScaleSettingObserver() {
506 super(mH);
507 final ContentResolver resolver = mContext.getContentResolver();
508 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
509 resolver.registerContentObserver(mHideErrorDialogsUri, false, this,
510 UserHandle.USER_ALL);
511 }
512
513 @Override
514 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
515 if (mFontScaleUri.equals(uri)) {
516 updateFontScaleIfNeeded(userId);
517 } else if (mHideErrorDialogsUri.equals(uri)) {
518 synchronized (mGlobalLock) {
519 updateShouldShowDialogsLocked(getGlobalConfiguration());
520 }
521 }
522 }
523 }
524
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700525 ActivityTaskManagerService(Context context) {
526 mContext = context;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700527 mUiContext = ActivityThread.currentActivityThread().getSystemUiContext();
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700528 mLifecycleManager = new ClientLifecycleManager();
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700529 }
530
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700531 void onSystemReady() {
532 mAssistUtils = new AssistUtils(mContext);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700533 mVrController.onSystemReady();
534 mRecentTasks.onSystemReadyLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700535 }
536
Wale Ogunwalef6733932018-06-27 05:14:34 -0700537 void onInitPowerManagement() {
538 mStackSupervisor.initPowerManagement();
539 final PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
540 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
541 mVoiceWakeLock.setReferenceCounted(false);
542 }
543
544 void installSystemProviders() {
545 mFontScaleSettingObserver = new FontScaleSettingObserver();
546 }
547
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700548 void retrieveSettings(ContentResolver resolver) {
549 final boolean freeformWindowManagement =
550 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
551 || Settings.Global.getInt(
552 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
553
554 final boolean supportsMultiWindow = ActivityTaskManager.supportsMultiWindow(mContext);
555 final boolean supportsPictureInPicture = supportsMultiWindow &&
556 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
557 final boolean supportsSplitScreenMultiWindow =
558 ActivityTaskManager.supportsSplitScreenMultiWindow(mContext);
559 final boolean supportsMultiDisplay = mContext.getPackageManager()
560 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
561 final boolean alwaysFinishActivities =
562 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
563 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
564 final boolean forceResizable = Settings.Global.getInt(
565 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
Garfield Tane0846042018-07-26 13:42:04 -0700566 final boolean isPc = mContext.getPackageManager().hasSystemFeature(FEATURE_PC);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700567
568 // Transfer any global setting for forcing RTL layout, into a System Property
569 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
570
571 final Configuration configuration = new Configuration();
572 Settings.System.getConfiguration(resolver, configuration);
573 if (forceRtl) {
574 // This will take care of setting the correct layout direction flags
575 configuration.setLayoutDirection(configuration.locale);
576 }
577
578 synchronized (mGlobalLock) {
579 mForceResizableActivities = forceResizable;
580 final boolean multiWindowFormEnabled = freeformWindowManagement
581 || supportsSplitScreenMultiWindow
582 || supportsPictureInPicture
583 || supportsMultiDisplay;
584 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
585 mSupportsMultiWindow = true;
586 mSupportsFreeformWindowManagement = freeformWindowManagement;
587 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
588 mSupportsPictureInPicture = supportsPictureInPicture;
589 mSupportsMultiDisplay = supportsMultiDisplay;
590 } else {
591 mSupportsMultiWindow = false;
592 mSupportsFreeformWindowManagement = false;
593 mSupportsSplitScreenMultiWindow = false;
594 mSupportsPictureInPicture = false;
595 mSupportsMultiDisplay = false;
596 }
597 mWindowManager.setForceResizableTasks(mForceResizableActivities);
598 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
Garfield Tane0846042018-07-26 13:42:04 -0700599 mWindowManager.setSupportsFreeformWindowManagement(mSupportsFreeformWindowManagement);
600 mWindowManager.setIsPc(isPc);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700601 // This happens before any activities are started, so we can change global configuration
602 // in-place.
603 updateConfigurationLocked(configuration, null, true);
604 final Configuration globalConfig = getGlobalConfiguration();
605 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
606
607 // Load resources only after the current configuration has been set.
608 final Resources res = mContext.getResources();
609 mThumbnailWidth = res.getDimensionPixelSize(
610 com.android.internal.R.dimen.thumbnail_width);
611 mThumbnailHeight = res.getDimensionPixelSize(
612 com.android.internal.R.dimen.thumbnail_height);
613
614 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
615 mFullscreenThumbnailScale = (float) res
616 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
617 (float) globalConfig.screenWidthDp;
618 } else {
619 mFullscreenThumbnailScale = res.getFraction(
620 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
621 }
622 }
623 }
624
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700625 // TODO: Will be converted to WM lock once transition is complete.
626 void setActivityManagerService(ActivityManagerService am) {
627 mAm = am;
628 mGlobalLock = mAm;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700629 mH = new H(mAm.mHandlerThread.getLooper());
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700630 mUiHandler = new UiHandler();
Wale Ogunwale53783742018-09-16 10:21:51 -0700631 final File systemDir = SystemServiceManager.ensureSystemDir();
632 mAppWarnings = new AppWarnings(this, mUiContext, mH, mUiHandler, systemDir);
633 mCompatModePackages = new CompatModePackages(this, systemDir, mH);
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700634 mPendingIntentController = mAm.mPendingIntentController;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700635
636 mTempConfig.setToDefaults();
637 mTempConfig.setLocales(LocaleList.getDefault());
638 mConfigurationSeq = mTempConfig.seq = 1;
639 mStackSupervisor = createStackSupervisor();
640 mStackSupervisor.onConfigurationChanged(mTempConfig);
641
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700642 mTaskChangeNotificationController =
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700643 new TaskChangeNotificationController(mGlobalLock, mStackSupervisor, mH);
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700644 mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mH);
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700645 mActivityStartController = new ActivityStartController(this);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700646 mRecentTasks = createRecentTasks();
647 mStackSupervisor.setRecentTasks(mRecentTasks);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700648 mVrController = new VrController(mGlobalLock);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700649 mKeyguardController = mStackSupervisor.getKeyguardController();
650 }
651
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700652 void onActivityManagerInternalAdded() {
653 mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700654 mUgmInternal = LocalServices.getService(UriGrantsManagerInternal.class);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700655 }
656
Yunfan Chen75157d72018-07-27 14:47:21 +0900657 int increaseConfigurationSeqLocked() {
658 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
659 return mConfigurationSeq;
660 }
661
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700662 protected ActivityStackSupervisor createStackSupervisor() {
663 final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mH.getLooper());
664 supervisor.initialize();
665 return supervisor;
666 }
667
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700668 void setWindowManager(WindowManagerService wm) {
669 mWindowManager = wm;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700670 mLockTaskController.setWindowManager(wm);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700671 }
672
Wale Ogunwalef6733932018-06-27 05:14:34 -0700673 UserManagerService getUserManager() {
674 if (mUserManager == null) {
675 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
676 mUserManager = (UserManagerService) IUserManager.Stub.asInterface(b);
677 }
678 return mUserManager;
679 }
680
681 AppOpsService getAppOpsService() {
682 if (mAppOpsService == null) {
683 IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
684 mAppOpsService = (AppOpsService) IAppOpsService.Stub.asInterface(b);
685 }
686 return mAppOpsService;
687 }
688
689 boolean hasUserRestriction(String restriction, int userId) {
690 return getUserManager().hasUserRestriction(restriction, userId);
691 }
692
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700693 protected RecentTasks createRecentTasks() {
694 return new RecentTasks(this, mStackSupervisor);
695 }
696
697 RecentTasks getRecentTasks() {
698 return mRecentTasks;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700699 }
700
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700701 ClientLifecycleManager getLifecycleManager() {
702 return mLifecycleManager;
703 }
704
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700705 ActivityStartController getActivityStartController() {
706 return mActivityStartController;
707 }
708
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700709 TaskChangeNotificationController getTaskChangeNotificationController() {
710 return mTaskChangeNotificationController;
711 }
712
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700713 LockTaskController getLockTaskController() {
714 return mLockTaskController;
715 }
716
Yunfan Chen75157d72018-07-27 14:47:21 +0900717 /**
718 * Return the global configuration used by the process corresponding to the input pid. This is
719 * usually the global configuration with some overrides specific to that process.
720 */
721 Configuration getGlobalConfigurationForCallingPid() {
722 final int pid = Binder.getCallingPid();
723 if (pid == MY_PID || pid < 0) {
724 return getGlobalConfiguration();
725 }
726 synchronized (mGlobalLock) {
727 final WindowProcessController app = mPidMap.get(pid);
728 return app != null ? app.getConfiguration() : getGlobalConfiguration();
729 }
730 }
731
732 /**
733 * Return the device configuration info used by the process corresponding to the input pid.
734 * The value is consistent with the global configuration for the process.
735 */
736 @Override
737 public ConfigurationInfo getDeviceConfigurationInfo() {
738 ConfigurationInfo config = new ConfigurationInfo();
739 synchronized (mGlobalLock) {
740 final Configuration globalConfig = getGlobalConfigurationForCallingPid();
741 config.reqTouchScreen = globalConfig.touchscreen;
742 config.reqKeyboardType = globalConfig.keyboard;
743 config.reqNavigation = globalConfig.navigation;
744 if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
745 || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
746 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
747 }
748 if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
749 && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
750 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
751 }
752 config.reqGlEsVersion = mAm.GL_ES_VERSION;
753 }
754 return config;
755 }
756
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700757 private void start() {
Wale Ogunwale53783742018-09-16 10:21:51 -0700758 mInternal = new LocalService();
759 LocalServices.addService(ActivityTaskManagerInternal.class, mInternal);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700760 }
761
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700762 public static final class Lifecycle extends SystemService {
763 private final ActivityTaskManagerService mService;
764
765 public Lifecycle(Context context) {
766 super(context);
767 mService = new ActivityTaskManagerService(context);
768 }
769
770 @Override
771 public void onStart() {
772 publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700773 mService.start();
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700774 }
775
776 public ActivityTaskManagerService getService() {
777 return mService;
778 }
779 }
780
781 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700782 public final int startActivity(IApplicationThread caller, String callingPackage,
783 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
784 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
785 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
786 resultWho, requestCode, startFlags, profilerInfo, bOptions,
787 UserHandle.getCallingUserId());
788 }
789
790 @Override
791 public final int startActivities(IApplicationThread caller, String callingPackage,
792 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
793 int userId) {
794 final String reason = "startActivities";
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700795 enforceNotIsolatedCaller(reason);
796 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, reason);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700797 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700798 return getActivityStartController().startActivities(caller, -1, callingPackage, intents,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100799 resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId, reason,
800 null /* originatingPendingIntent */);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700801 }
802
803 @Override
804 public int startActivityAsUser(IApplicationThread caller, String callingPackage,
805 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
806 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
807 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
808 resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
809 true /*validateIncomingUser*/);
810 }
811
812 int startActivityAsUser(IApplicationThread caller, String callingPackage,
813 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
814 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
815 boolean validateIncomingUser) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700816 enforceNotIsolatedCaller("startActivityAsUser");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700817
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700818 userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700819 Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
820
821 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700822 return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700823 .setCaller(caller)
824 .setCallingPackage(callingPackage)
825 .setResolvedType(resolvedType)
826 .setResultTo(resultTo)
827 .setResultWho(resultWho)
828 .setRequestCode(requestCode)
829 .setStartFlags(startFlags)
830 .setProfilerInfo(profilerInfo)
831 .setActivityOptions(bOptions)
832 .setMayWait(userId)
833 .execute();
834
835 }
836
837 @Override
838 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
839 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700840 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions) {
841 enforceNotIsolatedCaller("startActivityIntentSender");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700842 // Refuse possible leaked file descriptors
843 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
844 throw new IllegalArgumentException("File descriptors passed in Intent");
845 }
846
847 if (!(target instanceof PendingIntentRecord)) {
848 throw new IllegalArgumentException("Bad PendingIntent object");
849 }
850
851 PendingIntentRecord pir = (PendingIntentRecord)target;
852
853 synchronized (mGlobalLock) {
854 // If this is coming from the currently resumed activity, it is
855 // effectively saying that app switches are allowed at this point.
Andrii Kulian5f750bc2018-07-17 08:57:23 -0700856 final ActivityStack stack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700857 if (stack.mResumedActivity != null &&
858 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700859 mAppSwitchesAllowedTime = 0;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700860 }
861 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700862 return pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700863 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700864 }
865
866 @Override
867 public boolean startNextMatchingActivity(IBinder callingActivity, Intent intent,
868 Bundle bOptions) {
869 // Refuse possible leaked file descriptors
870 if (intent != null && intent.hasFileDescriptors()) {
871 throw new IllegalArgumentException("File descriptors passed in Intent");
872 }
873 SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
874
875 synchronized (mGlobalLock) {
876 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
877 if (r == null) {
878 SafeActivityOptions.abort(options);
879 return false;
880 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700881 if (!r.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700882 // The caller is not running... d'oh!
883 SafeActivityOptions.abort(options);
884 return false;
885 }
886 intent = new Intent(intent);
887 // The caller is not allowed to change the data.
888 intent.setDataAndType(r.intent.getData(), r.intent.getType());
889 // And we are resetting to find the next component...
890 intent.setComponent(null);
891
892 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
893
894 ActivityInfo aInfo = null;
895 try {
896 List<ResolveInfo> resolves =
897 AppGlobals.getPackageManager().queryIntentActivities(
898 intent, r.resolvedType,
899 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
900 UserHandle.getCallingUserId()).getList();
901
902 // Look for the original activity in the list...
903 final int N = resolves != null ? resolves.size() : 0;
904 for (int i=0; i<N; i++) {
905 ResolveInfo rInfo = resolves.get(i);
906 if (rInfo.activityInfo.packageName.equals(r.packageName)
907 && rInfo.activityInfo.name.equals(r.info.name)) {
908 // We found the current one... the next matching is
909 // after it.
910 i++;
911 if (i<N) {
912 aInfo = resolves.get(i).activityInfo;
913 }
914 if (debug) {
915 Slog.v(TAG, "Next matching activity: found current " + r.packageName
916 + "/" + r.info.name);
917 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
918 ? "null" : aInfo.packageName + "/" + aInfo.name));
919 }
920 break;
921 }
922 }
923 } catch (RemoteException e) {
924 }
925
926 if (aInfo == null) {
927 // Nobody who is next!
928 SafeActivityOptions.abort(options);
929 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
930 return false;
931 }
932
933 intent.setComponent(new ComponentName(
934 aInfo.applicationInfo.packageName, aInfo.name));
935 intent.setFlags(intent.getFlags()&~(
936 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
937 Intent.FLAG_ACTIVITY_CLEAR_TOP|
938 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
939 FLAG_ACTIVITY_NEW_TASK));
940
941 // Okay now we need to start the new activity, replacing the currently running activity.
942 // This is a little tricky because we want to start the new one as if the current one is
943 // finished, but not finish the current one first so that there is no flicker.
944 // And thus...
945 final boolean wasFinishing = r.finishing;
946 r.finishing = true;
947
948 // Propagate reply information over to the new activity.
949 final ActivityRecord resultTo = r.resultTo;
950 final String resultWho = r.resultWho;
951 final int requestCode = r.requestCode;
952 r.resultTo = null;
953 if (resultTo != null) {
954 resultTo.removeResultsLocked(r, resultWho, requestCode);
955 }
956
957 final long origId = Binder.clearCallingIdentity();
958 // TODO(b/64750076): Check if calling pid should really be -1.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700959 final int res = getActivityStartController()
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700960 .obtainStarter(intent, "startNextMatchingActivity")
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700961 .setCaller(r.app.getThread())
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700962 .setResolvedType(r.resolvedType)
963 .setActivityInfo(aInfo)
964 .setResultTo(resultTo != null ? resultTo.appToken : null)
965 .setResultWho(resultWho)
966 .setRequestCode(requestCode)
967 .setCallingPid(-1)
968 .setCallingUid(r.launchedFromUid)
969 .setCallingPackage(r.launchedFromPackage)
970 .setRealCallingPid(-1)
971 .setRealCallingUid(r.launchedFromUid)
972 .setActivityOptions(options)
973 .execute();
974 Binder.restoreCallingIdentity(origId);
975
976 r.finishing = wasFinishing;
977 if (res != ActivityManager.START_SUCCESS) {
978 return false;
979 }
980 return true;
981 }
982 }
983
984 @Override
985 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
986 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
987 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
988 final WaitResult res = new WaitResult();
989 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700990 enforceNotIsolatedCaller("startActivityAndWait");
991 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
992 userId, "startActivityAndWait");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700993 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700994 getActivityStartController().obtainStarter(intent, "startActivityAndWait")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700995 .setCaller(caller)
996 .setCallingPackage(callingPackage)
997 .setResolvedType(resolvedType)
998 .setResultTo(resultTo)
999 .setResultWho(resultWho)
1000 .setRequestCode(requestCode)
1001 .setStartFlags(startFlags)
1002 .setActivityOptions(bOptions)
1003 .setMayWait(userId)
1004 .setProfilerInfo(profilerInfo)
1005 .setWaitResult(res)
1006 .execute();
1007 }
1008 return res;
1009 }
1010
1011 @Override
1012 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
1013 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1014 int startFlags, Configuration config, Bundle bOptions, int userId) {
1015 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001016 enforceNotIsolatedCaller("startActivityWithConfig");
1017 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
1018 "startActivityWithConfig");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001019 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001020 return getActivityStartController().obtainStarter(intent, "startActivityWithConfig")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001021 .setCaller(caller)
1022 .setCallingPackage(callingPackage)
1023 .setResolvedType(resolvedType)
1024 .setResultTo(resultTo)
1025 .setResultWho(resultWho)
1026 .setRequestCode(requestCode)
1027 .setStartFlags(startFlags)
1028 .setGlobalConfiguration(config)
1029 .setActivityOptions(bOptions)
1030 .setMayWait(userId)
1031 .execute();
1032 }
1033 }
1034
1035 @Override
1036 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
1037 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1038 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
1039 int userId) {
1040
1041 // This is very dangerous -- it allows you to perform a start activity (including
1042 // permission grants) as any app that may launch one of your own activities. So
1043 // we will only allow this to be done from activities that are part of the core framework,
1044 // and then only when they are running as the system.
1045 final ActivityRecord sourceRecord;
1046 final int targetUid;
1047 final String targetPackage;
1048 final boolean isResolver;
1049 synchronized (mGlobalLock) {
1050 if (resultTo == null) {
1051 throw new SecurityException("Must be called from an activity");
1052 }
1053 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
1054 if (sourceRecord == null) {
1055 throw new SecurityException("Called with bad activity token: " + resultTo);
1056 }
1057 if (!sourceRecord.info.packageName.equals("android")) {
1058 throw new SecurityException(
1059 "Must be called from an activity that is declared in the android package");
1060 }
1061 if (sourceRecord.app == null) {
1062 throw new SecurityException("Called without a process attached to activity");
1063 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001064 if (UserHandle.getAppId(sourceRecord.app.mUid) != SYSTEM_UID) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001065 // This is still okay, as long as this activity is running under the
1066 // uid of the original calling activity.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001067 if (sourceRecord.app.mUid != sourceRecord.launchedFromUid) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001068 throw new SecurityException(
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001069 "Calling activity in uid " + sourceRecord.app.mUid
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001070 + " must be system uid or original calling uid "
1071 + sourceRecord.launchedFromUid);
1072 }
1073 }
1074 if (ignoreTargetSecurity) {
1075 if (intent.getComponent() == null) {
1076 throw new SecurityException(
1077 "Component must be specified with ignoreTargetSecurity");
1078 }
1079 if (intent.getSelector() != null) {
1080 throw new SecurityException(
1081 "Selector not allowed with ignoreTargetSecurity");
1082 }
1083 }
1084 targetUid = sourceRecord.launchedFromUid;
1085 targetPackage = sourceRecord.launchedFromPackage;
1086 isResolver = sourceRecord.isResolverOrChildActivity();
1087 }
1088
1089 if (userId == UserHandle.USER_NULL) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001090 userId = UserHandle.getUserId(sourceRecord.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001091 }
1092
1093 // TODO: Switch to user app stacks here.
1094 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001095 return getActivityStartController().obtainStarter(intent, "startActivityAsCaller")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001096 .setCallingUid(targetUid)
1097 .setCallingPackage(targetPackage)
1098 .setResolvedType(resolvedType)
1099 .setResultTo(resultTo)
1100 .setResultWho(resultWho)
1101 .setRequestCode(requestCode)
1102 .setStartFlags(startFlags)
1103 .setActivityOptions(bOptions)
1104 .setMayWait(userId)
1105 .setIgnoreTargetSecurity(ignoreTargetSecurity)
1106 .setFilterCallingUid(isResolver ? 0 /* system */ : targetUid)
1107 .execute();
1108 } catch (SecurityException e) {
1109 // XXX need to figure out how to propagate to original app.
1110 // A SecurityException here is generally actually a fault of the original
1111 // calling activity (such as a fairly granting permissions), so propagate it
1112 // back to them.
1113 /*
1114 StringBuilder msg = new StringBuilder();
1115 msg.append("While launching");
1116 msg.append(intent.toString());
1117 msg.append(": ");
1118 msg.append(e.getMessage());
1119 */
1120 throw e;
1121 }
1122 }
1123
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001124 int handleIncomingUser(int callingPid, int callingUid, int userId, String name) {
1125 return mAmInternal.handleIncomingUser(callingPid, callingUid, userId, false /* allowAll */,
1126 ALLOW_FULL_ONLY, name, null /* callerPackage */);
1127 }
1128
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001129 @Override
1130 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
1131 Intent intent, String resolvedType, IVoiceInteractionSession session,
1132 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
1133 Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001134 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001135 if (session == null || interactor == null) {
1136 throw new NullPointerException("null session or interactor");
1137 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001138 userId = handleIncomingUser(callingPid, callingUid, userId, "startVoiceActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001139 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001140 return getActivityStartController().obtainStarter(intent, "startVoiceActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001141 .setCallingUid(callingUid)
1142 .setCallingPackage(callingPackage)
1143 .setResolvedType(resolvedType)
1144 .setVoiceSession(session)
1145 .setVoiceInteractor(interactor)
1146 .setStartFlags(startFlags)
1147 .setProfilerInfo(profilerInfo)
1148 .setActivityOptions(bOptions)
1149 .setMayWait(userId)
1150 .execute();
1151 }
1152
1153 @Override
1154 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
1155 Intent intent, String resolvedType, Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001156 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
1157 userId = handleIncomingUser(callingPid, callingUid, userId, "startAssistantActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001158
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001159 return getActivityStartController().obtainStarter(intent, "startAssistantActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001160 .setCallingUid(callingUid)
1161 .setCallingPackage(callingPackage)
1162 .setResolvedType(resolvedType)
1163 .setActivityOptions(bOptions)
1164 .setMayWait(userId)
1165 .execute();
1166 }
1167
1168 @Override
1169 public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
1170 IRecentsAnimationRunner recentsAnimationRunner) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001171 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001172 final int callingPid = Binder.getCallingPid();
1173 final long origId = Binder.clearCallingIdentity();
1174 try {
1175 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07001176 final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
1177 final int recentsUid = mRecentTasks.getRecentsComponentUid();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001178
1179 // Start a new recents animation
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001180 final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
1181 getActivityStartController(), mWindowManager, callingPid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001182 anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
1183 recentsUid, assistDataReceiver);
1184 }
1185 } finally {
1186 Binder.restoreCallingIdentity(origId);
1187 }
1188 }
1189
1190 @Override
1191 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001192 enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001193 "startActivityFromRecents()");
1194
1195 final int callingPid = Binder.getCallingPid();
1196 final int callingUid = Binder.getCallingUid();
1197 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(bOptions);
1198 final long origId = Binder.clearCallingIdentity();
1199 try {
1200 synchronized (mGlobalLock) {
1201 return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
1202 safeOptions);
1203 }
1204 } finally {
1205 Binder.restoreCallingIdentity(origId);
1206 }
1207 }
1208
1209 /**
1210 * This is the internal entry point for handling Activity.finish().
1211 *
1212 * @param token The Binder token referencing the Activity we want to finish.
1213 * @param resultCode Result code, if any, from this Activity.
1214 * @param resultData Result data (Intent), if any, from this Activity.
1215 * @param finishTask Whether to finish the task associated with this Activity.
1216 *
1217 * @return Returns true if the activity successfully finished, or false if it is still running.
1218 */
1219 @Override
1220 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
1221 int finishTask) {
1222 // Refuse possible leaked file descriptors
1223 if (resultData != null && resultData.hasFileDescriptors()) {
1224 throw new IllegalArgumentException("File descriptors passed in Intent");
1225 }
1226
1227 synchronized (mGlobalLock) {
1228 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1229 if (r == null) {
1230 return true;
1231 }
1232 // Keep track of the root activity of the task before we finish it
1233 TaskRecord tr = r.getTask();
1234 ActivityRecord rootR = tr.getRootActivity();
1235 if (rootR == null) {
1236 Slog.w(TAG, "Finishing task with all activities already finished");
1237 }
1238 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
1239 // finish.
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001240 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001241 return false;
1242 }
1243
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001244 // TODO: There is a dup. of this block of code in ActivityStack.navigateUpToLocked
1245 // We should consolidate.
1246 if (mController != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001247 // Find the first activity that is not finishing.
1248 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
1249 if (next != null) {
1250 // ask watcher if this is allowed
1251 boolean resumeOK = true;
1252 try {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001253 resumeOK = mController.activityResuming(next.packageName);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001254 } catch (RemoteException e) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001255 mController = null;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001256 Watchdog.getInstance().setActivityController(null);
1257 }
1258
1259 if (!resumeOK) {
1260 Slog.i(TAG, "Not finishing activity because controller resumed");
1261 return false;
1262 }
1263 }
1264 }
1265 final long origId = Binder.clearCallingIdentity();
1266 try {
1267 boolean res;
1268 final boolean finishWithRootActivity =
1269 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
1270 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
1271 || (finishWithRootActivity && r == rootR)) {
1272 // If requested, remove the task that is associated to this activity only if it
1273 // was the root activity in the task. The result code and data is ignored
1274 // because we don't support returning them across task boundaries. Also, to
1275 // keep backwards compatibility we remove the task from recents when finishing
1276 // task with root activity.
1277 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
1278 finishWithRootActivity, "finish-activity");
1279 if (!res) {
1280 Slog.i(TAG, "Removing task failed to finish activity");
1281 }
Garfield Tan2746ab52018-07-25 12:33:01 -07001282 // Explicitly dismissing the activity so reset its relaunch flag.
1283 r.mRelaunchReason = ActivityRecord.RELAUNCH_REASON_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001284 } else {
1285 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
1286 resultData, "app-request", true);
1287 if (!res) {
1288 Slog.i(TAG, "Failed to finish by app-request");
1289 }
1290 }
1291 return res;
1292 } finally {
1293 Binder.restoreCallingIdentity(origId);
1294 }
1295 }
1296 }
1297
1298 @Override
1299 public boolean finishActivityAffinity(IBinder token) {
1300 synchronized (mGlobalLock) {
1301 final long origId = Binder.clearCallingIdentity();
1302 try {
1303 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1304 if (r == null) {
1305 return false;
1306 }
1307
1308 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
1309 // can finish.
1310 final TaskRecord task = r.getTask();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001311 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001312 return false;
1313 }
1314 return task.getStack().finishActivityAffinityLocked(r);
1315 } finally {
1316 Binder.restoreCallingIdentity(origId);
1317 }
1318 }
1319 }
1320
1321 @Override
1322 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
1323 final long origId = Binder.clearCallingIdentity();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001324 try {
1325 WindowProcessController proc = null;
1326 synchronized (mGlobalLock) {
1327 ActivityStack stack = ActivityRecord.getStackLocked(token);
1328 if (stack == null) {
1329 return;
1330 }
1331 final ActivityRecord r = mStackSupervisor.activityIdleInternalLocked(token,
1332 false /* fromTimeout */, false /* processPausingActivities */, config);
1333 if (r != null) {
1334 proc = r.app;
1335 }
1336 if (stopProfiling && proc != null) {
1337 proc.clearProfilerIfNeeded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001338 }
1339 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001340 } finally {
1341 Binder.restoreCallingIdentity(origId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001342 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001343 }
1344
1345 @Override
1346 public final void activityResumed(IBinder token) {
1347 final long origId = Binder.clearCallingIdentity();
1348 synchronized (mGlobalLock) {
1349 ActivityRecord.activityResumedLocked(token);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001350 mWindowManager.notifyAppResumedFinished(token);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001351 }
1352 Binder.restoreCallingIdentity(origId);
1353 }
1354
1355 @Override
1356 public final void activityPaused(IBinder token) {
1357 final long origId = Binder.clearCallingIdentity();
1358 synchronized (mGlobalLock) {
1359 ActivityStack stack = ActivityRecord.getStackLocked(token);
1360 if (stack != null) {
1361 stack.activityPausedLocked(token, false);
1362 }
1363 }
1364 Binder.restoreCallingIdentity(origId);
1365 }
1366
1367 @Override
1368 public final void activityStopped(IBinder token, Bundle icicle,
1369 PersistableBundle persistentState, CharSequence description) {
1370 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
1371
1372 // Refuse possible leaked file descriptors
1373 if (icicle != null && icicle.hasFileDescriptors()) {
1374 throw new IllegalArgumentException("File descriptors passed in Bundle");
1375 }
1376
1377 final long origId = Binder.clearCallingIdentity();
1378
1379 synchronized (mGlobalLock) {
1380 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1381 if (r != null) {
1382 r.activityStoppedLocked(icicle, persistentState, description);
1383 }
1384 }
1385
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001386 mAmInternal.trimApplications();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001387
1388 Binder.restoreCallingIdentity(origId);
1389 }
1390
1391 @Override
1392 public final void activityDestroyed(IBinder token) {
1393 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
1394 synchronized (mGlobalLock) {
1395 ActivityStack stack = ActivityRecord.getStackLocked(token);
1396 if (stack != null) {
1397 stack.activityDestroyedLocked(token, "activityDestroyed");
1398 }
1399 }
1400 }
1401
1402 @Override
1403 public final void activityRelaunched(IBinder token) {
1404 final long origId = Binder.clearCallingIdentity();
1405 synchronized (mGlobalLock) {
1406 mStackSupervisor.activityRelaunchedLocked(token);
1407 }
1408 Binder.restoreCallingIdentity(origId);
1409 }
1410
1411 public final void activitySlept(IBinder token) {
1412 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
1413
1414 final long origId = Binder.clearCallingIdentity();
1415
1416 synchronized (mGlobalLock) {
1417 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1418 if (r != null) {
1419 mStackSupervisor.activitySleptLocked(r);
1420 }
1421 }
1422
1423 Binder.restoreCallingIdentity(origId);
1424 }
1425
1426 @Override
1427 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
1428 synchronized (mGlobalLock) {
1429 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1430 if (r == null) {
1431 return;
1432 }
1433 final long origId = Binder.clearCallingIdentity();
1434 try {
1435 r.setRequestedOrientation(requestedOrientation);
1436 } finally {
1437 Binder.restoreCallingIdentity(origId);
1438 }
1439 }
1440 }
1441
1442 @Override
1443 public int getRequestedOrientation(IBinder token) {
1444 synchronized (mGlobalLock) {
1445 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1446 if (r == null) {
1447 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
1448 }
1449 return r.getRequestedOrientation();
1450 }
1451 }
1452
1453 @Override
1454 public void setImmersive(IBinder token, boolean immersive) {
1455 synchronized (mGlobalLock) {
1456 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1457 if (r == null) {
1458 throw new IllegalArgumentException();
1459 }
1460 r.immersive = immersive;
1461
1462 // update associated state if we're frontmost
Andrii Kulian52d255c2018-07-13 11:32:19 -07001463 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001464 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001465 applyUpdateLockStateLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001466 }
1467 }
1468 }
1469
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001470 void applyUpdateLockStateLocked(ActivityRecord r) {
1471 // Modifications to the UpdateLock state are done on our handler, outside
1472 // the activity manager's locks. The new state is determined based on the
1473 // state *now* of the relevant activity record. The object is passed to
1474 // the handler solely for logging detail, not to be consulted/modified.
1475 final boolean nextState = r != null && r.immersive;
1476 mH.post(() -> {
1477 if (mUpdateLock.isHeld() != nextState) {
1478 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1479 "Applying new update lock state '" + nextState + "' for " + r);
1480 if (nextState) {
1481 mUpdateLock.acquire();
1482 } else {
1483 mUpdateLock.release();
1484 }
1485 }
1486 });
1487 }
1488
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001489 @Override
1490 public boolean isImmersive(IBinder token) {
1491 synchronized (mGlobalLock) {
1492 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1493 if (r == null) {
1494 throw new IllegalArgumentException();
1495 }
1496 return r.immersive;
1497 }
1498 }
1499
1500 @Override
1501 public boolean isTopActivityImmersive() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001502 enforceNotIsolatedCaller("isTopActivityImmersive");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001503 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001504 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001505 return (r != null) ? r.immersive : false;
1506 }
1507 }
1508
1509 @Override
1510 public void overridePendingTransition(IBinder token, String packageName,
1511 int enterAnim, int exitAnim) {
1512 synchronized (mGlobalLock) {
1513 ActivityRecord self = ActivityRecord.isInStackLocked(token);
1514 if (self == null) {
1515 return;
1516 }
1517
1518 final long origId = Binder.clearCallingIdentity();
1519
1520 if (self.isState(
1521 ActivityStack.ActivityState.RESUMED, ActivityStack.ActivityState.PAUSING)) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001522 mWindowManager.overridePendingAppTransition(packageName,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001523 enterAnim, exitAnim, null);
1524 }
1525
1526 Binder.restoreCallingIdentity(origId);
1527 }
1528 }
1529
1530 @Override
1531 public int getFrontActivityScreenCompatMode() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001532 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001533 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001534 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001535 if (r == null) {
1536 return ActivityManager.COMPAT_MODE_UNKNOWN;
1537 }
Wale Ogunwale53783742018-09-16 10:21:51 -07001538 return mCompatModePackages.computeCompatModeLocked(r.info.applicationInfo);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001539 }
1540 }
1541
1542 @Override
1543 public void setFrontActivityScreenCompatMode(int mode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001544 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001545 "setFrontActivityScreenCompatMode");
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001546 ApplicationInfo ai;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001547 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001548 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001549 if (r == null) {
1550 Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity");
1551 return;
1552 }
1553 ai = r.info.applicationInfo;
Wale Ogunwale53783742018-09-16 10:21:51 -07001554 mCompatModePackages.setPackageScreenCompatModeLocked(ai, mode);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001555 }
1556 }
1557
1558 @Override
1559 public int getLaunchedFromUid(IBinder activityToken) {
1560 ActivityRecord srec;
1561 synchronized (mGlobalLock) {
1562 srec = ActivityRecord.forTokenLocked(activityToken);
1563 }
1564 if (srec == null) {
1565 return -1;
1566 }
1567 return srec.launchedFromUid;
1568 }
1569
1570 @Override
1571 public String getLaunchedFromPackage(IBinder activityToken) {
1572 ActivityRecord srec;
1573 synchronized (mGlobalLock) {
1574 srec = ActivityRecord.forTokenLocked(activityToken);
1575 }
1576 if (srec == null) {
1577 return null;
1578 }
1579 return srec.launchedFromPackage;
1580 }
1581
1582 @Override
1583 public boolean convertFromTranslucent(IBinder token) {
1584 final long origId = Binder.clearCallingIdentity();
1585 try {
1586 synchronized (mGlobalLock) {
1587 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1588 if (r == null) {
1589 return false;
1590 }
1591 final boolean translucentChanged = r.changeWindowTranslucency(true);
1592 if (translucentChanged) {
1593 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
1594 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001595 mWindowManager.setAppFullscreen(token, true);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001596 return translucentChanged;
1597 }
1598 } finally {
1599 Binder.restoreCallingIdentity(origId);
1600 }
1601 }
1602
1603 @Override
1604 public boolean convertToTranslucent(IBinder token, Bundle options) {
1605 SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
1606 final long origId = Binder.clearCallingIdentity();
1607 try {
1608 synchronized (mGlobalLock) {
1609 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1610 if (r == null) {
1611 return false;
1612 }
1613 final TaskRecord task = r.getTask();
1614 int index = task.mActivities.lastIndexOf(r);
1615 if (index > 0) {
1616 ActivityRecord under = task.mActivities.get(index - 1);
1617 under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
1618 }
1619 final boolean translucentChanged = r.changeWindowTranslucency(false);
1620 if (translucentChanged) {
1621 r.getStack().convertActivityToTranslucent(r);
1622 }
1623 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001624 mWindowManager.setAppFullscreen(token, false);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001625 return translucentChanged;
1626 }
1627 } finally {
1628 Binder.restoreCallingIdentity(origId);
1629 }
1630 }
1631
1632 @Override
1633 public void notifyActivityDrawn(IBinder token) {
1634 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
1635 synchronized (mGlobalLock) {
1636 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
1637 if (r != null) {
1638 r.getStack().notifyActivityDrawnLocked(r);
1639 }
1640 }
1641 }
1642
1643 @Override
1644 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
1645 synchronized (mGlobalLock) {
1646 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1647 if (r == null) {
1648 return;
1649 }
1650 r.reportFullyDrawnLocked(restoredFromBundle);
1651 }
1652 }
1653
1654 @Override
1655 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
1656 synchronized (mGlobalLock) {
1657 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
1658 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
1659 return stack.mDisplayId;
1660 }
1661 return DEFAULT_DISPLAY;
1662 }
1663 }
1664
1665 @Override
1666 public ActivityManager.StackInfo getFocusedStackInfo() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001667 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001668 long ident = Binder.clearCallingIdentity();
1669 try {
1670 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001671 ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001672 if (focusedStack != null) {
1673 return mStackSupervisor.getStackInfo(focusedStack.mStackId);
1674 }
1675 return null;
1676 }
1677 } finally {
1678 Binder.restoreCallingIdentity(ident);
1679 }
1680 }
1681
1682 @Override
1683 public void setFocusedStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001684 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001685 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
1686 final long callingId = Binder.clearCallingIdentity();
1687 try {
1688 synchronized (mGlobalLock) {
1689 final ActivityStack stack = mStackSupervisor.getStack(stackId);
1690 if (stack == null) {
1691 Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
1692 return;
1693 }
1694 final ActivityRecord r = stack.topRunningActivityLocked();
1695 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
1696 r, "setFocusedStack")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08001697 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001698 }
1699 }
1700 } finally {
1701 Binder.restoreCallingIdentity(callingId);
1702 }
1703 }
1704
1705 @Override
1706 public void setFocusedTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001707 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001708 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
1709 final long callingId = Binder.clearCallingIdentity();
1710 try {
1711 synchronized (mGlobalLock) {
1712 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1713 if (task == null) {
1714 return;
1715 }
1716 final ActivityRecord r = task.topRunningActivityLocked();
1717 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08001718 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001719 }
1720 }
1721 } finally {
1722 Binder.restoreCallingIdentity(callingId);
1723 }
1724 }
1725
1726 @Override
1727 public boolean removeTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001728 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001729 synchronized (mGlobalLock) {
1730 final long ident = Binder.clearCallingIdentity();
1731 try {
1732 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
1733 "remove-task");
1734 } finally {
1735 Binder.restoreCallingIdentity(ident);
1736 }
1737 }
1738 }
1739
1740 @Override
Winson Chunge6439102018-07-30 15:48:01 -07001741 public void removeAllVisibleRecentTasks() {
1742 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeAllVisibleRecentTasks()");
1743 synchronized (mGlobalLock) {
1744 final long ident = Binder.clearCallingIdentity();
1745 try {
1746 getRecentTasks().removeAllVisibleTasks();
1747 } finally {
1748 Binder.restoreCallingIdentity(ident);
1749 }
1750 }
1751 }
1752
1753 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001754 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
1755 synchronized (mGlobalLock) {
1756 final ActivityRecord srec = ActivityRecord.forTokenLocked(token);
1757 if (srec != null) {
1758 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
1759 }
1760 }
1761 return false;
1762 }
1763
1764 @Override
1765 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
1766 Intent resultData) {
1767
1768 synchronized (mGlobalLock) {
1769 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
1770 if (r != null) {
1771 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
1772 }
1773 return false;
1774 }
1775 }
1776
1777 /**
1778 * Attempts to move a task backwards in z-order (the order of activities within the task is
1779 * unchanged).
1780 *
1781 * There are several possible results of this call:
1782 * - if the task is locked, then we will show the lock toast
1783 * - if there is a task behind the provided task, then that task is made visible and resumed as
1784 * this task is moved to the back
1785 * - otherwise, if there are no other tasks in the stack:
1786 * - if this task is in the pinned stack, then we remove the stack completely, which will
1787 * have the effect of moving the task to the top or bottom of the fullscreen stack
1788 * (depending on whether it is visible)
1789 * - otherwise, we simply return home and hide this task
1790 *
1791 * @param token A reference to the activity we wish to move
1792 * @param nonRoot If false then this only works if the activity is the root
1793 * of a task; if true it will work for any activity in a task.
1794 * @return Returns true if the move completed, false if not.
1795 */
1796 @Override
1797 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001798 enforceNotIsolatedCaller("moveActivityTaskToBack");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001799 synchronized (mGlobalLock) {
1800 final long origId = Binder.clearCallingIdentity();
1801 try {
1802 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
1803 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1804 if (task != null) {
1805 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
1806 }
1807 } finally {
1808 Binder.restoreCallingIdentity(origId);
1809 }
1810 }
1811 return false;
1812 }
1813
1814 @Override
1815 public Rect getTaskBounds(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001816 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001817 long ident = Binder.clearCallingIdentity();
1818 Rect rect = new Rect();
1819 try {
1820 synchronized (mGlobalLock) {
1821 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
1822 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1823 if (task == null) {
1824 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
1825 return rect;
1826 }
1827 if (task.getStack() != null) {
1828 // Return the bounds from window manager since it will be adjusted for various
1829 // things like the presense of a docked stack for tasks that aren't resizeable.
1830 task.getWindowContainerBounds(rect);
1831 } else {
1832 // Task isn't in window manager yet since it isn't associated with a stack.
1833 // Return the persist value from activity manager
1834 if (!task.matchParentBounds()) {
1835 rect.set(task.getBounds());
1836 } else if (task.mLastNonFullscreenBounds != null) {
1837 rect.set(task.mLastNonFullscreenBounds);
1838 }
1839 }
1840 }
1841 } finally {
1842 Binder.restoreCallingIdentity(ident);
1843 }
1844 return rect;
1845 }
1846
1847 @Override
1848 public ActivityManager.TaskDescription getTaskDescription(int id) {
1849 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001850 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001851 MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
1852 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
1853 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1854 if (tr != null) {
1855 return tr.lastTaskDescription;
1856 }
1857 }
1858 return null;
1859 }
1860
1861 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001862 public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
1863 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
1864 setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
1865 toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
1866 return;
1867 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001868 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001869 synchronized (mGlobalLock) {
1870 final long ident = Binder.clearCallingIdentity();
1871 try {
1872 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1873 if (task == null) {
1874 Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
1875 return;
1876 }
1877
1878 if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
1879 + " to windowingMode=" + windowingMode + " toTop=" + toTop);
1880
1881 if (!task.isActivityTypeStandardOrUndefined()) {
1882 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
1883 + " non-standard task " + taskId + " to windowing mode="
1884 + windowingMode);
1885 }
1886
1887 final ActivityStack stack = task.getStack();
1888 if (toTop) {
1889 stack.moveToFront("setTaskWindowingMode", task);
1890 }
1891 stack.setWindowingMode(windowingMode);
1892 } finally {
1893 Binder.restoreCallingIdentity(ident);
1894 }
1895 }
1896 }
1897
1898 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001899 public String getCallingPackage(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001900 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001901 ActivityRecord r = getCallingRecordLocked(token);
1902 return r != null ? r.info.packageName : null;
1903 }
1904 }
1905
1906 @Override
1907 public ComponentName getCallingActivity(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001908 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001909 ActivityRecord r = getCallingRecordLocked(token);
1910 return r != null ? r.intent.getComponent() : null;
1911 }
1912 }
1913
1914 private ActivityRecord getCallingRecordLocked(IBinder token) {
1915 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1916 if (r == null) {
1917 return null;
1918 }
1919 return r.resultTo;
1920 }
1921
1922 @Override
1923 public void unhandledBack() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001924 mAmInternal.enforceCallingPermission(android.Manifest.permission.FORCE_BACK, "unhandledBack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001925
1926 synchronized (mGlobalLock) {
1927 final long origId = Binder.clearCallingIdentity();
1928 try {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001929 getTopDisplayFocusedStack().unhandledBackLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001930 } finally {
1931 Binder.restoreCallingIdentity(origId);
1932 }
1933 }
1934 }
1935
1936 /**
1937 * TODO: Add mController hook
1938 */
1939 @Override
1940 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001941 mAmInternal.enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001942
1943 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
1944 synchronized (mGlobalLock) {
1945 moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
1946 false /* fromRecents */);
1947 }
1948 }
1949
1950 void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
1951 boolean fromRecents) {
1952
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001953 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001954 Binder.getCallingUid(), -1, -1, "Task to front")) {
1955 SafeActivityOptions.abort(options);
1956 return;
1957 }
1958 final long origId = Binder.clearCallingIdentity();
1959 try {
1960 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1961 if (task == null) {
1962 Slog.d(TAG, "Could not find task for id: "+ taskId);
Winson Chungd0243682018-09-25 18:11:54 -07001963 SafeActivityOptions.abort(options);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001964 return;
1965 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001966 if (getLockTaskController().isLockTaskModeViolation(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001967 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
Winson Chungd0243682018-09-25 18:11:54 -07001968 SafeActivityOptions.abort(options);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001969 return;
1970 }
1971 ActivityOptions realOptions = options != null
1972 ? options.getOptions(mStackSupervisor)
1973 : null;
1974 mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
1975 false /* forceNonResizable */);
1976
1977 final ActivityRecord topActivity = task.getTopActivity();
1978 if (topActivity != null) {
1979
1980 // We are reshowing a task, use a starting window to hide the initial draw delay
1981 // so the transition can start earlier.
1982 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
1983 true /* taskSwitch */, fromRecents);
1984 }
1985 } finally {
1986 Binder.restoreCallingIdentity(origId);
1987 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001988 }
1989
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001990 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
1991 int callingPid, int callingUid, String name) {
1992 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
1993 return true;
1994 }
1995
1996 if (getRecentTasks().isCallerRecents(sourceUid)) {
1997 return true;
1998 }
1999
2000 int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
2001 if (perm == PackageManager.PERMISSION_GRANTED) {
2002 return true;
2003 }
2004 if (checkAllowAppSwitchUid(sourceUid)) {
2005 return true;
2006 }
2007
2008 // If the actual IPC caller is different from the logical source, then
2009 // also see if they are allowed to control app switches.
2010 if (callingUid != -1 && callingUid != sourceUid) {
2011 perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
2012 if (perm == PackageManager.PERMISSION_GRANTED) {
2013 return true;
2014 }
2015 if (checkAllowAppSwitchUid(callingUid)) {
2016 return true;
2017 }
2018 }
2019
2020 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
2021 return false;
2022 }
2023
2024 private boolean checkAllowAppSwitchUid(int uid) {
2025 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
2026 if (types != null) {
2027 for (int i = types.size() - 1; i >= 0; i--) {
2028 if (types.valueAt(i).intValue() == uid) {
2029 return true;
2030 }
2031 }
2032 }
2033 return false;
2034 }
2035
2036 @Override
2037 public void setActivityController(IActivityController controller, boolean imAMonkey) {
2038 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
2039 "setActivityController()");
2040 synchronized (mGlobalLock) {
2041 mController = controller;
2042 mControllerIsAMonkey = imAMonkey;
2043 Watchdog.getInstance().setActivityController(controller);
2044 }
2045 }
2046
2047 boolean isControllerAMonkey() {
2048 synchronized (mGlobalLock) {
2049 return mController != null && mControllerIsAMonkey;
2050 }
2051 }
2052
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002053 @Override
2054 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
2055 synchronized (mGlobalLock) {
2056 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
2057 }
2058 }
2059
2060 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002061 public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum) {
2062 return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
2063 }
2064
2065 @Override
2066 public List<ActivityManager.RunningTaskInfo> getFilteredTasks(int maxNum,
2067 @WindowConfiguration.ActivityType int ignoreActivityType,
2068 @WindowConfiguration.WindowingMode int ignoreWindowingMode) {
2069 final int callingUid = Binder.getCallingUid();
2070 ArrayList<ActivityManager.RunningTaskInfo> list = new ArrayList<>();
2071
2072 synchronized (mGlobalLock) {
2073 if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
2074
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002075 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002076 callingUid);
2077 mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
2078 ignoreWindowingMode, callingUid, allowed);
2079 }
2080
2081 return list;
2082 }
2083
2084 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002085 public final void finishSubActivity(IBinder token, String resultWho, int requestCode) {
2086 synchronized (mGlobalLock) {
2087 final long origId = Binder.clearCallingIdentity();
2088 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2089 if (r != null) {
2090 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
2091 }
2092 Binder.restoreCallingIdentity(origId);
2093 }
2094 }
2095
2096 @Override
2097 public boolean willActivityBeVisible(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002098 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002099 ActivityStack stack = ActivityRecord.getStackLocked(token);
2100 if (stack != null) {
2101 return stack.willActivityBeVisibleLocked(token);
2102 }
2103 return false;
2104 }
2105 }
2106
2107 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002108 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002109 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002110 synchronized (mGlobalLock) {
2111 final long ident = Binder.clearCallingIdentity();
2112 try {
2113 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2114 if (task == null) {
2115 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
2116 return;
2117 }
2118
2119 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
2120 + " to stackId=" + stackId + " toTop=" + toTop);
2121
2122 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2123 if (stack == null) {
2124 throw new IllegalStateException(
2125 "moveTaskToStack: No stack for stackId=" + stackId);
2126 }
2127 if (!stack.isActivityTypeStandardOrUndefined()) {
2128 throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
2129 + taskId + " to stack " + stackId);
2130 }
2131 if (stack.inSplitScreenPrimaryWindowingMode()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002132 mWindowManager.setDockedStackCreateState(
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002133 SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
2134 }
2135 task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
2136 "moveTaskToStack");
2137 } finally {
2138 Binder.restoreCallingIdentity(ident);
2139 }
2140 }
2141 }
2142
2143 @Override
2144 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
2145 boolean preserveWindows, boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002146 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002147
2148 final long ident = Binder.clearCallingIdentity();
2149 try {
2150 synchronized (mGlobalLock) {
2151 if (animate) {
2152 final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
2153 if (stack == null) {
2154 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2155 return;
2156 }
2157 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
2158 throw new IllegalArgumentException("Stack: " + stackId
2159 + " doesn't support animated resize.");
2160 }
2161 stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
2162 animationDuration, false /* fromFullscreen */);
2163 } else {
2164 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2165 if (stack == null) {
2166 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2167 return;
2168 }
2169 mStackSupervisor.resizeStackLocked(stack, destBounds,
2170 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
2171 preserveWindows, allowResizeInDockedMode, !DEFER_RESUME);
2172 }
2173 }
2174 } finally {
2175 Binder.restoreCallingIdentity(ident);
2176 }
2177 }
2178
2179 /**
2180 * Moves the specified task to the primary-split-screen stack.
2181 *
2182 * @param taskId Id of task to move.
2183 * @param createMode The mode the primary split screen stack should be created in if it doesn't
2184 * exist already. See
2185 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
2186 * and
2187 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
2188 * @param toTop If the task and stack should be moved to the top.
2189 * @param animate Whether we should play an animation for the moving the task.
2190 * @param initialBounds If the primary stack gets created, it will use these bounds for the
2191 * stack. Pass {@code null} to use default bounds.
2192 * @param showRecents If the recents activity should be shown on the other side of the task
2193 * going into split-screen mode.
2194 */
2195 @Override
2196 public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode,
2197 boolean toTop, boolean animate, Rect initialBounds, boolean showRecents) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002198 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002199 "setTaskWindowingModeSplitScreenPrimary()");
2200 synchronized (mGlobalLock) {
2201 final long ident = Binder.clearCallingIdentity();
2202 try {
2203 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2204 if (task == null) {
2205 Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
2206 return false;
2207 }
2208 if (DEBUG_STACK) Slog.d(TAG_STACK,
2209 "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
2210 + " to createMode=" + createMode + " toTop=" + toTop);
2211 if (!task.isActivityTypeStandardOrUndefined()) {
2212 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
2213 + " non-standard task " + taskId + " to split-screen windowing mode");
2214 }
2215
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002216 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002217 final int windowingMode = task.getWindowingMode();
2218 final ActivityStack stack = task.getStack();
2219 if (toTop) {
2220 stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
2221 }
2222 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
2223 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */);
2224 return windowingMode != task.getWindowingMode();
2225 } finally {
2226 Binder.restoreCallingIdentity(ident);
2227 }
2228 }
2229 }
2230
2231 /**
2232 * Removes stacks in the input windowing modes from the system if they are of activity type
2233 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
2234 */
2235 @Override
2236 public void removeStacksInWindowingModes(int[] windowingModes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002237 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002238 "removeStacksInWindowingModes()");
2239
2240 synchronized (mGlobalLock) {
2241 final long ident = Binder.clearCallingIdentity();
2242 try {
2243 mStackSupervisor.removeStacksInWindowingModes(windowingModes);
2244 } finally {
2245 Binder.restoreCallingIdentity(ident);
2246 }
2247 }
2248 }
2249
2250 @Override
2251 public void removeStacksWithActivityTypes(int[] activityTypes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002252 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002253 "removeStacksWithActivityTypes()");
2254
2255 synchronized (mGlobalLock) {
2256 final long ident = Binder.clearCallingIdentity();
2257 try {
2258 mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
2259 } finally {
2260 Binder.restoreCallingIdentity(ident);
2261 }
2262 }
2263 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002264
2265 @Override
2266 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
2267 int userId) {
2268 final int callingUid = Binder.getCallingUid();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002269 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, "getRecentTasks");
2270 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002271 callingUid);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002272 final boolean detailed = checkGetTasksPermission(
2273 android.Manifest.permission.GET_DETAILED_TASKS, Binder.getCallingPid(),
2274 UserHandle.getAppId(callingUid))
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002275 == PackageManager.PERMISSION_GRANTED;
2276
2277 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002278 return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002279 callingUid);
2280 }
2281 }
2282
2283 @Override
2284 public List<ActivityManager.StackInfo> getAllStackInfos() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002285 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002286 long ident = Binder.clearCallingIdentity();
2287 try {
2288 synchronized (mGlobalLock) {
2289 return mStackSupervisor.getAllStackInfosLocked();
2290 }
2291 } finally {
2292 Binder.restoreCallingIdentity(ident);
2293 }
2294 }
2295
2296 @Override
2297 public ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002298 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002299 long ident = Binder.clearCallingIdentity();
2300 try {
2301 synchronized (mGlobalLock) {
2302 return mStackSupervisor.getStackInfo(windowingMode, activityType);
2303 }
2304 } finally {
2305 Binder.restoreCallingIdentity(ident);
2306 }
2307 }
2308
2309 @Override
2310 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002311 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002312 final long callingUid = Binder.getCallingUid();
2313 final long origId = Binder.clearCallingIdentity();
2314 try {
2315 synchronized (mGlobalLock) {
2316 // Cancel the recents animation synchronously (do not hold the WM lock)
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002317 mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002318 ? REORDER_MOVE_TO_ORIGINAL_POSITION
2319 : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
2320 }
2321 } finally {
2322 Binder.restoreCallingIdentity(origId);
2323 }
2324 }
2325
2326 @Override
2327 public void startLockTaskModeByToken(IBinder token) {
2328 synchronized (mGlobalLock) {
2329 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2330 if (r == null) {
2331 return;
2332 }
2333 startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
2334 }
2335 }
2336
2337 @Override
2338 public void startSystemLockTaskMode(int taskId) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002339 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002340 // This makes inner call to look as if it was initiated by system.
2341 long ident = Binder.clearCallingIdentity();
2342 try {
2343 synchronized (mGlobalLock) {
2344 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2345
2346 // When starting lock task mode the stack must be in front and focused
2347 task.getStack().moveToFront("startSystemLockTaskMode");
2348 startLockTaskModeLocked(task, true /* isSystemCaller */);
2349 }
2350 } finally {
2351 Binder.restoreCallingIdentity(ident);
2352 }
2353 }
2354
2355 @Override
2356 public void stopLockTaskModeByToken(IBinder token) {
2357 synchronized (mGlobalLock) {
2358 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2359 if (r == null) {
2360 return;
2361 }
2362 stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
2363 }
2364 }
2365
2366 /**
2367 * This API should be called by SystemUI only when user perform certain action to dismiss
2368 * lock task mode. We should only dismiss pinned lock task mode in this case.
2369 */
2370 @Override
2371 public void stopSystemLockTaskMode() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002372 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002373 stopLockTaskModeInternal(null, true /* isSystemCaller */);
2374 }
2375
2376 private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
2377 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
2378 if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
2379 return;
2380 }
2381
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002382 final ActivityStack stack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002383 if (stack == null || task != stack.topTask()) {
2384 throw new IllegalArgumentException("Invalid task, not in foreground");
2385 }
2386
2387 // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
2388 // system or a specific app.
2389 // * System-initiated requests will only start the pinned mode (screen pinning)
2390 // * App-initiated requests
2391 // - will put the device in fully locked mode (LockTask), if the app is whitelisted
2392 // - will start the pinned mode, otherwise
2393 final int callingUid = Binder.getCallingUid();
2394 long ident = Binder.clearCallingIdentity();
2395 try {
2396 // When a task is locked, dismiss the pinned stack if it exists
2397 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2398
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002399 getLockTaskController().startLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002400 } finally {
2401 Binder.restoreCallingIdentity(ident);
2402 }
2403 }
2404
2405 private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
2406 final int callingUid = Binder.getCallingUid();
2407 long ident = Binder.clearCallingIdentity();
2408 try {
2409 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002410 getLockTaskController().stopLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002411 }
2412 // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
2413 // task and jumping straight into a call in the case of emergency call back.
2414 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
2415 if (tm != null) {
2416 tm.showInCallScreen(false);
2417 }
2418 } finally {
2419 Binder.restoreCallingIdentity(ident);
2420 }
2421 }
2422
2423 @Override
2424 public boolean isInLockTaskMode() {
2425 return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
2426 }
2427
2428 @Override
2429 public int getLockTaskModeState() {
2430 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002431 return getLockTaskController().getLockTaskModeState();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002432 }
2433 }
2434
2435 @Override
2436 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
2437 synchronized (mGlobalLock) {
2438 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2439 if (r != null) {
2440 r.setTaskDescription(td);
2441 final TaskRecord task = r.getTask();
2442 task.updateTaskDescription();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002443 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002444 }
2445 }
2446 }
2447
2448 @Override
2449 public Bundle getActivityOptions(IBinder token) {
2450 final long origId = Binder.clearCallingIdentity();
2451 try {
2452 synchronized (mGlobalLock) {
2453 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
2454 if (r != null) {
2455 final ActivityOptions activityOptions = r.takeOptionsLocked();
2456 return activityOptions == null ? null : activityOptions.toBundle();
2457 }
2458 return null;
2459 }
2460 } finally {
2461 Binder.restoreCallingIdentity(origId);
2462 }
2463 }
2464
2465 @Override
2466 public List<IBinder> getAppTasks(String callingPackage) {
2467 int callingUid = Binder.getCallingUid();
2468 long ident = Binder.clearCallingIdentity();
2469 try {
2470 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002471 return mRecentTasks.getAppTasksList(callingUid, callingPackage);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002472 }
2473 } finally {
2474 Binder.restoreCallingIdentity(ident);
2475 }
2476 }
2477
2478 @Override
2479 public void finishVoiceTask(IVoiceInteractionSession session) {
2480 synchronized (mGlobalLock) {
2481 final long origId = Binder.clearCallingIdentity();
2482 try {
2483 // TODO: VI Consider treating local voice interactions and voice tasks
2484 // differently here
2485 mStackSupervisor.finishVoiceTask(session);
2486 } finally {
2487 Binder.restoreCallingIdentity(origId);
2488 }
2489 }
2490
2491 }
2492
2493 @Override
2494 public boolean isTopOfTask(IBinder token) {
2495 synchronized (mGlobalLock) {
2496 ActivityRecord r = ActivityRecord.isInStackLocked(token);
Riddle Hsu66b74a82018-07-26 00:20:12 +08002497 return r != null && r.getTask().getTopActivity() == r;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002498 }
2499 }
2500
2501 @Override
2502 public void notifyLaunchTaskBehindComplete(IBinder token) {
2503 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
2504 }
2505
2506 @Override
2507 public void notifyEnterAnimationComplete(IBinder token) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002508 mH.post(() -> {
2509 synchronized (mGlobalLock) {
2510 ActivityRecord r = ActivityRecord.forTokenLocked(token);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002511 if (r != null && r.attachedToProcess()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002512 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002513 r.app.getThread().scheduleEnterAnimationComplete(r.appToken);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002514 } catch (RemoteException e) {
2515 }
2516 }
2517 }
2518
2519 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002520 }
2521
2522 /** Called from an app when assist data is ready. */
2523 @Override
2524 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
2525 AssistContent content, Uri referrer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002526 PendingAssistExtras pae = (PendingAssistExtras) token;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002527 synchronized (pae) {
2528 pae.result = extras;
2529 pae.structure = structure;
2530 pae.content = content;
2531 if (referrer != null) {
2532 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
2533 }
2534 if (structure != null) {
2535 structure.setHomeActivity(pae.isHome);
2536 }
2537 pae.haveResult = true;
2538 pae.notifyAll();
2539 if (pae.intent == null && pae.receiver == null) {
2540 // Caller is just waiting for the result.
2541 return;
2542 }
2543 }
2544 // We are now ready to launch the assist activity.
2545 IAssistDataReceiver sendReceiver = null;
2546 Bundle sendBundle = null;
2547 synchronized (mGlobalLock) {
2548 buildAssistBundleLocked(pae, extras);
2549 boolean exists = mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002550 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002551 if (!exists) {
2552 // Timed out.
2553 return;
2554 }
2555
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002556 if ((sendReceiver = pae.receiver) != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002557 // Caller wants result sent back to them.
2558 sendBundle = new Bundle();
2559 sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
2560 sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
2561 sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
2562 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
2563 }
2564 }
2565 if (sendReceiver != null) {
2566 try {
2567 sendReceiver.onHandleAssistData(sendBundle);
2568 } catch (RemoteException e) {
2569 }
2570 return;
2571 }
2572
2573 final long ident = Binder.clearCallingIdentity();
2574 try {
2575 if (TextUtils.equals(pae.intent.getAction(),
2576 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
2577 pae.intent.putExtras(pae.extras);
2578 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
2579 } else {
2580 pae.intent.replaceExtras(pae.extras);
2581 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
2582 | Intent.FLAG_ACTIVITY_SINGLE_TOP
2583 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002584 mAmInternal.closeSystemDialogs("assist");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002585
2586 try {
2587 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
2588 } catch (ActivityNotFoundException e) {
2589 Slog.w(TAG, "No activity to handle assist action.", e);
2590 }
2591 }
2592 } finally {
2593 Binder.restoreCallingIdentity(ident);
2594 }
2595 }
2596
2597 @Override
2598 public int addAppTask(IBinder activityToken, Intent intent,
2599 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
2600 final int callingUid = Binder.getCallingUid();
2601 final long callingIdent = Binder.clearCallingIdentity();
2602
2603 try {
2604 synchronized (mGlobalLock) {
2605 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
2606 if (r == null) {
2607 throw new IllegalArgumentException("Activity does not exist; token="
2608 + activityToken);
2609 }
2610 ComponentName comp = intent.getComponent();
2611 if (comp == null) {
2612 throw new IllegalArgumentException("Intent " + intent
2613 + " must specify explicit component");
2614 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002615 if (thumbnail.getWidth() != mThumbnailWidth
2616 || thumbnail.getHeight() != mThumbnailHeight) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002617 throw new IllegalArgumentException("Bad thumbnail size: got "
2618 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002619 + mThumbnailWidth + "x" + mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002620 }
2621 if (intent.getSelector() != null) {
2622 intent.setSelector(null);
2623 }
2624 if (intent.getSourceBounds() != null) {
2625 intent.setSourceBounds(null);
2626 }
2627 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
2628 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
2629 // The caller has added this as an auto-remove task... that makes no
2630 // sense, so turn off auto-remove.
2631 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
2632 }
2633 }
2634 final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
2635 STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
2636 if (ainfo.applicationInfo.uid != callingUid) {
2637 throw new SecurityException(
2638 "Can't add task for another application: target uid="
2639 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
2640 }
2641
2642 final ActivityStack stack = r.getStack();
2643 final TaskRecord task = stack.createTaskRecord(
2644 mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent,
2645 null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002646 if (!mRecentTasks.addToBottom(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002647 // The app has too many tasks already and we can't add any more
2648 stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
2649 return INVALID_TASK_ID;
2650 }
2651 task.lastTaskDescription.copyFrom(description);
2652
2653 // TODO: Send the thumbnail to WM to store it.
2654
2655 return task.taskId;
2656 }
2657 } finally {
2658 Binder.restoreCallingIdentity(callingIdent);
2659 }
2660 }
2661
2662 @Override
2663 public Point getAppTaskThumbnailSize() {
2664 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002665 return new Point(mThumbnailWidth, mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002666 }
2667 }
2668
2669 @Override
2670 public void setTaskResizeable(int taskId, int resizeableMode) {
2671 synchronized (mGlobalLock) {
2672 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
2673 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
2674 if (task == null) {
2675 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
2676 return;
2677 }
2678 task.setResizeMode(resizeableMode);
2679 }
2680 }
2681
2682 @Override
2683 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002684 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002685 long ident = Binder.clearCallingIdentity();
2686 try {
2687 synchronized (mGlobalLock) {
2688 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2689 if (task == null) {
2690 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
2691 return;
2692 }
2693 // Place the task in the right stack if it isn't there already based on
2694 // the requested bounds.
2695 // The stack transition logic is:
2696 // - a null bounds on a freeform task moves that task to fullscreen
2697 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
2698 // that task to freeform
2699 // - otherwise the task is not moved
2700 ActivityStack stack = task.getStack();
2701 if (!task.getWindowConfiguration().canResizeTask()) {
2702 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
2703 }
2704 if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
2705 stack = stack.getDisplay().getOrCreateStack(
2706 WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
2707 } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
2708 stack = stack.getDisplay().getOrCreateStack(
2709 WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
2710 }
2711
2712 // Reparent the task to the right stack if necessary
2713 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
2714 if (stack != task.getStack()) {
2715 // Defer resume until the task is resized below
2716 task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
2717 DEFER_RESUME, "resizeTask");
2718 preserveWindow = false;
2719 }
2720
2721 // After reparenting (which only resizes the task to the stack bounds), resize the
2722 // task to the actual bounds provided
2723 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
2724 }
2725 } finally {
2726 Binder.restoreCallingIdentity(ident);
2727 }
2728 }
2729
2730 @Override
2731 public boolean releaseActivityInstance(IBinder token) {
2732 synchronized (mGlobalLock) {
2733 final long origId = Binder.clearCallingIdentity();
2734 try {
2735 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2736 if (r == null) {
2737 return false;
2738 }
2739 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
2740 } finally {
2741 Binder.restoreCallingIdentity(origId);
2742 }
2743 }
2744 }
2745
2746 @Override
2747 public void releaseSomeActivities(IApplicationThread appInt) {
2748 synchronized (mGlobalLock) {
2749 final long origId = Binder.clearCallingIdentity();
2750 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002751 WindowProcessController app =
2752 mAm.getRecordForAppLocked(appInt).getWindowProcessController();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002753 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
2754 } finally {
2755 Binder.restoreCallingIdentity(origId);
2756 }
2757 }
2758 }
2759
2760 @Override
2761 public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
2762 int secondaryDisplayShowing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002763 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002764 != PackageManager.PERMISSION_GRANTED) {
2765 throw new SecurityException("Requires permission "
2766 + android.Manifest.permission.DEVICE_POWER);
2767 }
2768
2769 synchronized (mGlobalLock) {
2770 long ident = Binder.clearCallingIdentity();
2771 if (mKeyguardShown != keyguardShowing) {
2772 mKeyguardShown = keyguardShowing;
2773 reportCurKeyguardUsageEventLocked(keyguardShowing);
2774 }
2775 try {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002776 mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002777 secondaryDisplayShowing);
2778 } finally {
2779 Binder.restoreCallingIdentity(ident);
2780 }
2781 }
2782
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002783 mH.post(() -> {
2784 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2785 mScreenObservers.get(i).onKeyguardStateChanged(keyguardShowing);
2786 }
2787 });
2788 }
2789
2790 void onScreenAwakeChanged(boolean isAwake) {
2791 mH.post(() -> {
2792 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2793 mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2794 }
2795 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002796 }
2797
2798 @Override
2799 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002800 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
2801 userId, "getTaskDescriptionIcon");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002802
2803 final File passedIconFile = new File(filePath);
2804 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
2805 passedIconFile.getName());
2806 if (!legitIconFile.getPath().equals(filePath)
2807 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
2808 throw new IllegalArgumentException("Bad file path: " + filePath
2809 + " passed for userId " + userId);
2810 }
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002811 return mRecentTasks.getTaskDescriptionIcon(filePath);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002812 }
2813
2814 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002815 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002816 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
2817 final ActivityOptions activityOptions = safeOptions != null
2818 ? safeOptions.getOptions(mStackSupervisor)
2819 : null;
2820 if (activityOptions == null
2821 || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
2822 || activityOptions.getCustomInPlaceResId() == 0) {
2823 throw new IllegalArgumentException("Expected in-place ActivityOption " +
2824 "with valid animation");
2825 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002826 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
2827 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002828 activityOptions.getCustomInPlaceResId());
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002829 mWindowManager.executeAppTransition();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002830 }
2831
2832 @Override
2833 public void removeStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002834 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002835 synchronized (mGlobalLock) {
2836 final long ident = Binder.clearCallingIdentity();
2837 try {
2838 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2839 if (stack == null) {
2840 Slog.w(TAG, "removeStack: No stack with id=" + stackId);
2841 return;
2842 }
2843 if (!stack.isActivityTypeStandardOrUndefined()) {
2844 throw new IllegalArgumentException(
2845 "Removing non-standard stack is not allowed.");
2846 }
2847 mStackSupervisor.removeStack(stack);
2848 } finally {
2849 Binder.restoreCallingIdentity(ident);
2850 }
2851 }
2852 }
2853
2854 @Override
2855 public void moveStackToDisplay(int stackId, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002856 mAmInternal.enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002857
2858 synchronized (mGlobalLock) {
2859 final long ident = Binder.clearCallingIdentity();
2860 try {
2861 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
2862 + " to displayId=" + displayId);
2863 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
2864 } finally {
2865 Binder.restoreCallingIdentity(ident);
2866 }
2867 }
2868 }
2869
2870 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002871 public void exitFreeformMode(IBinder token) {
2872 synchronized (mGlobalLock) {
2873 long ident = Binder.clearCallingIdentity();
2874 try {
2875 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2876 if (r == null) {
2877 throw new IllegalArgumentException(
2878 "exitFreeformMode: No activity record matching token=" + token);
2879 }
2880
2881 final ActivityStack stack = r.getStack();
2882 if (stack == null || !stack.inFreeformWindowingMode()) {
2883 throw new IllegalStateException(
2884 "exitFreeformMode: You can only go fullscreen from freeform.");
2885 }
2886
2887 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
2888 } finally {
2889 Binder.restoreCallingIdentity(ident);
2890 }
2891 }
2892 }
2893
2894 /** Sets the task stack listener that gets callbacks when a task stack changes. */
2895 @Override
2896 public void registerTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002897 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002898 "registerTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002899 mTaskChangeNotificationController.registerTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002900 }
2901
2902 /** Unregister a task stack listener so that it stops receiving callbacks. */
2903 @Override
2904 public void unregisterTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002905 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002906 "unregisterTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002907 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002908 }
2909
2910 private void reportCurKeyguardUsageEventLocked(boolean keyguardShowing) {
2911 mAm.reportGlobalUsageEventLocked(keyguardShowing
2912 ? UsageEvents.Event.KEYGUARD_SHOWN
2913 : UsageEvents.Event.KEYGUARD_HIDDEN);
2914 }
2915
2916 @Override
2917 public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
2918 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
2919 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
2920 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
2921 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
2922 }
2923
2924 @Override
2925 public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
2926 IBinder activityToken, int flags) {
2927 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
2928 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
2929 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
2930 }
2931
2932 @Override
2933 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
2934 Bundle args) {
2935 return enqueueAssistContext(requestType, intent, hint, null, null, null,
2936 true /* focused */, true /* newSessionId */, userHandle, args,
2937 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
2938 }
2939
2940 @Override
2941 public Bundle getAssistContextExtras(int requestType) {
2942 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
2943 null, null, true /* focused */, true /* newSessionId */,
2944 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
2945 if (pae == null) {
2946 return null;
2947 }
2948 synchronized (pae) {
2949 while (!pae.haveResult) {
2950 try {
2951 pae.wait();
2952 } catch (InterruptedException e) {
2953 }
2954 }
2955 }
2956 synchronized (mGlobalLock) {
2957 buildAssistBundleLocked(pae, pae.result);
2958 mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002959 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002960 }
2961 return pae.extras;
2962 }
2963
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002964 /**
2965 * Binder IPC calls go through the public entry point.
2966 * This can be called with or without the global lock held.
2967 */
2968 private static int checkCallingPermission(String permission) {
2969 return checkPermission(
2970 permission, Binder.getCallingPid(), UserHandle.getAppId(Binder.getCallingUid()));
2971 }
2972
2973 /** This can be called with or without the global lock held. */
2974 void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
2975 if (!getRecentTasks().isCallerRecents(Binder.getCallingUid())) {
2976 mAmInternal.enforceCallingPermission(permission, func);
2977 }
2978 }
2979
2980 @VisibleForTesting
2981 int checkGetTasksPermission(String permission, int pid, int uid) {
2982 return checkPermission(permission, pid, uid);
2983 }
2984
2985 static int checkPermission(String permission, int pid, int uid) {
2986 if (permission == null) {
2987 return PackageManager.PERMISSION_DENIED;
2988 }
2989 return checkComponentPermission(permission, pid, uid, -1, true);
2990 }
2991
2992 boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
2993 if (getRecentTasks().isCallerRecents(callingUid)) {
2994 // Always allow the recents component to get tasks
2995 return true;
2996 }
2997
2998 boolean allowed = checkGetTasksPermission(android.Manifest.permission.REAL_GET_TASKS,
2999 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
3000 if (!allowed) {
3001 if (checkGetTasksPermission(android.Manifest.permission.GET_TASKS,
3002 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
3003 // Temporary compatibility: some existing apps on the system image may
3004 // still be requesting the old permission and not switched to the new
3005 // one; if so, we'll still allow them full access. This means we need
3006 // to see if they are holding the old permission and are a system app.
3007 try {
3008 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
3009 allowed = true;
3010 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
3011 + " is using old GET_TASKS but privileged; allowing");
3012 }
3013 } catch (RemoteException e) {
3014 }
3015 }
3016 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
3017 + " does not hold REAL_GET_TASKS; limiting output");
3018 }
3019 return allowed;
3020 }
3021
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003022 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
3023 IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
3024 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
3025 int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003026 mAmInternal.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003027 "enqueueAssistContext()");
3028
3029 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003030 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003031 if (activity == null) {
3032 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
3033 return null;
3034 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003035 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003036 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
3037 return null;
3038 }
3039 if (focused) {
3040 if (activityToken != null) {
3041 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
3042 if (activity != caller) {
3043 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
3044 + " is not current top " + activity);
3045 return null;
3046 }
3047 }
3048 } else {
3049 activity = ActivityRecord.forTokenLocked(activityToken);
3050 if (activity == null) {
3051 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
3052 + " couldn't be found");
3053 return null;
3054 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003055 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003056 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
3057 return null;
3058 }
3059 }
3060
3061 PendingAssistExtras pae;
3062 Bundle extras = new Bundle();
3063 if (args != null) {
3064 extras.putAll(args);
3065 }
3066 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003067 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003068
3069 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
3070 userHandle);
3071 pae.isHome = activity.isActivityTypeHome();
3072
3073 // Increment the sessionId if necessary
3074 if (newSessionId) {
3075 mViSessionId++;
3076 }
3077 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003078 activity.app.getThread().requestAssistContextExtras(activity.appToken, pae,
3079 requestType, mViSessionId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003080 mPendingAssistExtras.add(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003081 mUiHandler.postDelayed(pae, timeout);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003082 } catch (RemoteException e) {
3083 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
3084 return null;
3085 }
3086 return pae;
3087 }
3088 }
3089
3090 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
3091 if (result != null) {
3092 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
3093 }
3094 if (pae.hint != null) {
3095 pae.extras.putBoolean(pae.hint, true);
3096 }
3097 }
3098
3099 private void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
3100 IAssistDataReceiver receiver;
3101 synchronized (mGlobalLock) {
3102 mPendingAssistExtras.remove(pae);
3103 receiver = pae.receiver;
3104 }
3105 if (receiver != null) {
3106 // Caller wants result sent back to them.
3107 Bundle sendBundle = new Bundle();
3108 // At least return the receiver extras
3109 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
3110 try {
3111 pae.receiver.onHandleAssistData(sendBundle);
3112 } catch (RemoteException e) {
3113 }
3114 }
3115 }
3116
3117 public class PendingAssistExtras extends Binder implements Runnable {
3118 public final ActivityRecord activity;
3119 public boolean isHome;
3120 public final Bundle extras;
3121 public final Intent intent;
3122 public final String hint;
3123 public final IAssistDataReceiver receiver;
3124 public final int userHandle;
3125 public boolean haveResult = false;
3126 public Bundle result = null;
3127 public AssistStructure structure = null;
3128 public AssistContent content = null;
3129 public Bundle receiverExtras;
3130
3131 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
3132 String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
3133 int _userHandle) {
3134 activity = _activity;
3135 extras = _extras;
3136 intent = _intent;
3137 hint = _hint;
3138 receiver = _receiver;
3139 receiverExtras = _receiverExtras;
3140 userHandle = _userHandle;
3141 }
3142
3143 @Override
3144 public void run() {
3145 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
3146 synchronized (this) {
3147 haveResult = true;
3148 notifyAll();
3149 }
3150 pendingAssistExtrasTimedOut(this);
3151 }
3152 }
3153
3154 @Override
3155 public boolean isAssistDataAllowedOnCurrentActivity() {
3156 int userId;
3157 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003158 final ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003159 if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
3160 return false;
3161 }
3162
3163 final ActivityRecord activity = focusedStack.getTopActivity();
3164 if (activity == null) {
3165 return false;
3166 }
3167 userId = activity.userId;
3168 }
3169 return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
3170 }
3171
3172 @Override
3173 public boolean showAssistFromActivity(IBinder token, Bundle args) {
3174 long ident = Binder.clearCallingIdentity();
3175 try {
3176 synchronized (mGlobalLock) {
3177 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003178 ActivityRecord top = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003179 if (top != caller) {
3180 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3181 + " is not current top " + top);
3182 return false;
3183 }
3184 if (!top.nowVisible) {
3185 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3186 + " is not visible");
3187 return false;
3188 }
3189 }
3190 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
3191 token);
3192 } finally {
3193 Binder.restoreCallingIdentity(ident);
3194 }
3195 }
3196
3197 @Override
3198 public boolean isRootVoiceInteraction(IBinder token) {
3199 synchronized (mGlobalLock) {
3200 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3201 if (r == null) {
3202 return false;
3203 }
3204 return r.rootVoiceInteraction;
3205 }
3206 }
3207
Wale Ogunwalef6733932018-06-27 05:14:34 -07003208 private void onLocalVoiceInteractionStartedLocked(IBinder activity,
3209 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
3210 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
3211 if (activityToCallback == null) return;
3212 activityToCallback.setVoiceSessionLocked(voiceSession);
3213
3214 // Inform the activity
3215 try {
3216 activityToCallback.app.getThread().scheduleLocalVoiceInteractionStarted(activity,
3217 voiceInteractor);
3218 long token = Binder.clearCallingIdentity();
3219 try {
3220 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
3221 } finally {
3222 Binder.restoreCallingIdentity(token);
3223 }
3224 // TODO: VI Should we cache the activity so that it's easier to find later
3225 // rather than scan through all the stacks and activities?
3226 } catch (RemoteException re) {
3227 activityToCallback.clearVoiceSessionLocked();
3228 // TODO: VI Should this terminate the voice session?
3229 }
3230 }
3231
3232 private void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
3233 Slog.d(TAG, "<<< startRunningVoiceLocked()");
3234 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
3235 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
3236 boolean wasRunningVoice = mRunningVoice != null;
3237 mRunningVoice = session;
3238 if (!wasRunningVoice) {
3239 mVoiceWakeLock.acquire();
3240 updateSleepIfNeededLocked();
3241 }
3242 }
3243 }
3244
3245 void finishRunningVoiceLocked() {
3246 if (mRunningVoice != null) {
3247 mRunningVoice = null;
3248 mVoiceWakeLock.release();
3249 updateSleepIfNeededLocked();
3250 }
3251 }
3252
3253 @Override
3254 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3255 synchronized (mGlobalLock) {
3256 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3257 if (keepAwake) {
3258 mVoiceWakeLock.acquire();
3259 } else {
3260 mVoiceWakeLock.release();
3261 }
3262 }
3263 }
3264 }
3265
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003266 @Override
3267 public ComponentName getActivityClassForToken(IBinder token) {
3268 synchronized (mGlobalLock) {
3269 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3270 if (r == null) {
3271 return null;
3272 }
3273 return r.intent.getComponent();
3274 }
3275 }
3276
3277 @Override
3278 public String getPackageForToken(IBinder token) {
3279 synchronized (mGlobalLock) {
3280 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3281 if (r == null) {
3282 return null;
3283 }
3284 return r.packageName;
3285 }
3286 }
3287
3288 @Override
3289 public void showLockTaskEscapeMessage(IBinder token) {
3290 synchronized (mGlobalLock) {
3291 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3292 if (r == null) {
3293 return;
3294 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003295 getLockTaskController().showLockTaskToast();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003296 }
3297 }
3298
3299 @Override
3300 public void keyguardGoingAway(int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003301 enforceNotIsolatedCaller("keyguardGoingAway");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003302 final long token = Binder.clearCallingIdentity();
3303 try {
3304 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003305 mKeyguardController.keyguardGoingAway(flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003306 }
3307 } finally {
3308 Binder.restoreCallingIdentity(token);
3309 }
3310 }
3311
3312 /**
3313 * Try to place task to provided position. The final position might be different depending on
3314 * current user and stacks state. The task will be moved to target stack if it's currently in
3315 * different stack.
3316 */
3317 @Override
3318 public void positionTaskInStack(int taskId, int stackId, int position) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003319 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003320 synchronized (mGlobalLock) {
3321 long ident = Binder.clearCallingIdentity();
3322 try {
3323 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
3324 + taskId + " in stackId=" + stackId + " at position=" + position);
3325 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3326 if (task == null) {
3327 throw new IllegalArgumentException("positionTaskInStack: no task for id="
3328 + taskId);
3329 }
3330
3331 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3332
3333 if (stack == null) {
3334 throw new IllegalArgumentException("positionTaskInStack: no stack for id="
3335 + stackId);
3336 }
3337 if (!stack.isActivityTypeStandardOrUndefined()) {
3338 throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
3339 + " the position of task " + taskId + " in/to non-standard stack");
3340 }
3341
3342 // TODO: Have the callers of this API call a separate reparent method if that is
3343 // what they intended to do vs. having this method also do reparenting.
3344 if (task.getStack() == stack) {
3345 // Change position in current stack.
3346 stack.positionChildAt(task, position);
3347 } else {
3348 // Reparent to new stack.
3349 task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
3350 !DEFER_RESUME, "positionTaskInStack");
3351 }
3352 } finally {
3353 Binder.restoreCallingIdentity(ident);
3354 }
3355 }
3356 }
3357
3358 @Override
3359 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
3360 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
3361 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
3362 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
3363 synchronized (mGlobalLock) {
3364 ActivityRecord record = ActivityRecord.isInStackLocked(token);
3365 if (record == null) {
3366 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
3367 + "found for: " + token);
3368 }
3369 record.setSizeConfigurations(horizontalSizeConfiguration,
3370 verticalSizeConfigurations, smallestSizeConfigurations);
3371 }
3372 }
3373
3374 /**
3375 * Dismisses split-screen multi-window mode.
3376 * @param toTop If true the current primary split-screen stack will be placed or left on top.
3377 */
3378 @Override
3379 public void dismissSplitScreenMode(boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003380 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003381 MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
3382 final long ident = Binder.clearCallingIdentity();
3383 try {
3384 synchronized (mGlobalLock) {
3385 final ActivityStack stack =
3386 mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
3387 if (stack == null) {
3388 Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
3389 return;
3390 }
3391
3392 if (toTop) {
3393 // Caller wants the current split-screen primary stack to be the top stack after
3394 // it goes fullscreen, so move it to the front.
3395 stack.moveToFront("dismissSplitScreenMode");
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003396 } else if (mStackSupervisor.isTopDisplayFocusedStack(stack)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003397 // In this case the current split-screen primary stack shouldn't be the top
3398 // stack after it goes fullscreen, but it current has focus, so we move the
3399 // focus to the top-most split-screen secondary stack next to it.
3400 final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
3401 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
3402 if (otherStack != null) {
3403 otherStack.moveToFront("dismissSplitScreenMode_other");
3404 }
3405 }
3406
Evan Rosky10475742018-09-05 19:02:48 -07003407 stack.setWindowingMode(WINDOWING_MODE_UNDEFINED);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003408 }
3409 } finally {
3410 Binder.restoreCallingIdentity(ident);
3411 }
3412 }
3413
3414 /**
3415 * Dismisses Pip
3416 * @param animate True if the dismissal should be animated.
3417 * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
3418 * default animation duration should be used.
3419 */
3420 @Override
3421 public void dismissPip(boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003422 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003423 final long ident = Binder.clearCallingIdentity();
3424 try {
3425 synchronized (mGlobalLock) {
3426 final PinnedActivityStack stack =
3427 mStackSupervisor.getDefaultDisplay().getPinnedStack();
3428 if (stack == null) {
3429 Slog.w(TAG, "dismissPip: pinned stack not found.");
3430 return;
3431 }
3432 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
3433 throw new IllegalArgumentException("Stack: " + stack
3434 + " doesn't support animated resize.");
3435 }
3436 if (animate) {
3437 stack.animateResizePinnedStack(null /* sourceHintBounds */,
3438 null /* destBounds */, animationDuration, false /* fromFullscreen */);
3439 } else {
3440 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
3441 }
3442 }
3443 } finally {
3444 Binder.restoreCallingIdentity(ident);
3445 }
3446 }
3447
3448 @Override
3449 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003450 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003451 synchronized (mGlobalLock) {
3452 mSuppressResizeConfigChanges = suppress;
3453 }
3454 }
3455
3456 /**
3457 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
3458 * animated the stack to the fullscreen, but can also be called if we are relaunching an
3459 * activity and clearing the task at the same time.
3460 */
3461 @Override
3462 // TODO: API should just be about changing windowing modes...
3463 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003464 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003465 "moveTasksToFullscreenStack()");
3466 synchronized (mGlobalLock) {
3467 final long origId = Binder.clearCallingIdentity();
3468 try {
3469 final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
3470 if (stack != null){
3471 if (!stack.isActivityTypeStandardOrUndefined()) {
3472 throw new IllegalArgumentException(
3473 "You can't move tasks from non-standard stacks.");
3474 }
3475 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
3476 }
3477 } finally {
3478 Binder.restoreCallingIdentity(origId);
3479 }
3480 }
3481 }
3482
3483 /**
3484 * Moves the top activity in the input stackId to the pinned stack.
3485 *
3486 * @param stackId Id of stack to move the top activity to pinned stack.
3487 * @param bounds Bounds to use for pinned stack.
3488 *
3489 * @return True if the top activity of the input stack was successfully moved to the pinned
3490 * stack.
3491 */
3492 @Override
3493 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003494 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003495 "moveTopActivityToPinnedStack()");
3496 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003497 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003498 throw new IllegalStateException("moveTopActivityToPinnedStack:"
3499 + "Device doesn't support picture-in-picture mode");
3500 }
3501
3502 long ident = Binder.clearCallingIdentity();
3503 try {
3504 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
3505 } finally {
3506 Binder.restoreCallingIdentity(ident);
3507 }
3508 }
3509 }
3510
3511 @Override
3512 public boolean isInMultiWindowMode(IBinder token) {
3513 final long origId = Binder.clearCallingIdentity();
3514 try {
3515 synchronized (mGlobalLock) {
3516 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3517 if (r == null) {
3518 return false;
3519 }
3520 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
3521 return r.inMultiWindowMode();
3522 }
3523 } finally {
3524 Binder.restoreCallingIdentity(origId);
3525 }
3526 }
3527
3528 @Override
3529 public boolean isInPictureInPictureMode(IBinder token) {
3530 final long origId = Binder.clearCallingIdentity();
3531 try {
3532 synchronized (mGlobalLock) {
3533 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
3534 }
3535 } finally {
3536 Binder.restoreCallingIdentity(origId);
3537 }
3538 }
3539
3540 private boolean isInPictureInPictureMode(ActivityRecord r) {
3541 if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
3542 || r.getStack().isInStackLocked(r) == null) {
3543 return false;
3544 }
3545
3546 // If we are animating to fullscreen then we have already dispatched the PIP mode
3547 // changed, so we should reflect that check here as well.
3548 final PinnedActivityStack stack = r.getStack();
3549 final PinnedStackWindowController windowController = stack.getWindowContainerController();
3550 return !windowController.isAnimatingBoundsToFullscreen();
3551 }
3552
3553 @Override
3554 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
3555 final long origId = Binder.clearCallingIdentity();
3556 try {
3557 synchronized (mGlobalLock) {
3558 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3559 "enterPictureInPictureMode", token, params);
3560
3561 // If the activity is already in picture in picture mode, then just return early
3562 if (isInPictureInPictureMode(r)) {
3563 return true;
3564 }
3565
3566 // Activity supports picture-in-picture, now check that we can enter PiP at this
3567 // point, if it is
3568 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
3569 false /* beforeStopping */)) {
3570 return false;
3571 }
3572
3573 final Runnable enterPipRunnable = () -> {
Wale Ogunwalef276a6f2018-06-15 08:26:07 -07003574 synchronized (mGlobalLock) {
3575 // Only update the saved args from the args that are set
3576 r.pictureInPictureArgs.copyOnlySet(params);
3577 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
3578 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
3579 // Adjust the source bounds by the insets for the transition down
3580 final Rect sourceBounds = new Rect(
3581 r.pictureInPictureArgs.getSourceRectHint());
3582 mStackSupervisor.moveActivityToPinnedStackLocked(
3583 r, sourceBounds, aspectRatio, "enterPictureInPictureMode");
3584 final PinnedActivityStack stack = r.getStack();
3585 stack.setPictureInPictureAspectRatio(aspectRatio);
3586 stack.setPictureInPictureActions(actions);
3587 MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
3588 r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
3589 logPictureInPictureArgs(params);
3590 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003591 };
3592
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003593 if (isKeyguardLocked()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003594 // If the keyguard is showing or occluded, then try and dismiss it before
3595 // entering picture-in-picture (this will prompt the user to authenticate if the
3596 // device is currently locked).
3597 dismissKeyguard(token, new KeyguardDismissCallback() {
3598 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003599 public void onDismissSucceeded() {
3600 mH.post(enterPipRunnable);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003601 }
3602 }, null /* message */);
3603 } else {
3604 // Enter picture in picture immediately otherwise
3605 enterPipRunnable.run();
3606 }
3607 return true;
3608 }
3609 } finally {
3610 Binder.restoreCallingIdentity(origId);
3611 }
3612 }
3613
3614 @Override
3615 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
3616 final long origId = Binder.clearCallingIdentity();
3617 try {
3618 synchronized (mGlobalLock) {
3619 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3620 "setPictureInPictureParams", token, params);
3621
3622 // Only update the saved args from the args that are set
3623 r.pictureInPictureArgs.copyOnlySet(params);
3624 if (r.inPinnedWindowingMode()) {
3625 // If the activity is already in picture-in-picture, update the pinned stack now
3626 // if it is not already expanding to fullscreen. Otherwise, the arguments will
3627 // be used the next time the activity enters PiP
3628 final PinnedActivityStack stack = r.getStack();
3629 if (!stack.isAnimatingBoundsToFullscreen()) {
3630 stack.setPictureInPictureAspectRatio(
3631 r.pictureInPictureArgs.getAspectRatio());
3632 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
3633 }
3634 }
3635 logPictureInPictureArgs(params);
3636 }
3637 } finally {
3638 Binder.restoreCallingIdentity(origId);
3639 }
3640 }
3641
3642 @Override
3643 public int getMaxNumPictureInPictureActions(IBinder token) {
3644 // Currently, this is a static constant, but later, we may change this to be dependent on
3645 // the context of the activity
3646 return 3;
3647 }
3648
3649 private void logPictureInPictureArgs(PictureInPictureParams params) {
3650 if (params.hasSetActions()) {
3651 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
3652 params.getActions().size());
3653 }
3654 if (params.hasSetAspectRatio()) {
3655 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
3656 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
3657 MetricsLogger.action(lm);
3658 }
3659 }
3660
3661 /**
3662 * Checks the state of the system and the activity associated with the given {@param token} to
3663 * verify that picture-in-picture is supported for that activity.
3664 *
3665 * @return the activity record for the given {@param token} if all the checks pass.
3666 */
3667 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
3668 IBinder token, PictureInPictureParams params) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003669 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003670 throw new IllegalStateException(caller
3671 + ": Device doesn't support picture-in-picture mode.");
3672 }
3673
3674 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3675 if (r == null) {
3676 throw new IllegalStateException(caller
3677 + ": Can't find activity for token=" + token);
3678 }
3679
3680 if (!r.supportsPictureInPicture()) {
3681 throw new IllegalStateException(caller
3682 + ": Current activity does not support picture-in-picture.");
3683 }
3684
3685 if (params.hasSetAspectRatio()
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003686 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003687 params.getAspectRatio())) {
3688 final float minAspectRatio = mContext.getResources().getFloat(
3689 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
3690 final float maxAspectRatio = mContext.getResources().getFloat(
3691 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
3692 throw new IllegalArgumentException(String.format(caller
3693 + ": Aspect ratio is too extreme (must be between %f and %f).",
3694 minAspectRatio, maxAspectRatio));
3695 }
3696
3697 // Truncate the number of actions if necessary
3698 params.truncateActions(getMaxNumPictureInPictureActions(token));
3699
3700 return r;
3701 }
3702
3703 @Override
3704 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003705 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003706 synchronized (mGlobalLock) {
3707 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
3708 if (r == null) {
3709 throw new IllegalArgumentException("Activity does not exist; token="
3710 + activityToken);
3711 }
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07003712 return r.getUriPermissionsLocked().getExternalToken();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003713 }
3714 }
3715
3716 @Override
3717 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
3718 Rect tempDockedTaskInsetBounds,
3719 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003720 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003721 long ident = Binder.clearCallingIdentity();
3722 try {
3723 synchronized (mGlobalLock) {
3724 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
3725 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
3726 PRESERVE_WINDOWS);
3727 }
3728 } finally {
3729 Binder.restoreCallingIdentity(ident);
3730 }
3731 }
3732
3733 @Override
3734 public void setSplitScreenResizing(boolean resizing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003735 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003736 final long ident = Binder.clearCallingIdentity();
3737 try {
3738 synchronized (mGlobalLock) {
3739 mStackSupervisor.setSplitScreenResizing(resizing);
3740 }
3741 } finally {
3742 Binder.restoreCallingIdentity(ident);
3743 }
3744 }
3745
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003746 /**
3747 * Check that we have the features required for VR-related API calls, and throw an exception if
3748 * not.
3749 */
3750 void enforceSystemHasVrFeature() {
3751 if (!mContext.getPackageManager().hasSystemFeature(
3752 PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
3753 throw new UnsupportedOperationException("VR mode not supported on this device!");
3754 }
3755 }
3756
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003757 @Override
3758 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003759 enforceSystemHasVrFeature();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003760
3761 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3762
3763 ActivityRecord r;
3764 synchronized (mGlobalLock) {
3765 r = ActivityRecord.isInStackLocked(token);
3766 }
3767
3768 if (r == null) {
3769 throw new IllegalArgumentException();
3770 }
3771
3772 int err;
3773 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
3774 VrManagerInternal.NO_ERROR) {
3775 return err;
3776 }
3777
3778 // Clear the binder calling uid since this path may call moveToTask().
3779 final long callingId = Binder.clearCallingIdentity();
3780 try {
3781 synchronized (mGlobalLock) {
3782 r.requestedVrComponent = (enabled) ? packageName : null;
3783
3784 // Update associated state if this activity is currently focused
Andrii Kulian52d255c2018-07-13 11:32:19 -07003785 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003786 applyUpdateVrModeLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003787 }
3788 return 0;
3789 }
3790 } finally {
3791 Binder.restoreCallingIdentity(callingId);
3792 }
3793 }
3794
3795 @Override
3796 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
3797 Slog.i(TAG, "Activity tried to startLocalVoiceInteraction");
3798 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003799 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003800 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
3801 throw new SecurityException("Only focused activity can call startVoiceInteraction");
3802 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07003803 if (mRunningVoice != null || activity.getTask().voiceSession != null
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003804 || activity.voiceSession != null) {
3805 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
3806 return;
3807 }
3808 if (activity.pendingVoiceInteractionStart) {
3809 Slog.w(TAG, "Pending start of voice interaction already.");
3810 return;
3811 }
3812 activity.pendingVoiceInteractionStart = true;
3813 }
3814 LocalServices.getService(VoiceInteractionManagerInternal.class)
3815 .startLocalVoiceInteraction(callingActivity, options);
3816 }
3817
3818 @Override
3819 public void stopLocalVoiceInteraction(IBinder callingActivity) {
3820 LocalServices.getService(VoiceInteractionManagerInternal.class)
3821 .stopLocalVoiceInteraction(callingActivity);
3822 }
3823
3824 @Override
3825 public boolean supportsLocalVoiceInteraction() {
3826 return LocalServices.getService(VoiceInteractionManagerInternal.class)
3827 .supportsLocalVoiceInteraction();
3828 }
3829
3830 /** Notifies all listeners when the pinned stack animation starts. */
3831 @Override
3832 public void notifyPinnedStackAnimationStarted() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003833 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003834 }
3835
3836 /** Notifies all listeners when the pinned stack animation ends. */
3837 @Override
3838 public void notifyPinnedStackAnimationEnded() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003839 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003840 }
3841
3842 @Override
3843 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003844 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003845 final long ident = Binder.clearCallingIdentity();
3846 try {
3847 synchronized (mGlobalLock) {
3848 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
3849 }
3850 } finally {
3851 Binder.restoreCallingIdentity(ident);
3852 }
3853 }
3854
3855 @Override
3856 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003857 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003858
3859 synchronized (mGlobalLock) {
3860 // Check if display is initialized in AM.
3861 if (!mStackSupervisor.isDisplayAdded(displayId)) {
3862 // Call might come when display is not yet added or has already been removed.
3863 if (DEBUG_CONFIGURATION) {
3864 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
3865 + displayId);
3866 }
3867 return false;
3868 }
3869
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003870 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003871 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003872 values = mWindowManager.computeNewConfiguration(displayId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003873 }
3874
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003875 if (mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003876 // Update OOM levels based on display size.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003877 mAm.mProcessList.applyDisplaySize(mWindowManager);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003878 }
3879
3880 final long origId = Binder.clearCallingIdentity();
3881 try {
3882 if (values != null) {
3883 Settings.System.clearConfiguration(values);
3884 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003885 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003886 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
3887 return mTmpUpdateConfigurationResult.changes != 0;
3888 } finally {
3889 Binder.restoreCallingIdentity(origId);
3890 }
3891 }
3892 }
3893
3894 @Override
3895 public boolean updateConfiguration(Configuration values) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003896 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003897
3898 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003899 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003900 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003901 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003902 }
3903
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003904 if (mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003905 // Update OOM levels based on display size.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003906 mAm.mProcessList.applyDisplaySize(mWindowManager);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003907 }
3908
3909 final long origId = Binder.clearCallingIdentity();
3910 try {
3911 if (values != null) {
3912 Settings.System.clearConfiguration(values);
3913 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003914 updateConfigurationLocked(values, null, false, false /* persistent */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003915 UserHandle.USER_NULL, false /* deferResume */,
3916 mTmpUpdateConfigurationResult);
3917 return mTmpUpdateConfigurationResult.changes != 0;
3918 } finally {
3919 Binder.restoreCallingIdentity(origId);
3920 }
3921 }
3922 }
3923
3924 @Override
3925 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
3926 CharSequence message) {
3927 if (message != null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003928 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003929 Manifest.permission.SHOW_KEYGUARD_MESSAGE, "dismissKeyguard()");
3930 }
3931 final long callingId = Binder.clearCallingIdentity();
3932 try {
3933 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003934 mKeyguardController.dismissKeyguard(token, callback, message);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003935 }
3936 } finally {
3937 Binder.restoreCallingIdentity(callingId);
3938 }
3939 }
3940
3941 @Override
3942 public void cancelTaskWindowTransition(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003943 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003944 "cancelTaskWindowTransition()");
3945 final long ident = Binder.clearCallingIdentity();
3946 try {
3947 synchronized (mGlobalLock) {
3948 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
3949 MATCH_TASK_IN_STACKS_ONLY);
3950 if (task == null) {
3951 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
3952 return;
3953 }
3954 task.cancelWindowTransition();
3955 }
3956 } finally {
3957 Binder.restoreCallingIdentity(ident);
3958 }
3959 }
3960
3961 @Override
3962 public ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003963 enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003964 final long ident = Binder.clearCallingIdentity();
3965 try {
3966 final TaskRecord task;
3967 synchronized (mGlobalLock) {
3968 task = mStackSupervisor.anyTaskForIdLocked(taskId,
3969 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
3970 if (task == null) {
3971 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
3972 return null;
3973 }
3974 }
3975 // Don't call this while holding the lock as this operation might hit the disk.
3976 return task.getSnapshot(reducedResolution);
3977 } finally {
3978 Binder.restoreCallingIdentity(ident);
3979 }
3980 }
3981
3982 @Override
3983 public void setDisablePreviewScreenshots(IBinder token, boolean disable) {
3984 synchronized (mGlobalLock) {
3985 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3986 if (r == null) {
3987 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
3988 + token);
3989 return;
3990 }
3991 final long origId = Binder.clearCallingIdentity();
3992 try {
3993 r.setDisablePreviewScreenshots(disable);
3994 } finally {
3995 Binder.restoreCallingIdentity(origId);
3996 }
3997 }
3998 }
3999
4000 /** Return the user id of the last resumed activity. */
4001 @Override
4002 public @UserIdInt
4003 int getLastResumedActivityUserId() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004004 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004005 Manifest.permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
4006 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07004007 if (mLastResumedActivity == null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004008 return getCurrentUserId();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004009 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004010 return mLastResumedActivity.userId;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004011 }
4012 }
4013
4014 @Override
4015 public void updateLockTaskFeatures(int userId, int flags) {
4016 final int callingUid = Binder.getCallingUid();
4017 if (callingUid != 0 && callingUid != SYSTEM_UID) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004018 mAmInternal.enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004019 "updateLockTaskFeatures()");
4020 }
4021 synchronized (mGlobalLock) {
4022 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
4023 Integer.toHexString(flags));
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07004024 getLockTaskController().updateLockTaskFeatures(userId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004025 }
4026 }
4027
4028 @Override
4029 public void setShowWhenLocked(IBinder token, boolean showWhenLocked) {
4030 synchronized (mGlobalLock) {
4031 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4032 if (r == null) {
4033 return;
4034 }
4035 final long origId = Binder.clearCallingIdentity();
4036 try {
4037 r.setShowWhenLocked(showWhenLocked);
4038 } finally {
4039 Binder.restoreCallingIdentity(origId);
4040 }
4041 }
4042 }
4043
4044 @Override
4045 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) {
4046 synchronized (mGlobalLock) {
4047 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4048 if (r == null) {
4049 return;
4050 }
4051 final long origId = Binder.clearCallingIdentity();
4052 try {
4053 r.setTurnScreenOn(turnScreenOn);
4054 } finally {
4055 Binder.restoreCallingIdentity(origId);
4056 }
4057 }
4058 }
4059
4060 @Override
4061 public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004062 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004063 "registerRemoteAnimations");
4064 definition.setCallingPid(Binder.getCallingPid());
4065 synchronized (mGlobalLock) {
4066 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4067 if (r == null) {
4068 return;
4069 }
4070 final long origId = Binder.clearCallingIdentity();
4071 try {
4072 r.registerRemoteAnimations(definition);
4073 } finally {
4074 Binder.restoreCallingIdentity(origId);
4075 }
4076 }
4077 }
4078
4079 @Override
4080 public void registerRemoteAnimationForNextActivityStart(String packageName,
4081 RemoteAnimationAdapter adapter) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004082 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004083 "registerRemoteAnimationForNextActivityStart");
4084 adapter.setCallingPid(Binder.getCallingPid());
4085 synchronized (mGlobalLock) {
4086 final long origId = Binder.clearCallingIdentity();
4087 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07004088 getActivityStartController().registerRemoteAnimationForNextActivityStart(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004089 packageName, adapter);
4090 } finally {
4091 Binder.restoreCallingIdentity(origId);
4092 }
4093 }
4094 }
4095
4096 /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
4097 @Override
4098 public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
4099 synchronized (mGlobalLock) {
4100 final long origId = Binder.clearCallingIdentity();
4101 try {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004102 mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004103 } finally {
4104 Binder.restoreCallingIdentity(origId);
4105 }
4106 }
4107 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004108
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004109 @Override
4110 public void setVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004111 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004112 synchronized (mGlobalLock) {
4113 synchronized (mAm.mPidsSelfLocked) {
4114 final int pid = Binder.getCallingPid();
4115 final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004116 mVrController.setVrThreadLocked(tid, pid, proc.getWindowProcessController());
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004117 }
4118 }
4119 }
4120
4121 @Override
4122 public void setPersistentVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004123 if (checkCallingPermission(Manifest.permission.RESTRICTED_VR_ACCESS)
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004124 != PERMISSION_GRANTED) {
4125 final String msg = "Permission Denial: setPersistentVrThread() from pid="
4126 + Binder.getCallingPid()
4127 + ", uid=" + Binder.getCallingUid()
4128 + " requires " + Manifest.permission.RESTRICTED_VR_ACCESS;
4129 Slog.w(TAG, msg);
4130 throw new SecurityException(msg);
4131 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004132 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004133 synchronized (mGlobalLock) {
4134 synchronized (mAm.mPidsSelfLocked) {
4135 final int pid = Binder.getCallingPid();
4136 final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
4137 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
4138 }
4139 }
4140 }
4141
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004142 @Override
4143 public void stopAppSwitches() {
4144 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
4145 synchronized (mGlobalLock) {
4146 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME;
4147 mDidAppSwitch = false;
4148 getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
4149 }
4150 }
4151
4152 @Override
4153 public void resumeAppSwitches() {
4154 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
4155 synchronized (mGlobalLock) {
4156 // Note that we don't execute any pending app switches... we will
4157 // let those wait until either the timeout, or the next start
4158 // activity request.
4159 mAppSwitchesAllowedTime = 0;
4160 }
4161 }
4162
4163 void onStartActivitySetDidAppSwitch() {
4164 if (mDidAppSwitch) {
4165 // This is the second allowed switch since we stopped switches, so now just generally
4166 // allow switches. Use case:
4167 // - user presses home (switches disabled, switch to home, mDidAppSwitch now true);
4168 // - user taps a home icon (coming from home so allowed, we hit here and now allow
4169 // anyone to switch again).
4170 mAppSwitchesAllowedTime = 0;
4171 } else {
4172 mDidAppSwitch = true;
4173 }
4174 }
4175
4176 /** @return whether the system should disable UI modes incompatible with VR mode. */
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004177 boolean shouldDisableNonVrUiLocked() {
4178 return mVrController.shouldDisableNonVrUiLocked();
4179 }
4180
Wale Ogunwale53783742018-09-16 10:21:51 -07004181 private void applyUpdateVrModeLocked(ActivityRecord r) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004182 // VR apps are expected to run in a main display. If an app is turning on VR for
4183 // itself, but lives in a dynamic stack, then make sure that it is moved to the main
4184 // fullscreen stack before enabling VR Mode.
4185 // TODO: The goal of this code is to keep the VR app on the main display. When the
4186 // stack implementation changes in the future, keep in mind that the use of the fullscreen
4187 // stack is a means to move the activity to the main display and a moveActivityToDisplay()
4188 // option would be a better choice here.
4189 if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
4190 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
4191 + " to main stack for VR");
4192 final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
4193 WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
4194 moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
4195 }
4196 mH.post(() -> {
4197 if (!mVrController.onVrModeChanged(r)) {
4198 return;
4199 }
4200 synchronized (mGlobalLock) {
4201 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
4202 mWindowManager.disableNonVrUi(disableNonVrUi);
4203 if (disableNonVrUi) {
4204 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
4205 // then remove the pinned stack.
4206 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
4207 }
4208 }
4209 });
4210 }
4211
Wale Ogunwale53783742018-09-16 10:21:51 -07004212 @Override
4213 public int getPackageScreenCompatMode(String packageName) {
4214 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4215 synchronized (mGlobalLock) {
4216 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4217 }
4218 }
4219
4220 @Override
4221 public void setPackageScreenCompatMode(String packageName, int mode) {
4222 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4223 "setPackageScreenCompatMode");
4224 synchronized (mGlobalLock) {
4225 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4226 }
4227 }
4228
4229 @Override
4230 public boolean getPackageAskScreenCompat(String packageName) {
4231 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4232 synchronized (mGlobalLock) {
4233 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4234 }
4235 }
4236
4237 @Override
4238 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4239 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4240 "setPackageAskScreenCompat");
4241 synchronized (mGlobalLock) {
4242 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4243 }
4244 }
4245
Andrii Kulian5f750bc2018-07-17 08:57:23 -07004246 ActivityStack getTopDisplayFocusedStack() {
4247 return mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004248 }
4249
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004250 /** Pokes the task persister. */
4251 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
4252 mRecentTasks.notifyTaskPersisterLocked(task, flush);
4253 }
4254
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004255 void onTopProcChangedLocked(WindowProcessController proc) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004256 mVrController.onTopProcChangedLocked(proc);
4257 }
4258
4259 boolean isKeyguardLocked() {
4260 return mKeyguardController.isKeyguardLocked();
4261 }
4262
4263 boolean isNextTransitionForward() {
4264 int transit = mWindowManager.getPendingAppTransition();
4265 return transit == TRANSIT_ACTIVITY_OPEN
4266 || transit == TRANSIT_TASK_OPEN
4267 || transit == TRANSIT_TASK_TO_FRONT;
4268 }
4269
Wale Ogunwalef6733932018-06-27 05:14:34 -07004270 void dumpSleepStates(PrintWriter pw, boolean testPssMode) {
4271 synchronized (mGlobalLock) {
4272 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
4273 if (mRunningVoice != null) {
4274 pw.println(" mRunningVoice=" + mRunningVoice);
4275 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
4276 }
4277 pw.println(" mSleeping=" + mSleeping);
4278 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + testPssMode);
4279 pw.println(" mVrController=" + mVrController);
4280 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004281 }
4282
Wale Ogunwalef6733932018-06-27 05:14:34 -07004283 void writeSleepStateToProto(ProtoOutputStream proto) {
4284 for (ActivityTaskManagerInternal.SleepToken st : mStackSupervisor.mSleepTokens) {
4285 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS,
4286 st.toString());
4287 }
4288
4289 if (mRunningVoice != null) {
4290 final long vrToken = proto.start(
4291 ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
4292 proto.write(ActivityManagerServiceDumpProcessesProto.Voice.SESSION,
4293 mRunningVoice.toString());
4294 mVoiceWakeLock.writeToProto(
4295 proto, ActivityManagerServiceDumpProcessesProto.Voice.WAKELOCK);
4296 proto.end(vrToken);
4297 }
4298
4299 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
4300 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN,
4301 mShuttingDown);
4302 mVrController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004303 }
4304
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004305 int getCurrentUserId() {
4306 return mAmInternal.getCurrentUserId();
4307 }
4308
4309 private void enforceNotIsolatedCaller(String caller) {
4310 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4311 throw new SecurityException("Isolated process not allowed to call " + caller);
4312 }
4313 }
4314
Wale Ogunwalef6733932018-06-27 05:14:34 -07004315 public Configuration getConfiguration() {
4316 Configuration ci;
4317 synchronized(mGlobalLock) {
Yunfan Chen75157d72018-07-27 14:47:21 +09004318 ci = new Configuration(getGlobalConfigurationForCallingPid());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004319 ci.userSetLocale = false;
4320 }
4321 return ci;
4322 }
4323
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004324 /**
4325 * Current global configuration information. Contains general settings for the entire system,
4326 * also corresponds to the merged configuration of the default display.
4327 */
4328 Configuration getGlobalConfiguration() {
4329 return mStackSupervisor.getConfiguration();
4330 }
4331
4332 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4333 boolean initLocale) {
4334 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
4335 }
4336
4337 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4338 boolean initLocale, boolean deferResume) {
4339 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
4340 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
4341 UserHandle.USER_NULL, deferResume);
4342 }
4343
4344 void updatePersistentConfiguration(Configuration values, @UserIdInt int userId) {
4345 final long origId = Binder.clearCallingIdentity();
4346 try {
4347 synchronized (mGlobalLock) {
4348 updateConfigurationLocked(values, null, false, true, userId,
4349 false /* deferResume */);
4350 }
4351 } finally {
4352 Binder.restoreCallingIdentity(origId);
4353 }
4354 }
4355
4356 void updateUserConfiguration() {
4357 synchronized (mGlobalLock) {
4358 final Configuration configuration = new Configuration(getGlobalConfiguration());
4359 final int currentUserId = mAmInternal.getCurrentUserId();
4360 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
4361 currentUserId, Settings.System.canWrite(mContext));
4362 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
4363 false /* persistent */, currentUserId, false /* deferResume */);
4364 }
4365 }
4366
4367 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4368 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
4369 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
4370 deferResume, null /* result */);
4371 }
4372
4373 /**
4374 * Do either or both things: (1) change the current configuration, and (2)
4375 * make sure the given activity is running with the (now) current
4376 * configuration. Returns true if the activity has been left running, or
4377 * false if <var>starting</var> is being destroyed to match the new
4378 * configuration.
4379 *
4380 * @param userId is only used when persistent parameter is set to true to persist configuration
4381 * for that particular user
4382 */
4383 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4384 boolean initLocale, boolean persistent, int userId, boolean deferResume,
4385 ActivityTaskManagerService.UpdateConfigurationResult result) {
4386 int changes = 0;
4387 boolean kept = true;
4388
4389 if (mWindowManager != null) {
4390 mWindowManager.deferSurfaceLayout();
4391 }
4392 try {
4393 if (values != null) {
4394 changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
4395 deferResume);
4396 }
4397
4398 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4399 } finally {
4400 if (mWindowManager != null) {
4401 mWindowManager.continueSurfaceLayout();
4402 }
4403 }
4404
4405 if (result != null) {
4406 result.changes = changes;
4407 result.activityRelaunched = !kept;
4408 }
4409 return kept;
4410 }
4411
4412 /**
4413 * Returns true if this configuration change is interesting enough to send an
4414 * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
4415 */
4416 private static boolean isSplitConfigurationChange(int configDiff) {
4417 return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
4418 }
4419
4420 /** Update default (global) configuration and notify listeners about changes. */
4421 private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
4422 boolean persistent, int userId, boolean deferResume) {
4423 mTempConfig.setTo(getGlobalConfiguration());
4424 final int changes = mTempConfig.updateFrom(values);
4425 if (changes == 0) {
4426 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
4427 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
4428 // performDisplayOverrideConfigUpdate in order to send the new display configuration
4429 // (even if there are no actual changes) to unfreeze the window.
4430 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
4431 return 0;
4432 }
4433
4434 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
4435 "Updating global configuration to: " + values);
4436
4437 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
4438 StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
4439 values.colorMode,
4440 values.densityDpi,
4441 values.fontScale,
4442 values.hardKeyboardHidden,
4443 values.keyboard,
4444 values.keyboardHidden,
4445 values.mcc,
4446 values.mnc,
4447 values.navigation,
4448 values.navigationHidden,
4449 values.orientation,
4450 values.screenHeightDp,
4451 values.screenLayout,
4452 values.screenWidthDp,
4453 values.smallestScreenWidthDp,
4454 values.touchscreen,
4455 values.uiMode);
4456
4457
4458 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
4459 final LocaleList locales = values.getLocales();
4460 int bestLocaleIndex = 0;
4461 if (locales.size() > 1) {
4462 if (mSupportedSystemLocales == null) {
4463 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
4464 }
4465 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
4466 }
4467 SystemProperties.set("persist.sys.locale",
4468 locales.get(bestLocaleIndex).toLanguageTag());
4469 LocaleList.setDefault(locales, bestLocaleIndex);
4470 mAm.mHandler.sendMessage(mAm.mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
4471 locales.get(bestLocaleIndex)));
4472 }
4473
Yunfan Chen75157d72018-07-27 14:47:21 +09004474 mTempConfig.seq = increaseConfigurationSeqLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004475
4476 // Update stored global config and notify everyone about the change.
4477 mStackSupervisor.onConfigurationChanged(mTempConfig);
4478
4479 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
4480 // TODO(multi-display): Update UsageEvents#Event to include displayId.
4481 mAm.mUsageStatsService.reportConfigurationChange(
4482 mTempConfig, mAmInternal.getCurrentUserId());
4483
4484 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
Wale Ogunwalef6733932018-06-27 05:14:34 -07004485 updateShouldShowDialogsLocked(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004486
4487 AttributeCache ac = AttributeCache.instance();
4488 if (ac != null) {
4489 ac.updateConfiguration(mTempConfig);
4490 }
4491
4492 // Make sure all resources in our process are updated right now, so that anyone who is going
4493 // to retrieve resource values after we return will be sure to get the new ones. This is
4494 // especially important during boot, where the first config change needs to guarantee all
4495 // resources have that config before following boot code is executed.
4496 mAm.mSystemThread.applyConfigurationToResources(mTempConfig);
4497
4498 // We need another copy of global config because we're scheduling some calls instead of
4499 // running them in place. We need to be sure that object we send will be handled unchanged.
4500 final Configuration configCopy = new Configuration(mTempConfig);
4501 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
4502 Message msg = mAm.mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
4503 msg.obj = configCopy;
4504 msg.arg1 = userId;
4505 mAm.mHandler.sendMessage(msg);
4506 }
4507
Yunfan Chen75157d72018-07-27 14:47:21 +09004508 // TODO: Consider using mPidMap to update configurations for processes.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004509 for (int i = mAm.mLruProcesses.size() - 1; i >= 0; i--) {
4510 ProcessRecord app = mAm.mLruProcesses.get(i);
4511 try {
4512 if (app.thread != null) {
4513 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
4514 + app.processName + " new config " + configCopy);
4515 getLifecycleManager().scheduleTransaction(app.thread,
4516 ConfigurationChangeItem.obtain(configCopy));
4517 }
4518 } catch (Exception e) {
4519 Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
4520 }
4521 }
4522
4523 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
4524 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
4525 | Intent.FLAG_RECEIVER_FOREGROUND
4526 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4527 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4528 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4529 UserHandle.USER_ALL);
4530 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
4531 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
4532 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
4533 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
4534 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4535 if (initLocale || !mAm.mProcessesReady) {
4536 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
4537 }
4538 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4539 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4540 UserHandle.USER_ALL);
4541 }
4542
4543 // Send a broadcast to PackageInstallers if the configuration change is interesting
4544 // for the purposes of installing additional splits.
4545 if (!initLocale && isSplitConfigurationChange(changes)) {
4546 intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
4547 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
4548 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
4549
4550 // Typically only app stores will have this permission.
4551 String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES };
4552 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions,
4553 OP_NONE, null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
4554 }
4555
4556 // Override configuration of the default display duplicates global config, so we need to
4557 // update it also. This will also notify WindowManager about changes.
4558 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
4559 DEFAULT_DISPLAY);
4560
4561 return changes;
4562 }
4563
4564 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
4565 boolean deferResume, int displayId) {
4566 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
4567 displayId, null /* result */);
4568 }
4569
4570 /**
4571 * Updates override configuration specific for the selected display. If no config is provided,
4572 * new one will be computed in WM based on current display info.
4573 */
4574 boolean updateDisplayOverrideConfigurationLocked(Configuration values,
4575 ActivityRecord starting, boolean deferResume, int displayId,
4576 ActivityTaskManagerService.UpdateConfigurationResult result) {
4577 int changes = 0;
4578 boolean kept = true;
4579
4580 if (mWindowManager != null) {
4581 mWindowManager.deferSurfaceLayout();
4582 }
4583 try {
4584 if (values != null) {
4585 if (displayId == DEFAULT_DISPLAY) {
4586 // Override configuration of the default display duplicates global config, so
4587 // we're calling global config update instead for default display. It will also
4588 // apply the correct override config.
4589 changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
4590 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
4591 } else {
4592 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
4593 }
4594 }
4595
4596 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4597 } finally {
4598 if (mWindowManager != null) {
4599 mWindowManager.continueSurfaceLayout();
4600 }
4601 }
4602
4603 if (result != null) {
4604 result.changes = changes;
4605 result.activityRelaunched = !kept;
4606 }
4607 return kept;
4608 }
4609
4610 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
4611 int displayId) {
4612 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
4613 final int changes = mTempConfig.updateFrom(values);
4614 if (changes != 0) {
4615 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
4616 + mTempConfig + " for displayId=" + displayId);
4617 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
4618
4619 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
4620 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004621 mAppWarnings.onDensityChanged();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004622
4623 mAm.killAllBackgroundProcessesExcept(N,
4624 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
4625 }
4626 }
4627
4628 // Update the configuration with WM first and check if any of the stacks need to be resized
4629 // due to the configuration change. If so, resize the stacks now and do any relaunches if
4630 // necessary. This way we don't need to relaunch again afterwards in
4631 // ensureActivityConfiguration().
4632 if (mWindowManager != null) {
4633 final int[] resizedStacks =
4634 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
4635 if (resizedStacks != null) {
4636 for (int stackId : resizedStacks) {
4637 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
4638 }
4639 }
4640 }
4641
4642 return changes;
4643 }
4644
Wale Ogunwalef6733932018-06-27 05:14:34 -07004645 private void updateEventDispatchingLocked(boolean booted) {
4646 mWindowManager.setEventDispatching(booted && !mShuttingDown);
4647 }
4648
4649 void enableScreenAfterBoot(boolean booted) {
4650 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4651 SystemClock.uptimeMillis());
4652 mWindowManager.enableScreenAfterBoot();
4653
4654 synchronized (mGlobalLock) {
4655 updateEventDispatchingLocked(booted);
4656 }
4657 }
4658
4659 boolean canShowErrorDialogs() {
4660 return mShowDialogs && !mSleeping && !mShuttingDown
4661 && !mKeyguardController.isKeyguardOrAodShowing(DEFAULT_DISPLAY)
4662 && !hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
Wale Ogunwale86b74462018-07-02 08:42:43 -07004663 mAmInternal.getCurrentUserId())
Wale Ogunwalef6733932018-06-27 05:14:34 -07004664 && !(UserManager.isDeviceInDemoMode(mContext)
Wale Ogunwale86b74462018-07-02 08:42:43 -07004665 && mAmInternal.getCurrentUser().isDemo());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004666 }
4667
Wale Ogunwale906f9c62018-07-23 11:23:44 -07004668 static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
4669 if (r == null || !r.hasProcess()) {
4670 return KEY_DISPATCHING_TIMEOUT_MS;
4671 }
4672 return getInputDispatchingTimeoutLocked(r.app);
4673 }
4674
4675 private static long getInputDispatchingTimeoutLocked(WindowProcessController r) {
4676 if (r != null && (r.isInstrumenting() || r.isUsingWrapper())) {
4677 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS;
4678 }
4679 return KEY_DISPATCHING_TIMEOUT_MS;
4680 }
4681
4682 long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
4683 if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
4684 throw new SecurityException("Requires permission " + FILTER_EVENTS);
4685 }
4686 WindowProcessController proc;
4687 long timeout;
4688 synchronized (mGlobalLock) {
4689 proc = mPidMap.get(pid);
4690 timeout = getInputDispatchingTimeoutLocked(proc);
4691 }
4692
4693 if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
4694 return -1;
4695 }
4696
4697 return timeout;
4698 }
4699
4700 /**
4701 * Handle input dispatching timeouts.
4702 * Returns whether input dispatching should be aborted or not.
4703 */
4704 boolean inputDispatchingTimedOut(final WindowProcessController proc,
4705 final ActivityRecord activity, final ActivityRecord parent,
4706 final boolean aboveSystem, String reason) {
4707 if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
4708 throw new SecurityException("Requires permission " + FILTER_EVENTS);
4709 }
4710
4711 final String annotation;
4712 if (reason == null) {
4713 annotation = "Input dispatching timed out";
4714 } else {
4715 annotation = "Input dispatching timed out (" + reason + ")";
4716 }
4717
4718 if (proc != null) {
4719 synchronized (mGlobalLock) {
4720 if (proc.isDebugging()) {
4721 return false;
4722 }
4723
4724 if (proc.isInstrumenting()) {
4725 Bundle info = new Bundle();
4726 info.putString("shortMsg", "keyDispatchingTimedOut");
4727 info.putString("longMsg", annotation);
4728 mAm.finishInstrumentationLocked(
4729 (ProcessRecord) proc.mOwner, Activity.RESULT_CANCELED, info);
4730 return true;
4731 }
4732 }
4733 mH.post(() -> {
4734 mAm.mAppErrors.appNotResponding(
4735 (ProcessRecord) proc.mOwner, activity, parent, aboveSystem, annotation);
4736 });
4737 }
4738
4739 return true;
4740 }
4741
Wale Ogunwalef6733932018-06-27 05:14:34 -07004742 /**
4743 * Decide based on the configuration whether we should show the ANR,
4744 * crash, etc dialogs. The idea is that if there is no affordance to
4745 * press the on-screen buttons, or the user experience would be more
4746 * greatly impacted than the crash itself, we shouldn't show the dialog.
4747 *
4748 * A thought: SystemUI might also want to get told about this, the Power
4749 * dialog / global actions also might want different behaviors.
4750 */
4751 private void updateShouldShowDialogsLocked(Configuration config) {
4752 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
4753 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
4754 && config.navigation == Configuration.NAVIGATION_NONAV);
4755 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
4756 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
4757 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
4758 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
4759 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
4760 final boolean hideDialogsSet = Settings.Global.getInt(mContext.getContentResolver(),
4761 HIDE_ERROR_DIALOGS, 0) != 0;
4762 mShowDialogs = inputMethodExists && uiModeSupportsDialogs && !hideDialogsSet;
4763 }
4764
4765 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
4766 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
4767 FONT_SCALE, 1.0f, userId);
4768
4769 synchronized (this) {
4770 if (getGlobalConfiguration().fontScale == scaleFactor) {
4771 return;
4772 }
4773
4774 final Configuration configuration
4775 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
4776 configuration.fontScale = scaleFactor;
4777 updatePersistentConfiguration(configuration, userId);
4778 }
4779 }
4780
4781 // Actually is sleeping or shutting down or whatever else in the future
4782 // is an inactive state.
4783 boolean isSleepingOrShuttingDownLocked() {
4784 return isSleepingLocked() || mShuttingDown;
4785 }
4786
4787 boolean isSleepingLocked() {
4788 return mSleeping;
4789 }
4790
Riddle Hsu16567132018-08-16 21:37:47 +08004791 /** Update AMS states when an activity is resumed. */
Wale Ogunwalef6733932018-06-27 05:14:34 -07004792 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
4793 final TaskRecord task = r.getTask();
4794 if (task.isActivityTypeStandard()) {
4795 if (mCurAppTimeTracker != r.appTimeTracker) {
4796 // We are switching app tracking. Complete the current one.
4797 if (mCurAppTimeTracker != null) {
4798 mCurAppTimeTracker.stop();
4799 mH.obtainMessage(
4800 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
4801 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
4802 mCurAppTimeTracker = null;
4803 }
4804 if (r.appTimeTracker != null) {
4805 mCurAppTimeTracker = r.appTimeTracker;
4806 startTimeTrackingFocusedActivityLocked();
4807 }
4808 } else {
4809 startTimeTrackingFocusedActivityLocked();
4810 }
4811 } else {
4812 r.appTimeTracker = null;
4813 }
4814 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
4815 // TODO: Probably not, because we don't want to resume voice on switching
4816 // back to this activity
4817 if (task.voiceInteractor != null) {
4818 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
4819 } else {
4820 finishRunningVoiceLocked();
4821
4822 if (mLastResumedActivity != null) {
4823 final IVoiceInteractionSession session;
4824
4825 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
4826 if (lastResumedActivityTask != null
4827 && lastResumedActivityTask.voiceSession != null) {
4828 session = lastResumedActivityTask.voiceSession;
4829 } else {
4830 session = mLastResumedActivity.voiceSession;
4831 }
4832
4833 if (session != null) {
4834 // We had been in a voice interaction session, but now focused has
4835 // move to something different. Just finish the session, we can't
4836 // return to it and retain the proper state and synchronization with
4837 // the voice interaction service.
4838 finishVoiceTask(session);
4839 }
4840 }
4841 }
4842
4843 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
4844 mAmInternal.sendForegroundProfileChanged(r.userId);
4845 }
4846 updateResumedAppTrace(r);
4847 mLastResumedActivity = r;
4848
Riddle Hsu3026e8d2018-08-03 15:50:53 +08004849 // TODO(b/111361570): Support multiple focused apps in WM
Wale Ogunwalef6733932018-06-27 05:14:34 -07004850 mWindowManager.setFocusedApp(r.appToken, true);
4851
4852 applyUpdateLockStateLocked(r);
4853 applyUpdateVrModeLocked(r);
4854
4855 EventLogTags.writeAmSetResumedActivity(
4856 r == null ? -1 : r.userId,
4857 r == null ? "NULL" : r.shortComponentName,
4858 reason);
4859 }
4860
4861 ActivityTaskManagerInternal.SleepToken acquireSleepToken(String tag, int displayId) {
4862 synchronized (mGlobalLock) {
4863 final ActivityTaskManagerInternal.SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
4864 updateSleepIfNeededLocked();
4865 return token;
4866 }
4867 }
4868
4869 void updateSleepIfNeededLocked() {
4870 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
4871 final boolean wasSleeping = mSleeping;
4872 boolean updateOomAdj = false;
4873
4874 if (!shouldSleep) {
4875 // If wasSleeping is true, we need to wake up activity manager state from when
4876 // we started sleeping. In either case, we need to apply the sleep tokens, which
4877 // will wake up stacks or put them to sleep as appropriate.
4878 if (wasSleeping) {
4879 mSleeping = false;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07004880 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
4881 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__AWAKE);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004882 startTimeTrackingFocusedActivityLocked();
4883 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
4884 mStackSupervisor.comeOutOfSleepIfNeededLocked();
4885 }
4886 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
4887 if (wasSleeping) {
4888 updateOomAdj = true;
4889 }
4890 } else if (!mSleeping && shouldSleep) {
4891 mSleeping = true;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07004892 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
4893 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__ASLEEP);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004894 if (mCurAppTimeTracker != null) {
4895 mCurAppTimeTracker.stop();
4896 }
4897 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
4898 mStackSupervisor.goingToSleepLocked();
4899 updateResumedAppTrace(null /* resumed */);
4900 updateOomAdj = true;
4901 }
4902 if (updateOomAdj) {
4903 mH.post(mAmInternal::updateOomAdj);
4904 }
4905 }
4906
4907 void updateOomAdj() {
4908 mH.post(mAmInternal::updateOomAdj);
4909 }
4910
Wale Ogunwale53783742018-09-16 10:21:51 -07004911 void updateCpuStats() {
4912 mH.post(mAmInternal::updateCpuStats);
4913 }
4914
4915 void updateUsageStats(ActivityRecord component, boolean resumed) {
4916 final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::updateUsageStats,
4917 mAmInternal, component.realActivity, component.app.mUid, component.userId, resumed);
4918 mH.sendMessage(m);
4919 }
4920
4921 void setBooting(boolean booting) {
4922 mAmInternal.setBooting(booting);
4923 }
4924
4925 boolean isBooting() {
4926 return mAmInternal.isBooting();
4927 }
4928
4929 void setBooted(boolean booted) {
4930 mAmInternal.setBooted(booted);
4931 }
4932
4933 boolean isBooted() {
4934 return mAmInternal.isBooted();
4935 }
4936
4937 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
4938 mH.post(() -> {
4939 if (finishBooting) {
4940 mAmInternal.finishBooting();
4941 }
4942 if (enableScreen) {
4943 mInternal.enableScreenAfterBoot(isBooted());
4944 }
4945 });
4946 }
4947
4948 void setHeavyWeightProcess(ActivityRecord root) {
4949 mHeavyWeightProcess = root.app;
4950 final Message m = PooledLambda.obtainMessage(
4951 ActivityTaskManagerService::postHeavyWeightProcessNotification, this,
4952 root.app, root.intent, root.userId);
4953 mH.sendMessage(m);
4954 }
4955
4956 void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
4957 if (mHeavyWeightProcess == null || mHeavyWeightProcess != proc) {
4958 return;
4959 }
4960
4961 mHeavyWeightProcess = null;
4962 final Message m = PooledLambda.obtainMessage(
4963 ActivityTaskManagerService::cancelHeavyWeightProcessNotification, this,
4964 proc.mUserId);
4965 mH.sendMessage(m);
4966 }
4967
4968 private void cancelHeavyWeightProcessNotification(int userId) {
4969 final INotificationManager inm = NotificationManager.getService();
4970 if (inm == null) {
4971 return;
4972 }
4973 try {
4974 inm.cancelNotificationWithTag("android", null,
4975 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, userId);
4976 } catch (RuntimeException e) {
4977 Slog.w(TAG, "Error canceling notification for service", e);
4978 } catch (RemoteException e) {
4979 }
4980
4981 }
4982
4983 private void postHeavyWeightProcessNotification(
4984 WindowProcessController proc, Intent intent, int userId) {
4985 if (proc == null) {
4986 return;
4987 }
4988
4989 final INotificationManager inm = NotificationManager.getService();
4990 if (inm == null) {
4991 return;
4992 }
4993
4994 try {
4995 Context context = mContext.createPackageContext(proc.mInfo.packageName, 0);
4996 String text = mContext.getString(R.string.heavy_weight_notification,
4997 context.getApplicationInfo().loadLabel(context.getPackageManager()));
4998 Notification notification =
4999 new Notification.Builder(context,
5000 SystemNotificationChannels.HEAVY_WEIGHT_APP)
5001 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
5002 .setWhen(0)
5003 .setOngoing(true)
5004 .setTicker(text)
5005 .setColor(mContext.getColor(
5006 com.android.internal.R.color.system_notification_accent_color))
5007 .setContentTitle(text)
5008 .setContentText(
5009 mContext.getText(R.string.heavy_weight_notification_detail))
5010 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
5011 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
5012 new UserHandle(userId)))
5013 .build();
5014 try {
5015 inm.enqueueNotificationWithTag("android", "android", null,
5016 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, notification, userId);
5017 } catch (RuntimeException e) {
5018 Slog.w(TAG, "Error showing notification for heavy-weight app", e);
5019 } catch (RemoteException e) {
5020 }
5021 } catch (PackageManager.NameNotFoundException e) {
5022 Slog.w(TAG, "Unable to create context for heavy notification", e);
5023 }
5024
5025 }
5026
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07005027 IIntentSender getIntentSenderLocked(int type, String packageName, int callingUid, int userId,
5028 IBinder token, String resultWho, int requestCode, Intent[] intents,
5029 String[] resolvedTypes, int flags, Bundle bOptions) {
5030
5031 ActivityRecord activity = null;
5032 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5033 activity = ActivityRecord.isInStackLocked(token);
5034 if (activity == null) {
5035 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
5036 return null;
5037 }
5038 if (activity.finishing) {
5039 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
5040 return null;
5041 }
5042 }
5043
5044 final PendingIntentRecord rec = mPendingIntentController.getIntentSender(type, packageName,
5045 callingUid, userId, token, resultWho, requestCode, intents, resolvedTypes, flags,
5046 bOptions);
5047 final boolean noCreate = (flags & PendingIntent.FLAG_NO_CREATE) != 0;
5048 if (noCreate) {
5049 return rec;
5050 }
5051 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5052 if (activity.pendingResults == null) {
5053 activity.pendingResults = new HashSet<>();
5054 }
5055 activity.pendingResults.add(rec.ref);
5056 }
5057 return rec;
5058 }
5059
Andrii Kulian52d255c2018-07-13 11:32:19 -07005060 // TODO(b/111541062): Update app time tracking to make it aware of multiple resumed activities
Wale Ogunwalef6733932018-06-27 05:14:34 -07005061 private void startTimeTrackingFocusedActivityLocked() {
Andrii Kulian52d255c2018-07-13 11:32:19 -07005062 final ActivityRecord resumedActivity = mStackSupervisor.getTopResumedActivity();
Wale Ogunwalef6733932018-06-27 05:14:34 -07005063 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
5064 mCurAppTimeTracker.start(resumedActivity.packageName);
5065 }
5066 }
5067
5068 private void updateResumedAppTrace(@Nullable ActivityRecord resumed) {
5069 if (mTracedResumedActivity != null) {
5070 Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER,
5071 constructResumedTraceName(mTracedResumedActivity.packageName), 0);
5072 }
5073 if (resumed != null) {
5074 Trace.asyncTraceBegin(TRACE_TAG_ACTIVITY_MANAGER,
5075 constructResumedTraceName(resumed.packageName), 0);
5076 }
5077 mTracedResumedActivity = resumed;
5078 }
5079
5080 private String constructResumedTraceName(String packageName) {
5081 return "focused app: " + packageName;
5082 }
5083
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005084 /** Helper method that requests bounds from WM and applies them to stack. */
5085 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
5086 final Rect newStackBounds = new Rect();
5087 final ActivityStack stack = mStackSupervisor.getStack(stackId);
5088
5089 // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
5090 if (stack == null) {
5091 final StringWriter writer = new StringWriter();
5092 final PrintWriter printWriter = new PrintWriter(writer);
5093 mStackSupervisor.dumpDisplays(printWriter);
5094 printWriter.flush();
5095
5096 Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
5097 }
5098
5099 stack.getBoundsForNewConfiguration(newStackBounds);
5100 mStackSupervisor.resizeStackLocked(
5101 stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
5102 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
5103 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
5104 }
5105
5106 /** Applies latest configuration and/or visibility updates if needed. */
5107 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
5108 boolean kept = true;
Andrii Kulian5f750bc2018-07-17 08:57:23 -07005109 final ActivityStack mainStack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005110 // mainStack is null during startup.
5111 if (mainStack != null) {
5112 if (changes != 0 && starting == null) {
5113 // If the configuration changed, and the caller is not already
5114 // in the process of starting an activity, then find the top
5115 // activity to check if its configuration needs to change.
5116 starting = mainStack.topRunningActivityLocked();
5117 }
5118
5119 if (starting != null) {
5120 kept = starting.ensureActivityConfiguration(changes,
5121 false /* preserveWindow */);
5122 // And we need to make sure at this point that all other activities
5123 // are made visible with the correct configuration.
5124 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
5125 !PRESERVE_WINDOWS);
5126 }
5127 }
5128
5129 return kept;
5130 }
5131
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005132 void scheduleAppGcsLocked() {
5133 mH.post(() -> mAmInternal.scheduleAppGcs());
5134 }
5135
Wale Ogunwale53783742018-09-16 10:21:51 -07005136 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
5137 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
5138 }
5139
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005140 /**
5141 * Returns the PackageManager. Used by classes hosted by {@link ActivityTaskManagerService}. The
5142 * PackageManager could be unavailable at construction time and therefore needs to be accessed
5143 * on demand.
5144 */
5145 IPackageManager getPackageManager() {
5146 return AppGlobals.getPackageManager();
5147 }
5148
5149 PackageManagerInternal getPackageManagerInternalLocked() {
5150 if (mPmInternal == null) {
5151 mPmInternal = LocalServices.getService(PackageManagerInternal.class);
5152 }
5153 return mPmInternal;
5154 }
5155
Wale Ogunwale008163e2018-07-23 23:11:08 -07005156 AppWarnings getAppWarningsLocked() {
5157 return mAppWarnings;
5158 }
5159
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005160 void logAppTooSlow(WindowProcessController app, long startTime, String msg) {
5161 if (true || Build.IS_USER) {
5162 return;
5163 }
5164
5165 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5166 StrictMode.allowThreadDiskWrites();
5167 try {
5168 File tracesDir = new File("/data/anr");
5169 File tracesFile = null;
5170 try {
5171 tracesFile = File.createTempFile("app_slow", null, tracesDir);
5172
5173 StringBuilder sb = new StringBuilder();
5174 Time tobj = new Time();
5175 tobj.set(System.currentTimeMillis());
5176 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5177 sb.append(": ");
5178 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5179 sb.append(" since ");
5180 sb.append(msg);
5181 FileOutputStream fos = new FileOutputStream(tracesFile);
5182 fos.write(sb.toString().getBytes());
5183 if (app == null) {
5184 fos.write("\n*** No application process!".getBytes());
5185 }
5186 fos.close();
5187 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5188 } catch (IOException e) {
5189 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesFile, e);
5190 return;
5191 }
5192
5193 if (app != null && app.getPid() > 0) {
5194 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5195 firstPids.add(app.getPid());
5196 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, null, null);
5197 }
5198
5199 File lastTracesFile = null;
5200 File curTracesFile = null;
5201 for (int i=9; i>=0; i--) {
5202 String name = String.format(Locale.US, "slow%02d.txt", i);
5203 curTracesFile = new File(tracesDir, name);
5204 if (curTracesFile.exists()) {
5205 if (lastTracesFile != null) {
5206 curTracesFile.renameTo(lastTracesFile);
5207 } else {
5208 curTracesFile.delete();
5209 }
5210 }
5211 lastTracesFile = curTracesFile;
5212 }
5213 tracesFile.renameTo(curTracesFile);
5214 } finally {
5215 StrictMode.setThreadPolicy(oldPolicy);
5216 }
5217 }
5218
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005219 final class H extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005220 static final int REPORT_TIME_TRACKER_MSG = 1;
5221
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005222 public H(Looper looper) {
5223 super(looper, null, true);
5224 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005225
5226 @Override
5227 public void handleMessage(Message msg) {
5228 switch (msg.what) {
5229 case REPORT_TIME_TRACKER_MSG: {
5230 AppTimeTracker tracker = (AppTimeTracker) msg.obj;
5231 tracker.deliverResult(mContext);
5232 } break;
5233 }
5234 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005235 }
5236
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005237 final class UiHandler extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005238 static final int DISMISS_DIALOG_UI_MSG = 1;
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005239
5240 public UiHandler() {
5241 super(com.android.server.UiThread.get().getLooper(), null, true);
5242 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005243
5244 @Override
5245 public void handleMessage(Message msg) {
5246 switch (msg.what) {
5247 case DISMISS_DIALOG_UI_MSG: {
5248 final Dialog d = (Dialog) msg.obj;
5249 d.dismiss();
5250 break;
5251 }
5252 }
5253 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005254 }
5255
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005256 final class LocalService extends ActivityTaskManagerInternal {
5257 @Override
5258 public SleepToken acquireSleepToken(String tag, int displayId) {
5259 Preconditions.checkNotNull(tag);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005260 return ActivityTaskManagerService.this.acquireSleepToken(tag, displayId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005261 }
5262
5263 @Override
5264 public ComponentName getHomeActivityForUser(int userId) {
5265 synchronized (mGlobalLock) {
5266 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
5267 return homeActivity == null ? null : homeActivity.realActivity;
5268 }
5269 }
5270
5271 @Override
5272 public void onLocalVoiceInteractionStarted(IBinder activity,
5273 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
5274 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005275 onLocalVoiceInteractionStartedLocked(activity, voiceSession, voiceInteractor);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005276 }
5277 }
5278
5279 @Override
5280 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
5281 synchronized (mGlobalLock) {
5282 mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
5283 reasons, timestamp);
5284 }
5285 }
5286
5287 @Override
5288 public void notifyAppTransitionFinished() {
5289 synchronized (mGlobalLock) {
5290 mStackSupervisor.notifyAppTransitionDone();
5291 }
5292 }
5293
5294 @Override
5295 public void notifyAppTransitionCancelled() {
5296 synchronized (mGlobalLock) {
5297 mStackSupervisor.notifyAppTransitionDone();
5298 }
5299 }
5300
5301 @Override
5302 public List<IBinder> getTopVisibleActivities() {
5303 synchronized (mGlobalLock) {
5304 return mStackSupervisor.getTopVisibleActivities();
5305 }
5306 }
5307
5308 @Override
5309 public void notifyDockedStackMinimizedChanged(boolean minimized) {
5310 synchronized (mGlobalLock) {
5311 mStackSupervisor.setDockedStackMinimized(minimized);
5312 }
5313 }
5314
5315 @Override
5316 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
5317 Bundle bOptions) {
5318 Preconditions.checkNotNull(intents, "intents");
5319 final String[] resolvedTypes = new String[intents.length];
5320
5321 // UID of the package on user userId.
5322 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
5323 // packageUid may not be initialized.
5324 int packageUid = 0;
5325 final long ident = Binder.clearCallingIdentity();
5326
5327 try {
5328 for (int i = 0; i < intents.length; i++) {
5329 resolvedTypes[i] =
5330 intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
5331 }
5332
5333 packageUid = AppGlobals.getPackageManager().getPackageUid(
5334 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
5335 } catch (RemoteException e) {
5336 // Shouldn't happen.
5337 } finally {
5338 Binder.restoreCallingIdentity(ident);
5339 }
5340
5341 synchronized (mGlobalLock) {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07005342 return getActivityStartController().startActivitiesInPackage(
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005343 packageUid, packageName,
5344 intents, resolvedTypes, null /* resultTo */,
5345 SafeActivityOptions.fromBundle(bOptions), userId,
Michal Karpinski201bc0c2018-07-20 15:32:00 +01005346 false /* validateIncomingUser */, null /* originatingPendingIntent */);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005347 }
5348 }
5349
5350 @Override
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07005351 public int startActivitiesInPackage(int uid, String callingPackage, Intent[] intents,
5352 String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, int userId,
5353 boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent) {
5354 synchronized (mGlobalLock) {
5355 return getActivityStartController().startActivitiesInPackage(uid, callingPackage,
5356 intents, resolvedTypes, resultTo, options, userId, validateIncomingUser,
5357 originatingPendingIntent);
5358 }
5359 }
5360
5361 @Override
5362 public int startActivityInPackage(int uid, int realCallingPid, int realCallingUid,
5363 String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
5364 String resultWho, int requestCode, int startFlags, SafeActivityOptions options,
5365 int userId, TaskRecord inTask, String reason, boolean validateIncomingUser,
5366 PendingIntentRecord originatingPendingIntent) {
5367 synchronized (mGlobalLock) {
5368 return getActivityStartController().startActivityInPackage(uid, realCallingPid,
5369 realCallingUid, callingPackage, intent, resolvedType, resultTo, resultWho,
5370 requestCode, startFlags, options, userId, inTask, reason,
5371 validateIncomingUser, originatingPendingIntent);
5372 }
5373 }
5374
5375 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005376 public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
5377 Intent intent, Bundle options, int userId) {
5378 return ActivityTaskManagerService.this.startActivityAsUser(
5379 caller, callerPacakge, intent,
5380 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
5381 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
5382 false /*validateIncomingUser*/);
5383 }
5384
5385 @Override
5386 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
5387 synchronized (mGlobalLock) {
5388
5389 // We might change the visibilities here, so prepare an empty app transition which
5390 // might be overridden later if we actually change visibilities.
5391 final boolean wasTransitionSet =
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005392 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005393 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005394 mWindowManager.prepareAppTransition(TRANSIT_NONE,
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005395 false /* alwaysKeepCurrent */);
5396 }
5397 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5398
5399 // If there was a transition set already we don't want to interfere with it as we
5400 // might be starting it too early.
5401 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005402 mWindowManager.executeAppTransition();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005403 }
5404 }
5405 if (callback != null) {
5406 callback.run();
5407 }
5408 }
5409
5410 @Override
5411 public void notifyKeyguardTrustedChanged() {
5412 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005413 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005414 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5415 }
5416 }
5417 }
5418
5419 /**
5420 * Called after virtual display Id is updated by
5421 * {@link com.android.server.vr.Vr2dDisplay} with a specific
5422 * {@param vrVr2dDisplayId}.
5423 */
5424 @Override
5425 public void setVr2dDisplayId(int vr2dDisplayId) {
5426 if (DEBUG_STACK) Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
5427 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005428 mVr2dDisplayId = vr2dDisplayId;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005429 }
5430 }
5431
5432 @Override
5433 public void setFocusedActivity(IBinder token) {
5434 synchronized (mGlobalLock) {
5435 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
5436 if (r == null) {
5437 throw new IllegalArgumentException(
5438 "setFocusedActivity: No activity record matching token=" + token);
5439 }
5440 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
5441 r, "setFocusedActivity")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08005442 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005443 }
5444 }
5445 }
5446
5447 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005448 public void registerScreenObserver(ScreenObserver observer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005449 mScreenObservers.add(observer);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005450 }
5451
5452 @Override
5453 public boolean isCallerRecents(int callingUid) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005454 return getRecentTasks().isCallerRecents(callingUid);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005455 }
5456
5457 @Override
5458 public boolean isRecentsComponentHomeActivity(int userId) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005459 return getRecentTasks().isRecentsComponentHomeActivity(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005460 }
5461
5462 @Override
5463 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
5464 ActivityTaskManagerService.this.cancelRecentsAnimation(restoreHomeStackPosition);
5465 }
5466
5467 @Override
5468 public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005469 ActivityTaskManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005470 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005471
5472 @Override
5473 public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
5474 synchronized (mGlobalLock) {
5475 mActiveVoiceInteractionServiceComponent = component;
5476 }
5477 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005478
5479 @Override
5480 public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
5481 if (!mAmInternal.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
5482 return;
5483 }
5484 synchronized (mGlobalLock) {
5485 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
5486 if (types == null) {
5487 if (uid < 0) {
5488 return;
5489 }
5490 types = new ArrayMap<>();
5491 mAllowAppSwitchUids.put(userId, types);
5492 }
5493 if (uid < 0) {
5494 types.remove(type);
5495 } else {
5496 types.put(type, uid);
5497 }
5498 }
5499 }
5500
5501 @Override
5502 public void onUserStopped(int userId) {
5503 synchronized (mGlobalLock) {
5504 getRecentTasks().unloadUserDataFromMemoryLocked(userId);
5505 mAllowAppSwitchUids.remove(userId);
5506 }
5507 }
5508
5509 @Override
5510 public boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
5511 synchronized (mGlobalLock) {
5512 return ActivityTaskManagerService.this.isGetTasksAllowed(
5513 caller, callingPid, callingUid);
5514 }
5515 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005516
5517 @Override
5518 public void onProcessAdded(WindowProcessController proc) {
5519 synchronized (mGlobalLock) {
5520 mProcessNames.put(proc.mName, proc.mUid, proc);
5521 }
5522 }
5523
5524 @Override
5525 public void onProcessRemoved(String name, int uid) {
5526 synchronized (mGlobalLock) {
5527 mProcessNames.remove(name, uid);
5528 }
5529 }
5530
5531 @Override
5532 public void onCleanUpApplicationRecord(WindowProcessController proc) {
5533 synchronized (mGlobalLock) {
5534 if (proc == mHomeProcess) {
5535 mHomeProcess = null;
5536 }
5537 if (proc == mPreviousProcess) {
5538 mPreviousProcess = null;
5539 }
5540 }
5541 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005542
5543 @Override
5544 public int getTopProcessState() {
5545 synchronized (mGlobalLock) {
5546 return mTopProcessState;
5547 }
5548 }
5549
5550 @Override
Wale Ogunwale53783742018-09-16 10:21:51 -07005551 public boolean isHeavyWeightProcess(WindowProcessController proc) {
5552 synchronized (mGlobalLock) {
5553 return proc == mHeavyWeightProcess;
5554 }
5555 }
5556
5557 @Override
5558 public void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
5559 synchronized (mGlobalLock) {
5560 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(proc);
5561 }
5562 }
5563
5564 @Override
5565 public void finishHeavyWeightApp() {
5566 synchronized (mGlobalLock) {
5567 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(
5568 mHeavyWeightProcess);
5569 }
5570 }
5571
5572 @Override
Wale Ogunwalef6733932018-06-27 05:14:34 -07005573 public boolean isSleeping() {
5574 synchronized (mGlobalLock) {
5575 return isSleepingLocked();
5576 }
5577 }
5578
5579 @Override
5580 public boolean isShuttingDown() {
5581 synchronized (mGlobalLock) {
5582 return mShuttingDown;
5583 }
5584 }
5585
5586 @Override
5587 public boolean shuttingDown(boolean booted, int timeout) {
5588 synchronized (mGlobalLock) {
5589 mShuttingDown = true;
5590 mStackSupervisor.prepareForShutdownLocked();
5591 updateEventDispatchingLocked(booted);
5592 return mStackSupervisor.shutdownLocked(timeout);
5593 }
5594 }
5595
5596 @Override
5597 public void enableScreenAfterBoot(boolean booted) {
5598 synchronized (mGlobalLock) {
5599 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5600 SystemClock.uptimeMillis());
5601 mWindowManager.enableScreenAfterBoot();
5602 updateEventDispatchingLocked(booted);
5603 }
5604 }
5605
5606 @Override
5607 public boolean showStrictModeViolationDialog() {
5608 synchronized (mGlobalLock) {
5609 return mShowDialogs && !mSleeping && !mShuttingDown;
5610 }
5611 }
5612
5613 @Override
5614 public void showSystemReadyErrorDialogsIfNeeded() {
5615 synchronized (mGlobalLock) {
5616 try {
5617 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
5618 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
5619 + " data partition or your device will be unstable.");
5620 mUiHandler.post(() -> {
5621 if (mShowDialogs) {
5622 AlertDialog d = new BaseErrorDialog(mUiContext);
5623 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5624 d.setCancelable(false);
5625 d.setTitle(mUiContext.getText(R.string.android_system_label));
5626 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
5627 d.setButton(DialogInterface.BUTTON_POSITIVE,
5628 mUiContext.getText(R.string.ok),
5629 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5630 d.show();
5631 }
5632 });
5633 }
5634 } catch (RemoteException e) {
5635 }
5636
5637 if (!Build.isBuildConsistent()) {
5638 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
5639 mUiHandler.post(() -> {
5640 if (mShowDialogs) {
5641 AlertDialog d = new BaseErrorDialog(mUiContext);
5642 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5643 d.setCancelable(false);
5644 d.setTitle(mUiContext.getText(R.string.android_system_label));
5645 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
5646 d.setButton(DialogInterface.BUTTON_POSITIVE,
5647 mUiContext.getText(R.string.ok),
5648 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5649 d.show();
5650 }
5651 });
5652 }
5653 }
5654 }
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005655
5656 @Override
5657 public long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason) {
5658 synchronized (mGlobalLock) {
5659 return ActivityTaskManagerService.this.inputDispatchingTimedOut(
5660 pid, aboveSystem, reason);
5661 }
5662 }
5663
5664 @Override
5665 public void onProcessMapped(int pid, WindowProcessController proc) {
5666 synchronized (mGlobalLock) {
5667 mPidMap.put(pid, proc);
5668 }
5669 }
5670
5671 @Override
5672 public void onProcessUnMapped(int pid) {
5673 synchronized (mGlobalLock) {
5674 mPidMap.remove(pid);
5675 }
5676 }
Wale Ogunwale008163e2018-07-23 23:11:08 -07005677
5678 @Override
5679 public void onPackageDataCleared(String name) {
5680 synchronized (mGlobalLock) {
Wale Ogunwale53783742018-09-16 10:21:51 -07005681 mCompatModePackages.handlePackageDataClearedLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07005682 mAppWarnings.onPackageDataCleared(name);
5683 }
5684 }
5685
5686 @Override
5687 public void onPackageUninstalled(String name) {
5688 synchronized (mGlobalLock) {
5689 mAppWarnings.onPackageUninstalled(name);
Wale Ogunwale53783742018-09-16 10:21:51 -07005690 mCompatModePackages.handlePackageUninstalledLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07005691 }
5692 }
Wale Ogunwale53783742018-09-16 10:21:51 -07005693
5694 @Override
5695 public void onPackageAdded(String name, boolean replacing) {
5696 synchronized (mGlobalLock) {
5697 mCompatModePackages.handlePackageAddedLocked(name, replacing);
5698 }
5699 }
5700
5701 @Override
5702 public CompatibilityInfo compatibilityInfoForPackage(ApplicationInfo ai) {
5703 synchronized (mGlobalLock) {
5704 return compatibilityInfoForPackageLocked(ai);
5705 }
5706 }
5707
Yunfan Chen75157d72018-07-27 14:47:21 +09005708 /**
5709 * Set the corresponding display information for the process global configuration. To be
5710 * called when we need to show IME on a different display.
5711 *
5712 * @param pid The process id associated with the IME window.
5713 * @param displayId The ID of the display showing the IME.
5714 */
5715 @Override
5716 public void onImeWindowSetOnDisplay(int pid, int displayId) {
5717 if (pid == MY_PID || pid < 0) {
5718 if (DEBUG_CONFIGURATION) {
5719 Slog.w(TAG,
5720 "Trying to update display configuration for system/invalid process.");
5721 }
5722 return;
5723 }
5724 mH.post(() -> {
5725 synchronized (mGlobalLock) {
5726 // Check if display is initialized in AM.
5727 if (!mStackSupervisor.isDisplayAdded(displayId)) {
5728 // Call come when display is not yet added or has already been removed.
5729 if (DEBUG_CONFIGURATION) {
5730 Slog.w(TAG, "Trying to update display configuration for non-existing "
5731 + "displayId=" + displayId);
5732 }
5733 return;
5734 }
5735 final WindowProcessController imeProcess = mPidMap.get(pid);
5736 if (imeProcess == null) {
5737 if (DEBUG_CONFIGURATION) {
5738 Slog.w(TAG, "Trying to update display configuration for invalid pid: "
5739 + pid);
5740 }
5741 return;
5742 }
5743 // Fetch the current override configuration of the display and set it to the
5744 // process global configuration.
5745 imeProcess.onConfigurationChanged(
5746 mStackSupervisor.getDisplayOverrideConfiguration(displayId));
5747 }
5748 });
5749 }
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07005750
5751 @Override
5752 public void sendActivityResult(int callingUid, IBinder activityToken, String resultWho,
5753 int requestCode, int resultCode, Intent data) {
5754 synchronized (mGlobalLock) {
5755 final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
5756 if (r != null && r.getStack() != null) {
5757 r.getStack().sendActivityResultLocked(callingUid, r, resultWho, requestCode,
5758 resultCode, data);
5759 }
5760 }
5761 }
5762
5763 @Override
5764 public void clearPendingResultForActivity(IBinder activityToken,
5765 WeakReference<PendingIntentRecord> pir) {
5766 synchronized (mGlobalLock) {
5767 final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
5768 if (r != null && r.pendingResults != null) {
5769 r.pendingResults.remove(pir);
5770 }
5771 }
5772 }
5773
5774 @Override
5775 public IIntentSender getIntentSender(int type, String packageName,
5776 int callingUid, int userId, IBinder token, String resultWho,
5777 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5778 Bundle bOptions) {
5779 synchronized (mGlobalLock) {
5780 return getIntentSenderLocked(type, packageName, callingUid, userId, token,
5781 resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
5782 }
5783 }
Wale Ogunwalec4e63a42018-10-02 13:19:54 -07005784
5785 @Override
5786 public ActivityServiceConnectionsHolder getServiceConnectionsHolder(IBinder token) {
5787 synchronized (mGlobalLock) {
5788 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
5789 if (r == null) {
5790 return null;
5791 }
5792 if (r.mServiceConnectionsHolder == null) {
5793 r.mServiceConnectionsHolder = new ActivityServiceConnectionsHolder(
5794 ActivityTaskManagerService.this, r);
5795 }
5796
5797 return r.mServiceConnectionsHolder;
5798 }
5799 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005800 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07005801}