blob: b369b7135b4ea72e866e23e806800c584573ec38 [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 Ogunwale214f3482018-10-04 11:00:47 -070042import static android.content.pm.ApplicationInfo.FLAG_FACTORY_TEST;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070043import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
44import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
Evan Rosky4505b352018-09-06 11:20:40 -070045import static android.content.pm.PackageManager.FEATURE_PC;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070046import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070047import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070048import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
49import static android.os.Build.VERSION_CODES.N;
Wale Ogunwale214f3482018-10-04 11:00:47 -070050import static android.os.FactoryTest.FACTORY_TEST_HIGH_LEVEL;
51import static android.os.FactoryTest.FACTORY_TEST_LOW_LEVEL;
52import static android.os.FactoryTest.FACTORY_TEST_OFF;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070053import static android.os.Process.SYSTEM_UID;
Evan Rosky4505b352018-09-06 11:20:40 -070054import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070055import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
56import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
57import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
58import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
Evan Rosky4505b352018-09-06 11:20:40 -070059import static android.provider.Settings.Global.HIDE_ERROR_DIALOGS;
60import static android.provider.Settings.System.FONT_SCALE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070061import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
62import static android.view.Display.DEFAULT_DISPLAY;
63import static android.view.Display.INVALID_DISPLAY;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070064import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
Wale Ogunwale6767eae2018-05-03 15:52:51 -070065import static android.view.WindowManager.TRANSIT_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070066import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070067import static android.view.WindowManager.TRANSIT_TASK_OPEN;
68import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
Evan Rosky4505b352018-09-06 11:20:40 -070069
Wale Ogunwale65ebd952018-04-25 15:41:44 -070070import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070071import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
72import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
73import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
74import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070075import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070076import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070077import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070078import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070079import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070080import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
81import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
82import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070083import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070084import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
85import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070086import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
87import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
88import static com.android.server.am.ActivityManagerService.ANIMATE;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070089import static com.android.server.am.ActivityManagerService.MY_PID;
90import static com.android.server.am.ActivityManagerService.SEND_LOCALE_TO_MOUNT_DAEMON_MSG;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070091import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070092import static com.android.server.am.ActivityManagerService.UPDATE_CONFIGURATION_MSG;
Evan Rosky4505b352018-09-06 11:20:40 -070093import static com.android.server.am.ActivityManagerService.dumpStackTraces;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070094import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070095import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070096import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
97import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
98import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
99import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
100import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
Evan Rosky4505b352018-09-06 11:20:40 -0700101import static com.android.server.am.ActivityTaskManagerService.H.REPORT_TIME_TRACKER_MSG;
102import static com.android.server.am.ActivityTaskManagerService.UiHandler.DISMISS_DIALOG_UI_MSG;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700103import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
104import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700105import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700106import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
Evan Rosky4505b352018-09-06 11:20:40 -0700107import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT;
108import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_DATA;
109import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
110import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700111import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
112import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700113
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700114import android.Manifest;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700115import android.annotation.NonNull;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700116import android.annotation.Nullable;
117import android.annotation.UserIdInt;
118import android.app.Activity;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700119import android.app.ActivityManager;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700120import android.app.ActivityManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700121import android.app.ActivityOptions;
122import android.app.ActivityTaskManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700123import android.app.ActivityThread;
124import android.app.AlertDialog;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700125import android.app.AppGlobals;
Evan Rosky4505b352018-09-06 11:20:40 -0700126import android.app.Dialog;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700127import android.app.IActivityController;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700128import android.app.IActivityTaskManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700129import android.app.IApplicationThread;
130import android.app.IAssistDataReceiver;
Wale Ogunwale53783742018-09-16 10:21:51 -0700131import android.app.INotificationManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700132import android.app.ITaskStackListener;
Wale Ogunwale53783742018-09-16 10:21:51 -0700133import android.app.Notification;
134import android.app.NotificationManager;
135import android.app.PendingIntent;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700136import android.app.PictureInPictureParams;
137import android.app.ProfilerInfo;
138import android.app.RemoteAction;
139import android.app.WaitResult;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700140import android.app.WindowConfiguration;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700141import android.app.admin.DevicePolicyCache;
142import android.app.assist.AssistContent;
143import android.app.assist.AssistStructure;
144import android.app.usage.UsageEvents;
145import android.content.ActivityNotFoundException;
146import android.content.ComponentName;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700147import android.content.ContentResolver;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700148import android.content.Context;
Evan Rosky4505b352018-09-06 11:20:40 -0700149import android.content.DialogInterface;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700150import android.content.IIntentSender;
151import android.content.Intent;
152import android.content.pm.ActivityInfo;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700153import android.content.pm.ApplicationInfo;
Yunfan Chen75157d72018-07-27 14:47:21 +0900154import android.content.pm.ConfigurationInfo;
Evan Rosky4505b352018-09-06 11:20:40 -0700155import android.content.pm.IPackageManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700156import android.content.pm.PackageManager;
Evan Rosky4505b352018-09-06 11:20:40 -0700157import android.content.pm.PackageManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700158import android.content.pm.ParceledListSlice;
159import android.content.pm.ResolveInfo;
Wale Ogunwale53783742018-09-16 10:21:51 -0700160import android.content.res.CompatibilityInfo;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700161import android.content.res.Configuration;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700162import android.content.res.Resources;
Evan Rosky4505b352018-09-06 11:20:40 -0700163import android.database.ContentObserver;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700164import android.graphics.Bitmap;
165import android.graphics.Point;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700166import android.graphics.Rect;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700167import android.metrics.LogMaker;
168import android.net.Uri;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700169import android.os.Binder;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700170import android.os.Build;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700171import android.os.Bundle;
Wale Ogunwale214f3482018-10-04 11:00:47 -0700172import android.os.FactoryTest;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700173import android.os.FileUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700174import android.os.Handler;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700175import android.os.IBinder;
Evan Rosky4505b352018-09-06 11:20:40 -0700176import android.os.IUserManager;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700177import android.os.LocaleList;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700178import android.os.Looper;
179import android.os.Message;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700180import android.os.PersistableBundle;
Evan Rosky4505b352018-09-06 11:20:40 -0700181import android.os.PowerManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700182import android.os.RemoteException;
Evan Rosky4505b352018-09-06 11:20:40 -0700183import android.os.ServiceManager;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700184import android.os.StrictMode;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700185import android.os.SystemClock;
186import android.os.SystemProperties;
Evan Rosky4505b352018-09-06 11:20:40 -0700187import android.os.Trace;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700188import android.os.UpdateLock;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700189import android.os.UserHandle;
Evan Rosky4505b352018-09-06 11:20:40 -0700190import android.os.UserManager;
191import android.os.WorkSource;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700192import android.provider.Settings;
193import android.service.voice.IVoiceInteractionSession;
194import android.service.voice.VoiceInteractionManagerInternal;
195import android.telecom.TelecomManager;
196import android.text.TextUtils;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700197import android.text.format.Time;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700198import android.util.ArrayMap;
199import android.util.EventLog;
200import android.util.Log;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700201import android.util.Slog;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700202import android.util.SparseArray;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700203import android.util.SparseIntArray;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700204import android.util.StatsLog;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700205import android.util.TimeUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700206import android.util.proto.ProtoOutputStream;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700207import android.view.IRecentsAnimationRunner;
208import android.view.RemoteAnimationAdapter;
209import android.view.RemoteAnimationDefinition;
Evan Rosky4505b352018-09-06 11:20:40 -0700210import android.view.WindowManager;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700211
Evan Rosky4505b352018-09-06 11:20:40 -0700212import com.android.internal.R;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700213import com.android.internal.annotations.VisibleForTesting;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700214import com.android.internal.app.AssistUtils;
Evan Rosky4505b352018-09-06 11:20:40 -0700215import com.android.internal.app.IAppOpsService;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700216import com.android.internal.app.IVoiceInteractor;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700217import com.android.internal.app.ProcessMap;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700218import com.android.internal.logging.MetricsLogger;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700219import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Wale Ogunwale53783742018-09-16 10:21:51 -0700220import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
221import com.android.internal.notification.SystemNotificationChannels;
Evan Rosky4505b352018-09-06 11:20:40 -0700222import com.android.internal.os.logging.MetricsLoggerWrapper;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700223import com.android.internal.policy.IKeyguardDismissCallback;
224import com.android.internal.policy.KeyguardDismissCallback;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700225import com.android.internal.util.Preconditions;
Wale Ogunwale53783742018-09-16 10:21:51 -0700226import com.android.internal.util.function.pooled.PooledLambda;
Evan Rosky4505b352018-09-06 11:20:40 -0700227import com.android.server.AppOpsService;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700228import com.android.server.AttributeCache;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700229import com.android.server.LocalServices;
230import com.android.server.SystemService;
Evan Rosky4505b352018-09-06 11:20:40 -0700231import com.android.server.SystemServiceManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700232import com.android.server.Watchdog;
Evan Rosky4505b352018-09-06 11:20:40 -0700233import com.android.server.pm.UserManagerService;
234import com.android.server.uri.UriGrantsManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700235import com.android.server.vr.VrManagerInternal;
Evan Rosky4505b352018-09-06 11:20:40 -0700236import com.android.server.wm.ActivityTaskManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700237import com.android.server.wm.PinnedStackWindowController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700238import com.android.server.wm.WindowManagerService;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700239
240import java.io.File;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700241import java.io.FileOutputStream;
242import java.io.IOException;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700243import java.io.PrintWriter;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700244import java.io.StringWriter;
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700245import java.lang.ref.WeakReference;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700246import java.util.ArrayList;
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700247import java.util.HashSet;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700248import java.util.List;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700249import java.util.Locale;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700250
251/**
252 * System service for managing activities and their containers (task, stacks, displays,... ).
253 *
254 * {@hide}
255 */
256public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
257 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityTaskManagerService" : TAG_AM;
258 private static final String TAG_STACK = TAG + POSTFIX_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700259 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
260 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
261 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
262 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
263 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700264 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700265
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700266 // How long we wait until we timeout on key dispatching.
267 private static final int KEY_DISPATCHING_TIMEOUT_MS = 5 * 1000;
268 // How long we wait until we timeout on key dispatching during instrumentation.
269 private static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS = 60 * 1000;
270
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700271 Context mContext;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700272 /**
273 * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
274 * change at runtime. Use mContext for non-UI purposes.
275 */
276 final Context mUiContext;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700277 H mH;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700278 UiHandler mUiHandler;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700279 ActivityManagerService mAm;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700280 ActivityManagerInternal mAmInternal;
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700281 UriGrantsManagerInternal mUgmInternal;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700282 private PackageManagerInternal mPmInternal;
Wale Ogunwale53783742018-09-16 10:21:51 -0700283 private ActivityTaskManagerInternal mInternal;
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700284 PendingIntentController mPendingIntentController;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700285 /* Global service lock used by the package the owns this service. */
286 Object mGlobalLock;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700287 ActivityStackSupervisor mStackSupervisor;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700288 WindowManagerService mWindowManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700289 private UserManagerService mUserManager;
290 private AppOpsService mAppOpsService;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700291 /** All processes currently running that might have a window organized by name. */
292 final ProcessMap<WindowProcessController> mProcessNames = new ProcessMap<>();
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700293 /** All processes we currently have running mapped by pid */
294 final SparseArray<WindowProcessController> mPidMap = new SparseArray<>();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700295 /** This is the process holding what we currently consider to be the "home" activity. */
296 WindowProcessController mHomeProcess;
Wale Ogunwale53783742018-09-16 10:21:51 -0700297 /** The currently running heavy-weight process, if any. */
298 WindowProcessController mHeavyWeightProcess = null;
Wale Ogunwale214f3482018-10-04 11:00:47 -0700299 boolean mHasHeavyWeightFeature;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700300 /**
301 * This is the process holding the activity the user last visited that is in a different process
302 * from the one they are currently in.
303 */
304 WindowProcessController mPreviousProcess;
305 /** The time at which the previous process was last visible. */
306 long mPreviousProcessVisibleTime;
307
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700308 /** List of intents that were used to start the most recent tasks. */
309 private RecentTasks mRecentTasks;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700310 /** State of external calls telling us if the device is awake or asleep. */
311 private boolean mKeyguardShown = false;
312
313 // Wrapper around VoiceInteractionServiceManager
314 private AssistUtils mAssistUtils;
315
316 // VoiceInteraction session ID that changes for each new request except when
317 // being called for multi-window assist in a single session.
318 private int mViSessionId = 1000;
319
320 // How long to wait in getAssistContextExtras for the activity and foreground services
321 // to respond with the result.
322 private static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
323
324 // How long top wait when going through the modern assist (which doesn't need to block
325 // on getting this result before starting to launch its UI).
326 private static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
327
328 // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
329 private static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
330
331 private final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
332
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700333 // Keeps track of the active voice interaction service component, notified from
334 // VoiceInteractionManagerService
335 ComponentName mActiveVoiceInteractionServiceComponent;
336
337 private VrController mVrController;
338 KeyguardController mKeyguardController;
339 private final ClientLifecycleManager mLifecycleManager;
340 private TaskChangeNotificationController mTaskChangeNotificationController;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700341 /** The controller for all operations related to locktask. */
342 private LockTaskController mLockTaskController;
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700343 private ActivityStartController mActivityStartController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700344
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700345 boolean mSuppressResizeConfigChanges;
346
347 private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
348 new UpdateConfigurationResult();
349
350 static final class UpdateConfigurationResult {
351 // Configuration changes that were updated.
352 int changes;
353 // If the activity was relaunched to match the new configuration.
354 boolean activityRelaunched;
355
356 void reset() {
357 changes = 0;
358 activityRelaunched = false;
359 }
360 }
361
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700362 /** Current sequencing integer of the configuration, for skipping old configurations. */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700363 private int mConfigurationSeq;
364 // To cache the list of supported system locales
365 private String[] mSupportedSystemLocales = null;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700366
367 /**
368 * Temp object used when global and/or display override configuration is updated. It is also
369 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
370 * anyone...
371 */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700372 private Configuration mTempConfig = new Configuration();
373
Wale Ogunwalef6733932018-06-27 05:14:34 -0700374 /** Temporary to avoid allocations. */
375 final StringBuilder mStringBuilder = new StringBuilder(256);
376
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700377 // Amount of time after a call to stopAppSwitches() during which we will
378 // prevent further untrusted switches from happening.
379 private static final long APP_SWITCH_DELAY_TIME = 5 * 1000;
380
381 /**
382 * The time at which we will allow normal application switches again,
383 * after a call to {@link #stopAppSwitches()}.
384 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700385 private long mAppSwitchesAllowedTime;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700386 /**
387 * This is set to true after the first switch after mAppSwitchesAllowedTime
388 * is set; any switches after that will clear the time.
389 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700390 private boolean mDidAppSwitch;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700391
392 IActivityController mController = null;
393 boolean mControllerIsAMonkey = false;
394
Wale Ogunwale214f3482018-10-04 11:00:47 -0700395 final int mFactoryTest;
396
397 /** Used to control how we initialize the service. */
398 ComponentName mTopComponent;
399 String mTopAction = Intent.ACTION_MAIN;
400 String mTopData;
401
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700402 /**
403 * Used to retain an update lock when the foreground activity is in
404 * immersive mode.
405 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700406 private final UpdateLock mUpdateLock = new UpdateLock("immersive");
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700407
408 /**
409 * Packages that are being allowed to perform unrestricted app switches. Mapping is
410 * User -> Type -> uid.
411 */
412 final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
413
414 /** The dimensions of the thumbnails in the Recents UI. */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700415 private int mThumbnailWidth;
416 private int mThumbnailHeight;
417 private float mFullscreenThumbnailScale;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700418
419 /**
420 * Flag that indicates if multi-window is enabled.
421 *
422 * For any particular form of multi-window to be enabled, generic multi-window must be enabled
423 * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
424 * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
425 * At least one of the forms of multi-window must be enabled in order for this flag to be
426 * initialized to 'true'.
427 *
428 * @see #mSupportsSplitScreenMultiWindow
429 * @see #mSupportsFreeformWindowManagement
430 * @see #mSupportsPictureInPicture
431 * @see #mSupportsMultiDisplay
432 */
433 boolean mSupportsMultiWindow;
434 boolean mSupportsSplitScreenMultiWindow;
435 boolean mSupportsFreeformWindowManagement;
436 boolean mSupportsPictureInPicture;
437 boolean mSupportsMultiDisplay;
438 boolean mForceResizableActivities;
439
440 final List<ActivityTaskManagerInternal.ScreenObserver> mScreenObservers = new ArrayList<>();
441
442 // VR Vr2d Display Id.
443 int mVr2dDisplayId = INVALID_DISPLAY;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700444
Wale Ogunwalef6733932018-06-27 05:14:34 -0700445 /**
446 * Set while we are wanting to sleep, to prevent any
447 * activities from being started/resumed.
448 *
449 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
450 *
451 * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
452 * while in the sleep state until there is a pending transition out of sleep, in which case
453 * mSleeping is set to false, and remains false while awake.
454 *
455 * Whether mSleeping can quickly toggled between true/false without the device actually
456 * display changing states is undefined.
457 */
458 private boolean mSleeping = false;
459
460 /**
461 * The process state used for processes that are running the top activities.
462 * This changes between TOP and TOP_SLEEPING to following mSleeping.
463 */
464 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
465
466 // Whether we should show our dialogs (ANR, crash, etc) or just perform their default action
467 // automatically. Important for devices without direct input devices.
468 private boolean mShowDialogs = true;
469
470 /** Set if we are shutting down the system, similar to sleeping. */
471 boolean mShuttingDown = false;
472
473 /**
474 * We want to hold a wake lock while running a voice interaction session, since
475 * this may happen with the screen off and we need to keep the CPU running to
476 * be able to continue to interact with the user.
477 */
478 PowerManager.WakeLock mVoiceWakeLock;
479
480 /**
481 * Set while we are running a voice interaction. This overrides sleeping while it is active.
482 */
483 IVoiceInteractionSession mRunningVoice;
484
485 /**
486 * The last resumed activity. This is identical to the current resumed activity most
487 * of the time but could be different when we're pausing one activity before we resume
488 * another activity.
489 */
490 ActivityRecord mLastResumedActivity;
491
492 /**
493 * The activity that is currently being traced as the active resumed activity.
494 *
495 * @see #updateResumedAppTrace
496 */
497 private @Nullable ActivityRecord mTracedResumedActivity;
498
499 /** If non-null, we are tracking the time the user spends in the currently focused app. */
500 AppTimeTracker mCurAppTimeTracker;
501
Wale Ogunwale008163e2018-07-23 23:11:08 -0700502 private AppWarnings mAppWarnings;
503
Wale Ogunwale53783742018-09-16 10:21:51 -0700504 /**
505 * Packages that the user has asked to have run in screen size
506 * compatibility mode instead of filling the screen.
507 */
508 CompatModePackages mCompatModePackages;
509
Wale Ogunwalef6733932018-06-27 05:14:34 -0700510 private FontScaleSettingObserver mFontScaleSettingObserver;
511
512 private final class FontScaleSettingObserver extends ContentObserver {
513 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
514 private final Uri mHideErrorDialogsUri = Settings.Global.getUriFor(HIDE_ERROR_DIALOGS);
515
516 public FontScaleSettingObserver() {
517 super(mH);
518 final ContentResolver resolver = mContext.getContentResolver();
519 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
520 resolver.registerContentObserver(mHideErrorDialogsUri, false, this,
521 UserHandle.USER_ALL);
522 }
523
524 @Override
525 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
526 if (mFontScaleUri.equals(uri)) {
527 updateFontScaleIfNeeded(userId);
528 } else if (mHideErrorDialogsUri.equals(uri)) {
529 synchronized (mGlobalLock) {
530 updateShouldShowDialogsLocked(getGlobalConfiguration());
531 }
532 }
533 }
534 }
535
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700536 ActivityTaskManagerService(Context context) {
537 mContext = context;
Wale Ogunwale214f3482018-10-04 11:00:47 -0700538 mFactoryTest = FactoryTest.getMode();
Wale Ogunwalef6733932018-06-27 05:14:34 -0700539 mUiContext = ActivityThread.currentActivityThread().getSystemUiContext();
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700540 mLifecycleManager = new ClientLifecycleManager();
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700541 }
542
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700543 void onSystemReady() {
Wale Ogunwale214f3482018-10-04 11:00:47 -0700544 mHasHeavyWeightFeature = mContext.getPackageManager().hasSystemFeature(
545 PackageManager.FEATURE_CANT_SAVE_STATE);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700546 mAssistUtils = new AssistUtils(mContext);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700547 mVrController.onSystemReady();
548 mRecentTasks.onSystemReadyLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700549 }
550
Wale Ogunwalef6733932018-06-27 05:14:34 -0700551 void onInitPowerManagement() {
552 mStackSupervisor.initPowerManagement();
553 final PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
554 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
555 mVoiceWakeLock.setReferenceCounted(false);
556 }
557
558 void installSystemProviders() {
559 mFontScaleSettingObserver = new FontScaleSettingObserver();
560 }
561
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700562 void retrieveSettings(ContentResolver resolver) {
563 final boolean freeformWindowManagement =
564 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
565 || Settings.Global.getInt(
566 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
567
568 final boolean supportsMultiWindow = ActivityTaskManager.supportsMultiWindow(mContext);
569 final boolean supportsPictureInPicture = supportsMultiWindow &&
570 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
571 final boolean supportsSplitScreenMultiWindow =
572 ActivityTaskManager.supportsSplitScreenMultiWindow(mContext);
573 final boolean supportsMultiDisplay = mContext.getPackageManager()
574 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
575 final boolean alwaysFinishActivities =
576 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
577 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
578 final boolean forceResizable = Settings.Global.getInt(
579 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
Garfield Tane0846042018-07-26 13:42:04 -0700580 final boolean isPc = mContext.getPackageManager().hasSystemFeature(FEATURE_PC);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700581
582 // Transfer any global setting for forcing RTL layout, into a System Property
583 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
584
585 final Configuration configuration = new Configuration();
586 Settings.System.getConfiguration(resolver, configuration);
587 if (forceRtl) {
588 // This will take care of setting the correct layout direction flags
589 configuration.setLayoutDirection(configuration.locale);
590 }
591
592 synchronized (mGlobalLock) {
593 mForceResizableActivities = forceResizable;
594 final boolean multiWindowFormEnabled = freeformWindowManagement
595 || supportsSplitScreenMultiWindow
596 || supportsPictureInPicture
597 || supportsMultiDisplay;
598 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
599 mSupportsMultiWindow = true;
600 mSupportsFreeformWindowManagement = freeformWindowManagement;
601 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
602 mSupportsPictureInPicture = supportsPictureInPicture;
603 mSupportsMultiDisplay = supportsMultiDisplay;
604 } else {
605 mSupportsMultiWindow = false;
606 mSupportsFreeformWindowManagement = false;
607 mSupportsSplitScreenMultiWindow = false;
608 mSupportsPictureInPicture = false;
609 mSupportsMultiDisplay = false;
610 }
611 mWindowManager.setForceResizableTasks(mForceResizableActivities);
612 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
Garfield Tane0846042018-07-26 13:42:04 -0700613 mWindowManager.setSupportsFreeformWindowManagement(mSupportsFreeformWindowManagement);
614 mWindowManager.setIsPc(isPc);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700615 // This happens before any activities are started, so we can change global configuration
616 // in-place.
617 updateConfigurationLocked(configuration, null, true);
618 final Configuration globalConfig = getGlobalConfiguration();
619 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
620
621 // Load resources only after the current configuration has been set.
622 final Resources res = mContext.getResources();
623 mThumbnailWidth = res.getDimensionPixelSize(
624 com.android.internal.R.dimen.thumbnail_width);
625 mThumbnailHeight = res.getDimensionPixelSize(
626 com.android.internal.R.dimen.thumbnail_height);
627
628 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
629 mFullscreenThumbnailScale = (float) res
630 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
631 (float) globalConfig.screenWidthDp;
632 } else {
633 mFullscreenThumbnailScale = res.getFraction(
634 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
635 }
636 }
637 }
638
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700639 // TODO: Will be converted to WM lock once transition is complete.
640 void setActivityManagerService(ActivityManagerService am) {
641 mAm = am;
642 mGlobalLock = mAm;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700643 mH = new H(mAm.mHandlerThread.getLooper());
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700644 mUiHandler = new UiHandler();
Wale Ogunwale53783742018-09-16 10:21:51 -0700645 final File systemDir = SystemServiceManager.ensureSystemDir();
646 mAppWarnings = new AppWarnings(this, mUiContext, mH, mUiHandler, systemDir);
647 mCompatModePackages = new CompatModePackages(this, systemDir, mH);
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700648 mPendingIntentController = mAm.mPendingIntentController;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700649
650 mTempConfig.setToDefaults();
651 mTempConfig.setLocales(LocaleList.getDefault());
652 mConfigurationSeq = mTempConfig.seq = 1;
653 mStackSupervisor = createStackSupervisor();
654 mStackSupervisor.onConfigurationChanged(mTempConfig);
655
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700656 mTaskChangeNotificationController =
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700657 new TaskChangeNotificationController(mGlobalLock, mStackSupervisor, mH);
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700658 mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mH);
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700659 mActivityStartController = new ActivityStartController(this);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700660 mRecentTasks = createRecentTasks();
661 mStackSupervisor.setRecentTasks(mRecentTasks);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700662 mVrController = new VrController(mGlobalLock);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700663 mKeyguardController = mStackSupervisor.getKeyguardController();
664 }
665
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700666 void onActivityManagerInternalAdded() {
667 mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700668 mUgmInternal = LocalServices.getService(UriGrantsManagerInternal.class);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700669 }
670
Yunfan Chen75157d72018-07-27 14:47:21 +0900671 int increaseConfigurationSeqLocked() {
672 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
673 return mConfigurationSeq;
674 }
675
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700676 protected ActivityStackSupervisor createStackSupervisor() {
677 final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mH.getLooper());
678 supervisor.initialize();
679 return supervisor;
680 }
681
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700682 void setWindowManager(WindowManagerService wm) {
683 mWindowManager = wm;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700684 mLockTaskController.setWindowManager(wm);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700685 }
686
Wale Ogunwalef6733932018-06-27 05:14:34 -0700687 UserManagerService getUserManager() {
688 if (mUserManager == null) {
689 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
690 mUserManager = (UserManagerService) IUserManager.Stub.asInterface(b);
691 }
692 return mUserManager;
693 }
694
695 AppOpsService getAppOpsService() {
696 if (mAppOpsService == null) {
697 IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
698 mAppOpsService = (AppOpsService) IAppOpsService.Stub.asInterface(b);
699 }
700 return mAppOpsService;
701 }
702
703 boolean hasUserRestriction(String restriction, int userId) {
704 return getUserManager().hasUserRestriction(restriction, userId);
705 }
706
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700707 protected RecentTasks createRecentTasks() {
708 return new RecentTasks(this, mStackSupervisor);
709 }
710
711 RecentTasks getRecentTasks() {
712 return mRecentTasks;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700713 }
714
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700715 ClientLifecycleManager getLifecycleManager() {
716 return mLifecycleManager;
717 }
718
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700719 ActivityStartController getActivityStartController() {
720 return mActivityStartController;
721 }
722
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700723 TaskChangeNotificationController getTaskChangeNotificationController() {
724 return mTaskChangeNotificationController;
725 }
726
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700727 LockTaskController getLockTaskController() {
728 return mLockTaskController;
729 }
730
Yunfan Chen75157d72018-07-27 14:47:21 +0900731 /**
732 * Return the global configuration used by the process corresponding to the input pid. This is
733 * usually the global configuration with some overrides specific to that process.
734 */
735 Configuration getGlobalConfigurationForCallingPid() {
736 final int pid = Binder.getCallingPid();
737 if (pid == MY_PID || pid < 0) {
738 return getGlobalConfiguration();
739 }
740 synchronized (mGlobalLock) {
741 final WindowProcessController app = mPidMap.get(pid);
742 return app != null ? app.getConfiguration() : getGlobalConfiguration();
743 }
744 }
745
746 /**
747 * Return the device configuration info used by the process corresponding to the input pid.
748 * The value is consistent with the global configuration for the process.
749 */
750 @Override
751 public ConfigurationInfo getDeviceConfigurationInfo() {
752 ConfigurationInfo config = new ConfigurationInfo();
753 synchronized (mGlobalLock) {
754 final Configuration globalConfig = getGlobalConfigurationForCallingPid();
755 config.reqTouchScreen = globalConfig.touchscreen;
756 config.reqKeyboardType = globalConfig.keyboard;
757 config.reqNavigation = globalConfig.navigation;
758 if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
759 || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
760 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
761 }
762 if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
763 && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
764 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
765 }
766 config.reqGlEsVersion = mAm.GL_ES_VERSION;
767 }
768 return config;
769 }
770
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700771 private void start() {
Wale Ogunwale53783742018-09-16 10:21:51 -0700772 mInternal = new LocalService();
773 LocalServices.addService(ActivityTaskManagerInternal.class, mInternal);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700774 }
775
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700776 public static final class Lifecycle extends SystemService {
777 private final ActivityTaskManagerService mService;
778
779 public Lifecycle(Context context) {
780 super(context);
781 mService = new ActivityTaskManagerService(context);
782 }
783
784 @Override
785 public void onStart() {
786 publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700787 mService.start();
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700788 }
789
790 public ActivityTaskManagerService getService() {
791 return mService;
792 }
793 }
794
795 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700796 public final int startActivity(IApplicationThread caller, String callingPackage,
797 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
798 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
799 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
800 resultWho, requestCode, startFlags, profilerInfo, bOptions,
801 UserHandle.getCallingUserId());
802 }
803
804 @Override
805 public final int startActivities(IApplicationThread caller, String callingPackage,
806 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
807 int userId) {
808 final String reason = "startActivities";
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700809 enforceNotIsolatedCaller(reason);
810 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, reason);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700811 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700812 return getActivityStartController().startActivities(caller, -1, callingPackage, intents,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100813 resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId, reason,
814 null /* originatingPendingIntent */);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700815 }
816
817 @Override
818 public int startActivityAsUser(IApplicationThread caller, String callingPackage,
819 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
820 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
821 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
822 resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
823 true /*validateIncomingUser*/);
824 }
825
826 int startActivityAsUser(IApplicationThread caller, String callingPackage,
827 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
828 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
829 boolean validateIncomingUser) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700830 enforceNotIsolatedCaller("startActivityAsUser");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700831
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700832 userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700833 Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
834
835 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700836 return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700837 .setCaller(caller)
838 .setCallingPackage(callingPackage)
839 .setResolvedType(resolvedType)
840 .setResultTo(resultTo)
841 .setResultWho(resultWho)
842 .setRequestCode(requestCode)
843 .setStartFlags(startFlags)
844 .setProfilerInfo(profilerInfo)
845 .setActivityOptions(bOptions)
846 .setMayWait(userId)
847 .execute();
848
849 }
850
851 @Override
852 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
853 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700854 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions) {
855 enforceNotIsolatedCaller("startActivityIntentSender");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700856 // Refuse possible leaked file descriptors
857 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
858 throw new IllegalArgumentException("File descriptors passed in Intent");
859 }
860
861 if (!(target instanceof PendingIntentRecord)) {
862 throw new IllegalArgumentException("Bad PendingIntent object");
863 }
864
865 PendingIntentRecord pir = (PendingIntentRecord)target;
866
867 synchronized (mGlobalLock) {
868 // If this is coming from the currently resumed activity, it is
869 // effectively saying that app switches are allowed at this point.
Andrii Kulian5f750bc2018-07-17 08:57:23 -0700870 final ActivityStack stack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700871 if (stack.mResumedActivity != null &&
872 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700873 mAppSwitchesAllowedTime = 0;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700874 }
875 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700876 return pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700877 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700878 }
879
880 @Override
881 public boolean startNextMatchingActivity(IBinder callingActivity, Intent intent,
882 Bundle bOptions) {
883 // Refuse possible leaked file descriptors
884 if (intent != null && intent.hasFileDescriptors()) {
885 throw new IllegalArgumentException("File descriptors passed in Intent");
886 }
887 SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
888
889 synchronized (mGlobalLock) {
890 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
891 if (r == null) {
892 SafeActivityOptions.abort(options);
893 return false;
894 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700895 if (!r.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700896 // The caller is not running... d'oh!
897 SafeActivityOptions.abort(options);
898 return false;
899 }
900 intent = new Intent(intent);
901 // The caller is not allowed to change the data.
902 intent.setDataAndType(r.intent.getData(), r.intent.getType());
903 // And we are resetting to find the next component...
904 intent.setComponent(null);
905
906 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
907
908 ActivityInfo aInfo = null;
909 try {
910 List<ResolveInfo> resolves =
911 AppGlobals.getPackageManager().queryIntentActivities(
912 intent, r.resolvedType,
913 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
914 UserHandle.getCallingUserId()).getList();
915
916 // Look for the original activity in the list...
917 final int N = resolves != null ? resolves.size() : 0;
918 for (int i=0; i<N; i++) {
919 ResolveInfo rInfo = resolves.get(i);
920 if (rInfo.activityInfo.packageName.equals(r.packageName)
921 && rInfo.activityInfo.name.equals(r.info.name)) {
922 // We found the current one... the next matching is
923 // after it.
924 i++;
925 if (i<N) {
926 aInfo = resolves.get(i).activityInfo;
927 }
928 if (debug) {
929 Slog.v(TAG, "Next matching activity: found current " + r.packageName
930 + "/" + r.info.name);
931 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
932 ? "null" : aInfo.packageName + "/" + aInfo.name));
933 }
934 break;
935 }
936 }
937 } catch (RemoteException e) {
938 }
939
940 if (aInfo == null) {
941 // Nobody who is next!
942 SafeActivityOptions.abort(options);
943 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
944 return false;
945 }
946
947 intent.setComponent(new ComponentName(
948 aInfo.applicationInfo.packageName, aInfo.name));
949 intent.setFlags(intent.getFlags()&~(
950 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
951 Intent.FLAG_ACTIVITY_CLEAR_TOP|
952 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
953 FLAG_ACTIVITY_NEW_TASK));
954
955 // Okay now we need to start the new activity, replacing the currently running activity.
956 // This is a little tricky because we want to start the new one as if the current one is
957 // finished, but not finish the current one first so that there is no flicker.
958 // And thus...
959 final boolean wasFinishing = r.finishing;
960 r.finishing = true;
961
962 // Propagate reply information over to the new activity.
963 final ActivityRecord resultTo = r.resultTo;
964 final String resultWho = r.resultWho;
965 final int requestCode = r.requestCode;
966 r.resultTo = null;
967 if (resultTo != null) {
968 resultTo.removeResultsLocked(r, resultWho, requestCode);
969 }
970
971 final long origId = Binder.clearCallingIdentity();
972 // TODO(b/64750076): Check if calling pid should really be -1.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700973 final int res = getActivityStartController()
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700974 .obtainStarter(intent, "startNextMatchingActivity")
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700975 .setCaller(r.app.getThread())
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700976 .setResolvedType(r.resolvedType)
977 .setActivityInfo(aInfo)
978 .setResultTo(resultTo != null ? resultTo.appToken : null)
979 .setResultWho(resultWho)
980 .setRequestCode(requestCode)
981 .setCallingPid(-1)
982 .setCallingUid(r.launchedFromUid)
983 .setCallingPackage(r.launchedFromPackage)
984 .setRealCallingPid(-1)
985 .setRealCallingUid(r.launchedFromUid)
986 .setActivityOptions(options)
987 .execute();
988 Binder.restoreCallingIdentity(origId);
989
990 r.finishing = wasFinishing;
991 if (res != ActivityManager.START_SUCCESS) {
992 return false;
993 }
994 return true;
995 }
996 }
997
998 @Override
999 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
1000 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1001 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
1002 final WaitResult res = new WaitResult();
1003 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001004 enforceNotIsolatedCaller("startActivityAndWait");
1005 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
1006 userId, "startActivityAndWait");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001007 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001008 getActivityStartController().obtainStarter(intent, "startActivityAndWait")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001009 .setCaller(caller)
1010 .setCallingPackage(callingPackage)
1011 .setResolvedType(resolvedType)
1012 .setResultTo(resultTo)
1013 .setResultWho(resultWho)
1014 .setRequestCode(requestCode)
1015 .setStartFlags(startFlags)
1016 .setActivityOptions(bOptions)
1017 .setMayWait(userId)
1018 .setProfilerInfo(profilerInfo)
1019 .setWaitResult(res)
1020 .execute();
1021 }
1022 return res;
1023 }
1024
1025 @Override
1026 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
1027 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1028 int startFlags, Configuration config, Bundle bOptions, int userId) {
1029 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001030 enforceNotIsolatedCaller("startActivityWithConfig");
1031 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
1032 "startActivityWithConfig");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001033 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001034 return getActivityStartController().obtainStarter(intent, "startActivityWithConfig")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001035 .setCaller(caller)
1036 .setCallingPackage(callingPackage)
1037 .setResolvedType(resolvedType)
1038 .setResultTo(resultTo)
1039 .setResultWho(resultWho)
1040 .setRequestCode(requestCode)
1041 .setStartFlags(startFlags)
1042 .setGlobalConfiguration(config)
1043 .setActivityOptions(bOptions)
1044 .setMayWait(userId)
1045 .execute();
1046 }
1047 }
1048
1049 @Override
1050 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
1051 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1052 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
1053 int userId) {
1054
1055 // This is very dangerous -- it allows you to perform a start activity (including
1056 // permission grants) as any app that may launch one of your own activities. So
1057 // we will only allow this to be done from activities that are part of the core framework,
1058 // and then only when they are running as the system.
1059 final ActivityRecord sourceRecord;
1060 final int targetUid;
1061 final String targetPackage;
1062 final boolean isResolver;
1063 synchronized (mGlobalLock) {
1064 if (resultTo == null) {
1065 throw new SecurityException("Must be called from an activity");
1066 }
1067 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
1068 if (sourceRecord == null) {
1069 throw new SecurityException("Called with bad activity token: " + resultTo);
1070 }
1071 if (!sourceRecord.info.packageName.equals("android")) {
1072 throw new SecurityException(
1073 "Must be called from an activity that is declared in the android package");
1074 }
1075 if (sourceRecord.app == null) {
1076 throw new SecurityException("Called without a process attached to activity");
1077 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001078 if (UserHandle.getAppId(sourceRecord.app.mUid) != SYSTEM_UID) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001079 // This is still okay, as long as this activity is running under the
1080 // uid of the original calling activity.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001081 if (sourceRecord.app.mUid != sourceRecord.launchedFromUid) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001082 throw new SecurityException(
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001083 "Calling activity in uid " + sourceRecord.app.mUid
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001084 + " must be system uid or original calling uid "
1085 + sourceRecord.launchedFromUid);
1086 }
1087 }
1088 if (ignoreTargetSecurity) {
1089 if (intent.getComponent() == null) {
1090 throw new SecurityException(
1091 "Component must be specified with ignoreTargetSecurity");
1092 }
1093 if (intent.getSelector() != null) {
1094 throw new SecurityException(
1095 "Selector not allowed with ignoreTargetSecurity");
1096 }
1097 }
1098 targetUid = sourceRecord.launchedFromUid;
1099 targetPackage = sourceRecord.launchedFromPackage;
1100 isResolver = sourceRecord.isResolverOrChildActivity();
1101 }
1102
1103 if (userId == UserHandle.USER_NULL) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001104 userId = UserHandle.getUserId(sourceRecord.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001105 }
1106
1107 // TODO: Switch to user app stacks here.
1108 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001109 return getActivityStartController().obtainStarter(intent, "startActivityAsCaller")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001110 .setCallingUid(targetUid)
1111 .setCallingPackage(targetPackage)
1112 .setResolvedType(resolvedType)
1113 .setResultTo(resultTo)
1114 .setResultWho(resultWho)
1115 .setRequestCode(requestCode)
1116 .setStartFlags(startFlags)
1117 .setActivityOptions(bOptions)
1118 .setMayWait(userId)
1119 .setIgnoreTargetSecurity(ignoreTargetSecurity)
1120 .setFilterCallingUid(isResolver ? 0 /* system */ : targetUid)
1121 .execute();
1122 } catch (SecurityException e) {
1123 // XXX need to figure out how to propagate to original app.
1124 // A SecurityException here is generally actually a fault of the original
1125 // calling activity (such as a fairly granting permissions), so propagate it
1126 // back to them.
1127 /*
1128 StringBuilder msg = new StringBuilder();
1129 msg.append("While launching");
1130 msg.append(intent.toString());
1131 msg.append(": ");
1132 msg.append(e.getMessage());
1133 */
1134 throw e;
1135 }
1136 }
1137
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001138 int handleIncomingUser(int callingPid, int callingUid, int userId, String name) {
1139 return mAmInternal.handleIncomingUser(callingPid, callingUid, userId, false /* allowAll */,
1140 ALLOW_FULL_ONLY, name, null /* callerPackage */);
1141 }
1142
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001143 @Override
1144 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
1145 Intent intent, String resolvedType, IVoiceInteractionSession session,
1146 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
1147 Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001148 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001149 if (session == null || interactor == null) {
1150 throw new NullPointerException("null session or interactor");
1151 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001152 userId = handleIncomingUser(callingPid, callingUid, userId, "startVoiceActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001153 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001154 return getActivityStartController().obtainStarter(intent, "startVoiceActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001155 .setCallingUid(callingUid)
1156 .setCallingPackage(callingPackage)
1157 .setResolvedType(resolvedType)
1158 .setVoiceSession(session)
1159 .setVoiceInteractor(interactor)
1160 .setStartFlags(startFlags)
1161 .setProfilerInfo(profilerInfo)
1162 .setActivityOptions(bOptions)
1163 .setMayWait(userId)
1164 .execute();
1165 }
1166
1167 @Override
1168 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
1169 Intent intent, String resolvedType, Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001170 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
1171 userId = handleIncomingUser(callingPid, callingUid, userId, "startAssistantActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001172
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001173 return getActivityStartController().obtainStarter(intent, "startAssistantActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001174 .setCallingUid(callingUid)
1175 .setCallingPackage(callingPackage)
1176 .setResolvedType(resolvedType)
1177 .setActivityOptions(bOptions)
1178 .setMayWait(userId)
1179 .execute();
1180 }
1181
1182 @Override
1183 public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
1184 IRecentsAnimationRunner recentsAnimationRunner) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001185 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001186 final int callingPid = Binder.getCallingPid();
1187 final long origId = Binder.clearCallingIdentity();
1188 try {
1189 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07001190 final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
1191 final int recentsUid = mRecentTasks.getRecentsComponentUid();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001192
1193 // Start a new recents animation
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001194 final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
1195 getActivityStartController(), mWindowManager, callingPid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001196 anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
1197 recentsUid, assistDataReceiver);
1198 }
1199 } finally {
1200 Binder.restoreCallingIdentity(origId);
1201 }
1202 }
1203
1204 @Override
1205 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001206 enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001207 "startActivityFromRecents()");
1208
1209 final int callingPid = Binder.getCallingPid();
1210 final int callingUid = Binder.getCallingUid();
1211 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(bOptions);
1212 final long origId = Binder.clearCallingIdentity();
1213 try {
1214 synchronized (mGlobalLock) {
1215 return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
1216 safeOptions);
1217 }
1218 } finally {
1219 Binder.restoreCallingIdentity(origId);
1220 }
1221 }
1222
1223 /**
1224 * This is the internal entry point for handling Activity.finish().
1225 *
1226 * @param token The Binder token referencing the Activity we want to finish.
1227 * @param resultCode Result code, if any, from this Activity.
1228 * @param resultData Result data (Intent), if any, from this Activity.
1229 * @param finishTask Whether to finish the task associated with this Activity.
1230 *
1231 * @return Returns true if the activity successfully finished, or false if it is still running.
1232 */
1233 @Override
1234 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
1235 int finishTask) {
1236 // Refuse possible leaked file descriptors
1237 if (resultData != null && resultData.hasFileDescriptors()) {
1238 throw new IllegalArgumentException("File descriptors passed in Intent");
1239 }
1240
1241 synchronized (mGlobalLock) {
1242 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1243 if (r == null) {
1244 return true;
1245 }
1246 // Keep track of the root activity of the task before we finish it
1247 TaskRecord tr = r.getTask();
1248 ActivityRecord rootR = tr.getRootActivity();
1249 if (rootR == null) {
1250 Slog.w(TAG, "Finishing task with all activities already finished");
1251 }
1252 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
1253 // finish.
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001254 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001255 return false;
1256 }
1257
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001258 // TODO: There is a dup. of this block of code in ActivityStack.navigateUpToLocked
1259 // We should consolidate.
1260 if (mController != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001261 // Find the first activity that is not finishing.
1262 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
1263 if (next != null) {
1264 // ask watcher if this is allowed
1265 boolean resumeOK = true;
1266 try {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001267 resumeOK = mController.activityResuming(next.packageName);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001268 } catch (RemoteException e) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001269 mController = null;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001270 Watchdog.getInstance().setActivityController(null);
1271 }
1272
1273 if (!resumeOK) {
1274 Slog.i(TAG, "Not finishing activity because controller resumed");
1275 return false;
1276 }
1277 }
1278 }
1279 final long origId = Binder.clearCallingIdentity();
1280 try {
1281 boolean res;
1282 final boolean finishWithRootActivity =
1283 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
1284 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
1285 || (finishWithRootActivity && r == rootR)) {
1286 // If requested, remove the task that is associated to this activity only if it
1287 // was the root activity in the task. The result code and data is ignored
1288 // because we don't support returning them across task boundaries. Also, to
1289 // keep backwards compatibility we remove the task from recents when finishing
1290 // task with root activity.
1291 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
1292 finishWithRootActivity, "finish-activity");
1293 if (!res) {
1294 Slog.i(TAG, "Removing task failed to finish activity");
1295 }
Garfield Tan2746ab52018-07-25 12:33:01 -07001296 // Explicitly dismissing the activity so reset its relaunch flag.
1297 r.mRelaunchReason = ActivityRecord.RELAUNCH_REASON_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001298 } else {
1299 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
1300 resultData, "app-request", true);
1301 if (!res) {
1302 Slog.i(TAG, "Failed to finish by app-request");
1303 }
1304 }
1305 return res;
1306 } finally {
1307 Binder.restoreCallingIdentity(origId);
1308 }
1309 }
1310 }
1311
1312 @Override
1313 public boolean finishActivityAffinity(IBinder token) {
1314 synchronized (mGlobalLock) {
1315 final long origId = Binder.clearCallingIdentity();
1316 try {
1317 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1318 if (r == null) {
1319 return false;
1320 }
1321
1322 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
1323 // can finish.
1324 final TaskRecord task = r.getTask();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001325 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001326 return false;
1327 }
1328 return task.getStack().finishActivityAffinityLocked(r);
1329 } finally {
1330 Binder.restoreCallingIdentity(origId);
1331 }
1332 }
1333 }
1334
1335 @Override
1336 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
1337 final long origId = Binder.clearCallingIdentity();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001338 try {
1339 WindowProcessController proc = null;
1340 synchronized (mGlobalLock) {
1341 ActivityStack stack = ActivityRecord.getStackLocked(token);
1342 if (stack == null) {
1343 return;
1344 }
1345 final ActivityRecord r = mStackSupervisor.activityIdleInternalLocked(token,
1346 false /* fromTimeout */, false /* processPausingActivities */, config);
1347 if (r != null) {
1348 proc = r.app;
1349 }
1350 if (stopProfiling && proc != null) {
1351 proc.clearProfilerIfNeeded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001352 }
1353 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001354 } finally {
1355 Binder.restoreCallingIdentity(origId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001356 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001357 }
1358
1359 @Override
1360 public final void activityResumed(IBinder token) {
1361 final long origId = Binder.clearCallingIdentity();
1362 synchronized (mGlobalLock) {
1363 ActivityRecord.activityResumedLocked(token);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001364 mWindowManager.notifyAppResumedFinished(token);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001365 }
1366 Binder.restoreCallingIdentity(origId);
1367 }
1368
1369 @Override
1370 public final void activityPaused(IBinder token) {
1371 final long origId = Binder.clearCallingIdentity();
1372 synchronized (mGlobalLock) {
1373 ActivityStack stack = ActivityRecord.getStackLocked(token);
1374 if (stack != null) {
1375 stack.activityPausedLocked(token, false);
1376 }
1377 }
1378 Binder.restoreCallingIdentity(origId);
1379 }
1380
1381 @Override
1382 public final void activityStopped(IBinder token, Bundle icicle,
1383 PersistableBundle persistentState, CharSequence description) {
1384 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
1385
1386 // Refuse possible leaked file descriptors
1387 if (icicle != null && icicle.hasFileDescriptors()) {
1388 throw new IllegalArgumentException("File descriptors passed in Bundle");
1389 }
1390
1391 final long origId = Binder.clearCallingIdentity();
1392
1393 synchronized (mGlobalLock) {
1394 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1395 if (r != null) {
1396 r.activityStoppedLocked(icicle, persistentState, description);
1397 }
1398 }
1399
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001400 mAmInternal.trimApplications();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001401
1402 Binder.restoreCallingIdentity(origId);
1403 }
1404
1405 @Override
1406 public final void activityDestroyed(IBinder token) {
1407 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
1408 synchronized (mGlobalLock) {
1409 ActivityStack stack = ActivityRecord.getStackLocked(token);
1410 if (stack != null) {
1411 stack.activityDestroyedLocked(token, "activityDestroyed");
1412 }
1413 }
1414 }
1415
1416 @Override
1417 public final void activityRelaunched(IBinder token) {
1418 final long origId = Binder.clearCallingIdentity();
1419 synchronized (mGlobalLock) {
1420 mStackSupervisor.activityRelaunchedLocked(token);
1421 }
1422 Binder.restoreCallingIdentity(origId);
1423 }
1424
1425 public final void activitySlept(IBinder token) {
1426 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
1427
1428 final long origId = Binder.clearCallingIdentity();
1429
1430 synchronized (mGlobalLock) {
1431 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1432 if (r != null) {
1433 mStackSupervisor.activitySleptLocked(r);
1434 }
1435 }
1436
1437 Binder.restoreCallingIdentity(origId);
1438 }
1439
1440 @Override
1441 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
1442 synchronized (mGlobalLock) {
1443 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1444 if (r == null) {
1445 return;
1446 }
1447 final long origId = Binder.clearCallingIdentity();
1448 try {
1449 r.setRequestedOrientation(requestedOrientation);
1450 } finally {
1451 Binder.restoreCallingIdentity(origId);
1452 }
1453 }
1454 }
1455
1456 @Override
1457 public int getRequestedOrientation(IBinder token) {
1458 synchronized (mGlobalLock) {
1459 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1460 if (r == null) {
1461 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
1462 }
1463 return r.getRequestedOrientation();
1464 }
1465 }
1466
1467 @Override
1468 public void setImmersive(IBinder token, boolean immersive) {
1469 synchronized (mGlobalLock) {
1470 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1471 if (r == null) {
1472 throw new IllegalArgumentException();
1473 }
1474 r.immersive = immersive;
1475
1476 // update associated state if we're frontmost
Andrii Kulian52d255c2018-07-13 11:32:19 -07001477 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001478 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001479 applyUpdateLockStateLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001480 }
1481 }
1482 }
1483
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001484 void applyUpdateLockStateLocked(ActivityRecord r) {
1485 // Modifications to the UpdateLock state are done on our handler, outside
1486 // the activity manager's locks. The new state is determined based on the
1487 // state *now* of the relevant activity record. The object is passed to
1488 // the handler solely for logging detail, not to be consulted/modified.
1489 final boolean nextState = r != null && r.immersive;
1490 mH.post(() -> {
1491 if (mUpdateLock.isHeld() != nextState) {
1492 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1493 "Applying new update lock state '" + nextState + "' for " + r);
1494 if (nextState) {
1495 mUpdateLock.acquire();
1496 } else {
1497 mUpdateLock.release();
1498 }
1499 }
1500 });
1501 }
1502
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001503 @Override
1504 public boolean isImmersive(IBinder token) {
1505 synchronized (mGlobalLock) {
1506 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1507 if (r == null) {
1508 throw new IllegalArgumentException();
1509 }
1510 return r.immersive;
1511 }
1512 }
1513
1514 @Override
1515 public boolean isTopActivityImmersive() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001516 enforceNotIsolatedCaller("isTopActivityImmersive");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001517 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001518 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001519 return (r != null) ? r.immersive : false;
1520 }
1521 }
1522
1523 @Override
1524 public void overridePendingTransition(IBinder token, String packageName,
1525 int enterAnim, int exitAnim) {
1526 synchronized (mGlobalLock) {
1527 ActivityRecord self = ActivityRecord.isInStackLocked(token);
1528 if (self == null) {
1529 return;
1530 }
1531
1532 final long origId = Binder.clearCallingIdentity();
1533
1534 if (self.isState(
1535 ActivityStack.ActivityState.RESUMED, ActivityStack.ActivityState.PAUSING)) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001536 mWindowManager.overridePendingAppTransition(packageName,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001537 enterAnim, exitAnim, null);
1538 }
1539
1540 Binder.restoreCallingIdentity(origId);
1541 }
1542 }
1543
1544 @Override
1545 public int getFrontActivityScreenCompatMode() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001546 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
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 return ActivityManager.COMPAT_MODE_UNKNOWN;
1551 }
Wale Ogunwale53783742018-09-16 10:21:51 -07001552 return mCompatModePackages.computeCompatModeLocked(r.info.applicationInfo);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001553 }
1554 }
1555
1556 @Override
1557 public void setFrontActivityScreenCompatMode(int mode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001558 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001559 "setFrontActivityScreenCompatMode");
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001560 ApplicationInfo ai;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001561 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001562 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001563 if (r == null) {
1564 Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity");
1565 return;
1566 }
1567 ai = r.info.applicationInfo;
Wale Ogunwale53783742018-09-16 10:21:51 -07001568 mCompatModePackages.setPackageScreenCompatModeLocked(ai, mode);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001569 }
1570 }
1571
1572 @Override
1573 public int getLaunchedFromUid(IBinder activityToken) {
1574 ActivityRecord srec;
1575 synchronized (mGlobalLock) {
1576 srec = ActivityRecord.forTokenLocked(activityToken);
1577 }
1578 if (srec == null) {
1579 return -1;
1580 }
1581 return srec.launchedFromUid;
1582 }
1583
1584 @Override
1585 public String getLaunchedFromPackage(IBinder activityToken) {
1586 ActivityRecord srec;
1587 synchronized (mGlobalLock) {
1588 srec = ActivityRecord.forTokenLocked(activityToken);
1589 }
1590 if (srec == null) {
1591 return null;
1592 }
1593 return srec.launchedFromPackage;
1594 }
1595
1596 @Override
1597 public boolean convertFromTranslucent(IBinder token) {
1598 final long origId = Binder.clearCallingIdentity();
1599 try {
1600 synchronized (mGlobalLock) {
1601 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1602 if (r == null) {
1603 return false;
1604 }
1605 final boolean translucentChanged = r.changeWindowTranslucency(true);
1606 if (translucentChanged) {
1607 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
1608 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001609 mWindowManager.setAppFullscreen(token, true);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001610 return translucentChanged;
1611 }
1612 } finally {
1613 Binder.restoreCallingIdentity(origId);
1614 }
1615 }
1616
1617 @Override
1618 public boolean convertToTranslucent(IBinder token, Bundle options) {
1619 SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
1620 final long origId = Binder.clearCallingIdentity();
1621 try {
1622 synchronized (mGlobalLock) {
1623 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1624 if (r == null) {
1625 return false;
1626 }
1627 final TaskRecord task = r.getTask();
1628 int index = task.mActivities.lastIndexOf(r);
1629 if (index > 0) {
1630 ActivityRecord under = task.mActivities.get(index - 1);
1631 under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
1632 }
1633 final boolean translucentChanged = r.changeWindowTranslucency(false);
1634 if (translucentChanged) {
1635 r.getStack().convertActivityToTranslucent(r);
1636 }
1637 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001638 mWindowManager.setAppFullscreen(token, false);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001639 return translucentChanged;
1640 }
1641 } finally {
1642 Binder.restoreCallingIdentity(origId);
1643 }
1644 }
1645
1646 @Override
1647 public void notifyActivityDrawn(IBinder token) {
1648 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
1649 synchronized (mGlobalLock) {
1650 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
1651 if (r != null) {
1652 r.getStack().notifyActivityDrawnLocked(r);
1653 }
1654 }
1655 }
1656
1657 @Override
1658 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
1659 synchronized (mGlobalLock) {
1660 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1661 if (r == null) {
1662 return;
1663 }
1664 r.reportFullyDrawnLocked(restoredFromBundle);
1665 }
1666 }
1667
1668 @Override
1669 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
1670 synchronized (mGlobalLock) {
1671 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
1672 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
1673 return stack.mDisplayId;
1674 }
1675 return DEFAULT_DISPLAY;
1676 }
1677 }
1678
1679 @Override
1680 public ActivityManager.StackInfo getFocusedStackInfo() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001681 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001682 long ident = Binder.clearCallingIdentity();
1683 try {
1684 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001685 ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001686 if (focusedStack != null) {
1687 return mStackSupervisor.getStackInfo(focusedStack.mStackId);
1688 }
1689 return null;
1690 }
1691 } finally {
1692 Binder.restoreCallingIdentity(ident);
1693 }
1694 }
1695
1696 @Override
1697 public void setFocusedStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001698 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001699 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
1700 final long callingId = Binder.clearCallingIdentity();
1701 try {
1702 synchronized (mGlobalLock) {
1703 final ActivityStack stack = mStackSupervisor.getStack(stackId);
1704 if (stack == null) {
1705 Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
1706 return;
1707 }
1708 final ActivityRecord r = stack.topRunningActivityLocked();
Louis Chang19443452018-10-09 12:10:21 +08001709 if (r != null && r.moveFocusableActivityToTop("setFocusedStack")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08001710 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001711 }
1712 }
1713 } finally {
1714 Binder.restoreCallingIdentity(callingId);
1715 }
1716 }
1717
1718 @Override
1719 public void setFocusedTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001720 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001721 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
1722 final long callingId = Binder.clearCallingIdentity();
1723 try {
1724 synchronized (mGlobalLock) {
1725 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1726 if (task == null) {
1727 return;
1728 }
1729 final ActivityRecord r = task.topRunningActivityLocked();
Louis Chang19443452018-10-09 12:10:21 +08001730 if (r != null && r.moveFocusableActivityToTop("setFocusedTask")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08001731 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001732 }
1733 }
1734 } finally {
1735 Binder.restoreCallingIdentity(callingId);
1736 }
1737 }
1738
1739 @Override
1740 public boolean removeTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001741 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001742 synchronized (mGlobalLock) {
1743 final long ident = Binder.clearCallingIdentity();
1744 try {
1745 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
1746 "remove-task");
1747 } finally {
1748 Binder.restoreCallingIdentity(ident);
1749 }
1750 }
1751 }
1752
1753 @Override
Winson Chunge6439102018-07-30 15:48:01 -07001754 public void removeAllVisibleRecentTasks() {
1755 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeAllVisibleRecentTasks()");
1756 synchronized (mGlobalLock) {
1757 final long ident = Binder.clearCallingIdentity();
1758 try {
1759 getRecentTasks().removeAllVisibleTasks();
1760 } finally {
1761 Binder.restoreCallingIdentity(ident);
1762 }
1763 }
1764 }
1765
1766 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001767 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
1768 synchronized (mGlobalLock) {
1769 final ActivityRecord srec = ActivityRecord.forTokenLocked(token);
1770 if (srec != null) {
1771 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
1772 }
1773 }
1774 return false;
1775 }
1776
1777 @Override
1778 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
1779 Intent resultData) {
1780
1781 synchronized (mGlobalLock) {
1782 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
1783 if (r != null) {
1784 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
1785 }
1786 return false;
1787 }
1788 }
1789
1790 /**
1791 * Attempts to move a task backwards in z-order (the order of activities within the task is
1792 * unchanged).
1793 *
1794 * There are several possible results of this call:
1795 * - if the task is locked, then we will show the lock toast
1796 * - if there is a task behind the provided task, then that task is made visible and resumed as
1797 * this task is moved to the back
1798 * - otherwise, if there are no other tasks in the stack:
1799 * - if this task is in the pinned stack, then we remove the stack completely, which will
1800 * have the effect of moving the task to the top or bottom of the fullscreen stack
1801 * (depending on whether it is visible)
1802 * - otherwise, we simply return home and hide this task
1803 *
1804 * @param token A reference to the activity we wish to move
1805 * @param nonRoot If false then this only works if the activity is the root
1806 * of a task; if true it will work for any activity in a task.
1807 * @return Returns true if the move completed, false if not.
1808 */
1809 @Override
1810 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001811 enforceNotIsolatedCaller("moveActivityTaskToBack");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001812 synchronized (mGlobalLock) {
1813 final long origId = Binder.clearCallingIdentity();
1814 try {
1815 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
1816 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1817 if (task != null) {
1818 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
1819 }
1820 } finally {
1821 Binder.restoreCallingIdentity(origId);
1822 }
1823 }
1824 return false;
1825 }
1826
1827 @Override
1828 public Rect getTaskBounds(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001829 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001830 long ident = Binder.clearCallingIdentity();
1831 Rect rect = new Rect();
1832 try {
1833 synchronized (mGlobalLock) {
1834 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
1835 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1836 if (task == null) {
1837 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
1838 return rect;
1839 }
1840 if (task.getStack() != null) {
1841 // Return the bounds from window manager since it will be adjusted for various
1842 // things like the presense of a docked stack for tasks that aren't resizeable.
1843 task.getWindowContainerBounds(rect);
1844 } else {
1845 // Task isn't in window manager yet since it isn't associated with a stack.
1846 // Return the persist value from activity manager
1847 if (!task.matchParentBounds()) {
1848 rect.set(task.getBounds());
1849 } else if (task.mLastNonFullscreenBounds != null) {
1850 rect.set(task.mLastNonFullscreenBounds);
1851 }
1852 }
1853 }
1854 } finally {
1855 Binder.restoreCallingIdentity(ident);
1856 }
1857 return rect;
1858 }
1859
1860 @Override
1861 public ActivityManager.TaskDescription getTaskDescription(int id) {
1862 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001863 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001864 MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
1865 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
1866 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1867 if (tr != null) {
1868 return tr.lastTaskDescription;
1869 }
1870 }
1871 return null;
1872 }
1873
1874 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001875 public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
1876 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
1877 setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
1878 toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
1879 return;
1880 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001881 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001882 synchronized (mGlobalLock) {
1883 final long ident = Binder.clearCallingIdentity();
1884 try {
1885 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1886 if (task == null) {
1887 Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
1888 return;
1889 }
1890
1891 if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
1892 + " to windowingMode=" + windowingMode + " toTop=" + toTop);
1893
1894 if (!task.isActivityTypeStandardOrUndefined()) {
1895 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
1896 + " non-standard task " + taskId + " to windowing mode="
1897 + windowingMode);
1898 }
1899
1900 final ActivityStack stack = task.getStack();
1901 if (toTop) {
1902 stack.moveToFront("setTaskWindowingMode", task);
1903 }
1904 stack.setWindowingMode(windowingMode);
1905 } finally {
1906 Binder.restoreCallingIdentity(ident);
1907 }
1908 }
1909 }
1910
1911 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001912 public String getCallingPackage(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001913 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001914 ActivityRecord r = getCallingRecordLocked(token);
1915 return r != null ? r.info.packageName : null;
1916 }
1917 }
1918
1919 @Override
1920 public ComponentName getCallingActivity(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001921 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001922 ActivityRecord r = getCallingRecordLocked(token);
1923 return r != null ? r.intent.getComponent() : null;
1924 }
1925 }
1926
1927 private ActivityRecord getCallingRecordLocked(IBinder token) {
1928 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1929 if (r == null) {
1930 return null;
1931 }
1932 return r.resultTo;
1933 }
1934
1935 @Override
1936 public void unhandledBack() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001937 mAmInternal.enforceCallingPermission(android.Manifest.permission.FORCE_BACK, "unhandledBack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001938
1939 synchronized (mGlobalLock) {
1940 final long origId = Binder.clearCallingIdentity();
1941 try {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001942 getTopDisplayFocusedStack().unhandledBackLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001943 } finally {
1944 Binder.restoreCallingIdentity(origId);
1945 }
1946 }
1947 }
1948
1949 /**
1950 * TODO: Add mController hook
1951 */
1952 @Override
1953 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001954 mAmInternal.enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001955
1956 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
1957 synchronized (mGlobalLock) {
1958 moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
1959 false /* fromRecents */);
1960 }
1961 }
1962
1963 void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
1964 boolean fromRecents) {
1965
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001966 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001967 Binder.getCallingUid(), -1, -1, "Task to front")) {
1968 SafeActivityOptions.abort(options);
1969 return;
1970 }
1971 final long origId = Binder.clearCallingIdentity();
1972 try {
1973 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1974 if (task == null) {
1975 Slog.d(TAG, "Could not find task for id: "+ taskId);
Winson Chungd0243682018-09-25 18:11:54 -07001976 SafeActivityOptions.abort(options);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001977 return;
1978 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001979 if (getLockTaskController().isLockTaskModeViolation(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001980 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
Winson Chungd0243682018-09-25 18:11:54 -07001981 SafeActivityOptions.abort(options);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001982 return;
1983 }
1984 ActivityOptions realOptions = options != null
1985 ? options.getOptions(mStackSupervisor)
1986 : null;
1987 mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
1988 false /* forceNonResizable */);
1989
1990 final ActivityRecord topActivity = task.getTopActivity();
1991 if (topActivity != null) {
1992
1993 // We are reshowing a task, use a starting window to hide the initial draw delay
1994 // so the transition can start earlier.
1995 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
1996 true /* taskSwitch */, fromRecents);
1997 }
1998 } finally {
1999 Binder.restoreCallingIdentity(origId);
2000 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002001 }
2002
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002003 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
2004 int callingPid, int callingUid, String name) {
2005 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
2006 return true;
2007 }
2008
2009 if (getRecentTasks().isCallerRecents(sourceUid)) {
2010 return true;
2011 }
2012
2013 int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
2014 if (perm == PackageManager.PERMISSION_GRANTED) {
2015 return true;
2016 }
2017 if (checkAllowAppSwitchUid(sourceUid)) {
2018 return true;
2019 }
2020
2021 // If the actual IPC caller is different from the logical source, then
2022 // also see if they are allowed to control app switches.
2023 if (callingUid != -1 && callingUid != sourceUid) {
2024 perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
2025 if (perm == PackageManager.PERMISSION_GRANTED) {
2026 return true;
2027 }
2028 if (checkAllowAppSwitchUid(callingUid)) {
2029 return true;
2030 }
2031 }
2032
2033 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
2034 return false;
2035 }
2036
2037 private boolean checkAllowAppSwitchUid(int uid) {
2038 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
2039 if (types != null) {
2040 for (int i = types.size() - 1; i >= 0; i--) {
2041 if (types.valueAt(i).intValue() == uid) {
2042 return true;
2043 }
2044 }
2045 }
2046 return false;
2047 }
2048
2049 @Override
2050 public void setActivityController(IActivityController controller, boolean imAMonkey) {
2051 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
2052 "setActivityController()");
2053 synchronized (mGlobalLock) {
2054 mController = controller;
2055 mControllerIsAMonkey = imAMonkey;
2056 Watchdog.getInstance().setActivityController(controller);
2057 }
2058 }
2059
2060 boolean isControllerAMonkey() {
2061 synchronized (mGlobalLock) {
2062 return mController != null && mControllerIsAMonkey;
2063 }
2064 }
2065
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002066 @Override
2067 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
2068 synchronized (mGlobalLock) {
2069 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
2070 }
2071 }
2072
2073 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002074 public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum) {
2075 return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
2076 }
2077
2078 @Override
2079 public List<ActivityManager.RunningTaskInfo> getFilteredTasks(int maxNum,
2080 @WindowConfiguration.ActivityType int ignoreActivityType,
2081 @WindowConfiguration.WindowingMode int ignoreWindowingMode) {
2082 final int callingUid = Binder.getCallingUid();
2083 ArrayList<ActivityManager.RunningTaskInfo> list = new ArrayList<>();
2084
2085 synchronized (mGlobalLock) {
2086 if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
2087
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002088 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002089 callingUid);
2090 mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
2091 ignoreWindowingMode, callingUid, allowed);
2092 }
2093
2094 return list;
2095 }
2096
2097 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002098 public final void finishSubActivity(IBinder token, String resultWho, int requestCode) {
2099 synchronized (mGlobalLock) {
2100 final long origId = Binder.clearCallingIdentity();
2101 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2102 if (r != null) {
2103 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
2104 }
2105 Binder.restoreCallingIdentity(origId);
2106 }
2107 }
2108
2109 @Override
2110 public boolean willActivityBeVisible(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002111 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002112 ActivityStack stack = ActivityRecord.getStackLocked(token);
2113 if (stack != null) {
2114 return stack.willActivityBeVisibleLocked(token);
2115 }
2116 return false;
2117 }
2118 }
2119
2120 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002121 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002122 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002123 synchronized (mGlobalLock) {
2124 final long ident = Binder.clearCallingIdentity();
2125 try {
2126 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2127 if (task == null) {
2128 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
2129 return;
2130 }
2131
2132 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
2133 + " to stackId=" + stackId + " toTop=" + toTop);
2134
2135 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2136 if (stack == null) {
2137 throw new IllegalStateException(
2138 "moveTaskToStack: No stack for stackId=" + stackId);
2139 }
2140 if (!stack.isActivityTypeStandardOrUndefined()) {
2141 throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
2142 + taskId + " to stack " + stackId);
2143 }
2144 if (stack.inSplitScreenPrimaryWindowingMode()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002145 mWindowManager.setDockedStackCreateState(
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002146 SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
2147 }
2148 task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
2149 "moveTaskToStack");
2150 } finally {
2151 Binder.restoreCallingIdentity(ident);
2152 }
2153 }
2154 }
2155
2156 @Override
2157 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
2158 boolean preserveWindows, boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002159 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002160
2161 final long ident = Binder.clearCallingIdentity();
2162 try {
2163 synchronized (mGlobalLock) {
2164 if (animate) {
2165 final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
2166 if (stack == null) {
2167 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2168 return;
2169 }
2170 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
2171 throw new IllegalArgumentException("Stack: " + stackId
2172 + " doesn't support animated resize.");
2173 }
2174 stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
2175 animationDuration, false /* fromFullscreen */);
2176 } else {
2177 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2178 if (stack == null) {
2179 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2180 return;
2181 }
2182 mStackSupervisor.resizeStackLocked(stack, destBounds,
2183 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
2184 preserveWindows, allowResizeInDockedMode, !DEFER_RESUME);
2185 }
2186 }
2187 } finally {
2188 Binder.restoreCallingIdentity(ident);
2189 }
2190 }
2191
2192 /**
2193 * Moves the specified task to the primary-split-screen stack.
2194 *
2195 * @param taskId Id of task to move.
2196 * @param createMode The mode the primary split screen stack should be created in if it doesn't
2197 * exist already. See
2198 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
2199 * and
2200 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
2201 * @param toTop If the task and stack should be moved to the top.
2202 * @param animate Whether we should play an animation for the moving the task.
2203 * @param initialBounds If the primary stack gets created, it will use these bounds for the
2204 * stack. Pass {@code null} to use default bounds.
2205 * @param showRecents If the recents activity should be shown on the other side of the task
2206 * going into split-screen mode.
2207 */
2208 @Override
2209 public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode,
2210 boolean toTop, boolean animate, Rect initialBounds, boolean showRecents) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002211 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002212 "setTaskWindowingModeSplitScreenPrimary()");
2213 synchronized (mGlobalLock) {
2214 final long ident = Binder.clearCallingIdentity();
2215 try {
2216 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2217 if (task == null) {
2218 Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
2219 return false;
2220 }
2221 if (DEBUG_STACK) Slog.d(TAG_STACK,
2222 "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
2223 + " to createMode=" + createMode + " toTop=" + toTop);
2224 if (!task.isActivityTypeStandardOrUndefined()) {
2225 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
2226 + " non-standard task " + taskId + " to split-screen windowing mode");
2227 }
2228
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002229 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002230 final int windowingMode = task.getWindowingMode();
2231 final ActivityStack stack = task.getStack();
2232 if (toTop) {
2233 stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
2234 }
2235 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
2236 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */);
2237 return windowingMode != task.getWindowingMode();
2238 } finally {
2239 Binder.restoreCallingIdentity(ident);
2240 }
2241 }
2242 }
2243
2244 /**
2245 * Removes stacks in the input windowing modes from the system if they are of activity type
2246 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
2247 */
2248 @Override
2249 public void removeStacksInWindowingModes(int[] windowingModes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002250 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002251 "removeStacksInWindowingModes()");
2252
2253 synchronized (mGlobalLock) {
2254 final long ident = Binder.clearCallingIdentity();
2255 try {
2256 mStackSupervisor.removeStacksInWindowingModes(windowingModes);
2257 } finally {
2258 Binder.restoreCallingIdentity(ident);
2259 }
2260 }
2261 }
2262
2263 @Override
2264 public void removeStacksWithActivityTypes(int[] activityTypes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002265 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002266 "removeStacksWithActivityTypes()");
2267
2268 synchronized (mGlobalLock) {
2269 final long ident = Binder.clearCallingIdentity();
2270 try {
2271 mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
2272 } finally {
2273 Binder.restoreCallingIdentity(ident);
2274 }
2275 }
2276 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002277
2278 @Override
2279 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
2280 int userId) {
2281 final int callingUid = Binder.getCallingUid();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002282 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, "getRecentTasks");
2283 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002284 callingUid);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002285 final boolean detailed = checkGetTasksPermission(
2286 android.Manifest.permission.GET_DETAILED_TASKS, Binder.getCallingPid(),
2287 UserHandle.getAppId(callingUid))
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002288 == PackageManager.PERMISSION_GRANTED;
2289
2290 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002291 return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002292 callingUid);
2293 }
2294 }
2295
2296 @Override
2297 public List<ActivityManager.StackInfo> getAllStackInfos() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002298 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002299 long ident = Binder.clearCallingIdentity();
2300 try {
2301 synchronized (mGlobalLock) {
2302 return mStackSupervisor.getAllStackInfosLocked();
2303 }
2304 } finally {
2305 Binder.restoreCallingIdentity(ident);
2306 }
2307 }
2308
2309 @Override
2310 public ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002311 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002312 long ident = Binder.clearCallingIdentity();
2313 try {
2314 synchronized (mGlobalLock) {
2315 return mStackSupervisor.getStackInfo(windowingMode, activityType);
2316 }
2317 } finally {
2318 Binder.restoreCallingIdentity(ident);
2319 }
2320 }
2321
2322 @Override
2323 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002324 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002325 final long callingUid = Binder.getCallingUid();
2326 final long origId = Binder.clearCallingIdentity();
2327 try {
2328 synchronized (mGlobalLock) {
2329 // Cancel the recents animation synchronously (do not hold the WM lock)
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002330 mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002331 ? REORDER_MOVE_TO_ORIGINAL_POSITION
2332 : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
2333 }
2334 } finally {
2335 Binder.restoreCallingIdentity(origId);
2336 }
2337 }
2338
2339 @Override
2340 public void startLockTaskModeByToken(IBinder token) {
2341 synchronized (mGlobalLock) {
2342 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2343 if (r == null) {
2344 return;
2345 }
2346 startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
2347 }
2348 }
2349
2350 @Override
2351 public void startSystemLockTaskMode(int taskId) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002352 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002353 // This makes inner call to look as if it was initiated by system.
2354 long ident = Binder.clearCallingIdentity();
2355 try {
2356 synchronized (mGlobalLock) {
2357 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2358
2359 // When starting lock task mode the stack must be in front and focused
2360 task.getStack().moveToFront("startSystemLockTaskMode");
2361 startLockTaskModeLocked(task, true /* isSystemCaller */);
2362 }
2363 } finally {
2364 Binder.restoreCallingIdentity(ident);
2365 }
2366 }
2367
2368 @Override
2369 public void stopLockTaskModeByToken(IBinder token) {
2370 synchronized (mGlobalLock) {
2371 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2372 if (r == null) {
2373 return;
2374 }
2375 stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
2376 }
2377 }
2378
2379 /**
2380 * This API should be called by SystemUI only when user perform certain action to dismiss
2381 * lock task mode. We should only dismiss pinned lock task mode in this case.
2382 */
2383 @Override
2384 public void stopSystemLockTaskMode() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002385 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002386 stopLockTaskModeInternal(null, true /* isSystemCaller */);
2387 }
2388
2389 private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
2390 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
2391 if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
2392 return;
2393 }
2394
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002395 final ActivityStack stack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002396 if (stack == null || task != stack.topTask()) {
2397 throw new IllegalArgumentException("Invalid task, not in foreground");
2398 }
2399
2400 // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
2401 // system or a specific app.
2402 // * System-initiated requests will only start the pinned mode (screen pinning)
2403 // * App-initiated requests
2404 // - will put the device in fully locked mode (LockTask), if the app is whitelisted
2405 // - will start the pinned mode, otherwise
2406 final int callingUid = Binder.getCallingUid();
2407 long ident = Binder.clearCallingIdentity();
2408 try {
2409 // When a task is locked, dismiss the pinned stack if it exists
2410 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2411
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002412 getLockTaskController().startLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002413 } finally {
2414 Binder.restoreCallingIdentity(ident);
2415 }
2416 }
2417
2418 private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
2419 final int callingUid = Binder.getCallingUid();
2420 long ident = Binder.clearCallingIdentity();
2421 try {
2422 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002423 getLockTaskController().stopLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002424 }
2425 // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
2426 // task and jumping straight into a call in the case of emergency call back.
2427 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
2428 if (tm != null) {
2429 tm.showInCallScreen(false);
2430 }
2431 } finally {
2432 Binder.restoreCallingIdentity(ident);
2433 }
2434 }
2435
2436 @Override
2437 public boolean isInLockTaskMode() {
2438 return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
2439 }
2440
2441 @Override
2442 public int getLockTaskModeState() {
2443 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002444 return getLockTaskController().getLockTaskModeState();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002445 }
2446 }
2447
2448 @Override
2449 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
2450 synchronized (mGlobalLock) {
2451 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2452 if (r != null) {
2453 r.setTaskDescription(td);
2454 final TaskRecord task = r.getTask();
2455 task.updateTaskDescription();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002456 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002457 }
2458 }
2459 }
2460
2461 @Override
2462 public Bundle getActivityOptions(IBinder token) {
2463 final long origId = Binder.clearCallingIdentity();
2464 try {
2465 synchronized (mGlobalLock) {
2466 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
2467 if (r != null) {
2468 final ActivityOptions activityOptions = r.takeOptionsLocked();
2469 return activityOptions == null ? null : activityOptions.toBundle();
2470 }
2471 return null;
2472 }
2473 } finally {
2474 Binder.restoreCallingIdentity(origId);
2475 }
2476 }
2477
2478 @Override
2479 public List<IBinder> getAppTasks(String callingPackage) {
2480 int callingUid = Binder.getCallingUid();
2481 long ident = Binder.clearCallingIdentity();
2482 try {
2483 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002484 return mRecentTasks.getAppTasksList(callingUid, callingPackage);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002485 }
2486 } finally {
2487 Binder.restoreCallingIdentity(ident);
2488 }
2489 }
2490
2491 @Override
2492 public void finishVoiceTask(IVoiceInteractionSession session) {
2493 synchronized (mGlobalLock) {
2494 final long origId = Binder.clearCallingIdentity();
2495 try {
2496 // TODO: VI Consider treating local voice interactions and voice tasks
2497 // differently here
2498 mStackSupervisor.finishVoiceTask(session);
2499 } finally {
2500 Binder.restoreCallingIdentity(origId);
2501 }
2502 }
2503
2504 }
2505
2506 @Override
2507 public boolean isTopOfTask(IBinder token) {
2508 synchronized (mGlobalLock) {
2509 ActivityRecord r = ActivityRecord.isInStackLocked(token);
Riddle Hsu66b74a82018-07-26 00:20:12 +08002510 return r != null && r.getTask().getTopActivity() == r;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002511 }
2512 }
2513
2514 @Override
2515 public void notifyLaunchTaskBehindComplete(IBinder token) {
2516 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
2517 }
2518
2519 @Override
2520 public void notifyEnterAnimationComplete(IBinder token) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002521 mH.post(() -> {
2522 synchronized (mGlobalLock) {
2523 ActivityRecord r = ActivityRecord.forTokenLocked(token);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002524 if (r != null && r.attachedToProcess()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002525 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002526 r.app.getThread().scheduleEnterAnimationComplete(r.appToken);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002527 } catch (RemoteException e) {
2528 }
2529 }
2530 }
2531
2532 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002533 }
2534
2535 /** Called from an app when assist data is ready. */
2536 @Override
2537 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
2538 AssistContent content, Uri referrer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002539 PendingAssistExtras pae = (PendingAssistExtras) token;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002540 synchronized (pae) {
2541 pae.result = extras;
2542 pae.structure = structure;
2543 pae.content = content;
2544 if (referrer != null) {
2545 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
2546 }
2547 if (structure != null) {
2548 structure.setHomeActivity(pae.isHome);
2549 }
2550 pae.haveResult = true;
2551 pae.notifyAll();
2552 if (pae.intent == null && pae.receiver == null) {
2553 // Caller is just waiting for the result.
2554 return;
2555 }
2556 }
2557 // We are now ready to launch the assist activity.
2558 IAssistDataReceiver sendReceiver = null;
2559 Bundle sendBundle = null;
2560 synchronized (mGlobalLock) {
2561 buildAssistBundleLocked(pae, extras);
2562 boolean exists = mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002563 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002564 if (!exists) {
2565 // Timed out.
2566 return;
2567 }
2568
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002569 if ((sendReceiver = pae.receiver) != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002570 // Caller wants result sent back to them.
2571 sendBundle = new Bundle();
2572 sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
2573 sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
2574 sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
2575 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
2576 }
2577 }
2578 if (sendReceiver != null) {
2579 try {
2580 sendReceiver.onHandleAssistData(sendBundle);
2581 } catch (RemoteException e) {
2582 }
2583 return;
2584 }
2585
2586 final long ident = Binder.clearCallingIdentity();
2587 try {
2588 if (TextUtils.equals(pae.intent.getAction(),
2589 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
2590 pae.intent.putExtras(pae.extras);
2591 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
2592 } else {
2593 pae.intent.replaceExtras(pae.extras);
2594 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
2595 | Intent.FLAG_ACTIVITY_SINGLE_TOP
2596 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002597 mAmInternal.closeSystemDialogs("assist");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002598
2599 try {
2600 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
2601 } catch (ActivityNotFoundException e) {
2602 Slog.w(TAG, "No activity to handle assist action.", e);
2603 }
2604 }
2605 } finally {
2606 Binder.restoreCallingIdentity(ident);
2607 }
2608 }
2609
2610 @Override
2611 public int addAppTask(IBinder activityToken, Intent intent,
2612 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
2613 final int callingUid = Binder.getCallingUid();
2614 final long callingIdent = Binder.clearCallingIdentity();
2615
2616 try {
2617 synchronized (mGlobalLock) {
2618 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
2619 if (r == null) {
2620 throw new IllegalArgumentException("Activity does not exist; token="
2621 + activityToken);
2622 }
2623 ComponentName comp = intent.getComponent();
2624 if (comp == null) {
2625 throw new IllegalArgumentException("Intent " + intent
2626 + " must specify explicit component");
2627 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002628 if (thumbnail.getWidth() != mThumbnailWidth
2629 || thumbnail.getHeight() != mThumbnailHeight) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002630 throw new IllegalArgumentException("Bad thumbnail size: got "
2631 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002632 + mThumbnailWidth + "x" + mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002633 }
2634 if (intent.getSelector() != null) {
2635 intent.setSelector(null);
2636 }
2637 if (intent.getSourceBounds() != null) {
2638 intent.setSourceBounds(null);
2639 }
2640 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
2641 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
2642 // The caller has added this as an auto-remove task... that makes no
2643 // sense, so turn off auto-remove.
2644 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
2645 }
2646 }
2647 final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
2648 STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
2649 if (ainfo.applicationInfo.uid != callingUid) {
2650 throw new SecurityException(
2651 "Can't add task for another application: target uid="
2652 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
2653 }
2654
2655 final ActivityStack stack = r.getStack();
2656 final TaskRecord task = stack.createTaskRecord(
2657 mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent,
2658 null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002659 if (!mRecentTasks.addToBottom(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002660 // The app has too many tasks already and we can't add any more
2661 stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
2662 return INVALID_TASK_ID;
2663 }
2664 task.lastTaskDescription.copyFrom(description);
2665
2666 // TODO: Send the thumbnail to WM to store it.
2667
2668 return task.taskId;
2669 }
2670 } finally {
2671 Binder.restoreCallingIdentity(callingIdent);
2672 }
2673 }
2674
2675 @Override
2676 public Point getAppTaskThumbnailSize() {
2677 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002678 return new Point(mThumbnailWidth, mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002679 }
2680 }
2681
2682 @Override
2683 public void setTaskResizeable(int taskId, int resizeableMode) {
2684 synchronized (mGlobalLock) {
2685 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
2686 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
2687 if (task == null) {
2688 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
2689 return;
2690 }
2691 task.setResizeMode(resizeableMode);
2692 }
2693 }
2694
2695 @Override
2696 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002697 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002698 long ident = Binder.clearCallingIdentity();
2699 try {
2700 synchronized (mGlobalLock) {
2701 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2702 if (task == null) {
2703 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
2704 return;
2705 }
2706 // Place the task in the right stack if it isn't there already based on
2707 // the requested bounds.
2708 // The stack transition logic is:
2709 // - a null bounds on a freeform task moves that task to fullscreen
2710 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
2711 // that task to freeform
2712 // - otherwise the task is not moved
2713 ActivityStack stack = task.getStack();
2714 if (!task.getWindowConfiguration().canResizeTask()) {
2715 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
2716 }
2717 if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
2718 stack = stack.getDisplay().getOrCreateStack(
2719 WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
2720 } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
2721 stack = stack.getDisplay().getOrCreateStack(
2722 WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
2723 }
2724
2725 // Reparent the task to the right stack if necessary
2726 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
2727 if (stack != task.getStack()) {
2728 // Defer resume until the task is resized below
2729 task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
2730 DEFER_RESUME, "resizeTask");
2731 preserveWindow = false;
2732 }
2733
2734 // After reparenting (which only resizes the task to the stack bounds), resize the
2735 // task to the actual bounds provided
2736 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
2737 }
2738 } finally {
2739 Binder.restoreCallingIdentity(ident);
2740 }
2741 }
2742
2743 @Override
2744 public boolean releaseActivityInstance(IBinder token) {
2745 synchronized (mGlobalLock) {
2746 final long origId = Binder.clearCallingIdentity();
2747 try {
2748 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2749 if (r == null) {
2750 return false;
2751 }
2752 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
2753 } finally {
2754 Binder.restoreCallingIdentity(origId);
2755 }
2756 }
2757 }
2758
2759 @Override
2760 public void releaseSomeActivities(IApplicationThread appInt) {
2761 synchronized (mGlobalLock) {
2762 final long origId = Binder.clearCallingIdentity();
2763 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002764 WindowProcessController app =
2765 mAm.getRecordForAppLocked(appInt).getWindowProcessController();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002766 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
2767 } finally {
2768 Binder.restoreCallingIdentity(origId);
2769 }
2770 }
2771 }
2772
2773 @Override
2774 public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
2775 int secondaryDisplayShowing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002776 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002777 != PackageManager.PERMISSION_GRANTED) {
2778 throw new SecurityException("Requires permission "
2779 + android.Manifest.permission.DEVICE_POWER);
2780 }
2781
2782 synchronized (mGlobalLock) {
2783 long ident = Binder.clearCallingIdentity();
2784 if (mKeyguardShown != keyguardShowing) {
2785 mKeyguardShown = keyguardShowing;
2786 reportCurKeyguardUsageEventLocked(keyguardShowing);
2787 }
2788 try {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002789 mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002790 secondaryDisplayShowing);
2791 } finally {
2792 Binder.restoreCallingIdentity(ident);
2793 }
2794 }
2795
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002796 mH.post(() -> {
2797 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2798 mScreenObservers.get(i).onKeyguardStateChanged(keyguardShowing);
2799 }
2800 });
2801 }
2802
2803 void onScreenAwakeChanged(boolean isAwake) {
2804 mH.post(() -> {
2805 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2806 mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2807 }
2808 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002809 }
2810
2811 @Override
2812 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002813 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
2814 userId, "getTaskDescriptionIcon");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002815
2816 final File passedIconFile = new File(filePath);
2817 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
2818 passedIconFile.getName());
2819 if (!legitIconFile.getPath().equals(filePath)
2820 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
2821 throw new IllegalArgumentException("Bad file path: " + filePath
2822 + " passed for userId " + userId);
2823 }
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002824 return mRecentTasks.getTaskDescriptionIcon(filePath);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002825 }
2826
2827 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002828 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002829 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
2830 final ActivityOptions activityOptions = safeOptions != null
2831 ? safeOptions.getOptions(mStackSupervisor)
2832 : null;
2833 if (activityOptions == null
2834 || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
2835 || activityOptions.getCustomInPlaceResId() == 0) {
2836 throw new IllegalArgumentException("Expected in-place ActivityOption " +
2837 "with valid animation");
2838 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002839 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
2840 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002841 activityOptions.getCustomInPlaceResId());
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002842 mWindowManager.executeAppTransition();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002843 }
2844
2845 @Override
2846 public void removeStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002847 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002848 synchronized (mGlobalLock) {
2849 final long ident = Binder.clearCallingIdentity();
2850 try {
2851 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2852 if (stack == null) {
2853 Slog.w(TAG, "removeStack: No stack with id=" + stackId);
2854 return;
2855 }
2856 if (!stack.isActivityTypeStandardOrUndefined()) {
2857 throw new IllegalArgumentException(
2858 "Removing non-standard stack is not allowed.");
2859 }
2860 mStackSupervisor.removeStack(stack);
2861 } finally {
2862 Binder.restoreCallingIdentity(ident);
2863 }
2864 }
2865 }
2866
2867 @Override
2868 public void moveStackToDisplay(int stackId, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002869 mAmInternal.enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002870
2871 synchronized (mGlobalLock) {
2872 final long ident = Binder.clearCallingIdentity();
2873 try {
2874 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
2875 + " to displayId=" + displayId);
2876 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
2877 } finally {
2878 Binder.restoreCallingIdentity(ident);
2879 }
2880 }
2881 }
2882
2883 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002884 public void exitFreeformMode(IBinder token) {
2885 synchronized (mGlobalLock) {
2886 long ident = Binder.clearCallingIdentity();
2887 try {
2888 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2889 if (r == null) {
2890 throw new IllegalArgumentException(
2891 "exitFreeformMode: No activity record matching token=" + token);
2892 }
2893
2894 final ActivityStack stack = r.getStack();
2895 if (stack == null || !stack.inFreeformWindowingMode()) {
2896 throw new IllegalStateException(
2897 "exitFreeformMode: You can only go fullscreen from freeform.");
2898 }
2899
2900 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
2901 } finally {
2902 Binder.restoreCallingIdentity(ident);
2903 }
2904 }
2905 }
2906
2907 /** Sets the task stack listener that gets callbacks when a task stack changes. */
2908 @Override
2909 public void registerTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002910 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002911 "registerTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002912 mTaskChangeNotificationController.registerTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002913 }
2914
2915 /** Unregister a task stack listener so that it stops receiving callbacks. */
2916 @Override
2917 public void unregisterTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002918 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002919 "unregisterTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002920 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002921 }
2922
2923 private void reportCurKeyguardUsageEventLocked(boolean keyguardShowing) {
2924 mAm.reportGlobalUsageEventLocked(keyguardShowing
2925 ? UsageEvents.Event.KEYGUARD_SHOWN
2926 : UsageEvents.Event.KEYGUARD_HIDDEN);
2927 }
2928
2929 @Override
2930 public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
2931 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
2932 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
2933 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
2934 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
2935 }
2936
2937 @Override
2938 public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
2939 IBinder activityToken, int flags) {
2940 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
2941 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
2942 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
2943 }
2944
2945 @Override
2946 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
2947 Bundle args) {
2948 return enqueueAssistContext(requestType, intent, hint, null, null, null,
2949 true /* focused */, true /* newSessionId */, userHandle, args,
2950 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
2951 }
2952
2953 @Override
2954 public Bundle getAssistContextExtras(int requestType) {
2955 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
2956 null, null, true /* focused */, true /* newSessionId */,
2957 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
2958 if (pae == null) {
2959 return null;
2960 }
2961 synchronized (pae) {
2962 while (!pae.haveResult) {
2963 try {
2964 pae.wait();
2965 } catch (InterruptedException e) {
2966 }
2967 }
2968 }
2969 synchronized (mGlobalLock) {
2970 buildAssistBundleLocked(pae, pae.result);
2971 mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002972 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002973 }
2974 return pae.extras;
2975 }
2976
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002977 /**
2978 * Binder IPC calls go through the public entry point.
2979 * This can be called with or without the global lock held.
2980 */
2981 private static int checkCallingPermission(String permission) {
2982 return checkPermission(
2983 permission, Binder.getCallingPid(), UserHandle.getAppId(Binder.getCallingUid()));
2984 }
2985
2986 /** This can be called with or without the global lock held. */
Wale Ogunwale214f3482018-10-04 11:00:47 -07002987 private void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002988 if (!getRecentTasks().isCallerRecents(Binder.getCallingUid())) {
2989 mAmInternal.enforceCallingPermission(permission, func);
2990 }
2991 }
2992
2993 @VisibleForTesting
2994 int checkGetTasksPermission(String permission, int pid, int uid) {
2995 return checkPermission(permission, pid, uid);
2996 }
2997
2998 static int checkPermission(String permission, int pid, int uid) {
2999 if (permission == null) {
3000 return PackageManager.PERMISSION_DENIED;
3001 }
3002 return checkComponentPermission(permission, pid, uid, -1, true);
3003 }
3004
Wale Ogunwale214f3482018-10-04 11:00:47 -07003005 public static int checkComponentPermission(String permission, int pid, int uid,
3006 int owningUid, boolean exported) {
3007 return ActivityManagerService.checkComponentPermission(
3008 permission, pid, uid, owningUid, exported);
3009 }
3010
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003011 boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
3012 if (getRecentTasks().isCallerRecents(callingUid)) {
3013 // Always allow the recents component to get tasks
3014 return true;
3015 }
3016
3017 boolean allowed = checkGetTasksPermission(android.Manifest.permission.REAL_GET_TASKS,
3018 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
3019 if (!allowed) {
3020 if (checkGetTasksPermission(android.Manifest.permission.GET_TASKS,
3021 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
3022 // Temporary compatibility: some existing apps on the system image may
3023 // still be requesting the old permission and not switched to the new
3024 // one; if so, we'll still allow them full access. This means we need
3025 // to see if they are holding the old permission and are a system app.
3026 try {
3027 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
3028 allowed = true;
3029 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
3030 + " is using old GET_TASKS but privileged; allowing");
3031 }
3032 } catch (RemoteException e) {
3033 }
3034 }
3035 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
3036 + " does not hold REAL_GET_TASKS; limiting output");
3037 }
3038 return allowed;
3039 }
3040
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003041 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
3042 IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
3043 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
3044 int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003045 mAmInternal.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003046 "enqueueAssistContext()");
3047
3048 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003049 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003050 if (activity == null) {
3051 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
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, "getAssistContextExtras failed: no process for " + activity);
3056 return null;
3057 }
3058 if (focused) {
3059 if (activityToken != null) {
3060 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
3061 if (activity != caller) {
3062 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
3063 + " is not current top " + activity);
3064 return null;
3065 }
3066 }
3067 } else {
3068 activity = ActivityRecord.forTokenLocked(activityToken);
3069 if (activity == null) {
3070 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
3071 + " couldn't be found");
3072 return null;
3073 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003074 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003075 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
3076 return null;
3077 }
3078 }
3079
3080 PendingAssistExtras pae;
3081 Bundle extras = new Bundle();
3082 if (args != null) {
3083 extras.putAll(args);
3084 }
3085 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003086 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003087
3088 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
3089 userHandle);
3090 pae.isHome = activity.isActivityTypeHome();
3091
3092 // Increment the sessionId if necessary
3093 if (newSessionId) {
3094 mViSessionId++;
3095 }
3096 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003097 activity.app.getThread().requestAssistContextExtras(activity.appToken, pae,
3098 requestType, mViSessionId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003099 mPendingAssistExtras.add(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003100 mUiHandler.postDelayed(pae, timeout);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003101 } catch (RemoteException e) {
3102 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
3103 return null;
3104 }
3105 return pae;
3106 }
3107 }
3108
3109 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
3110 if (result != null) {
3111 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
3112 }
3113 if (pae.hint != null) {
3114 pae.extras.putBoolean(pae.hint, true);
3115 }
3116 }
3117
3118 private void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
3119 IAssistDataReceiver receiver;
3120 synchronized (mGlobalLock) {
3121 mPendingAssistExtras.remove(pae);
3122 receiver = pae.receiver;
3123 }
3124 if (receiver != null) {
3125 // Caller wants result sent back to them.
3126 Bundle sendBundle = new Bundle();
3127 // At least return the receiver extras
3128 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
3129 try {
3130 pae.receiver.onHandleAssistData(sendBundle);
3131 } catch (RemoteException e) {
3132 }
3133 }
3134 }
3135
3136 public class PendingAssistExtras extends Binder implements Runnable {
3137 public final ActivityRecord activity;
3138 public boolean isHome;
3139 public final Bundle extras;
3140 public final Intent intent;
3141 public final String hint;
3142 public final IAssistDataReceiver receiver;
3143 public final int userHandle;
3144 public boolean haveResult = false;
3145 public Bundle result = null;
3146 public AssistStructure structure = null;
3147 public AssistContent content = null;
3148 public Bundle receiverExtras;
3149
3150 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
3151 String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
3152 int _userHandle) {
3153 activity = _activity;
3154 extras = _extras;
3155 intent = _intent;
3156 hint = _hint;
3157 receiver = _receiver;
3158 receiverExtras = _receiverExtras;
3159 userHandle = _userHandle;
3160 }
3161
3162 @Override
3163 public void run() {
3164 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
3165 synchronized (this) {
3166 haveResult = true;
3167 notifyAll();
3168 }
3169 pendingAssistExtrasTimedOut(this);
3170 }
3171 }
3172
3173 @Override
3174 public boolean isAssistDataAllowedOnCurrentActivity() {
3175 int userId;
3176 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003177 final ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003178 if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
3179 return false;
3180 }
3181
3182 final ActivityRecord activity = focusedStack.getTopActivity();
3183 if (activity == null) {
3184 return false;
3185 }
3186 userId = activity.userId;
3187 }
3188 return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
3189 }
3190
3191 @Override
3192 public boolean showAssistFromActivity(IBinder token, Bundle args) {
3193 long ident = Binder.clearCallingIdentity();
3194 try {
3195 synchronized (mGlobalLock) {
3196 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003197 ActivityRecord top = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003198 if (top != caller) {
3199 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3200 + " is not current top " + top);
3201 return false;
3202 }
3203 if (!top.nowVisible) {
3204 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3205 + " is not visible");
3206 return false;
3207 }
3208 }
3209 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
3210 token);
3211 } finally {
3212 Binder.restoreCallingIdentity(ident);
3213 }
3214 }
3215
3216 @Override
3217 public boolean isRootVoiceInteraction(IBinder token) {
3218 synchronized (mGlobalLock) {
3219 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3220 if (r == null) {
3221 return false;
3222 }
3223 return r.rootVoiceInteraction;
3224 }
3225 }
3226
Wale Ogunwalef6733932018-06-27 05:14:34 -07003227 private void onLocalVoiceInteractionStartedLocked(IBinder activity,
3228 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
3229 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
3230 if (activityToCallback == null) return;
3231 activityToCallback.setVoiceSessionLocked(voiceSession);
3232
3233 // Inform the activity
3234 try {
3235 activityToCallback.app.getThread().scheduleLocalVoiceInteractionStarted(activity,
3236 voiceInteractor);
3237 long token = Binder.clearCallingIdentity();
3238 try {
3239 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
3240 } finally {
3241 Binder.restoreCallingIdentity(token);
3242 }
3243 // TODO: VI Should we cache the activity so that it's easier to find later
3244 // rather than scan through all the stacks and activities?
3245 } catch (RemoteException re) {
3246 activityToCallback.clearVoiceSessionLocked();
3247 // TODO: VI Should this terminate the voice session?
3248 }
3249 }
3250
3251 private void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
3252 Slog.d(TAG, "<<< startRunningVoiceLocked()");
3253 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
3254 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
3255 boolean wasRunningVoice = mRunningVoice != null;
3256 mRunningVoice = session;
3257 if (!wasRunningVoice) {
3258 mVoiceWakeLock.acquire();
3259 updateSleepIfNeededLocked();
3260 }
3261 }
3262 }
3263
3264 void finishRunningVoiceLocked() {
3265 if (mRunningVoice != null) {
3266 mRunningVoice = null;
3267 mVoiceWakeLock.release();
3268 updateSleepIfNeededLocked();
3269 }
3270 }
3271
3272 @Override
3273 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3274 synchronized (mGlobalLock) {
3275 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3276 if (keepAwake) {
3277 mVoiceWakeLock.acquire();
3278 } else {
3279 mVoiceWakeLock.release();
3280 }
3281 }
3282 }
3283 }
3284
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003285 @Override
3286 public ComponentName getActivityClassForToken(IBinder token) {
3287 synchronized (mGlobalLock) {
3288 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3289 if (r == null) {
3290 return null;
3291 }
3292 return r.intent.getComponent();
3293 }
3294 }
3295
3296 @Override
3297 public String getPackageForToken(IBinder token) {
3298 synchronized (mGlobalLock) {
3299 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3300 if (r == null) {
3301 return null;
3302 }
3303 return r.packageName;
3304 }
3305 }
3306
3307 @Override
3308 public void showLockTaskEscapeMessage(IBinder token) {
3309 synchronized (mGlobalLock) {
3310 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3311 if (r == null) {
3312 return;
3313 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003314 getLockTaskController().showLockTaskToast();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003315 }
3316 }
3317
3318 @Override
3319 public void keyguardGoingAway(int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003320 enforceNotIsolatedCaller("keyguardGoingAway");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003321 final long token = Binder.clearCallingIdentity();
3322 try {
3323 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003324 mKeyguardController.keyguardGoingAway(flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003325 }
3326 } finally {
3327 Binder.restoreCallingIdentity(token);
3328 }
3329 }
3330
3331 /**
3332 * Try to place task to provided position. The final position might be different depending on
3333 * current user and stacks state. The task will be moved to target stack if it's currently in
3334 * different stack.
3335 */
3336 @Override
3337 public void positionTaskInStack(int taskId, int stackId, int position) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003338 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003339 synchronized (mGlobalLock) {
3340 long ident = Binder.clearCallingIdentity();
3341 try {
3342 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
3343 + taskId + " in stackId=" + stackId + " at position=" + position);
3344 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3345 if (task == null) {
3346 throw new IllegalArgumentException("positionTaskInStack: no task for id="
3347 + taskId);
3348 }
3349
3350 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3351
3352 if (stack == null) {
3353 throw new IllegalArgumentException("positionTaskInStack: no stack for id="
3354 + stackId);
3355 }
3356 if (!stack.isActivityTypeStandardOrUndefined()) {
3357 throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
3358 + " the position of task " + taskId + " in/to non-standard stack");
3359 }
3360
3361 // TODO: Have the callers of this API call a separate reparent method if that is
3362 // what they intended to do vs. having this method also do reparenting.
3363 if (task.getStack() == stack) {
3364 // Change position in current stack.
3365 stack.positionChildAt(task, position);
3366 } else {
3367 // Reparent to new stack.
3368 task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
3369 !DEFER_RESUME, "positionTaskInStack");
3370 }
3371 } finally {
3372 Binder.restoreCallingIdentity(ident);
3373 }
3374 }
3375 }
3376
3377 @Override
3378 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
3379 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
3380 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
3381 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
3382 synchronized (mGlobalLock) {
3383 ActivityRecord record = ActivityRecord.isInStackLocked(token);
3384 if (record == null) {
3385 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
3386 + "found for: " + token);
3387 }
3388 record.setSizeConfigurations(horizontalSizeConfiguration,
3389 verticalSizeConfigurations, smallestSizeConfigurations);
3390 }
3391 }
3392
3393 /**
3394 * Dismisses split-screen multi-window mode.
3395 * @param toTop If true the current primary split-screen stack will be placed or left on top.
3396 */
3397 @Override
3398 public void dismissSplitScreenMode(boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003399 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003400 MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
3401 final long ident = Binder.clearCallingIdentity();
3402 try {
3403 synchronized (mGlobalLock) {
3404 final ActivityStack stack =
3405 mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
3406 if (stack == null) {
3407 Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
3408 return;
3409 }
3410
3411 if (toTop) {
3412 // Caller wants the current split-screen primary stack to be the top stack after
3413 // it goes fullscreen, so move it to the front.
3414 stack.moveToFront("dismissSplitScreenMode");
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003415 } else if (mStackSupervisor.isTopDisplayFocusedStack(stack)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003416 // In this case the current split-screen primary stack shouldn't be the top
3417 // stack after it goes fullscreen, but it current has focus, so we move the
3418 // focus to the top-most split-screen secondary stack next to it.
3419 final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
3420 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
3421 if (otherStack != null) {
3422 otherStack.moveToFront("dismissSplitScreenMode_other");
3423 }
3424 }
3425
Evan Rosky10475742018-09-05 19:02:48 -07003426 stack.setWindowingMode(WINDOWING_MODE_UNDEFINED);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003427 }
3428 } finally {
3429 Binder.restoreCallingIdentity(ident);
3430 }
3431 }
3432
3433 /**
3434 * Dismisses Pip
3435 * @param animate True if the dismissal should be animated.
3436 * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
3437 * default animation duration should be used.
3438 */
3439 @Override
3440 public void dismissPip(boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003441 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003442 final long ident = Binder.clearCallingIdentity();
3443 try {
3444 synchronized (mGlobalLock) {
3445 final PinnedActivityStack stack =
3446 mStackSupervisor.getDefaultDisplay().getPinnedStack();
3447 if (stack == null) {
3448 Slog.w(TAG, "dismissPip: pinned stack not found.");
3449 return;
3450 }
3451 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
3452 throw new IllegalArgumentException("Stack: " + stack
3453 + " doesn't support animated resize.");
3454 }
3455 if (animate) {
3456 stack.animateResizePinnedStack(null /* sourceHintBounds */,
3457 null /* destBounds */, animationDuration, false /* fromFullscreen */);
3458 } else {
3459 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
3460 }
3461 }
3462 } finally {
3463 Binder.restoreCallingIdentity(ident);
3464 }
3465 }
3466
3467 @Override
3468 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003469 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003470 synchronized (mGlobalLock) {
3471 mSuppressResizeConfigChanges = suppress;
3472 }
3473 }
3474
3475 /**
3476 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
3477 * animated the stack to the fullscreen, but can also be called if we are relaunching an
3478 * activity and clearing the task at the same time.
3479 */
3480 @Override
3481 // TODO: API should just be about changing windowing modes...
3482 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003483 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003484 "moveTasksToFullscreenStack()");
3485 synchronized (mGlobalLock) {
3486 final long origId = Binder.clearCallingIdentity();
3487 try {
3488 final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
3489 if (stack != null){
3490 if (!stack.isActivityTypeStandardOrUndefined()) {
3491 throw new IllegalArgumentException(
3492 "You can't move tasks from non-standard stacks.");
3493 }
3494 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
3495 }
3496 } finally {
3497 Binder.restoreCallingIdentity(origId);
3498 }
3499 }
3500 }
3501
3502 /**
3503 * Moves the top activity in the input stackId to the pinned stack.
3504 *
3505 * @param stackId Id of stack to move the top activity to pinned stack.
3506 * @param bounds Bounds to use for pinned stack.
3507 *
3508 * @return True if the top activity of the input stack was successfully moved to the pinned
3509 * stack.
3510 */
3511 @Override
3512 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003513 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003514 "moveTopActivityToPinnedStack()");
3515 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003516 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003517 throw new IllegalStateException("moveTopActivityToPinnedStack:"
3518 + "Device doesn't support picture-in-picture mode");
3519 }
3520
3521 long ident = Binder.clearCallingIdentity();
3522 try {
3523 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
3524 } finally {
3525 Binder.restoreCallingIdentity(ident);
3526 }
3527 }
3528 }
3529
3530 @Override
3531 public boolean isInMultiWindowMode(IBinder token) {
3532 final long origId = Binder.clearCallingIdentity();
3533 try {
3534 synchronized (mGlobalLock) {
3535 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3536 if (r == null) {
3537 return false;
3538 }
3539 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
3540 return r.inMultiWindowMode();
3541 }
3542 } finally {
3543 Binder.restoreCallingIdentity(origId);
3544 }
3545 }
3546
3547 @Override
3548 public boolean isInPictureInPictureMode(IBinder token) {
3549 final long origId = Binder.clearCallingIdentity();
3550 try {
3551 synchronized (mGlobalLock) {
3552 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
3553 }
3554 } finally {
3555 Binder.restoreCallingIdentity(origId);
3556 }
3557 }
3558
3559 private boolean isInPictureInPictureMode(ActivityRecord r) {
3560 if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
3561 || r.getStack().isInStackLocked(r) == null) {
3562 return false;
3563 }
3564
3565 // If we are animating to fullscreen then we have already dispatched the PIP mode
3566 // changed, so we should reflect that check here as well.
3567 final PinnedActivityStack stack = r.getStack();
3568 final PinnedStackWindowController windowController = stack.getWindowContainerController();
3569 return !windowController.isAnimatingBoundsToFullscreen();
3570 }
3571
3572 @Override
3573 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
3574 final long origId = Binder.clearCallingIdentity();
3575 try {
3576 synchronized (mGlobalLock) {
3577 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3578 "enterPictureInPictureMode", token, params);
3579
3580 // If the activity is already in picture in picture mode, then just return early
3581 if (isInPictureInPictureMode(r)) {
3582 return true;
3583 }
3584
3585 // Activity supports picture-in-picture, now check that we can enter PiP at this
3586 // point, if it is
3587 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
3588 false /* beforeStopping */)) {
3589 return false;
3590 }
3591
3592 final Runnable enterPipRunnable = () -> {
Wale Ogunwalef276a6f2018-06-15 08:26:07 -07003593 synchronized (mGlobalLock) {
3594 // Only update the saved args from the args that are set
3595 r.pictureInPictureArgs.copyOnlySet(params);
3596 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
3597 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
3598 // Adjust the source bounds by the insets for the transition down
3599 final Rect sourceBounds = new Rect(
3600 r.pictureInPictureArgs.getSourceRectHint());
3601 mStackSupervisor.moveActivityToPinnedStackLocked(
3602 r, sourceBounds, aspectRatio, "enterPictureInPictureMode");
3603 final PinnedActivityStack stack = r.getStack();
3604 stack.setPictureInPictureAspectRatio(aspectRatio);
3605 stack.setPictureInPictureActions(actions);
3606 MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
3607 r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
3608 logPictureInPictureArgs(params);
3609 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003610 };
3611
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003612 if (isKeyguardLocked()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003613 // If the keyguard is showing or occluded, then try and dismiss it before
3614 // entering picture-in-picture (this will prompt the user to authenticate if the
3615 // device is currently locked).
3616 dismissKeyguard(token, new KeyguardDismissCallback() {
3617 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003618 public void onDismissSucceeded() {
3619 mH.post(enterPipRunnable);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003620 }
3621 }, null /* message */);
3622 } else {
3623 // Enter picture in picture immediately otherwise
3624 enterPipRunnable.run();
3625 }
3626 return true;
3627 }
3628 } finally {
3629 Binder.restoreCallingIdentity(origId);
3630 }
3631 }
3632
3633 @Override
3634 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
3635 final long origId = Binder.clearCallingIdentity();
3636 try {
3637 synchronized (mGlobalLock) {
3638 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3639 "setPictureInPictureParams", token, params);
3640
3641 // Only update the saved args from the args that are set
3642 r.pictureInPictureArgs.copyOnlySet(params);
3643 if (r.inPinnedWindowingMode()) {
3644 // If the activity is already in picture-in-picture, update the pinned stack now
3645 // if it is not already expanding to fullscreen. Otherwise, the arguments will
3646 // be used the next time the activity enters PiP
3647 final PinnedActivityStack stack = r.getStack();
3648 if (!stack.isAnimatingBoundsToFullscreen()) {
3649 stack.setPictureInPictureAspectRatio(
3650 r.pictureInPictureArgs.getAspectRatio());
3651 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
3652 }
3653 }
3654 logPictureInPictureArgs(params);
3655 }
3656 } finally {
3657 Binder.restoreCallingIdentity(origId);
3658 }
3659 }
3660
3661 @Override
3662 public int getMaxNumPictureInPictureActions(IBinder token) {
3663 // Currently, this is a static constant, but later, we may change this to be dependent on
3664 // the context of the activity
3665 return 3;
3666 }
3667
3668 private void logPictureInPictureArgs(PictureInPictureParams params) {
3669 if (params.hasSetActions()) {
3670 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
3671 params.getActions().size());
3672 }
3673 if (params.hasSetAspectRatio()) {
3674 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
3675 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
3676 MetricsLogger.action(lm);
3677 }
3678 }
3679
3680 /**
3681 * Checks the state of the system and the activity associated with the given {@param token} to
3682 * verify that picture-in-picture is supported for that activity.
3683 *
3684 * @return the activity record for the given {@param token} if all the checks pass.
3685 */
3686 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
3687 IBinder token, PictureInPictureParams params) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003688 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003689 throw new IllegalStateException(caller
3690 + ": Device doesn't support picture-in-picture mode.");
3691 }
3692
3693 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3694 if (r == null) {
3695 throw new IllegalStateException(caller
3696 + ": Can't find activity for token=" + token);
3697 }
3698
3699 if (!r.supportsPictureInPicture()) {
3700 throw new IllegalStateException(caller
3701 + ": Current activity does not support picture-in-picture.");
3702 }
3703
3704 if (params.hasSetAspectRatio()
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003705 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003706 params.getAspectRatio())) {
3707 final float minAspectRatio = mContext.getResources().getFloat(
3708 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
3709 final float maxAspectRatio = mContext.getResources().getFloat(
3710 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
3711 throw new IllegalArgumentException(String.format(caller
3712 + ": Aspect ratio is too extreme (must be between %f and %f).",
3713 minAspectRatio, maxAspectRatio));
3714 }
3715
3716 // Truncate the number of actions if necessary
3717 params.truncateActions(getMaxNumPictureInPictureActions(token));
3718
3719 return r;
3720 }
3721
3722 @Override
3723 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003724 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003725 synchronized (mGlobalLock) {
3726 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
3727 if (r == null) {
3728 throw new IllegalArgumentException("Activity does not exist; token="
3729 + activityToken);
3730 }
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07003731 return r.getUriPermissionsLocked().getExternalToken();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003732 }
3733 }
3734
3735 @Override
3736 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
3737 Rect tempDockedTaskInsetBounds,
3738 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003739 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003740 long ident = Binder.clearCallingIdentity();
3741 try {
3742 synchronized (mGlobalLock) {
3743 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
3744 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
3745 PRESERVE_WINDOWS);
3746 }
3747 } finally {
3748 Binder.restoreCallingIdentity(ident);
3749 }
3750 }
3751
3752 @Override
3753 public void setSplitScreenResizing(boolean resizing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003754 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003755 final long ident = Binder.clearCallingIdentity();
3756 try {
3757 synchronized (mGlobalLock) {
3758 mStackSupervisor.setSplitScreenResizing(resizing);
3759 }
3760 } finally {
3761 Binder.restoreCallingIdentity(ident);
3762 }
3763 }
3764
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003765 /**
3766 * Check that we have the features required for VR-related API calls, and throw an exception if
3767 * not.
3768 */
3769 void enforceSystemHasVrFeature() {
3770 if (!mContext.getPackageManager().hasSystemFeature(
3771 PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
3772 throw new UnsupportedOperationException("VR mode not supported on this device!");
3773 }
3774 }
3775
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003776 @Override
3777 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003778 enforceSystemHasVrFeature();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003779
3780 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3781
3782 ActivityRecord r;
3783 synchronized (mGlobalLock) {
3784 r = ActivityRecord.isInStackLocked(token);
3785 }
3786
3787 if (r == null) {
3788 throw new IllegalArgumentException();
3789 }
3790
3791 int err;
3792 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
3793 VrManagerInternal.NO_ERROR) {
3794 return err;
3795 }
3796
3797 // Clear the binder calling uid since this path may call moveToTask().
3798 final long callingId = Binder.clearCallingIdentity();
3799 try {
3800 synchronized (mGlobalLock) {
3801 r.requestedVrComponent = (enabled) ? packageName : null;
3802
3803 // Update associated state if this activity is currently focused
Andrii Kulian52d255c2018-07-13 11:32:19 -07003804 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003805 applyUpdateVrModeLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003806 }
3807 return 0;
3808 }
3809 } finally {
3810 Binder.restoreCallingIdentity(callingId);
3811 }
3812 }
3813
3814 @Override
3815 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
3816 Slog.i(TAG, "Activity tried to startLocalVoiceInteraction");
3817 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003818 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003819 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
3820 throw new SecurityException("Only focused activity can call startVoiceInteraction");
3821 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07003822 if (mRunningVoice != null || activity.getTask().voiceSession != null
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003823 || activity.voiceSession != null) {
3824 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
3825 return;
3826 }
3827 if (activity.pendingVoiceInteractionStart) {
3828 Slog.w(TAG, "Pending start of voice interaction already.");
3829 return;
3830 }
3831 activity.pendingVoiceInteractionStart = true;
3832 }
3833 LocalServices.getService(VoiceInteractionManagerInternal.class)
3834 .startLocalVoiceInteraction(callingActivity, options);
3835 }
3836
3837 @Override
3838 public void stopLocalVoiceInteraction(IBinder callingActivity) {
3839 LocalServices.getService(VoiceInteractionManagerInternal.class)
3840 .stopLocalVoiceInteraction(callingActivity);
3841 }
3842
3843 @Override
3844 public boolean supportsLocalVoiceInteraction() {
3845 return LocalServices.getService(VoiceInteractionManagerInternal.class)
3846 .supportsLocalVoiceInteraction();
3847 }
3848
3849 /** Notifies all listeners when the pinned stack animation starts. */
3850 @Override
3851 public void notifyPinnedStackAnimationStarted() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003852 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003853 }
3854
3855 /** Notifies all listeners when the pinned stack animation ends. */
3856 @Override
3857 public void notifyPinnedStackAnimationEnded() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003858 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003859 }
3860
3861 @Override
3862 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003863 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003864 final long ident = Binder.clearCallingIdentity();
3865 try {
3866 synchronized (mGlobalLock) {
3867 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
3868 }
3869 } finally {
3870 Binder.restoreCallingIdentity(ident);
3871 }
3872 }
3873
3874 @Override
3875 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003876 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003877
3878 synchronized (mGlobalLock) {
3879 // Check if display is initialized in AM.
3880 if (!mStackSupervisor.isDisplayAdded(displayId)) {
3881 // Call might come when display is not yet added or has already been removed.
3882 if (DEBUG_CONFIGURATION) {
3883 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
3884 + displayId);
3885 }
3886 return false;
3887 }
3888
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003889 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003890 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003891 values = mWindowManager.computeNewConfiguration(displayId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003892 }
3893
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003894 if (mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003895 // Update OOM levels based on display size.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003896 mAm.mProcessList.applyDisplaySize(mWindowManager);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003897 }
3898
3899 final long origId = Binder.clearCallingIdentity();
3900 try {
3901 if (values != null) {
3902 Settings.System.clearConfiguration(values);
3903 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003904 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003905 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
3906 return mTmpUpdateConfigurationResult.changes != 0;
3907 } finally {
3908 Binder.restoreCallingIdentity(origId);
3909 }
3910 }
3911 }
3912
3913 @Override
3914 public boolean updateConfiguration(Configuration values) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003915 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003916
3917 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003918 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003919 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003920 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003921 }
3922
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003923 if (mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003924 // Update OOM levels based on display size.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003925 mAm.mProcessList.applyDisplaySize(mWindowManager);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003926 }
3927
3928 final long origId = Binder.clearCallingIdentity();
3929 try {
3930 if (values != null) {
3931 Settings.System.clearConfiguration(values);
3932 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003933 updateConfigurationLocked(values, null, false, false /* persistent */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003934 UserHandle.USER_NULL, false /* deferResume */,
3935 mTmpUpdateConfigurationResult);
3936 return mTmpUpdateConfigurationResult.changes != 0;
3937 } finally {
3938 Binder.restoreCallingIdentity(origId);
3939 }
3940 }
3941 }
3942
3943 @Override
3944 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
3945 CharSequence message) {
3946 if (message != null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003947 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003948 Manifest.permission.SHOW_KEYGUARD_MESSAGE, "dismissKeyguard()");
3949 }
3950 final long callingId = Binder.clearCallingIdentity();
3951 try {
3952 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003953 mKeyguardController.dismissKeyguard(token, callback, message);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003954 }
3955 } finally {
3956 Binder.restoreCallingIdentity(callingId);
3957 }
3958 }
3959
3960 @Override
3961 public void cancelTaskWindowTransition(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003962 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003963 "cancelTaskWindowTransition()");
3964 final long ident = Binder.clearCallingIdentity();
3965 try {
3966 synchronized (mGlobalLock) {
3967 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
3968 MATCH_TASK_IN_STACKS_ONLY);
3969 if (task == null) {
3970 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
3971 return;
3972 }
3973 task.cancelWindowTransition();
3974 }
3975 } finally {
3976 Binder.restoreCallingIdentity(ident);
3977 }
3978 }
3979
3980 @Override
3981 public ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003982 enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003983 final long ident = Binder.clearCallingIdentity();
3984 try {
3985 final TaskRecord task;
3986 synchronized (mGlobalLock) {
3987 task = mStackSupervisor.anyTaskForIdLocked(taskId,
3988 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
3989 if (task == null) {
3990 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
3991 return null;
3992 }
3993 }
3994 // Don't call this while holding the lock as this operation might hit the disk.
3995 return task.getSnapshot(reducedResolution);
3996 } finally {
3997 Binder.restoreCallingIdentity(ident);
3998 }
3999 }
4000
4001 @Override
4002 public void setDisablePreviewScreenshots(IBinder token, boolean disable) {
4003 synchronized (mGlobalLock) {
4004 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4005 if (r == null) {
4006 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
4007 + token);
4008 return;
4009 }
4010 final long origId = Binder.clearCallingIdentity();
4011 try {
4012 r.setDisablePreviewScreenshots(disable);
4013 } finally {
4014 Binder.restoreCallingIdentity(origId);
4015 }
4016 }
4017 }
4018
4019 /** Return the user id of the last resumed activity. */
4020 @Override
4021 public @UserIdInt
4022 int getLastResumedActivityUserId() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004023 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004024 Manifest.permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
4025 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07004026 if (mLastResumedActivity == null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004027 return getCurrentUserId();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004028 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004029 return mLastResumedActivity.userId;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004030 }
4031 }
4032
4033 @Override
4034 public void updateLockTaskFeatures(int userId, int flags) {
4035 final int callingUid = Binder.getCallingUid();
4036 if (callingUid != 0 && callingUid != SYSTEM_UID) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004037 mAmInternal.enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004038 "updateLockTaskFeatures()");
4039 }
4040 synchronized (mGlobalLock) {
4041 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
4042 Integer.toHexString(flags));
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07004043 getLockTaskController().updateLockTaskFeatures(userId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004044 }
4045 }
4046
4047 @Override
4048 public void setShowWhenLocked(IBinder token, boolean showWhenLocked) {
4049 synchronized (mGlobalLock) {
4050 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4051 if (r == null) {
4052 return;
4053 }
4054 final long origId = Binder.clearCallingIdentity();
4055 try {
4056 r.setShowWhenLocked(showWhenLocked);
4057 } finally {
4058 Binder.restoreCallingIdentity(origId);
4059 }
4060 }
4061 }
4062
4063 @Override
4064 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) {
4065 synchronized (mGlobalLock) {
4066 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4067 if (r == null) {
4068 return;
4069 }
4070 final long origId = Binder.clearCallingIdentity();
4071 try {
4072 r.setTurnScreenOn(turnScreenOn);
4073 } finally {
4074 Binder.restoreCallingIdentity(origId);
4075 }
4076 }
4077 }
4078
4079 @Override
4080 public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004081 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004082 "registerRemoteAnimations");
4083 definition.setCallingPid(Binder.getCallingPid());
4084 synchronized (mGlobalLock) {
4085 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4086 if (r == null) {
4087 return;
4088 }
4089 final long origId = Binder.clearCallingIdentity();
4090 try {
4091 r.registerRemoteAnimations(definition);
4092 } finally {
4093 Binder.restoreCallingIdentity(origId);
4094 }
4095 }
4096 }
4097
4098 @Override
4099 public void registerRemoteAnimationForNextActivityStart(String packageName,
4100 RemoteAnimationAdapter adapter) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004101 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004102 "registerRemoteAnimationForNextActivityStart");
4103 adapter.setCallingPid(Binder.getCallingPid());
4104 synchronized (mGlobalLock) {
4105 final long origId = Binder.clearCallingIdentity();
4106 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07004107 getActivityStartController().registerRemoteAnimationForNextActivityStart(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004108 packageName, adapter);
4109 } finally {
4110 Binder.restoreCallingIdentity(origId);
4111 }
4112 }
4113 }
4114
4115 /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
4116 @Override
4117 public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
4118 synchronized (mGlobalLock) {
4119 final long origId = Binder.clearCallingIdentity();
4120 try {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004121 mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004122 } finally {
4123 Binder.restoreCallingIdentity(origId);
4124 }
4125 }
4126 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004127
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004128 @Override
4129 public void setVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004130 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004131 synchronized (mGlobalLock) {
4132 synchronized (mAm.mPidsSelfLocked) {
4133 final int pid = Binder.getCallingPid();
4134 final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004135 mVrController.setVrThreadLocked(tid, pid, proc.getWindowProcessController());
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004136 }
4137 }
4138 }
4139
4140 @Override
4141 public void setPersistentVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004142 if (checkCallingPermission(Manifest.permission.RESTRICTED_VR_ACCESS)
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004143 != PERMISSION_GRANTED) {
4144 final String msg = "Permission Denial: setPersistentVrThread() from pid="
4145 + Binder.getCallingPid()
4146 + ", uid=" + Binder.getCallingUid()
4147 + " requires " + Manifest.permission.RESTRICTED_VR_ACCESS;
4148 Slog.w(TAG, msg);
4149 throw new SecurityException(msg);
4150 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004151 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004152 synchronized (mGlobalLock) {
4153 synchronized (mAm.mPidsSelfLocked) {
4154 final int pid = Binder.getCallingPid();
4155 final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
4156 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
4157 }
4158 }
4159 }
4160
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004161 @Override
4162 public void stopAppSwitches() {
4163 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
4164 synchronized (mGlobalLock) {
4165 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME;
4166 mDidAppSwitch = false;
4167 getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
4168 }
4169 }
4170
4171 @Override
4172 public void resumeAppSwitches() {
4173 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
4174 synchronized (mGlobalLock) {
4175 // Note that we don't execute any pending app switches... we will
4176 // let those wait until either the timeout, or the next start
4177 // activity request.
4178 mAppSwitchesAllowedTime = 0;
4179 }
4180 }
4181
4182 void onStartActivitySetDidAppSwitch() {
4183 if (mDidAppSwitch) {
4184 // This is the second allowed switch since we stopped switches, so now just generally
4185 // allow switches. Use case:
4186 // - user presses home (switches disabled, switch to home, mDidAppSwitch now true);
4187 // - user taps a home icon (coming from home so allowed, we hit here and now allow
4188 // anyone to switch again).
4189 mAppSwitchesAllowedTime = 0;
4190 } else {
4191 mDidAppSwitch = true;
4192 }
4193 }
4194
4195 /** @return whether the system should disable UI modes incompatible with VR mode. */
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004196 boolean shouldDisableNonVrUiLocked() {
4197 return mVrController.shouldDisableNonVrUiLocked();
4198 }
4199
Wale Ogunwale53783742018-09-16 10:21:51 -07004200 private void applyUpdateVrModeLocked(ActivityRecord r) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004201 // VR apps are expected to run in a main display. If an app is turning on VR for
4202 // itself, but lives in a dynamic stack, then make sure that it is moved to the main
4203 // fullscreen stack before enabling VR Mode.
4204 // TODO: The goal of this code is to keep the VR app on the main display. When the
4205 // stack implementation changes in the future, keep in mind that the use of the fullscreen
4206 // stack is a means to move the activity to the main display and a moveActivityToDisplay()
4207 // option would be a better choice here.
4208 if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
4209 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
4210 + " to main stack for VR");
4211 final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
4212 WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
4213 moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
4214 }
4215 mH.post(() -> {
4216 if (!mVrController.onVrModeChanged(r)) {
4217 return;
4218 }
4219 synchronized (mGlobalLock) {
4220 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
4221 mWindowManager.disableNonVrUi(disableNonVrUi);
4222 if (disableNonVrUi) {
4223 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
4224 // then remove the pinned stack.
4225 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
4226 }
4227 }
4228 });
4229 }
4230
Wale Ogunwale53783742018-09-16 10:21:51 -07004231 @Override
4232 public int getPackageScreenCompatMode(String packageName) {
4233 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4234 synchronized (mGlobalLock) {
4235 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4236 }
4237 }
4238
4239 @Override
4240 public void setPackageScreenCompatMode(String packageName, int mode) {
4241 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4242 "setPackageScreenCompatMode");
4243 synchronized (mGlobalLock) {
4244 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4245 }
4246 }
4247
4248 @Override
4249 public boolean getPackageAskScreenCompat(String packageName) {
4250 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4251 synchronized (mGlobalLock) {
4252 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4253 }
4254 }
4255
4256 @Override
4257 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4258 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4259 "setPackageAskScreenCompat");
4260 synchronized (mGlobalLock) {
4261 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4262 }
4263 }
4264
Andrii Kulian5f750bc2018-07-17 08:57:23 -07004265 ActivityStack getTopDisplayFocusedStack() {
4266 return mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004267 }
4268
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004269 /** Pokes the task persister. */
4270 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
4271 mRecentTasks.notifyTaskPersisterLocked(task, flush);
4272 }
4273
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004274 void onTopProcChangedLocked(WindowProcessController proc) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004275 mVrController.onTopProcChangedLocked(proc);
4276 }
4277
4278 boolean isKeyguardLocked() {
4279 return mKeyguardController.isKeyguardLocked();
4280 }
4281
4282 boolean isNextTransitionForward() {
4283 int transit = mWindowManager.getPendingAppTransition();
4284 return transit == TRANSIT_ACTIVITY_OPEN
4285 || transit == TRANSIT_TASK_OPEN
4286 || transit == TRANSIT_TASK_TO_FRONT;
4287 }
4288
Wale Ogunwalef6733932018-06-27 05:14:34 -07004289 void dumpSleepStates(PrintWriter pw, boolean testPssMode) {
4290 synchronized (mGlobalLock) {
4291 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
4292 if (mRunningVoice != null) {
4293 pw.println(" mRunningVoice=" + mRunningVoice);
4294 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
4295 }
4296 pw.println(" mSleeping=" + mSleeping);
4297 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + testPssMode);
4298 pw.println(" mVrController=" + mVrController);
4299 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004300 }
4301
Wale Ogunwalef6733932018-06-27 05:14:34 -07004302 void writeSleepStateToProto(ProtoOutputStream proto) {
4303 for (ActivityTaskManagerInternal.SleepToken st : mStackSupervisor.mSleepTokens) {
4304 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS,
4305 st.toString());
4306 }
4307
4308 if (mRunningVoice != null) {
4309 final long vrToken = proto.start(
4310 ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
4311 proto.write(ActivityManagerServiceDumpProcessesProto.Voice.SESSION,
4312 mRunningVoice.toString());
4313 mVoiceWakeLock.writeToProto(
4314 proto, ActivityManagerServiceDumpProcessesProto.Voice.WAKELOCK);
4315 proto.end(vrToken);
4316 }
4317
4318 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
4319 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN,
4320 mShuttingDown);
4321 mVrController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004322 }
4323
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004324 int getCurrentUserId() {
4325 return mAmInternal.getCurrentUserId();
4326 }
4327
4328 private void enforceNotIsolatedCaller(String caller) {
4329 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4330 throw new SecurityException("Isolated process not allowed to call " + caller);
4331 }
4332 }
4333
Wale Ogunwalef6733932018-06-27 05:14:34 -07004334 public Configuration getConfiguration() {
4335 Configuration ci;
4336 synchronized(mGlobalLock) {
Yunfan Chen75157d72018-07-27 14:47:21 +09004337 ci = new Configuration(getGlobalConfigurationForCallingPid());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004338 ci.userSetLocale = false;
4339 }
4340 return ci;
4341 }
4342
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004343 /**
4344 * Current global configuration information. Contains general settings for the entire system,
4345 * also corresponds to the merged configuration of the default display.
4346 */
4347 Configuration getGlobalConfiguration() {
4348 return mStackSupervisor.getConfiguration();
4349 }
4350
4351 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4352 boolean initLocale) {
4353 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
4354 }
4355
4356 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4357 boolean initLocale, boolean deferResume) {
4358 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
4359 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
4360 UserHandle.USER_NULL, deferResume);
4361 }
4362
4363 void updatePersistentConfiguration(Configuration values, @UserIdInt int userId) {
4364 final long origId = Binder.clearCallingIdentity();
4365 try {
4366 synchronized (mGlobalLock) {
4367 updateConfigurationLocked(values, null, false, true, userId,
4368 false /* deferResume */);
4369 }
4370 } finally {
4371 Binder.restoreCallingIdentity(origId);
4372 }
4373 }
4374
4375 void updateUserConfiguration() {
4376 synchronized (mGlobalLock) {
4377 final Configuration configuration = new Configuration(getGlobalConfiguration());
4378 final int currentUserId = mAmInternal.getCurrentUserId();
4379 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
4380 currentUserId, Settings.System.canWrite(mContext));
4381 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
4382 false /* persistent */, currentUserId, false /* deferResume */);
4383 }
4384 }
4385
4386 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4387 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
4388 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
4389 deferResume, null /* result */);
4390 }
4391
4392 /**
4393 * Do either or both things: (1) change the current configuration, and (2)
4394 * make sure the given activity is running with the (now) current
4395 * configuration. Returns true if the activity has been left running, or
4396 * false if <var>starting</var> is being destroyed to match the new
4397 * configuration.
4398 *
4399 * @param userId is only used when persistent parameter is set to true to persist configuration
4400 * for that particular user
4401 */
4402 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4403 boolean initLocale, boolean persistent, int userId, boolean deferResume,
4404 ActivityTaskManagerService.UpdateConfigurationResult result) {
4405 int changes = 0;
4406 boolean kept = true;
4407
4408 if (mWindowManager != null) {
4409 mWindowManager.deferSurfaceLayout();
4410 }
4411 try {
4412 if (values != null) {
4413 changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
4414 deferResume);
4415 }
4416
4417 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4418 } finally {
4419 if (mWindowManager != null) {
4420 mWindowManager.continueSurfaceLayout();
4421 }
4422 }
4423
4424 if (result != null) {
4425 result.changes = changes;
4426 result.activityRelaunched = !kept;
4427 }
4428 return kept;
4429 }
4430
4431 /**
4432 * Returns true if this configuration change is interesting enough to send an
4433 * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
4434 */
4435 private static boolean isSplitConfigurationChange(int configDiff) {
4436 return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
4437 }
4438
4439 /** Update default (global) configuration and notify listeners about changes. */
4440 private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
4441 boolean persistent, int userId, boolean deferResume) {
4442 mTempConfig.setTo(getGlobalConfiguration());
4443 final int changes = mTempConfig.updateFrom(values);
4444 if (changes == 0) {
4445 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
4446 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
4447 // performDisplayOverrideConfigUpdate in order to send the new display configuration
4448 // (even if there are no actual changes) to unfreeze the window.
4449 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
4450 return 0;
4451 }
4452
4453 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
4454 "Updating global configuration to: " + values);
4455
4456 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
4457 StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
4458 values.colorMode,
4459 values.densityDpi,
4460 values.fontScale,
4461 values.hardKeyboardHidden,
4462 values.keyboard,
4463 values.keyboardHidden,
4464 values.mcc,
4465 values.mnc,
4466 values.navigation,
4467 values.navigationHidden,
4468 values.orientation,
4469 values.screenHeightDp,
4470 values.screenLayout,
4471 values.screenWidthDp,
4472 values.smallestScreenWidthDp,
4473 values.touchscreen,
4474 values.uiMode);
4475
4476
4477 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
4478 final LocaleList locales = values.getLocales();
4479 int bestLocaleIndex = 0;
4480 if (locales.size() > 1) {
4481 if (mSupportedSystemLocales == null) {
4482 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
4483 }
4484 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
4485 }
4486 SystemProperties.set("persist.sys.locale",
4487 locales.get(bestLocaleIndex).toLanguageTag());
4488 LocaleList.setDefault(locales, bestLocaleIndex);
4489 mAm.mHandler.sendMessage(mAm.mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
4490 locales.get(bestLocaleIndex)));
4491 }
4492
Yunfan Chen75157d72018-07-27 14:47:21 +09004493 mTempConfig.seq = increaseConfigurationSeqLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004494
4495 // Update stored global config and notify everyone about the change.
4496 mStackSupervisor.onConfigurationChanged(mTempConfig);
4497
4498 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
4499 // TODO(multi-display): Update UsageEvents#Event to include displayId.
4500 mAm.mUsageStatsService.reportConfigurationChange(
4501 mTempConfig, mAmInternal.getCurrentUserId());
4502
4503 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
Wale Ogunwalef6733932018-06-27 05:14:34 -07004504 updateShouldShowDialogsLocked(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004505
4506 AttributeCache ac = AttributeCache.instance();
4507 if (ac != null) {
4508 ac.updateConfiguration(mTempConfig);
4509 }
4510
4511 // Make sure all resources in our process are updated right now, so that anyone who is going
4512 // to retrieve resource values after we return will be sure to get the new ones. This is
4513 // especially important during boot, where the first config change needs to guarantee all
4514 // resources have that config before following boot code is executed.
4515 mAm.mSystemThread.applyConfigurationToResources(mTempConfig);
4516
4517 // We need another copy of global config because we're scheduling some calls instead of
4518 // running them in place. We need to be sure that object we send will be handled unchanged.
4519 final Configuration configCopy = new Configuration(mTempConfig);
4520 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
4521 Message msg = mAm.mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
4522 msg.obj = configCopy;
4523 msg.arg1 = userId;
4524 mAm.mHandler.sendMessage(msg);
4525 }
4526
Yunfan Chen34fcc7a2018-10-11 16:26:09 -07004527 for (int i = mPidMap.size() - 1; i >= 0; i--) {
4528 WindowProcessController app = mPidMap.get(mPidMap.keyAt(i));
4529 if (DEBUG_CONFIGURATION) {
4530 Slog.v(TAG_CONFIGURATION, "Update process config of "
4531 + app.mName + " to new config " + configCopy);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004532 }
Yunfan Chen34fcc7a2018-10-11 16:26:09 -07004533 app.onConfigurationChanged(configCopy);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004534 }
4535
4536 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
4537 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
4538 | Intent.FLAG_RECEIVER_FOREGROUND
4539 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4540 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4541 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4542 UserHandle.USER_ALL);
4543 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
4544 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
4545 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
4546 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
4547 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4548 if (initLocale || !mAm.mProcessesReady) {
4549 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
4550 }
4551 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4552 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4553 UserHandle.USER_ALL);
4554 }
4555
4556 // Send a broadcast to PackageInstallers if the configuration change is interesting
4557 // for the purposes of installing additional splits.
4558 if (!initLocale && isSplitConfigurationChange(changes)) {
4559 intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
4560 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
4561 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
4562
4563 // Typically only app stores will have this permission.
4564 String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES };
4565 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions,
4566 OP_NONE, null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
4567 }
4568
4569 // Override configuration of the default display duplicates global config, so we need to
4570 // update it also. This will also notify WindowManager about changes.
4571 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
4572 DEFAULT_DISPLAY);
4573
4574 return changes;
4575 }
4576
4577 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
4578 boolean deferResume, int displayId) {
4579 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
4580 displayId, null /* result */);
4581 }
4582
4583 /**
4584 * Updates override configuration specific for the selected display. If no config is provided,
4585 * new one will be computed in WM based on current display info.
4586 */
4587 boolean updateDisplayOverrideConfigurationLocked(Configuration values,
4588 ActivityRecord starting, boolean deferResume, int displayId,
4589 ActivityTaskManagerService.UpdateConfigurationResult result) {
4590 int changes = 0;
4591 boolean kept = true;
4592
4593 if (mWindowManager != null) {
4594 mWindowManager.deferSurfaceLayout();
4595 }
4596 try {
4597 if (values != null) {
4598 if (displayId == DEFAULT_DISPLAY) {
4599 // Override configuration of the default display duplicates global config, so
4600 // we're calling global config update instead for default display. It will also
4601 // apply the correct override config.
4602 changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
4603 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
4604 } else {
4605 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
4606 }
4607 }
4608
4609 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4610 } finally {
4611 if (mWindowManager != null) {
4612 mWindowManager.continueSurfaceLayout();
4613 }
4614 }
4615
4616 if (result != null) {
4617 result.changes = changes;
4618 result.activityRelaunched = !kept;
4619 }
4620 return kept;
4621 }
4622
4623 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
4624 int displayId) {
4625 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
4626 final int changes = mTempConfig.updateFrom(values);
4627 if (changes != 0) {
4628 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
4629 + mTempConfig + " for displayId=" + displayId);
4630 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
4631
4632 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
4633 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004634 mAppWarnings.onDensityChanged();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004635
4636 mAm.killAllBackgroundProcessesExcept(N,
4637 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
4638 }
4639 }
4640
4641 // Update the configuration with WM first and check if any of the stacks need to be resized
4642 // due to the configuration change. If so, resize the stacks now and do any relaunches if
4643 // necessary. This way we don't need to relaunch again afterwards in
4644 // ensureActivityConfiguration().
4645 if (mWindowManager != null) {
4646 final int[] resizedStacks =
4647 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
4648 if (resizedStacks != null) {
4649 for (int stackId : resizedStacks) {
4650 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
4651 }
4652 }
4653 }
4654
4655 return changes;
4656 }
4657
Wale Ogunwalef6733932018-06-27 05:14:34 -07004658 private void updateEventDispatchingLocked(boolean booted) {
4659 mWindowManager.setEventDispatching(booted && !mShuttingDown);
4660 }
4661
4662 void enableScreenAfterBoot(boolean booted) {
4663 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4664 SystemClock.uptimeMillis());
4665 mWindowManager.enableScreenAfterBoot();
4666
4667 synchronized (mGlobalLock) {
4668 updateEventDispatchingLocked(booted);
4669 }
4670 }
4671
4672 boolean canShowErrorDialogs() {
4673 return mShowDialogs && !mSleeping && !mShuttingDown
4674 && !mKeyguardController.isKeyguardOrAodShowing(DEFAULT_DISPLAY)
4675 && !hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
Wale Ogunwale86b74462018-07-02 08:42:43 -07004676 mAmInternal.getCurrentUserId())
Wale Ogunwalef6733932018-06-27 05:14:34 -07004677 && !(UserManager.isDeviceInDemoMode(mContext)
Wale Ogunwale86b74462018-07-02 08:42:43 -07004678 && mAmInternal.getCurrentUser().isDemo());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004679 }
4680
Wale Ogunwale906f9c62018-07-23 11:23:44 -07004681 static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
4682 if (r == null || !r.hasProcess()) {
4683 return KEY_DISPATCHING_TIMEOUT_MS;
4684 }
4685 return getInputDispatchingTimeoutLocked(r.app);
4686 }
4687
4688 private static long getInputDispatchingTimeoutLocked(WindowProcessController r) {
4689 if (r != null && (r.isInstrumenting() || r.isUsingWrapper())) {
4690 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS;
4691 }
4692 return KEY_DISPATCHING_TIMEOUT_MS;
4693 }
4694
4695 long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
4696 if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
4697 throw new SecurityException("Requires permission " + FILTER_EVENTS);
4698 }
4699 WindowProcessController proc;
4700 long timeout;
4701 synchronized (mGlobalLock) {
4702 proc = mPidMap.get(pid);
4703 timeout = getInputDispatchingTimeoutLocked(proc);
4704 }
4705
4706 if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
4707 return -1;
4708 }
4709
4710 return timeout;
4711 }
4712
4713 /**
4714 * Handle input dispatching timeouts.
4715 * Returns whether input dispatching should be aborted or not.
4716 */
4717 boolean inputDispatchingTimedOut(final WindowProcessController proc,
4718 final ActivityRecord activity, final ActivityRecord parent,
4719 final boolean aboveSystem, String reason) {
4720 if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
4721 throw new SecurityException("Requires permission " + FILTER_EVENTS);
4722 }
4723
4724 final String annotation;
4725 if (reason == null) {
4726 annotation = "Input dispatching timed out";
4727 } else {
4728 annotation = "Input dispatching timed out (" + reason + ")";
4729 }
4730
4731 if (proc != null) {
4732 synchronized (mGlobalLock) {
4733 if (proc.isDebugging()) {
4734 return false;
4735 }
4736
4737 if (proc.isInstrumenting()) {
4738 Bundle info = new Bundle();
4739 info.putString("shortMsg", "keyDispatchingTimedOut");
4740 info.putString("longMsg", annotation);
4741 mAm.finishInstrumentationLocked(
4742 (ProcessRecord) proc.mOwner, Activity.RESULT_CANCELED, info);
4743 return true;
4744 }
4745 }
4746 mH.post(() -> {
4747 mAm.mAppErrors.appNotResponding(
4748 (ProcessRecord) proc.mOwner, activity, parent, aboveSystem, annotation);
4749 });
4750 }
4751
4752 return true;
4753 }
4754
Wale Ogunwalef6733932018-06-27 05:14:34 -07004755 /**
4756 * Decide based on the configuration whether we should show the ANR,
4757 * crash, etc dialogs. The idea is that if there is no affordance to
4758 * press the on-screen buttons, or the user experience would be more
4759 * greatly impacted than the crash itself, we shouldn't show the dialog.
4760 *
4761 * A thought: SystemUI might also want to get told about this, the Power
4762 * dialog / global actions also might want different behaviors.
4763 */
4764 private void updateShouldShowDialogsLocked(Configuration config) {
4765 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
4766 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
4767 && config.navigation == Configuration.NAVIGATION_NONAV);
4768 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
4769 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
4770 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
4771 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
4772 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
4773 final boolean hideDialogsSet = Settings.Global.getInt(mContext.getContentResolver(),
4774 HIDE_ERROR_DIALOGS, 0) != 0;
4775 mShowDialogs = inputMethodExists && uiModeSupportsDialogs && !hideDialogsSet;
4776 }
4777
4778 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
4779 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
4780 FONT_SCALE, 1.0f, userId);
4781
4782 synchronized (this) {
4783 if (getGlobalConfiguration().fontScale == scaleFactor) {
4784 return;
4785 }
4786
4787 final Configuration configuration
4788 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
4789 configuration.fontScale = scaleFactor;
4790 updatePersistentConfiguration(configuration, userId);
4791 }
4792 }
4793
4794 // Actually is sleeping or shutting down or whatever else in the future
4795 // is an inactive state.
4796 boolean isSleepingOrShuttingDownLocked() {
4797 return isSleepingLocked() || mShuttingDown;
4798 }
4799
4800 boolean isSleepingLocked() {
4801 return mSleeping;
4802 }
4803
Riddle Hsu16567132018-08-16 21:37:47 +08004804 /** Update AMS states when an activity is resumed. */
Wale Ogunwalef6733932018-06-27 05:14:34 -07004805 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
4806 final TaskRecord task = r.getTask();
4807 if (task.isActivityTypeStandard()) {
4808 if (mCurAppTimeTracker != r.appTimeTracker) {
4809 // We are switching app tracking. Complete the current one.
4810 if (mCurAppTimeTracker != null) {
4811 mCurAppTimeTracker.stop();
4812 mH.obtainMessage(
4813 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
4814 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
4815 mCurAppTimeTracker = null;
4816 }
4817 if (r.appTimeTracker != null) {
4818 mCurAppTimeTracker = r.appTimeTracker;
4819 startTimeTrackingFocusedActivityLocked();
4820 }
4821 } else {
4822 startTimeTrackingFocusedActivityLocked();
4823 }
4824 } else {
4825 r.appTimeTracker = null;
4826 }
4827 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
4828 // TODO: Probably not, because we don't want to resume voice on switching
4829 // back to this activity
4830 if (task.voiceInteractor != null) {
4831 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
4832 } else {
4833 finishRunningVoiceLocked();
4834
4835 if (mLastResumedActivity != null) {
4836 final IVoiceInteractionSession session;
4837
4838 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
4839 if (lastResumedActivityTask != null
4840 && lastResumedActivityTask.voiceSession != null) {
4841 session = lastResumedActivityTask.voiceSession;
4842 } else {
4843 session = mLastResumedActivity.voiceSession;
4844 }
4845
4846 if (session != null) {
4847 // We had been in a voice interaction session, but now focused has
4848 // move to something different. Just finish the session, we can't
4849 // return to it and retain the proper state and synchronization with
4850 // the voice interaction service.
4851 finishVoiceTask(session);
4852 }
4853 }
4854 }
4855
4856 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
4857 mAmInternal.sendForegroundProfileChanged(r.userId);
4858 }
4859 updateResumedAppTrace(r);
4860 mLastResumedActivity = r;
4861
Tiger Huang1e5b10a2018-07-30 20:19:51 +08004862 r.getDisplay().setFocusedApp(r, true);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004863
4864 applyUpdateLockStateLocked(r);
4865 applyUpdateVrModeLocked(r);
4866
4867 EventLogTags.writeAmSetResumedActivity(
4868 r == null ? -1 : r.userId,
4869 r == null ? "NULL" : r.shortComponentName,
4870 reason);
4871 }
4872
4873 ActivityTaskManagerInternal.SleepToken acquireSleepToken(String tag, int displayId) {
4874 synchronized (mGlobalLock) {
4875 final ActivityTaskManagerInternal.SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
4876 updateSleepIfNeededLocked();
4877 return token;
4878 }
4879 }
4880
4881 void updateSleepIfNeededLocked() {
4882 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
4883 final boolean wasSleeping = mSleeping;
4884 boolean updateOomAdj = false;
4885
4886 if (!shouldSleep) {
4887 // If wasSleeping is true, we need to wake up activity manager state from when
4888 // we started sleeping. In either case, we need to apply the sleep tokens, which
4889 // will wake up stacks or put them to sleep as appropriate.
4890 if (wasSleeping) {
4891 mSleeping = false;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07004892 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
4893 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__AWAKE);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004894 startTimeTrackingFocusedActivityLocked();
4895 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
4896 mStackSupervisor.comeOutOfSleepIfNeededLocked();
4897 }
4898 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
4899 if (wasSleeping) {
4900 updateOomAdj = true;
4901 }
4902 } else if (!mSleeping && shouldSleep) {
4903 mSleeping = true;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07004904 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
4905 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__ASLEEP);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004906 if (mCurAppTimeTracker != null) {
4907 mCurAppTimeTracker.stop();
4908 }
4909 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
4910 mStackSupervisor.goingToSleepLocked();
4911 updateResumedAppTrace(null /* resumed */);
4912 updateOomAdj = true;
4913 }
4914 if (updateOomAdj) {
4915 mH.post(mAmInternal::updateOomAdj);
4916 }
4917 }
4918
4919 void updateOomAdj() {
4920 mH.post(mAmInternal::updateOomAdj);
4921 }
4922
Wale Ogunwale53783742018-09-16 10:21:51 -07004923 void updateCpuStats() {
4924 mH.post(mAmInternal::updateCpuStats);
4925 }
4926
4927 void updateUsageStats(ActivityRecord component, boolean resumed) {
4928 final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::updateUsageStats,
4929 mAmInternal, component.realActivity, component.app.mUid, component.userId, resumed);
4930 mH.sendMessage(m);
4931 }
4932
4933 void setBooting(boolean booting) {
4934 mAmInternal.setBooting(booting);
4935 }
4936
4937 boolean isBooting() {
4938 return mAmInternal.isBooting();
4939 }
4940
4941 void setBooted(boolean booted) {
4942 mAmInternal.setBooted(booted);
4943 }
4944
4945 boolean isBooted() {
4946 return mAmInternal.isBooted();
4947 }
4948
4949 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
4950 mH.post(() -> {
4951 if (finishBooting) {
4952 mAmInternal.finishBooting();
4953 }
4954 if (enableScreen) {
4955 mInternal.enableScreenAfterBoot(isBooted());
4956 }
4957 });
4958 }
4959
4960 void setHeavyWeightProcess(ActivityRecord root) {
4961 mHeavyWeightProcess = root.app;
4962 final Message m = PooledLambda.obtainMessage(
4963 ActivityTaskManagerService::postHeavyWeightProcessNotification, this,
4964 root.app, root.intent, root.userId);
4965 mH.sendMessage(m);
4966 }
4967
4968 void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
4969 if (mHeavyWeightProcess == null || mHeavyWeightProcess != proc) {
4970 return;
4971 }
4972
4973 mHeavyWeightProcess = null;
4974 final Message m = PooledLambda.obtainMessage(
4975 ActivityTaskManagerService::cancelHeavyWeightProcessNotification, this,
4976 proc.mUserId);
4977 mH.sendMessage(m);
4978 }
4979
4980 private void cancelHeavyWeightProcessNotification(int userId) {
4981 final INotificationManager inm = NotificationManager.getService();
4982 if (inm == null) {
4983 return;
4984 }
4985 try {
4986 inm.cancelNotificationWithTag("android", null,
4987 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, userId);
4988 } catch (RuntimeException e) {
4989 Slog.w(TAG, "Error canceling notification for service", e);
4990 } catch (RemoteException e) {
4991 }
4992
4993 }
4994
4995 private void postHeavyWeightProcessNotification(
4996 WindowProcessController proc, Intent intent, int userId) {
4997 if (proc == null) {
4998 return;
4999 }
5000
5001 final INotificationManager inm = NotificationManager.getService();
5002 if (inm == null) {
5003 return;
5004 }
5005
5006 try {
5007 Context context = mContext.createPackageContext(proc.mInfo.packageName, 0);
5008 String text = mContext.getString(R.string.heavy_weight_notification,
5009 context.getApplicationInfo().loadLabel(context.getPackageManager()));
5010 Notification notification =
5011 new Notification.Builder(context,
5012 SystemNotificationChannels.HEAVY_WEIGHT_APP)
5013 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
5014 .setWhen(0)
5015 .setOngoing(true)
5016 .setTicker(text)
5017 .setColor(mContext.getColor(
5018 com.android.internal.R.color.system_notification_accent_color))
5019 .setContentTitle(text)
5020 .setContentText(
5021 mContext.getText(R.string.heavy_weight_notification_detail))
5022 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
5023 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
5024 new UserHandle(userId)))
5025 .build();
5026 try {
5027 inm.enqueueNotificationWithTag("android", "android", null,
5028 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, notification, userId);
5029 } catch (RuntimeException e) {
5030 Slog.w(TAG, "Error showing notification for heavy-weight app", e);
5031 } catch (RemoteException e) {
5032 }
5033 } catch (PackageManager.NameNotFoundException e) {
5034 Slog.w(TAG, "Unable to create context for heavy notification", e);
5035 }
5036
5037 }
5038
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07005039 IIntentSender getIntentSenderLocked(int type, String packageName, int callingUid, int userId,
5040 IBinder token, String resultWho, int requestCode, Intent[] intents,
5041 String[] resolvedTypes, int flags, Bundle bOptions) {
5042
5043 ActivityRecord activity = null;
5044 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5045 activity = ActivityRecord.isInStackLocked(token);
5046 if (activity == null) {
5047 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
5048 return null;
5049 }
5050 if (activity.finishing) {
5051 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
5052 return null;
5053 }
5054 }
5055
5056 final PendingIntentRecord rec = mPendingIntentController.getIntentSender(type, packageName,
5057 callingUid, userId, token, resultWho, requestCode, intents, resolvedTypes, flags,
5058 bOptions);
5059 final boolean noCreate = (flags & PendingIntent.FLAG_NO_CREATE) != 0;
5060 if (noCreate) {
5061 return rec;
5062 }
5063 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5064 if (activity.pendingResults == null) {
5065 activity.pendingResults = new HashSet<>();
5066 }
5067 activity.pendingResults.add(rec.ref);
5068 }
5069 return rec;
5070 }
5071
Andrii Kulian52d255c2018-07-13 11:32:19 -07005072 // TODO(b/111541062): Update app time tracking to make it aware of multiple resumed activities
Wale Ogunwalef6733932018-06-27 05:14:34 -07005073 private void startTimeTrackingFocusedActivityLocked() {
Andrii Kulian52d255c2018-07-13 11:32:19 -07005074 final ActivityRecord resumedActivity = mStackSupervisor.getTopResumedActivity();
Wale Ogunwalef6733932018-06-27 05:14:34 -07005075 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
5076 mCurAppTimeTracker.start(resumedActivity.packageName);
5077 }
5078 }
5079
5080 private void updateResumedAppTrace(@Nullable ActivityRecord resumed) {
5081 if (mTracedResumedActivity != null) {
5082 Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER,
5083 constructResumedTraceName(mTracedResumedActivity.packageName), 0);
5084 }
5085 if (resumed != null) {
5086 Trace.asyncTraceBegin(TRACE_TAG_ACTIVITY_MANAGER,
5087 constructResumedTraceName(resumed.packageName), 0);
5088 }
5089 mTracedResumedActivity = resumed;
5090 }
5091
5092 private String constructResumedTraceName(String packageName) {
5093 return "focused app: " + packageName;
5094 }
5095
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005096 /** Helper method that requests bounds from WM and applies them to stack. */
5097 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
5098 final Rect newStackBounds = new Rect();
5099 final ActivityStack stack = mStackSupervisor.getStack(stackId);
5100
5101 // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
5102 if (stack == null) {
5103 final StringWriter writer = new StringWriter();
5104 final PrintWriter printWriter = new PrintWriter(writer);
5105 mStackSupervisor.dumpDisplays(printWriter);
5106 printWriter.flush();
5107
5108 Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
5109 }
5110
5111 stack.getBoundsForNewConfiguration(newStackBounds);
5112 mStackSupervisor.resizeStackLocked(
5113 stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
5114 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
5115 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
5116 }
5117
5118 /** Applies latest configuration and/or visibility updates if needed. */
5119 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
5120 boolean kept = true;
Andrii Kulian5f750bc2018-07-17 08:57:23 -07005121 final ActivityStack mainStack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005122 // mainStack is null during startup.
5123 if (mainStack != null) {
5124 if (changes != 0 && starting == null) {
5125 // If the configuration changed, and the caller is not already
5126 // in the process of starting an activity, then find the top
5127 // activity to check if its configuration needs to change.
5128 starting = mainStack.topRunningActivityLocked();
5129 }
5130
5131 if (starting != null) {
5132 kept = starting.ensureActivityConfiguration(changes,
5133 false /* preserveWindow */);
5134 // And we need to make sure at this point that all other activities
5135 // are made visible with the correct configuration.
5136 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
5137 !PRESERVE_WINDOWS);
5138 }
5139 }
5140
5141 return kept;
5142 }
5143
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005144 void scheduleAppGcsLocked() {
5145 mH.post(() -> mAmInternal.scheduleAppGcs());
5146 }
5147
Wale Ogunwale53783742018-09-16 10:21:51 -07005148 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
5149 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
5150 }
5151
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005152 /**
5153 * Returns the PackageManager. Used by classes hosted by {@link ActivityTaskManagerService}. The
5154 * PackageManager could be unavailable at construction time and therefore needs to be accessed
5155 * on demand.
5156 */
5157 IPackageManager getPackageManager() {
5158 return AppGlobals.getPackageManager();
5159 }
5160
5161 PackageManagerInternal getPackageManagerInternalLocked() {
5162 if (mPmInternal == null) {
5163 mPmInternal = LocalServices.getService(PackageManagerInternal.class);
5164 }
5165 return mPmInternal;
5166 }
5167
Wale Ogunwale008163e2018-07-23 23:11:08 -07005168 AppWarnings getAppWarningsLocked() {
5169 return mAppWarnings;
5170 }
5171
Wale Ogunwale214f3482018-10-04 11:00:47 -07005172 Intent getHomeIntent() {
5173 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
5174 intent.setComponent(mTopComponent);
5175 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
5176 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5177 intent.addCategory(Intent.CATEGORY_HOME);
5178 }
5179 return intent;
5180 }
5181
5182 /**
5183 * This starts home activity on displays that can have system decorations and only if the
5184 * home activity can have multiple instances.
5185 */
5186 boolean startHomeActivityLocked(int userId, String reason, int displayId) {
5187 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL && mTopAction == null) {
5188 // We are running in factory test mode, but unable to find the factory test app, so just
5189 // sit around displaying the error message and don't try to start anything.
5190 return false;
5191 }
5192
5193 final Intent intent = getHomeIntent();
5194 ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
5195 if (aInfo != null) {
5196 intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
5197 // Don't do this if the home app is currently being instrumented.
5198 aInfo = new ActivityInfo(aInfo);
5199 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
5200 WindowProcessController app =
5201 getProcessController(aInfo.processName, aInfo.applicationInfo.uid);
5202 if (app == null || !app.isInstrumenting()) {
5203 intent.setFlags(intent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
5204 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
5205 // For ANR debugging to verify if the user activity is the one that actually
5206 // launched.
5207 final String myReason = reason + ":" + userId + ":" + resolvedUserId;
5208 getActivityStartController().startHomeActivity(intent, aInfo, myReason, displayId);
5209 }
5210 } else {
5211 Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
5212 }
5213
5214 return true;
5215 }
5216
5217 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
5218 ActivityInfo ai = null;
5219 final ComponentName comp = intent.getComponent();
5220 try {
5221 if (comp != null) {
5222 // Factory test.
5223 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
5224 } else {
5225 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
5226 intent,
5227 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
5228 flags, userId);
5229
5230 if (info != null) {
5231 ai = info.activityInfo;
5232 }
5233 }
5234 } catch (RemoteException e) {
5235 // ignore
5236 }
5237
5238 return ai;
5239 }
5240
5241 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
5242 if (info == null) return null;
5243 ApplicationInfo newInfo = new ApplicationInfo(info);
5244 newInfo.initForUser(userId);
5245 return newInfo;
5246 }
5247
5248 private WindowProcessController getProcessController(String processName, int uid) {
5249 if (uid == SYSTEM_UID) {
5250 // The system gets to run in any process. If there are multiple processes with the same
5251 // uid, just pick the first (this should never happen).
5252 final SparseArray<WindowProcessController> procs =
5253 mProcessNames.getMap().get(processName);
5254 if (procs == null) return null;
5255 final int procCount = procs.size();
5256 for (int i = 0; i < procCount; i++) {
5257 final int procUid = procs.keyAt(i);
5258 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
5259 // Don't use an app process or different user process for system component.
5260 continue;
5261 }
5262 return procs.valueAt(i);
5263 }
5264 }
5265
5266 return mProcessNames.get(processName, uid);
5267 }
5268
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005269 void logAppTooSlow(WindowProcessController app, long startTime, String msg) {
5270 if (true || Build.IS_USER) {
5271 return;
5272 }
5273
5274 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5275 StrictMode.allowThreadDiskWrites();
5276 try {
5277 File tracesDir = new File("/data/anr");
5278 File tracesFile = null;
5279 try {
5280 tracesFile = File.createTempFile("app_slow", null, tracesDir);
5281
5282 StringBuilder sb = new StringBuilder();
5283 Time tobj = new Time();
5284 tobj.set(System.currentTimeMillis());
5285 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5286 sb.append(": ");
5287 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5288 sb.append(" since ");
5289 sb.append(msg);
5290 FileOutputStream fos = new FileOutputStream(tracesFile);
5291 fos.write(sb.toString().getBytes());
5292 if (app == null) {
5293 fos.write("\n*** No application process!".getBytes());
5294 }
5295 fos.close();
5296 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5297 } catch (IOException e) {
5298 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesFile, e);
5299 return;
5300 }
5301
5302 if (app != null && app.getPid() > 0) {
5303 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5304 firstPids.add(app.getPid());
5305 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, null, null);
5306 }
5307
5308 File lastTracesFile = null;
5309 File curTracesFile = null;
5310 for (int i=9; i>=0; i--) {
5311 String name = String.format(Locale.US, "slow%02d.txt", i);
5312 curTracesFile = new File(tracesDir, name);
5313 if (curTracesFile.exists()) {
5314 if (lastTracesFile != null) {
5315 curTracesFile.renameTo(lastTracesFile);
5316 } else {
5317 curTracesFile.delete();
5318 }
5319 }
5320 lastTracesFile = curTracesFile;
5321 }
5322 tracesFile.renameTo(curTracesFile);
5323 } finally {
5324 StrictMode.setThreadPolicy(oldPolicy);
5325 }
5326 }
5327
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005328 final class H extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005329 static final int REPORT_TIME_TRACKER_MSG = 1;
5330
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005331 public H(Looper looper) {
5332 super(looper, null, true);
5333 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005334
5335 @Override
5336 public void handleMessage(Message msg) {
5337 switch (msg.what) {
5338 case REPORT_TIME_TRACKER_MSG: {
5339 AppTimeTracker tracker = (AppTimeTracker) msg.obj;
5340 tracker.deliverResult(mContext);
5341 } break;
5342 }
5343 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005344 }
5345
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005346 final class UiHandler extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005347 static final int DISMISS_DIALOG_UI_MSG = 1;
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005348
5349 public UiHandler() {
5350 super(com.android.server.UiThread.get().getLooper(), null, true);
5351 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005352
5353 @Override
5354 public void handleMessage(Message msg) {
5355 switch (msg.what) {
5356 case DISMISS_DIALOG_UI_MSG: {
5357 final Dialog d = (Dialog) msg.obj;
5358 d.dismiss();
5359 break;
5360 }
5361 }
5362 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005363 }
5364
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005365 final class LocalService extends ActivityTaskManagerInternal {
5366 @Override
5367 public SleepToken acquireSleepToken(String tag, int displayId) {
5368 Preconditions.checkNotNull(tag);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005369 return ActivityTaskManagerService.this.acquireSleepToken(tag, displayId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005370 }
5371
5372 @Override
5373 public ComponentName getHomeActivityForUser(int userId) {
5374 synchronized (mGlobalLock) {
Louis Changbd48dca2018-08-29 17:44:34 +08005375 ActivityRecord homeActivity =
5376 mStackSupervisor.getDefaultDisplayHomeActivityForUser(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005377 return homeActivity == null ? null : homeActivity.realActivity;
5378 }
5379 }
5380
5381 @Override
5382 public void onLocalVoiceInteractionStarted(IBinder activity,
5383 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
5384 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005385 onLocalVoiceInteractionStartedLocked(activity, voiceSession, voiceInteractor);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005386 }
5387 }
5388
5389 @Override
5390 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
5391 synchronized (mGlobalLock) {
5392 mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
5393 reasons, timestamp);
5394 }
5395 }
5396
5397 @Override
5398 public void notifyAppTransitionFinished() {
5399 synchronized (mGlobalLock) {
5400 mStackSupervisor.notifyAppTransitionDone();
5401 }
5402 }
5403
5404 @Override
5405 public void notifyAppTransitionCancelled() {
5406 synchronized (mGlobalLock) {
5407 mStackSupervisor.notifyAppTransitionDone();
5408 }
5409 }
5410
5411 @Override
5412 public List<IBinder> getTopVisibleActivities() {
5413 synchronized (mGlobalLock) {
5414 return mStackSupervisor.getTopVisibleActivities();
5415 }
5416 }
5417
5418 @Override
5419 public void notifyDockedStackMinimizedChanged(boolean minimized) {
5420 synchronized (mGlobalLock) {
5421 mStackSupervisor.setDockedStackMinimized(minimized);
5422 }
5423 }
5424
5425 @Override
5426 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
5427 Bundle bOptions) {
5428 Preconditions.checkNotNull(intents, "intents");
5429 final String[] resolvedTypes = new String[intents.length];
5430
5431 // UID of the package on user userId.
5432 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
5433 // packageUid may not be initialized.
5434 int packageUid = 0;
5435 final long ident = Binder.clearCallingIdentity();
5436
5437 try {
5438 for (int i = 0; i < intents.length; i++) {
5439 resolvedTypes[i] =
5440 intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
5441 }
5442
5443 packageUid = AppGlobals.getPackageManager().getPackageUid(
5444 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
5445 } catch (RemoteException e) {
5446 // Shouldn't happen.
5447 } finally {
5448 Binder.restoreCallingIdentity(ident);
5449 }
5450
5451 synchronized (mGlobalLock) {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07005452 return getActivityStartController().startActivitiesInPackage(
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005453 packageUid, packageName,
5454 intents, resolvedTypes, null /* resultTo */,
5455 SafeActivityOptions.fromBundle(bOptions), userId,
Michal Karpinski201bc0c2018-07-20 15:32:00 +01005456 false /* validateIncomingUser */, null /* originatingPendingIntent */);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005457 }
5458 }
5459
5460 @Override
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07005461 public int startActivitiesInPackage(int uid, String callingPackage, Intent[] intents,
5462 String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, int userId,
5463 boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent) {
5464 synchronized (mGlobalLock) {
5465 return getActivityStartController().startActivitiesInPackage(uid, callingPackage,
5466 intents, resolvedTypes, resultTo, options, userId, validateIncomingUser,
5467 originatingPendingIntent);
5468 }
5469 }
5470
5471 @Override
5472 public int startActivityInPackage(int uid, int realCallingPid, int realCallingUid,
5473 String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
5474 String resultWho, int requestCode, int startFlags, SafeActivityOptions options,
5475 int userId, TaskRecord inTask, String reason, boolean validateIncomingUser,
5476 PendingIntentRecord originatingPendingIntent) {
5477 synchronized (mGlobalLock) {
5478 return getActivityStartController().startActivityInPackage(uid, realCallingPid,
5479 realCallingUid, callingPackage, intent, resolvedType, resultTo, resultWho,
5480 requestCode, startFlags, options, userId, inTask, reason,
5481 validateIncomingUser, originatingPendingIntent);
5482 }
5483 }
5484
5485 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005486 public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
5487 Intent intent, Bundle options, int userId) {
5488 return ActivityTaskManagerService.this.startActivityAsUser(
5489 caller, callerPacakge, intent,
5490 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
5491 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
5492 false /*validateIncomingUser*/);
5493 }
5494
5495 @Override
5496 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
5497 synchronized (mGlobalLock) {
5498
5499 // We might change the visibilities here, so prepare an empty app transition which
5500 // might be overridden later if we actually change visibilities.
5501 final boolean wasTransitionSet =
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005502 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005503 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005504 mWindowManager.prepareAppTransition(TRANSIT_NONE,
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005505 false /* alwaysKeepCurrent */);
5506 }
5507 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5508
5509 // If there was a transition set already we don't want to interfere with it as we
5510 // might be starting it too early.
5511 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005512 mWindowManager.executeAppTransition();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005513 }
5514 }
5515 if (callback != null) {
5516 callback.run();
5517 }
5518 }
5519
5520 @Override
5521 public void notifyKeyguardTrustedChanged() {
5522 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005523 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005524 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5525 }
5526 }
5527 }
5528
5529 /**
5530 * Called after virtual display Id is updated by
5531 * {@link com.android.server.vr.Vr2dDisplay} with a specific
5532 * {@param vrVr2dDisplayId}.
5533 */
5534 @Override
5535 public void setVr2dDisplayId(int vr2dDisplayId) {
5536 if (DEBUG_STACK) Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
5537 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005538 mVr2dDisplayId = vr2dDisplayId;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005539 }
5540 }
5541
5542 @Override
5543 public void setFocusedActivity(IBinder token) {
5544 synchronized (mGlobalLock) {
5545 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
5546 if (r == null) {
5547 throw new IllegalArgumentException(
5548 "setFocusedActivity: No activity record matching token=" + token);
5549 }
Louis Chang19443452018-10-09 12:10:21 +08005550 if (r.moveFocusableActivityToTop("setFocusedActivity")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08005551 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005552 }
5553 }
5554 }
5555
5556 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005557 public void registerScreenObserver(ScreenObserver observer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005558 mScreenObservers.add(observer);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005559 }
5560
5561 @Override
5562 public boolean isCallerRecents(int callingUid) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005563 return getRecentTasks().isCallerRecents(callingUid);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005564 }
5565
5566 @Override
5567 public boolean isRecentsComponentHomeActivity(int userId) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005568 return getRecentTasks().isRecentsComponentHomeActivity(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005569 }
5570
5571 @Override
5572 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
5573 ActivityTaskManagerService.this.cancelRecentsAnimation(restoreHomeStackPosition);
5574 }
5575
5576 @Override
5577 public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005578 ActivityTaskManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005579 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005580
5581 @Override
5582 public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
5583 synchronized (mGlobalLock) {
5584 mActiveVoiceInteractionServiceComponent = component;
5585 }
5586 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005587
5588 @Override
5589 public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
5590 if (!mAmInternal.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
5591 return;
5592 }
5593 synchronized (mGlobalLock) {
5594 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
5595 if (types == null) {
5596 if (uid < 0) {
5597 return;
5598 }
5599 types = new ArrayMap<>();
5600 mAllowAppSwitchUids.put(userId, types);
5601 }
5602 if (uid < 0) {
5603 types.remove(type);
5604 } else {
5605 types.put(type, uid);
5606 }
5607 }
5608 }
5609
5610 @Override
5611 public void onUserStopped(int userId) {
5612 synchronized (mGlobalLock) {
5613 getRecentTasks().unloadUserDataFromMemoryLocked(userId);
5614 mAllowAppSwitchUids.remove(userId);
5615 }
5616 }
5617
5618 @Override
5619 public boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
5620 synchronized (mGlobalLock) {
5621 return ActivityTaskManagerService.this.isGetTasksAllowed(
5622 caller, callingPid, callingUid);
5623 }
5624 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005625
5626 @Override
5627 public void onProcessAdded(WindowProcessController proc) {
5628 synchronized (mGlobalLock) {
5629 mProcessNames.put(proc.mName, proc.mUid, proc);
5630 }
5631 }
5632
5633 @Override
5634 public void onProcessRemoved(String name, int uid) {
5635 synchronized (mGlobalLock) {
5636 mProcessNames.remove(name, uid);
5637 }
5638 }
5639
5640 @Override
5641 public void onCleanUpApplicationRecord(WindowProcessController proc) {
5642 synchronized (mGlobalLock) {
5643 if (proc == mHomeProcess) {
5644 mHomeProcess = null;
5645 }
5646 if (proc == mPreviousProcess) {
5647 mPreviousProcess = null;
5648 }
5649 }
5650 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005651
5652 @Override
5653 public int getTopProcessState() {
5654 synchronized (mGlobalLock) {
5655 return mTopProcessState;
5656 }
5657 }
5658
5659 @Override
Wale Ogunwale53783742018-09-16 10:21:51 -07005660 public boolean isHeavyWeightProcess(WindowProcessController proc) {
5661 synchronized (mGlobalLock) {
5662 return proc == mHeavyWeightProcess;
5663 }
5664 }
5665
5666 @Override
5667 public void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
5668 synchronized (mGlobalLock) {
5669 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(proc);
5670 }
5671 }
5672
5673 @Override
5674 public void finishHeavyWeightApp() {
5675 synchronized (mGlobalLock) {
5676 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(
5677 mHeavyWeightProcess);
5678 }
5679 }
5680
5681 @Override
Wale Ogunwalef6733932018-06-27 05:14:34 -07005682 public boolean isSleeping() {
5683 synchronized (mGlobalLock) {
5684 return isSleepingLocked();
5685 }
5686 }
5687
5688 @Override
5689 public boolean isShuttingDown() {
5690 synchronized (mGlobalLock) {
5691 return mShuttingDown;
5692 }
5693 }
5694
5695 @Override
5696 public boolean shuttingDown(boolean booted, int timeout) {
5697 synchronized (mGlobalLock) {
5698 mShuttingDown = true;
5699 mStackSupervisor.prepareForShutdownLocked();
5700 updateEventDispatchingLocked(booted);
5701 return mStackSupervisor.shutdownLocked(timeout);
5702 }
5703 }
5704
5705 @Override
5706 public void enableScreenAfterBoot(boolean booted) {
5707 synchronized (mGlobalLock) {
5708 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5709 SystemClock.uptimeMillis());
5710 mWindowManager.enableScreenAfterBoot();
5711 updateEventDispatchingLocked(booted);
5712 }
5713 }
5714
5715 @Override
5716 public boolean showStrictModeViolationDialog() {
5717 synchronized (mGlobalLock) {
5718 return mShowDialogs && !mSleeping && !mShuttingDown;
5719 }
5720 }
5721
5722 @Override
5723 public void showSystemReadyErrorDialogsIfNeeded() {
5724 synchronized (mGlobalLock) {
5725 try {
5726 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
5727 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
5728 + " data partition or your device will be unstable.");
5729 mUiHandler.post(() -> {
5730 if (mShowDialogs) {
5731 AlertDialog d = new BaseErrorDialog(mUiContext);
5732 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5733 d.setCancelable(false);
5734 d.setTitle(mUiContext.getText(R.string.android_system_label));
5735 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
5736 d.setButton(DialogInterface.BUTTON_POSITIVE,
5737 mUiContext.getText(R.string.ok),
5738 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5739 d.show();
5740 }
5741 });
5742 }
5743 } catch (RemoteException e) {
5744 }
5745
5746 if (!Build.isBuildConsistent()) {
5747 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
5748 mUiHandler.post(() -> {
5749 if (mShowDialogs) {
5750 AlertDialog d = new BaseErrorDialog(mUiContext);
5751 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5752 d.setCancelable(false);
5753 d.setTitle(mUiContext.getText(R.string.android_system_label));
5754 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
5755 d.setButton(DialogInterface.BUTTON_POSITIVE,
5756 mUiContext.getText(R.string.ok),
5757 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5758 d.show();
5759 }
5760 });
5761 }
5762 }
5763 }
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005764
5765 @Override
5766 public long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason) {
5767 synchronized (mGlobalLock) {
5768 return ActivityTaskManagerService.this.inputDispatchingTimedOut(
5769 pid, aboveSystem, reason);
5770 }
5771 }
5772
5773 @Override
5774 public void onProcessMapped(int pid, WindowProcessController proc) {
5775 synchronized (mGlobalLock) {
5776 mPidMap.put(pid, proc);
5777 }
5778 }
5779
5780 @Override
5781 public void onProcessUnMapped(int pid) {
5782 synchronized (mGlobalLock) {
5783 mPidMap.remove(pid);
5784 }
5785 }
Wale Ogunwale008163e2018-07-23 23:11:08 -07005786
5787 @Override
5788 public void onPackageDataCleared(String name) {
5789 synchronized (mGlobalLock) {
Wale Ogunwale53783742018-09-16 10:21:51 -07005790 mCompatModePackages.handlePackageDataClearedLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07005791 mAppWarnings.onPackageDataCleared(name);
5792 }
5793 }
5794
5795 @Override
5796 public void onPackageUninstalled(String name) {
5797 synchronized (mGlobalLock) {
5798 mAppWarnings.onPackageUninstalled(name);
Wale Ogunwale53783742018-09-16 10:21:51 -07005799 mCompatModePackages.handlePackageUninstalledLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07005800 }
5801 }
Wale Ogunwale53783742018-09-16 10:21:51 -07005802
5803 @Override
5804 public void onPackageAdded(String name, boolean replacing) {
5805 synchronized (mGlobalLock) {
5806 mCompatModePackages.handlePackageAddedLocked(name, replacing);
5807 }
5808 }
5809
5810 @Override
5811 public CompatibilityInfo compatibilityInfoForPackage(ApplicationInfo ai) {
5812 synchronized (mGlobalLock) {
5813 return compatibilityInfoForPackageLocked(ai);
5814 }
5815 }
5816
Yunfan Chen75157d72018-07-27 14:47:21 +09005817 /**
5818 * Set the corresponding display information for the process global configuration. To be
5819 * called when we need to show IME on a different display.
5820 *
5821 * @param pid The process id associated with the IME window.
5822 * @param displayId The ID of the display showing the IME.
5823 */
5824 @Override
5825 public void onImeWindowSetOnDisplay(int pid, int displayId) {
5826 if (pid == MY_PID || pid < 0) {
5827 if (DEBUG_CONFIGURATION) {
5828 Slog.w(TAG,
5829 "Trying to update display configuration for system/invalid process.");
5830 }
5831 return;
5832 }
5833 mH.post(() -> {
5834 synchronized (mGlobalLock) {
5835 // Check if display is initialized in AM.
5836 if (!mStackSupervisor.isDisplayAdded(displayId)) {
5837 // Call come when display is not yet added or has already been removed.
5838 if (DEBUG_CONFIGURATION) {
5839 Slog.w(TAG, "Trying to update display configuration for non-existing "
5840 + "displayId=" + displayId);
5841 }
5842 return;
5843 }
5844 final WindowProcessController imeProcess = mPidMap.get(pid);
5845 if (imeProcess == null) {
5846 if (DEBUG_CONFIGURATION) {
5847 Slog.w(TAG, "Trying to update display configuration for invalid pid: "
5848 + pid);
5849 }
5850 return;
5851 }
5852 // Fetch the current override configuration of the display and set it to the
5853 // process global configuration.
5854 imeProcess.onConfigurationChanged(
5855 mStackSupervisor.getDisplayOverrideConfiguration(displayId));
5856 }
5857 });
5858 }
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07005859
5860 @Override
5861 public void sendActivityResult(int callingUid, IBinder activityToken, String resultWho,
5862 int requestCode, int resultCode, Intent data) {
5863 synchronized (mGlobalLock) {
5864 final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
5865 if (r != null && r.getStack() != null) {
5866 r.getStack().sendActivityResultLocked(callingUid, r, resultWho, requestCode,
5867 resultCode, data);
5868 }
5869 }
5870 }
5871
5872 @Override
5873 public void clearPendingResultForActivity(IBinder activityToken,
5874 WeakReference<PendingIntentRecord> pir) {
5875 synchronized (mGlobalLock) {
5876 final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
5877 if (r != null && r.pendingResults != null) {
5878 r.pendingResults.remove(pir);
5879 }
5880 }
5881 }
5882
5883 @Override
5884 public IIntentSender getIntentSender(int type, String packageName,
5885 int callingUid, int userId, IBinder token, String resultWho,
5886 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5887 Bundle bOptions) {
5888 synchronized (mGlobalLock) {
5889 return getIntentSenderLocked(type, packageName, callingUid, userId, token,
5890 resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
5891 }
5892 }
Wale Ogunwalec4e63a42018-10-02 13:19:54 -07005893
5894 @Override
5895 public ActivityServiceConnectionsHolder getServiceConnectionsHolder(IBinder token) {
5896 synchronized (mGlobalLock) {
5897 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
5898 if (r == null) {
5899 return null;
5900 }
5901 if (r.mServiceConnectionsHolder == null) {
5902 r.mServiceConnectionsHolder = new ActivityServiceConnectionsHolder(
5903 ActivityTaskManagerService.this, r);
5904 }
5905
5906 return r.mServiceConnectionsHolder;
5907 }
5908 }
Wale Ogunwale214f3482018-10-04 11:00:47 -07005909
5910 @Override
5911 public Intent getHomeIntent() {
5912 synchronized (mGlobalLock) {
5913 return ActivityTaskManagerService.this.getHomeIntent();
5914 }
5915 }
5916
5917 @Override
5918 public boolean startHomeActivity(int userId, String reason) {
5919 synchronized (mGlobalLock) {
5920 return startHomeActivityLocked(userId, reason, DEFAULT_DISPLAY);
5921 }
5922 }
5923
5924 @Override
5925 public boolean isFactoryTestProcess(WindowProcessController wpc) {
5926 synchronized (mGlobalLock) {
5927 if (mFactoryTest == FACTORY_TEST_OFF) {
5928 return false;
5929 }
5930 if (mFactoryTest == FACTORY_TEST_LOW_LEVEL && mTopComponent != null
5931 && wpc.mName.equals(mTopComponent.getPackageName())) {
5932 return true;
5933 }
5934 return mFactoryTest == FACTORY_TEST_HIGH_LEVEL
5935 && (wpc.mInfo.flags & FLAG_FACTORY_TEST) != 0;
5936 }
5937 }
5938
5939 @Override
5940 public void updateTopComponentForFactoryTest() {
5941 synchronized (mGlobalLock) {
5942 if (mFactoryTest != FACTORY_TEST_LOW_LEVEL) {
5943 return;
5944 }
5945 final ResolveInfo ri = mContext.getPackageManager()
5946 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), STOCK_PM_FLAGS);
5947 final CharSequence errorMsg;
5948 if (ri != null) {
5949 final ActivityInfo ai = ri.activityInfo;
5950 final ApplicationInfo app = ai.applicationInfo;
5951 if ((app.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
5952 mTopAction = Intent.ACTION_FACTORY_TEST;
5953 mTopData = null;
5954 mTopComponent = new ComponentName(app.packageName, ai.name);
5955 errorMsg = null;
5956 } else {
5957 errorMsg = mContext.getResources().getText(
5958 com.android.internal.R.string.factorytest_not_system);
5959 }
5960 } else {
5961 errorMsg = mContext.getResources().getText(
5962 com.android.internal.R.string.factorytest_no_action);
5963 }
5964 if (errorMsg == null) {
5965 return;
5966 }
5967
5968 mTopAction = null;
5969 mTopData = null;
5970 mTopComponent = null;
5971 mUiHandler.post(() -> {
5972 Dialog d = new FactoryErrorDialog(mUiContext, errorMsg);
5973 d.show();
5974 mAm.ensureBootCompleted();
5975 });
5976 }
5977 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005978 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07005979}