blob: add9f2a7e9d87ded5bd5d111df634458e20c2ddb [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);
1963 return;
1964 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001965 if (getLockTaskController().isLockTaskModeViolation(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001966 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
1967 return;
1968 }
1969 ActivityOptions realOptions = options != null
1970 ? options.getOptions(mStackSupervisor)
1971 : null;
1972 mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
1973 false /* forceNonResizable */);
1974
1975 final ActivityRecord topActivity = task.getTopActivity();
1976 if (topActivity != null) {
1977
1978 // We are reshowing a task, use a starting window to hide the initial draw delay
1979 // so the transition can start earlier.
1980 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
1981 true /* taskSwitch */, fromRecents);
1982 }
1983 } finally {
1984 Binder.restoreCallingIdentity(origId);
1985 }
1986 SafeActivityOptions.abort(options);
1987 }
1988
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001989 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
1990 int callingPid, int callingUid, String name) {
1991 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
1992 return true;
1993 }
1994
1995 if (getRecentTasks().isCallerRecents(sourceUid)) {
1996 return true;
1997 }
1998
1999 int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
2000 if (perm == PackageManager.PERMISSION_GRANTED) {
2001 return true;
2002 }
2003 if (checkAllowAppSwitchUid(sourceUid)) {
2004 return true;
2005 }
2006
2007 // If the actual IPC caller is different from the logical source, then
2008 // also see if they are allowed to control app switches.
2009 if (callingUid != -1 && callingUid != sourceUid) {
2010 perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
2011 if (perm == PackageManager.PERMISSION_GRANTED) {
2012 return true;
2013 }
2014 if (checkAllowAppSwitchUid(callingUid)) {
2015 return true;
2016 }
2017 }
2018
2019 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
2020 return false;
2021 }
2022
2023 private boolean checkAllowAppSwitchUid(int uid) {
2024 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
2025 if (types != null) {
2026 for (int i = types.size() - 1; i >= 0; i--) {
2027 if (types.valueAt(i).intValue() == uid) {
2028 return true;
2029 }
2030 }
2031 }
2032 return false;
2033 }
2034
2035 @Override
2036 public void setActivityController(IActivityController controller, boolean imAMonkey) {
2037 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
2038 "setActivityController()");
2039 synchronized (mGlobalLock) {
2040 mController = controller;
2041 mControllerIsAMonkey = imAMonkey;
2042 Watchdog.getInstance().setActivityController(controller);
2043 }
2044 }
2045
2046 boolean isControllerAMonkey() {
2047 synchronized (mGlobalLock) {
2048 return mController != null && mControllerIsAMonkey;
2049 }
2050 }
2051
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002052 @Override
2053 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
2054 synchronized (mGlobalLock) {
2055 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
2056 }
2057 }
2058
2059 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002060 public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum) {
2061 return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
2062 }
2063
2064 @Override
2065 public List<ActivityManager.RunningTaskInfo> getFilteredTasks(int maxNum,
2066 @WindowConfiguration.ActivityType int ignoreActivityType,
2067 @WindowConfiguration.WindowingMode int ignoreWindowingMode) {
2068 final int callingUid = Binder.getCallingUid();
2069 ArrayList<ActivityManager.RunningTaskInfo> list = new ArrayList<>();
2070
2071 synchronized (mGlobalLock) {
2072 if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
2073
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002074 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002075 callingUid);
2076 mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
2077 ignoreWindowingMode, callingUid, allowed);
2078 }
2079
2080 return list;
2081 }
2082
2083 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002084 public final void finishSubActivity(IBinder token, String resultWho, int requestCode) {
2085 synchronized (mGlobalLock) {
2086 final long origId = Binder.clearCallingIdentity();
2087 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2088 if (r != null) {
2089 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
2090 }
2091 Binder.restoreCallingIdentity(origId);
2092 }
2093 }
2094
2095 @Override
2096 public boolean willActivityBeVisible(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002097 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002098 ActivityStack stack = ActivityRecord.getStackLocked(token);
2099 if (stack != null) {
2100 return stack.willActivityBeVisibleLocked(token);
2101 }
2102 return false;
2103 }
2104 }
2105
2106 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002107 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002108 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002109 synchronized (mGlobalLock) {
2110 final long ident = Binder.clearCallingIdentity();
2111 try {
2112 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2113 if (task == null) {
2114 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
2115 return;
2116 }
2117
2118 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
2119 + " to stackId=" + stackId + " toTop=" + toTop);
2120
2121 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2122 if (stack == null) {
2123 throw new IllegalStateException(
2124 "moveTaskToStack: No stack for stackId=" + stackId);
2125 }
2126 if (!stack.isActivityTypeStandardOrUndefined()) {
2127 throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
2128 + taskId + " to stack " + stackId);
2129 }
2130 if (stack.inSplitScreenPrimaryWindowingMode()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002131 mWindowManager.setDockedStackCreateState(
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002132 SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
2133 }
2134 task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
2135 "moveTaskToStack");
2136 } finally {
2137 Binder.restoreCallingIdentity(ident);
2138 }
2139 }
2140 }
2141
2142 @Override
2143 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
2144 boolean preserveWindows, boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002145 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002146
2147 final long ident = Binder.clearCallingIdentity();
2148 try {
2149 synchronized (mGlobalLock) {
2150 if (animate) {
2151 final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
2152 if (stack == null) {
2153 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2154 return;
2155 }
2156 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
2157 throw new IllegalArgumentException("Stack: " + stackId
2158 + " doesn't support animated resize.");
2159 }
2160 stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
2161 animationDuration, false /* fromFullscreen */);
2162 } else {
2163 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2164 if (stack == null) {
2165 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2166 return;
2167 }
2168 mStackSupervisor.resizeStackLocked(stack, destBounds,
2169 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
2170 preserveWindows, allowResizeInDockedMode, !DEFER_RESUME);
2171 }
2172 }
2173 } finally {
2174 Binder.restoreCallingIdentity(ident);
2175 }
2176 }
2177
2178 /**
2179 * Moves the specified task to the primary-split-screen stack.
2180 *
2181 * @param taskId Id of task to move.
2182 * @param createMode The mode the primary split screen stack should be created in if it doesn't
2183 * exist already. See
2184 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
2185 * and
2186 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
2187 * @param toTop If the task and stack should be moved to the top.
2188 * @param animate Whether we should play an animation for the moving the task.
2189 * @param initialBounds If the primary stack gets created, it will use these bounds for the
2190 * stack. Pass {@code null} to use default bounds.
2191 * @param showRecents If the recents activity should be shown on the other side of the task
2192 * going into split-screen mode.
2193 */
2194 @Override
2195 public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode,
2196 boolean toTop, boolean animate, Rect initialBounds, boolean showRecents) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002197 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002198 "setTaskWindowingModeSplitScreenPrimary()");
2199 synchronized (mGlobalLock) {
2200 final long ident = Binder.clearCallingIdentity();
2201 try {
2202 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2203 if (task == null) {
2204 Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
2205 return false;
2206 }
2207 if (DEBUG_STACK) Slog.d(TAG_STACK,
2208 "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
2209 + " to createMode=" + createMode + " toTop=" + toTop);
2210 if (!task.isActivityTypeStandardOrUndefined()) {
2211 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
2212 + " non-standard task " + taskId + " to split-screen windowing mode");
2213 }
2214
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002215 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002216 final int windowingMode = task.getWindowingMode();
2217 final ActivityStack stack = task.getStack();
2218 if (toTop) {
2219 stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
2220 }
2221 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
2222 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */);
2223 return windowingMode != task.getWindowingMode();
2224 } finally {
2225 Binder.restoreCallingIdentity(ident);
2226 }
2227 }
2228 }
2229
2230 /**
2231 * Removes stacks in the input windowing modes from the system if they are of activity type
2232 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
2233 */
2234 @Override
2235 public void removeStacksInWindowingModes(int[] windowingModes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002236 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002237 "removeStacksInWindowingModes()");
2238
2239 synchronized (mGlobalLock) {
2240 final long ident = Binder.clearCallingIdentity();
2241 try {
2242 mStackSupervisor.removeStacksInWindowingModes(windowingModes);
2243 } finally {
2244 Binder.restoreCallingIdentity(ident);
2245 }
2246 }
2247 }
2248
2249 @Override
2250 public void removeStacksWithActivityTypes(int[] activityTypes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002251 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002252 "removeStacksWithActivityTypes()");
2253
2254 synchronized (mGlobalLock) {
2255 final long ident = Binder.clearCallingIdentity();
2256 try {
2257 mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
2258 } finally {
2259 Binder.restoreCallingIdentity(ident);
2260 }
2261 }
2262 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002263
2264 @Override
2265 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
2266 int userId) {
2267 final int callingUid = Binder.getCallingUid();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002268 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, "getRecentTasks");
2269 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002270 callingUid);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002271 final boolean detailed = checkGetTasksPermission(
2272 android.Manifest.permission.GET_DETAILED_TASKS, Binder.getCallingPid(),
2273 UserHandle.getAppId(callingUid))
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002274 == PackageManager.PERMISSION_GRANTED;
2275
2276 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002277 return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002278 callingUid);
2279 }
2280 }
2281
2282 @Override
2283 public List<ActivityManager.StackInfo> getAllStackInfos() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002284 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002285 long ident = Binder.clearCallingIdentity();
2286 try {
2287 synchronized (mGlobalLock) {
2288 return mStackSupervisor.getAllStackInfosLocked();
2289 }
2290 } finally {
2291 Binder.restoreCallingIdentity(ident);
2292 }
2293 }
2294
2295 @Override
2296 public ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002297 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002298 long ident = Binder.clearCallingIdentity();
2299 try {
2300 synchronized (mGlobalLock) {
2301 return mStackSupervisor.getStackInfo(windowingMode, activityType);
2302 }
2303 } finally {
2304 Binder.restoreCallingIdentity(ident);
2305 }
2306 }
2307
2308 @Override
2309 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002310 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002311 final long callingUid = Binder.getCallingUid();
2312 final long origId = Binder.clearCallingIdentity();
2313 try {
2314 synchronized (mGlobalLock) {
2315 // Cancel the recents animation synchronously (do not hold the WM lock)
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002316 mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002317 ? REORDER_MOVE_TO_ORIGINAL_POSITION
2318 : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
2319 }
2320 } finally {
2321 Binder.restoreCallingIdentity(origId);
2322 }
2323 }
2324
2325 @Override
2326 public void startLockTaskModeByToken(IBinder token) {
2327 synchronized (mGlobalLock) {
2328 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2329 if (r == null) {
2330 return;
2331 }
2332 startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
2333 }
2334 }
2335
2336 @Override
2337 public void startSystemLockTaskMode(int taskId) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002338 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002339 // This makes inner call to look as if it was initiated by system.
2340 long ident = Binder.clearCallingIdentity();
2341 try {
2342 synchronized (mGlobalLock) {
2343 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2344
2345 // When starting lock task mode the stack must be in front and focused
2346 task.getStack().moveToFront("startSystemLockTaskMode");
2347 startLockTaskModeLocked(task, true /* isSystemCaller */);
2348 }
2349 } finally {
2350 Binder.restoreCallingIdentity(ident);
2351 }
2352 }
2353
2354 @Override
2355 public void stopLockTaskModeByToken(IBinder token) {
2356 synchronized (mGlobalLock) {
2357 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2358 if (r == null) {
2359 return;
2360 }
2361 stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
2362 }
2363 }
2364
2365 /**
2366 * This API should be called by SystemUI only when user perform certain action to dismiss
2367 * lock task mode. We should only dismiss pinned lock task mode in this case.
2368 */
2369 @Override
2370 public void stopSystemLockTaskMode() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002371 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002372 stopLockTaskModeInternal(null, true /* isSystemCaller */);
2373 }
2374
2375 private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
2376 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
2377 if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
2378 return;
2379 }
2380
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002381 final ActivityStack stack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002382 if (stack == null || task != stack.topTask()) {
2383 throw new IllegalArgumentException("Invalid task, not in foreground");
2384 }
2385
2386 // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
2387 // system or a specific app.
2388 // * System-initiated requests will only start the pinned mode (screen pinning)
2389 // * App-initiated requests
2390 // - will put the device in fully locked mode (LockTask), if the app is whitelisted
2391 // - will start the pinned mode, otherwise
2392 final int callingUid = Binder.getCallingUid();
2393 long ident = Binder.clearCallingIdentity();
2394 try {
2395 // When a task is locked, dismiss the pinned stack if it exists
2396 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2397
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002398 getLockTaskController().startLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002399 } finally {
2400 Binder.restoreCallingIdentity(ident);
2401 }
2402 }
2403
2404 private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
2405 final int callingUid = Binder.getCallingUid();
2406 long ident = Binder.clearCallingIdentity();
2407 try {
2408 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002409 getLockTaskController().stopLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002410 }
2411 // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
2412 // task and jumping straight into a call in the case of emergency call back.
2413 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
2414 if (tm != null) {
2415 tm.showInCallScreen(false);
2416 }
2417 } finally {
2418 Binder.restoreCallingIdentity(ident);
2419 }
2420 }
2421
2422 @Override
2423 public boolean isInLockTaskMode() {
2424 return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
2425 }
2426
2427 @Override
2428 public int getLockTaskModeState() {
2429 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002430 return getLockTaskController().getLockTaskModeState();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002431 }
2432 }
2433
2434 @Override
2435 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
2436 synchronized (mGlobalLock) {
2437 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2438 if (r != null) {
2439 r.setTaskDescription(td);
2440 final TaskRecord task = r.getTask();
2441 task.updateTaskDescription();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002442 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002443 }
2444 }
2445 }
2446
2447 @Override
2448 public Bundle getActivityOptions(IBinder token) {
2449 final long origId = Binder.clearCallingIdentity();
2450 try {
2451 synchronized (mGlobalLock) {
2452 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
2453 if (r != null) {
2454 final ActivityOptions activityOptions = r.takeOptionsLocked();
2455 return activityOptions == null ? null : activityOptions.toBundle();
2456 }
2457 return null;
2458 }
2459 } finally {
2460 Binder.restoreCallingIdentity(origId);
2461 }
2462 }
2463
2464 @Override
2465 public List<IBinder> getAppTasks(String callingPackage) {
2466 int callingUid = Binder.getCallingUid();
2467 long ident = Binder.clearCallingIdentity();
2468 try {
2469 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002470 return mRecentTasks.getAppTasksList(callingUid, callingPackage);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002471 }
2472 } finally {
2473 Binder.restoreCallingIdentity(ident);
2474 }
2475 }
2476
2477 @Override
2478 public void finishVoiceTask(IVoiceInteractionSession session) {
2479 synchronized (mGlobalLock) {
2480 final long origId = Binder.clearCallingIdentity();
2481 try {
2482 // TODO: VI Consider treating local voice interactions and voice tasks
2483 // differently here
2484 mStackSupervisor.finishVoiceTask(session);
2485 } finally {
2486 Binder.restoreCallingIdentity(origId);
2487 }
2488 }
2489
2490 }
2491
2492 @Override
2493 public boolean isTopOfTask(IBinder token) {
2494 synchronized (mGlobalLock) {
2495 ActivityRecord r = ActivityRecord.isInStackLocked(token);
Riddle Hsu66b74a82018-07-26 00:20:12 +08002496 return r != null && r.getTask().getTopActivity() == r;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002497 }
2498 }
2499
2500 @Override
2501 public void notifyLaunchTaskBehindComplete(IBinder token) {
2502 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
2503 }
2504
2505 @Override
2506 public void notifyEnterAnimationComplete(IBinder token) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002507 mH.post(() -> {
2508 synchronized (mGlobalLock) {
2509 ActivityRecord r = ActivityRecord.forTokenLocked(token);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002510 if (r != null && r.attachedToProcess()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002511 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002512 r.app.getThread().scheduleEnterAnimationComplete(r.appToken);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002513 } catch (RemoteException e) {
2514 }
2515 }
2516 }
2517
2518 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002519 }
2520
2521 /** Called from an app when assist data is ready. */
2522 @Override
2523 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
2524 AssistContent content, Uri referrer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002525 PendingAssistExtras pae = (PendingAssistExtras) token;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002526 synchronized (pae) {
2527 pae.result = extras;
2528 pae.structure = structure;
2529 pae.content = content;
2530 if (referrer != null) {
2531 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
2532 }
2533 if (structure != null) {
2534 structure.setHomeActivity(pae.isHome);
2535 }
2536 pae.haveResult = true;
2537 pae.notifyAll();
2538 if (pae.intent == null && pae.receiver == null) {
2539 // Caller is just waiting for the result.
2540 return;
2541 }
2542 }
2543 // We are now ready to launch the assist activity.
2544 IAssistDataReceiver sendReceiver = null;
2545 Bundle sendBundle = null;
2546 synchronized (mGlobalLock) {
2547 buildAssistBundleLocked(pae, extras);
2548 boolean exists = mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002549 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002550 if (!exists) {
2551 // Timed out.
2552 return;
2553 }
2554
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002555 if ((sendReceiver = pae.receiver) != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002556 // Caller wants result sent back to them.
2557 sendBundle = new Bundle();
2558 sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
2559 sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
2560 sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
2561 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
2562 }
2563 }
2564 if (sendReceiver != null) {
2565 try {
2566 sendReceiver.onHandleAssistData(sendBundle);
2567 } catch (RemoteException e) {
2568 }
2569 return;
2570 }
2571
2572 final long ident = Binder.clearCallingIdentity();
2573 try {
2574 if (TextUtils.equals(pae.intent.getAction(),
2575 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
2576 pae.intent.putExtras(pae.extras);
2577 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
2578 } else {
2579 pae.intent.replaceExtras(pae.extras);
2580 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
2581 | Intent.FLAG_ACTIVITY_SINGLE_TOP
2582 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002583 mAmInternal.closeSystemDialogs("assist");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002584
2585 try {
2586 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
2587 } catch (ActivityNotFoundException e) {
2588 Slog.w(TAG, "No activity to handle assist action.", e);
2589 }
2590 }
2591 } finally {
2592 Binder.restoreCallingIdentity(ident);
2593 }
2594 }
2595
2596 @Override
2597 public int addAppTask(IBinder activityToken, Intent intent,
2598 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
2599 final int callingUid = Binder.getCallingUid();
2600 final long callingIdent = Binder.clearCallingIdentity();
2601
2602 try {
2603 synchronized (mGlobalLock) {
2604 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
2605 if (r == null) {
2606 throw new IllegalArgumentException("Activity does not exist; token="
2607 + activityToken);
2608 }
2609 ComponentName comp = intent.getComponent();
2610 if (comp == null) {
2611 throw new IllegalArgumentException("Intent " + intent
2612 + " must specify explicit component");
2613 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002614 if (thumbnail.getWidth() != mThumbnailWidth
2615 || thumbnail.getHeight() != mThumbnailHeight) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002616 throw new IllegalArgumentException("Bad thumbnail size: got "
2617 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002618 + mThumbnailWidth + "x" + mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002619 }
2620 if (intent.getSelector() != null) {
2621 intent.setSelector(null);
2622 }
2623 if (intent.getSourceBounds() != null) {
2624 intent.setSourceBounds(null);
2625 }
2626 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
2627 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
2628 // The caller has added this as an auto-remove task... that makes no
2629 // sense, so turn off auto-remove.
2630 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
2631 }
2632 }
2633 final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
2634 STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
2635 if (ainfo.applicationInfo.uid != callingUid) {
2636 throw new SecurityException(
2637 "Can't add task for another application: target uid="
2638 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
2639 }
2640
2641 final ActivityStack stack = r.getStack();
2642 final TaskRecord task = stack.createTaskRecord(
2643 mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent,
2644 null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002645 if (!mRecentTasks.addToBottom(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002646 // The app has too many tasks already and we can't add any more
2647 stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
2648 return INVALID_TASK_ID;
2649 }
2650 task.lastTaskDescription.copyFrom(description);
2651
2652 // TODO: Send the thumbnail to WM to store it.
2653
2654 return task.taskId;
2655 }
2656 } finally {
2657 Binder.restoreCallingIdentity(callingIdent);
2658 }
2659 }
2660
2661 @Override
2662 public Point getAppTaskThumbnailSize() {
2663 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002664 return new Point(mThumbnailWidth, mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002665 }
2666 }
2667
2668 @Override
2669 public void setTaskResizeable(int taskId, int resizeableMode) {
2670 synchronized (mGlobalLock) {
2671 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
2672 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
2673 if (task == null) {
2674 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
2675 return;
2676 }
2677 task.setResizeMode(resizeableMode);
2678 }
2679 }
2680
2681 @Override
2682 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002683 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002684 long ident = Binder.clearCallingIdentity();
2685 try {
2686 synchronized (mGlobalLock) {
2687 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2688 if (task == null) {
2689 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
2690 return;
2691 }
2692 // Place the task in the right stack if it isn't there already based on
2693 // the requested bounds.
2694 // The stack transition logic is:
2695 // - a null bounds on a freeform task moves that task to fullscreen
2696 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
2697 // that task to freeform
2698 // - otherwise the task is not moved
2699 ActivityStack stack = task.getStack();
2700 if (!task.getWindowConfiguration().canResizeTask()) {
2701 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
2702 }
2703 if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
2704 stack = stack.getDisplay().getOrCreateStack(
2705 WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
2706 } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
2707 stack = stack.getDisplay().getOrCreateStack(
2708 WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
2709 }
2710
2711 // Reparent the task to the right stack if necessary
2712 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
2713 if (stack != task.getStack()) {
2714 // Defer resume until the task is resized below
2715 task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
2716 DEFER_RESUME, "resizeTask");
2717 preserveWindow = false;
2718 }
2719
2720 // After reparenting (which only resizes the task to the stack bounds), resize the
2721 // task to the actual bounds provided
2722 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
2723 }
2724 } finally {
2725 Binder.restoreCallingIdentity(ident);
2726 }
2727 }
2728
2729 @Override
2730 public boolean releaseActivityInstance(IBinder token) {
2731 synchronized (mGlobalLock) {
2732 final long origId = Binder.clearCallingIdentity();
2733 try {
2734 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2735 if (r == null) {
2736 return false;
2737 }
2738 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
2739 } finally {
2740 Binder.restoreCallingIdentity(origId);
2741 }
2742 }
2743 }
2744
2745 @Override
2746 public void releaseSomeActivities(IApplicationThread appInt) {
2747 synchronized (mGlobalLock) {
2748 final long origId = Binder.clearCallingIdentity();
2749 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002750 WindowProcessController app =
2751 mAm.getRecordForAppLocked(appInt).getWindowProcessController();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002752 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
2753 } finally {
2754 Binder.restoreCallingIdentity(origId);
2755 }
2756 }
2757 }
2758
2759 @Override
2760 public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
2761 int secondaryDisplayShowing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002762 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002763 != PackageManager.PERMISSION_GRANTED) {
2764 throw new SecurityException("Requires permission "
2765 + android.Manifest.permission.DEVICE_POWER);
2766 }
2767
2768 synchronized (mGlobalLock) {
2769 long ident = Binder.clearCallingIdentity();
2770 if (mKeyguardShown != keyguardShowing) {
2771 mKeyguardShown = keyguardShowing;
2772 reportCurKeyguardUsageEventLocked(keyguardShowing);
2773 }
2774 try {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002775 mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002776 secondaryDisplayShowing);
2777 } finally {
2778 Binder.restoreCallingIdentity(ident);
2779 }
2780 }
2781
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002782 mH.post(() -> {
2783 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2784 mScreenObservers.get(i).onKeyguardStateChanged(keyguardShowing);
2785 }
2786 });
2787 }
2788
2789 void onScreenAwakeChanged(boolean isAwake) {
2790 mH.post(() -> {
2791 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2792 mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2793 }
2794 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002795 }
2796
2797 @Override
2798 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002799 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
2800 userId, "getTaskDescriptionIcon");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002801
2802 final File passedIconFile = new File(filePath);
2803 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
2804 passedIconFile.getName());
2805 if (!legitIconFile.getPath().equals(filePath)
2806 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
2807 throw new IllegalArgumentException("Bad file path: " + filePath
2808 + " passed for userId " + userId);
2809 }
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002810 return mRecentTasks.getTaskDescriptionIcon(filePath);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002811 }
2812
2813 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002814 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002815 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
2816 final ActivityOptions activityOptions = safeOptions != null
2817 ? safeOptions.getOptions(mStackSupervisor)
2818 : null;
2819 if (activityOptions == null
2820 || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
2821 || activityOptions.getCustomInPlaceResId() == 0) {
2822 throw new IllegalArgumentException("Expected in-place ActivityOption " +
2823 "with valid animation");
2824 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002825 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
2826 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002827 activityOptions.getCustomInPlaceResId());
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002828 mWindowManager.executeAppTransition();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002829 }
2830
2831 @Override
2832 public void removeStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002833 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002834 synchronized (mGlobalLock) {
2835 final long ident = Binder.clearCallingIdentity();
2836 try {
2837 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2838 if (stack == null) {
2839 Slog.w(TAG, "removeStack: No stack with id=" + stackId);
2840 return;
2841 }
2842 if (!stack.isActivityTypeStandardOrUndefined()) {
2843 throw new IllegalArgumentException(
2844 "Removing non-standard stack is not allowed.");
2845 }
2846 mStackSupervisor.removeStack(stack);
2847 } finally {
2848 Binder.restoreCallingIdentity(ident);
2849 }
2850 }
2851 }
2852
2853 @Override
2854 public void moveStackToDisplay(int stackId, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002855 mAmInternal.enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002856
2857 synchronized (mGlobalLock) {
2858 final long ident = Binder.clearCallingIdentity();
2859 try {
2860 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
2861 + " to displayId=" + displayId);
2862 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
2863 } finally {
2864 Binder.restoreCallingIdentity(ident);
2865 }
2866 }
2867 }
2868
2869 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002870 public void exitFreeformMode(IBinder token) {
2871 synchronized (mGlobalLock) {
2872 long ident = Binder.clearCallingIdentity();
2873 try {
2874 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2875 if (r == null) {
2876 throw new IllegalArgumentException(
2877 "exitFreeformMode: No activity record matching token=" + token);
2878 }
2879
2880 final ActivityStack stack = r.getStack();
2881 if (stack == null || !stack.inFreeformWindowingMode()) {
2882 throw new IllegalStateException(
2883 "exitFreeformMode: You can only go fullscreen from freeform.");
2884 }
2885
2886 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
2887 } finally {
2888 Binder.restoreCallingIdentity(ident);
2889 }
2890 }
2891 }
2892
2893 /** Sets the task stack listener that gets callbacks when a task stack changes. */
2894 @Override
2895 public void registerTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002896 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002897 "registerTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002898 mTaskChangeNotificationController.registerTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002899 }
2900
2901 /** Unregister a task stack listener so that it stops receiving callbacks. */
2902 @Override
2903 public void unregisterTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002904 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002905 "unregisterTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002906 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002907 }
2908
2909 private void reportCurKeyguardUsageEventLocked(boolean keyguardShowing) {
2910 mAm.reportGlobalUsageEventLocked(keyguardShowing
2911 ? UsageEvents.Event.KEYGUARD_SHOWN
2912 : UsageEvents.Event.KEYGUARD_HIDDEN);
2913 }
2914
2915 @Override
2916 public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
2917 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
2918 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
2919 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
2920 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
2921 }
2922
2923 @Override
2924 public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
2925 IBinder activityToken, int flags) {
2926 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
2927 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
2928 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
2929 }
2930
2931 @Override
2932 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
2933 Bundle args) {
2934 return enqueueAssistContext(requestType, intent, hint, null, null, null,
2935 true /* focused */, true /* newSessionId */, userHandle, args,
2936 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
2937 }
2938
2939 @Override
2940 public Bundle getAssistContextExtras(int requestType) {
2941 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
2942 null, null, true /* focused */, true /* newSessionId */,
2943 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
2944 if (pae == null) {
2945 return null;
2946 }
2947 synchronized (pae) {
2948 while (!pae.haveResult) {
2949 try {
2950 pae.wait();
2951 } catch (InterruptedException e) {
2952 }
2953 }
2954 }
2955 synchronized (mGlobalLock) {
2956 buildAssistBundleLocked(pae, pae.result);
2957 mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002958 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002959 }
2960 return pae.extras;
2961 }
2962
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002963 /**
2964 * Binder IPC calls go through the public entry point.
2965 * This can be called with or without the global lock held.
2966 */
2967 private static int checkCallingPermission(String permission) {
2968 return checkPermission(
2969 permission, Binder.getCallingPid(), UserHandle.getAppId(Binder.getCallingUid()));
2970 }
2971
2972 /** This can be called with or without the global lock held. */
2973 void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
2974 if (!getRecentTasks().isCallerRecents(Binder.getCallingUid())) {
2975 mAmInternal.enforceCallingPermission(permission, func);
2976 }
2977 }
2978
2979 @VisibleForTesting
2980 int checkGetTasksPermission(String permission, int pid, int uid) {
2981 return checkPermission(permission, pid, uid);
2982 }
2983
2984 static int checkPermission(String permission, int pid, int uid) {
2985 if (permission == null) {
2986 return PackageManager.PERMISSION_DENIED;
2987 }
2988 return checkComponentPermission(permission, pid, uid, -1, true);
2989 }
2990
2991 boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
2992 if (getRecentTasks().isCallerRecents(callingUid)) {
2993 // Always allow the recents component to get tasks
2994 return true;
2995 }
2996
2997 boolean allowed = checkGetTasksPermission(android.Manifest.permission.REAL_GET_TASKS,
2998 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
2999 if (!allowed) {
3000 if (checkGetTasksPermission(android.Manifest.permission.GET_TASKS,
3001 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
3002 // Temporary compatibility: some existing apps on the system image may
3003 // still be requesting the old permission and not switched to the new
3004 // one; if so, we'll still allow them full access. This means we need
3005 // to see if they are holding the old permission and are a system app.
3006 try {
3007 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
3008 allowed = true;
3009 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
3010 + " is using old GET_TASKS but privileged; allowing");
3011 }
3012 } catch (RemoteException e) {
3013 }
3014 }
3015 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
3016 + " does not hold REAL_GET_TASKS; limiting output");
3017 }
3018 return allowed;
3019 }
3020
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003021 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
3022 IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
3023 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
3024 int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003025 mAmInternal.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003026 "enqueueAssistContext()");
3027
3028 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003029 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003030 if (activity == null) {
3031 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
3032 return null;
3033 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003034 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003035 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
3036 return null;
3037 }
3038 if (focused) {
3039 if (activityToken != null) {
3040 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
3041 if (activity != caller) {
3042 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
3043 + " is not current top " + activity);
3044 return null;
3045 }
3046 }
3047 } else {
3048 activity = ActivityRecord.forTokenLocked(activityToken);
3049 if (activity == null) {
3050 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
3051 + " couldn't be found");
3052 return null;
3053 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003054 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003055 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
3056 return null;
3057 }
3058 }
3059
3060 PendingAssistExtras pae;
3061 Bundle extras = new Bundle();
3062 if (args != null) {
3063 extras.putAll(args);
3064 }
3065 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003066 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003067
3068 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
3069 userHandle);
3070 pae.isHome = activity.isActivityTypeHome();
3071
3072 // Increment the sessionId if necessary
3073 if (newSessionId) {
3074 mViSessionId++;
3075 }
3076 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003077 activity.app.getThread().requestAssistContextExtras(activity.appToken, pae,
3078 requestType, mViSessionId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003079 mPendingAssistExtras.add(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003080 mUiHandler.postDelayed(pae, timeout);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003081 } catch (RemoteException e) {
3082 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
3083 return null;
3084 }
3085 return pae;
3086 }
3087 }
3088
3089 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
3090 if (result != null) {
3091 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
3092 }
3093 if (pae.hint != null) {
3094 pae.extras.putBoolean(pae.hint, true);
3095 }
3096 }
3097
3098 private void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
3099 IAssistDataReceiver receiver;
3100 synchronized (mGlobalLock) {
3101 mPendingAssistExtras.remove(pae);
3102 receiver = pae.receiver;
3103 }
3104 if (receiver != null) {
3105 // Caller wants result sent back to them.
3106 Bundle sendBundle = new Bundle();
3107 // At least return the receiver extras
3108 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
3109 try {
3110 pae.receiver.onHandleAssistData(sendBundle);
3111 } catch (RemoteException e) {
3112 }
3113 }
3114 }
3115
3116 public class PendingAssistExtras extends Binder implements Runnable {
3117 public final ActivityRecord activity;
3118 public boolean isHome;
3119 public final Bundle extras;
3120 public final Intent intent;
3121 public final String hint;
3122 public final IAssistDataReceiver receiver;
3123 public final int userHandle;
3124 public boolean haveResult = false;
3125 public Bundle result = null;
3126 public AssistStructure structure = null;
3127 public AssistContent content = null;
3128 public Bundle receiverExtras;
3129
3130 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
3131 String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
3132 int _userHandle) {
3133 activity = _activity;
3134 extras = _extras;
3135 intent = _intent;
3136 hint = _hint;
3137 receiver = _receiver;
3138 receiverExtras = _receiverExtras;
3139 userHandle = _userHandle;
3140 }
3141
3142 @Override
3143 public void run() {
3144 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
3145 synchronized (this) {
3146 haveResult = true;
3147 notifyAll();
3148 }
3149 pendingAssistExtrasTimedOut(this);
3150 }
3151 }
3152
3153 @Override
3154 public boolean isAssistDataAllowedOnCurrentActivity() {
3155 int userId;
3156 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003157 final ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003158 if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
3159 return false;
3160 }
3161
3162 final ActivityRecord activity = focusedStack.getTopActivity();
3163 if (activity == null) {
3164 return false;
3165 }
3166 userId = activity.userId;
3167 }
3168 return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
3169 }
3170
3171 @Override
3172 public boolean showAssistFromActivity(IBinder token, Bundle args) {
3173 long ident = Binder.clearCallingIdentity();
3174 try {
3175 synchronized (mGlobalLock) {
3176 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003177 ActivityRecord top = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003178 if (top != caller) {
3179 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3180 + " is not current top " + top);
3181 return false;
3182 }
3183 if (!top.nowVisible) {
3184 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3185 + " is not visible");
3186 return false;
3187 }
3188 }
3189 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
3190 token);
3191 } finally {
3192 Binder.restoreCallingIdentity(ident);
3193 }
3194 }
3195
3196 @Override
3197 public boolean isRootVoiceInteraction(IBinder token) {
3198 synchronized (mGlobalLock) {
3199 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3200 if (r == null) {
3201 return false;
3202 }
3203 return r.rootVoiceInteraction;
3204 }
3205 }
3206
Wale Ogunwalef6733932018-06-27 05:14:34 -07003207 private void onLocalVoiceInteractionStartedLocked(IBinder activity,
3208 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
3209 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
3210 if (activityToCallback == null) return;
3211 activityToCallback.setVoiceSessionLocked(voiceSession);
3212
3213 // Inform the activity
3214 try {
3215 activityToCallback.app.getThread().scheduleLocalVoiceInteractionStarted(activity,
3216 voiceInteractor);
3217 long token = Binder.clearCallingIdentity();
3218 try {
3219 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
3220 } finally {
3221 Binder.restoreCallingIdentity(token);
3222 }
3223 // TODO: VI Should we cache the activity so that it's easier to find later
3224 // rather than scan through all the stacks and activities?
3225 } catch (RemoteException re) {
3226 activityToCallback.clearVoiceSessionLocked();
3227 // TODO: VI Should this terminate the voice session?
3228 }
3229 }
3230
3231 private void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
3232 Slog.d(TAG, "<<< startRunningVoiceLocked()");
3233 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
3234 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
3235 boolean wasRunningVoice = mRunningVoice != null;
3236 mRunningVoice = session;
3237 if (!wasRunningVoice) {
3238 mVoiceWakeLock.acquire();
3239 updateSleepIfNeededLocked();
3240 }
3241 }
3242 }
3243
3244 void finishRunningVoiceLocked() {
3245 if (mRunningVoice != null) {
3246 mRunningVoice = null;
3247 mVoiceWakeLock.release();
3248 updateSleepIfNeededLocked();
3249 }
3250 }
3251
3252 @Override
3253 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3254 synchronized (mGlobalLock) {
3255 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3256 if (keepAwake) {
3257 mVoiceWakeLock.acquire();
3258 } else {
3259 mVoiceWakeLock.release();
3260 }
3261 }
3262 }
3263 }
3264
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003265 @Override
3266 public ComponentName getActivityClassForToken(IBinder token) {
3267 synchronized (mGlobalLock) {
3268 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3269 if (r == null) {
3270 return null;
3271 }
3272 return r.intent.getComponent();
3273 }
3274 }
3275
3276 @Override
3277 public String getPackageForToken(IBinder token) {
3278 synchronized (mGlobalLock) {
3279 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3280 if (r == null) {
3281 return null;
3282 }
3283 return r.packageName;
3284 }
3285 }
3286
3287 @Override
3288 public void showLockTaskEscapeMessage(IBinder token) {
3289 synchronized (mGlobalLock) {
3290 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3291 if (r == null) {
3292 return;
3293 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003294 getLockTaskController().showLockTaskToast();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003295 }
3296 }
3297
3298 @Override
3299 public void keyguardGoingAway(int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003300 enforceNotIsolatedCaller("keyguardGoingAway");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003301 final long token = Binder.clearCallingIdentity();
3302 try {
3303 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003304 mKeyguardController.keyguardGoingAway(flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003305 }
3306 } finally {
3307 Binder.restoreCallingIdentity(token);
3308 }
3309 }
3310
3311 /**
3312 * Try to place task to provided position. The final position might be different depending on
3313 * current user and stacks state. The task will be moved to target stack if it's currently in
3314 * different stack.
3315 */
3316 @Override
3317 public void positionTaskInStack(int taskId, int stackId, int position) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003318 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003319 synchronized (mGlobalLock) {
3320 long ident = Binder.clearCallingIdentity();
3321 try {
3322 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
3323 + taskId + " in stackId=" + stackId + " at position=" + position);
3324 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3325 if (task == null) {
3326 throw new IllegalArgumentException("positionTaskInStack: no task for id="
3327 + taskId);
3328 }
3329
3330 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3331
3332 if (stack == null) {
3333 throw new IllegalArgumentException("positionTaskInStack: no stack for id="
3334 + stackId);
3335 }
3336 if (!stack.isActivityTypeStandardOrUndefined()) {
3337 throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
3338 + " the position of task " + taskId + " in/to non-standard stack");
3339 }
3340
3341 // TODO: Have the callers of this API call a separate reparent method if that is
3342 // what they intended to do vs. having this method also do reparenting.
3343 if (task.getStack() == stack) {
3344 // Change position in current stack.
3345 stack.positionChildAt(task, position);
3346 } else {
3347 // Reparent to new stack.
3348 task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
3349 !DEFER_RESUME, "positionTaskInStack");
3350 }
3351 } finally {
3352 Binder.restoreCallingIdentity(ident);
3353 }
3354 }
3355 }
3356
3357 @Override
3358 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
3359 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
3360 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
3361 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
3362 synchronized (mGlobalLock) {
3363 ActivityRecord record = ActivityRecord.isInStackLocked(token);
3364 if (record == null) {
3365 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
3366 + "found for: " + token);
3367 }
3368 record.setSizeConfigurations(horizontalSizeConfiguration,
3369 verticalSizeConfigurations, smallestSizeConfigurations);
3370 }
3371 }
3372
3373 /**
3374 * Dismisses split-screen multi-window mode.
3375 * @param toTop If true the current primary split-screen stack will be placed or left on top.
3376 */
3377 @Override
3378 public void dismissSplitScreenMode(boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003379 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003380 MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
3381 final long ident = Binder.clearCallingIdentity();
3382 try {
3383 synchronized (mGlobalLock) {
3384 final ActivityStack stack =
3385 mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
3386 if (stack == null) {
3387 Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
3388 return;
3389 }
3390
3391 if (toTop) {
3392 // Caller wants the current split-screen primary stack to be the top stack after
3393 // it goes fullscreen, so move it to the front.
3394 stack.moveToFront("dismissSplitScreenMode");
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003395 } else if (mStackSupervisor.isTopDisplayFocusedStack(stack)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003396 // In this case the current split-screen primary stack shouldn't be the top
3397 // stack after it goes fullscreen, but it current has focus, so we move the
3398 // focus to the top-most split-screen secondary stack next to it.
3399 final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
3400 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
3401 if (otherStack != null) {
3402 otherStack.moveToFront("dismissSplitScreenMode_other");
3403 }
3404 }
3405
Evan Rosky10475742018-09-05 19:02:48 -07003406 stack.setWindowingMode(WINDOWING_MODE_UNDEFINED);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003407 }
3408 } finally {
3409 Binder.restoreCallingIdentity(ident);
3410 }
3411 }
3412
3413 /**
3414 * Dismisses Pip
3415 * @param animate True if the dismissal should be animated.
3416 * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
3417 * default animation duration should be used.
3418 */
3419 @Override
3420 public void dismissPip(boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003421 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003422 final long ident = Binder.clearCallingIdentity();
3423 try {
3424 synchronized (mGlobalLock) {
3425 final PinnedActivityStack stack =
3426 mStackSupervisor.getDefaultDisplay().getPinnedStack();
3427 if (stack == null) {
3428 Slog.w(TAG, "dismissPip: pinned stack not found.");
3429 return;
3430 }
3431 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
3432 throw new IllegalArgumentException("Stack: " + stack
3433 + " doesn't support animated resize.");
3434 }
3435 if (animate) {
3436 stack.animateResizePinnedStack(null /* sourceHintBounds */,
3437 null /* destBounds */, animationDuration, false /* fromFullscreen */);
3438 } else {
3439 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
3440 }
3441 }
3442 } finally {
3443 Binder.restoreCallingIdentity(ident);
3444 }
3445 }
3446
3447 @Override
3448 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003449 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003450 synchronized (mGlobalLock) {
3451 mSuppressResizeConfigChanges = suppress;
3452 }
3453 }
3454
3455 /**
3456 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
3457 * animated the stack to the fullscreen, but can also be called if we are relaunching an
3458 * activity and clearing the task at the same time.
3459 */
3460 @Override
3461 // TODO: API should just be about changing windowing modes...
3462 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003463 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003464 "moveTasksToFullscreenStack()");
3465 synchronized (mGlobalLock) {
3466 final long origId = Binder.clearCallingIdentity();
3467 try {
3468 final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
3469 if (stack != null){
3470 if (!stack.isActivityTypeStandardOrUndefined()) {
3471 throw new IllegalArgumentException(
3472 "You can't move tasks from non-standard stacks.");
3473 }
3474 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
3475 }
3476 } finally {
3477 Binder.restoreCallingIdentity(origId);
3478 }
3479 }
3480 }
3481
3482 /**
3483 * Moves the top activity in the input stackId to the pinned stack.
3484 *
3485 * @param stackId Id of stack to move the top activity to pinned stack.
3486 * @param bounds Bounds to use for pinned stack.
3487 *
3488 * @return True if the top activity of the input stack was successfully moved to the pinned
3489 * stack.
3490 */
3491 @Override
3492 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003493 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003494 "moveTopActivityToPinnedStack()");
3495 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003496 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003497 throw new IllegalStateException("moveTopActivityToPinnedStack:"
3498 + "Device doesn't support picture-in-picture mode");
3499 }
3500
3501 long ident = Binder.clearCallingIdentity();
3502 try {
3503 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
3504 } finally {
3505 Binder.restoreCallingIdentity(ident);
3506 }
3507 }
3508 }
3509
3510 @Override
3511 public boolean isInMultiWindowMode(IBinder token) {
3512 final long origId = Binder.clearCallingIdentity();
3513 try {
3514 synchronized (mGlobalLock) {
3515 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3516 if (r == null) {
3517 return false;
3518 }
3519 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
3520 return r.inMultiWindowMode();
3521 }
3522 } finally {
3523 Binder.restoreCallingIdentity(origId);
3524 }
3525 }
3526
3527 @Override
3528 public boolean isInPictureInPictureMode(IBinder token) {
3529 final long origId = Binder.clearCallingIdentity();
3530 try {
3531 synchronized (mGlobalLock) {
3532 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
3533 }
3534 } finally {
3535 Binder.restoreCallingIdentity(origId);
3536 }
3537 }
3538
3539 private boolean isInPictureInPictureMode(ActivityRecord r) {
3540 if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
3541 || r.getStack().isInStackLocked(r) == null) {
3542 return false;
3543 }
3544
3545 // If we are animating to fullscreen then we have already dispatched the PIP mode
3546 // changed, so we should reflect that check here as well.
3547 final PinnedActivityStack stack = r.getStack();
3548 final PinnedStackWindowController windowController = stack.getWindowContainerController();
3549 return !windowController.isAnimatingBoundsToFullscreen();
3550 }
3551
3552 @Override
3553 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
3554 final long origId = Binder.clearCallingIdentity();
3555 try {
3556 synchronized (mGlobalLock) {
3557 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3558 "enterPictureInPictureMode", token, params);
3559
3560 // If the activity is already in picture in picture mode, then just return early
3561 if (isInPictureInPictureMode(r)) {
3562 return true;
3563 }
3564
3565 // Activity supports picture-in-picture, now check that we can enter PiP at this
3566 // point, if it is
3567 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
3568 false /* beforeStopping */)) {
3569 return false;
3570 }
3571
3572 final Runnable enterPipRunnable = () -> {
Wale Ogunwalef276a6f2018-06-15 08:26:07 -07003573 synchronized (mGlobalLock) {
3574 // Only update the saved args from the args that are set
3575 r.pictureInPictureArgs.copyOnlySet(params);
3576 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
3577 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
3578 // Adjust the source bounds by the insets for the transition down
3579 final Rect sourceBounds = new Rect(
3580 r.pictureInPictureArgs.getSourceRectHint());
3581 mStackSupervisor.moveActivityToPinnedStackLocked(
3582 r, sourceBounds, aspectRatio, "enterPictureInPictureMode");
3583 final PinnedActivityStack stack = r.getStack();
3584 stack.setPictureInPictureAspectRatio(aspectRatio);
3585 stack.setPictureInPictureActions(actions);
3586 MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
3587 r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
3588 logPictureInPictureArgs(params);
3589 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003590 };
3591
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003592 if (isKeyguardLocked()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003593 // If the keyguard is showing or occluded, then try and dismiss it before
3594 // entering picture-in-picture (this will prompt the user to authenticate if the
3595 // device is currently locked).
3596 dismissKeyguard(token, new KeyguardDismissCallback() {
3597 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003598 public void onDismissSucceeded() {
3599 mH.post(enterPipRunnable);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003600 }
3601 }, null /* message */);
3602 } else {
3603 // Enter picture in picture immediately otherwise
3604 enterPipRunnable.run();
3605 }
3606 return true;
3607 }
3608 } finally {
3609 Binder.restoreCallingIdentity(origId);
3610 }
3611 }
3612
3613 @Override
3614 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
3615 final long origId = Binder.clearCallingIdentity();
3616 try {
3617 synchronized (mGlobalLock) {
3618 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3619 "setPictureInPictureParams", token, params);
3620
3621 // Only update the saved args from the args that are set
3622 r.pictureInPictureArgs.copyOnlySet(params);
3623 if (r.inPinnedWindowingMode()) {
3624 // If the activity is already in picture-in-picture, update the pinned stack now
3625 // if it is not already expanding to fullscreen. Otherwise, the arguments will
3626 // be used the next time the activity enters PiP
3627 final PinnedActivityStack stack = r.getStack();
3628 if (!stack.isAnimatingBoundsToFullscreen()) {
3629 stack.setPictureInPictureAspectRatio(
3630 r.pictureInPictureArgs.getAspectRatio());
3631 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
3632 }
3633 }
3634 logPictureInPictureArgs(params);
3635 }
3636 } finally {
3637 Binder.restoreCallingIdentity(origId);
3638 }
3639 }
3640
3641 @Override
3642 public int getMaxNumPictureInPictureActions(IBinder token) {
3643 // Currently, this is a static constant, but later, we may change this to be dependent on
3644 // the context of the activity
3645 return 3;
3646 }
3647
3648 private void logPictureInPictureArgs(PictureInPictureParams params) {
3649 if (params.hasSetActions()) {
3650 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
3651 params.getActions().size());
3652 }
3653 if (params.hasSetAspectRatio()) {
3654 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
3655 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
3656 MetricsLogger.action(lm);
3657 }
3658 }
3659
3660 /**
3661 * Checks the state of the system and the activity associated with the given {@param token} to
3662 * verify that picture-in-picture is supported for that activity.
3663 *
3664 * @return the activity record for the given {@param token} if all the checks pass.
3665 */
3666 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
3667 IBinder token, PictureInPictureParams params) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003668 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003669 throw new IllegalStateException(caller
3670 + ": Device doesn't support picture-in-picture mode.");
3671 }
3672
3673 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3674 if (r == null) {
3675 throw new IllegalStateException(caller
3676 + ": Can't find activity for token=" + token);
3677 }
3678
3679 if (!r.supportsPictureInPicture()) {
3680 throw new IllegalStateException(caller
3681 + ": Current activity does not support picture-in-picture.");
3682 }
3683
3684 if (params.hasSetAspectRatio()
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003685 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003686 params.getAspectRatio())) {
3687 final float minAspectRatio = mContext.getResources().getFloat(
3688 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
3689 final float maxAspectRatio = mContext.getResources().getFloat(
3690 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
3691 throw new IllegalArgumentException(String.format(caller
3692 + ": Aspect ratio is too extreme (must be between %f and %f).",
3693 minAspectRatio, maxAspectRatio));
3694 }
3695
3696 // Truncate the number of actions if necessary
3697 params.truncateActions(getMaxNumPictureInPictureActions(token));
3698
3699 return r;
3700 }
3701
3702 @Override
3703 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003704 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003705 synchronized (mGlobalLock) {
3706 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
3707 if (r == null) {
3708 throw new IllegalArgumentException("Activity does not exist; token="
3709 + activityToken);
3710 }
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07003711 return r.getUriPermissionsLocked().getExternalToken();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003712 }
3713 }
3714
3715 @Override
3716 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
3717 Rect tempDockedTaskInsetBounds,
3718 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003719 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003720 long ident = Binder.clearCallingIdentity();
3721 try {
3722 synchronized (mGlobalLock) {
3723 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
3724 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
3725 PRESERVE_WINDOWS);
3726 }
3727 } finally {
3728 Binder.restoreCallingIdentity(ident);
3729 }
3730 }
3731
3732 @Override
3733 public void setSplitScreenResizing(boolean resizing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003734 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003735 final long ident = Binder.clearCallingIdentity();
3736 try {
3737 synchronized (mGlobalLock) {
3738 mStackSupervisor.setSplitScreenResizing(resizing);
3739 }
3740 } finally {
3741 Binder.restoreCallingIdentity(ident);
3742 }
3743 }
3744
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003745 /**
3746 * Check that we have the features required for VR-related API calls, and throw an exception if
3747 * not.
3748 */
3749 void enforceSystemHasVrFeature() {
3750 if (!mContext.getPackageManager().hasSystemFeature(
3751 PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
3752 throw new UnsupportedOperationException("VR mode not supported on this device!");
3753 }
3754 }
3755
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003756 @Override
3757 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003758 enforceSystemHasVrFeature();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003759
3760 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3761
3762 ActivityRecord r;
3763 synchronized (mGlobalLock) {
3764 r = ActivityRecord.isInStackLocked(token);
3765 }
3766
3767 if (r == null) {
3768 throw new IllegalArgumentException();
3769 }
3770
3771 int err;
3772 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
3773 VrManagerInternal.NO_ERROR) {
3774 return err;
3775 }
3776
3777 // Clear the binder calling uid since this path may call moveToTask().
3778 final long callingId = Binder.clearCallingIdentity();
3779 try {
3780 synchronized (mGlobalLock) {
3781 r.requestedVrComponent = (enabled) ? packageName : null;
3782
3783 // Update associated state if this activity is currently focused
Andrii Kulian52d255c2018-07-13 11:32:19 -07003784 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003785 applyUpdateVrModeLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003786 }
3787 return 0;
3788 }
3789 } finally {
3790 Binder.restoreCallingIdentity(callingId);
3791 }
3792 }
3793
3794 @Override
3795 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
3796 Slog.i(TAG, "Activity tried to startLocalVoiceInteraction");
3797 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003798 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003799 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
3800 throw new SecurityException("Only focused activity can call startVoiceInteraction");
3801 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07003802 if (mRunningVoice != null || activity.getTask().voiceSession != null
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003803 || activity.voiceSession != null) {
3804 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
3805 return;
3806 }
3807 if (activity.pendingVoiceInteractionStart) {
3808 Slog.w(TAG, "Pending start of voice interaction already.");
3809 return;
3810 }
3811 activity.pendingVoiceInteractionStart = true;
3812 }
3813 LocalServices.getService(VoiceInteractionManagerInternal.class)
3814 .startLocalVoiceInteraction(callingActivity, options);
3815 }
3816
3817 @Override
3818 public void stopLocalVoiceInteraction(IBinder callingActivity) {
3819 LocalServices.getService(VoiceInteractionManagerInternal.class)
3820 .stopLocalVoiceInteraction(callingActivity);
3821 }
3822
3823 @Override
3824 public boolean supportsLocalVoiceInteraction() {
3825 return LocalServices.getService(VoiceInteractionManagerInternal.class)
3826 .supportsLocalVoiceInteraction();
3827 }
3828
3829 /** Notifies all listeners when the pinned stack animation starts. */
3830 @Override
3831 public void notifyPinnedStackAnimationStarted() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003832 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003833 }
3834
3835 /** Notifies all listeners when the pinned stack animation ends. */
3836 @Override
3837 public void notifyPinnedStackAnimationEnded() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003838 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003839 }
3840
3841 @Override
3842 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003843 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003844 final long ident = Binder.clearCallingIdentity();
3845 try {
3846 synchronized (mGlobalLock) {
3847 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
3848 }
3849 } finally {
3850 Binder.restoreCallingIdentity(ident);
3851 }
3852 }
3853
3854 @Override
3855 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003856 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003857
3858 synchronized (mGlobalLock) {
3859 // Check if display is initialized in AM.
3860 if (!mStackSupervisor.isDisplayAdded(displayId)) {
3861 // Call might come when display is not yet added or has already been removed.
3862 if (DEBUG_CONFIGURATION) {
3863 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
3864 + displayId);
3865 }
3866 return false;
3867 }
3868
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003869 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003870 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003871 values = mWindowManager.computeNewConfiguration(displayId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003872 }
3873
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003874 if (mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003875 // Update OOM levels based on display size.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003876 mAm.mProcessList.applyDisplaySize(mWindowManager);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003877 }
3878
3879 final long origId = Binder.clearCallingIdentity();
3880 try {
3881 if (values != null) {
3882 Settings.System.clearConfiguration(values);
3883 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003884 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003885 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
3886 return mTmpUpdateConfigurationResult.changes != 0;
3887 } finally {
3888 Binder.restoreCallingIdentity(origId);
3889 }
3890 }
3891 }
3892
3893 @Override
3894 public boolean updateConfiguration(Configuration values) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003895 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003896
3897 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003898 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003899 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003900 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003901 }
3902
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003903 if (mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003904 // Update OOM levels based on display size.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003905 mAm.mProcessList.applyDisplaySize(mWindowManager);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003906 }
3907
3908 final long origId = Binder.clearCallingIdentity();
3909 try {
3910 if (values != null) {
3911 Settings.System.clearConfiguration(values);
3912 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003913 updateConfigurationLocked(values, null, false, false /* persistent */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003914 UserHandle.USER_NULL, false /* deferResume */,
3915 mTmpUpdateConfigurationResult);
3916 return mTmpUpdateConfigurationResult.changes != 0;
3917 } finally {
3918 Binder.restoreCallingIdentity(origId);
3919 }
3920 }
3921 }
3922
3923 @Override
3924 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
3925 CharSequence message) {
3926 if (message != null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003927 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003928 Manifest.permission.SHOW_KEYGUARD_MESSAGE, "dismissKeyguard()");
3929 }
3930 final long callingId = Binder.clearCallingIdentity();
3931 try {
3932 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003933 mKeyguardController.dismissKeyguard(token, callback, message);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003934 }
3935 } finally {
3936 Binder.restoreCallingIdentity(callingId);
3937 }
3938 }
3939
3940 @Override
3941 public void cancelTaskWindowTransition(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003942 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003943 "cancelTaskWindowTransition()");
3944 final long ident = Binder.clearCallingIdentity();
3945 try {
3946 synchronized (mGlobalLock) {
3947 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
3948 MATCH_TASK_IN_STACKS_ONLY);
3949 if (task == null) {
3950 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
3951 return;
3952 }
3953 task.cancelWindowTransition();
3954 }
3955 } finally {
3956 Binder.restoreCallingIdentity(ident);
3957 }
3958 }
3959
3960 @Override
3961 public ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003962 enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003963 final long ident = Binder.clearCallingIdentity();
3964 try {
3965 final TaskRecord task;
3966 synchronized (mGlobalLock) {
3967 task = mStackSupervisor.anyTaskForIdLocked(taskId,
3968 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
3969 if (task == null) {
3970 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
3971 return null;
3972 }
3973 }
3974 // Don't call this while holding the lock as this operation might hit the disk.
3975 return task.getSnapshot(reducedResolution);
3976 } finally {
3977 Binder.restoreCallingIdentity(ident);
3978 }
3979 }
3980
3981 @Override
3982 public void setDisablePreviewScreenshots(IBinder token, boolean disable) {
3983 synchronized (mGlobalLock) {
3984 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3985 if (r == null) {
3986 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
3987 + token);
3988 return;
3989 }
3990 final long origId = Binder.clearCallingIdentity();
3991 try {
3992 r.setDisablePreviewScreenshots(disable);
3993 } finally {
3994 Binder.restoreCallingIdentity(origId);
3995 }
3996 }
3997 }
3998
3999 /** Return the user id of the last resumed activity. */
4000 @Override
4001 public @UserIdInt
4002 int getLastResumedActivityUserId() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004003 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004004 Manifest.permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
4005 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07004006 if (mLastResumedActivity == null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004007 return getCurrentUserId();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004008 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004009 return mLastResumedActivity.userId;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004010 }
4011 }
4012
4013 @Override
4014 public void updateLockTaskFeatures(int userId, int flags) {
4015 final int callingUid = Binder.getCallingUid();
4016 if (callingUid != 0 && callingUid != SYSTEM_UID) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004017 mAmInternal.enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004018 "updateLockTaskFeatures()");
4019 }
4020 synchronized (mGlobalLock) {
4021 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
4022 Integer.toHexString(flags));
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07004023 getLockTaskController().updateLockTaskFeatures(userId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004024 }
4025 }
4026
4027 @Override
4028 public void setShowWhenLocked(IBinder token, boolean showWhenLocked) {
4029 synchronized (mGlobalLock) {
4030 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4031 if (r == null) {
4032 return;
4033 }
4034 final long origId = Binder.clearCallingIdentity();
4035 try {
4036 r.setShowWhenLocked(showWhenLocked);
4037 } finally {
4038 Binder.restoreCallingIdentity(origId);
4039 }
4040 }
4041 }
4042
4043 @Override
4044 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) {
4045 synchronized (mGlobalLock) {
4046 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4047 if (r == null) {
4048 return;
4049 }
4050 final long origId = Binder.clearCallingIdentity();
4051 try {
4052 r.setTurnScreenOn(turnScreenOn);
4053 } finally {
4054 Binder.restoreCallingIdentity(origId);
4055 }
4056 }
4057 }
4058
4059 @Override
4060 public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004061 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004062 "registerRemoteAnimations");
4063 definition.setCallingPid(Binder.getCallingPid());
4064 synchronized (mGlobalLock) {
4065 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4066 if (r == null) {
4067 return;
4068 }
4069 final long origId = Binder.clearCallingIdentity();
4070 try {
4071 r.registerRemoteAnimations(definition);
4072 } finally {
4073 Binder.restoreCallingIdentity(origId);
4074 }
4075 }
4076 }
4077
4078 @Override
4079 public void registerRemoteAnimationForNextActivityStart(String packageName,
4080 RemoteAnimationAdapter adapter) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004081 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004082 "registerRemoteAnimationForNextActivityStart");
4083 adapter.setCallingPid(Binder.getCallingPid());
4084 synchronized (mGlobalLock) {
4085 final long origId = Binder.clearCallingIdentity();
4086 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07004087 getActivityStartController().registerRemoteAnimationForNextActivityStart(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004088 packageName, adapter);
4089 } finally {
4090 Binder.restoreCallingIdentity(origId);
4091 }
4092 }
4093 }
4094
4095 /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
4096 @Override
4097 public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
4098 synchronized (mGlobalLock) {
4099 final long origId = Binder.clearCallingIdentity();
4100 try {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004101 mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004102 } finally {
4103 Binder.restoreCallingIdentity(origId);
4104 }
4105 }
4106 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004107
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004108 @Override
4109 public void setVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004110 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004111 synchronized (mGlobalLock) {
4112 synchronized (mAm.mPidsSelfLocked) {
4113 final int pid = Binder.getCallingPid();
4114 final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004115 mVrController.setVrThreadLocked(tid, pid, proc.getWindowProcessController());
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004116 }
4117 }
4118 }
4119
4120 @Override
4121 public void setPersistentVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004122 if (checkCallingPermission(Manifest.permission.RESTRICTED_VR_ACCESS)
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004123 != PERMISSION_GRANTED) {
4124 final String msg = "Permission Denial: setPersistentVrThread() from pid="
4125 + Binder.getCallingPid()
4126 + ", uid=" + Binder.getCallingUid()
4127 + " requires " + Manifest.permission.RESTRICTED_VR_ACCESS;
4128 Slog.w(TAG, msg);
4129 throw new SecurityException(msg);
4130 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004131 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004132 synchronized (mGlobalLock) {
4133 synchronized (mAm.mPidsSelfLocked) {
4134 final int pid = Binder.getCallingPid();
4135 final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
4136 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
4137 }
4138 }
4139 }
4140
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004141 @Override
4142 public void stopAppSwitches() {
4143 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
4144 synchronized (mGlobalLock) {
4145 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME;
4146 mDidAppSwitch = false;
4147 getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
4148 }
4149 }
4150
4151 @Override
4152 public void resumeAppSwitches() {
4153 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
4154 synchronized (mGlobalLock) {
4155 // Note that we don't execute any pending app switches... we will
4156 // let those wait until either the timeout, or the next start
4157 // activity request.
4158 mAppSwitchesAllowedTime = 0;
4159 }
4160 }
4161
4162 void onStartActivitySetDidAppSwitch() {
4163 if (mDidAppSwitch) {
4164 // This is the second allowed switch since we stopped switches, so now just generally
4165 // allow switches. Use case:
4166 // - user presses home (switches disabled, switch to home, mDidAppSwitch now true);
4167 // - user taps a home icon (coming from home so allowed, we hit here and now allow
4168 // anyone to switch again).
4169 mAppSwitchesAllowedTime = 0;
4170 } else {
4171 mDidAppSwitch = true;
4172 }
4173 }
4174
4175 /** @return whether the system should disable UI modes incompatible with VR mode. */
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004176 boolean shouldDisableNonVrUiLocked() {
4177 return mVrController.shouldDisableNonVrUiLocked();
4178 }
4179
Wale Ogunwale53783742018-09-16 10:21:51 -07004180 private void applyUpdateVrModeLocked(ActivityRecord r) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004181 // VR apps are expected to run in a main display. If an app is turning on VR for
4182 // itself, but lives in a dynamic stack, then make sure that it is moved to the main
4183 // fullscreen stack before enabling VR Mode.
4184 // TODO: The goal of this code is to keep the VR app on the main display. When the
4185 // stack implementation changes in the future, keep in mind that the use of the fullscreen
4186 // stack is a means to move the activity to the main display and a moveActivityToDisplay()
4187 // option would be a better choice here.
4188 if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
4189 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
4190 + " to main stack for VR");
4191 final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
4192 WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
4193 moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
4194 }
4195 mH.post(() -> {
4196 if (!mVrController.onVrModeChanged(r)) {
4197 return;
4198 }
4199 synchronized (mGlobalLock) {
4200 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
4201 mWindowManager.disableNonVrUi(disableNonVrUi);
4202 if (disableNonVrUi) {
4203 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
4204 // then remove the pinned stack.
4205 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
4206 }
4207 }
4208 });
4209 }
4210
Wale Ogunwale53783742018-09-16 10:21:51 -07004211 @Override
4212 public int getPackageScreenCompatMode(String packageName) {
4213 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4214 synchronized (mGlobalLock) {
4215 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4216 }
4217 }
4218
4219 @Override
4220 public void setPackageScreenCompatMode(String packageName, int mode) {
4221 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4222 "setPackageScreenCompatMode");
4223 synchronized (mGlobalLock) {
4224 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4225 }
4226 }
4227
4228 @Override
4229 public boolean getPackageAskScreenCompat(String packageName) {
4230 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4231 synchronized (mGlobalLock) {
4232 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4233 }
4234 }
4235
4236 @Override
4237 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4238 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4239 "setPackageAskScreenCompat");
4240 synchronized (mGlobalLock) {
4241 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4242 }
4243 }
4244
Andrii Kulian5f750bc2018-07-17 08:57:23 -07004245 ActivityStack getTopDisplayFocusedStack() {
4246 return mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004247 }
4248
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004249 /** Pokes the task persister. */
4250 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
4251 mRecentTasks.notifyTaskPersisterLocked(task, flush);
4252 }
4253
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004254 void onTopProcChangedLocked(WindowProcessController proc) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004255 mVrController.onTopProcChangedLocked(proc);
4256 }
4257
4258 boolean isKeyguardLocked() {
4259 return mKeyguardController.isKeyguardLocked();
4260 }
4261
4262 boolean isNextTransitionForward() {
4263 int transit = mWindowManager.getPendingAppTransition();
4264 return transit == TRANSIT_ACTIVITY_OPEN
4265 || transit == TRANSIT_TASK_OPEN
4266 || transit == TRANSIT_TASK_TO_FRONT;
4267 }
4268
Wale Ogunwalef6733932018-06-27 05:14:34 -07004269 void dumpSleepStates(PrintWriter pw, boolean testPssMode) {
4270 synchronized (mGlobalLock) {
4271 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
4272 if (mRunningVoice != null) {
4273 pw.println(" mRunningVoice=" + mRunningVoice);
4274 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
4275 }
4276 pw.println(" mSleeping=" + mSleeping);
4277 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + testPssMode);
4278 pw.println(" mVrController=" + mVrController);
4279 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004280 }
4281
Wale Ogunwalef6733932018-06-27 05:14:34 -07004282 void writeSleepStateToProto(ProtoOutputStream proto) {
4283 for (ActivityTaskManagerInternal.SleepToken st : mStackSupervisor.mSleepTokens) {
4284 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS,
4285 st.toString());
4286 }
4287
4288 if (mRunningVoice != null) {
4289 final long vrToken = proto.start(
4290 ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
4291 proto.write(ActivityManagerServiceDumpProcessesProto.Voice.SESSION,
4292 mRunningVoice.toString());
4293 mVoiceWakeLock.writeToProto(
4294 proto, ActivityManagerServiceDumpProcessesProto.Voice.WAKELOCK);
4295 proto.end(vrToken);
4296 }
4297
4298 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
4299 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN,
4300 mShuttingDown);
4301 mVrController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004302 }
4303
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004304 int getCurrentUserId() {
4305 return mAmInternal.getCurrentUserId();
4306 }
4307
4308 private void enforceNotIsolatedCaller(String caller) {
4309 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4310 throw new SecurityException("Isolated process not allowed to call " + caller);
4311 }
4312 }
4313
Wale Ogunwalef6733932018-06-27 05:14:34 -07004314 public Configuration getConfiguration() {
4315 Configuration ci;
4316 synchronized(mGlobalLock) {
Yunfan Chen75157d72018-07-27 14:47:21 +09004317 ci = new Configuration(getGlobalConfigurationForCallingPid());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004318 ci.userSetLocale = false;
4319 }
4320 return ci;
4321 }
4322
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004323 /**
4324 * Current global configuration information. Contains general settings for the entire system,
4325 * also corresponds to the merged configuration of the default display.
4326 */
4327 Configuration getGlobalConfiguration() {
4328 return mStackSupervisor.getConfiguration();
4329 }
4330
4331 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4332 boolean initLocale) {
4333 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
4334 }
4335
4336 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4337 boolean initLocale, boolean deferResume) {
4338 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
4339 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
4340 UserHandle.USER_NULL, deferResume);
4341 }
4342
4343 void updatePersistentConfiguration(Configuration values, @UserIdInt int userId) {
4344 final long origId = Binder.clearCallingIdentity();
4345 try {
4346 synchronized (mGlobalLock) {
4347 updateConfigurationLocked(values, null, false, true, userId,
4348 false /* deferResume */);
4349 }
4350 } finally {
4351 Binder.restoreCallingIdentity(origId);
4352 }
4353 }
4354
4355 void updateUserConfiguration() {
4356 synchronized (mGlobalLock) {
4357 final Configuration configuration = new Configuration(getGlobalConfiguration());
4358 final int currentUserId = mAmInternal.getCurrentUserId();
4359 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
4360 currentUserId, Settings.System.canWrite(mContext));
4361 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
4362 false /* persistent */, currentUserId, false /* deferResume */);
4363 }
4364 }
4365
4366 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4367 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
4368 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
4369 deferResume, null /* result */);
4370 }
4371
4372 /**
4373 * Do either or both things: (1) change the current configuration, and (2)
4374 * make sure the given activity is running with the (now) current
4375 * configuration. Returns true if the activity has been left running, or
4376 * false if <var>starting</var> is being destroyed to match the new
4377 * configuration.
4378 *
4379 * @param userId is only used when persistent parameter is set to true to persist configuration
4380 * for that particular user
4381 */
4382 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4383 boolean initLocale, boolean persistent, int userId, boolean deferResume,
4384 ActivityTaskManagerService.UpdateConfigurationResult result) {
4385 int changes = 0;
4386 boolean kept = true;
4387
4388 if (mWindowManager != null) {
4389 mWindowManager.deferSurfaceLayout();
4390 }
4391 try {
4392 if (values != null) {
4393 changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
4394 deferResume);
4395 }
4396
4397 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4398 } finally {
4399 if (mWindowManager != null) {
4400 mWindowManager.continueSurfaceLayout();
4401 }
4402 }
4403
4404 if (result != null) {
4405 result.changes = changes;
4406 result.activityRelaunched = !kept;
4407 }
4408 return kept;
4409 }
4410
4411 /**
4412 * Returns true if this configuration change is interesting enough to send an
4413 * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
4414 */
4415 private static boolean isSplitConfigurationChange(int configDiff) {
4416 return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
4417 }
4418
4419 /** Update default (global) configuration and notify listeners about changes. */
4420 private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
4421 boolean persistent, int userId, boolean deferResume) {
4422 mTempConfig.setTo(getGlobalConfiguration());
4423 final int changes = mTempConfig.updateFrom(values);
4424 if (changes == 0) {
4425 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
4426 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
4427 // performDisplayOverrideConfigUpdate in order to send the new display configuration
4428 // (even if there are no actual changes) to unfreeze the window.
4429 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
4430 return 0;
4431 }
4432
4433 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
4434 "Updating global configuration to: " + values);
4435
4436 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
4437 StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
4438 values.colorMode,
4439 values.densityDpi,
4440 values.fontScale,
4441 values.hardKeyboardHidden,
4442 values.keyboard,
4443 values.keyboardHidden,
4444 values.mcc,
4445 values.mnc,
4446 values.navigation,
4447 values.navigationHidden,
4448 values.orientation,
4449 values.screenHeightDp,
4450 values.screenLayout,
4451 values.screenWidthDp,
4452 values.smallestScreenWidthDp,
4453 values.touchscreen,
4454 values.uiMode);
4455
4456
4457 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
4458 final LocaleList locales = values.getLocales();
4459 int bestLocaleIndex = 0;
4460 if (locales.size() > 1) {
4461 if (mSupportedSystemLocales == null) {
4462 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
4463 }
4464 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
4465 }
4466 SystemProperties.set("persist.sys.locale",
4467 locales.get(bestLocaleIndex).toLanguageTag());
4468 LocaleList.setDefault(locales, bestLocaleIndex);
4469 mAm.mHandler.sendMessage(mAm.mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
4470 locales.get(bestLocaleIndex)));
4471 }
4472
Yunfan Chen75157d72018-07-27 14:47:21 +09004473 mTempConfig.seq = increaseConfigurationSeqLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004474
4475 // Update stored global config and notify everyone about the change.
4476 mStackSupervisor.onConfigurationChanged(mTempConfig);
4477
4478 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
4479 // TODO(multi-display): Update UsageEvents#Event to include displayId.
4480 mAm.mUsageStatsService.reportConfigurationChange(
4481 mTempConfig, mAmInternal.getCurrentUserId());
4482
4483 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
Wale Ogunwalef6733932018-06-27 05:14:34 -07004484 updateShouldShowDialogsLocked(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004485
4486 AttributeCache ac = AttributeCache.instance();
4487 if (ac != null) {
4488 ac.updateConfiguration(mTempConfig);
4489 }
4490
4491 // Make sure all resources in our process are updated right now, so that anyone who is going
4492 // to retrieve resource values after we return will be sure to get the new ones. This is
4493 // especially important during boot, where the first config change needs to guarantee all
4494 // resources have that config before following boot code is executed.
4495 mAm.mSystemThread.applyConfigurationToResources(mTempConfig);
4496
4497 // We need another copy of global config because we're scheduling some calls instead of
4498 // running them in place. We need to be sure that object we send will be handled unchanged.
4499 final Configuration configCopy = new Configuration(mTempConfig);
4500 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
4501 Message msg = mAm.mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
4502 msg.obj = configCopy;
4503 msg.arg1 = userId;
4504 mAm.mHandler.sendMessage(msg);
4505 }
4506
Yunfan Chen75157d72018-07-27 14:47:21 +09004507 // TODO: Consider using mPidMap to update configurations for processes.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004508 for (int i = mAm.mLruProcesses.size() - 1; i >= 0; i--) {
4509 ProcessRecord app = mAm.mLruProcesses.get(i);
4510 try {
4511 if (app.thread != null) {
4512 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
4513 + app.processName + " new config " + configCopy);
4514 getLifecycleManager().scheduleTransaction(app.thread,
4515 ConfigurationChangeItem.obtain(configCopy));
4516 }
4517 } catch (Exception e) {
4518 Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
4519 }
4520 }
4521
4522 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
4523 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
4524 | Intent.FLAG_RECEIVER_FOREGROUND
4525 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4526 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4527 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4528 UserHandle.USER_ALL);
4529 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
4530 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
4531 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
4532 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
4533 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4534 if (initLocale || !mAm.mProcessesReady) {
4535 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
4536 }
4537 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4538 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4539 UserHandle.USER_ALL);
4540 }
4541
4542 // Send a broadcast to PackageInstallers if the configuration change is interesting
4543 // for the purposes of installing additional splits.
4544 if (!initLocale && isSplitConfigurationChange(changes)) {
4545 intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
4546 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
4547 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
4548
4549 // Typically only app stores will have this permission.
4550 String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES };
4551 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions,
4552 OP_NONE, null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
4553 }
4554
4555 // Override configuration of the default display duplicates global config, so we need to
4556 // update it also. This will also notify WindowManager about changes.
4557 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
4558 DEFAULT_DISPLAY);
4559
4560 return changes;
4561 }
4562
4563 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
4564 boolean deferResume, int displayId) {
4565 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
4566 displayId, null /* result */);
4567 }
4568
4569 /**
4570 * Updates override configuration specific for the selected display. If no config is provided,
4571 * new one will be computed in WM based on current display info.
4572 */
4573 boolean updateDisplayOverrideConfigurationLocked(Configuration values,
4574 ActivityRecord starting, boolean deferResume, int displayId,
4575 ActivityTaskManagerService.UpdateConfigurationResult result) {
4576 int changes = 0;
4577 boolean kept = true;
4578
4579 if (mWindowManager != null) {
4580 mWindowManager.deferSurfaceLayout();
4581 }
4582 try {
4583 if (values != null) {
4584 if (displayId == DEFAULT_DISPLAY) {
4585 // Override configuration of the default display duplicates global config, so
4586 // we're calling global config update instead for default display. It will also
4587 // apply the correct override config.
4588 changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
4589 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
4590 } else {
4591 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
4592 }
4593 }
4594
4595 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4596 } finally {
4597 if (mWindowManager != null) {
4598 mWindowManager.continueSurfaceLayout();
4599 }
4600 }
4601
4602 if (result != null) {
4603 result.changes = changes;
4604 result.activityRelaunched = !kept;
4605 }
4606 return kept;
4607 }
4608
4609 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
4610 int displayId) {
4611 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
4612 final int changes = mTempConfig.updateFrom(values);
4613 if (changes != 0) {
4614 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
4615 + mTempConfig + " for displayId=" + displayId);
4616 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
4617
4618 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
4619 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004620 mAppWarnings.onDensityChanged();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004621
4622 mAm.killAllBackgroundProcessesExcept(N,
4623 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
4624 }
4625 }
4626
4627 // Update the configuration with WM first and check if any of the stacks need to be resized
4628 // due to the configuration change. If so, resize the stacks now and do any relaunches if
4629 // necessary. This way we don't need to relaunch again afterwards in
4630 // ensureActivityConfiguration().
4631 if (mWindowManager != null) {
4632 final int[] resizedStacks =
4633 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
4634 if (resizedStacks != null) {
4635 for (int stackId : resizedStacks) {
4636 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
4637 }
4638 }
4639 }
4640
4641 return changes;
4642 }
4643
Wale Ogunwalef6733932018-06-27 05:14:34 -07004644 private void updateEventDispatchingLocked(boolean booted) {
4645 mWindowManager.setEventDispatching(booted && !mShuttingDown);
4646 }
4647
4648 void enableScreenAfterBoot(boolean booted) {
4649 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4650 SystemClock.uptimeMillis());
4651 mWindowManager.enableScreenAfterBoot();
4652
4653 synchronized (mGlobalLock) {
4654 updateEventDispatchingLocked(booted);
4655 }
4656 }
4657
4658 boolean canShowErrorDialogs() {
4659 return mShowDialogs && !mSleeping && !mShuttingDown
4660 && !mKeyguardController.isKeyguardOrAodShowing(DEFAULT_DISPLAY)
4661 && !hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
Wale Ogunwale86b74462018-07-02 08:42:43 -07004662 mAmInternal.getCurrentUserId())
Wale Ogunwalef6733932018-06-27 05:14:34 -07004663 && !(UserManager.isDeviceInDemoMode(mContext)
Wale Ogunwale86b74462018-07-02 08:42:43 -07004664 && mAmInternal.getCurrentUser().isDemo());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004665 }
4666
Wale Ogunwale906f9c62018-07-23 11:23:44 -07004667 static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
4668 if (r == null || !r.hasProcess()) {
4669 return KEY_DISPATCHING_TIMEOUT_MS;
4670 }
4671 return getInputDispatchingTimeoutLocked(r.app);
4672 }
4673
4674 private static long getInputDispatchingTimeoutLocked(WindowProcessController r) {
4675 if (r != null && (r.isInstrumenting() || r.isUsingWrapper())) {
4676 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS;
4677 }
4678 return KEY_DISPATCHING_TIMEOUT_MS;
4679 }
4680
4681 long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
4682 if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
4683 throw new SecurityException("Requires permission " + FILTER_EVENTS);
4684 }
4685 WindowProcessController proc;
4686 long timeout;
4687 synchronized (mGlobalLock) {
4688 proc = mPidMap.get(pid);
4689 timeout = getInputDispatchingTimeoutLocked(proc);
4690 }
4691
4692 if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
4693 return -1;
4694 }
4695
4696 return timeout;
4697 }
4698
4699 /**
4700 * Handle input dispatching timeouts.
4701 * Returns whether input dispatching should be aborted or not.
4702 */
4703 boolean inputDispatchingTimedOut(final WindowProcessController proc,
4704 final ActivityRecord activity, final ActivityRecord parent,
4705 final boolean aboveSystem, String reason) {
4706 if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
4707 throw new SecurityException("Requires permission " + FILTER_EVENTS);
4708 }
4709
4710 final String annotation;
4711 if (reason == null) {
4712 annotation = "Input dispatching timed out";
4713 } else {
4714 annotation = "Input dispatching timed out (" + reason + ")";
4715 }
4716
4717 if (proc != null) {
4718 synchronized (mGlobalLock) {
4719 if (proc.isDebugging()) {
4720 return false;
4721 }
4722
4723 if (proc.isInstrumenting()) {
4724 Bundle info = new Bundle();
4725 info.putString("shortMsg", "keyDispatchingTimedOut");
4726 info.putString("longMsg", annotation);
4727 mAm.finishInstrumentationLocked(
4728 (ProcessRecord) proc.mOwner, Activity.RESULT_CANCELED, info);
4729 return true;
4730 }
4731 }
4732 mH.post(() -> {
4733 mAm.mAppErrors.appNotResponding(
4734 (ProcessRecord) proc.mOwner, activity, parent, aboveSystem, annotation);
4735 });
4736 }
4737
4738 return true;
4739 }
4740
Wale Ogunwalef6733932018-06-27 05:14:34 -07004741 /**
4742 * Decide based on the configuration whether we should show the ANR,
4743 * crash, etc dialogs. The idea is that if there is no affordance to
4744 * press the on-screen buttons, or the user experience would be more
4745 * greatly impacted than the crash itself, we shouldn't show the dialog.
4746 *
4747 * A thought: SystemUI might also want to get told about this, the Power
4748 * dialog / global actions also might want different behaviors.
4749 */
4750 private void updateShouldShowDialogsLocked(Configuration config) {
4751 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
4752 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
4753 && config.navigation == Configuration.NAVIGATION_NONAV);
4754 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
4755 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
4756 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
4757 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
4758 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
4759 final boolean hideDialogsSet = Settings.Global.getInt(mContext.getContentResolver(),
4760 HIDE_ERROR_DIALOGS, 0) != 0;
4761 mShowDialogs = inputMethodExists && uiModeSupportsDialogs && !hideDialogsSet;
4762 }
4763
4764 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
4765 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
4766 FONT_SCALE, 1.0f, userId);
4767
4768 synchronized (this) {
4769 if (getGlobalConfiguration().fontScale == scaleFactor) {
4770 return;
4771 }
4772
4773 final Configuration configuration
4774 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
4775 configuration.fontScale = scaleFactor;
4776 updatePersistentConfiguration(configuration, userId);
4777 }
4778 }
4779
4780 // Actually is sleeping or shutting down or whatever else in the future
4781 // is an inactive state.
4782 boolean isSleepingOrShuttingDownLocked() {
4783 return isSleepingLocked() || mShuttingDown;
4784 }
4785
4786 boolean isSleepingLocked() {
4787 return mSleeping;
4788 }
4789
Riddle Hsu16567132018-08-16 21:37:47 +08004790 /** Update AMS states when an activity is resumed. */
Wale Ogunwalef6733932018-06-27 05:14:34 -07004791 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
4792 final TaskRecord task = r.getTask();
4793 if (task.isActivityTypeStandard()) {
4794 if (mCurAppTimeTracker != r.appTimeTracker) {
4795 // We are switching app tracking. Complete the current one.
4796 if (mCurAppTimeTracker != null) {
4797 mCurAppTimeTracker.stop();
4798 mH.obtainMessage(
4799 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
4800 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
4801 mCurAppTimeTracker = null;
4802 }
4803 if (r.appTimeTracker != null) {
4804 mCurAppTimeTracker = r.appTimeTracker;
4805 startTimeTrackingFocusedActivityLocked();
4806 }
4807 } else {
4808 startTimeTrackingFocusedActivityLocked();
4809 }
4810 } else {
4811 r.appTimeTracker = null;
4812 }
4813 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
4814 // TODO: Probably not, because we don't want to resume voice on switching
4815 // back to this activity
4816 if (task.voiceInteractor != null) {
4817 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
4818 } else {
4819 finishRunningVoiceLocked();
4820
4821 if (mLastResumedActivity != null) {
4822 final IVoiceInteractionSession session;
4823
4824 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
4825 if (lastResumedActivityTask != null
4826 && lastResumedActivityTask.voiceSession != null) {
4827 session = lastResumedActivityTask.voiceSession;
4828 } else {
4829 session = mLastResumedActivity.voiceSession;
4830 }
4831
4832 if (session != null) {
4833 // We had been in a voice interaction session, but now focused has
4834 // move to something different. Just finish the session, we can't
4835 // return to it and retain the proper state and synchronization with
4836 // the voice interaction service.
4837 finishVoiceTask(session);
4838 }
4839 }
4840 }
4841
4842 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
4843 mAmInternal.sendForegroundProfileChanged(r.userId);
4844 }
4845 updateResumedAppTrace(r);
4846 mLastResumedActivity = r;
4847
Riddle Hsu3026e8d2018-08-03 15:50:53 +08004848 // TODO(b/111361570): Support multiple focused apps in WM
Wale Ogunwalef6733932018-06-27 05:14:34 -07004849 mWindowManager.setFocusedApp(r.appToken, true);
4850
4851 applyUpdateLockStateLocked(r);
4852 applyUpdateVrModeLocked(r);
4853
4854 EventLogTags.writeAmSetResumedActivity(
4855 r == null ? -1 : r.userId,
4856 r == null ? "NULL" : r.shortComponentName,
4857 reason);
4858 }
4859
4860 ActivityTaskManagerInternal.SleepToken acquireSleepToken(String tag, int displayId) {
4861 synchronized (mGlobalLock) {
4862 final ActivityTaskManagerInternal.SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
4863 updateSleepIfNeededLocked();
4864 return token;
4865 }
4866 }
4867
4868 void updateSleepIfNeededLocked() {
4869 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
4870 final boolean wasSleeping = mSleeping;
4871 boolean updateOomAdj = false;
4872
4873 if (!shouldSleep) {
4874 // If wasSleeping is true, we need to wake up activity manager state from when
4875 // we started sleeping. In either case, we need to apply the sleep tokens, which
4876 // will wake up stacks or put them to sleep as appropriate.
4877 if (wasSleeping) {
4878 mSleeping = false;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07004879 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
4880 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__AWAKE);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004881 startTimeTrackingFocusedActivityLocked();
4882 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
4883 mStackSupervisor.comeOutOfSleepIfNeededLocked();
4884 }
4885 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
4886 if (wasSleeping) {
4887 updateOomAdj = true;
4888 }
4889 } else if (!mSleeping && shouldSleep) {
4890 mSleeping = true;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07004891 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
4892 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__ASLEEP);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004893 if (mCurAppTimeTracker != null) {
4894 mCurAppTimeTracker.stop();
4895 }
4896 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
4897 mStackSupervisor.goingToSleepLocked();
4898 updateResumedAppTrace(null /* resumed */);
4899 updateOomAdj = true;
4900 }
4901 if (updateOomAdj) {
4902 mH.post(mAmInternal::updateOomAdj);
4903 }
4904 }
4905
4906 void updateOomAdj() {
4907 mH.post(mAmInternal::updateOomAdj);
4908 }
4909
Wale Ogunwale53783742018-09-16 10:21:51 -07004910 void updateCpuStats() {
4911 mH.post(mAmInternal::updateCpuStats);
4912 }
4913
4914 void updateUsageStats(ActivityRecord component, boolean resumed) {
4915 final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::updateUsageStats,
4916 mAmInternal, component.realActivity, component.app.mUid, component.userId, resumed);
4917 mH.sendMessage(m);
4918 }
4919
4920 void setBooting(boolean booting) {
4921 mAmInternal.setBooting(booting);
4922 }
4923
4924 boolean isBooting() {
4925 return mAmInternal.isBooting();
4926 }
4927
4928 void setBooted(boolean booted) {
4929 mAmInternal.setBooted(booted);
4930 }
4931
4932 boolean isBooted() {
4933 return mAmInternal.isBooted();
4934 }
4935
4936 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
4937 mH.post(() -> {
4938 if (finishBooting) {
4939 mAmInternal.finishBooting();
4940 }
4941 if (enableScreen) {
4942 mInternal.enableScreenAfterBoot(isBooted());
4943 }
4944 });
4945 }
4946
4947 void setHeavyWeightProcess(ActivityRecord root) {
4948 mHeavyWeightProcess = root.app;
4949 final Message m = PooledLambda.obtainMessage(
4950 ActivityTaskManagerService::postHeavyWeightProcessNotification, this,
4951 root.app, root.intent, root.userId);
4952 mH.sendMessage(m);
4953 }
4954
4955 void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
4956 if (mHeavyWeightProcess == null || mHeavyWeightProcess != proc) {
4957 return;
4958 }
4959
4960 mHeavyWeightProcess = null;
4961 final Message m = PooledLambda.obtainMessage(
4962 ActivityTaskManagerService::cancelHeavyWeightProcessNotification, this,
4963 proc.mUserId);
4964 mH.sendMessage(m);
4965 }
4966
4967 private void cancelHeavyWeightProcessNotification(int userId) {
4968 final INotificationManager inm = NotificationManager.getService();
4969 if (inm == null) {
4970 return;
4971 }
4972 try {
4973 inm.cancelNotificationWithTag("android", null,
4974 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, userId);
4975 } catch (RuntimeException e) {
4976 Slog.w(TAG, "Error canceling notification for service", e);
4977 } catch (RemoteException e) {
4978 }
4979
4980 }
4981
4982 private void postHeavyWeightProcessNotification(
4983 WindowProcessController proc, Intent intent, int userId) {
4984 if (proc == null) {
4985 return;
4986 }
4987
4988 final INotificationManager inm = NotificationManager.getService();
4989 if (inm == null) {
4990 return;
4991 }
4992
4993 try {
4994 Context context = mContext.createPackageContext(proc.mInfo.packageName, 0);
4995 String text = mContext.getString(R.string.heavy_weight_notification,
4996 context.getApplicationInfo().loadLabel(context.getPackageManager()));
4997 Notification notification =
4998 new Notification.Builder(context,
4999 SystemNotificationChannels.HEAVY_WEIGHT_APP)
5000 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
5001 .setWhen(0)
5002 .setOngoing(true)
5003 .setTicker(text)
5004 .setColor(mContext.getColor(
5005 com.android.internal.R.color.system_notification_accent_color))
5006 .setContentTitle(text)
5007 .setContentText(
5008 mContext.getText(R.string.heavy_weight_notification_detail))
5009 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
5010 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
5011 new UserHandle(userId)))
5012 .build();
5013 try {
5014 inm.enqueueNotificationWithTag("android", "android", null,
5015 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, notification, userId);
5016 } catch (RuntimeException e) {
5017 Slog.w(TAG, "Error showing notification for heavy-weight app", e);
5018 } catch (RemoteException e) {
5019 }
5020 } catch (PackageManager.NameNotFoundException e) {
5021 Slog.w(TAG, "Unable to create context for heavy notification", e);
5022 }
5023
5024 }
5025
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07005026 IIntentSender getIntentSenderLocked(int type, String packageName, int callingUid, int userId,
5027 IBinder token, String resultWho, int requestCode, Intent[] intents,
5028 String[] resolvedTypes, int flags, Bundle bOptions) {
5029
5030 ActivityRecord activity = null;
5031 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5032 activity = ActivityRecord.isInStackLocked(token);
5033 if (activity == null) {
5034 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
5035 return null;
5036 }
5037 if (activity.finishing) {
5038 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
5039 return null;
5040 }
5041 }
5042
5043 final PendingIntentRecord rec = mPendingIntentController.getIntentSender(type, packageName,
5044 callingUid, userId, token, resultWho, requestCode, intents, resolvedTypes, flags,
5045 bOptions);
5046 final boolean noCreate = (flags & PendingIntent.FLAG_NO_CREATE) != 0;
5047 if (noCreate) {
5048 return rec;
5049 }
5050 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5051 if (activity.pendingResults == null) {
5052 activity.pendingResults = new HashSet<>();
5053 }
5054 activity.pendingResults.add(rec.ref);
5055 }
5056 return rec;
5057 }
5058
Andrii Kulian52d255c2018-07-13 11:32:19 -07005059 // TODO(b/111541062): Update app time tracking to make it aware of multiple resumed activities
Wale Ogunwalef6733932018-06-27 05:14:34 -07005060 private void startTimeTrackingFocusedActivityLocked() {
Andrii Kulian52d255c2018-07-13 11:32:19 -07005061 final ActivityRecord resumedActivity = mStackSupervisor.getTopResumedActivity();
Wale Ogunwalef6733932018-06-27 05:14:34 -07005062 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
5063 mCurAppTimeTracker.start(resumedActivity.packageName);
5064 }
5065 }
5066
5067 private void updateResumedAppTrace(@Nullable ActivityRecord resumed) {
5068 if (mTracedResumedActivity != null) {
5069 Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER,
5070 constructResumedTraceName(mTracedResumedActivity.packageName), 0);
5071 }
5072 if (resumed != null) {
5073 Trace.asyncTraceBegin(TRACE_TAG_ACTIVITY_MANAGER,
5074 constructResumedTraceName(resumed.packageName), 0);
5075 }
5076 mTracedResumedActivity = resumed;
5077 }
5078
5079 private String constructResumedTraceName(String packageName) {
5080 return "focused app: " + packageName;
5081 }
5082
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005083 /** Helper method that requests bounds from WM and applies them to stack. */
5084 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
5085 final Rect newStackBounds = new Rect();
5086 final ActivityStack stack = mStackSupervisor.getStack(stackId);
5087
5088 // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
5089 if (stack == null) {
5090 final StringWriter writer = new StringWriter();
5091 final PrintWriter printWriter = new PrintWriter(writer);
5092 mStackSupervisor.dumpDisplays(printWriter);
5093 printWriter.flush();
5094
5095 Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
5096 }
5097
5098 stack.getBoundsForNewConfiguration(newStackBounds);
5099 mStackSupervisor.resizeStackLocked(
5100 stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
5101 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
5102 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
5103 }
5104
5105 /** Applies latest configuration and/or visibility updates if needed. */
5106 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
5107 boolean kept = true;
Andrii Kulian5f750bc2018-07-17 08:57:23 -07005108 final ActivityStack mainStack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005109 // mainStack is null during startup.
5110 if (mainStack != null) {
5111 if (changes != 0 && starting == null) {
5112 // If the configuration changed, and the caller is not already
5113 // in the process of starting an activity, then find the top
5114 // activity to check if its configuration needs to change.
5115 starting = mainStack.topRunningActivityLocked();
5116 }
5117
5118 if (starting != null) {
5119 kept = starting.ensureActivityConfiguration(changes,
5120 false /* preserveWindow */);
5121 // And we need to make sure at this point that all other activities
5122 // are made visible with the correct configuration.
5123 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
5124 !PRESERVE_WINDOWS);
5125 }
5126 }
5127
5128 return kept;
5129 }
5130
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005131 void scheduleAppGcsLocked() {
5132 mH.post(() -> mAmInternal.scheduleAppGcs());
5133 }
5134
Wale Ogunwale53783742018-09-16 10:21:51 -07005135 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
5136 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
5137 }
5138
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005139 /**
5140 * Returns the PackageManager. Used by classes hosted by {@link ActivityTaskManagerService}. The
5141 * PackageManager could be unavailable at construction time and therefore needs to be accessed
5142 * on demand.
5143 */
5144 IPackageManager getPackageManager() {
5145 return AppGlobals.getPackageManager();
5146 }
5147
5148 PackageManagerInternal getPackageManagerInternalLocked() {
5149 if (mPmInternal == null) {
5150 mPmInternal = LocalServices.getService(PackageManagerInternal.class);
5151 }
5152 return mPmInternal;
5153 }
5154
Wale Ogunwale008163e2018-07-23 23:11:08 -07005155 AppWarnings getAppWarningsLocked() {
5156 return mAppWarnings;
5157 }
5158
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005159 void logAppTooSlow(WindowProcessController app, long startTime, String msg) {
5160 if (true || Build.IS_USER) {
5161 return;
5162 }
5163
5164 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5165 StrictMode.allowThreadDiskWrites();
5166 try {
5167 File tracesDir = new File("/data/anr");
5168 File tracesFile = null;
5169 try {
5170 tracesFile = File.createTempFile("app_slow", null, tracesDir);
5171
5172 StringBuilder sb = new StringBuilder();
5173 Time tobj = new Time();
5174 tobj.set(System.currentTimeMillis());
5175 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5176 sb.append(": ");
5177 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5178 sb.append(" since ");
5179 sb.append(msg);
5180 FileOutputStream fos = new FileOutputStream(tracesFile);
5181 fos.write(sb.toString().getBytes());
5182 if (app == null) {
5183 fos.write("\n*** No application process!".getBytes());
5184 }
5185 fos.close();
5186 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5187 } catch (IOException e) {
5188 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesFile, e);
5189 return;
5190 }
5191
5192 if (app != null && app.getPid() > 0) {
5193 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5194 firstPids.add(app.getPid());
5195 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, null, null);
5196 }
5197
5198 File lastTracesFile = null;
5199 File curTracesFile = null;
5200 for (int i=9; i>=0; i--) {
5201 String name = String.format(Locale.US, "slow%02d.txt", i);
5202 curTracesFile = new File(tracesDir, name);
5203 if (curTracesFile.exists()) {
5204 if (lastTracesFile != null) {
5205 curTracesFile.renameTo(lastTracesFile);
5206 } else {
5207 curTracesFile.delete();
5208 }
5209 }
5210 lastTracesFile = curTracesFile;
5211 }
5212 tracesFile.renameTo(curTracesFile);
5213 } finally {
5214 StrictMode.setThreadPolicy(oldPolicy);
5215 }
5216 }
5217
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005218 final class H extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005219 static final int REPORT_TIME_TRACKER_MSG = 1;
5220
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005221 public H(Looper looper) {
5222 super(looper, null, true);
5223 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005224
5225 @Override
5226 public void handleMessage(Message msg) {
5227 switch (msg.what) {
5228 case REPORT_TIME_TRACKER_MSG: {
5229 AppTimeTracker tracker = (AppTimeTracker) msg.obj;
5230 tracker.deliverResult(mContext);
5231 } break;
5232 }
5233 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005234 }
5235
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005236 final class UiHandler extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005237 static final int DISMISS_DIALOG_UI_MSG = 1;
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005238
5239 public UiHandler() {
5240 super(com.android.server.UiThread.get().getLooper(), null, true);
5241 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005242
5243 @Override
5244 public void handleMessage(Message msg) {
5245 switch (msg.what) {
5246 case DISMISS_DIALOG_UI_MSG: {
5247 final Dialog d = (Dialog) msg.obj;
5248 d.dismiss();
5249 break;
5250 }
5251 }
5252 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005253 }
5254
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005255 final class LocalService extends ActivityTaskManagerInternal {
5256 @Override
5257 public SleepToken acquireSleepToken(String tag, int displayId) {
5258 Preconditions.checkNotNull(tag);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005259 return ActivityTaskManagerService.this.acquireSleepToken(tag, displayId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005260 }
5261
5262 @Override
5263 public ComponentName getHomeActivityForUser(int userId) {
5264 synchronized (mGlobalLock) {
5265 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
5266 return homeActivity == null ? null : homeActivity.realActivity;
5267 }
5268 }
5269
5270 @Override
5271 public void onLocalVoiceInteractionStarted(IBinder activity,
5272 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
5273 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005274 onLocalVoiceInteractionStartedLocked(activity, voiceSession, voiceInteractor);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005275 }
5276 }
5277
5278 @Override
5279 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
5280 synchronized (mGlobalLock) {
5281 mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
5282 reasons, timestamp);
5283 }
5284 }
5285
5286 @Override
5287 public void notifyAppTransitionFinished() {
5288 synchronized (mGlobalLock) {
5289 mStackSupervisor.notifyAppTransitionDone();
5290 }
5291 }
5292
5293 @Override
5294 public void notifyAppTransitionCancelled() {
5295 synchronized (mGlobalLock) {
5296 mStackSupervisor.notifyAppTransitionDone();
5297 }
5298 }
5299
5300 @Override
5301 public List<IBinder> getTopVisibleActivities() {
5302 synchronized (mGlobalLock) {
5303 return mStackSupervisor.getTopVisibleActivities();
5304 }
5305 }
5306
5307 @Override
5308 public void notifyDockedStackMinimizedChanged(boolean minimized) {
5309 synchronized (mGlobalLock) {
5310 mStackSupervisor.setDockedStackMinimized(minimized);
5311 }
5312 }
5313
5314 @Override
5315 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
5316 Bundle bOptions) {
5317 Preconditions.checkNotNull(intents, "intents");
5318 final String[] resolvedTypes = new String[intents.length];
5319
5320 // UID of the package on user userId.
5321 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
5322 // packageUid may not be initialized.
5323 int packageUid = 0;
5324 final long ident = Binder.clearCallingIdentity();
5325
5326 try {
5327 for (int i = 0; i < intents.length; i++) {
5328 resolvedTypes[i] =
5329 intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
5330 }
5331
5332 packageUid = AppGlobals.getPackageManager().getPackageUid(
5333 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
5334 } catch (RemoteException e) {
5335 // Shouldn't happen.
5336 } finally {
5337 Binder.restoreCallingIdentity(ident);
5338 }
5339
5340 synchronized (mGlobalLock) {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07005341 return getActivityStartController().startActivitiesInPackage(
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005342 packageUid, packageName,
5343 intents, resolvedTypes, null /* resultTo */,
5344 SafeActivityOptions.fromBundle(bOptions), userId,
Michal Karpinski201bc0c2018-07-20 15:32:00 +01005345 false /* validateIncomingUser */, null /* originatingPendingIntent */);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005346 }
5347 }
5348
5349 @Override
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07005350 public int startActivitiesInPackage(int uid, String callingPackage, Intent[] intents,
5351 String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, int userId,
5352 boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent) {
5353 synchronized (mGlobalLock) {
5354 return getActivityStartController().startActivitiesInPackage(uid, callingPackage,
5355 intents, resolvedTypes, resultTo, options, userId, validateIncomingUser,
5356 originatingPendingIntent);
5357 }
5358 }
5359
5360 @Override
5361 public int startActivityInPackage(int uid, int realCallingPid, int realCallingUid,
5362 String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
5363 String resultWho, int requestCode, int startFlags, SafeActivityOptions options,
5364 int userId, TaskRecord inTask, String reason, boolean validateIncomingUser,
5365 PendingIntentRecord originatingPendingIntent) {
5366 synchronized (mGlobalLock) {
5367 return getActivityStartController().startActivityInPackage(uid, realCallingPid,
5368 realCallingUid, callingPackage, intent, resolvedType, resultTo, resultWho,
5369 requestCode, startFlags, options, userId, inTask, reason,
5370 validateIncomingUser, originatingPendingIntent);
5371 }
5372 }
5373
5374 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005375 public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
5376 Intent intent, Bundle options, int userId) {
5377 return ActivityTaskManagerService.this.startActivityAsUser(
5378 caller, callerPacakge, intent,
5379 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
5380 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
5381 false /*validateIncomingUser*/);
5382 }
5383
5384 @Override
5385 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
5386 synchronized (mGlobalLock) {
5387
5388 // We might change the visibilities here, so prepare an empty app transition which
5389 // might be overridden later if we actually change visibilities.
5390 final boolean wasTransitionSet =
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005391 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005392 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005393 mWindowManager.prepareAppTransition(TRANSIT_NONE,
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005394 false /* alwaysKeepCurrent */);
5395 }
5396 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5397
5398 // If there was a transition set already we don't want to interfere with it as we
5399 // might be starting it too early.
5400 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005401 mWindowManager.executeAppTransition();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005402 }
5403 }
5404 if (callback != null) {
5405 callback.run();
5406 }
5407 }
5408
5409 @Override
5410 public void notifyKeyguardTrustedChanged() {
5411 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005412 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005413 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5414 }
5415 }
5416 }
5417
5418 /**
5419 * Called after virtual display Id is updated by
5420 * {@link com.android.server.vr.Vr2dDisplay} with a specific
5421 * {@param vrVr2dDisplayId}.
5422 */
5423 @Override
5424 public void setVr2dDisplayId(int vr2dDisplayId) {
5425 if (DEBUG_STACK) Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
5426 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005427 mVr2dDisplayId = vr2dDisplayId;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005428 }
5429 }
5430
5431 @Override
5432 public void setFocusedActivity(IBinder token) {
5433 synchronized (mGlobalLock) {
5434 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
5435 if (r == null) {
5436 throw new IllegalArgumentException(
5437 "setFocusedActivity: No activity record matching token=" + token);
5438 }
5439 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
5440 r, "setFocusedActivity")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08005441 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005442 }
5443 }
5444 }
5445
5446 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005447 public void registerScreenObserver(ScreenObserver observer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005448 mScreenObservers.add(observer);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005449 }
5450
5451 @Override
5452 public boolean isCallerRecents(int callingUid) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005453 return getRecentTasks().isCallerRecents(callingUid);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005454 }
5455
5456 @Override
5457 public boolean isRecentsComponentHomeActivity(int userId) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005458 return getRecentTasks().isRecentsComponentHomeActivity(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005459 }
5460
5461 @Override
5462 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
5463 ActivityTaskManagerService.this.cancelRecentsAnimation(restoreHomeStackPosition);
5464 }
5465
5466 @Override
5467 public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005468 ActivityTaskManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005469 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005470
5471 @Override
5472 public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
5473 synchronized (mGlobalLock) {
5474 mActiveVoiceInteractionServiceComponent = component;
5475 }
5476 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005477
5478 @Override
5479 public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
5480 if (!mAmInternal.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
5481 return;
5482 }
5483 synchronized (mGlobalLock) {
5484 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
5485 if (types == null) {
5486 if (uid < 0) {
5487 return;
5488 }
5489 types = new ArrayMap<>();
5490 mAllowAppSwitchUids.put(userId, types);
5491 }
5492 if (uid < 0) {
5493 types.remove(type);
5494 } else {
5495 types.put(type, uid);
5496 }
5497 }
5498 }
5499
5500 @Override
5501 public void onUserStopped(int userId) {
5502 synchronized (mGlobalLock) {
5503 getRecentTasks().unloadUserDataFromMemoryLocked(userId);
5504 mAllowAppSwitchUids.remove(userId);
5505 }
5506 }
5507
5508 @Override
5509 public boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
5510 synchronized (mGlobalLock) {
5511 return ActivityTaskManagerService.this.isGetTasksAllowed(
5512 caller, callingPid, callingUid);
5513 }
5514 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005515
5516 @Override
5517 public void onProcessAdded(WindowProcessController proc) {
5518 synchronized (mGlobalLock) {
5519 mProcessNames.put(proc.mName, proc.mUid, proc);
5520 }
5521 }
5522
5523 @Override
5524 public void onProcessRemoved(String name, int uid) {
5525 synchronized (mGlobalLock) {
5526 mProcessNames.remove(name, uid);
5527 }
5528 }
5529
5530 @Override
5531 public void onCleanUpApplicationRecord(WindowProcessController proc) {
5532 synchronized (mGlobalLock) {
5533 if (proc == mHomeProcess) {
5534 mHomeProcess = null;
5535 }
5536 if (proc == mPreviousProcess) {
5537 mPreviousProcess = null;
5538 }
5539 }
5540 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005541
5542 @Override
5543 public int getTopProcessState() {
5544 synchronized (mGlobalLock) {
5545 return mTopProcessState;
5546 }
5547 }
5548
5549 @Override
Wale Ogunwale53783742018-09-16 10:21:51 -07005550 public boolean isHeavyWeightProcess(WindowProcessController proc) {
5551 synchronized (mGlobalLock) {
5552 return proc == mHeavyWeightProcess;
5553 }
5554 }
5555
5556 @Override
5557 public void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
5558 synchronized (mGlobalLock) {
5559 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(proc);
5560 }
5561 }
5562
5563 @Override
5564 public void finishHeavyWeightApp() {
5565 synchronized (mGlobalLock) {
5566 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(
5567 mHeavyWeightProcess);
5568 }
5569 }
5570
5571 @Override
Wale Ogunwalef6733932018-06-27 05:14:34 -07005572 public boolean isSleeping() {
5573 synchronized (mGlobalLock) {
5574 return isSleepingLocked();
5575 }
5576 }
5577
5578 @Override
5579 public boolean isShuttingDown() {
5580 synchronized (mGlobalLock) {
5581 return mShuttingDown;
5582 }
5583 }
5584
5585 @Override
5586 public boolean shuttingDown(boolean booted, int timeout) {
5587 synchronized (mGlobalLock) {
5588 mShuttingDown = true;
5589 mStackSupervisor.prepareForShutdownLocked();
5590 updateEventDispatchingLocked(booted);
5591 return mStackSupervisor.shutdownLocked(timeout);
5592 }
5593 }
5594
5595 @Override
5596 public void enableScreenAfterBoot(boolean booted) {
5597 synchronized (mGlobalLock) {
5598 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5599 SystemClock.uptimeMillis());
5600 mWindowManager.enableScreenAfterBoot();
5601 updateEventDispatchingLocked(booted);
5602 }
5603 }
5604
5605 @Override
5606 public boolean showStrictModeViolationDialog() {
5607 synchronized (mGlobalLock) {
5608 return mShowDialogs && !mSleeping && !mShuttingDown;
5609 }
5610 }
5611
5612 @Override
5613 public void showSystemReadyErrorDialogsIfNeeded() {
5614 synchronized (mGlobalLock) {
5615 try {
5616 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
5617 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
5618 + " data partition or your device will be unstable.");
5619 mUiHandler.post(() -> {
5620 if (mShowDialogs) {
5621 AlertDialog d = new BaseErrorDialog(mUiContext);
5622 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5623 d.setCancelable(false);
5624 d.setTitle(mUiContext.getText(R.string.android_system_label));
5625 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
5626 d.setButton(DialogInterface.BUTTON_POSITIVE,
5627 mUiContext.getText(R.string.ok),
5628 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5629 d.show();
5630 }
5631 });
5632 }
5633 } catch (RemoteException e) {
5634 }
5635
5636 if (!Build.isBuildConsistent()) {
5637 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
5638 mUiHandler.post(() -> {
5639 if (mShowDialogs) {
5640 AlertDialog d = new BaseErrorDialog(mUiContext);
5641 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5642 d.setCancelable(false);
5643 d.setTitle(mUiContext.getText(R.string.android_system_label));
5644 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
5645 d.setButton(DialogInterface.BUTTON_POSITIVE,
5646 mUiContext.getText(R.string.ok),
5647 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5648 d.show();
5649 }
5650 });
5651 }
5652 }
5653 }
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005654
5655 @Override
5656 public long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason) {
5657 synchronized (mGlobalLock) {
5658 return ActivityTaskManagerService.this.inputDispatchingTimedOut(
5659 pid, aboveSystem, reason);
5660 }
5661 }
5662
5663 @Override
5664 public void onProcessMapped(int pid, WindowProcessController proc) {
5665 synchronized (mGlobalLock) {
5666 mPidMap.put(pid, proc);
5667 }
5668 }
5669
5670 @Override
5671 public void onProcessUnMapped(int pid) {
5672 synchronized (mGlobalLock) {
5673 mPidMap.remove(pid);
5674 }
5675 }
Wale Ogunwale008163e2018-07-23 23:11:08 -07005676
5677 @Override
5678 public void onPackageDataCleared(String name) {
5679 synchronized (mGlobalLock) {
Wale Ogunwale53783742018-09-16 10:21:51 -07005680 mCompatModePackages.handlePackageDataClearedLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07005681 mAppWarnings.onPackageDataCleared(name);
5682 }
5683 }
5684
5685 @Override
5686 public void onPackageUninstalled(String name) {
5687 synchronized (mGlobalLock) {
5688 mAppWarnings.onPackageUninstalled(name);
Wale Ogunwale53783742018-09-16 10:21:51 -07005689 mCompatModePackages.handlePackageUninstalledLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07005690 }
5691 }
Wale Ogunwale53783742018-09-16 10:21:51 -07005692
5693 @Override
5694 public void onPackageAdded(String name, boolean replacing) {
5695 synchronized (mGlobalLock) {
5696 mCompatModePackages.handlePackageAddedLocked(name, replacing);
5697 }
5698 }
5699
5700 @Override
5701 public CompatibilityInfo compatibilityInfoForPackage(ApplicationInfo ai) {
5702 synchronized (mGlobalLock) {
5703 return compatibilityInfoForPackageLocked(ai);
5704 }
5705 }
5706
Yunfan Chen75157d72018-07-27 14:47:21 +09005707 /**
5708 * Set the corresponding display information for the process global configuration. To be
5709 * called when we need to show IME on a different display.
5710 *
5711 * @param pid The process id associated with the IME window.
5712 * @param displayId The ID of the display showing the IME.
5713 */
5714 @Override
5715 public void onImeWindowSetOnDisplay(int pid, int displayId) {
5716 if (pid == MY_PID || pid < 0) {
5717 if (DEBUG_CONFIGURATION) {
5718 Slog.w(TAG,
5719 "Trying to update display configuration for system/invalid process.");
5720 }
5721 return;
5722 }
5723 mH.post(() -> {
5724 synchronized (mGlobalLock) {
5725 // Check if display is initialized in AM.
5726 if (!mStackSupervisor.isDisplayAdded(displayId)) {
5727 // Call come when display is not yet added or has already been removed.
5728 if (DEBUG_CONFIGURATION) {
5729 Slog.w(TAG, "Trying to update display configuration for non-existing "
5730 + "displayId=" + displayId);
5731 }
5732 return;
5733 }
5734 final WindowProcessController imeProcess = mPidMap.get(pid);
5735 if (imeProcess == null) {
5736 if (DEBUG_CONFIGURATION) {
5737 Slog.w(TAG, "Trying to update display configuration for invalid pid: "
5738 + pid);
5739 }
5740 return;
5741 }
5742 // Fetch the current override configuration of the display and set it to the
5743 // process global configuration.
5744 imeProcess.onConfigurationChanged(
5745 mStackSupervisor.getDisplayOverrideConfiguration(displayId));
5746 }
5747 });
5748 }
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07005749
5750 @Override
5751 public void sendActivityResult(int callingUid, IBinder activityToken, String resultWho,
5752 int requestCode, int resultCode, Intent data) {
5753 synchronized (mGlobalLock) {
5754 final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
5755 if (r != null && r.getStack() != null) {
5756 r.getStack().sendActivityResultLocked(callingUid, r, resultWho, requestCode,
5757 resultCode, data);
5758 }
5759 }
5760 }
5761
5762 @Override
5763 public void clearPendingResultForActivity(IBinder activityToken,
5764 WeakReference<PendingIntentRecord> pir) {
5765 synchronized (mGlobalLock) {
5766 final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
5767 if (r != null && r.pendingResults != null) {
5768 r.pendingResults.remove(pir);
5769 }
5770 }
5771 }
5772
5773 @Override
5774 public IIntentSender getIntentSender(int type, String packageName,
5775 int callingUid, int userId, IBinder token, String resultWho,
5776 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5777 Bundle bOptions) {
5778 synchronized (mGlobalLock) {
5779 return getIntentSenderLocked(type, packageName, callingUid, userId, token,
5780 resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
5781 }
5782 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005783 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07005784}