blob: 6398680b7122aa6ab406036c2ee1207b4a7e9640 [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 Ogunwale342fbe92018-10-09 08:44:10 -070043import static android.content.pm.ConfigurationInfo.GL_ES_VERSION_UNDEFINED;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070044import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
45import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
Evan Rosky4505b352018-09-06 11:20:40 -070046import static android.content.pm.PackageManager.FEATURE_PC;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070047import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070048import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070049import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
50import static android.os.Build.VERSION_CODES.N;
Wale Ogunwale214f3482018-10-04 11:00:47 -070051import static android.os.FactoryTest.FACTORY_TEST_HIGH_LEVEL;
52import static android.os.FactoryTest.FACTORY_TEST_LOW_LEVEL;
53import static android.os.FactoryTest.FACTORY_TEST_OFF;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070054import static android.os.Process.SYSTEM_UID;
Evan Rosky4505b352018-09-06 11:20:40 -070055import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070056import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
57import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
58import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
59import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
Evan Rosky4505b352018-09-06 11:20:40 -070060import static android.provider.Settings.Global.HIDE_ERROR_DIALOGS;
61import static android.provider.Settings.System.FONT_SCALE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070062import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
63import static android.view.Display.DEFAULT_DISPLAY;
64import static android.view.Display.INVALID_DISPLAY;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070065import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
Wale Ogunwale6767eae2018-05-03 15:52:51 -070066import static android.view.WindowManager.TRANSIT_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070067import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070068import static android.view.WindowManager.TRANSIT_TASK_OPEN;
69import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
Evan Rosky4505b352018-09-06 11:20:40 -070070
Wale Ogunwale98875612018-10-12 07:53:02 -070071import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_ALL;
72import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
73import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_FOCUS;
74import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_IMMERSIVE;
75import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_LOCKTASK;
76import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_STACK;
77import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
78import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
79import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_VISIBILITY;
80import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
81import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS;
82import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_IMMERSIVE;
83import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_LOCKTASK;
84import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_STACK;
85import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH;
86import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_VISIBILITY;
87import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_ATM;
88import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070089import static com.android.server.am.ActivityManagerService.MY_PID;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070090import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS;
Evan Rosky4505b352018-09-06 11:20:40 -070091import static com.android.server.am.ActivityManagerService.dumpStackTraces;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070092import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070093import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070094import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
95import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
96import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
97import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
98import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
Evan Rosky4505b352018-09-06 11:20:40 -070099import static com.android.server.am.ActivityTaskManagerService.H.REPORT_TIME_TRACKER_MSG;
100import static com.android.server.am.ActivityTaskManagerService.UiHandler.DISMISS_DIALOG_UI_MSG;
Wale Ogunwale98875612018-10-12 07:53:02 -0700101import static android.app.ActivityTaskManager.INVALID_TASK_ID;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700102import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700103import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700104import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
Evan Rosky4505b352018-09-06 11:20:40 -0700105import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT;
106import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_DATA;
107import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
108import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700109import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
110import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700111
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700112import android.Manifest;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700113import android.annotation.NonNull;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700114import android.annotation.Nullable;
115import android.annotation.UserIdInt;
116import android.app.Activity;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700117import android.app.ActivityManager;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700118import android.app.ActivityManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700119import android.app.ActivityOptions;
120import android.app.ActivityTaskManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700121import android.app.ActivityThread;
122import android.app.AlertDialog;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700123import android.app.AppGlobals;
Evan Rosky4505b352018-09-06 11:20:40 -0700124import android.app.Dialog;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700125import android.app.IActivityController;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700126import android.app.IActivityTaskManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700127import android.app.IApplicationThread;
128import android.app.IAssistDataReceiver;
Wale Ogunwale53783742018-09-16 10:21:51 -0700129import android.app.INotificationManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700130import android.app.ITaskStackListener;
Wale Ogunwale53783742018-09-16 10:21:51 -0700131import android.app.Notification;
132import android.app.NotificationManager;
133import android.app.PendingIntent;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700134import android.app.PictureInPictureParams;
135import android.app.ProfilerInfo;
136import android.app.RemoteAction;
137import android.app.WaitResult;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700138import android.app.WindowConfiguration;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700139import android.app.admin.DevicePolicyCache;
140import android.app.assist.AssistContent;
141import android.app.assist.AssistStructure;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700142import android.app.usage.UsageStatsManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700143import android.content.ActivityNotFoundException;
144import android.content.ComponentName;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700145import android.content.ContentResolver;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700146import android.content.Context;
Evan Rosky4505b352018-09-06 11:20:40 -0700147import android.content.DialogInterface;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700148import android.content.IIntentSender;
149import android.content.Intent;
150import android.content.pm.ActivityInfo;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700151import android.content.pm.ApplicationInfo;
Yunfan Chen75157d72018-07-27 14:47:21 +0900152import android.content.pm.ConfigurationInfo;
Evan Rosky4505b352018-09-06 11:20:40 -0700153import android.content.pm.IPackageManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700154import android.content.pm.PackageManager;
Evan Rosky4505b352018-09-06 11:20:40 -0700155import android.content.pm.PackageManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700156import android.content.pm.ParceledListSlice;
157import android.content.pm.ResolveInfo;
Wale Ogunwale53783742018-09-16 10:21:51 -0700158import android.content.res.CompatibilityInfo;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700159import android.content.res.Configuration;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700160import android.content.res.Resources;
Evan Rosky4505b352018-09-06 11:20:40 -0700161import android.database.ContentObserver;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700162import android.graphics.Bitmap;
163import android.graphics.Point;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700164import android.graphics.Rect;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700165import android.metrics.LogMaker;
166import android.net.Uri;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700167import android.os.Binder;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700168import android.os.Build;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700169import android.os.Bundle;
Wale Ogunwale214f3482018-10-04 11:00:47 -0700170import android.os.FactoryTest;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700171import android.os.FileUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700172import android.os.Handler;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700173import android.os.IBinder;
Evan Rosky4505b352018-09-06 11:20:40 -0700174import android.os.IUserManager;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700175import android.os.LocaleList;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700176import android.os.Looper;
177import android.os.Message;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700178import android.os.PersistableBundle;
Evan Rosky4505b352018-09-06 11:20:40 -0700179import android.os.PowerManager;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700180import android.os.PowerManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700181import android.os.RemoteException;
Evan Rosky4505b352018-09-06 11:20:40 -0700182import android.os.ServiceManager;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700183import android.os.StrictMode;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700184import android.os.SystemClock;
185import android.os.SystemProperties;
Evan Rosky4505b352018-09-06 11:20:40 -0700186import android.os.Trace;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700187import android.os.UpdateLock;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700188import android.os.UserHandle;
Evan Rosky4505b352018-09-06 11:20:40 -0700189import android.os.UserManager;
190import android.os.WorkSource;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700191import android.os.storage.IStorageManager;
192import android.os.storage.StorageManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700193import android.provider.Settings;
194import android.service.voice.IVoiceInteractionSession;
195import android.service.voice.VoiceInteractionManagerInternal;
196import android.telecom.TelecomManager;
197import android.text.TextUtils;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700198import android.text.format.Time;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700199import android.util.ArrayMap;
200import android.util.EventLog;
201import android.util.Log;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700202import android.util.Slog;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700203import android.util.SparseArray;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700204import android.util.SparseIntArray;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700205import android.util.StatsLog;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700206import android.util.TimeUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700207import android.util.proto.ProtoOutputStream;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700208import android.view.IRecentsAnimationRunner;
209import android.view.RemoteAnimationAdapter;
210import android.view.RemoteAnimationDefinition;
Evan Rosky4505b352018-09-06 11:20:40 -0700211import android.view.WindowManager;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700212
Evan Rosky4505b352018-09-06 11:20:40 -0700213import com.android.internal.R;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700214import com.android.internal.annotations.VisibleForTesting;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700215import com.android.internal.app.AssistUtils;
Evan Rosky4505b352018-09-06 11:20:40 -0700216import com.android.internal.app.IAppOpsService;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700217import com.android.internal.app.IVoiceInteractor;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700218import com.android.internal.app.ProcessMap;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700219import com.android.internal.logging.MetricsLogger;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700220import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Wale Ogunwale53783742018-09-16 10:21:51 -0700221import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
222import com.android.internal.notification.SystemNotificationChannels;
Evan Rosky4505b352018-09-06 11:20:40 -0700223import com.android.internal.os.logging.MetricsLoggerWrapper;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700224import com.android.internal.policy.IKeyguardDismissCallback;
225import com.android.internal.policy.KeyguardDismissCallback;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700226import com.android.internal.util.Preconditions;
Wale Ogunwale53783742018-09-16 10:21:51 -0700227import com.android.internal.util.function.pooled.PooledLambda;
Evan Rosky4505b352018-09-06 11:20:40 -0700228import com.android.server.AppOpsService;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700229import com.android.server.AttributeCache;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700230import com.android.server.LocalServices;
231import com.android.server.SystemService;
Evan Rosky4505b352018-09-06 11:20:40 -0700232import com.android.server.SystemServiceManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700233import com.android.server.Watchdog;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700234import com.android.server.firewall.IntentFirewall;
Evan Rosky4505b352018-09-06 11:20:40 -0700235import com.android.server.pm.UserManagerService;
236import com.android.server.uri.UriGrantsManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700237import com.android.server.vr.VrManagerInternal;
Evan Rosky4505b352018-09-06 11:20:40 -0700238import com.android.server.wm.ActivityTaskManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700239import com.android.server.wm.PinnedStackWindowController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700240import com.android.server.wm.WindowManagerService;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700241
242import java.io.File;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700243import java.io.FileOutputStream;
244import java.io.IOException;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700245import java.io.PrintWriter;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700246import java.io.StringWriter;
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700247import java.lang.ref.WeakReference;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700248import java.util.ArrayList;
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700249import java.util.HashSet;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700250import java.util.List;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700251import java.util.Locale;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700252
253/**
254 * System service for managing activities and their containers (task, stacks, displays,... ).
255 *
256 * {@hide}
257 */
258public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
Wale Ogunwale98875612018-10-12 07:53:02 -0700259 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityTaskManagerService" : TAG_ATM;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700260 private static final String TAG_STACK = TAG + POSTFIX_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700261 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
262 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
263 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
264 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
265 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700266 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700267
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700268 // How long we wait until we timeout on key dispatching.
269 private static final int KEY_DISPATCHING_TIMEOUT_MS = 5 * 1000;
270 // How long we wait until we timeout on key dispatching during instrumentation.
271 private static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS = 60 * 1000;
272
Wale Ogunwale98875612018-10-12 07:53:02 -0700273 /** Used to indicate that an app transition should be animated. */
274 static final boolean ANIMATE = true;
275
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700276 /** Hardware-reported OpenGLES version. */
277 final int GL_ES_VERSION;
278
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700279 Context mContext;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700280 /**
281 * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
282 * change at runtime. Use mContext for non-UI purposes.
283 */
284 final Context mUiContext;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700285 final ActivityThread mSystemThread;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700286 H mH;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700287 UiHandler mUiHandler;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700288 ActivityManagerService mAm;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700289 ActivityManagerInternal mAmInternal;
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700290 UriGrantsManagerInternal mUgmInternal;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700291 private PackageManagerInternal mPmInternal;
Wale Ogunwale53783742018-09-16 10:21:51 -0700292 private ActivityTaskManagerInternal mInternal;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700293 PowerManagerInternal mPowerManagerInternal;
294 private UsageStatsManagerInternal mUsageStatsInternal;
295
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700296 PendingIntentController mPendingIntentController;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700297 IntentFirewall mIntentFirewall;
298
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700299 /* Global service lock used by the package the owns this service. */
300 Object mGlobalLock;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700301 ActivityStackSupervisor mStackSupervisor;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700302 WindowManagerService mWindowManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700303 private UserManagerService mUserManager;
304 private AppOpsService mAppOpsService;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700305 /** All processes currently running that might have a window organized by name. */
306 final ProcessMap<WindowProcessController> mProcessNames = new ProcessMap<>();
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700307 /** All processes we currently have running mapped by pid */
308 final SparseArray<WindowProcessController> mPidMap = new SparseArray<>();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700309 /** This is the process holding what we currently consider to be the "home" activity. */
310 WindowProcessController mHomeProcess;
Wale Ogunwale53783742018-09-16 10:21:51 -0700311 /** The currently running heavy-weight process, if any. */
312 WindowProcessController mHeavyWeightProcess = null;
Wale Ogunwale214f3482018-10-04 11:00:47 -0700313 boolean mHasHeavyWeightFeature;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700314 /**
315 * This is the process holding the activity the user last visited that is in a different process
316 * from the one they are currently in.
317 */
318 WindowProcessController mPreviousProcess;
319 /** The time at which the previous process was last visible. */
320 long mPreviousProcessVisibleTime;
321
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700322 /** List of intents that were used to start the most recent tasks. */
323 private RecentTasks mRecentTasks;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700324 /** State of external calls telling us if the device is awake or asleep. */
325 private boolean mKeyguardShown = false;
326
327 // Wrapper around VoiceInteractionServiceManager
328 private AssistUtils mAssistUtils;
329
330 // VoiceInteraction session ID that changes for each new request except when
331 // being called for multi-window assist in a single session.
332 private int mViSessionId = 1000;
333
334 // How long to wait in getAssistContextExtras for the activity and foreground services
335 // to respond with the result.
336 private static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
337
338 // How long top wait when going through the modern assist (which doesn't need to block
339 // on getting this result before starting to launch its UI).
340 private static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
341
342 // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
343 private static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
344
345 private final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
346
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700347 // Keeps track of the active voice interaction service component, notified from
348 // VoiceInteractionManagerService
349 ComponentName mActiveVoiceInteractionServiceComponent;
350
351 private VrController mVrController;
352 KeyguardController mKeyguardController;
353 private final ClientLifecycleManager mLifecycleManager;
354 private TaskChangeNotificationController mTaskChangeNotificationController;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700355 /** The controller for all operations related to locktask. */
356 private LockTaskController mLockTaskController;
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700357 private ActivityStartController mActivityStartController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700358
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700359 boolean mSuppressResizeConfigChanges;
360
361 private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
362 new UpdateConfigurationResult();
363
364 static final class UpdateConfigurationResult {
365 // Configuration changes that were updated.
366 int changes;
367 // If the activity was relaunched to match the new configuration.
368 boolean activityRelaunched;
369
370 void reset() {
371 changes = 0;
372 activityRelaunched = false;
373 }
374 }
375
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700376 /** Current sequencing integer of the configuration, for skipping old configurations. */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700377 private int mConfigurationSeq;
378 // To cache the list of supported system locales
379 private String[] mSupportedSystemLocales = null;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700380
381 /**
382 * Temp object used when global and/or display override configuration is updated. It is also
383 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
384 * anyone...
385 */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700386 private Configuration mTempConfig = new Configuration();
387
Wale Ogunwalef6733932018-06-27 05:14:34 -0700388 /** Temporary to avoid allocations. */
389 final StringBuilder mStringBuilder = new StringBuilder(256);
390
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700391 // Amount of time after a call to stopAppSwitches() during which we will
392 // prevent further untrusted switches from happening.
393 private static final long APP_SWITCH_DELAY_TIME = 5 * 1000;
394
395 /**
396 * The time at which we will allow normal application switches again,
397 * after a call to {@link #stopAppSwitches()}.
398 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700399 private long mAppSwitchesAllowedTime;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700400 /**
401 * This is set to true after the first switch after mAppSwitchesAllowedTime
402 * is set; any switches after that will clear the time.
403 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700404 private boolean mDidAppSwitch;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700405
406 IActivityController mController = null;
407 boolean mControllerIsAMonkey = false;
408
Wale Ogunwale214f3482018-10-04 11:00:47 -0700409 final int mFactoryTest;
410
411 /** Used to control how we initialize the service. */
412 ComponentName mTopComponent;
413 String mTopAction = Intent.ACTION_MAIN;
414 String mTopData;
415
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700416 /**
417 * Used to retain an update lock when the foreground activity is in
418 * immersive mode.
419 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700420 private final UpdateLock mUpdateLock = new UpdateLock("immersive");
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700421
422 /**
423 * Packages that are being allowed to perform unrestricted app switches. Mapping is
424 * User -> Type -> uid.
425 */
426 final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
427
428 /** The dimensions of the thumbnails in the Recents UI. */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700429 private int mThumbnailWidth;
430 private int mThumbnailHeight;
431 private float mFullscreenThumbnailScale;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700432
433 /**
434 * Flag that indicates if multi-window is enabled.
435 *
436 * For any particular form of multi-window to be enabled, generic multi-window must be enabled
437 * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
438 * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
439 * At least one of the forms of multi-window must be enabled in order for this flag to be
440 * initialized to 'true'.
441 *
442 * @see #mSupportsSplitScreenMultiWindow
443 * @see #mSupportsFreeformWindowManagement
444 * @see #mSupportsPictureInPicture
445 * @see #mSupportsMultiDisplay
446 */
447 boolean mSupportsMultiWindow;
448 boolean mSupportsSplitScreenMultiWindow;
449 boolean mSupportsFreeformWindowManagement;
450 boolean mSupportsPictureInPicture;
451 boolean mSupportsMultiDisplay;
452 boolean mForceResizableActivities;
453
454 final List<ActivityTaskManagerInternal.ScreenObserver> mScreenObservers = new ArrayList<>();
455
456 // VR Vr2d Display Id.
457 int mVr2dDisplayId = INVALID_DISPLAY;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700458
Wale Ogunwalef6733932018-06-27 05:14:34 -0700459 /**
460 * Set while we are wanting to sleep, to prevent any
461 * activities from being started/resumed.
462 *
463 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
464 *
465 * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
466 * while in the sleep state until there is a pending transition out of sleep, in which case
467 * mSleeping is set to false, and remains false while awake.
468 *
469 * Whether mSleeping can quickly toggled between true/false without the device actually
470 * display changing states is undefined.
471 */
472 private boolean mSleeping = false;
473
474 /**
475 * The process state used for processes that are running the top activities.
476 * This changes between TOP and TOP_SLEEPING to following mSleeping.
477 */
478 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
479
480 // Whether we should show our dialogs (ANR, crash, etc) or just perform their default action
481 // automatically. Important for devices without direct input devices.
482 private boolean mShowDialogs = true;
483
484 /** Set if we are shutting down the system, similar to sleeping. */
485 boolean mShuttingDown = false;
486
487 /**
488 * We want to hold a wake lock while running a voice interaction session, since
489 * this may happen with the screen off and we need to keep the CPU running to
490 * be able to continue to interact with the user.
491 */
492 PowerManager.WakeLock mVoiceWakeLock;
493
494 /**
495 * Set while we are running a voice interaction. This overrides sleeping while it is active.
496 */
497 IVoiceInteractionSession mRunningVoice;
498
499 /**
500 * The last resumed activity. This is identical to the current resumed activity most
501 * of the time but could be different when we're pausing one activity before we resume
502 * another activity.
503 */
504 ActivityRecord mLastResumedActivity;
505
506 /**
507 * The activity that is currently being traced as the active resumed activity.
508 *
509 * @see #updateResumedAppTrace
510 */
511 private @Nullable ActivityRecord mTracedResumedActivity;
512
513 /** If non-null, we are tracking the time the user spends in the currently focused app. */
514 AppTimeTracker mCurAppTimeTracker;
515
Wale Ogunwale008163e2018-07-23 23:11:08 -0700516 private AppWarnings mAppWarnings;
517
Wale Ogunwale53783742018-09-16 10:21:51 -0700518 /**
519 * Packages that the user has asked to have run in screen size
520 * compatibility mode instead of filling the screen.
521 */
522 CompatModePackages mCompatModePackages;
523
Wale Ogunwalef6733932018-06-27 05:14:34 -0700524 private FontScaleSettingObserver mFontScaleSettingObserver;
525
526 private final class FontScaleSettingObserver extends ContentObserver {
527 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
528 private final Uri mHideErrorDialogsUri = Settings.Global.getUriFor(HIDE_ERROR_DIALOGS);
529
530 public FontScaleSettingObserver() {
531 super(mH);
532 final ContentResolver resolver = mContext.getContentResolver();
533 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
534 resolver.registerContentObserver(mHideErrorDialogsUri, false, this,
535 UserHandle.USER_ALL);
536 }
537
538 @Override
539 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
540 if (mFontScaleUri.equals(uri)) {
541 updateFontScaleIfNeeded(userId);
542 } else if (mHideErrorDialogsUri.equals(uri)) {
543 synchronized (mGlobalLock) {
544 updateShouldShowDialogsLocked(getGlobalConfiguration());
545 }
546 }
547 }
548 }
549
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700550 ActivityTaskManagerService(Context context) {
551 mContext = context;
Wale Ogunwale214f3482018-10-04 11:00:47 -0700552 mFactoryTest = FactoryTest.getMode();
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700553 mSystemThread = ActivityThread.currentActivityThread();
554 mUiContext = mSystemThread.getSystemUiContext();
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700555 mLifecycleManager = new ClientLifecycleManager();
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700556 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", GL_ES_VERSION_UNDEFINED);
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700557 }
558
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700559 void onSystemReady() {
Wale Ogunwale214f3482018-10-04 11:00:47 -0700560 mHasHeavyWeightFeature = mContext.getPackageManager().hasSystemFeature(
561 PackageManager.FEATURE_CANT_SAVE_STATE);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700562 mAssistUtils = new AssistUtils(mContext);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700563 mVrController.onSystemReady();
564 mRecentTasks.onSystemReadyLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700565 }
566
Wale Ogunwalef6733932018-06-27 05:14:34 -0700567 void onInitPowerManagement() {
568 mStackSupervisor.initPowerManagement();
569 final PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700570 mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
Wale Ogunwalef6733932018-06-27 05:14:34 -0700571 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
572 mVoiceWakeLock.setReferenceCounted(false);
573 }
574
575 void installSystemProviders() {
576 mFontScaleSettingObserver = new FontScaleSettingObserver();
577 }
578
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700579 void retrieveSettings(ContentResolver resolver) {
580 final boolean freeformWindowManagement =
581 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
582 || Settings.Global.getInt(
583 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
584
585 final boolean supportsMultiWindow = ActivityTaskManager.supportsMultiWindow(mContext);
586 final boolean supportsPictureInPicture = supportsMultiWindow &&
587 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
588 final boolean supportsSplitScreenMultiWindow =
589 ActivityTaskManager.supportsSplitScreenMultiWindow(mContext);
590 final boolean supportsMultiDisplay = mContext.getPackageManager()
591 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
592 final boolean alwaysFinishActivities =
593 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
594 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
595 final boolean forceResizable = Settings.Global.getInt(
596 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
Garfield Tane0846042018-07-26 13:42:04 -0700597 final boolean isPc = mContext.getPackageManager().hasSystemFeature(FEATURE_PC);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700598
599 // Transfer any global setting for forcing RTL layout, into a System Property
600 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
601
602 final Configuration configuration = new Configuration();
603 Settings.System.getConfiguration(resolver, configuration);
604 if (forceRtl) {
605 // This will take care of setting the correct layout direction flags
606 configuration.setLayoutDirection(configuration.locale);
607 }
608
609 synchronized (mGlobalLock) {
610 mForceResizableActivities = forceResizable;
611 final boolean multiWindowFormEnabled = freeformWindowManagement
612 || supportsSplitScreenMultiWindow
613 || supportsPictureInPicture
614 || supportsMultiDisplay;
615 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
616 mSupportsMultiWindow = true;
617 mSupportsFreeformWindowManagement = freeformWindowManagement;
618 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
619 mSupportsPictureInPicture = supportsPictureInPicture;
620 mSupportsMultiDisplay = supportsMultiDisplay;
621 } else {
622 mSupportsMultiWindow = false;
623 mSupportsFreeformWindowManagement = false;
624 mSupportsSplitScreenMultiWindow = false;
625 mSupportsPictureInPicture = false;
626 mSupportsMultiDisplay = false;
627 }
628 mWindowManager.setForceResizableTasks(mForceResizableActivities);
629 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
Garfield Tane0846042018-07-26 13:42:04 -0700630 mWindowManager.setSupportsFreeformWindowManagement(mSupportsFreeformWindowManagement);
631 mWindowManager.setIsPc(isPc);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700632 // This happens before any activities are started, so we can change global configuration
633 // in-place.
634 updateConfigurationLocked(configuration, null, true);
635 final Configuration globalConfig = getGlobalConfiguration();
636 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
637
638 // Load resources only after the current configuration has been set.
639 final Resources res = mContext.getResources();
640 mThumbnailWidth = res.getDimensionPixelSize(
641 com.android.internal.R.dimen.thumbnail_width);
642 mThumbnailHeight = res.getDimensionPixelSize(
643 com.android.internal.R.dimen.thumbnail_height);
644
645 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
646 mFullscreenThumbnailScale = (float) res
647 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
648 (float) globalConfig.screenWidthDp;
649 } else {
650 mFullscreenThumbnailScale = res.getFraction(
651 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
652 }
653 }
654 }
655
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700656 // TODO: Will be converted to WM lock once transition is complete.
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700657 void setActivityManagerService(ActivityManagerService am, Looper looper,
658 IntentFirewall intentFirewall, PendingIntentController intentController) {
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700659 mAm = am;
660 mGlobalLock = mAm;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700661 mH = new H(looper);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700662 mUiHandler = new UiHandler();
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700663 mIntentFirewall = intentFirewall;
Wale Ogunwale53783742018-09-16 10:21:51 -0700664 final File systemDir = SystemServiceManager.ensureSystemDir();
665 mAppWarnings = new AppWarnings(this, mUiContext, mH, mUiHandler, systemDir);
666 mCompatModePackages = new CompatModePackages(this, systemDir, mH);
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700667 mPendingIntentController = intentController;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700668
669 mTempConfig.setToDefaults();
670 mTempConfig.setLocales(LocaleList.getDefault());
671 mConfigurationSeq = mTempConfig.seq = 1;
672 mStackSupervisor = createStackSupervisor();
673 mStackSupervisor.onConfigurationChanged(mTempConfig);
674
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700675 mTaskChangeNotificationController =
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700676 new TaskChangeNotificationController(mGlobalLock, mStackSupervisor, mH);
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700677 mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mH);
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700678 mActivityStartController = new ActivityStartController(this);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700679 mRecentTasks = createRecentTasks();
680 mStackSupervisor.setRecentTasks(mRecentTasks);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700681 mVrController = new VrController(mGlobalLock);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700682 mKeyguardController = mStackSupervisor.getKeyguardController();
683 }
684
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700685 void onActivityManagerInternalAdded() {
686 mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700687 mUgmInternal = LocalServices.getService(UriGrantsManagerInternal.class);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700688 }
689
Yunfan Chen75157d72018-07-27 14:47:21 +0900690 int increaseConfigurationSeqLocked() {
691 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
692 return mConfigurationSeq;
693 }
694
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700695 protected ActivityStackSupervisor createStackSupervisor() {
696 final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mH.getLooper());
697 supervisor.initialize();
698 return supervisor;
699 }
700
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700701 void setWindowManager(WindowManagerService wm) {
702 mWindowManager = wm;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700703 mLockTaskController.setWindowManager(wm);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700704 }
705
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700706 void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
707 mUsageStatsInternal = usageStatsManager;
708 }
709
Wale Ogunwalef6733932018-06-27 05:14:34 -0700710 UserManagerService getUserManager() {
711 if (mUserManager == null) {
712 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
713 mUserManager = (UserManagerService) IUserManager.Stub.asInterface(b);
714 }
715 return mUserManager;
716 }
717
718 AppOpsService getAppOpsService() {
719 if (mAppOpsService == null) {
720 IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
721 mAppOpsService = (AppOpsService) IAppOpsService.Stub.asInterface(b);
722 }
723 return mAppOpsService;
724 }
725
726 boolean hasUserRestriction(String restriction, int userId) {
727 return getUserManager().hasUserRestriction(restriction, userId);
728 }
729
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700730 protected RecentTasks createRecentTasks() {
731 return new RecentTasks(this, mStackSupervisor);
732 }
733
734 RecentTasks getRecentTasks() {
735 return mRecentTasks;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700736 }
737
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700738 ClientLifecycleManager getLifecycleManager() {
739 return mLifecycleManager;
740 }
741
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700742 ActivityStartController getActivityStartController() {
743 return mActivityStartController;
744 }
745
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700746 TaskChangeNotificationController getTaskChangeNotificationController() {
747 return mTaskChangeNotificationController;
748 }
749
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700750 LockTaskController getLockTaskController() {
751 return mLockTaskController;
752 }
753
Yunfan Chen75157d72018-07-27 14:47:21 +0900754 /**
755 * Return the global configuration used by the process corresponding to the input pid. This is
756 * usually the global configuration with some overrides specific to that process.
757 */
758 Configuration getGlobalConfigurationForCallingPid() {
759 final int pid = Binder.getCallingPid();
760 if (pid == MY_PID || pid < 0) {
761 return getGlobalConfiguration();
762 }
763 synchronized (mGlobalLock) {
764 final WindowProcessController app = mPidMap.get(pid);
765 return app != null ? app.getConfiguration() : getGlobalConfiguration();
766 }
767 }
768
769 /**
770 * Return the device configuration info used by the process corresponding to the input pid.
771 * The value is consistent with the global configuration for the process.
772 */
773 @Override
774 public ConfigurationInfo getDeviceConfigurationInfo() {
775 ConfigurationInfo config = new ConfigurationInfo();
776 synchronized (mGlobalLock) {
777 final Configuration globalConfig = getGlobalConfigurationForCallingPid();
778 config.reqTouchScreen = globalConfig.touchscreen;
779 config.reqKeyboardType = globalConfig.keyboard;
780 config.reqNavigation = globalConfig.navigation;
781 if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
782 || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
783 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
784 }
785 if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
786 && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
787 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
788 }
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700789 config.reqGlEsVersion = GL_ES_VERSION;
Yunfan Chen75157d72018-07-27 14:47:21 +0900790 }
791 return config;
792 }
793
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700794 private void start() {
Wale Ogunwale53783742018-09-16 10:21:51 -0700795 mInternal = new LocalService();
796 LocalServices.addService(ActivityTaskManagerInternal.class, mInternal);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700797 }
798
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700799 public static final class Lifecycle extends SystemService {
800 private final ActivityTaskManagerService mService;
801
802 public Lifecycle(Context context) {
803 super(context);
804 mService = new ActivityTaskManagerService(context);
805 }
806
807 @Override
808 public void onStart() {
809 publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700810 mService.start();
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700811 }
812
813 public ActivityTaskManagerService getService() {
814 return mService;
815 }
816 }
817
818 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700819 public final int startActivity(IApplicationThread caller, String callingPackage,
820 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
821 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
822 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
823 resultWho, requestCode, startFlags, profilerInfo, bOptions,
824 UserHandle.getCallingUserId());
825 }
826
827 @Override
828 public final int startActivities(IApplicationThread caller, String callingPackage,
829 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
830 int userId) {
831 final String reason = "startActivities";
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700832 enforceNotIsolatedCaller(reason);
833 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, reason);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700834 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700835 return getActivityStartController().startActivities(caller, -1, callingPackage, intents,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100836 resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId, reason,
837 null /* originatingPendingIntent */);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700838 }
839
840 @Override
841 public int startActivityAsUser(IApplicationThread caller, String callingPackage,
842 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
843 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
844 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
845 resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
846 true /*validateIncomingUser*/);
847 }
848
849 int startActivityAsUser(IApplicationThread caller, String callingPackage,
850 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
851 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
852 boolean validateIncomingUser) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700853 enforceNotIsolatedCaller("startActivityAsUser");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700854
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700855 userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700856 Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
857
858 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700859 return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700860 .setCaller(caller)
861 .setCallingPackage(callingPackage)
862 .setResolvedType(resolvedType)
863 .setResultTo(resultTo)
864 .setResultWho(resultWho)
865 .setRequestCode(requestCode)
866 .setStartFlags(startFlags)
867 .setProfilerInfo(profilerInfo)
868 .setActivityOptions(bOptions)
869 .setMayWait(userId)
870 .execute();
871
872 }
873
874 @Override
875 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
876 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700877 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions) {
878 enforceNotIsolatedCaller("startActivityIntentSender");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700879 // Refuse possible leaked file descriptors
880 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
881 throw new IllegalArgumentException("File descriptors passed in Intent");
882 }
883
884 if (!(target instanceof PendingIntentRecord)) {
885 throw new IllegalArgumentException("Bad PendingIntent object");
886 }
887
888 PendingIntentRecord pir = (PendingIntentRecord)target;
889
890 synchronized (mGlobalLock) {
891 // If this is coming from the currently resumed activity, it is
892 // effectively saying that app switches are allowed at this point.
Andrii Kulian5f750bc2018-07-17 08:57:23 -0700893 final ActivityStack stack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700894 if (stack.mResumedActivity != null &&
895 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700896 mAppSwitchesAllowedTime = 0;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700897 }
898 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700899 return pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700900 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700901 }
902
903 @Override
904 public boolean startNextMatchingActivity(IBinder callingActivity, Intent intent,
905 Bundle bOptions) {
906 // Refuse possible leaked file descriptors
907 if (intent != null && intent.hasFileDescriptors()) {
908 throw new IllegalArgumentException("File descriptors passed in Intent");
909 }
910 SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
911
912 synchronized (mGlobalLock) {
913 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
914 if (r == null) {
915 SafeActivityOptions.abort(options);
916 return false;
917 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700918 if (!r.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700919 // The caller is not running... d'oh!
920 SafeActivityOptions.abort(options);
921 return false;
922 }
923 intent = new Intent(intent);
924 // The caller is not allowed to change the data.
925 intent.setDataAndType(r.intent.getData(), r.intent.getType());
926 // And we are resetting to find the next component...
927 intent.setComponent(null);
928
929 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
930
931 ActivityInfo aInfo = null;
932 try {
933 List<ResolveInfo> resolves =
934 AppGlobals.getPackageManager().queryIntentActivities(
935 intent, r.resolvedType,
936 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
937 UserHandle.getCallingUserId()).getList();
938
939 // Look for the original activity in the list...
940 final int N = resolves != null ? resolves.size() : 0;
941 for (int i=0; i<N; i++) {
942 ResolveInfo rInfo = resolves.get(i);
943 if (rInfo.activityInfo.packageName.equals(r.packageName)
944 && rInfo.activityInfo.name.equals(r.info.name)) {
945 // We found the current one... the next matching is
946 // after it.
947 i++;
948 if (i<N) {
949 aInfo = resolves.get(i).activityInfo;
950 }
951 if (debug) {
952 Slog.v(TAG, "Next matching activity: found current " + r.packageName
953 + "/" + r.info.name);
954 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
955 ? "null" : aInfo.packageName + "/" + aInfo.name));
956 }
957 break;
958 }
959 }
960 } catch (RemoteException e) {
961 }
962
963 if (aInfo == null) {
964 // Nobody who is next!
965 SafeActivityOptions.abort(options);
966 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
967 return false;
968 }
969
970 intent.setComponent(new ComponentName(
971 aInfo.applicationInfo.packageName, aInfo.name));
972 intent.setFlags(intent.getFlags()&~(
973 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
974 Intent.FLAG_ACTIVITY_CLEAR_TOP|
975 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
976 FLAG_ACTIVITY_NEW_TASK));
977
978 // Okay now we need to start the new activity, replacing the currently running activity.
979 // This is a little tricky because we want to start the new one as if the current one is
980 // finished, but not finish the current one first so that there is no flicker.
981 // And thus...
982 final boolean wasFinishing = r.finishing;
983 r.finishing = true;
984
985 // Propagate reply information over to the new activity.
986 final ActivityRecord resultTo = r.resultTo;
987 final String resultWho = r.resultWho;
988 final int requestCode = r.requestCode;
989 r.resultTo = null;
990 if (resultTo != null) {
991 resultTo.removeResultsLocked(r, resultWho, requestCode);
992 }
993
994 final long origId = Binder.clearCallingIdentity();
995 // TODO(b/64750076): Check if calling pid should really be -1.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700996 final int res = getActivityStartController()
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700997 .obtainStarter(intent, "startNextMatchingActivity")
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700998 .setCaller(r.app.getThread())
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700999 .setResolvedType(r.resolvedType)
1000 .setActivityInfo(aInfo)
1001 .setResultTo(resultTo != null ? resultTo.appToken : null)
1002 .setResultWho(resultWho)
1003 .setRequestCode(requestCode)
1004 .setCallingPid(-1)
1005 .setCallingUid(r.launchedFromUid)
1006 .setCallingPackage(r.launchedFromPackage)
1007 .setRealCallingPid(-1)
1008 .setRealCallingUid(r.launchedFromUid)
1009 .setActivityOptions(options)
1010 .execute();
1011 Binder.restoreCallingIdentity(origId);
1012
1013 r.finishing = wasFinishing;
1014 if (res != ActivityManager.START_SUCCESS) {
1015 return false;
1016 }
1017 return true;
1018 }
1019 }
1020
1021 @Override
1022 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
1023 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1024 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
1025 final WaitResult res = new WaitResult();
1026 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001027 enforceNotIsolatedCaller("startActivityAndWait");
1028 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
1029 userId, "startActivityAndWait");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001030 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001031 getActivityStartController().obtainStarter(intent, "startActivityAndWait")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001032 .setCaller(caller)
1033 .setCallingPackage(callingPackage)
1034 .setResolvedType(resolvedType)
1035 .setResultTo(resultTo)
1036 .setResultWho(resultWho)
1037 .setRequestCode(requestCode)
1038 .setStartFlags(startFlags)
1039 .setActivityOptions(bOptions)
1040 .setMayWait(userId)
1041 .setProfilerInfo(profilerInfo)
1042 .setWaitResult(res)
1043 .execute();
1044 }
1045 return res;
1046 }
1047
1048 @Override
1049 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
1050 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1051 int startFlags, Configuration config, Bundle bOptions, int userId) {
1052 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001053 enforceNotIsolatedCaller("startActivityWithConfig");
1054 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
1055 "startActivityWithConfig");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001056 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001057 return getActivityStartController().obtainStarter(intent, "startActivityWithConfig")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001058 .setCaller(caller)
1059 .setCallingPackage(callingPackage)
1060 .setResolvedType(resolvedType)
1061 .setResultTo(resultTo)
1062 .setResultWho(resultWho)
1063 .setRequestCode(requestCode)
1064 .setStartFlags(startFlags)
1065 .setGlobalConfiguration(config)
1066 .setActivityOptions(bOptions)
1067 .setMayWait(userId)
1068 .execute();
1069 }
1070 }
1071
1072 @Override
1073 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
1074 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1075 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
1076 int userId) {
1077
1078 // This is very dangerous -- it allows you to perform a start activity (including
1079 // permission grants) as any app that may launch one of your own activities. So
1080 // we will only allow this to be done from activities that are part of the core framework,
1081 // and then only when they are running as the system.
1082 final ActivityRecord sourceRecord;
1083 final int targetUid;
1084 final String targetPackage;
1085 final boolean isResolver;
1086 synchronized (mGlobalLock) {
1087 if (resultTo == null) {
1088 throw new SecurityException("Must be called from an activity");
1089 }
1090 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
1091 if (sourceRecord == null) {
1092 throw new SecurityException("Called with bad activity token: " + resultTo);
1093 }
1094 if (!sourceRecord.info.packageName.equals("android")) {
1095 throw new SecurityException(
1096 "Must be called from an activity that is declared in the android package");
1097 }
1098 if (sourceRecord.app == null) {
1099 throw new SecurityException("Called without a process attached to activity");
1100 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001101 if (UserHandle.getAppId(sourceRecord.app.mUid) != SYSTEM_UID) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001102 // This is still okay, as long as this activity is running under the
1103 // uid of the original calling activity.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001104 if (sourceRecord.app.mUid != sourceRecord.launchedFromUid) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001105 throw new SecurityException(
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001106 "Calling activity in uid " + sourceRecord.app.mUid
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001107 + " must be system uid or original calling uid "
1108 + sourceRecord.launchedFromUid);
1109 }
1110 }
1111 if (ignoreTargetSecurity) {
1112 if (intent.getComponent() == null) {
1113 throw new SecurityException(
1114 "Component must be specified with ignoreTargetSecurity");
1115 }
1116 if (intent.getSelector() != null) {
1117 throw new SecurityException(
1118 "Selector not allowed with ignoreTargetSecurity");
1119 }
1120 }
1121 targetUid = sourceRecord.launchedFromUid;
1122 targetPackage = sourceRecord.launchedFromPackage;
1123 isResolver = sourceRecord.isResolverOrChildActivity();
1124 }
1125
1126 if (userId == UserHandle.USER_NULL) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001127 userId = UserHandle.getUserId(sourceRecord.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001128 }
1129
1130 // TODO: Switch to user app stacks here.
1131 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001132 return getActivityStartController().obtainStarter(intent, "startActivityAsCaller")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001133 .setCallingUid(targetUid)
1134 .setCallingPackage(targetPackage)
1135 .setResolvedType(resolvedType)
1136 .setResultTo(resultTo)
1137 .setResultWho(resultWho)
1138 .setRequestCode(requestCode)
1139 .setStartFlags(startFlags)
1140 .setActivityOptions(bOptions)
1141 .setMayWait(userId)
1142 .setIgnoreTargetSecurity(ignoreTargetSecurity)
1143 .setFilterCallingUid(isResolver ? 0 /* system */ : targetUid)
1144 .execute();
1145 } catch (SecurityException e) {
1146 // XXX need to figure out how to propagate to original app.
1147 // A SecurityException here is generally actually a fault of the original
1148 // calling activity (such as a fairly granting permissions), so propagate it
1149 // back to them.
1150 /*
1151 StringBuilder msg = new StringBuilder();
1152 msg.append("While launching");
1153 msg.append(intent.toString());
1154 msg.append(": ");
1155 msg.append(e.getMessage());
1156 */
1157 throw e;
1158 }
1159 }
1160
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001161 int handleIncomingUser(int callingPid, int callingUid, int userId, String name) {
1162 return mAmInternal.handleIncomingUser(callingPid, callingUid, userId, false /* allowAll */,
1163 ALLOW_FULL_ONLY, name, null /* callerPackage */);
1164 }
1165
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001166 @Override
1167 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
1168 Intent intent, String resolvedType, IVoiceInteractionSession session,
1169 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
1170 Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001171 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001172 if (session == null || interactor == null) {
1173 throw new NullPointerException("null session or interactor");
1174 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001175 userId = handleIncomingUser(callingPid, callingUid, userId, "startVoiceActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001176 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001177 return getActivityStartController().obtainStarter(intent, "startVoiceActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001178 .setCallingUid(callingUid)
1179 .setCallingPackage(callingPackage)
1180 .setResolvedType(resolvedType)
1181 .setVoiceSession(session)
1182 .setVoiceInteractor(interactor)
1183 .setStartFlags(startFlags)
1184 .setProfilerInfo(profilerInfo)
1185 .setActivityOptions(bOptions)
1186 .setMayWait(userId)
1187 .execute();
1188 }
1189
1190 @Override
1191 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
1192 Intent intent, String resolvedType, Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001193 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
1194 userId = handleIncomingUser(callingPid, callingUid, userId, "startAssistantActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001195
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001196 return getActivityStartController().obtainStarter(intent, "startAssistantActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001197 .setCallingUid(callingUid)
1198 .setCallingPackage(callingPackage)
1199 .setResolvedType(resolvedType)
1200 .setActivityOptions(bOptions)
1201 .setMayWait(userId)
1202 .execute();
1203 }
1204
1205 @Override
1206 public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
1207 IRecentsAnimationRunner recentsAnimationRunner) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001208 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001209 final int callingPid = Binder.getCallingPid();
1210 final long origId = Binder.clearCallingIdentity();
1211 try {
1212 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07001213 final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
1214 final int recentsUid = mRecentTasks.getRecentsComponentUid();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001215
1216 // Start a new recents animation
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001217 final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
1218 getActivityStartController(), mWindowManager, callingPid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001219 anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
1220 recentsUid, assistDataReceiver);
1221 }
1222 } finally {
1223 Binder.restoreCallingIdentity(origId);
1224 }
1225 }
1226
1227 @Override
1228 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001229 enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001230 "startActivityFromRecents()");
1231
1232 final int callingPid = Binder.getCallingPid();
1233 final int callingUid = Binder.getCallingUid();
1234 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(bOptions);
1235 final long origId = Binder.clearCallingIdentity();
1236 try {
1237 synchronized (mGlobalLock) {
1238 return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
1239 safeOptions);
1240 }
1241 } finally {
1242 Binder.restoreCallingIdentity(origId);
1243 }
1244 }
1245
1246 /**
1247 * This is the internal entry point for handling Activity.finish().
1248 *
1249 * @param token The Binder token referencing the Activity we want to finish.
1250 * @param resultCode Result code, if any, from this Activity.
1251 * @param resultData Result data (Intent), if any, from this Activity.
1252 * @param finishTask Whether to finish the task associated with this Activity.
1253 *
1254 * @return Returns true if the activity successfully finished, or false if it is still running.
1255 */
1256 @Override
1257 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
1258 int finishTask) {
1259 // Refuse possible leaked file descriptors
1260 if (resultData != null && resultData.hasFileDescriptors()) {
1261 throw new IllegalArgumentException("File descriptors passed in Intent");
1262 }
1263
1264 synchronized (mGlobalLock) {
1265 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1266 if (r == null) {
1267 return true;
1268 }
1269 // Keep track of the root activity of the task before we finish it
1270 TaskRecord tr = r.getTask();
1271 ActivityRecord rootR = tr.getRootActivity();
1272 if (rootR == null) {
1273 Slog.w(TAG, "Finishing task with all activities already finished");
1274 }
1275 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
1276 // finish.
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001277 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001278 return false;
1279 }
1280
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001281 // TODO: There is a dup. of this block of code in ActivityStack.navigateUpToLocked
1282 // We should consolidate.
1283 if (mController != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001284 // Find the first activity that is not finishing.
1285 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
1286 if (next != null) {
1287 // ask watcher if this is allowed
1288 boolean resumeOK = true;
1289 try {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001290 resumeOK = mController.activityResuming(next.packageName);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001291 } catch (RemoteException e) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001292 mController = null;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001293 Watchdog.getInstance().setActivityController(null);
1294 }
1295
1296 if (!resumeOK) {
1297 Slog.i(TAG, "Not finishing activity because controller resumed");
1298 return false;
1299 }
1300 }
1301 }
1302 final long origId = Binder.clearCallingIdentity();
1303 try {
1304 boolean res;
1305 final boolean finishWithRootActivity =
1306 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
1307 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
1308 || (finishWithRootActivity && r == rootR)) {
1309 // If requested, remove the task that is associated to this activity only if it
1310 // was the root activity in the task. The result code and data is ignored
1311 // because we don't support returning them across task boundaries. Also, to
1312 // keep backwards compatibility we remove the task from recents when finishing
1313 // task with root activity.
1314 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
1315 finishWithRootActivity, "finish-activity");
1316 if (!res) {
1317 Slog.i(TAG, "Removing task failed to finish activity");
1318 }
Garfield Tan2746ab52018-07-25 12:33:01 -07001319 // Explicitly dismissing the activity so reset its relaunch flag.
1320 r.mRelaunchReason = ActivityRecord.RELAUNCH_REASON_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001321 } else {
1322 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
1323 resultData, "app-request", true);
1324 if (!res) {
1325 Slog.i(TAG, "Failed to finish by app-request");
1326 }
1327 }
1328 return res;
1329 } finally {
1330 Binder.restoreCallingIdentity(origId);
1331 }
1332 }
1333 }
1334
1335 @Override
1336 public boolean finishActivityAffinity(IBinder token) {
1337 synchronized (mGlobalLock) {
1338 final long origId = Binder.clearCallingIdentity();
1339 try {
1340 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1341 if (r == null) {
1342 return false;
1343 }
1344
1345 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
1346 // can finish.
1347 final TaskRecord task = r.getTask();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001348 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001349 return false;
1350 }
1351 return task.getStack().finishActivityAffinityLocked(r);
1352 } finally {
1353 Binder.restoreCallingIdentity(origId);
1354 }
1355 }
1356 }
1357
1358 @Override
1359 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
1360 final long origId = Binder.clearCallingIdentity();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001361 try {
1362 WindowProcessController proc = null;
1363 synchronized (mGlobalLock) {
1364 ActivityStack stack = ActivityRecord.getStackLocked(token);
1365 if (stack == null) {
1366 return;
1367 }
1368 final ActivityRecord r = mStackSupervisor.activityIdleInternalLocked(token,
1369 false /* fromTimeout */, false /* processPausingActivities */, config);
1370 if (r != null) {
1371 proc = r.app;
1372 }
1373 if (stopProfiling && proc != null) {
1374 proc.clearProfilerIfNeeded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001375 }
1376 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001377 } finally {
1378 Binder.restoreCallingIdentity(origId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001379 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001380 }
1381
1382 @Override
1383 public final void activityResumed(IBinder token) {
1384 final long origId = Binder.clearCallingIdentity();
1385 synchronized (mGlobalLock) {
1386 ActivityRecord.activityResumedLocked(token);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001387 mWindowManager.notifyAppResumedFinished(token);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001388 }
1389 Binder.restoreCallingIdentity(origId);
1390 }
1391
1392 @Override
1393 public final void activityPaused(IBinder token) {
1394 final long origId = Binder.clearCallingIdentity();
1395 synchronized (mGlobalLock) {
1396 ActivityStack stack = ActivityRecord.getStackLocked(token);
1397 if (stack != null) {
1398 stack.activityPausedLocked(token, false);
1399 }
1400 }
1401 Binder.restoreCallingIdentity(origId);
1402 }
1403
1404 @Override
1405 public final void activityStopped(IBinder token, Bundle icicle,
1406 PersistableBundle persistentState, CharSequence description) {
1407 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
1408
1409 // Refuse possible leaked file descriptors
1410 if (icicle != null && icicle.hasFileDescriptors()) {
1411 throw new IllegalArgumentException("File descriptors passed in Bundle");
1412 }
1413
1414 final long origId = Binder.clearCallingIdentity();
1415
1416 synchronized (mGlobalLock) {
1417 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1418 if (r != null) {
1419 r.activityStoppedLocked(icicle, persistentState, description);
1420 }
1421 }
1422
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001423 mAmInternal.trimApplications();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001424
1425 Binder.restoreCallingIdentity(origId);
1426 }
1427
1428 @Override
1429 public final void activityDestroyed(IBinder token) {
1430 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
1431 synchronized (mGlobalLock) {
1432 ActivityStack stack = ActivityRecord.getStackLocked(token);
1433 if (stack != null) {
1434 stack.activityDestroyedLocked(token, "activityDestroyed");
1435 }
1436 }
1437 }
1438
1439 @Override
1440 public final void activityRelaunched(IBinder token) {
1441 final long origId = Binder.clearCallingIdentity();
1442 synchronized (mGlobalLock) {
1443 mStackSupervisor.activityRelaunchedLocked(token);
1444 }
1445 Binder.restoreCallingIdentity(origId);
1446 }
1447
1448 public final void activitySlept(IBinder token) {
1449 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
1450
1451 final long origId = Binder.clearCallingIdentity();
1452
1453 synchronized (mGlobalLock) {
1454 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1455 if (r != null) {
1456 mStackSupervisor.activitySleptLocked(r);
1457 }
1458 }
1459
1460 Binder.restoreCallingIdentity(origId);
1461 }
1462
1463 @Override
1464 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
1465 synchronized (mGlobalLock) {
1466 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1467 if (r == null) {
1468 return;
1469 }
1470 final long origId = Binder.clearCallingIdentity();
1471 try {
1472 r.setRequestedOrientation(requestedOrientation);
1473 } finally {
1474 Binder.restoreCallingIdentity(origId);
1475 }
1476 }
1477 }
1478
1479 @Override
1480 public int getRequestedOrientation(IBinder token) {
1481 synchronized (mGlobalLock) {
1482 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1483 if (r == null) {
1484 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
1485 }
1486 return r.getRequestedOrientation();
1487 }
1488 }
1489
1490 @Override
1491 public void setImmersive(IBinder token, boolean immersive) {
1492 synchronized (mGlobalLock) {
1493 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1494 if (r == null) {
1495 throw new IllegalArgumentException();
1496 }
1497 r.immersive = immersive;
1498
1499 // update associated state if we're frontmost
Andrii Kulian52d255c2018-07-13 11:32:19 -07001500 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001501 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001502 applyUpdateLockStateLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001503 }
1504 }
1505 }
1506
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001507 void applyUpdateLockStateLocked(ActivityRecord r) {
1508 // Modifications to the UpdateLock state are done on our handler, outside
1509 // the activity manager's locks. The new state is determined based on the
1510 // state *now* of the relevant activity record. The object is passed to
1511 // the handler solely for logging detail, not to be consulted/modified.
1512 final boolean nextState = r != null && r.immersive;
1513 mH.post(() -> {
1514 if (mUpdateLock.isHeld() != nextState) {
1515 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1516 "Applying new update lock state '" + nextState + "' for " + r);
1517 if (nextState) {
1518 mUpdateLock.acquire();
1519 } else {
1520 mUpdateLock.release();
1521 }
1522 }
1523 });
1524 }
1525
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001526 @Override
1527 public boolean isImmersive(IBinder token) {
1528 synchronized (mGlobalLock) {
1529 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1530 if (r == null) {
1531 throw new IllegalArgumentException();
1532 }
1533 return r.immersive;
1534 }
1535 }
1536
1537 @Override
1538 public boolean isTopActivityImmersive() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001539 enforceNotIsolatedCaller("isTopActivityImmersive");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001540 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001541 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001542 return (r != null) ? r.immersive : false;
1543 }
1544 }
1545
1546 @Override
1547 public void overridePendingTransition(IBinder token, String packageName,
1548 int enterAnim, int exitAnim) {
1549 synchronized (mGlobalLock) {
1550 ActivityRecord self = ActivityRecord.isInStackLocked(token);
1551 if (self == null) {
1552 return;
1553 }
1554
1555 final long origId = Binder.clearCallingIdentity();
1556
1557 if (self.isState(
1558 ActivityStack.ActivityState.RESUMED, ActivityStack.ActivityState.PAUSING)) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001559 mWindowManager.overridePendingAppTransition(packageName,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001560 enterAnim, exitAnim, null);
1561 }
1562
1563 Binder.restoreCallingIdentity(origId);
1564 }
1565 }
1566
1567 @Override
1568 public int getFrontActivityScreenCompatMode() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001569 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001570 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001571 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001572 if (r == null) {
1573 return ActivityManager.COMPAT_MODE_UNKNOWN;
1574 }
Wale Ogunwale53783742018-09-16 10:21:51 -07001575 return mCompatModePackages.computeCompatModeLocked(r.info.applicationInfo);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001576 }
1577 }
1578
1579 @Override
1580 public void setFrontActivityScreenCompatMode(int mode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001581 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001582 "setFrontActivityScreenCompatMode");
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001583 ApplicationInfo ai;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001584 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001585 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001586 if (r == null) {
1587 Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity");
1588 return;
1589 }
1590 ai = r.info.applicationInfo;
Wale Ogunwale53783742018-09-16 10:21:51 -07001591 mCompatModePackages.setPackageScreenCompatModeLocked(ai, mode);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001592 }
1593 }
1594
1595 @Override
1596 public int getLaunchedFromUid(IBinder activityToken) {
1597 ActivityRecord srec;
1598 synchronized (mGlobalLock) {
1599 srec = ActivityRecord.forTokenLocked(activityToken);
1600 }
1601 if (srec == null) {
1602 return -1;
1603 }
1604 return srec.launchedFromUid;
1605 }
1606
1607 @Override
1608 public String getLaunchedFromPackage(IBinder activityToken) {
1609 ActivityRecord srec;
1610 synchronized (mGlobalLock) {
1611 srec = ActivityRecord.forTokenLocked(activityToken);
1612 }
1613 if (srec == null) {
1614 return null;
1615 }
1616 return srec.launchedFromPackage;
1617 }
1618
1619 @Override
1620 public boolean convertFromTranslucent(IBinder token) {
1621 final long origId = Binder.clearCallingIdentity();
1622 try {
1623 synchronized (mGlobalLock) {
1624 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1625 if (r == null) {
1626 return false;
1627 }
1628 final boolean translucentChanged = r.changeWindowTranslucency(true);
1629 if (translucentChanged) {
1630 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
1631 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001632 mWindowManager.setAppFullscreen(token, true);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001633 return translucentChanged;
1634 }
1635 } finally {
1636 Binder.restoreCallingIdentity(origId);
1637 }
1638 }
1639
1640 @Override
1641 public boolean convertToTranslucent(IBinder token, Bundle options) {
1642 SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
1643 final long origId = Binder.clearCallingIdentity();
1644 try {
1645 synchronized (mGlobalLock) {
1646 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1647 if (r == null) {
1648 return false;
1649 }
1650 final TaskRecord task = r.getTask();
1651 int index = task.mActivities.lastIndexOf(r);
1652 if (index > 0) {
1653 ActivityRecord under = task.mActivities.get(index - 1);
1654 under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
1655 }
1656 final boolean translucentChanged = r.changeWindowTranslucency(false);
1657 if (translucentChanged) {
1658 r.getStack().convertActivityToTranslucent(r);
1659 }
1660 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001661 mWindowManager.setAppFullscreen(token, false);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001662 return translucentChanged;
1663 }
1664 } finally {
1665 Binder.restoreCallingIdentity(origId);
1666 }
1667 }
1668
1669 @Override
1670 public void notifyActivityDrawn(IBinder token) {
1671 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
1672 synchronized (mGlobalLock) {
1673 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
1674 if (r != null) {
1675 r.getStack().notifyActivityDrawnLocked(r);
1676 }
1677 }
1678 }
1679
1680 @Override
1681 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
1682 synchronized (mGlobalLock) {
1683 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1684 if (r == null) {
1685 return;
1686 }
1687 r.reportFullyDrawnLocked(restoredFromBundle);
1688 }
1689 }
1690
1691 @Override
1692 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
1693 synchronized (mGlobalLock) {
1694 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
1695 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
1696 return stack.mDisplayId;
1697 }
1698 return DEFAULT_DISPLAY;
1699 }
1700 }
1701
1702 @Override
1703 public ActivityManager.StackInfo getFocusedStackInfo() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001704 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001705 long ident = Binder.clearCallingIdentity();
1706 try {
1707 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001708 ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001709 if (focusedStack != null) {
1710 return mStackSupervisor.getStackInfo(focusedStack.mStackId);
1711 }
1712 return null;
1713 }
1714 } finally {
1715 Binder.restoreCallingIdentity(ident);
1716 }
1717 }
1718
1719 @Override
1720 public void setFocusedStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001721 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001722 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
1723 final long callingId = Binder.clearCallingIdentity();
1724 try {
1725 synchronized (mGlobalLock) {
1726 final ActivityStack stack = mStackSupervisor.getStack(stackId);
1727 if (stack == null) {
1728 Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
1729 return;
1730 }
1731 final ActivityRecord r = stack.topRunningActivityLocked();
Louis Chang19443452018-10-09 12:10:21 +08001732 if (r != null && r.moveFocusableActivityToTop("setFocusedStack")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08001733 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001734 }
1735 }
1736 } finally {
1737 Binder.restoreCallingIdentity(callingId);
1738 }
1739 }
1740
1741 @Override
1742 public void setFocusedTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001743 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001744 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
1745 final long callingId = Binder.clearCallingIdentity();
1746 try {
1747 synchronized (mGlobalLock) {
1748 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1749 if (task == null) {
1750 return;
1751 }
1752 final ActivityRecord r = task.topRunningActivityLocked();
Louis Chang19443452018-10-09 12:10:21 +08001753 if (r != null && r.moveFocusableActivityToTop("setFocusedTask")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08001754 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001755 }
1756 }
1757 } finally {
1758 Binder.restoreCallingIdentity(callingId);
1759 }
1760 }
1761
1762 @Override
1763 public boolean removeTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001764 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001765 synchronized (mGlobalLock) {
1766 final long ident = Binder.clearCallingIdentity();
1767 try {
1768 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
1769 "remove-task");
1770 } finally {
1771 Binder.restoreCallingIdentity(ident);
1772 }
1773 }
1774 }
1775
1776 @Override
Winson Chunge6439102018-07-30 15:48:01 -07001777 public void removeAllVisibleRecentTasks() {
1778 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeAllVisibleRecentTasks()");
1779 synchronized (mGlobalLock) {
1780 final long ident = Binder.clearCallingIdentity();
1781 try {
1782 getRecentTasks().removeAllVisibleTasks();
1783 } finally {
1784 Binder.restoreCallingIdentity(ident);
1785 }
1786 }
1787 }
1788
1789 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001790 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
1791 synchronized (mGlobalLock) {
1792 final ActivityRecord srec = ActivityRecord.forTokenLocked(token);
1793 if (srec != null) {
1794 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
1795 }
1796 }
1797 return false;
1798 }
1799
1800 @Override
1801 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
1802 Intent resultData) {
1803
1804 synchronized (mGlobalLock) {
1805 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
1806 if (r != null) {
1807 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
1808 }
1809 return false;
1810 }
1811 }
1812
1813 /**
1814 * Attempts to move a task backwards in z-order (the order of activities within the task is
1815 * unchanged).
1816 *
1817 * There are several possible results of this call:
1818 * - if the task is locked, then we will show the lock toast
1819 * - if there is a task behind the provided task, then that task is made visible and resumed as
1820 * this task is moved to the back
1821 * - otherwise, if there are no other tasks in the stack:
1822 * - if this task is in the pinned stack, then we remove the stack completely, which will
1823 * have the effect of moving the task to the top or bottom of the fullscreen stack
1824 * (depending on whether it is visible)
1825 * - otherwise, we simply return home and hide this task
1826 *
1827 * @param token A reference to the activity we wish to move
1828 * @param nonRoot If false then this only works if the activity is the root
1829 * of a task; if true it will work for any activity in a task.
1830 * @return Returns true if the move completed, false if not.
1831 */
1832 @Override
1833 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001834 enforceNotIsolatedCaller("moveActivityTaskToBack");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001835 synchronized (mGlobalLock) {
1836 final long origId = Binder.clearCallingIdentity();
1837 try {
1838 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
1839 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1840 if (task != null) {
1841 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
1842 }
1843 } finally {
1844 Binder.restoreCallingIdentity(origId);
1845 }
1846 }
1847 return false;
1848 }
1849
1850 @Override
1851 public Rect getTaskBounds(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001852 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001853 long ident = Binder.clearCallingIdentity();
1854 Rect rect = new Rect();
1855 try {
1856 synchronized (mGlobalLock) {
1857 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
1858 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1859 if (task == null) {
1860 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
1861 return rect;
1862 }
1863 if (task.getStack() != null) {
1864 // Return the bounds from window manager since it will be adjusted for various
1865 // things like the presense of a docked stack for tasks that aren't resizeable.
1866 task.getWindowContainerBounds(rect);
1867 } else {
1868 // Task isn't in window manager yet since it isn't associated with a stack.
1869 // Return the persist value from activity manager
1870 if (!task.matchParentBounds()) {
1871 rect.set(task.getBounds());
1872 } else if (task.mLastNonFullscreenBounds != null) {
1873 rect.set(task.mLastNonFullscreenBounds);
1874 }
1875 }
1876 }
1877 } finally {
1878 Binder.restoreCallingIdentity(ident);
1879 }
1880 return rect;
1881 }
1882
1883 @Override
1884 public ActivityManager.TaskDescription getTaskDescription(int id) {
1885 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001886 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001887 MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
1888 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
1889 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1890 if (tr != null) {
1891 return tr.lastTaskDescription;
1892 }
1893 }
1894 return null;
1895 }
1896
1897 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001898 public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
1899 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
1900 setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
1901 toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
1902 return;
1903 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001904 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001905 synchronized (mGlobalLock) {
1906 final long ident = Binder.clearCallingIdentity();
1907 try {
1908 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1909 if (task == null) {
1910 Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
1911 return;
1912 }
1913
1914 if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
1915 + " to windowingMode=" + windowingMode + " toTop=" + toTop);
1916
1917 if (!task.isActivityTypeStandardOrUndefined()) {
1918 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
1919 + " non-standard task " + taskId + " to windowing mode="
1920 + windowingMode);
1921 }
1922
1923 final ActivityStack stack = task.getStack();
1924 if (toTop) {
1925 stack.moveToFront("setTaskWindowingMode", task);
1926 }
1927 stack.setWindowingMode(windowingMode);
1928 } finally {
1929 Binder.restoreCallingIdentity(ident);
1930 }
1931 }
1932 }
1933
1934 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001935 public String getCallingPackage(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001936 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001937 ActivityRecord r = getCallingRecordLocked(token);
1938 return r != null ? r.info.packageName : null;
1939 }
1940 }
1941
1942 @Override
1943 public ComponentName getCallingActivity(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001944 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001945 ActivityRecord r = getCallingRecordLocked(token);
1946 return r != null ? r.intent.getComponent() : null;
1947 }
1948 }
1949
1950 private ActivityRecord getCallingRecordLocked(IBinder token) {
1951 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1952 if (r == null) {
1953 return null;
1954 }
1955 return r.resultTo;
1956 }
1957
1958 @Override
1959 public void unhandledBack() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001960 mAmInternal.enforceCallingPermission(android.Manifest.permission.FORCE_BACK, "unhandledBack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001961
1962 synchronized (mGlobalLock) {
1963 final long origId = Binder.clearCallingIdentity();
1964 try {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001965 getTopDisplayFocusedStack().unhandledBackLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001966 } finally {
1967 Binder.restoreCallingIdentity(origId);
1968 }
1969 }
1970 }
1971
1972 /**
1973 * TODO: Add mController hook
1974 */
1975 @Override
1976 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001977 mAmInternal.enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001978
1979 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
1980 synchronized (mGlobalLock) {
1981 moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
1982 false /* fromRecents */);
1983 }
1984 }
1985
1986 void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
1987 boolean fromRecents) {
1988
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001989 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001990 Binder.getCallingUid(), -1, -1, "Task to front")) {
1991 SafeActivityOptions.abort(options);
1992 return;
1993 }
1994 final long origId = Binder.clearCallingIdentity();
1995 try {
1996 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1997 if (task == null) {
1998 Slog.d(TAG, "Could not find task for id: "+ taskId);
Winson Chungd0243682018-09-25 18:11:54 -07001999 SafeActivityOptions.abort(options);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002000 return;
2001 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002002 if (getLockTaskController().isLockTaskModeViolation(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002003 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
Winson Chungd0243682018-09-25 18:11:54 -07002004 SafeActivityOptions.abort(options);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002005 return;
2006 }
2007 ActivityOptions realOptions = options != null
2008 ? options.getOptions(mStackSupervisor)
2009 : null;
2010 mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
2011 false /* forceNonResizable */);
2012
2013 final ActivityRecord topActivity = task.getTopActivity();
2014 if (topActivity != null) {
2015
2016 // We are reshowing a task, use a starting window to hide the initial draw delay
2017 // so the transition can start earlier.
2018 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
2019 true /* taskSwitch */, fromRecents);
2020 }
2021 } finally {
2022 Binder.restoreCallingIdentity(origId);
2023 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002024 }
2025
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002026 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
2027 int callingPid, int callingUid, String name) {
2028 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
2029 return true;
2030 }
2031
2032 if (getRecentTasks().isCallerRecents(sourceUid)) {
2033 return true;
2034 }
2035
2036 int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
2037 if (perm == PackageManager.PERMISSION_GRANTED) {
2038 return true;
2039 }
2040 if (checkAllowAppSwitchUid(sourceUid)) {
2041 return true;
2042 }
2043
2044 // If the actual IPC caller is different from the logical source, then
2045 // also see if they are allowed to control app switches.
2046 if (callingUid != -1 && callingUid != sourceUid) {
2047 perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
2048 if (perm == PackageManager.PERMISSION_GRANTED) {
2049 return true;
2050 }
2051 if (checkAllowAppSwitchUid(callingUid)) {
2052 return true;
2053 }
2054 }
2055
2056 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
2057 return false;
2058 }
2059
2060 private boolean checkAllowAppSwitchUid(int uid) {
2061 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
2062 if (types != null) {
2063 for (int i = types.size() - 1; i >= 0; i--) {
2064 if (types.valueAt(i).intValue() == uid) {
2065 return true;
2066 }
2067 }
2068 }
2069 return false;
2070 }
2071
2072 @Override
2073 public void setActivityController(IActivityController controller, boolean imAMonkey) {
2074 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
2075 "setActivityController()");
2076 synchronized (mGlobalLock) {
2077 mController = controller;
2078 mControllerIsAMonkey = imAMonkey;
2079 Watchdog.getInstance().setActivityController(controller);
2080 }
2081 }
2082
2083 boolean isControllerAMonkey() {
2084 synchronized (mGlobalLock) {
2085 return mController != null && mControllerIsAMonkey;
2086 }
2087 }
2088
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002089 @Override
2090 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
2091 synchronized (mGlobalLock) {
2092 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
2093 }
2094 }
2095
2096 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002097 public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum) {
2098 return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
2099 }
2100
2101 @Override
2102 public List<ActivityManager.RunningTaskInfo> getFilteredTasks(int maxNum,
2103 @WindowConfiguration.ActivityType int ignoreActivityType,
2104 @WindowConfiguration.WindowingMode int ignoreWindowingMode) {
2105 final int callingUid = Binder.getCallingUid();
2106 ArrayList<ActivityManager.RunningTaskInfo> list = new ArrayList<>();
2107
2108 synchronized (mGlobalLock) {
2109 if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
2110
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002111 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002112 callingUid);
2113 mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
2114 ignoreWindowingMode, callingUid, allowed);
2115 }
2116
2117 return list;
2118 }
2119
2120 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002121 public final void finishSubActivity(IBinder token, String resultWho, int requestCode) {
2122 synchronized (mGlobalLock) {
2123 final long origId = Binder.clearCallingIdentity();
2124 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2125 if (r != null) {
2126 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
2127 }
2128 Binder.restoreCallingIdentity(origId);
2129 }
2130 }
2131
2132 @Override
2133 public boolean willActivityBeVisible(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002134 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002135 ActivityStack stack = ActivityRecord.getStackLocked(token);
2136 if (stack != null) {
2137 return stack.willActivityBeVisibleLocked(token);
2138 }
2139 return false;
2140 }
2141 }
2142
2143 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002144 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002145 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002146 synchronized (mGlobalLock) {
2147 final long ident = Binder.clearCallingIdentity();
2148 try {
2149 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2150 if (task == null) {
2151 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
2152 return;
2153 }
2154
2155 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
2156 + " to stackId=" + stackId + " toTop=" + toTop);
2157
2158 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2159 if (stack == null) {
2160 throw new IllegalStateException(
2161 "moveTaskToStack: No stack for stackId=" + stackId);
2162 }
2163 if (!stack.isActivityTypeStandardOrUndefined()) {
2164 throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
2165 + taskId + " to stack " + stackId);
2166 }
2167 if (stack.inSplitScreenPrimaryWindowingMode()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002168 mWindowManager.setDockedStackCreateState(
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002169 SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
2170 }
2171 task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
2172 "moveTaskToStack");
2173 } finally {
2174 Binder.restoreCallingIdentity(ident);
2175 }
2176 }
2177 }
2178
2179 @Override
2180 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
2181 boolean preserveWindows, boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002182 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002183
2184 final long ident = Binder.clearCallingIdentity();
2185 try {
2186 synchronized (mGlobalLock) {
2187 if (animate) {
2188 final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
2189 if (stack == null) {
2190 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2191 return;
2192 }
2193 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
2194 throw new IllegalArgumentException("Stack: " + stackId
2195 + " doesn't support animated resize.");
2196 }
2197 stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
2198 animationDuration, false /* fromFullscreen */);
2199 } else {
2200 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2201 if (stack == null) {
2202 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2203 return;
2204 }
2205 mStackSupervisor.resizeStackLocked(stack, destBounds,
2206 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
2207 preserveWindows, allowResizeInDockedMode, !DEFER_RESUME);
2208 }
2209 }
2210 } finally {
2211 Binder.restoreCallingIdentity(ident);
2212 }
2213 }
2214
2215 /**
2216 * Moves the specified task to the primary-split-screen stack.
2217 *
2218 * @param taskId Id of task to move.
2219 * @param createMode The mode the primary split screen stack should be created in if it doesn't
2220 * exist already. See
2221 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
2222 * and
2223 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
2224 * @param toTop If the task and stack should be moved to the top.
2225 * @param animate Whether we should play an animation for the moving the task.
2226 * @param initialBounds If the primary stack gets created, it will use these bounds for the
2227 * stack. Pass {@code null} to use default bounds.
2228 * @param showRecents If the recents activity should be shown on the other side of the task
2229 * going into split-screen mode.
2230 */
2231 @Override
2232 public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode,
2233 boolean toTop, boolean animate, Rect initialBounds, boolean showRecents) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002234 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002235 "setTaskWindowingModeSplitScreenPrimary()");
2236 synchronized (mGlobalLock) {
2237 final long ident = Binder.clearCallingIdentity();
2238 try {
2239 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2240 if (task == null) {
2241 Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
2242 return false;
2243 }
2244 if (DEBUG_STACK) Slog.d(TAG_STACK,
2245 "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
2246 + " to createMode=" + createMode + " toTop=" + toTop);
2247 if (!task.isActivityTypeStandardOrUndefined()) {
2248 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
2249 + " non-standard task " + taskId + " to split-screen windowing mode");
2250 }
2251
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002252 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002253 final int windowingMode = task.getWindowingMode();
2254 final ActivityStack stack = task.getStack();
2255 if (toTop) {
2256 stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
2257 }
2258 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
2259 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */);
2260 return windowingMode != task.getWindowingMode();
2261 } finally {
2262 Binder.restoreCallingIdentity(ident);
2263 }
2264 }
2265 }
2266
2267 /**
2268 * Removes stacks in the input windowing modes from the system if they are of activity type
2269 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
2270 */
2271 @Override
2272 public void removeStacksInWindowingModes(int[] windowingModes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002273 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002274 "removeStacksInWindowingModes()");
2275
2276 synchronized (mGlobalLock) {
2277 final long ident = Binder.clearCallingIdentity();
2278 try {
2279 mStackSupervisor.removeStacksInWindowingModes(windowingModes);
2280 } finally {
2281 Binder.restoreCallingIdentity(ident);
2282 }
2283 }
2284 }
2285
2286 @Override
2287 public void removeStacksWithActivityTypes(int[] activityTypes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002288 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002289 "removeStacksWithActivityTypes()");
2290
2291 synchronized (mGlobalLock) {
2292 final long ident = Binder.clearCallingIdentity();
2293 try {
2294 mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
2295 } finally {
2296 Binder.restoreCallingIdentity(ident);
2297 }
2298 }
2299 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002300
2301 @Override
2302 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
2303 int userId) {
2304 final int callingUid = Binder.getCallingUid();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002305 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, "getRecentTasks");
2306 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002307 callingUid);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002308 final boolean detailed = checkGetTasksPermission(
2309 android.Manifest.permission.GET_DETAILED_TASKS, Binder.getCallingPid(),
2310 UserHandle.getAppId(callingUid))
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002311 == PackageManager.PERMISSION_GRANTED;
2312
2313 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002314 return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002315 callingUid);
2316 }
2317 }
2318
2319 @Override
2320 public List<ActivityManager.StackInfo> getAllStackInfos() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002321 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002322 long ident = Binder.clearCallingIdentity();
2323 try {
2324 synchronized (mGlobalLock) {
2325 return mStackSupervisor.getAllStackInfosLocked();
2326 }
2327 } finally {
2328 Binder.restoreCallingIdentity(ident);
2329 }
2330 }
2331
2332 @Override
2333 public ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002334 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002335 long ident = Binder.clearCallingIdentity();
2336 try {
2337 synchronized (mGlobalLock) {
2338 return mStackSupervisor.getStackInfo(windowingMode, activityType);
2339 }
2340 } finally {
2341 Binder.restoreCallingIdentity(ident);
2342 }
2343 }
2344
2345 @Override
2346 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002347 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002348 final long callingUid = Binder.getCallingUid();
2349 final long origId = Binder.clearCallingIdentity();
2350 try {
2351 synchronized (mGlobalLock) {
2352 // Cancel the recents animation synchronously (do not hold the WM lock)
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002353 mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002354 ? REORDER_MOVE_TO_ORIGINAL_POSITION
2355 : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
2356 }
2357 } finally {
2358 Binder.restoreCallingIdentity(origId);
2359 }
2360 }
2361
2362 @Override
2363 public void startLockTaskModeByToken(IBinder token) {
2364 synchronized (mGlobalLock) {
2365 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2366 if (r == null) {
2367 return;
2368 }
2369 startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
2370 }
2371 }
2372
2373 @Override
2374 public void startSystemLockTaskMode(int taskId) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002375 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002376 // This makes inner call to look as if it was initiated by system.
2377 long ident = Binder.clearCallingIdentity();
2378 try {
2379 synchronized (mGlobalLock) {
2380 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2381
2382 // When starting lock task mode the stack must be in front and focused
2383 task.getStack().moveToFront("startSystemLockTaskMode");
2384 startLockTaskModeLocked(task, true /* isSystemCaller */);
2385 }
2386 } finally {
2387 Binder.restoreCallingIdentity(ident);
2388 }
2389 }
2390
2391 @Override
2392 public void stopLockTaskModeByToken(IBinder token) {
2393 synchronized (mGlobalLock) {
2394 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2395 if (r == null) {
2396 return;
2397 }
2398 stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
2399 }
2400 }
2401
2402 /**
2403 * This API should be called by SystemUI only when user perform certain action to dismiss
2404 * lock task mode. We should only dismiss pinned lock task mode in this case.
2405 */
2406 @Override
2407 public void stopSystemLockTaskMode() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002408 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002409 stopLockTaskModeInternal(null, true /* isSystemCaller */);
2410 }
2411
2412 private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
2413 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
2414 if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
2415 return;
2416 }
2417
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002418 final ActivityStack stack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002419 if (stack == null || task != stack.topTask()) {
2420 throw new IllegalArgumentException("Invalid task, not in foreground");
2421 }
2422
2423 // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
2424 // system or a specific app.
2425 // * System-initiated requests will only start the pinned mode (screen pinning)
2426 // * App-initiated requests
2427 // - will put the device in fully locked mode (LockTask), if the app is whitelisted
2428 // - will start the pinned mode, otherwise
2429 final int callingUid = Binder.getCallingUid();
2430 long ident = Binder.clearCallingIdentity();
2431 try {
2432 // When a task is locked, dismiss the pinned stack if it exists
2433 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2434
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002435 getLockTaskController().startLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002436 } finally {
2437 Binder.restoreCallingIdentity(ident);
2438 }
2439 }
2440
2441 private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
2442 final int callingUid = Binder.getCallingUid();
2443 long ident = Binder.clearCallingIdentity();
2444 try {
2445 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002446 getLockTaskController().stopLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002447 }
2448 // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
2449 // task and jumping straight into a call in the case of emergency call back.
2450 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
2451 if (tm != null) {
2452 tm.showInCallScreen(false);
2453 }
2454 } finally {
2455 Binder.restoreCallingIdentity(ident);
2456 }
2457 }
2458
2459 @Override
2460 public boolean isInLockTaskMode() {
2461 return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
2462 }
2463
2464 @Override
2465 public int getLockTaskModeState() {
2466 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002467 return getLockTaskController().getLockTaskModeState();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002468 }
2469 }
2470
2471 @Override
2472 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
2473 synchronized (mGlobalLock) {
2474 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2475 if (r != null) {
2476 r.setTaskDescription(td);
2477 final TaskRecord task = r.getTask();
2478 task.updateTaskDescription();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002479 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002480 }
2481 }
2482 }
2483
2484 @Override
2485 public Bundle getActivityOptions(IBinder token) {
2486 final long origId = Binder.clearCallingIdentity();
2487 try {
2488 synchronized (mGlobalLock) {
2489 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
2490 if (r != null) {
2491 final ActivityOptions activityOptions = r.takeOptionsLocked();
2492 return activityOptions == null ? null : activityOptions.toBundle();
2493 }
2494 return null;
2495 }
2496 } finally {
2497 Binder.restoreCallingIdentity(origId);
2498 }
2499 }
2500
2501 @Override
2502 public List<IBinder> getAppTasks(String callingPackage) {
2503 int callingUid = Binder.getCallingUid();
2504 long ident = Binder.clearCallingIdentity();
2505 try {
2506 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002507 return mRecentTasks.getAppTasksList(callingUid, callingPackage);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002508 }
2509 } finally {
2510 Binder.restoreCallingIdentity(ident);
2511 }
2512 }
2513
2514 @Override
2515 public void finishVoiceTask(IVoiceInteractionSession session) {
2516 synchronized (mGlobalLock) {
2517 final long origId = Binder.clearCallingIdentity();
2518 try {
2519 // TODO: VI Consider treating local voice interactions and voice tasks
2520 // differently here
2521 mStackSupervisor.finishVoiceTask(session);
2522 } finally {
2523 Binder.restoreCallingIdentity(origId);
2524 }
2525 }
2526
2527 }
2528
2529 @Override
2530 public boolean isTopOfTask(IBinder token) {
2531 synchronized (mGlobalLock) {
2532 ActivityRecord r = ActivityRecord.isInStackLocked(token);
Riddle Hsu66b74a82018-07-26 00:20:12 +08002533 return r != null && r.getTask().getTopActivity() == r;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002534 }
2535 }
2536
2537 @Override
2538 public void notifyLaunchTaskBehindComplete(IBinder token) {
2539 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
2540 }
2541
2542 @Override
2543 public void notifyEnterAnimationComplete(IBinder token) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002544 mH.post(() -> {
2545 synchronized (mGlobalLock) {
2546 ActivityRecord r = ActivityRecord.forTokenLocked(token);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002547 if (r != null && r.attachedToProcess()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002548 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002549 r.app.getThread().scheduleEnterAnimationComplete(r.appToken);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002550 } catch (RemoteException e) {
2551 }
2552 }
2553 }
2554
2555 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002556 }
2557
2558 /** Called from an app when assist data is ready. */
2559 @Override
2560 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
2561 AssistContent content, Uri referrer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002562 PendingAssistExtras pae = (PendingAssistExtras) token;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002563 synchronized (pae) {
2564 pae.result = extras;
2565 pae.structure = structure;
2566 pae.content = content;
2567 if (referrer != null) {
2568 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
2569 }
2570 if (structure != null) {
2571 structure.setHomeActivity(pae.isHome);
2572 }
2573 pae.haveResult = true;
2574 pae.notifyAll();
2575 if (pae.intent == null && pae.receiver == null) {
2576 // Caller is just waiting for the result.
2577 return;
2578 }
2579 }
2580 // We are now ready to launch the assist activity.
2581 IAssistDataReceiver sendReceiver = null;
2582 Bundle sendBundle = null;
2583 synchronized (mGlobalLock) {
2584 buildAssistBundleLocked(pae, extras);
2585 boolean exists = mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002586 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002587 if (!exists) {
2588 // Timed out.
2589 return;
2590 }
2591
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002592 if ((sendReceiver = pae.receiver) != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002593 // Caller wants result sent back to them.
2594 sendBundle = new Bundle();
2595 sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
2596 sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
2597 sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
2598 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
2599 }
2600 }
2601 if (sendReceiver != null) {
2602 try {
2603 sendReceiver.onHandleAssistData(sendBundle);
2604 } catch (RemoteException e) {
2605 }
2606 return;
2607 }
2608
2609 final long ident = Binder.clearCallingIdentity();
2610 try {
2611 if (TextUtils.equals(pae.intent.getAction(),
2612 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
2613 pae.intent.putExtras(pae.extras);
2614 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
2615 } else {
2616 pae.intent.replaceExtras(pae.extras);
2617 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
2618 | Intent.FLAG_ACTIVITY_SINGLE_TOP
2619 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002620 mAmInternal.closeSystemDialogs("assist");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002621
2622 try {
2623 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
2624 } catch (ActivityNotFoundException e) {
2625 Slog.w(TAG, "No activity to handle assist action.", e);
2626 }
2627 }
2628 } finally {
2629 Binder.restoreCallingIdentity(ident);
2630 }
2631 }
2632
2633 @Override
2634 public int addAppTask(IBinder activityToken, Intent intent,
2635 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
2636 final int callingUid = Binder.getCallingUid();
2637 final long callingIdent = Binder.clearCallingIdentity();
2638
2639 try {
2640 synchronized (mGlobalLock) {
2641 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
2642 if (r == null) {
2643 throw new IllegalArgumentException("Activity does not exist; token="
2644 + activityToken);
2645 }
2646 ComponentName comp = intent.getComponent();
2647 if (comp == null) {
2648 throw new IllegalArgumentException("Intent " + intent
2649 + " must specify explicit component");
2650 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002651 if (thumbnail.getWidth() != mThumbnailWidth
2652 || thumbnail.getHeight() != mThumbnailHeight) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002653 throw new IllegalArgumentException("Bad thumbnail size: got "
2654 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002655 + mThumbnailWidth + "x" + mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002656 }
2657 if (intent.getSelector() != null) {
2658 intent.setSelector(null);
2659 }
2660 if (intent.getSourceBounds() != null) {
2661 intent.setSourceBounds(null);
2662 }
2663 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
2664 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
2665 // The caller has added this as an auto-remove task... that makes no
2666 // sense, so turn off auto-remove.
2667 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
2668 }
2669 }
2670 final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
2671 STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
2672 if (ainfo.applicationInfo.uid != callingUid) {
2673 throw new SecurityException(
2674 "Can't add task for another application: target uid="
2675 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
2676 }
2677
2678 final ActivityStack stack = r.getStack();
2679 final TaskRecord task = stack.createTaskRecord(
2680 mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent,
2681 null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002682 if (!mRecentTasks.addToBottom(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002683 // The app has too many tasks already and we can't add any more
2684 stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
2685 return INVALID_TASK_ID;
2686 }
2687 task.lastTaskDescription.copyFrom(description);
2688
2689 // TODO: Send the thumbnail to WM to store it.
2690
2691 return task.taskId;
2692 }
2693 } finally {
2694 Binder.restoreCallingIdentity(callingIdent);
2695 }
2696 }
2697
2698 @Override
2699 public Point getAppTaskThumbnailSize() {
2700 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002701 return new Point(mThumbnailWidth, mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002702 }
2703 }
2704
2705 @Override
2706 public void setTaskResizeable(int taskId, int resizeableMode) {
2707 synchronized (mGlobalLock) {
2708 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
2709 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
2710 if (task == null) {
2711 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
2712 return;
2713 }
2714 task.setResizeMode(resizeableMode);
2715 }
2716 }
2717
2718 @Override
2719 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002720 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002721 long ident = Binder.clearCallingIdentity();
2722 try {
2723 synchronized (mGlobalLock) {
2724 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2725 if (task == null) {
2726 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
2727 return;
2728 }
2729 // Place the task in the right stack if it isn't there already based on
2730 // the requested bounds.
2731 // The stack transition logic is:
2732 // - a null bounds on a freeform task moves that task to fullscreen
2733 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
2734 // that task to freeform
2735 // - otherwise the task is not moved
2736 ActivityStack stack = task.getStack();
2737 if (!task.getWindowConfiguration().canResizeTask()) {
2738 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
2739 }
2740 if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
2741 stack = stack.getDisplay().getOrCreateStack(
2742 WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
2743 } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
2744 stack = stack.getDisplay().getOrCreateStack(
2745 WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
2746 }
2747
2748 // Reparent the task to the right stack if necessary
2749 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
2750 if (stack != task.getStack()) {
2751 // Defer resume until the task is resized below
2752 task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
2753 DEFER_RESUME, "resizeTask");
2754 preserveWindow = false;
2755 }
2756
2757 // After reparenting (which only resizes the task to the stack bounds), resize the
2758 // task to the actual bounds provided
2759 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
2760 }
2761 } finally {
2762 Binder.restoreCallingIdentity(ident);
2763 }
2764 }
2765
2766 @Override
2767 public boolean releaseActivityInstance(IBinder token) {
2768 synchronized (mGlobalLock) {
2769 final long origId = Binder.clearCallingIdentity();
2770 try {
2771 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2772 if (r == null) {
2773 return false;
2774 }
2775 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
2776 } finally {
2777 Binder.restoreCallingIdentity(origId);
2778 }
2779 }
2780 }
2781
2782 @Override
2783 public void releaseSomeActivities(IApplicationThread appInt) {
2784 synchronized (mGlobalLock) {
2785 final long origId = Binder.clearCallingIdentity();
2786 try {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07002787 final WindowProcessController app = getProcessController(appInt);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002788 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
2789 } finally {
2790 Binder.restoreCallingIdentity(origId);
2791 }
2792 }
2793 }
2794
2795 @Override
2796 public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
2797 int secondaryDisplayShowing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002798 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002799 != PackageManager.PERMISSION_GRANTED) {
2800 throw new SecurityException("Requires permission "
2801 + android.Manifest.permission.DEVICE_POWER);
2802 }
2803
2804 synchronized (mGlobalLock) {
2805 long ident = Binder.clearCallingIdentity();
2806 if (mKeyguardShown != keyguardShowing) {
2807 mKeyguardShown = keyguardShowing;
Wale Ogunwale342fbe92018-10-09 08:44:10 -07002808 final Message msg = PooledLambda.obtainMessage(
2809 ActivityManagerInternal::reportCurKeyguardUsageEvent, mAmInternal,
2810 keyguardShowing);
2811 mH.sendMessage(msg);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002812 }
2813 try {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002814 mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002815 secondaryDisplayShowing);
2816 } finally {
2817 Binder.restoreCallingIdentity(ident);
2818 }
2819 }
2820
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002821 mH.post(() -> {
2822 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2823 mScreenObservers.get(i).onKeyguardStateChanged(keyguardShowing);
2824 }
2825 });
2826 }
2827
2828 void onScreenAwakeChanged(boolean isAwake) {
2829 mH.post(() -> {
2830 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2831 mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2832 }
2833 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002834 }
2835
2836 @Override
2837 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002838 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
2839 userId, "getTaskDescriptionIcon");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002840
2841 final File passedIconFile = new File(filePath);
2842 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
2843 passedIconFile.getName());
2844 if (!legitIconFile.getPath().equals(filePath)
2845 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
2846 throw new IllegalArgumentException("Bad file path: " + filePath
2847 + " passed for userId " + userId);
2848 }
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002849 return mRecentTasks.getTaskDescriptionIcon(filePath);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002850 }
2851
2852 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002853 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002854 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
2855 final ActivityOptions activityOptions = safeOptions != null
2856 ? safeOptions.getOptions(mStackSupervisor)
2857 : null;
2858 if (activityOptions == null
2859 || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
2860 || activityOptions.getCustomInPlaceResId() == 0) {
2861 throw new IllegalArgumentException("Expected in-place ActivityOption " +
2862 "with valid animation");
2863 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002864 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
2865 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002866 activityOptions.getCustomInPlaceResId());
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002867 mWindowManager.executeAppTransition();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002868 }
2869
2870 @Override
2871 public void removeStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002872 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002873 synchronized (mGlobalLock) {
2874 final long ident = Binder.clearCallingIdentity();
2875 try {
2876 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2877 if (stack == null) {
2878 Slog.w(TAG, "removeStack: No stack with id=" + stackId);
2879 return;
2880 }
2881 if (!stack.isActivityTypeStandardOrUndefined()) {
2882 throw new IllegalArgumentException(
2883 "Removing non-standard stack is not allowed.");
2884 }
2885 mStackSupervisor.removeStack(stack);
2886 } finally {
2887 Binder.restoreCallingIdentity(ident);
2888 }
2889 }
2890 }
2891
2892 @Override
2893 public void moveStackToDisplay(int stackId, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002894 mAmInternal.enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002895
2896 synchronized (mGlobalLock) {
2897 final long ident = Binder.clearCallingIdentity();
2898 try {
2899 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
2900 + " to displayId=" + displayId);
2901 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
2902 } finally {
2903 Binder.restoreCallingIdentity(ident);
2904 }
2905 }
2906 }
2907
2908 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002909 public void exitFreeformMode(IBinder token) {
2910 synchronized (mGlobalLock) {
2911 long ident = Binder.clearCallingIdentity();
2912 try {
2913 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2914 if (r == null) {
2915 throw new IllegalArgumentException(
2916 "exitFreeformMode: No activity record matching token=" + token);
2917 }
2918
2919 final ActivityStack stack = r.getStack();
2920 if (stack == null || !stack.inFreeformWindowingMode()) {
2921 throw new IllegalStateException(
2922 "exitFreeformMode: You can only go fullscreen from freeform.");
2923 }
2924
2925 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
2926 } finally {
2927 Binder.restoreCallingIdentity(ident);
2928 }
2929 }
2930 }
2931
2932 /** Sets the task stack listener that gets callbacks when a task stack changes. */
2933 @Override
2934 public void registerTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002935 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002936 "registerTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002937 mTaskChangeNotificationController.registerTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002938 }
2939
2940 /** Unregister a task stack listener so that it stops receiving callbacks. */
2941 @Override
2942 public void unregisterTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002943 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002944 "unregisterTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002945 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002946 }
2947
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002948 @Override
2949 public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
2950 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
2951 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
2952 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
2953 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
2954 }
2955
2956 @Override
2957 public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
2958 IBinder activityToken, int flags) {
2959 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
2960 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
2961 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
2962 }
2963
2964 @Override
2965 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
2966 Bundle args) {
2967 return enqueueAssistContext(requestType, intent, hint, null, null, null,
2968 true /* focused */, true /* newSessionId */, userHandle, args,
2969 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
2970 }
2971
2972 @Override
2973 public Bundle getAssistContextExtras(int requestType) {
2974 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
2975 null, null, true /* focused */, true /* newSessionId */,
2976 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
2977 if (pae == null) {
2978 return null;
2979 }
2980 synchronized (pae) {
2981 while (!pae.haveResult) {
2982 try {
2983 pae.wait();
2984 } catch (InterruptedException e) {
2985 }
2986 }
2987 }
2988 synchronized (mGlobalLock) {
2989 buildAssistBundleLocked(pae, pae.result);
2990 mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002991 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002992 }
2993 return pae.extras;
2994 }
2995
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002996 /**
2997 * Binder IPC calls go through the public entry point.
2998 * This can be called with or without the global lock held.
2999 */
3000 private static int checkCallingPermission(String permission) {
3001 return checkPermission(
3002 permission, Binder.getCallingPid(), UserHandle.getAppId(Binder.getCallingUid()));
3003 }
3004
3005 /** This can be called with or without the global lock held. */
Wale Ogunwale214f3482018-10-04 11:00:47 -07003006 private void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003007 if (!getRecentTasks().isCallerRecents(Binder.getCallingUid())) {
3008 mAmInternal.enforceCallingPermission(permission, func);
3009 }
3010 }
3011
3012 @VisibleForTesting
3013 int checkGetTasksPermission(String permission, int pid, int uid) {
3014 return checkPermission(permission, pid, uid);
3015 }
3016
3017 static int checkPermission(String permission, int pid, int uid) {
3018 if (permission == null) {
3019 return PackageManager.PERMISSION_DENIED;
3020 }
3021 return checkComponentPermission(permission, pid, uid, -1, true);
3022 }
3023
Wale Ogunwale214f3482018-10-04 11:00:47 -07003024 public static int checkComponentPermission(String permission, int pid, int uid,
3025 int owningUid, boolean exported) {
3026 return ActivityManagerService.checkComponentPermission(
3027 permission, pid, uid, owningUid, exported);
3028 }
3029
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003030 boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
3031 if (getRecentTasks().isCallerRecents(callingUid)) {
3032 // Always allow the recents component to get tasks
3033 return true;
3034 }
3035
3036 boolean allowed = checkGetTasksPermission(android.Manifest.permission.REAL_GET_TASKS,
3037 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
3038 if (!allowed) {
3039 if (checkGetTasksPermission(android.Manifest.permission.GET_TASKS,
3040 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
3041 // Temporary compatibility: some existing apps on the system image may
3042 // still be requesting the old permission and not switched to the new
3043 // one; if so, we'll still allow them full access. This means we need
3044 // to see if they are holding the old permission and are a system app.
3045 try {
3046 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
3047 allowed = true;
3048 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
3049 + " is using old GET_TASKS but privileged; allowing");
3050 }
3051 } catch (RemoteException e) {
3052 }
3053 }
3054 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
3055 + " does not hold REAL_GET_TASKS; limiting output");
3056 }
3057 return allowed;
3058 }
3059
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003060 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
3061 IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
3062 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
3063 int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003064 mAmInternal.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003065 "enqueueAssistContext()");
3066
3067 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003068 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003069 if (activity == null) {
3070 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
3071 return null;
3072 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003073 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003074 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
3075 return null;
3076 }
3077 if (focused) {
3078 if (activityToken != null) {
3079 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
3080 if (activity != caller) {
3081 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
3082 + " is not current top " + activity);
3083 return null;
3084 }
3085 }
3086 } else {
3087 activity = ActivityRecord.forTokenLocked(activityToken);
3088 if (activity == null) {
3089 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
3090 + " couldn't be found");
3091 return null;
3092 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003093 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003094 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
3095 return null;
3096 }
3097 }
3098
3099 PendingAssistExtras pae;
3100 Bundle extras = new Bundle();
3101 if (args != null) {
3102 extras.putAll(args);
3103 }
3104 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003105 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003106
3107 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
3108 userHandle);
3109 pae.isHome = activity.isActivityTypeHome();
3110
3111 // Increment the sessionId if necessary
3112 if (newSessionId) {
3113 mViSessionId++;
3114 }
3115 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003116 activity.app.getThread().requestAssistContextExtras(activity.appToken, pae,
3117 requestType, mViSessionId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003118 mPendingAssistExtras.add(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003119 mUiHandler.postDelayed(pae, timeout);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003120 } catch (RemoteException e) {
3121 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
3122 return null;
3123 }
3124 return pae;
3125 }
3126 }
3127
3128 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
3129 if (result != null) {
3130 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
3131 }
3132 if (pae.hint != null) {
3133 pae.extras.putBoolean(pae.hint, true);
3134 }
3135 }
3136
3137 private void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
3138 IAssistDataReceiver receiver;
3139 synchronized (mGlobalLock) {
3140 mPendingAssistExtras.remove(pae);
3141 receiver = pae.receiver;
3142 }
3143 if (receiver != null) {
3144 // Caller wants result sent back to them.
3145 Bundle sendBundle = new Bundle();
3146 // At least return the receiver extras
3147 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
3148 try {
3149 pae.receiver.onHandleAssistData(sendBundle);
3150 } catch (RemoteException e) {
3151 }
3152 }
3153 }
3154
3155 public class PendingAssistExtras extends Binder implements Runnable {
3156 public final ActivityRecord activity;
3157 public boolean isHome;
3158 public final Bundle extras;
3159 public final Intent intent;
3160 public final String hint;
3161 public final IAssistDataReceiver receiver;
3162 public final int userHandle;
3163 public boolean haveResult = false;
3164 public Bundle result = null;
3165 public AssistStructure structure = null;
3166 public AssistContent content = null;
3167 public Bundle receiverExtras;
3168
3169 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
3170 String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
3171 int _userHandle) {
3172 activity = _activity;
3173 extras = _extras;
3174 intent = _intent;
3175 hint = _hint;
3176 receiver = _receiver;
3177 receiverExtras = _receiverExtras;
3178 userHandle = _userHandle;
3179 }
3180
3181 @Override
3182 public void run() {
3183 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
3184 synchronized (this) {
3185 haveResult = true;
3186 notifyAll();
3187 }
3188 pendingAssistExtrasTimedOut(this);
3189 }
3190 }
3191
3192 @Override
3193 public boolean isAssistDataAllowedOnCurrentActivity() {
3194 int userId;
3195 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003196 final ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003197 if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
3198 return false;
3199 }
3200
3201 final ActivityRecord activity = focusedStack.getTopActivity();
3202 if (activity == null) {
3203 return false;
3204 }
3205 userId = activity.userId;
3206 }
3207 return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
3208 }
3209
3210 @Override
3211 public boolean showAssistFromActivity(IBinder token, Bundle args) {
3212 long ident = Binder.clearCallingIdentity();
3213 try {
3214 synchronized (mGlobalLock) {
3215 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003216 ActivityRecord top = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003217 if (top != caller) {
3218 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3219 + " is not current top " + top);
3220 return false;
3221 }
3222 if (!top.nowVisible) {
3223 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3224 + " is not visible");
3225 return false;
3226 }
3227 }
3228 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
3229 token);
3230 } finally {
3231 Binder.restoreCallingIdentity(ident);
3232 }
3233 }
3234
3235 @Override
3236 public boolean isRootVoiceInteraction(IBinder token) {
3237 synchronized (mGlobalLock) {
3238 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3239 if (r == null) {
3240 return false;
3241 }
3242 return r.rootVoiceInteraction;
3243 }
3244 }
3245
Wale Ogunwalef6733932018-06-27 05:14:34 -07003246 private void onLocalVoiceInteractionStartedLocked(IBinder activity,
3247 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
3248 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
3249 if (activityToCallback == null) return;
3250 activityToCallback.setVoiceSessionLocked(voiceSession);
3251
3252 // Inform the activity
3253 try {
3254 activityToCallback.app.getThread().scheduleLocalVoiceInteractionStarted(activity,
3255 voiceInteractor);
3256 long token = Binder.clearCallingIdentity();
3257 try {
3258 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
3259 } finally {
3260 Binder.restoreCallingIdentity(token);
3261 }
3262 // TODO: VI Should we cache the activity so that it's easier to find later
3263 // rather than scan through all the stacks and activities?
3264 } catch (RemoteException re) {
3265 activityToCallback.clearVoiceSessionLocked();
3266 // TODO: VI Should this terminate the voice session?
3267 }
3268 }
3269
3270 private void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
3271 Slog.d(TAG, "<<< startRunningVoiceLocked()");
3272 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
3273 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
3274 boolean wasRunningVoice = mRunningVoice != null;
3275 mRunningVoice = session;
3276 if (!wasRunningVoice) {
3277 mVoiceWakeLock.acquire();
3278 updateSleepIfNeededLocked();
3279 }
3280 }
3281 }
3282
3283 void finishRunningVoiceLocked() {
3284 if (mRunningVoice != null) {
3285 mRunningVoice = null;
3286 mVoiceWakeLock.release();
3287 updateSleepIfNeededLocked();
3288 }
3289 }
3290
3291 @Override
3292 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3293 synchronized (mGlobalLock) {
3294 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3295 if (keepAwake) {
3296 mVoiceWakeLock.acquire();
3297 } else {
3298 mVoiceWakeLock.release();
3299 }
3300 }
3301 }
3302 }
3303
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003304 @Override
3305 public ComponentName getActivityClassForToken(IBinder token) {
3306 synchronized (mGlobalLock) {
3307 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3308 if (r == null) {
3309 return null;
3310 }
3311 return r.intent.getComponent();
3312 }
3313 }
3314
3315 @Override
3316 public String getPackageForToken(IBinder token) {
3317 synchronized (mGlobalLock) {
3318 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3319 if (r == null) {
3320 return null;
3321 }
3322 return r.packageName;
3323 }
3324 }
3325
3326 @Override
3327 public void showLockTaskEscapeMessage(IBinder token) {
3328 synchronized (mGlobalLock) {
3329 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3330 if (r == null) {
3331 return;
3332 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003333 getLockTaskController().showLockTaskToast();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003334 }
3335 }
3336
3337 @Override
3338 public void keyguardGoingAway(int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003339 enforceNotIsolatedCaller("keyguardGoingAway");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003340 final long token = Binder.clearCallingIdentity();
3341 try {
3342 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003343 mKeyguardController.keyguardGoingAway(flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003344 }
3345 } finally {
3346 Binder.restoreCallingIdentity(token);
3347 }
3348 }
3349
3350 /**
3351 * Try to place task to provided position. The final position might be different depending on
3352 * current user and stacks state. The task will be moved to target stack if it's currently in
3353 * different stack.
3354 */
3355 @Override
3356 public void positionTaskInStack(int taskId, int stackId, int position) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003357 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003358 synchronized (mGlobalLock) {
3359 long ident = Binder.clearCallingIdentity();
3360 try {
3361 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
3362 + taskId + " in stackId=" + stackId + " at position=" + position);
3363 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3364 if (task == null) {
3365 throw new IllegalArgumentException("positionTaskInStack: no task for id="
3366 + taskId);
3367 }
3368
3369 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3370
3371 if (stack == null) {
3372 throw new IllegalArgumentException("positionTaskInStack: no stack for id="
3373 + stackId);
3374 }
3375 if (!stack.isActivityTypeStandardOrUndefined()) {
3376 throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
3377 + " the position of task " + taskId + " in/to non-standard stack");
3378 }
3379
3380 // TODO: Have the callers of this API call a separate reparent method if that is
3381 // what they intended to do vs. having this method also do reparenting.
3382 if (task.getStack() == stack) {
3383 // Change position in current stack.
3384 stack.positionChildAt(task, position);
3385 } else {
3386 // Reparent to new stack.
3387 task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
3388 !DEFER_RESUME, "positionTaskInStack");
3389 }
3390 } finally {
3391 Binder.restoreCallingIdentity(ident);
3392 }
3393 }
3394 }
3395
3396 @Override
3397 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
3398 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
3399 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
3400 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
3401 synchronized (mGlobalLock) {
3402 ActivityRecord record = ActivityRecord.isInStackLocked(token);
3403 if (record == null) {
3404 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
3405 + "found for: " + token);
3406 }
3407 record.setSizeConfigurations(horizontalSizeConfiguration,
3408 verticalSizeConfigurations, smallestSizeConfigurations);
3409 }
3410 }
3411
3412 /**
3413 * Dismisses split-screen multi-window mode.
3414 * @param toTop If true the current primary split-screen stack will be placed or left on top.
3415 */
3416 @Override
3417 public void dismissSplitScreenMode(boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003418 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003419 MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
3420 final long ident = Binder.clearCallingIdentity();
3421 try {
3422 synchronized (mGlobalLock) {
3423 final ActivityStack stack =
3424 mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
3425 if (stack == null) {
3426 Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
3427 return;
3428 }
3429
3430 if (toTop) {
3431 // Caller wants the current split-screen primary stack to be the top stack after
3432 // it goes fullscreen, so move it to the front.
3433 stack.moveToFront("dismissSplitScreenMode");
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003434 } else if (mStackSupervisor.isTopDisplayFocusedStack(stack)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003435 // In this case the current split-screen primary stack shouldn't be the top
3436 // stack after it goes fullscreen, but it current has focus, so we move the
3437 // focus to the top-most split-screen secondary stack next to it.
3438 final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
3439 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
3440 if (otherStack != null) {
3441 otherStack.moveToFront("dismissSplitScreenMode_other");
3442 }
3443 }
3444
Evan Rosky10475742018-09-05 19:02:48 -07003445 stack.setWindowingMode(WINDOWING_MODE_UNDEFINED);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003446 }
3447 } finally {
3448 Binder.restoreCallingIdentity(ident);
3449 }
3450 }
3451
3452 /**
3453 * Dismisses Pip
3454 * @param animate True if the dismissal should be animated.
3455 * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
3456 * default animation duration should be used.
3457 */
3458 @Override
3459 public void dismissPip(boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003460 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003461 final long ident = Binder.clearCallingIdentity();
3462 try {
3463 synchronized (mGlobalLock) {
3464 final PinnedActivityStack stack =
3465 mStackSupervisor.getDefaultDisplay().getPinnedStack();
3466 if (stack == null) {
3467 Slog.w(TAG, "dismissPip: pinned stack not found.");
3468 return;
3469 }
3470 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
3471 throw new IllegalArgumentException("Stack: " + stack
3472 + " doesn't support animated resize.");
3473 }
3474 if (animate) {
3475 stack.animateResizePinnedStack(null /* sourceHintBounds */,
3476 null /* destBounds */, animationDuration, false /* fromFullscreen */);
3477 } else {
3478 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
3479 }
3480 }
3481 } finally {
3482 Binder.restoreCallingIdentity(ident);
3483 }
3484 }
3485
3486 @Override
3487 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003488 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003489 synchronized (mGlobalLock) {
3490 mSuppressResizeConfigChanges = suppress;
3491 }
3492 }
3493
3494 /**
3495 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
3496 * animated the stack to the fullscreen, but can also be called if we are relaunching an
3497 * activity and clearing the task at the same time.
3498 */
3499 @Override
3500 // TODO: API should just be about changing windowing modes...
3501 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003502 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003503 "moveTasksToFullscreenStack()");
3504 synchronized (mGlobalLock) {
3505 final long origId = Binder.clearCallingIdentity();
3506 try {
3507 final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
3508 if (stack != null){
3509 if (!stack.isActivityTypeStandardOrUndefined()) {
3510 throw new IllegalArgumentException(
3511 "You can't move tasks from non-standard stacks.");
3512 }
3513 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
3514 }
3515 } finally {
3516 Binder.restoreCallingIdentity(origId);
3517 }
3518 }
3519 }
3520
3521 /**
3522 * Moves the top activity in the input stackId to the pinned stack.
3523 *
3524 * @param stackId Id of stack to move the top activity to pinned stack.
3525 * @param bounds Bounds to use for pinned stack.
3526 *
3527 * @return True if the top activity of the input stack was successfully moved to the pinned
3528 * stack.
3529 */
3530 @Override
3531 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003532 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003533 "moveTopActivityToPinnedStack()");
3534 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003535 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003536 throw new IllegalStateException("moveTopActivityToPinnedStack:"
3537 + "Device doesn't support picture-in-picture mode");
3538 }
3539
3540 long ident = Binder.clearCallingIdentity();
3541 try {
3542 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
3543 } finally {
3544 Binder.restoreCallingIdentity(ident);
3545 }
3546 }
3547 }
3548
3549 @Override
3550 public boolean isInMultiWindowMode(IBinder token) {
3551 final long origId = Binder.clearCallingIdentity();
3552 try {
3553 synchronized (mGlobalLock) {
3554 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3555 if (r == null) {
3556 return false;
3557 }
3558 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
3559 return r.inMultiWindowMode();
3560 }
3561 } finally {
3562 Binder.restoreCallingIdentity(origId);
3563 }
3564 }
3565
3566 @Override
3567 public boolean isInPictureInPictureMode(IBinder token) {
3568 final long origId = Binder.clearCallingIdentity();
3569 try {
3570 synchronized (mGlobalLock) {
3571 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
3572 }
3573 } finally {
3574 Binder.restoreCallingIdentity(origId);
3575 }
3576 }
3577
3578 private boolean isInPictureInPictureMode(ActivityRecord r) {
3579 if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
3580 || r.getStack().isInStackLocked(r) == null) {
3581 return false;
3582 }
3583
3584 // If we are animating to fullscreen then we have already dispatched the PIP mode
3585 // changed, so we should reflect that check here as well.
3586 final PinnedActivityStack stack = r.getStack();
3587 final PinnedStackWindowController windowController = stack.getWindowContainerController();
3588 return !windowController.isAnimatingBoundsToFullscreen();
3589 }
3590
3591 @Override
3592 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
3593 final long origId = Binder.clearCallingIdentity();
3594 try {
3595 synchronized (mGlobalLock) {
3596 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3597 "enterPictureInPictureMode", token, params);
3598
3599 // If the activity is already in picture in picture mode, then just return early
3600 if (isInPictureInPictureMode(r)) {
3601 return true;
3602 }
3603
3604 // Activity supports picture-in-picture, now check that we can enter PiP at this
3605 // point, if it is
3606 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
3607 false /* beforeStopping */)) {
3608 return false;
3609 }
3610
3611 final Runnable enterPipRunnable = () -> {
Wale Ogunwalef276a6f2018-06-15 08:26:07 -07003612 synchronized (mGlobalLock) {
3613 // Only update the saved args from the args that are set
3614 r.pictureInPictureArgs.copyOnlySet(params);
3615 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
3616 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
3617 // Adjust the source bounds by the insets for the transition down
3618 final Rect sourceBounds = new Rect(
3619 r.pictureInPictureArgs.getSourceRectHint());
3620 mStackSupervisor.moveActivityToPinnedStackLocked(
3621 r, sourceBounds, aspectRatio, "enterPictureInPictureMode");
3622 final PinnedActivityStack stack = r.getStack();
3623 stack.setPictureInPictureAspectRatio(aspectRatio);
3624 stack.setPictureInPictureActions(actions);
3625 MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
3626 r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
3627 logPictureInPictureArgs(params);
3628 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003629 };
3630
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003631 if (isKeyguardLocked()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003632 // If the keyguard is showing or occluded, then try and dismiss it before
3633 // entering picture-in-picture (this will prompt the user to authenticate if the
3634 // device is currently locked).
3635 dismissKeyguard(token, new KeyguardDismissCallback() {
3636 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003637 public void onDismissSucceeded() {
3638 mH.post(enterPipRunnable);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003639 }
3640 }, null /* message */);
3641 } else {
3642 // Enter picture in picture immediately otherwise
3643 enterPipRunnable.run();
3644 }
3645 return true;
3646 }
3647 } finally {
3648 Binder.restoreCallingIdentity(origId);
3649 }
3650 }
3651
3652 @Override
3653 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
3654 final long origId = Binder.clearCallingIdentity();
3655 try {
3656 synchronized (mGlobalLock) {
3657 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3658 "setPictureInPictureParams", token, params);
3659
3660 // Only update the saved args from the args that are set
3661 r.pictureInPictureArgs.copyOnlySet(params);
3662 if (r.inPinnedWindowingMode()) {
3663 // If the activity is already in picture-in-picture, update the pinned stack now
3664 // if it is not already expanding to fullscreen. Otherwise, the arguments will
3665 // be used the next time the activity enters PiP
3666 final PinnedActivityStack stack = r.getStack();
3667 if (!stack.isAnimatingBoundsToFullscreen()) {
3668 stack.setPictureInPictureAspectRatio(
3669 r.pictureInPictureArgs.getAspectRatio());
3670 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
3671 }
3672 }
3673 logPictureInPictureArgs(params);
3674 }
3675 } finally {
3676 Binder.restoreCallingIdentity(origId);
3677 }
3678 }
3679
3680 @Override
3681 public int getMaxNumPictureInPictureActions(IBinder token) {
3682 // Currently, this is a static constant, but later, we may change this to be dependent on
3683 // the context of the activity
3684 return 3;
3685 }
3686
3687 private void logPictureInPictureArgs(PictureInPictureParams params) {
3688 if (params.hasSetActions()) {
3689 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
3690 params.getActions().size());
3691 }
3692 if (params.hasSetAspectRatio()) {
3693 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
3694 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
3695 MetricsLogger.action(lm);
3696 }
3697 }
3698
3699 /**
3700 * Checks the state of the system and the activity associated with the given {@param token} to
3701 * verify that picture-in-picture is supported for that activity.
3702 *
3703 * @return the activity record for the given {@param token} if all the checks pass.
3704 */
3705 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
3706 IBinder token, PictureInPictureParams params) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003707 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003708 throw new IllegalStateException(caller
3709 + ": Device doesn't support picture-in-picture mode.");
3710 }
3711
3712 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3713 if (r == null) {
3714 throw new IllegalStateException(caller
3715 + ": Can't find activity for token=" + token);
3716 }
3717
3718 if (!r.supportsPictureInPicture()) {
3719 throw new IllegalStateException(caller
3720 + ": Current activity does not support picture-in-picture.");
3721 }
3722
3723 if (params.hasSetAspectRatio()
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003724 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003725 params.getAspectRatio())) {
3726 final float minAspectRatio = mContext.getResources().getFloat(
3727 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
3728 final float maxAspectRatio = mContext.getResources().getFloat(
3729 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
3730 throw new IllegalArgumentException(String.format(caller
3731 + ": Aspect ratio is too extreme (must be between %f and %f).",
3732 minAspectRatio, maxAspectRatio));
3733 }
3734
3735 // Truncate the number of actions if necessary
3736 params.truncateActions(getMaxNumPictureInPictureActions(token));
3737
3738 return r;
3739 }
3740
3741 @Override
3742 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003743 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003744 synchronized (mGlobalLock) {
3745 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
3746 if (r == null) {
3747 throw new IllegalArgumentException("Activity does not exist; token="
3748 + activityToken);
3749 }
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07003750 return r.getUriPermissionsLocked().getExternalToken();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003751 }
3752 }
3753
3754 @Override
3755 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
3756 Rect tempDockedTaskInsetBounds,
3757 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003758 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003759 long ident = Binder.clearCallingIdentity();
3760 try {
3761 synchronized (mGlobalLock) {
3762 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
3763 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
3764 PRESERVE_WINDOWS);
3765 }
3766 } finally {
3767 Binder.restoreCallingIdentity(ident);
3768 }
3769 }
3770
3771 @Override
3772 public void setSplitScreenResizing(boolean resizing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003773 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003774 final long ident = Binder.clearCallingIdentity();
3775 try {
3776 synchronized (mGlobalLock) {
3777 mStackSupervisor.setSplitScreenResizing(resizing);
3778 }
3779 } finally {
3780 Binder.restoreCallingIdentity(ident);
3781 }
3782 }
3783
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003784 /**
3785 * Check that we have the features required for VR-related API calls, and throw an exception if
3786 * not.
3787 */
3788 void enforceSystemHasVrFeature() {
3789 if (!mContext.getPackageManager().hasSystemFeature(
3790 PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
3791 throw new UnsupportedOperationException("VR mode not supported on this device!");
3792 }
3793 }
3794
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003795 @Override
3796 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003797 enforceSystemHasVrFeature();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003798
3799 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3800
3801 ActivityRecord r;
3802 synchronized (mGlobalLock) {
3803 r = ActivityRecord.isInStackLocked(token);
3804 }
3805
3806 if (r == null) {
3807 throw new IllegalArgumentException();
3808 }
3809
3810 int err;
3811 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
3812 VrManagerInternal.NO_ERROR) {
3813 return err;
3814 }
3815
3816 // Clear the binder calling uid since this path may call moveToTask().
3817 final long callingId = Binder.clearCallingIdentity();
3818 try {
3819 synchronized (mGlobalLock) {
3820 r.requestedVrComponent = (enabled) ? packageName : null;
3821
3822 // Update associated state if this activity is currently focused
Andrii Kulian52d255c2018-07-13 11:32:19 -07003823 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003824 applyUpdateVrModeLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003825 }
3826 return 0;
3827 }
3828 } finally {
3829 Binder.restoreCallingIdentity(callingId);
3830 }
3831 }
3832
3833 @Override
3834 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
3835 Slog.i(TAG, "Activity tried to startLocalVoiceInteraction");
3836 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003837 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003838 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
3839 throw new SecurityException("Only focused activity can call startVoiceInteraction");
3840 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07003841 if (mRunningVoice != null || activity.getTask().voiceSession != null
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003842 || activity.voiceSession != null) {
3843 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
3844 return;
3845 }
3846 if (activity.pendingVoiceInteractionStart) {
3847 Slog.w(TAG, "Pending start of voice interaction already.");
3848 return;
3849 }
3850 activity.pendingVoiceInteractionStart = true;
3851 }
3852 LocalServices.getService(VoiceInteractionManagerInternal.class)
3853 .startLocalVoiceInteraction(callingActivity, options);
3854 }
3855
3856 @Override
3857 public void stopLocalVoiceInteraction(IBinder callingActivity) {
3858 LocalServices.getService(VoiceInteractionManagerInternal.class)
3859 .stopLocalVoiceInteraction(callingActivity);
3860 }
3861
3862 @Override
3863 public boolean supportsLocalVoiceInteraction() {
3864 return LocalServices.getService(VoiceInteractionManagerInternal.class)
3865 .supportsLocalVoiceInteraction();
3866 }
3867
3868 /** Notifies all listeners when the pinned stack animation starts. */
3869 @Override
3870 public void notifyPinnedStackAnimationStarted() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003871 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003872 }
3873
3874 /** Notifies all listeners when the pinned stack animation ends. */
3875 @Override
3876 public void notifyPinnedStackAnimationEnded() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003877 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003878 }
3879
3880 @Override
3881 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003882 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003883 final long ident = Binder.clearCallingIdentity();
3884 try {
3885 synchronized (mGlobalLock) {
3886 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
3887 }
3888 } finally {
3889 Binder.restoreCallingIdentity(ident);
3890 }
3891 }
3892
3893 @Override
3894 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003895 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003896
3897 synchronized (mGlobalLock) {
3898 // Check if display is initialized in AM.
3899 if (!mStackSupervisor.isDisplayAdded(displayId)) {
3900 // Call might come when display is not yet added or has already been removed.
3901 if (DEBUG_CONFIGURATION) {
3902 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
3903 + displayId);
3904 }
3905 return false;
3906 }
3907
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003908 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003909 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003910 values = mWindowManager.computeNewConfiguration(displayId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003911 }
3912
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003913 if (mWindowManager != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07003914 final Message msg = PooledLambda.obtainMessage(
3915 ActivityManagerInternal::updateOomLevelsForDisplay, mAmInternal, displayId);
3916 mH.sendMessage(msg);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003917 }
3918
3919 final long origId = Binder.clearCallingIdentity();
3920 try {
3921 if (values != null) {
3922 Settings.System.clearConfiguration(values);
3923 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003924 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003925 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
3926 return mTmpUpdateConfigurationResult.changes != 0;
3927 } finally {
3928 Binder.restoreCallingIdentity(origId);
3929 }
3930 }
3931 }
3932
3933 @Override
3934 public boolean updateConfiguration(Configuration values) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003935 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003936
3937 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003938 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003939 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003940 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003941 }
3942
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003943 if (mWindowManager != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07003944 final Message msg = PooledLambda.obtainMessage(
3945 ActivityManagerInternal::updateOomLevelsForDisplay, mAmInternal,
3946 DEFAULT_DISPLAY);
3947 mH.sendMessage(msg);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003948 }
3949
3950 final long origId = Binder.clearCallingIdentity();
3951 try {
3952 if (values != null) {
3953 Settings.System.clearConfiguration(values);
3954 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003955 updateConfigurationLocked(values, null, false, false /* persistent */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003956 UserHandle.USER_NULL, false /* deferResume */,
3957 mTmpUpdateConfigurationResult);
3958 return mTmpUpdateConfigurationResult.changes != 0;
3959 } finally {
3960 Binder.restoreCallingIdentity(origId);
3961 }
3962 }
3963 }
3964
3965 @Override
3966 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
3967 CharSequence message) {
3968 if (message != null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003969 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003970 Manifest.permission.SHOW_KEYGUARD_MESSAGE, "dismissKeyguard()");
3971 }
3972 final long callingId = Binder.clearCallingIdentity();
3973 try {
3974 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003975 mKeyguardController.dismissKeyguard(token, callback, message);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003976 }
3977 } finally {
3978 Binder.restoreCallingIdentity(callingId);
3979 }
3980 }
3981
3982 @Override
3983 public void cancelTaskWindowTransition(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003984 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003985 "cancelTaskWindowTransition()");
3986 final long ident = Binder.clearCallingIdentity();
3987 try {
3988 synchronized (mGlobalLock) {
3989 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
3990 MATCH_TASK_IN_STACKS_ONLY);
3991 if (task == null) {
3992 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
3993 return;
3994 }
3995 task.cancelWindowTransition();
3996 }
3997 } finally {
3998 Binder.restoreCallingIdentity(ident);
3999 }
4000 }
4001
4002 @Override
4003 public ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004004 enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004005 final long ident = Binder.clearCallingIdentity();
4006 try {
4007 final TaskRecord task;
4008 synchronized (mGlobalLock) {
4009 task = mStackSupervisor.anyTaskForIdLocked(taskId,
4010 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
4011 if (task == null) {
4012 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
4013 return null;
4014 }
4015 }
4016 // Don't call this while holding the lock as this operation might hit the disk.
4017 return task.getSnapshot(reducedResolution);
4018 } finally {
4019 Binder.restoreCallingIdentity(ident);
4020 }
4021 }
4022
4023 @Override
4024 public void setDisablePreviewScreenshots(IBinder token, boolean disable) {
4025 synchronized (mGlobalLock) {
4026 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4027 if (r == null) {
4028 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
4029 + token);
4030 return;
4031 }
4032 final long origId = Binder.clearCallingIdentity();
4033 try {
4034 r.setDisablePreviewScreenshots(disable);
4035 } finally {
4036 Binder.restoreCallingIdentity(origId);
4037 }
4038 }
4039 }
4040
4041 /** Return the user id of the last resumed activity. */
4042 @Override
4043 public @UserIdInt
4044 int getLastResumedActivityUserId() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004045 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004046 Manifest.permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
4047 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07004048 if (mLastResumedActivity == null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004049 return getCurrentUserId();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004050 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004051 return mLastResumedActivity.userId;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004052 }
4053 }
4054
4055 @Override
4056 public void updateLockTaskFeatures(int userId, int flags) {
4057 final int callingUid = Binder.getCallingUid();
4058 if (callingUid != 0 && callingUid != SYSTEM_UID) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004059 mAmInternal.enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004060 "updateLockTaskFeatures()");
4061 }
4062 synchronized (mGlobalLock) {
4063 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
4064 Integer.toHexString(flags));
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07004065 getLockTaskController().updateLockTaskFeatures(userId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004066 }
4067 }
4068
4069 @Override
4070 public void setShowWhenLocked(IBinder token, boolean showWhenLocked) {
4071 synchronized (mGlobalLock) {
4072 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4073 if (r == null) {
4074 return;
4075 }
4076 final long origId = Binder.clearCallingIdentity();
4077 try {
4078 r.setShowWhenLocked(showWhenLocked);
4079 } finally {
4080 Binder.restoreCallingIdentity(origId);
4081 }
4082 }
4083 }
4084
4085 @Override
4086 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) {
4087 synchronized (mGlobalLock) {
4088 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4089 if (r == null) {
4090 return;
4091 }
4092 final long origId = Binder.clearCallingIdentity();
4093 try {
4094 r.setTurnScreenOn(turnScreenOn);
4095 } finally {
4096 Binder.restoreCallingIdentity(origId);
4097 }
4098 }
4099 }
4100
4101 @Override
4102 public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004103 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004104 "registerRemoteAnimations");
4105 definition.setCallingPid(Binder.getCallingPid());
4106 synchronized (mGlobalLock) {
4107 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4108 if (r == null) {
4109 return;
4110 }
4111 final long origId = Binder.clearCallingIdentity();
4112 try {
4113 r.registerRemoteAnimations(definition);
4114 } finally {
4115 Binder.restoreCallingIdentity(origId);
4116 }
4117 }
4118 }
4119
4120 @Override
4121 public void registerRemoteAnimationForNextActivityStart(String packageName,
4122 RemoteAnimationAdapter adapter) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004123 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004124 "registerRemoteAnimationForNextActivityStart");
4125 adapter.setCallingPid(Binder.getCallingPid());
4126 synchronized (mGlobalLock) {
4127 final long origId = Binder.clearCallingIdentity();
4128 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07004129 getActivityStartController().registerRemoteAnimationForNextActivityStart(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004130 packageName, adapter);
4131 } finally {
4132 Binder.restoreCallingIdentity(origId);
4133 }
4134 }
4135 }
4136
4137 /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
4138 @Override
4139 public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
4140 synchronized (mGlobalLock) {
4141 final long origId = Binder.clearCallingIdentity();
4142 try {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004143 mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004144 } finally {
4145 Binder.restoreCallingIdentity(origId);
4146 }
4147 }
4148 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004149
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004150 @Override
4151 public void setVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004152 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004153 synchronized (mGlobalLock) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004154 final int pid = Binder.getCallingPid();
4155 final WindowProcessController wpc = mPidMap.get(pid);
4156 mVrController.setVrThreadLocked(tid, pid, wpc);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004157 }
4158 }
4159
4160 @Override
4161 public void setPersistentVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004162 if (checkCallingPermission(Manifest.permission.RESTRICTED_VR_ACCESS)
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004163 != PERMISSION_GRANTED) {
4164 final String msg = "Permission Denial: setPersistentVrThread() from pid="
4165 + Binder.getCallingPid()
4166 + ", uid=" + Binder.getCallingUid()
4167 + " requires " + Manifest.permission.RESTRICTED_VR_ACCESS;
4168 Slog.w(TAG, msg);
4169 throw new SecurityException(msg);
4170 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004171 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004172 synchronized (mGlobalLock) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004173 final int pid = Binder.getCallingPid();
4174 final WindowProcessController proc = mPidMap.get(pid);
4175 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004176 }
4177 }
4178
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004179 @Override
4180 public void stopAppSwitches() {
4181 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
4182 synchronized (mGlobalLock) {
4183 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME;
4184 mDidAppSwitch = false;
4185 getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
4186 }
4187 }
4188
4189 @Override
4190 public void resumeAppSwitches() {
4191 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
4192 synchronized (mGlobalLock) {
4193 // Note that we don't execute any pending app switches... we will
4194 // let those wait until either the timeout, or the next start
4195 // activity request.
4196 mAppSwitchesAllowedTime = 0;
4197 }
4198 }
4199
4200 void onStartActivitySetDidAppSwitch() {
4201 if (mDidAppSwitch) {
4202 // This is the second allowed switch since we stopped switches, so now just generally
4203 // allow switches. Use case:
4204 // - user presses home (switches disabled, switch to home, mDidAppSwitch now true);
4205 // - user taps a home icon (coming from home so allowed, we hit here and now allow
4206 // anyone to switch again).
4207 mAppSwitchesAllowedTime = 0;
4208 } else {
4209 mDidAppSwitch = true;
4210 }
4211 }
4212
4213 /** @return whether the system should disable UI modes incompatible with VR mode. */
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004214 boolean shouldDisableNonVrUiLocked() {
4215 return mVrController.shouldDisableNonVrUiLocked();
4216 }
4217
Wale Ogunwale53783742018-09-16 10:21:51 -07004218 private void applyUpdateVrModeLocked(ActivityRecord r) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004219 // VR apps are expected to run in a main display. If an app is turning on VR for
4220 // itself, but lives in a dynamic stack, then make sure that it is moved to the main
4221 // fullscreen stack before enabling VR Mode.
4222 // TODO: The goal of this code is to keep the VR app on the main display. When the
4223 // stack implementation changes in the future, keep in mind that the use of the fullscreen
4224 // stack is a means to move the activity to the main display and a moveActivityToDisplay()
4225 // option would be a better choice here.
4226 if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
4227 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
4228 + " to main stack for VR");
4229 final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
4230 WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
4231 moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
4232 }
4233 mH.post(() -> {
4234 if (!mVrController.onVrModeChanged(r)) {
4235 return;
4236 }
4237 synchronized (mGlobalLock) {
4238 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
4239 mWindowManager.disableNonVrUi(disableNonVrUi);
4240 if (disableNonVrUi) {
4241 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
4242 // then remove the pinned stack.
4243 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
4244 }
4245 }
4246 });
4247 }
4248
Wale Ogunwale53783742018-09-16 10:21:51 -07004249 @Override
4250 public int getPackageScreenCompatMode(String packageName) {
4251 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4252 synchronized (mGlobalLock) {
4253 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4254 }
4255 }
4256
4257 @Override
4258 public void setPackageScreenCompatMode(String packageName, int mode) {
4259 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4260 "setPackageScreenCompatMode");
4261 synchronized (mGlobalLock) {
4262 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4263 }
4264 }
4265
4266 @Override
4267 public boolean getPackageAskScreenCompat(String packageName) {
4268 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4269 synchronized (mGlobalLock) {
4270 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4271 }
4272 }
4273
4274 @Override
4275 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4276 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4277 "setPackageAskScreenCompat");
4278 synchronized (mGlobalLock) {
4279 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4280 }
4281 }
4282
Andrii Kulian5f750bc2018-07-17 08:57:23 -07004283 ActivityStack getTopDisplayFocusedStack() {
4284 return mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004285 }
4286
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004287 /** Pokes the task persister. */
4288 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
4289 mRecentTasks.notifyTaskPersisterLocked(task, flush);
4290 }
4291
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004292 void onTopProcChangedLocked(WindowProcessController proc) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004293 mVrController.onTopProcChangedLocked(proc);
4294 }
4295
4296 boolean isKeyguardLocked() {
4297 return mKeyguardController.isKeyguardLocked();
4298 }
4299
4300 boolean isNextTransitionForward() {
4301 int transit = mWindowManager.getPendingAppTransition();
4302 return transit == TRANSIT_ACTIVITY_OPEN
4303 || transit == TRANSIT_TASK_OPEN
4304 || transit == TRANSIT_TASK_TO_FRONT;
4305 }
4306
Wale Ogunwalef6733932018-06-27 05:14:34 -07004307 void dumpSleepStates(PrintWriter pw, boolean testPssMode) {
4308 synchronized (mGlobalLock) {
4309 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
4310 if (mRunningVoice != null) {
4311 pw.println(" mRunningVoice=" + mRunningVoice);
4312 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
4313 }
4314 pw.println(" mSleeping=" + mSleeping);
4315 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + testPssMode);
4316 pw.println(" mVrController=" + mVrController);
4317 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004318 }
4319
Wale Ogunwalef6733932018-06-27 05:14:34 -07004320 void writeSleepStateToProto(ProtoOutputStream proto) {
4321 for (ActivityTaskManagerInternal.SleepToken st : mStackSupervisor.mSleepTokens) {
4322 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS,
4323 st.toString());
4324 }
4325
4326 if (mRunningVoice != null) {
4327 final long vrToken = proto.start(
4328 ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
4329 proto.write(ActivityManagerServiceDumpProcessesProto.Voice.SESSION,
4330 mRunningVoice.toString());
4331 mVoiceWakeLock.writeToProto(
4332 proto, ActivityManagerServiceDumpProcessesProto.Voice.WAKELOCK);
4333 proto.end(vrToken);
4334 }
4335
4336 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
4337 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN,
4338 mShuttingDown);
4339 mVrController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004340 }
4341
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004342 int getCurrentUserId() {
4343 return mAmInternal.getCurrentUserId();
4344 }
4345
4346 private void enforceNotIsolatedCaller(String caller) {
4347 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4348 throw new SecurityException("Isolated process not allowed to call " + caller);
4349 }
4350 }
4351
Wale Ogunwalef6733932018-06-27 05:14:34 -07004352 public Configuration getConfiguration() {
4353 Configuration ci;
4354 synchronized(mGlobalLock) {
Yunfan Chen75157d72018-07-27 14:47:21 +09004355 ci = new Configuration(getGlobalConfigurationForCallingPid());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004356 ci.userSetLocale = false;
4357 }
4358 return ci;
4359 }
4360
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004361 /**
4362 * Current global configuration information. Contains general settings for the entire system,
4363 * also corresponds to the merged configuration of the default display.
4364 */
4365 Configuration getGlobalConfiguration() {
4366 return mStackSupervisor.getConfiguration();
4367 }
4368
4369 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4370 boolean initLocale) {
4371 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
4372 }
4373
4374 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4375 boolean initLocale, boolean deferResume) {
4376 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
4377 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
4378 UserHandle.USER_NULL, deferResume);
4379 }
4380
4381 void updatePersistentConfiguration(Configuration values, @UserIdInt int userId) {
4382 final long origId = Binder.clearCallingIdentity();
4383 try {
4384 synchronized (mGlobalLock) {
4385 updateConfigurationLocked(values, null, false, true, userId,
4386 false /* deferResume */);
4387 }
4388 } finally {
4389 Binder.restoreCallingIdentity(origId);
4390 }
4391 }
4392
4393 void updateUserConfiguration() {
4394 synchronized (mGlobalLock) {
4395 final Configuration configuration = new Configuration(getGlobalConfiguration());
4396 final int currentUserId = mAmInternal.getCurrentUserId();
4397 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
4398 currentUserId, Settings.System.canWrite(mContext));
4399 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
4400 false /* persistent */, currentUserId, false /* deferResume */);
4401 }
4402 }
4403
4404 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4405 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
4406 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
4407 deferResume, null /* result */);
4408 }
4409
4410 /**
4411 * Do either or both things: (1) change the current configuration, and (2)
4412 * make sure the given activity is running with the (now) current
4413 * configuration. Returns true if the activity has been left running, or
4414 * false if <var>starting</var> is being destroyed to match the new
4415 * configuration.
4416 *
4417 * @param userId is only used when persistent parameter is set to true to persist configuration
4418 * for that particular user
4419 */
4420 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4421 boolean initLocale, boolean persistent, int userId, boolean deferResume,
4422 ActivityTaskManagerService.UpdateConfigurationResult result) {
4423 int changes = 0;
4424 boolean kept = true;
4425
4426 if (mWindowManager != null) {
4427 mWindowManager.deferSurfaceLayout();
4428 }
4429 try {
4430 if (values != null) {
4431 changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
4432 deferResume);
4433 }
4434
4435 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4436 } finally {
4437 if (mWindowManager != null) {
4438 mWindowManager.continueSurfaceLayout();
4439 }
4440 }
4441
4442 if (result != null) {
4443 result.changes = changes;
4444 result.activityRelaunched = !kept;
4445 }
4446 return kept;
4447 }
4448
4449 /**
4450 * Returns true if this configuration change is interesting enough to send an
4451 * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
4452 */
4453 private static boolean isSplitConfigurationChange(int configDiff) {
4454 return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
4455 }
4456
4457 /** Update default (global) configuration and notify listeners about changes. */
4458 private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
4459 boolean persistent, int userId, boolean deferResume) {
4460 mTempConfig.setTo(getGlobalConfiguration());
4461 final int changes = mTempConfig.updateFrom(values);
4462 if (changes == 0) {
4463 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
4464 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
4465 // performDisplayOverrideConfigUpdate in order to send the new display configuration
4466 // (even if there are no actual changes) to unfreeze the window.
4467 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
4468 return 0;
4469 }
4470
4471 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
4472 "Updating global configuration to: " + values);
4473
4474 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
4475 StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
4476 values.colorMode,
4477 values.densityDpi,
4478 values.fontScale,
4479 values.hardKeyboardHidden,
4480 values.keyboard,
4481 values.keyboardHidden,
4482 values.mcc,
4483 values.mnc,
4484 values.navigation,
4485 values.navigationHidden,
4486 values.orientation,
4487 values.screenHeightDp,
4488 values.screenLayout,
4489 values.screenWidthDp,
4490 values.smallestScreenWidthDp,
4491 values.touchscreen,
4492 values.uiMode);
4493
4494
4495 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
4496 final LocaleList locales = values.getLocales();
4497 int bestLocaleIndex = 0;
4498 if (locales.size() > 1) {
4499 if (mSupportedSystemLocales == null) {
4500 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
4501 }
4502 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
4503 }
4504 SystemProperties.set("persist.sys.locale",
4505 locales.get(bestLocaleIndex).toLanguageTag());
4506 LocaleList.setDefault(locales, bestLocaleIndex);
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004507
4508 final Message m = PooledLambda.obtainMessage(
4509 ActivityTaskManagerService::sendLocaleToMountDaemonMsg, this,
4510 locales.get(bestLocaleIndex));
4511 mH.sendMessage(m);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004512 }
4513
Yunfan Chen75157d72018-07-27 14:47:21 +09004514 mTempConfig.seq = increaseConfigurationSeqLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004515
4516 // Update stored global config and notify everyone about the change.
4517 mStackSupervisor.onConfigurationChanged(mTempConfig);
4518
4519 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
4520 // TODO(multi-display): Update UsageEvents#Event to include displayId.
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004521 mUsageStatsInternal.reportConfigurationChange(mTempConfig, mAmInternal.getCurrentUserId());
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004522
4523 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
Wale Ogunwalef6733932018-06-27 05:14:34 -07004524 updateShouldShowDialogsLocked(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004525
4526 AttributeCache ac = AttributeCache.instance();
4527 if (ac != null) {
4528 ac.updateConfiguration(mTempConfig);
4529 }
4530
4531 // Make sure all resources in our process are updated right now, so that anyone who is going
4532 // to retrieve resource values after we return will be sure to get the new ones. This is
4533 // especially important during boot, where the first config change needs to guarantee all
4534 // resources have that config before following boot code is executed.
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004535 mSystemThread.applyConfigurationToResources(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004536
4537 // We need another copy of global config because we're scheduling some calls instead of
4538 // running them in place. We need to be sure that object we send will be handled unchanged.
4539 final Configuration configCopy = new Configuration(mTempConfig);
4540 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004541 final Message msg = PooledLambda.obtainMessage(
4542 ActivityTaskManagerService::sendPutConfigurationForUserMsg,
4543 this, userId, configCopy);
4544 mH.sendMessage(msg);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004545 }
4546
Yunfan Chen34fcc7a2018-10-11 16:26:09 -07004547 for (int i = mPidMap.size() - 1; i >= 0; i--) {
4548 WindowProcessController app = mPidMap.get(mPidMap.keyAt(i));
4549 if (DEBUG_CONFIGURATION) {
4550 Slog.v(TAG_CONFIGURATION, "Update process config of "
4551 + app.mName + " to new config " + configCopy);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004552 }
Yunfan Chen34fcc7a2018-10-11 16:26:09 -07004553 app.onConfigurationChanged(configCopy);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004554 }
4555
4556 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
4557 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
4558 | Intent.FLAG_RECEIVER_FOREGROUND
4559 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4560 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4561 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4562 UserHandle.USER_ALL);
4563 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
4564 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
4565 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
4566 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
4567 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4568 if (initLocale || !mAm.mProcessesReady) {
4569 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
4570 }
4571 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4572 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4573 UserHandle.USER_ALL);
4574 }
4575
4576 // Send a broadcast to PackageInstallers if the configuration change is interesting
4577 // for the purposes of installing additional splits.
4578 if (!initLocale && isSplitConfigurationChange(changes)) {
4579 intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
4580 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
4581 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
4582
4583 // Typically only app stores will have this permission.
4584 String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES };
4585 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions,
4586 OP_NONE, null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
4587 }
4588
4589 // Override configuration of the default display duplicates global config, so we need to
4590 // update it also. This will also notify WindowManager about changes.
4591 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
4592 DEFAULT_DISPLAY);
4593
4594 return changes;
4595 }
4596
4597 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
4598 boolean deferResume, int displayId) {
4599 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
4600 displayId, null /* result */);
4601 }
4602
4603 /**
4604 * Updates override configuration specific for the selected display. If no config is provided,
4605 * new one will be computed in WM based on current display info.
4606 */
4607 boolean updateDisplayOverrideConfigurationLocked(Configuration values,
4608 ActivityRecord starting, boolean deferResume, int displayId,
4609 ActivityTaskManagerService.UpdateConfigurationResult result) {
4610 int changes = 0;
4611 boolean kept = true;
4612
4613 if (mWindowManager != null) {
4614 mWindowManager.deferSurfaceLayout();
4615 }
4616 try {
4617 if (values != null) {
4618 if (displayId == DEFAULT_DISPLAY) {
4619 // Override configuration of the default display duplicates global config, so
4620 // we're calling global config update instead for default display. It will also
4621 // apply the correct override config.
4622 changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
4623 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
4624 } else {
4625 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
4626 }
4627 }
4628
4629 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4630 } finally {
4631 if (mWindowManager != null) {
4632 mWindowManager.continueSurfaceLayout();
4633 }
4634 }
4635
4636 if (result != null) {
4637 result.changes = changes;
4638 result.activityRelaunched = !kept;
4639 }
4640 return kept;
4641 }
4642
4643 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
4644 int displayId) {
4645 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
4646 final int changes = mTempConfig.updateFrom(values);
4647 if (changes != 0) {
4648 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
4649 + mTempConfig + " for displayId=" + displayId);
4650 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
4651
4652 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
4653 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004654 mAppWarnings.onDensityChanged();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004655
4656 mAm.killAllBackgroundProcessesExcept(N,
4657 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
4658 }
4659 }
4660
4661 // Update the configuration with WM first and check if any of the stacks need to be resized
4662 // due to the configuration change. If so, resize the stacks now and do any relaunches if
4663 // necessary. This way we don't need to relaunch again afterwards in
4664 // ensureActivityConfiguration().
4665 if (mWindowManager != null) {
4666 final int[] resizedStacks =
4667 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
4668 if (resizedStacks != null) {
4669 for (int stackId : resizedStacks) {
4670 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
4671 }
4672 }
4673 }
4674
4675 return changes;
4676 }
4677
Wale Ogunwalef6733932018-06-27 05:14:34 -07004678 private void updateEventDispatchingLocked(boolean booted) {
4679 mWindowManager.setEventDispatching(booted && !mShuttingDown);
4680 }
4681
Wale Ogunwale342fbe92018-10-09 08:44:10 -07004682 private void sendPutConfigurationForUserMsg(int userId, Configuration config) {
4683 final ContentResolver resolver = mContext.getContentResolver();
4684 Settings.System.putConfigurationForUser(resolver, config, userId);
4685 }
4686
4687 private void sendLocaleToMountDaemonMsg(Locale l) {
4688 try {
4689 IBinder service = ServiceManager.getService("mount");
4690 IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
4691 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
4692 storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
4693 } catch (RemoteException e) {
4694 Log.e(TAG, "Error storing locale for decryption UI", e);
4695 }
4696 }
4697
4698 boolean isActivityStartsLoggingEnabled() {
4699 return mAmInternal.isActivityStartsLoggingEnabled();
4700 }
4701
Wale Ogunwalef6733932018-06-27 05:14:34 -07004702 void enableScreenAfterBoot(boolean booted) {
4703 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4704 SystemClock.uptimeMillis());
4705 mWindowManager.enableScreenAfterBoot();
4706
4707 synchronized (mGlobalLock) {
4708 updateEventDispatchingLocked(booted);
4709 }
4710 }
4711
4712 boolean canShowErrorDialogs() {
4713 return mShowDialogs && !mSleeping && !mShuttingDown
4714 && !mKeyguardController.isKeyguardOrAodShowing(DEFAULT_DISPLAY)
4715 && !hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
Wale Ogunwale86b74462018-07-02 08:42:43 -07004716 mAmInternal.getCurrentUserId())
Wale Ogunwalef6733932018-06-27 05:14:34 -07004717 && !(UserManager.isDeviceInDemoMode(mContext)
Wale Ogunwale86b74462018-07-02 08:42:43 -07004718 && mAmInternal.getCurrentUser().isDemo());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004719 }
4720
Wale Ogunwale906f9c62018-07-23 11:23:44 -07004721 static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
4722 if (r == null || !r.hasProcess()) {
4723 return KEY_DISPATCHING_TIMEOUT_MS;
4724 }
4725 return getInputDispatchingTimeoutLocked(r.app);
4726 }
4727
4728 private static long getInputDispatchingTimeoutLocked(WindowProcessController r) {
4729 if (r != null && (r.isInstrumenting() || r.isUsingWrapper())) {
4730 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS;
4731 }
4732 return KEY_DISPATCHING_TIMEOUT_MS;
4733 }
4734
4735 long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
4736 if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
4737 throw new SecurityException("Requires permission " + FILTER_EVENTS);
4738 }
4739 WindowProcessController proc;
4740 long timeout;
4741 synchronized (mGlobalLock) {
4742 proc = mPidMap.get(pid);
4743 timeout = getInputDispatchingTimeoutLocked(proc);
4744 }
4745
4746 if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
4747 return -1;
4748 }
4749
4750 return timeout;
4751 }
4752
4753 /**
4754 * Handle input dispatching timeouts.
4755 * Returns whether input dispatching should be aborted or not.
4756 */
4757 boolean inputDispatchingTimedOut(final WindowProcessController proc,
4758 final ActivityRecord activity, final ActivityRecord parent,
4759 final boolean aboveSystem, String reason) {
4760 if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
4761 throw new SecurityException("Requires permission " + FILTER_EVENTS);
4762 }
4763
4764 final String annotation;
4765 if (reason == null) {
4766 annotation = "Input dispatching timed out";
4767 } else {
4768 annotation = "Input dispatching timed out (" + reason + ")";
4769 }
4770
4771 if (proc != null) {
4772 synchronized (mGlobalLock) {
4773 if (proc.isDebugging()) {
4774 return false;
4775 }
4776
4777 if (proc.isInstrumenting()) {
4778 Bundle info = new Bundle();
4779 info.putString("shortMsg", "keyDispatchingTimedOut");
4780 info.putString("longMsg", annotation);
4781 mAm.finishInstrumentationLocked(
4782 (ProcessRecord) proc.mOwner, Activity.RESULT_CANCELED, info);
4783 return true;
4784 }
4785 }
4786 mH.post(() -> {
4787 mAm.mAppErrors.appNotResponding(
4788 (ProcessRecord) proc.mOwner, activity, parent, aboveSystem, annotation);
4789 });
4790 }
4791
4792 return true;
4793 }
4794
Wale Ogunwalef6733932018-06-27 05:14:34 -07004795 /**
4796 * Decide based on the configuration whether we should show the ANR,
4797 * crash, etc dialogs. The idea is that if there is no affordance to
4798 * press the on-screen buttons, or the user experience would be more
4799 * greatly impacted than the crash itself, we shouldn't show the dialog.
4800 *
4801 * A thought: SystemUI might also want to get told about this, the Power
4802 * dialog / global actions also might want different behaviors.
4803 */
4804 private void updateShouldShowDialogsLocked(Configuration config) {
4805 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
4806 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
4807 && config.navigation == Configuration.NAVIGATION_NONAV);
4808 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
4809 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
4810 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
4811 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
4812 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
4813 final boolean hideDialogsSet = Settings.Global.getInt(mContext.getContentResolver(),
4814 HIDE_ERROR_DIALOGS, 0) != 0;
4815 mShowDialogs = inputMethodExists && uiModeSupportsDialogs && !hideDialogsSet;
4816 }
4817
4818 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
4819 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
4820 FONT_SCALE, 1.0f, userId);
4821
4822 synchronized (this) {
4823 if (getGlobalConfiguration().fontScale == scaleFactor) {
4824 return;
4825 }
4826
4827 final Configuration configuration
4828 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
4829 configuration.fontScale = scaleFactor;
4830 updatePersistentConfiguration(configuration, userId);
4831 }
4832 }
4833
4834 // Actually is sleeping or shutting down or whatever else in the future
4835 // is an inactive state.
4836 boolean isSleepingOrShuttingDownLocked() {
4837 return isSleepingLocked() || mShuttingDown;
4838 }
4839
4840 boolean isSleepingLocked() {
4841 return mSleeping;
4842 }
4843
Riddle Hsu16567132018-08-16 21:37:47 +08004844 /** Update AMS states when an activity is resumed. */
Wale Ogunwalef6733932018-06-27 05:14:34 -07004845 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
4846 final TaskRecord task = r.getTask();
4847 if (task.isActivityTypeStandard()) {
4848 if (mCurAppTimeTracker != r.appTimeTracker) {
4849 // We are switching app tracking. Complete the current one.
4850 if (mCurAppTimeTracker != null) {
4851 mCurAppTimeTracker.stop();
4852 mH.obtainMessage(
4853 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
4854 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
4855 mCurAppTimeTracker = null;
4856 }
4857 if (r.appTimeTracker != null) {
4858 mCurAppTimeTracker = r.appTimeTracker;
4859 startTimeTrackingFocusedActivityLocked();
4860 }
4861 } else {
4862 startTimeTrackingFocusedActivityLocked();
4863 }
4864 } else {
4865 r.appTimeTracker = null;
4866 }
4867 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
4868 // TODO: Probably not, because we don't want to resume voice on switching
4869 // back to this activity
4870 if (task.voiceInteractor != null) {
4871 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
4872 } else {
4873 finishRunningVoiceLocked();
4874
4875 if (mLastResumedActivity != null) {
4876 final IVoiceInteractionSession session;
4877
4878 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
4879 if (lastResumedActivityTask != null
4880 && lastResumedActivityTask.voiceSession != null) {
4881 session = lastResumedActivityTask.voiceSession;
4882 } else {
4883 session = mLastResumedActivity.voiceSession;
4884 }
4885
4886 if (session != null) {
4887 // We had been in a voice interaction session, but now focused has
4888 // move to something different. Just finish the session, we can't
4889 // return to it and retain the proper state and synchronization with
4890 // the voice interaction service.
4891 finishVoiceTask(session);
4892 }
4893 }
4894 }
4895
4896 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
4897 mAmInternal.sendForegroundProfileChanged(r.userId);
4898 }
4899 updateResumedAppTrace(r);
4900 mLastResumedActivity = r;
4901
Tiger Huang1e5b10a2018-07-30 20:19:51 +08004902 r.getDisplay().setFocusedApp(r, true);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004903
4904 applyUpdateLockStateLocked(r);
4905 applyUpdateVrModeLocked(r);
4906
4907 EventLogTags.writeAmSetResumedActivity(
4908 r == null ? -1 : r.userId,
4909 r == null ? "NULL" : r.shortComponentName,
4910 reason);
4911 }
4912
4913 ActivityTaskManagerInternal.SleepToken acquireSleepToken(String tag, int displayId) {
4914 synchronized (mGlobalLock) {
4915 final ActivityTaskManagerInternal.SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
4916 updateSleepIfNeededLocked();
4917 return token;
4918 }
4919 }
4920
4921 void updateSleepIfNeededLocked() {
4922 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
4923 final boolean wasSleeping = mSleeping;
4924 boolean updateOomAdj = false;
4925
4926 if (!shouldSleep) {
4927 // If wasSleeping is true, we need to wake up activity manager state from when
4928 // we started sleeping. In either case, we need to apply the sleep tokens, which
4929 // will wake up stacks or put them to sleep as appropriate.
4930 if (wasSleeping) {
4931 mSleeping = false;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07004932 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
4933 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__AWAKE);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004934 startTimeTrackingFocusedActivityLocked();
4935 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
4936 mStackSupervisor.comeOutOfSleepIfNeededLocked();
4937 }
4938 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
4939 if (wasSleeping) {
4940 updateOomAdj = true;
4941 }
4942 } else if (!mSleeping && shouldSleep) {
4943 mSleeping = true;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07004944 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
4945 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__ASLEEP);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004946 if (mCurAppTimeTracker != null) {
4947 mCurAppTimeTracker.stop();
4948 }
4949 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
4950 mStackSupervisor.goingToSleepLocked();
4951 updateResumedAppTrace(null /* resumed */);
4952 updateOomAdj = true;
4953 }
4954 if (updateOomAdj) {
4955 mH.post(mAmInternal::updateOomAdj);
4956 }
4957 }
4958
4959 void updateOomAdj() {
4960 mH.post(mAmInternal::updateOomAdj);
4961 }
4962
Wale Ogunwale53783742018-09-16 10:21:51 -07004963 void updateCpuStats() {
4964 mH.post(mAmInternal::updateCpuStats);
4965 }
4966
4967 void updateUsageStats(ActivityRecord component, boolean resumed) {
4968 final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::updateUsageStats,
4969 mAmInternal, component.realActivity, component.app.mUid, component.userId, resumed);
4970 mH.sendMessage(m);
4971 }
4972
4973 void setBooting(boolean booting) {
4974 mAmInternal.setBooting(booting);
4975 }
4976
4977 boolean isBooting() {
4978 return mAmInternal.isBooting();
4979 }
4980
4981 void setBooted(boolean booted) {
4982 mAmInternal.setBooted(booted);
4983 }
4984
4985 boolean isBooted() {
4986 return mAmInternal.isBooted();
4987 }
4988
4989 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
4990 mH.post(() -> {
4991 if (finishBooting) {
4992 mAmInternal.finishBooting();
4993 }
4994 if (enableScreen) {
4995 mInternal.enableScreenAfterBoot(isBooted());
4996 }
4997 });
4998 }
4999
5000 void setHeavyWeightProcess(ActivityRecord root) {
5001 mHeavyWeightProcess = root.app;
5002 final Message m = PooledLambda.obtainMessage(
5003 ActivityTaskManagerService::postHeavyWeightProcessNotification, this,
5004 root.app, root.intent, root.userId);
5005 mH.sendMessage(m);
5006 }
5007
5008 void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
5009 if (mHeavyWeightProcess == null || mHeavyWeightProcess != proc) {
5010 return;
5011 }
5012
5013 mHeavyWeightProcess = null;
5014 final Message m = PooledLambda.obtainMessage(
5015 ActivityTaskManagerService::cancelHeavyWeightProcessNotification, this,
5016 proc.mUserId);
5017 mH.sendMessage(m);
5018 }
5019
5020 private void cancelHeavyWeightProcessNotification(int userId) {
5021 final INotificationManager inm = NotificationManager.getService();
5022 if (inm == null) {
5023 return;
5024 }
5025 try {
5026 inm.cancelNotificationWithTag("android", null,
5027 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, userId);
5028 } catch (RuntimeException e) {
5029 Slog.w(TAG, "Error canceling notification for service", e);
5030 } catch (RemoteException e) {
5031 }
5032
5033 }
5034
5035 private void postHeavyWeightProcessNotification(
5036 WindowProcessController proc, Intent intent, int userId) {
5037 if (proc == null) {
5038 return;
5039 }
5040
5041 final INotificationManager inm = NotificationManager.getService();
5042 if (inm == null) {
5043 return;
5044 }
5045
5046 try {
5047 Context context = mContext.createPackageContext(proc.mInfo.packageName, 0);
5048 String text = mContext.getString(R.string.heavy_weight_notification,
5049 context.getApplicationInfo().loadLabel(context.getPackageManager()));
5050 Notification notification =
5051 new Notification.Builder(context,
5052 SystemNotificationChannels.HEAVY_WEIGHT_APP)
5053 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
5054 .setWhen(0)
5055 .setOngoing(true)
5056 .setTicker(text)
5057 .setColor(mContext.getColor(
5058 com.android.internal.R.color.system_notification_accent_color))
5059 .setContentTitle(text)
5060 .setContentText(
5061 mContext.getText(R.string.heavy_weight_notification_detail))
5062 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
5063 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
5064 new UserHandle(userId)))
5065 .build();
5066 try {
5067 inm.enqueueNotificationWithTag("android", "android", null,
5068 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, notification, userId);
5069 } catch (RuntimeException e) {
5070 Slog.w(TAG, "Error showing notification for heavy-weight app", e);
5071 } catch (RemoteException e) {
5072 }
5073 } catch (PackageManager.NameNotFoundException e) {
5074 Slog.w(TAG, "Unable to create context for heavy notification", e);
5075 }
5076
5077 }
5078
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07005079 IIntentSender getIntentSenderLocked(int type, String packageName, int callingUid, int userId,
5080 IBinder token, String resultWho, int requestCode, Intent[] intents,
5081 String[] resolvedTypes, int flags, Bundle bOptions) {
5082
5083 ActivityRecord activity = null;
5084 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5085 activity = ActivityRecord.isInStackLocked(token);
5086 if (activity == null) {
5087 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
5088 return null;
5089 }
5090 if (activity.finishing) {
5091 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
5092 return null;
5093 }
5094 }
5095
5096 final PendingIntentRecord rec = mPendingIntentController.getIntentSender(type, packageName,
5097 callingUid, userId, token, resultWho, requestCode, intents, resolvedTypes, flags,
5098 bOptions);
5099 final boolean noCreate = (flags & PendingIntent.FLAG_NO_CREATE) != 0;
5100 if (noCreate) {
5101 return rec;
5102 }
5103 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5104 if (activity.pendingResults == null) {
5105 activity.pendingResults = new HashSet<>();
5106 }
5107 activity.pendingResults.add(rec.ref);
5108 }
5109 return rec;
5110 }
5111
Andrii Kulian52d255c2018-07-13 11:32:19 -07005112 // TODO(b/111541062): Update app time tracking to make it aware of multiple resumed activities
Wale Ogunwalef6733932018-06-27 05:14:34 -07005113 private void startTimeTrackingFocusedActivityLocked() {
Andrii Kulian52d255c2018-07-13 11:32:19 -07005114 final ActivityRecord resumedActivity = mStackSupervisor.getTopResumedActivity();
Wale Ogunwalef6733932018-06-27 05:14:34 -07005115 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
5116 mCurAppTimeTracker.start(resumedActivity.packageName);
5117 }
5118 }
5119
5120 private void updateResumedAppTrace(@Nullable ActivityRecord resumed) {
5121 if (mTracedResumedActivity != null) {
5122 Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER,
5123 constructResumedTraceName(mTracedResumedActivity.packageName), 0);
5124 }
5125 if (resumed != null) {
5126 Trace.asyncTraceBegin(TRACE_TAG_ACTIVITY_MANAGER,
5127 constructResumedTraceName(resumed.packageName), 0);
5128 }
5129 mTracedResumedActivity = resumed;
5130 }
5131
5132 private String constructResumedTraceName(String packageName) {
5133 return "focused app: " + packageName;
5134 }
5135
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005136 /** Helper method that requests bounds from WM and applies them to stack. */
5137 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
5138 final Rect newStackBounds = new Rect();
5139 final ActivityStack stack = mStackSupervisor.getStack(stackId);
5140
5141 // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
5142 if (stack == null) {
5143 final StringWriter writer = new StringWriter();
5144 final PrintWriter printWriter = new PrintWriter(writer);
5145 mStackSupervisor.dumpDisplays(printWriter);
5146 printWriter.flush();
5147
5148 Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
5149 }
5150
5151 stack.getBoundsForNewConfiguration(newStackBounds);
5152 mStackSupervisor.resizeStackLocked(
5153 stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
5154 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
5155 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
5156 }
5157
5158 /** Applies latest configuration and/or visibility updates if needed. */
5159 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
5160 boolean kept = true;
Andrii Kulian5f750bc2018-07-17 08:57:23 -07005161 final ActivityStack mainStack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005162 // mainStack is null during startup.
5163 if (mainStack != null) {
5164 if (changes != 0 && starting == null) {
5165 // If the configuration changed, and the caller is not already
5166 // in the process of starting an activity, then find the top
5167 // activity to check if its configuration needs to change.
5168 starting = mainStack.topRunningActivityLocked();
5169 }
5170
5171 if (starting != null) {
5172 kept = starting.ensureActivityConfiguration(changes,
5173 false /* preserveWindow */);
5174 // And we need to make sure at this point that all other activities
5175 // are made visible with the correct configuration.
5176 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
5177 !PRESERVE_WINDOWS);
5178 }
5179 }
5180
5181 return kept;
5182 }
5183
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005184 void scheduleAppGcsLocked() {
5185 mH.post(() -> mAmInternal.scheduleAppGcs());
5186 }
5187
Wale Ogunwale53783742018-09-16 10:21:51 -07005188 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
5189 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
5190 }
5191
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005192 /**
5193 * Returns the PackageManager. Used by classes hosted by {@link ActivityTaskManagerService}. The
5194 * PackageManager could be unavailable at construction time and therefore needs to be accessed
5195 * on demand.
5196 */
5197 IPackageManager getPackageManager() {
5198 return AppGlobals.getPackageManager();
5199 }
5200
5201 PackageManagerInternal getPackageManagerInternalLocked() {
5202 if (mPmInternal == null) {
5203 mPmInternal = LocalServices.getService(PackageManagerInternal.class);
5204 }
5205 return mPmInternal;
5206 }
5207
Wale Ogunwale008163e2018-07-23 23:11:08 -07005208 AppWarnings getAppWarningsLocked() {
5209 return mAppWarnings;
5210 }
5211
Wale Ogunwale214f3482018-10-04 11:00:47 -07005212 Intent getHomeIntent() {
5213 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
5214 intent.setComponent(mTopComponent);
5215 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
5216 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5217 intent.addCategory(Intent.CATEGORY_HOME);
5218 }
5219 return intent;
5220 }
5221
5222 /**
5223 * This starts home activity on displays that can have system decorations and only if the
5224 * home activity can have multiple instances.
5225 */
5226 boolean startHomeActivityLocked(int userId, String reason, int displayId) {
5227 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL && mTopAction == null) {
5228 // We are running in factory test mode, but unable to find the factory test app, so just
5229 // sit around displaying the error message and don't try to start anything.
5230 return false;
5231 }
5232
5233 final Intent intent = getHomeIntent();
5234 ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
5235 if (aInfo != null) {
5236 intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
5237 // Don't do this if the home app is currently being instrumented.
5238 aInfo = new ActivityInfo(aInfo);
5239 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
5240 WindowProcessController app =
5241 getProcessController(aInfo.processName, aInfo.applicationInfo.uid);
5242 if (app == null || !app.isInstrumenting()) {
5243 intent.setFlags(intent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
5244 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
5245 // For ANR debugging to verify if the user activity is the one that actually
5246 // launched.
5247 final String myReason = reason + ":" + userId + ":" + resolvedUserId;
5248 getActivityStartController().startHomeActivity(intent, aInfo, myReason, displayId);
5249 }
5250 } else {
5251 Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
5252 }
5253
5254 return true;
5255 }
5256
5257 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
5258 ActivityInfo ai = null;
5259 final ComponentName comp = intent.getComponent();
5260 try {
5261 if (comp != null) {
5262 // Factory test.
5263 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
5264 } else {
5265 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
5266 intent,
5267 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
5268 flags, userId);
5269
5270 if (info != null) {
5271 ai = info.activityInfo;
5272 }
5273 }
5274 } catch (RemoteException e) {
5275 // ignore
5276 }
5277
5278 return ai;
5279 }
5280
5281 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
5282 if (info == null) return null;
5283 ApplicationInfo newInfo = new ApplicationInfo(info);
5284 newInfo.initForUser(userId);
5285 return newInfo;
5286 }
5287
5288 private WindowProcessController getProcessController(String processName, int uid) {
5289 if (uid == SYSTEM_UID) {
5290 // The system gets to run in any process. If there are multiple processes with the same
5291 // uid, just pick the first (this should never happen).
5292 final SparseArray<WindowProcessController> procs =
5293 mProcessNames.getMap().get(processName);
5294 if (procs == null) return null;
5295 final int procCount = procs.size();
5296 for (int i = 0; i < procCount; i++) {
5297 final int procUid = procs.keyAt(i);
5298 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
5299 // Don't use an app process or different user process for system component.
5300 continue;
5301 }
5302 return procs.valueAt(i);
5303 }
5304 }
5305
5306 return mProcessNames.get(processName, uid);
5307 }
5308
Wale Ogunwale342fbe92018-10-09 08:44:10 -07005309 WindowProcessController getProcessController(IApplicationThread thread) {
5310 if (thread == null) {
5311 return null;
5312 }
5313
5314 final IBinder threadBinder = thread.asBinder();
5315 final ArrayMap<String, SparseArray<WindowProcessController>> pmap = mProcessNames.getMap();
5316 for (int i = pmap.size()-1; i >= 0; i--) {
5317 final SparseArray<WindowProcessController> procs = pmap.valueAt(i);
5318 for (int j = procs.size() - 1; j >= 0; j--) {
5319 final WindowProcessController proc = procs.valueAt(j);
5320 if (proc.hasThread() && proc.getThread().asBinder() == threadBinder) {
5321 return proc;
5322 }
5323 }
5324 }
5325
5326 return null;
5327 }
5328
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005329 void logAppTooSlow(WindowProcessController app, long startTime, String msg) {
5330 if (true || Build.IS_USER) {
5331 return;
5332 }
5333
5334 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5335 StrictMode.allowThreadDiskWrites();
5336 try {
5337 File tracesDir = new File("/data/anr");
5338 File tracesFile = null;
5339 try {
5340 tracesFile = File.createTempFile("app_slow", null, tracesDir);
5341
5342 StringBuilder sb = new StringBuilder();
5343 Time tobj = new Time();
5344 tobj.set(System.currentTimeMillis());
5345 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5346 sb.append(": ");
5347 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5348 sb.append(" since ");
5349 sb.append(msg);
5350 FileOutputStream fos = new FileOutputStream(tracesFile);
5351 fos.write(sb.toString().getBytes());
5352 if (app == null) {
5353 fos.write("\n*** No application process!".getBytes());
5354 }
5355 fos.close();
5356 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5357 } catch (IOException e) {
5358 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesFile, e);
5359 return;
5360 }
5361
5362 if (app != null && app.getPid() > 0) {
5363 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5364 firstPids.add(app.getPid());
5365 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, null, null);
5366 }
5367
5368 File lastTracesFile = null;
5369 File curTracesFile = null;
5370 for (int i=9; i>=0; i--) {
5371 String name = String.format(Locale.US, "slow%02d.txt", i);
5372 curTracesFile = new File(tracesDir, name);
5373 if (curTracesFile.exists()) {
5374 if (lastTracesFile != null) {
5375 curTracesFile.renameTo(lastTracesFile);
5376 } else {
5377 curTracesFile.delete();
5378 }
5379 }
5380 lastTracesFile = curTracesFile;
5381 }
5382 tracesFile.renameTo(curTracesFile);
5383 } finally {
5384 StrictMode.setThreadPolicy(oldPolicy);
5385 }
5386 }
5387
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005388 final class H extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005389 static final int REPORT_TIME_TRACKER_MSG = 1;
Wale Ogunwale98875612018-10-12 07:53:02 -07005390 static final int FIRST_ACTIVITY_STACK_MSG = 100;
5391 static final int FIRST_SUPERVISOR_STACK_MSG = 200;
Wale Ogunwalef6733932018-06-27 05:14:34 -07005392
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005393 public H(Looper looper) {
5394 super(looper, null, true);
5395 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005396
5397 @Override
5398 public void handleMessage(Message msg) {
5399 switch (msg.what) {
5400 case REPORT_TIME_TRACKER_MSG: {
5401 AppTimeTracker tracker = (AppTimeTracker) msg.obj;
5402 tracker.deliverResult(mContext);
5403 } break;
5404 }
5405 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005406 }
5407
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005408 final class UiHandler extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005409 static final int DISMISS_DIALOG_UI_MSG = 1;
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005410
5411 public UiHandler() {
5412 super(com.android.server.UiThread.get().getLooper(), null, true);
5413 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005414
5415 @Override
5416 public void handleMessage(Message msg) {
5417 switch (msg.what) {
5418 case DISMISS_DIALOG_UI_MSG: {
5419 final Dialog d = (Dialog) msg.obj;
5420 d.dismiss();
5421 break;
5422 }
5423 }
5424 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005425 }
5426
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005427 final class LocalService extends ActivityTaskManagerInternal {
5428 @Override
5429 public SleepToken acquireSleepToken(String tag, int displayId) {
5430 Preconditions.checkNotNull(tag);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005431 return ActivityTaskManagerService.this.acquireSleepToken(tag, displayId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005432 }
5433
5434 @Override
5435 public ComponentName getHomeActivityForUser(int userId) {
5436 synchronized (mGlobalLock) {
Louis Changbd48dca2018-08-29 17:44:34 +08005437 ActivityRecord homeActivity =
5438 mStackSupervisor.getDefaultDisplayHomeActivityForUser(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005439 return homeActivity == null ? null : homeActivity.realActivity;
5440 }
5441 }
5442
5443 @Override
5444 public void onLocalVoiceInteractionStarted(IBinder activity,
5445 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
5446 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005447 onLocalVoiceInteractionStartedLocked(activity, voiceSession, voiceInteractor);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005448 }
5449 }
5450
5451 @Override
5452 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
5453 synchronized (mGlobalLock) {
5454 mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
5455 reasons, timestamp);
5456 }
5457 }
5458
5459 @Override
5460 public void notifyAppTransitionFinished() {
5461 synchronized (mGlobalLock) {
5462 mStackSupervisor.notifyAppTransitionDone();
5463 }
5464 }
5465
5466 @Override
5467 public void notifyAppTransitionCancelled() {
5468 synchronized (mGlobalLock) {
5469 mStackSupervisor.notifyAppTransitionDone();
5470 }
5471 }
5472
5473 @Override
5474 public List<IBinder> getTopVisibleActivities() {
5475 synchronized (mGlobalLock) {
5476 return mStackSupervisor.getTopVisibleActivities();
5477 }
5478 }
5479
5480 @Override
5481 public void notifyDockedStackMinimizedChanged(boolean minimized) {
5482 synchronized (mGlobalLock) {
5483 mStackSupervisor.setDockedStackMinimized(minimized);
5484 }
5485 }
5486
5487 @Override
5488 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
5489 Bundle bOptions) {
5490 Preconditions.checkNotNull(intents, "intents");
5491 final String[] resolvedTypes = new String[intents.length];
5492
5493 // UID of the package on user userId.
5494 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
5495 // packageUid may not be initialized.
5496 int packageUid = 0;
5497 final long ident = Binder.clearCallingIdentity();
5498
5499 try {
5500 for (int i = 0; i < intents.length; i++) {
5501 resolvedTypes[i] =
5502 intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
5503 }
5504
5505 packageUid = AppGlobals.getPackageManager().getPackageUid(
5506 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
5507 } catch (RemoteException e) {
5508 // Shouldn't happen.
5509 } finally {
5510 Binder.restoreCallingIdentity(ident);
5511 }
5512
5513 synchronized (mGlobalLock) {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07005514 return getActivityStartController().startActivitiesInPackage(
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005515 packageUid, packageName,
5516 intents, resolvedTypes, null /* resultTo */,
5517 SafeActivityOptions.fromBundle(bOptions), userId,
Michal Karpinski201bc0c2018-07-20 15:32:00 +01005518 false /* validateIncomingUser */, null /* originatingPendingIntent */);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005519 }
5520 }
5521
5522 @Override
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07005523 public int startActivitiesInPackage(int uid, String callingPackage, Intent[] intents,
5524 String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, int userId,
5525 boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent) {
5526 synchronized (mGlobalLock) {
5527 return getActivityStartController().startActivitiesInPackage(uid, callingPackage,
5528 intents, resolvedTypes, resultTo, options, userId, validateIncomingUser,
5529 originatingPendingIntent);
5530 }
5531 }
5532
5533 @Override
5534 public int startActivityInPackage(int uid, int realCallingPid, int realCallingUid,
5535 String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
5536 String resultWho, int requestCode, int startFlags, SafeActivityOptions options,
5537 int userId, TaskRecord inTask, String reason, boolean validateIncomingUser,
5538 PendingIntentRecord originatingPendingIntent) {
5539 synchronized (mGlobalLock) {
5540 return getActivityStartController().startActivityInPackage(uid, realCallingPid,
5541 realCallingUid, callingPackage, intent, resolvedType, resultTo, resultWho,
5542 requestCode, startFlags, options, userId, inTask, reason,
5543 validateIncomingUser, originatingPendingIntent);
5544 }
5545 }
5546
5547 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005548 public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
5549 Intent intent, Bundle options, int userId) {
5550 return ActivityTaskManagerService.this.startActivityAsUser(
5551 caller, callerPacakge, intent,
5552 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
5553 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
5554 false /*validateIncomingUser*/);
5555 }
5556
5557 @Override
5558 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
5559 synchronized (mGlobalLock) {
5560
5561 // We might change the visibilities here, so prepare an empty app transition which
5562 // might be overridden later if we actually change visibilities.
5563 final boolean wasTransitionSet =
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005564 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005565 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005566 mWindowManager.prepareAppTransition(TRANSIT_NONE,
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005567 false /* alwaysKeepCurrent */);
5568 }
5569 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5570
5571 // If there was a transition set already we don't want to interfere with it as we
5572 // might be starting it too early.
5573 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005574 mWindowManager.executeAppTransition();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005575 }
5576 }
5577 if (callback != null) {
5578 callback.run();
5579 }
5580 }
5581
5582 @Override
5583 public void notifyKeyguardTrustedChanged() {
5584 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005585 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005586 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5587 }
5588 }
5589 }
5590
5591 /**
5592 * Called after virtual display Id is updated by
5593 * {@link com.android.server.vr.Vr2dDisplay} with a specific
5594 * {@param vrVr2dDisplayId}.
5595 */
5596 @Override
5597 public void setVr2dDisplayId(int vr2dDisplayId) {
5598 if (DEBUG_STACK) Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
5599 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005600 mVr2dDisplayId = vr2dDisplayId;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005601 }
5602 }
5603
5604 @Override
5605 public void setFocusedActivity(IBinder token) {
5606 synchronized (mGlobalLock) {
5607 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
5608 if (r == null) {
5609 throw new IllegalArgumentException(
5610 "setFocusedActivity: No activity record matching token=" + token);
5611 }
Louis Chang19443452018-10-09 12:10:21 +08005612 if (r.moveFocusableActivityToTop("setFocusedActivity")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08005613 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005614 }
5615 }
5616 }
5617
5618 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005619 public void registerScreenObserver(ScreenObserver observer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005620 mScreenObservers.add(observer);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005621 }
5622
5623 @Override
5624 public boolean isCallerRecents(int callingUid) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005625 return getRecentTasks().isCallerRecents(callingUid);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005626 }
5627
5628 @Override
5629 public boolean isRecentsComponentHomeActivity(int userId) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005630 return getRecentTasks().isRecentsComponentHomeActivity(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005631 }
5632
5633 @Override
5634 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
5635 ActivityTaskManagerService.this.cancelRecentsAnimation(restoreHomeStackPosition);
5636 }
5637
5638 @Override
5639 public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005640 ActivityTaskManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005641 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005642
5643 @Override
5644 public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
5645 synchronized (mGlobalLock) {
5646 mActiveVoiceInteractionServiceComponent = component;
5647 }
5648 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005649
5650 @Override
5651 public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
5652 if (!mAmInternal.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
5653 return;
5654 }
5655 synchronized (mGlobalLock) {
5656 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
5657 if (types == null) {
5658 if (uid < 0) {
5659 return;
5660 }
5661 types = new ArrayMap<>();
5662 mAllowAppSwitchUids.put(userId, types);
5663 }
5664 if (uid < 0) {
5665 types.remove(type);
5666 } else {
5667 types.put(type, uid);
5668 }
5669 }
5670 }
5671
5672 @Override
5673 public void onUserStopped(int userId) {
5674 synchronized (mGlobalLock) {
5675 getRecentTasks().unloadUserDataFromMemoryLocked(userId);
5676 mAllowAppSwitchUids.remove(userId);
5677 }
5678 }
5679
5680 @Override
5681 public boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
5682 synchronized (mGlobalLock) {
5683 return ActivityTaskManagerService.this.isGetTasksAllowed(
5684 caller, callingPid, callingUid);
5685 }
5686 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005687
5688 @Override
5689 public void onProcessAdded(WindowProcessController proc) {
5690 synchronized (mGlobalLock) {
5691 mProcessNames.put(proc.mName, proc.mUid, proc);
5692 }
5693 }
5694
5695 @Override
5696 public void onProcessRemoved(String name, int uid) {
5697 synchronized (mGlobalLock) {
5698 mProcessNames.remove(name, uid);
5699 }
5700 }
5701
5702 @Override
5703 public void onCleanUpApplicationRecord(WindowProcessController proc) {
5704 synchronized (mGlobalLock) {
5705 if (proc == mHomeProcess) {
5706 mHomeProcess = null;
5707 }
5708 if (proc == mPreviousProcess) {
5709 mPreviousProcess = null;
5710 }
5711 }
5712 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005713
5714 @Override
5715 public int getTopProcessState() {
5716 synchronized (mGlobalLock) {
5717 return mTopProcessState;
5718 }
5719 }
5720
5721 @Override
Wale Ogunwale53783742018-09-16 10:21:51 -07005722 public boolean isHeavyWeightProcess(WindowProcessController proc) {
5723 synchronized (mGlobalLock) {
5724 return proc == mHeavyWeightProcess;
5725 }
5726 }
5727
5728 @Override
5729 public void clearHeavyWeightProcessIfEquals(WindowProcessController proc) {
5730 synchronized (mGlobalLock) {
5731 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(proc);
5732 }
5733 }
5734
5735 @Override
5736 public void finishHeavyWeightApp() {
5737 synchronized (mGlobalLock) {
5738 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(
5739 mHeavyWeightProcess);
5740 }
5741 }
5742
5743 @Override
Wale Ogunwalef6733932018-06-27 05:14:34 -07005744 public boolean isSleeping() {
5745 synchronized (mGlobalLock) {
5746 return isSleepingLocked();
5747 }
5748 }
5749
5750 @Override
5751 public boolean isShuttingDown() {
5752 synchronized (mGlobalLock) {
5753 return mShuttingDown;
5754 }
5755 }
5756
5757 @Override
5758 public boolean shuttingDown(boolean booted, int timeout) {
5759 synchronized (mGlobalLock) {
5760 mShuttingDown = true;
5761 mStackSupervisor.prepareForShutdownLocked();
5762 updateEventDispatchingLocked(booted);
5763 return mStackSupervisor.shutdownLocked(timeout);
5764 }
5765 }
5766
5767 @Override
5768 public void enableScreenAfterBoot(boolean booted) {
5769 synchronized (mGlobalLock) {
5770 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5771 SystemClock.uptimeMillis());
5772 mWindowManager.enableScreenAfterBoot();
5773 updateEventDispatchingLocked(booted);
5774 }
5775 }
5776
5777 @Override
5778 public boolean showStrictModeViolationDialog() {
5779 synchronized (mGlobalLock) {
5780 return mShowDialogs && !mSleeping && !mShuttingDown;
5781 }
5782 }
5783
5784 @Override
5785 public void showSystemReadyErrorDialogsIfNeeded() {
5786 synchronized (mGlobalLock) {
5787 try {
5788 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
5789 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
5790 + " data partition or your device will be unstable.");
5791 mUiHandler.post(() -> {
5792 if (mShowDialogs) {
5793 AlertDialog d = new BaseErrorDialog(mUiContext);
5794 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5795 d.setCancelable(false);
5796 d.setTitle(mUiContext.getText(R.string.android_system_label));
5797 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
5798 d.setButton(DialogInterface.BUTTON_POSITIVE,
5799 mUiContext.getText(R.string.ok),
5800 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5801 d.show();
5802 }
5803 });
5804 }
5805 } catch (RemoteException e) {
5806 }
5807
5808 if (!Build.isBuildConsistent()) {
5809 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
5810 mUiHandler.post(() -> {
5811 if (mShowDialogs) {
5812 AlertDialog d = new BaseErrorDialog(mUiContext);
5813 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5814 d.setCancelable(false);
5815 d.setTitle(mUiContext.getText(R.string.android_system_label));
5816 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
5817 d.setButton(DialogInterface.BUTTON_POSITIVE,
5818 mUiContext.getText(R.string.ok),
5819 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5820 d.show();
5821 }
5822 });
5823 }
5824 }
5825 }
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005826
5827 @Override
5828 public long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason) {
5829 synchronized (mGlobalLock) {
5830 return ActivityTaskManagerService.this.inputDispatchingTimedOut(
5831 pid, aboveSystem, reason);
5832 }
5833 }
5834
5835 @Override
5836 public void onProcessMapped(int pid, WindowProcessController proc) {
5837 synchronized (mGlobalLock) {
5838 mPidMap.put(pid, proc);
5839 }
5840 }
5841
5842 @Override
5843 public void onProcessUnMapped(int pid) {
5844 synchronized (mGlobalLock) {
5845 mPidMap.remove(pid);
5846 }
5847 }
Wale Ogunwale008163e2018-07-23 23:11:08 -07005848
5849 @Override
5850 public void onPackageDataCleared(String name) {
5851 synchronized (mGlobalLock) {
Wale Ogunwale53783742018-09-16 10:21:51 -07005852 mCompatModePackages.handlePackageDataClearedLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07005853 mAppWarnings.onPackageDataCleared(name);
5854 }
5855 }
5856
5857 @Override
5858 public void onPackageUninstalled(String name) {
5859 synchronized (mGlobalLock) {
5860 mAppWarnings.onPackageUninstalled(name);
Wale Ogunwale53783742018-09-16 10:21:51 -07005861 mCompatModePackages.handlePackageUninstalledLocked(name);
Wale Ogunwale008163e2018-07-23 23:11:08 -07005862 }
5863 }
Wale Ogunwale53783742018-09-16 10:21:51 -07005864
5865 @Override
5866 public void onPackageAdded(String name, boolean replacing) {
5867 synchronized (mGlobalLock) {
5868 mCompatModePackages.handlePackageAddedLocked(name, replacing);
5869 }
5870 }
5871
5872 @Override
5873 public CompatibilityInfo compatibilityInfoForPackage(ApplicationInfo ai) {
5874 synchronized (mGlobalLock) {
5875 return compatibilityInfoForPackageLocked(ai);
5876 }
5877 }
5878
Yunfan Chen75157d72018-07-27 14:47:21 +09005879 /**
5880 * Set the corresponding display information for the process global configuration. To be
5881 * called when we need to show IME on a different display.
5882 *
5883 * @param pid The process id associated with the IME window.
5884 * @param displayId The ID of the display showing the IME.
5885 */
5886 @Override
5887 public void onImeWindowSetOnDisplay(int pid, int displayId) {
5888 if (pid == MY_PID || pid < 0) {
5889 if (DEBUG_CONFIGURATION) {
5890 Slog.w(TAG,
5891 "Trying to update display configuration for system/invalid process.");
5892 }
5893 return;
5894 }
5895 mH.post(() -> {
5896 synchronized (mGlobalLock) {
5897 // Check if display is initialized in AM.
5898 if (!mStackSupervisor.isDisplayAdded(displayId)) {
5899 // Call come when display is not yet added or has already been removed.
5900 if (DEBUG_CONFIGURATION) {
5901 Slog.w(TAG, "Trying to update display configuration for non-existing "
5902 + "displayId=" + displayId);
5903 }
5904 return;
5905 }
5906 final WindowProcessController imeProcess = mPidMap.get(pid);
5907 if (imeProcess == null) {
5908 if (DEBUG_CONFIGURATION) {
5909 Slog.w(TAG, "Trying to update display configuration for invalid pid: "
5910 + pid);
5911 }
5912 return;
5913 }
5914 // Fetch the current override configuration of the display and set it to the
5915 // process global configuration.
5916 imeProcess.onConfigurationChanged(
5917 mStackSupervisor.getDisplayOverrideConfiguration(displayId));
5918 }
5919 });
5920 }
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07005921
5922 @Override
5923 public void sendActivityResult(int callingUid, IBinder activityToken, String resultWho,
5924 int requestCode, int resultCode, Intent data) {
5925 synchronized (mGlobalLock) {
5926 final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
5927 if (r != null && r.getStack() != null) {
5928 r.getStack().sendActivityResultLocked(callingUid, r, resultWho, requestCode,
5929 resultCode, data);
5930 }
5931 }
5932 }
5933
5934 @Override
5935 public void clearPendingResultForActivity(IBinder activityToken,
5936 WeakReference<PendingIntentRecord> pir) {
5937 synchronized (mGlobalLock) {
5938 final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
5939 if (r != null && r.pendingResults != null) {
5940 r.pendingResults.remove(pir);
5941 }
5942 }
5943 }
5944
5945 @Override
5946 public IIntentSender getIntentSender(int type, String packageName,
5947 int callingUid, int userId, IBinder token, String resultWho,
5948 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5949 Bundle bOptions) {
5950 synchronized (mGlobalLock) {
5951 return getIntentSenderLocked(type, packageName, callingUid, userId, token,
5952 resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
5953 }
5954 }
Wale Ogunwalec4e63a42018-10-02 13:19:54 -07005955
5956 @Override
5957 public ActivityServiceConnectionsHolder getServiceConnectionsHolder(IBinder token) {
5958 synchronized (mGlobalLock) {
5959 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
5960 if (r == null) {
5961 return null;
5962 }
5963 if (r.mServiceConnectionsHolder == null) {
5964 r.mServiceConnectionsHolder = new ActivityServiceConnectionsHolder(
5965 ActivityTaskManagerService.this, r);
5966 }
5967
5968 return r.mServiceConnectionsHolder;
5969 }
5970 }
Wale Ogunwale214f3482018-10-04 11:00:47 -07005971
5972 @Override
5973 public Intent getHomeIntent() {
5974 synchronized (mGlobalLock) {
5975 return ActivityTaskManagerService.this.getHomeIntent();
5976 }
5977 }
5978
5979 @Override
5980 public boolean startHomeActivity(int userId, String reason) {
5981 synchronized (mGlobalLock) {
5982 return startHomeActivityLocked(userId, reason, DEFAULT_DISPLAY);
5983 }
5984 }
5985
5986 @Override
5987 public boolean isFactoryTestProcess(WindowProcessController wpc) {
5988 synchronized (mGlobalLock) {
5989 if (mFactoryTest == FACTORY_TEST_OFF) {
5990 return false;
5991 }
5992 if (mFactoryTest == FACTORY_TEST_LOW_LEVEL && mTopComponent != null
5993 && wpc.mName.equals(mTopComponent.getPackageName())) {
5994 return true;
5995 }
5996 return mFactoryTest == FACTORY_TEST_HIGH_LEVEL
5997 && (wpc.mInfo.flags & FLAG_FACTORY_TEST) != 0;
5998 }
5999 }
6000
6001 @Override
6002 public void updateTopComponentForFactoryTest() {
6003 synchronized (mGlobalLock) {
6004 if (mFactoryTest != FACTORY_TEST_LOW_LEVEL) {
6005 return;
6006 }
6007 final ResolveInfo ri = mContext.getPackageManager()
6008 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), STOCK_PM_FLAGS);
6009 final CharSequence errorMsg;
6010 if (ri != null) {
6011 final ActivityInfo ai = ri.activityInfo;
6012 final ApplicationInfo app = ai.applicationInfo;
6013 if ((app.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
6014 mTopAction = Intent.ACTION_FACTORY_TEST;
6015 mTopData = null;
6016 mTopComponent = new ComponentName(app.packageName, ai.name);
6017 errorMsg = null;
6018 } else {
6019 errorMsg = mContext.getResources().getText(
6020 com.android.internal.R.string.factorytest_not_system);
6021 }
6022 } else {
6023 errorMsg = mContext.getResources().getText(
6024 com.android.internal.R.string.factorytest_no_action);
6025 }
6026 if (errorMsg == null) {
6027 return;
6028 }
6029
6030 mTopAction = null;
6031 mTopData = null;
6032 mTopComponent = null;
6033 mUiHandler.post(() -> {
6034 Dialog d = new FactoryErrorDialog(mUiContext, errorMsg);
6035 d.show();
Wale Ogunwale342fbe92018-10-09 08:44:10 -07006036 mAmInternal.ensureBootCompleted();
Wale Ogunwale214f3482018-10-04 11:00:47 -07006037 });
6038 }
6039 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07006040 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07006041}