blob: 6935703dbd04e80467db05375fe87ab7a6ba148a [file] [log] [blame]
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.server.am;
18
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070019import static android.Manifest.permission.BIND_VOICE_INTERACTION;
20import static android.Manifest.permission.CHANGE_CONFIGURATION;
21import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
Wale Ogunwale906f9c62018-07-23 11:23:44 -070022import static android.Manifest.permission.FILTER_EVENTS;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070023import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070024import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070025import static android.Manifest.permission.READ_FRAME_BUFFER;
26import static android.Manifest.permission.REMOVE_TASKS;
27import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070028import static android.Manifest.permission.STOP_APP_SWITCHES;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070029import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
Evan Rosky4505b352018-09-06 11:20:40 -070030import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070031import static android.app.ActivityTaskManager.RESIZE_MODE_PRESERVE_WINDOW;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070032import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070033import static android.app.AppOpsManager.OP_NONE;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070034import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070035import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
36import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070037import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
38import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070039import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070040import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070041import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070042import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
43import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
Evan Rosky4505b352018-09-06 11:20:40 -070044import static android.content.pm.PackageManager.FEATURE_PC;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070045import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070046import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070047import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
48import static android.os.Build.VERSION_CODES.N;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070049import static android.os.Process.SYSTEM_UID;
Evan Rosky4505b352018-09-06 11:20:40 -070050import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070051import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
52import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
53import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
54import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
Evan Rosky4505b352018-09-06 11:20:40 -070055import static android.provider.Settings.Global.HIDE_ERROR_DIALOGS;
56import static android.provider.Settings.System.FONT_SCALE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070057import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
58import static android.view.Display.DEFAULT_DISPLAY;
59import static android.view.Display.INVALID_DISPLAY;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070060import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
Wale Ogunwale6767eae2018-05-03 15:52:51 -070061import static android.view.WindowManager.TRANSIT_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070062import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
Wale Ogunwaled0412b32018-05-08 09:25:50 -070063import static android.view.WindowManager.TRANSIT_TASK_OPEN;
64import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
Evan Rosky4505b352018-09-06 11:20:40 -070065
Wale Ogunwale65ebd952018-04-25 15:41:44 -070066import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070067import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
68import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
69import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
70import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070071import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070072import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070073import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070074import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070075import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070076import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
77import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
78import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070079import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070080import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
81import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070082import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
83import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
84import static com.android.server.am.ActivityManagerService.ANIMATE;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070085import static com.android.server.am.ActivityManagerService.MY_PID;
86import static com.android.server.am.ActivityManagerService.SEND_LOCALE_TO_MOUNT_DAEMON_MSG;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070087import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS;
Wale Ogunwalea6191b42018-05-09 07:41:32 -070088import static com.android.server.am.ActivityManagerService.UPDATE_CONFIGURATION_MSG;
89import static com.android.server.am.ActivityManagerService.checkComponentPermission;
Evan Rosky4505b352018-09-06 11:20:40 -070090import static com.android.server.am.ActivityManagerService.dumpStackTraces;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070091import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070092import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070093import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
94import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
95import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
96import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
97import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
Evan Rosky4505b352018-09-06 11:20:40 -070098import static com.android.server.am.ActivityTaskManagerService.H.REPORT_TIME_TRACKER_MSG;
99import static com.android.server.am.ActivityTaskManagerService.UiHandler.DISMISS_DIALOG_UI_MSG;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700100import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
101import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700102import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700103import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
Evan Rosky4505b352018-09-06 11:20:40 -0700104import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT;
105import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_DATA;
106import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
107import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700108import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
109import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700110
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700111import android.Manifest;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700112import android.annotation.NonNull;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700113import android.annotation.Nullable;
114import android.annotation.UserIdInt;
115import android.app.Activity;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700116import android.app.ActivityManager;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700117import android.app.ActivityManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700118import android.app.ActivityOptions;
119import android.app.ActivityTaskManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700120import android.app.ActivityThread;
121import android.app.AlertDialog;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700122import android.app.AppGlobals;
Evan Rosky4505b352018-09-06 11:20:40 -0700123import android.app.Dialog;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700124import android.app.IActivityController;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700125import android.app.IActivityTaskManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700126import android.app.IApplicationThread;
127import android.app.IAssistDataReceiver;
128import android.app.ITaskStackListener;
129import android.app.PictureInPictureParams;
130import android.app.ProfilerInfo;
131import android.app.RemoteAction;
132import android.app.WaitResult;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700133import android.app.WindowConfiguration;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700134import android.app.admin.DevicePolicyCache;
135import android.app.assist.AssistContent;
136import android.app.assist.AssistStructure;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700137import android.app.servertransaction.ConfigurationChangeItem;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700138import android.app.usage.UsageEvents;
139import android.content.ActivityNotFoundException;
140import android.content.ComponentName;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700141import android.content.ContentResolver;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700142import android.content.Context;
Evan Rosky4505b352018-09-06 11:20:40 -0700143import android.content.DialogInterface;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700144import android.content.IIntentSender;
145import android.content.Intent;
146import android.content.pm.ActivityInfo;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700147import android.content.pm.ApplicationInfo;
Evan Rosky4505b352018-09-06 11:20:40 -0700148import android.content.pm.IPackageManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700149import android.content.pm.PackageManager;
Evan Rosky4505b352018-09-06 11:20:40 -0700150import android.content.pm.PackageManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700151import android.content.pm.ParceledListSlice;
152import android.content.pm.ResolveInfo;
153import android.content.res.Configuration;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700154import android.content.res.Resources;
Evan Rosky4505b352018-09-06 11:20:40 -0700155import android.database.ContentObserver;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700156import android.graphics.Bitmap;
157import android.graphics.Point;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700158import android.graphics.Rect;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700159import android.metrics.LogMaker;
160import android.net.Uri;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700161import android.os.Binder;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700162import android.os.Build;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700163import android.os.Bundle;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700164import android.os.FileUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700165import android.os.Handler;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700166import android.os.IBinder;
Evan Rosky4505b352018-09-06 11:20:40 -0700167import android.os.IUserManager;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700168import android.os.LocaleList;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700169import android.os.Looper;
170import android.os.Message;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700171import android.os.PersistableBundle;
Evan Rosky4505b352018-09-06 11:20:40 -0700172import android.os.PowerManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700173import android.os.RemoteException;
Evan Rosky4505b352018-09-06 11:20:40 -0700174import android.os.ServiceManager;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700175import android.os.StrictMode;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700176import android.os.SystemClock;
177import android.os.SystemProperties;
Evan Rosky4505b352018-09-06 11:20:40 -0700178import android.os.Trace;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700179import android.os.UpdateLock;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700180import android.os.UserHandle;
Evan Rosky4505b352018-09-06 11:20:40 -0700181import android.os.UserManager;
182import android.os.WorkSource;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700183import android.provider.Settings;
184import android.service.voice.IVoiceInteractionSession;
185import android.service.voice.VoiceInteractionManagerInternal;
186import android.telecom.TelecomManager;
187import android.text.TextUtils;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700188import android.text.format.Time;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700189import android.util.ArrayMap;
190import android.util.EventLog;
191import android.util.Log;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700192import android.util.Slog;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700193import android.util.SparseArray;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700194import android.util.SparseIntArray;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700195import android.util.StatsLog;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700196import android.util.TimeUtils;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700197import android.util.proto.ProtoOutputStream;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700198import android.view.IRecentsAnimationRunner;
199import android.view.RemoteAnimationAdapter;
200import android.view.RemoteAnimationDefinition;
Evan Rosky4505b352018-09-06 11:20:40 -0700201import android.view.WindowManager;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700202
Evan Rosky4505b352018-09-06 11:20:40 -0700203import com.android.internal.R;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700204import com.android.internal.annotations.VisibleForTesting;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700205import com.android.internal.app.AssistUtils;
Evan Rosky4505b352018-09-06 11:20:40 -0700206import com.android.internal.app.IAppOpsService;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700207import com.android.internal.app.IVoiceInteractor;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700208import com.android.internal.app.ProcessMap;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700209import com.android.internal.logging.MetricsLogger;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700210import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Evan Rosky4505b352018-09-06 11:20:40 -0700211import com.android.internal.os.logging.MetricsLoggerWrapper;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700212import com.android.internal.policy.IKeyguardDismissCallback;
213import com.android.internal.policy.KeyguardDismissCallback;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700214import com.android.internal.util.Preconditions;
Evan Rosky4505b352018-09-06 11:20:40 -0700215import com.android.server.AppOpsService;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700216import com.android.server.AttributeCache;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700217import com.android.server.LocalServices;
218import com.android.server.SystemService;
Evan Rosky4505b352018-09-06 11:20:40 -0700219import com.android.server.SystemServiceManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700220import com.android.server.Watchdog;
Evan Rosky4505b352018-09-06 11:20:40 -0700221import com.android.server.pm.UserManagerService;
222import com.android.server.uri.UriGrantsManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700223import com.android.server.vr.VrManagerInternal;
Evan Rosky4505b352018-09-06 11:20:40 -0700224import com.android.server.wm.ActivityTaskManagerInternal;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700225import com.android.server.wm.PinnedStackWindowController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700226import com.android.server.wm.WindowManagerService;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700227
228import java.io.File;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700229import java.io.FileOutputStream;
230import java.io.IOException;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700231import java.io.PrintWriter;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700232import java.io.StringWriter;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700233import java.util.ArrayList;
234import java.util.List;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700235import java.util.Locale;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700236
237/**
238 * System service for managing activities and their containers (task, stacks, displays,... ).
239 *
240 * {@hide}
241 */
242public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
243 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityTaskManagerService" : TAG_AM;
244 private static final String TAG_STACK = TAG + POSTFIX_STACK;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700245 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
246 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
247 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
248 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
249 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700250 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700251
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700252 // How long we wait until we timeout on key dispatching.
253 private static final int KEY_DISPATCHING_TIMEOUT_MS = 5 * 1000;
254 // How long we wait until we timeout on key dispatching during instrumentation.
255 private static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS = 60 * 1000;
256
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700257 Context mContext;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700258 /**
259 * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
260 * change at runtime. Use mContext for non-UI purposes.
261 */
262 final Context mUiContext;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700263 H mH;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700264 UiHandler mUiHandler;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700265 ActivityManagerService mAm;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700266 ActivityManagerInternal mAmInternal;
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700267 UriGrantsManagerInternal mUgmInternal;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700268 private PackageManagerInternal mPmInternal;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700269 /* Global service lock used by the package the owns this service. */
270 Object mGlobalLock;
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700271 ActivityStackSupervisor mStackSupervisor;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700272 WindowManagerService mWindowManager;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700273 private UserManagerService mUserManager;
274 private AppOpsService mAppOpsService;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700275 /** All processes currently running that might have a window organized by name. */
276 final ProcessMap<WindowProcessController> mProcessNames = new ProcessMap<>();
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700277 /** All processes we currently have running mapped by pid */
278 final SparseArray<WindowProcessController> mPidMap = new SparseArray<>();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700279 /** This is the process holding what we currently consider to be the "home" activity. */
280 WindowProcessController mHomeProcess;
281 /**
282 * This is the process holding the activity the user last visited that is in a different process
283 * from the one they are currently in.
284 */
285 WindowProcessController mPreviousProcess;
286 /** The time at which the previous process was last visible. */
287 long mPreviousProcessVisibleTime;
288
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700289 /** List of intents that were used to start the most recent tasks. */
290 private RecentTasks mRecentTasks;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700291 /** State of external calls telling us if the device is awake or asleep. */
292 private boolean mKeyguardShown = false;
293
294 // Wrapper around VoiceInteractionServiceManager
295 private AssistUtils mAssistUtils;
296
297 // VoiceInteraction session ID that changes for each new request except when
298 // being called for multi-window assist in a single session.
299 private int mViSessionId = 1000;
300
301 // How long to wait in getAssistContextExtras for the activity and foreground services
302 // to respond with the result.
303 private static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
304
305 // How long top wait when going through the modern assist (which doesn't need to block
306 // on getting this result before starting to launch its UI).
307 private static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
308
309 // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
310 private static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
311
312 private final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
313
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700314 // Keeps track of the active voice interaction service component, notified from
315 // VoiceInteractionManagerService
316 ComponentName mActiveVoiceInteractionServiceComponent;
317
318 private VrController mVrController;
319 KeyguardController mKeyguardController;
320 private final ClientLifecycleManager mLifecycleManager;
321 private TaskChangeNotificationController mTaskChangeNotificationController;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700322 /** The controller for all operations related to locktask. */
323 private LockTaskController mLockTaskController;
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700324 private ActivityStartController mActivityStartController;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700325
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700326 boolean mSuppressResizeConfigChanges;
327
328 private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
329 new UpdateConfigurationResult();
330
331 static final class UpdateConfigurationResult {
332 // Configuration changes that were updated.
333 int changes;
334 // If the activity was relaunched to match the new configuration.
335 boolean activityRelaunched;
336
337 void reset() {
338 changes = 0;
339 activityRelaunched = false;
340 }
341 }
342
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700343 /** Current sequencing integer of the configuration, for skipping old configurations. */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700344 private int mConfigurationSeq;
345 // To cache the list of supported system locales
346 private String[] mSupportedSystemLocales = null;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700347
348 /**
349 * Temp object used when global and/or display override configuration is updated. It is also
350 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
351 * anyone...
352 */
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700353 private Configuration mTempConfig = new Configuration();
354
Wale Ogunwalef6733932018-06-27 05:14:34 -0700355 /** Temporary to avoid allocations. */
356 final StringBuilder mStringBuilder = new StringBuilder(256);
357
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700358 // Amount of time after a call to stopAppSwitches() during which we will
359 // prevent further untrusted switches from happening.
360 private static final long APP_SWITCH_DELAY_TIME = 5 * 1000;
361
362 /**
363 * The time at which we will allow normal application switches again,
364 * after a call to {@link #stopAppSwitches()}.
365 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700366 private long mAppSwitchesAllowedTime;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700367 /**
368 * This is set to true after the first switch after mAppSwitchesAllowedTime
369 * is set; any switches after that will clear the time.
370 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700371 private boolean mDidAppSwitch;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700372
373 IActivityController mController = null;
374 boolean mControllerIsAMonkey = false;
375
376 /**
377 * Used to retain an update lock when the foreground activity is in
378 * immersive mode.
379 */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700380 private final UpdateLock mUpdateLock = new UpdateLock("immersive");
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700381
382 /**
383 * Packages that are being allowed to perform unrestricted app switches. Mapping is
384 * User -> Type -> uid.
385 */
386 final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
387
388 /** The dimensions of the thumbnails in the Recents UI. */
Wale Ogunwalef6733932018-06-27 05:14:34 -0700389 private int mThumbnailWidth;
390 private int mThumbnailHeight;
391 private float mFullscreenThumbnailScale;
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700392
393 /**
394 * Flag that indicates if multi-window is enabled.
395 *
396 * For any particular form of multi-window to be enabled, generic multi-window must be enabled
397 * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
398 * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
399 * At least one of the forms of multi-window must be enabled in order for this flag to be
400 * initialized to 'true'.
401 *
402 * @see #mSupportsSplitScreenMultiWindow
403 * @see #mSupportsFreeformWindowManagement
404 * @see #mSupportsPictureInPicture
405 * @see #mSupportsMultiDisplay
406 */
407 boolean mSupportsMultiWindow;
408 boolean mSupportsSplitScreenMultiWindow;
409 boolean mSupportsFreeformWindowManagement;
410 boolean mSupportsPictureInPicture;
411 boolean mSupportsMultiDisplay;
412 boolean mForceResizableActivities;
413
414 final List<ActivityTaskManagerInternal.ScreenObserver> mScreenObservers = new ArrayList<>();
415
416 // VR Vr2d Display Id.
417 int mVr2dDisplayId = INVALID_DISPLAY;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700418
Wale Ogunwalef6733932018-06-27 05:14:34 -0700419 /**
420 * Set while we are wanting to sleep, to prevent any
421 * activities from being started/resumed.
422 *
423 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
424 *
425 * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
426 * while in the sleep state until there is a pending transition out of sleep, in which case
427 * mSleeping is set to false, and remains false while awake.
428 *
429 * Whether mSleeping can quickly toggled between true/false without the device actually
430 * display changing states is undefined.
431 */
432 private boolean mSleeping = false;
433
434 /**
435 * The process state used for processes that are running the top activities.
436 * This changes between TOP and TOP_SLEEPING to following mSleeping.
437 */
438 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
439
440 // Whether we should show our dialogs (ANR, crash, etc) or just perform their default action
441 // automatically. Important for devices without direct input devices.
442 private boolean mShowDialogs = true;
443
444 /** Set if we are shutting down the system, similar to sleeping. */
445 boolean mShuttingDown = false;
446
447 /**
448 * We want to hold a wake lock while running a voice interaction session, since
449 * this may happen with the screen off and we need to keep the CPU running to
450 * be able to continue to interact with the user.
451 */
452 PowerManager.WakeLock mVoiceWakeLock;
453
454 /**
455 * Set while we are running a voice interaction. This overrides sleeping while it is active.
456 */
457 IVoiceInteractionSession mRunningVoice;
458
459 /**
460 * The last resumed activity. This is identical to the current resumed activity most
461 * of the time but could be different when we're pausing one activity before we resume
462 * another activity.
463 */
464 ActivityRecord mLastResumedActivity;
465
466 /**
467 * The activity that is currently being traced as the active resumed activity.
468 *
469 * @see #updateResumedAppTrace
470 */
471 private @Nullable ActivityRecord mTracedResumedActivity;
472
473 /** If non-null, we are tracking the time the user spends in the currently focused app. */
474 AppTimeTracker mCurAppTimeTracker;
475
Wale Ogunwale008163e2018-07-23 23:11:08 -0700476 private AppWarnings mAppWarnings;
477
Wale Ogunwalef6733932018-06-27 05:14:34 -0700478 private FontScaleSettingObserver mFontScaleSettingObserver;
479
480 private final class FontScaleSettingObserver extends ContentObserver {
481 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
482 private final Uri mHideErrorDialogsUri = Settings.Global.getUriFor(HIDE_ERROR_DIALOGS);
483
484 public FontScaleSettingObserver() {
485 super(mH);
486 final ContentResolver resolver = mContext.getContentResolver();
487 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
488 resolver.registerContentObserver(mHideErrorDialogsUri, false, this,
489 UserHandle.USER_ALL);
490 }
491
492 @Override
493 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
494 if (mFontScaleUri.equals(uri)) {
495 updateFontScaleIfNeeded(userId);
496 } else if (mHideErrorDialogsUri.equals(uri)) {
497 synchronized (mGlobalLock) {
498 updateShouldShowDialogsLocked(getGlobalConfiguration());
499 }
500 }
501 }
502 }
503
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700504 ActivityTaskManagerService(Context context) {
505 mContext = context;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700506 mUiContext = ActivityThread.currentActivityThread().getSystemUiContext();
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700507 mLifecycleManager = new ClientLifecycleManager();
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700508 }
509
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700510 void onSystemReady() {
511 mAssistUtils = new AssistUtils(mContext);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700512 mVrController.onSystemReady();
513 mRecentTasks.onSystemReadyLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700514 }
515
Wale Ogunwalef6733932018-06-27 05:14:34 -0700516 void onInitPowerManagement() {
517 mStackSupervisor.initPowerManagement();
518 final PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
519 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
520 mVoiceWakeLock.setReferenceCounted(false);
521 }
522
523 void installSystemProviders() {
524 mFontScaleSettingObserver = new FontScaleSettingObserver();
525 }
526
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700527 void retrieveSettings(ContentResolver resolver) {
528 final boolean freeformWindowManagement =
529 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
530 || Settings.Global.getInt(
531 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
532
533 final boolean supportsMultiWindow = ActivityTaskManager.supportsMultiWindow(mContext);
534 final boolean supportsPictureInPicture = supportsMultiWindow &&
535 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
536 final boolean supportsSplitScreenMultiWindow =
537 ActivityTaskManager.supportsSplitScreenMultiWindow(mContext);
538 final boolean supportsMultiDisplay = mContext.getPackageManager()
539 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
540 final boolean alwaysFinishActivities =
541 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
542 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
543 final boolean forceResizable = Settings.Global.getInt(
544 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
Garfield Tane0846042018-07-26 13:42:04 -0700545 final boolean isPc = mContext.getPackageManager().hasSystemFeature(FEATURE_PC);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700546
547 // Transfer any global setting for forcing RTL layout, into a System Property
548 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
549
550 final Configuration configuration = new Configuration();
551 Settings.System.getConfiguration(resolver, configuration);
552 if (forceRtl) {
553 // This will take care of setting the correct layout direction flags
554 configuration.setLayoutDirection(configuration.locale);
555 }
556
557 synchronized (mGlobalLock) {
558 mForceResizableActivities = forceResizable;
559 final boolean multiWindowFormEnabled = freeformWindowManagement
560 || supportsSplitScreenMultiWindow
561 || supportsPictureInPicture
562 || supportsMultiDisplay;
563 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
564 mSupportsMultiWindow = true;
565 mSupportsFreeformWindowManagement = freeformWindowManagement;
566 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
567 mSupportsPictureInPicture = supportsPictureInPicture;
568 mSupportsMultiDisplay = supportsMultiDisplay;
569 } else {
570 mSupportsMultiWindow = false;
571 mSupportsFreeformWindowManagement = false;
572 mSupportsSplitScreenMultiWindow = false;
573 mSupportsPictureInPicture = false;
574 mSupportsMultiDisplay = false;
575 }
576 mWindowManager.setForceResizableTasks(mForceResizableActivities);
577 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
Garfield Tane0846042018-07-26 13:42:04 -0700578 mWindowManager.setSupportsFreeformWindowManagement(mSupportsFreeformWindowManagement);
579 mWindowManager.setIsPc(isPc);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700580 // This happens before any activities are started, so we can change global configuration
581 // in-place.
582 updateConfigurationLocked(configuration, null, true);
583 final Configuration globalConfig = getGlobalConfiguration();
584 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
585
586 // Load resources only after the current configuration has been set.
587 final Resources res = mContext.getResources();
588 mThumbnailWidth = res.getDimensionPixelSize(
589 com.android.internal.R.dimen.thumbnail_width);
590 mThumbnailHeight = res.getDimensionPixelSize(
591 com.android.internal.R.dimen.thumbnail_height);
592
593 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
594 mFullscreenThumbnailScale = (float) res
595 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
596 (float) globalConfig.screenWidthDp;
597 } else {
598 mFullscreenThumbnailScale = res.getFraction(
599 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
600 }
601 }
602 }
603
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700604 // TODO: Will be converted to WM lock once transition is complete.
605 void setActivityManagerService(ActivityManagerService am) {
606 mAm = am;
607 mGlobalLock = mAm;
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700608 mH = new H(mAm.mHandlerThread.getLooper());
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700609 mUiHandler = new UiHandler();
Wale Ogunwale008163e2018-07-23 23:11:08 -0700610 mAppWarnings = new AppWarnings(
611 this, mUiContext, mH, mUiHandler, SystemServiceManager.ensureSystemDir());
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700612
613 mTempConfig.setToDefaults();
614 mTempConfig.setLocales(LocaleList.getDefault());
615 mConfigurationSeq = mTempConfig.seq = 1;
616 mStackSupervisor = createStackSupervisor();
617 mStackSupervisor.onConfigurationChanged(mTempConfig);
618
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700619 mTaskChangeNotificationController =
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700620 new TaskChangeNotificationController(mGlobalLock, mStackSupervisor, mH);
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700621 mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mH);
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700622 mActivityStartController = new ActivityStartController(this);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700623 mRecentTasks = createRecentTasks();
624 mStackSupervisor.setRecentTasks(mRecentTasks);
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700625 mVrController = new VrController(mGlobalLock);
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700626 mKeyguardController = mStackSupervisor.getKeyguardController();
627 }
628
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700629 void onActivityManagerInternalAdded() {
630 mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -0700631 mUgmInternal = LocalServices.getService(UriGrantsManagerInternal.class);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700632 }
633
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700634 protected ActivityStackSupervisor createStackSupervisor() {
635 final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mH.getLooper());
636 supervisor.initialize();
637 return supervisor;
638 }
639
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700640 void setWindowManager(WindowManagerService wm) {
641 mWindowManager = wm;
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700642 mLockTaskController.setWindowManager(wm);
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700643 }
644
Wale Ogunwalef6733932018-06-27 05:14:34 -0700645 UserManagerService getUserManager() {
646 if (mUserManager == null) {
647 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
648 mUserManager = (UserManagerService) IUserManager.Stub.asInterface(b);
649 }
650 return mUserManager;
651 }
652
653 AppOpsService getAppOpsService() {
654 if (mAppOpsService == null) {
655 IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
656 mAppOpsService = (AppOpsService) IAppOpsService.Stub.asInterface(b);
657 }
658 return mAppOpsService;
659 }
660
661 boolean hasUserRestriction(String restriction, int userId) {
662 return getUserManager().hasUserRestriction(restriction, userId);
663 }
664
Wale Ogunwale16e505a2018-05-07 15:00:49 -0700665 protected RecentTasks createRecentTasks() {
666 return new RecentTasks(this, mStackSupervisor);
667 }
668
669 RecentTasks getRecentTasks() {
670 return mRecentTasks;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700671 }
672
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700673 ClientLifecycleManager getLifecycleManager() {
674 return mLifecycleManager;
675 }
676
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700677 ActivityStartController getActivityStartController() {
678 return mActivityStartController;
679 }
680
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700681 TaskChangeNotificationController getTaskChangeNotificationController() {
682 return mTaskChangeNotificationController;
683 }
684
Wale Ogunwaled95c06b2018-05-08 10:35:38 -0700685 LockTaskController getLockTaskController() {
686 return mLockTaskController;
687 }
688
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700689 private void start() {
690 LocalServices.addService(ActivityTaskManagerInternal.class, new LocalService());
691 }
692
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700693 public static final class Lifecycle extends SystemService {
694 private final ActivityTaskManagerService mService;
695
696 public Lifecycle(Context context) {
697 super(context);
698 mService = new ActivityTaskManagerService(context);
699 }
700
701 @Override
702 public void onStart() {
703 publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700704 mService.start();
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700705 }
706
707 public ActivityTaskManagerService getService() {
708 return mService;
709 }
710 }
711
712 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700713 public final int startActivity(IApplicationThread caller, String callingPackage,
714 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
715 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
716 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
717 resultWho, requestCode, startFlags, profilerInfo, bOptions,
718 UserHandle.getCallingUserId());
719 }
720
721 @Override
722 public final int startActivities(IApplicationThread caller, String callingPackage,
723 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
724 int userId) {
725 final String reason = "startActivities";
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700726 enforceNotIsolatedCaller(reason);
727 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, reason);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700728 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700729 return getActivityStartController().startActivities(caller, -1, callingPackage, intents,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100730 resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId, reason,
731 null /* originatingPendingIntent */);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700732 }
733
734 @Override
735 public int startActivityAsUser(IApplicationThread caller, String callingPackage,
736 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
737 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
738 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
739 resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
740 true /*validateIncomingUser*/);
741 }
742
743 int startActivityAsUser(IApplicationThread caller, String callingPackage,
744 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
745 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
746 boolean validateIncomingUser) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700747 enforceNotIsolatedCaller("startActivityAsUser");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700748
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700749 userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700750 Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
751
752 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700753 return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700754 .setCaller(caller)
755 .setCallingPackage(callingPackage)
756 .setResolvedType(resolvedType)
757 .setResultTo(resultTo)
758 .setResultWho(resultWho)
759 .setRequestCode(requestCode)
760 .setStartFlags(startFlags)
761 .setProfilerInfo(profilerInfo)
762 .setActivityOptions(bOptions)
763 .setMayWait(userId)
764 .execute();
765
766 }
767
768 @Override
769 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
770 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700771 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions) {
772 enforceNotIsolatedCaller("startActivityIntentSender");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700773 // Refuse possible leaked file descriptors
774 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
775 throw new IllegalArgumentException("File descriptors passed in Intent");
776 }
777
778 if (!(target instanceof PendingIntentRecord)) {
779 throw new IllegalArgumentException("Bad PendingIntent object");
780 }
781
782 PendingIntentRecord pir = (PendingIntentRecord)target;
783
784 synchronized (mGlobalLock) {
785 // If this is coming from the currently resumed activity, it is
786 // effectively saying that app switches are allowed at this point.
Andrii Kulian5f750bc2018-07-17 08:57:23 -0700787 final ActivityStack stack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700788 if (stack.mResumedActivity != null &&
789 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700790 mAppSwitchesAllowedTime = 0;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700791 }
792 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700793 return pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700794 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700795 }
796
797 @Override
798 public boolean startNextMatchingActivity(IBinder callingActivity, Intent intent,
799 Bundle bOptions) {
800 // Refuse possible leaked file descriptors
801 if (intent != null && intent.hasFileDescriptors()) {
802 throw new IllegalArgumentException("File descriptors passed in Intent");
803 }
804 SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
805
806 synchronized (mGlobalLock) {
807 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
808 if (r == null) {
809 SafeActivityOptions.abort(options);
810 return false;
811 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700812 if (!r.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700813 // The caller is not running... d'oh!
814 SafeActivityOptions.abort(options);
815 return false;
816 }
817 intent = new Intent(intent);
818 // The caller is not allowed to change the data.
819 intent.setDataAndType(r.intent.getData(), r.intent.getType());
820 // And we are resetting to find the next component...
821 intent.setComponent(null);
822
823 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
824
825 ActivityInfo aInfo = null;
826 try {
827 List<ResolveInfo> resolves =
828 AppGlobals.getPackageManager().queryIntentActivities(
829 intent, r.resolvedType,
830 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
831 UserHandle.getCallingUserId()).getList();
832
833 // Look for the original activity in the list...
834 final int N = resolves != null ? resolves.size() : 0;
835 for (int i=0; i<N; i++) {
836 ResolveInfo rInfo = resolves.get(i);
837 if (rInfo.activityInfo.packageName.equals(r.packageName)
838 && rInfo.activityInfo.name.equals(r.info.name)) {
839 // We found the current one... the next matching is
840 // after it.
841 i++;
842 if (i<N) {
843 aInfo = resolves.get(i).activityInfo;
844 }
845 if (debug) {
846 Slog.v(TAG, "Next matching activity: found current " + r.packageName
847 + "/" + r.info.name);
848 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
849 ? "null" : aInfo.packageName + "/" + aInfo.name));
850 }
851 break;
852 }
853 }
854 } catch (RemoteException e) {
855 }
856
857 if (aInfo == null) {
858 // Nobody who is next!
859 SafeActivityOptions.abort(options);
860 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
861 return false;
862 }
863
864 intent.setComponent(new ComponentName(
865 aInfo.applicationInfo.packageName, aInfo.name));
866 intent.setFlags(intent.getFlags()&~(
867 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
868 Intent.FLAG_ACTIVITY_CLEAR_TOP|
869 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
870 FLAG_ACTIVITY_NEW_TASK));
871
872 // Okay now we need to start the new activity, replacing the currently running activity.
873 // This is a little tricky because we want to start the new one as if the current one is
874 // finished, but not finish the current one first so that there is no flicker.
875 // And thus...
876 final boolean wasFinishing = r.finishing;
877 r.finishing = true;
878
879 // Propagate reply information over to the new activity.
880 final ActivityRecord resultTo = r.resultTo;
881 final String resultWho = r.resultWho;
882 final int requestCode = r.requestCode;
883 r.resultTo = null;
884 if (resultTo != null) {
885 resultTo.removeResultsLocked(r, resultWho, requestCode);
886 }
887
888 final long origId = Binder.clearCallingIdentity();
889 // TODO(b/64750076): Check if calling pid should really be -1.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700890 final int res = getActivityStartController()
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700891 .obtainStarter(intent, "startNextMatchingActivity")
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700892 .setCaller(r.app.getThread())
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700893 .setResolvedType(r.resolvedType)
894 .setActivityInfo(aInfo)
895 .setResultTo(resultTo != null ? resultTo.appToken : null)
896 .setResultWho(resultWho)
897 .setRequestCode(requestCode)
898 .setCallingPid(-1)
899 .setCallingUid(r.launchedFromUid)
900 .setCallingPackage(r.launchedFromPackage)
901 .setRealCallingPid(-1)
902 .setRealCallingUid(r.launchedFromUid)
903 .setActivityOptions(options)
904 .execute();
905 Binder.restoreCallingIdentity(origId);
906
907 r.finishing = wasFinishing;
908 if (res != ActivityManager.START_SUCCESS) {
909 return false;
910 }
911 return true;
912 }
913 }
914
915 @Override
916 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
917 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
918 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
919 final WaitResult res = new WaitResult();
920 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700921 enforceNotIsolatedCaller("startActivityAndWait");
922 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
923 userId, "startActivityAndWait");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700924 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700925 getActivityStartController().obtainStarter(intent, "startActivityAndWait")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700926 .setCaller(caller)
927 .setCallingPackage(callingPackage)
928 .setResolvedType(resolvedType)
929 .setResultTo(resultTo)
930 .setResultWho(resultWho)
931 .setRequestCode(requestCode)
932 .setStartFlags(startFlags)
933 .setActivityOptions(bOptions)
934 .setMayWait(userId)
935 .setProfilerInfo(profilerInfo)
936 .setWaitResult(res)
937 .execute();
938 }
939 return res;
940 }
941
942 @Override
943 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
944 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
945 int startFlags, Configuration config, Bundle bOptions, int userId) {
946 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700947 enforceNotIsolatedCaller("startActivityWithConfig");
948 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
949 "startActivityWithConfig");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700950 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -0700951 return getActivityStartController().obtainStarter(intent, "startActivityWithConfig")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700952 .setCaller(caller)
953 .setCallingPackage(callingPackage)
954 .setResolvedType(resolvedType)
955 .setResultTo(resultTo)
956 .setResultWho(resultWho)
957 .setRequestCode(requestCode)
958 .setStartFlags(startFlags)
959 .setGlobalConfiguration(config)
960 .setActivityOptions(bOptions)
961 .setMayWait(userId)
962 .execute();
963 }
964 }
965
966 @Override
967 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
968 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
969 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
970 int userId) {
971
972 // This is very dangerous -- it allows you to perform a start activity (including
973 // permission grants) as any app that may launch one of your own activities. So
974 // we will only allow this to be done from activities that are part of the core framework,
975 // and then only when they are running as the system.
976 final ActivityRecord sourceRecord;
977 final int targetUid;
978 final String targetPackage;
979 final boolean isResolver;
980 synchronized (mGlobalLock) {
981 if (resultTo == null) {
982 throw new SecurityException("Must be called from an activity");
983 }
984 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
985 if (sourceRecord == null) {
986 throw new SecurityException("Called with bad activity token: " + resultTo);
987 }
988 if (!sourceRecord.info.packageName.equals("android")) {
989 throw new SecurityException(
990 "Must be called from an activity that is declared in the android package");
991 }
992 if (sourceRecord.app == null) {
993 throw new SecurityException("Called without a process attached to activity");
994 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700995 if (UserHandle.getAppId(sourceRecord.app.mUid) != SYSTEM_UID) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700996 // This is still okay, as long as this activity is running under the
997 // uid of the original calling activity.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700998 if (sourceRecord.app.mUid != sourceRecord.launchedFromUid) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700999 throw new SecurityException(
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001000 "Calling activity in uid " + sourceRecord.app.mUid
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001001 + " must be system uid or original calling uid "
1002 + sourceRecord.launchedFromUid);
1003 }
1004 }
1005 if (ignoreTargetSecurity) {
1006 if (intent.getComponent() == null) {
1007 throw new SecurityException(
1008 "Component must be specified with ignoreTargetSecurity");
1009 }
1010 if (intent.getSelector() != null) {
1011 throw new SecurityException(
1012 "Selector not allowed with ignoreTargetSecurity");
1013 }
1014 }
1015 targetUid = sourceRecord.launchedFromUid;
1016 targetPackage = sourceRecord.launchedFromPackage;
1017 isResolver = sourceRecord.isResolverOrChildActivity();
1018 }
1019
1020 if (userId == UserHandle.USER_NULL) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001021 userId = UserHandle.getUserId(sourceRecord.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001022 }
1023
1024 // TODO: Switch to user app stacks here.
1025 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001026 return getActivityStartController().obtainStarter(intent, "startActivityAsCaller")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001027 .setCallingUid(targetUid)
1028 .setCallingPackage(targetPackage)
1029 .setResolvedType(resolvedType)
1030 .setResultTo(resultTo)
1031 .setResultWho(resultWho)
1032 .setRequestCode(requestCode)
1033 .setStartFlags(startFlags)
1034 .setActivityOptions(bOptions)
1035 .setMayWait(userId)
1036 .setIgnoreTargetSecurity(ignoreTargetSecurity)
1037 .setFilterCallingUid(isResolver ? 0 /* system */ : targetUid)
1038 .execute();
1039 } catch (SecurityException e) {
1040 // XXX need to figure out how to propagate to original app.
1041 // A SecurityException here is generally actually a fault of the original
1042 // calling activity (such as a fairly granting permissions), so propagate it
1043 // back to them.
1044 /*
1045 StringBuilder msg = new StringBuilder();
1046 msg.append("While launching");
1047 msg.append(intent.toString());
1048 msg.append(": ");
1049 msg.append(e.getMessage());
1050 */
1051 throw e;
1052 }
1053 }
1054
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001055 int handleIncomingUser(int callingPid, int callingUid, int userId, String name) {
1056 return mAmInternal.handleIncomingUser(callingPid, callingUid, userId, false /* allowAll */,
1057 ALLOW_FULL_ONLY, name, null /* callerPackage */);
1058 }
1059
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001060 @Override
1061 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
1062 Intent intent, String resolvedType, IVoiceInteractionSession session,
1063 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
1064 Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001065 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001066 if (session == null || interactor == null) {
1067 throw new NullPointerException("null session or interactor");
1068 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001069 userId = handleIncomingUser(callingPid, callingUid, userId, "startVoiceActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001070 // TODO: Switch to user app stacks here.
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001071 return getActivityStartController().obtainStarter(intent, "startVoiceActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001072 .setCallingUid(callingUid)
1073 .setCallingPackage(callingPackage)
1074 .setResolvedType(resolvedType)
1075 .setVoiceSession(session)
1076 .setVoiceInteractor(interactor)
1077 .setStartFlags(startFlags)
1078 .setProfilerInfo(profilerInfo)
1079 .setActivityOptions(bOptions)
1080 .setMayWait(userId)
1081 .execute();
1082 }
1083
1084 @Override
1085 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
1086 Intent intent, String resolvedType, Bundle bOptions, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001087 mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
1088 userId = handleIncomingUser(callingPid, callingUid, userId, "startAssistantActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001089
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07001090 return getActivityStartController().obtainStarter(intent, "startAssistantActivity")
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001091 .setCallingUid(callingUid)
1092 .setCallingPackage(callingPackage)
1093 .setResolvedType(resolvedType)
1094 .setActivityOptions(bOptions)
1095 .setMayWait(userId)
1096 .execute();
1097 }
1098
1099 @Override
1100 public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
1101 IRecentsAnimationRunner recentsAnimationRunner) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001102 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001103 final int callingPid = Binder.getCallingPid();
1104 final long origId = Binder.clearCallingIdentity();
1105 try {
1106 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07001107 final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
1108 final int recentsUid = mRecentTasks.getRecentsComponentUid();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001109
1110 // Start a new recents animation
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001111 final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
1112 getActivityStartController(), mWindowManager, callingPid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001113 anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
1114 recentsUid, assistDataReceiver);
1115 }
1116 } finally {
1117 Binder.restoreCallingIdentity(origId);
1118 }
1119 }
1120
1121 @Override
1122 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001123 enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001124 "startActivityFromRecents()");
1125
1126 final int callingPid = Binder.getCallingPid();
1127 final int callingUid = Binder.getCallingUid();
1128 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(bOptions);
1129 final long origId = Binder.clearCallingIdentity();
1130 try {
1131 synchronized (mGlobalLock) {
1132 return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
1133 safeOptions);
1134 }
1135 } finally {
1136 Binder.restoreCallingIdentity(origId);
1137 }
1138 }
1139
1140 /**
1141 * This is the internal entry point for handling Activity.finish().
1142 *
1143 * @param token The Binder token referencing the Activity we want to finish.
1144 * @param resultCode Result code, if any, from this Activity.
1145 * @param resultData Result data (Intent), if any, from this Activity.
1146 * @param finishTask Whether to finish the task associated with this Activity.
1147 *
1148 * @return Returns true if the activity successfully finished, or false if it is still running.
1149 */
1150 @Override
1151 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
1152 int finishTask) {
1153 // Refuse possible leaked file descriptors
1154 if (resultData != null && resultData.hasFileDescriptors()) {
1155 throw new IllegalArgumentException("File descriptors passed in Intent");
1156 }
1157
1158 synchronized (mGlobalLock) {
1159 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1160 if (r == null) {
1161 return true;
1162 }
1163 // Keep track of the root activity of the task before we finish it
1164 TaskRecord tr = r.getTask();
1165 ActivityRecord rootR = tr.getRootActivity();
1166 if (rootR == null) {
1167 Slog.w(TAG, "Finishing task with all activities already finished");
1168 }
1169 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
1170 // finish.
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001171 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001172 return false;
1173 }
1174
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001175 // TODO: There is a dup. of this block of code in ActivityStack.navigateUpToLocked
1176 // We should consolidate.
1177 if (mController != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001178 // Find the first activity that is not finishing.
1179 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
1180 if (next != null) {
1181 // ask watcher if this is allowed
1182 boolean resumeOK = true;
1183 try {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001184 resumeOK = mController.activityResuming(next.packageName);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001185 } catch (RemoteException e) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001186 mController = null;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001187 Watchdog.getInstance().setActivityController(null);
1188 }
1189
1190 if (!resumeOK) {
1191 Slog.i(TAG, "Not finishing activity because controller resumed");
1192 return false;
1193 }
1194 }
1195 }
1196 final long origId = Binder.clearCallingIdentity();
1197 try {
1198 boolean res;
1199 final boolean finishWithRootActivity =
1200 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
1201 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
1202 || (finishWithRootActivity && r == rootR)) {
1203 // If requested, remove the task that is associated to this activity only if it
1204 // was the root activity in the task. The result code and data is ignored
1205 // because we don't support returning them across task boundaries. Also, to
1206 // keep backwards compatibility we remove the task from recents when finishing
1207 // task with root activity.
1208 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
1209 finishWithRootActivity, "finish-activity");
1210 if (!res) {
1211 Slog.i(TAG, "Removing task failed to finish activity");
1212 }
Garfield Tan2746ab52018-07-25 12:33:01 -07001213 // Explicitly dismissing the activity so reset its relaunch flag.
1214 r.mRelaunchReason = ActivityRecord.RELAUNCH_REASON_NONE;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001215 } else {
1216 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
1217 resultData, "app-request", true);
1218 if (!res) {
1219 Slog.i(TAG, "Failed to finish by app-request");
1220 }
1221 }
1222 return res;
1223 } finally {
1224 Binder.restoreCallingIdentity(origId);
1225 }
1226 }
1227 }
1228
1229 @Override
1230 public boolean finishActivityAffinity(IBinder token) {
1231 synchronized (mGlobalLock) {
1232 final long origId = Binder.clearCallingIdentity();
1233 try {
1234 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1235 if (r == null) {
1236 return false;
1237 }
1238
1239 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
1240 // can finish.
1241 final TaskRecord task = r.getTask();
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001242 if (getLockTaskController().activityBlockedFromFinish(r)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001243 return false;
1244 }
1245 return task.getStack().finishActivityAffinityLocked(r);
1246 } finally {
1247 Binder.restoreCallingIdentity(origId);
1248 }
1249 }
1250 }
1251
1252 @Override
1253 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
1254 final long origId = Binder.clearCallingIdentity();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001255 try {
1256 WindowProcessController proc = null;
1257 synchronized (mGlobalLock) {
1258 ActivityStack stack = ActivityRecord.getStackLocked(token);
1259 if (stack == null) {
1260 return;
1261 }
1262 final ActivityRecord r = mStackSupervisor.activityIdleInternalLocked(token,
1263 false /* fromTimeout */, false /* processPausingActivities */, config);
1264 if (r != null) {
1265 proc = r.app;
1266 }
1267 if (stopProfiling && proc != null) {
1268 proc.clearProfilerIfNeeded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001269 }
1270 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001271 } finally {
1272 Binder.restoreCallingIdentity(origId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001273 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001274 }
1275
1276 @Override
1277 public final void activityResumed(IBinder token) {
1278 final long origId = Binder.clearCallingIdentity();
1279 synchronized (mGlobalLock) {
1280 ActivityRecord.activityResumedLocked(token);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001281 mWindowManager.notifyAppResumedFinished(token);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001282 }
1283 Binder.restoreCallingIdentity(origId);
1284 }
1285
1286 @Override
1287 public final void activityPaused(IBinder token) {
1288 final long origId = Binder.clearCallingIdentity();
1289 synchronized (mGlobalLock) {
1290 ActivityStack stack = ActivityRecord.getStackLocked(token);
1291 if (stack != null) {
1292 stack.activityPausedLocked(token, false);
1293 }
1294 }
1295 Binder.restoreCallingIdentity(origId);
1296 }
1297
1298 @Override
1299 public final void activityStopped(IBinder token, Bundle icicle,
1300 PersistableBundle persistentState, CharSequence description) {
1301 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
1302
1303 // Refuse possible leaked file descriptors
1304 if (icicle != null && icicle.hasFileDescriptors()) {
1305 throw new IllegalArgumentException("File descriptors passed in Bundle");
1306 }
1307
1308 final long origId = Binder.clearCallingIdentity();
1309
1310 synchronized (mGlobalLock) {
1311 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1312 if (r != null) {
1313 r.activityStoppedLocked(icicle, persistentState, description);
1314 }
1315 }
1316
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001317 mAmInternal.trimApplications();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001318
1319 Binder.restoreCallingIdentity(origId);
1320 }
1321
1322 @Override
1323 public final void activityDestroyed(IBinder token) {
1324 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
1325 synchronized (mGlobalLock) {
1326 ActivityStack stack = ActivityRecord.getStackLocked(token);
1327 if (stack != null) {
1328 stack.activityDestroyedLocked(token, "activityDestroyed");
1329 }
1330 }
1331 }
1332
1333 @Override
1334 public final void activityRelaunched(IBinder token) {
1335 final long origId = Binder.clearCallingIdentity();
1336 synchronized (mGlobalLock) {
1337 mStackSupervisor.activityRelaunchedLocked(token);
1338 }
1339 Binder.restoreCallingIdentity(origId);
1340 }
1341
1342 public final void activitySlept(IBinder token) {
1343 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
1344
1345 final long origId = Binder.clearCallingIdentity();
1346
1347 synchronized (mGlobalLock) {
1348 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1349 if (r != null) {
1350 mStackSupervisor.activitySleptLocked(r);
1351 }
1352 }
1353
1354 Binder.restoreCallingIdentity(origId);
1355 }
1356
1357 @Override
1358 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
1359 synchronized (mGlobalLock) {
1360 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1361 if (r == null) {
1362 return;
1363 }
1364 final long origId = Binder.clearCallingIdentity();
1365 try {
1366 r.setRequestedOrientation(requestedOrientation);
1367 } finally {
1368 Binder.restoreCallingIdentity(origId);
1369 }
1370 }
1371 }
1372
1373 @Override
1374 public int getRequestedOrientation(IBinder token) {
1375 synchronized (mGlobalLock) {
1376 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1377 if (r == null) {
1378 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
1379 }
1380 return r.getRequestedOrientation();
1381 }
1382 }
1383
1384 @Override
1385 public void setImmersive(IBinder token, boolean immersive) {
1386 synchronized (mGlobalLock) {
1387 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1388 if (r == null) {
1389 throw new IllegalArgumentException();
1390 }
1391 r.immersive = immersive;
1392
1393 // update associated state if we're frontmost
Andrii Kulian52d255c2018-07-13 11:32:19 -07001394 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001395 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001396 applyUpdateLockStateLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001397 }
1398 }
1399 }
1400
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001401 void applyUpdateLockStateLocked(ActivityRecord r) {
1402 // Modifications to the UpdateLock state are done on our handler, outside
1403 // the activity manager's locks. The new state is determined based on the
1404 // state *now* of the relevant activity record. The object is passed to
1405 // the handler solely for logging detail, not to be consulted/modified.
1406 final boolean nextState = r != null && r.immersive;
1407 mH.post(() -> {
1408 if (mUpdateLock.isHeld() != nextState) {
1409 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1410 "Applying new update lock state '" + nextState + "' for " + r);
1411 if (nextState) {
1412 mUpdateLock.acquire();
1413 } else {
1414 mUpdateLock.release();
1415 }
1416 }
1417 });
1418 }
1419
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001420 @Override
1421 public boolean isImmersive(IBinder token) {
1422 synchronized (mGlobalLock) {
1423 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1424 if (r == null) {
1425 throw new IllegalArgumentException();
1426 }
1427 return r.immersive;
1428 }
1429 }
1430
1431 @Override
1432 public boolean isTopActivityImmersive() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001433 enforceNotIsolatedCaller("isTopActivityImmersive");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001434 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001435 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001436 return (r != null) ? r.immersive : false;
1437 }
1438 }
1439
1440 @Override
1441 public void overridePendingTransition(IBinder token, String packageName,
1442 int enterAnim, int exitAnim) {
1443 synchronized (mGlobalLock) {
1444 ActivityRecord self = ActivityRecord.isInStackLocked(token);
1445 if (self == null) {
1446 return;
1447 }
1448
1449 final long origId = Binder.clearCallingIdentity();
1450
1451 if (self.isState(
1452 ActivityStack.ActivityState.RESUMED, ActivityStack.ActivityState.PAUSING)) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001453 mWindowManager.overridePendingAppTransition(packageName,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001454 enterAnim, exitAnim, null);
1455 }
1456
1457 Binder.restoreCallingIdentity(origId);
1458 }
1459 }
1460
1461 @Override
1462 public int getFrontActivityScreenCompatMode() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001463 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
1464 ApplicationInfo ai;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001465 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001466 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001467 if (r == null) {
1468 return ActivityManager.COMPAT_MODE_UNKNOWN;
1469 }
1470 ai = r.info.applicationInfo;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001471 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001472
1473 return mAmInternal.getPackageScreenCompatMode(ai);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001474 }
1475
1476 @Override
1477 public void setFrontActivityScreenCompatMode(int mode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001478 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001479 "setFrontActivityScreenCompatMode");
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001480 ApplicationInfo ai;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001481 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001482 final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001483 if (r == null) {
1484 Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity");
1485 return;
1486 }
1487 ai = r.info.applicationInfo;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001488 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001489
1490 mAmInternal.setPackageScreenCompatMode(ai, mode);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001491 }
1492
1493 @Override
1494 public int getLaunchedFromUid(IBinder activityToken) {
1495 ActivityRecord srec;
1496 synchronized (mGlobalLock) {
1497 srec = ActivityRecord.forTokenLocked(activityToken);
1498 }
1499 if (srec == null) {
1500 return -1;
1501 }
1502 return srec.launchedFromUid;
1503 }
1504
1505 @Override
1506 public String getLaunchedFromPackage(IBinder activityToken) {
1507 ActivityRecord srec;
1508 synchronized (mGlobalLock) {
1509 srec = ActivityRecord.forTokenLocked(activityToken);
1510 }
1511 if (srec == null) {
1512 return null;
1513 }
1514 return srec.launchedFromPackage;
1515 }
1516
1517 @Override
1518 public boolean convertFromTranslucent(IBinder token) {
1519 final long origId = Binder.clearCallingIdentity();
1520 try {
1521 synchronized (mGlobalLock) {
1522 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1523 if (r == null) {
1524 return false;
1525 }
1526 final boolean translucentChanged = r.changeWindowTranslucency(true);
1527 if (translucentChanged) {
1528 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
1529 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001530 mWindowManager.setAppFullscreen(token, true);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001531 return translucentChanged;
1532 }
1533 } finally {
1534 Binder.restoreCallingIdentity(origId);
1535 }
1536 }
1537
1538 @Override
1539 public boolean convertToTranslucent(IBinder token, Bundle options) {
1540 SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
1541 final long origId = Binder.clearCallingIdentity();
1542 try {
1543 synchronized (mGlobalLock) {
1544 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
1545 if (r == null) {
1546 return false;
1547 }
1548 final TaskRecord task = r.getTask();
1549 int index = task.mActivities.lastIndexOf(r);
1550 if (index > 0) {
1551 ActivityRecord under = task.mActivities.get(index - 1);
1552 under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
1553 }
1554 final boolean translucentChanged = r.changeWindowTranslucency(false);
1555 if (translucentChanged) {
1556 r.getStack().convertActivityToTranslucent(r);
1557 }
1558 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001559 mWindowManager.setAppFullscreen(token, false);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001560 return translucentChanged;
1561 }
1562 } finally {
1563 Binder.restoreCallingIdentity(origId);
1564 }
1565 }
1566
1567 @Override
1568 public void notifyActivityDrawn(IBinder token) {
1569 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
1570 synchronized (mGlobalLock) {
1571 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
1572 if (r != null) {
1573 r.getStack().notifyActivityDrawnLocked(r);
1574 }
1575 }
1576 }
1577
1578 @Override
1579 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
1580 synchronized (mGlobalLock) {
1581 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1582 if (r == null) {
1583 return;
1584 }
1585 r.reportFullyDrawnLocked(restoredFromBundle);
1586 }
1587 }
1588
1589 @Override
1590 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
1591 synchronized (mGlobalLock) {
1592 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
1593 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
1594 return stack.mDisplayId;
1595 }
1596 return DEFAULT_DISPLAY;
1597 }
1598 }
1599
1600 @Override
1601 public ActivityManager.StackInfo getFocusedStackInfo() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001602 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001603 long ident = Binder.clearCallingIdentity();
1604 try {
1605 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001606 ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001607 if (focusedStack != null) {
1608 return mStackSupervisor.getStackInfo(focusedStack.mStackId);
1609 }
1610 return null;
1611 }
1612 } finally {
1613 Binder.restoreCallingIdentity(ident);
1614 }
1615 }
1616
1617 @Override
1618 public void setFocusedStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001619 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001620 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
1621 final long callingId = Binder.clearCallingIdentity();
1622 try {
1623 synchronized (mGlobalLock) {
1624 final ActivityStack stack = mStackSupervisor.getStack(stackId);
1625 if (stack == null) {
1626 Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
1627 return;
1628 }
1629 final ActivityRecord r = stack.topRunningActivityLocked();
1630 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
1631 r, "setFocusedStack")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08001632 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001633 }
1634 }
1635 } finally {
1636 Binder.restoreCallingIdentity(callingId);
1637 }
1638 }
1639
1640 @Override
1641 public void setFocusedTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001642 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001643 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
1644 final long callingId = Binder.clearCallingIdentity();
1645 try {
1646 synchronized (mGlobalLock) {
1647 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1648 if (task == null) {
1649 return;
1650 }
1651 final ActivityRecord r = task.topRunningActivityLocked();
1652 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08001653 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001654 }
1655 }
1656 } finally {
1657 Binder.restoreCallingIdentity(callingId);
1658 }
1659 }
1660
1661 @Override
1662 public boolean removeTask(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001663 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001664 synchronized (mGlobalLock) {
1665 final long ident = Binder.clearCallingIdentity();
1666 try {
1667 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
1668 "remove-task");
1669 } finally {
1670 Binder.restoreCallingIdentity(ident);
1671 }
1672 }
1673 }
1674
1675 @Override
Winson Chunge6439102018-07-30 15:48:01 -07001676 public void removeAllVisibleRecentTasks() {
1677 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeAllVisibleRecentTasks()");
1678 synchronized (mGlobalLock) {
1679 final long ident = Binder.clearCallingIdentity();
1680 try {
1681 getRecentTasks().removeAllVisibleTasks();
1682 } finally {
1683 Binder.restoreCallingIdentity(ident);
1684 }
1685 }
1686 }
1687
1688 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001689 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
1690 synchronized (mGlobalLock) {
1691 final ActivityRecord srec = ActivityRecord.forTokenLocked(token);
1692 if (srec != null) {
1693 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
1694 }
1695 }
1696 return false;
1697 }
1698
1699 @Override
1700 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
1701 Intent resultData) {
1702
1703 synchronized (mGlobalLock) {
1704 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
1705 if (r != null) {
1706 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
1707 }
1708 return false;
1709 }
1710 }
1711
1712 /**
1713 * Attempts to move a task backwards in z-order (the order of activities within the task is
1714 * unchanged).
1715 *
1716 * There are several possible results of this call:
1717 * - if the task is locked, then we will show the lock toast
1718 * - if there is a task behind the provided task, then that task is made visible and resumed as
1719 * this task is moved to the back
1720 * - otherwise, if there are no other tasks in the stack:
1721 * - if this task is in the pinned stack, then we remove the stack completely, which will
1722 * have the effect of moving the task to the top or bottom of the fullscreen stack
1723 * (depending on whether it is visible)
1724 * - otherwise, we simply return home and hide this task
1725 *
1726 * @param token A reference to the activity we wish to move
1727 * @param nonRoot If false then this only works if the activity is the root
1728 * of a task; if true it will work for any activity in a task.
1729 * @return Returns true if the move completed, false if not.
1730 */
1731 @Override
1732 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001733 enforceNotIsolatedCaller("moveActivityTaskToBack");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001734 synchronized (mGlobalLock) {
1735 final long origId = Binder.clearCallingIdentity();
1736 try {
1737 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
1738 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1739 if (task != null) {
1740 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
1741 }
1742 } finally {
1743 Binder.restoreCallingIdentity(origId);
1744 }
1745 }
1746 return false;
1747 }
1748
1749 @Override
1750 public Rect getTaskBounds(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001751 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001752 long ident = Binder.clearCallingIdentity();
1753 Rect rect = new Rect();
1754 try {
1755 synchronized (mGlobalLock) {
1756 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
1757 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1758 if (task == null) {
1759 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
1760 return rect;
1761 }
1762 if (task.getStack() != null) {
1763 // Return the bounds from window manager since it will be adjusted for various
1764 // things like the presense of a docked stack for tasks that aren't resizeable.
1765 task.getWindowContainerBounds(rect);
1766 } else {
1767 // Task isn't in window manager yet since it isn't associated with a stack.
1768 // Return the persist value from activity manager
1769 if (!task.matchParentBounds()) {
1770 rect.set(task.getBounds());
1771 } else if (task.mLastNonFullscreenBounds != null) {
1772 rect.set(task.mLastNonFullscreenBounds);
1773 }
1774 }
1775 }
1776 } finally {
1777 Binder.restoreCallingIdentity(ident);
1778 }
1779 return rect;
1780 }
1781
1782 @Override
1783 public ActivityManager.TaskDescription getTaskDescription(int id) {
1784 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001785 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001786 MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
1787 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
1788 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
1789 if (tr != null) {
1790 return tr.lastTaskDescription;
1791 }
1792 }
1793 return null;
1794 }
1795
1796 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001797 public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
1798 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
1799 setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
1800 toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
1801 return;
1802 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001803 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001804 synchronized (mGlobalLock) {
1805 final long ident = Binder.clearCallingIdentity();
1806 try {
1807 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1808 if (task == null) {
1809 Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
1810 return;
1811 }
1812
1813 if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
1814 + " to windowingMode=" + windowingMode + " toTop=" + toTop);
1815
1816 if (!task.isActivityTypeStandardOrUndefined()) {
1817 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
1818 + " non-standard task " + taskId + " to windowing mode="
1819 + windowingMode);
1820 }
1821
1822 final ActivityStack stack = task.getStack();
1823 if (toTop) {
1824 stack.moveToFront("setTaskWindowingMode", task);
1825 }
1826 stack.setWindowingMode(windowingMode);
1827 } finally {
1828 Binder.restoreCallingIdentity(ident);
1829 }
1830 }
1831 }
1832
1833 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001834 public String getCallingPackage(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001835 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001836 ActivityRecord r = getCallingRecordLocked(token);
1837 return r != null ? r.info.packageName : null;
1838 }
1839 }
1840
1841 @Override
1842 public ComponentName getCallingActivity(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001843 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001844 ActivityRecord r = getCallingRecordLocked(token);
1845 return r != null ? r.intent.getComponent() : null;
1846 }
1847 }
1848
1849 private ActivityRecord getCallingRecordLocked(IBinder token) {
1850 ActivityRecord r = ActivityRecord.isInStackLocked(token);
1851 if (r == null) {
1852 return null;
1853 }
1854 return r.resultTo;
1855 }
1856
1857 @Override
1858 public void unhandledBack() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001859 mAmInternal.enforceCallingPermission(android.Manifest.permission.FORCE_BACK, "unhandledBack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001860
1861 synchronized (mGlobalLock) {
1862 final long origId = Binder.clearCallingIdentity();
1863 try {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001864 getTopDisplayFocusedStack().unhandledBackLocked();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001865 } finally {
1866 Binder.restoreCallingIdentity(origId);
1867 }
1868 }
1869 }
1870
1871 /**
1872 * TODO: Add mController hook
1873 */
1874 @Override
1875 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001876 mAmInternal.enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001877
1878 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
1879 synchronized (mGlobalLock) {
1880 moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
1881 false /* fromRecents */);
1882 }
1883 }
1884
1885 void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
1886 boolean fromRecents) {
1887
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001888 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001889 Binder.getCallingUid(), -1, -1, "Task to front")) {
1890 SafeActivityOptions.abort(options);
1891 return;
1892 }
1893 final long origId = Binder.clearCallingIdentity();
1894 try {
1895 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
1896 if (task == null) {
1897 Slog.d(TAG, "Could not find task for id: "+ taskId);
1898 return;
1899 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07001900 if (getLockTaskController().isLockTaskModeViolation(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001901 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
1902 return;
1903 }
1904 ActivityOptions realOptions = options != null
1905 ? options.getOptions(mStackSupervisor)
1906 : null;
1907 mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
1908 false /* forceNonResizable */);
1909
1910 final ActivityRecord topActivity = task.getTopActivity();
1911 if (topActivity != null) {
1912
1913 // We are reshowing a task, use a starting window to hide the initial draw delay
1914 // so the transition can start earlier.
1915 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
1916 true /* taskSwitch */, fromRecents);
1917 }
1918 } finally {
1919 Binder.restoreCallingIdentity(origId);
1920 }
1921 SafeActivityOptions.abort(options);
1922 }
1923
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001924 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
1925 int callingPid, int callingUid, String name) {
1926 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
1927 return true;
1928 }
1929
1930 if (getRecentTasks().isCallerRecents(sourceUid)) {
1931 return true;
1932 }
1933
1934 int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
1935 if (perm == PackageManager.PERMISSION_GRANTED) {
1936 return true;
1937 }
1938 if (checkAllowAppSwitchUid(sourceUid)) {
1939 return true;
1940 }
1941
1942 // If the actual IPC caller is different from the logical source, then
1943 // also see if they are allowed to control app switches.
1944 if (callingUid != -1 && callingUid != sourceUid) {
1945 perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
1946 if (perm == PackageManager.PERMISSION_GRANTED) {
1947 return true;
1948 }
1949 if (checkAllowAppSwitchUid(callingUid)) {
1950 return true;
1951 }
1952 }
1953
1954 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
1955 return false;
1956 }
1957
1958 private boolean checkAllowAppSwitchUid(int uid) {
1959 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
1960 if (types != null) {
1961 for (int i = types.size() - 1; i >= 0; i--) {
1962 if (types.valueAt(i).intValue() == uid) {
1963 return true;
1964 }
1965 }
1966 }
1967 return false;
1968 }
1969
1970 @Override
1971 public void setActivityController(IActivityController controller, boolean imAMonkey) {
1972 mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
1973 "setActivityController()");
1974 synchronized (mGlobalLock) {
1975 mController = controller;
1976 mControllerIsAMonkey = imAMonkey;
1977 Watchdog.getInstance().setActivityController(controller);
1978 }
1979 }
1980
1981 boolean isControllerAMonkey() {
1982 synchronized (mGlobalLock) {
1983 return mController != null && mControllerIsAMonkey;
1984 }
1985 }
1986
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07001987 @Override
1988 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
1989 synchronized (mGlobalLock) {
1990 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
1991 }
1992 }
1993
1994 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07001995 public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum) {
1996 return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
1997 }
1998
1999 @Override
2000 public List<ActivityManager.RunningTaskInfo> getFilteredTasks(int maxNum,
2001 @WindowConfiguration.ActivityType int ignoreActivityType,
2002 @WindowConfiguration.WindowingMode int ignoreWindowingMode) {
2003 final int callingUid = Binder.getCallingUid();
2004 ArrayList<ActivityManager.RunningTaskInfo> list = new ArrayList<>();
2005
2006 synchronized (mGlobalLock) {
2007 if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
2008
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002009 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002010 callingUid);
2011 mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
2012 ignoreWindowingMode, callingUid, allowed);
2013 }
2014
2015 return list;
2016 }
2017
2018 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002019 public final void finishSubActivity(IBinder token, String resultWho, int requestCode) {
2020 synchronized (mGlobalLock) {
2021 final long origId = Binder.clearCallingIdentity();
2022 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2023 if (r != null) {
2024 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
2025 }
2026 Binder.restoreCallingIdentity(origId);
2027 }
2028 }
2029
2030 @Override
2031 public boolean willActivityBeVisible(IBinder token) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002032 synchronized (mGlobalLock) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002033 ActivityStack stack = ActivityRecord.getStackLocked(token);
2034 if (stack != null) {
2035 return stack.willActivityBeVisibleLocked(token);
2036 }
2037 return false;
2038 }
2039 }
2040
2041 @Override
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002042 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002043 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002044 synchronized (mGlobalLock) {
2045 final long ident = Binder.clearCallingIdentity();
2046 try {
2047 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2048 if (task == null) {
2049 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
2050 return;
2051 }
2052
2053 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
2054 + " to stackId=" + stackId + " toTop=" + toTop);
2055
2056 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2057 if (stack == null) {
2058 throw new IllegalStateException(
2059 "moveTaskToStack: No stack for stackId=" + stackId);
2060 }
2061 if (!stack.isActivityTypeStandardOrUndefined()) {
2062 throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
2063 + taskId + " to stack " + stackId);
2064 }
2065 if (stack.inSplitScreenPrimaryWindowingMode()) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002066 mWindowManager.setDockedStackCreateState(
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002067 SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
2068 }
2069 task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
2070 "moveTaskToStack");
2071 } finally {
2072 Binder.restoreCallingIdentity(ident);
2073 }
2074 }
2075 }
2076
2077 @Override
2078 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
2079 boolean preserveWindows, boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002080 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002081
2082 final long ident = Binder.clearCallingIdentity();
2083 try {
2084 synchronized (mGlobalLock) {
2085 if (animate) {
2086 final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
2087 if (stack == null) {
2088 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2089 return;
2090 }
2091 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
2092 throw new IllegalArgumentException("Stack: " + stackId
2093 + " doesn't support animated resize.");
2094 }
2095 stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
2096 animationDuration, false /* fromFullscreen */);
2097 } else {
2098 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2099 if (stack == null) {
2100 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2101 return;
2102 }
2103 mStackSupervisor.resizeStackLocked(stack, destBounds,
2104 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
2105 preserveWindows, allowResizeInDockedMode, !DEFER_RESUME);
2106 }
2107 }
2108 } finally {
2109 Binder.restoreCallingIdentity(ident);
2110 }
2111 }
2112
2113 /**
2114 * Moves the specified task to the primary-split-screen stack.
2115 *
2116 * @param taskId Id of task to move.
2117 * @param createMode The mode the primary split screen stack should be created in if it doesn't
2118 * exist already. See
2119 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
2120 * and
2121 * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
2122 * @param toTop If the task and stack should be moved to the top.
2123 * @param animate Whether we should play an animation for the moving the task.
2124 * @param initialBounds If the primary stack gets created, it will use these bounds for the
2125 * stack. Pass {@code null} to use default bounds.
2126 * @param showRecents If the recents activity should be shown on the other side of the task
2127 * going into split-screen mode.
2128 */
2129 @Override
2130 public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode,
2131 boolean toTop, boolean animate, Rect initialBounds, boolean showRecents) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002132 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002133 "setTaskWindowingModeSplitScreenPrimary()");
2134 synchronized (mGlobalLock) {
2135 final long ident = Binder.clearCallingIdentity();
2136 try {
2137 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2138 if (task == null) {
2139 Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
2140 return false;
2141 }
2142 if (DEBUG_STACK) Slog.d(TAG_STACK,
2143 "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
2144 + " to createMode=" + createMode + " toTop=" + toTop);
2145 if (!task.isActivityTypeStandardOrUndefined()) {
2146 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
2147 + " non-standard task " + taskId + " to split-screen windowing mode");
2148 }
2149
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002150 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002151 final int windowingMode = task.getWindowingMode();
2152 final ActivityStack stack = task.getStack();
2153 if (toTop) {
2154 stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
2155 }
2156 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
2157 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */);
2158 return windowingMode != task.getWindowingMode();
2159 } finally {
2160 Binder.restoreCallingIdentity(ident);
2161 }
2162 }
2163 }
2164
2165 /**
2166 * Removes stacks in the input windowing modes from the system if they are of activity type
2167 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
2168 */
2169 @Override
2170 public void removeStacksInWindowingModes(int[] windowingModes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002171 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002172 "removeStacksInWindowingModes()");
2173
2174 synchronized (mGlobalLock) {
2175 final long ident = Binder.clearCallingIdentity();
2176 try {
2177 mStackSupervisor.removeStacksInWindowingModes(windowingModes);
2178 } finally {
2179 Binder.restoreCallingIdentity(ident);
2180 }
2181 }
2182 }
2183
2184 @Override
2185 public void removeStacksWithActivityTypes(int[] activityTypes) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002186 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002187 "removeStacksWithActivityTypes()");
2188
2189 synchronized (mGlobalLock) {
2190 final long ident = Binder.clearCallingIdentity();
2191 try {
2192 mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
2193 } finally {
2194 Binder.restoreCallingIdentity(ident);
2195 }
2196 }
2197 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002198
2199 @Override
2200 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
2201 int userId) {
2202 final int callingUid = Binder.getCallingUid();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002203 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, "getRecentTasks");
2204 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002205 callingUid);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002206 final boolean detailed = checkGetTasksPermission(
2207 android.Manifest.permission.GET_DETAILED_TASKS, Binder.getCallingPid(),
2208 UserHandle.getAppId(callingUid))
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002209 == PackageManager.PERMISSION_GRANTED;
2210
2211 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002212 return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002213 callingUid);
2214 }
2215 }
2216
2217 @Override
2218 public List<ActivityManager.StackInfo> getAllStackInfos() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002219 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002220 long ident = Binder.clearCallingIdentity();
2221 try {
2222 synchronized (mGlobalLock) {
2223 return mStackSupervisor.getAllStackInfosLocked();
2224 }
2225 } finally {
2226 Binder.restoreCallingIdentity(ident);
2227 }
2228 }
2229
2230 @Override
2231 public ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002232 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002233 long ident = Binder.clearCallingIdentity();
2234 try {
2235 synchronized (mGlobalLock) {
2236 return mStackSupervisor.getStackInfo(windowingMode, activityType);
2237 }
2238 } finally {
2239 Binder.restoreCallingIdentity(ident);
2240 }
2241 }
2242
2243 @Override
2244 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002245 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002246 final long callingUid = Binder.getCallingUid();
2247 final long origId = Binder.clearCallingIdentity();
2248 try {
2249 synchronized (mGlobalLock) {
2250 // Cancel the recents animation synchronously (do not hold the WM lock)
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002251 mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002252 ? REORDER_MOVE_TO_ORIGINAL_POSITION
2253 : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
2254 }
2255 } finally {
2256 Binder.restoreCallingIdentity(origId);
2257 }
2258 }
2259
2260 @Override
2261 public void startLockTaskModeByToken(IBinder token) {
2262 synchronized (mGlobalLock) {
2263 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2264 if (r == null) {
2265 return;
2266 }
2267 startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
2268 }
2269 }
2270
2271 @Override
2272 public void startSystemLockTaskMode(int taskId) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002273 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002274 // This makes inner call to look as if it was initiated by system.
2275 long ident = Binder.clearCallingIdentity();
2276 try {
2277 synchronized (mGlobalLock) {
2278 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2279
2280 // When starting lock task mode the stack must be in front and focused
2281 task.getStack().moveToFront("startSystemLockTaskMode");
2282 startLockTaskModeLocked(task, true /* isSystemCaller */);
2283 }
2284 } finally {
2285 Binder.restoreCallingIdentity(ident);
2286 }
2287 }
2288
2289 @Override
2290 public void stopLockTaskModeByToken(IBinder token) {
2291 synchronized (mGlobalLock) {
2292 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2293 if (r == null) {
2294 return;
2295 }
2296 stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
2297 }
2298 }
2299
2300 /**
2301 * This API should be called by SystemUI only when user perform certain action to dismiss
2302 * lock task mode. We should only dismiss pinned lock task mode in this case.
2303 */
2304 @Override
2305 public void stopSystemLockTaskMode() throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002306 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002307 stopLockTaskModeInternal(null, true /* isSystemCaller */);
2308 }
2309
2310 private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
2311 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
2312 if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
2313 return;
2314 }
2315
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002316 final ActivityStack stack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002317 if (stack == null || task != stack.topTask()) {
2318 throw new IllegalArgumentException("Invalid task, not in foreground");
2319 }
2320
2321 // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
2322 // system or a specific app.
2323 // * System-initiated requests will only start the pinned mode (screen pinning)
2324 // * App-initiated requests
2325 // - will put the device in fully locked mode (LockTask), if the app is whitelisted
2326 // - will start the pinned mode, otherwise
2327 final int callingUid = Binder.getCallingUid();
2328 long ident = Binder.clearCallingIdentity();
2329 try {
2330 // When a task is locked, dismiss the pinned stack if it exists
2331 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2332
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002333 getLockTaskController().startLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002334 } finally {
2335 Binder.restoreCallingIdentity(ident);
2336 }
2337 }
2338
2339 private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
2340 final int callingUid = Binder.getCallingUid();
2341 long ident = Binder.clearCallingIdentity();
2342 try {
2343 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002344 getLockTaskController().stopLockTaskMode(task, isSystemCaller, callingUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002345 }
2346 // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
2347 // task and jumping straight into a call in the case of emergency call back.
2348 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
2349 if (tm != null) {
2350 tm.showInCallScreen(false);
2351 }
2352 } finally {
2353 Binder.restoreCallingIdentity(ident);
2354 }
2355 }
2356
2357 @Override
2358 public boolean isInLockTaskMode() {
2359 return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
2360 }
2361
2362 @Override
2363 public int getLockTaskModeState() {
2364 synchronized (mGlobalLock) {
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07002365 return getLockTaskController().getLockTaskModeState();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002366 }
2367 }
2368
2369 @Override
2370 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
2371 synchronized (mGlobalLock) {
2372 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2373 if (r != null) {
2374 r.setTaskDescription(td);
2375 final TaskRecord task = r.getTask();
2376 task.updateTaskDescription();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002377 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002378 }
2379 }
2380 }
2381
2382 @Override
2383 public Bundle getActivityOptions(IBinder token) {
2384 final long origId = Binder.clearCallingIdentity();
2385 try {
2386 synchronized (mGlobalLock) {
2387 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
2388 if (r != null) {
2389 final ActivityOptions activityOptions = r.takeOptionsLocked();
2390 return activityOptions == null ? null : activityOptions.toBundle();
2391 }
2392 return null;
2393 }
2394 } finally {
2395 Binder.restoreCallingIdentity(origId);
2396 }
2397 }
2398
2399 @Override
2400 public List<IBinder> getAppTasks(String callingPackage) {
2401 int callingUid = Binder.getCallingUid();
2402 long ident = Binder.clearCallingIdentity();
2403 try {
2404 synchronized (mGlobalLock) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002405 return mRecentTasks.getAppTasksList(callingUid, callingPackage);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002406 }
2407 } finally {
2408 Binder.restoreCallingIdentity(ident);
2409 }
2410 }
2411
2412 @Override
2413 public void finishVoiceTask(IVoiceInteractionSession session) {
2414 synchronized (mGlobalLock) {
2415 final long origId = Binder.clearCallingIdentity();
2416 try {
2417 // TODO: VI Consider treating local voice interactions and voice tasks
2418 // differently here
2419 mStackSupervisor.finishVoiceTask(session);
2420 } finally {
2421 Binder.restoreCallingIdentity(origId);
2422 }
2423 }
2424
2425 }
2426
2427 @Override
2428 public boolean isTopOfTask(IBinder token) {
2429 synchronized (mGlobalLock) {
2430 ActivityRecord r = ActivityRecord.isInStackLocked(token);
Riddle Hsu66b74a82018-07-26 00:20:12 +08002431 return r != null && r.getTask().getTopActivity() == r;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002432 }
2433 }
2434
2435 @Override
2436 public void notifyLaunchTaskBehindComplete(IBinder token) {
2437 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
2438 }
2439
2440 @Override
2441 public void notifyEnterAnimationComplete(IBinder token) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002442 mH.post(() -> {
2443 synchronized (mGlobalLock) {
2444 ActivityRecord r = ActivityRecord.forTokenLocked(token);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002445 if (r != null && r.attachedToProcess()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002446 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002447 r.app.getThread().scheduleEnterAnimationComplete(r.appToken);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002448 } catch (RemoteException e) {
2449 }
2450 }
2451 }
2452
2453 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002454 }
2455
2456 /** Called from an app when assist data is ready. */
2457 @Override
2458 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
2459 AssistContent content, Uri referrer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002460 PendingAssistExtras pae = (PendingAssistExtras) token;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002461 synchronized (pae) {
2462 pae.result = extras;
2463 pae.structure = structure;
2464 pae.content = content;
2465 if (referrer != null) {
2466 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
2467 }
2468 if (structure != null) {
2469 structure.setHomeActivity(pae.isHome);
2470 }
2471 pae.haveResult = true;
2472 pae.notifyAll();
2473 if (pae.intent == null && pae.receiver == null) {
2474 // Caller is just waiting for the result.
2475 return;
2476 }
2477 }
2478 // We are now ready to launch the assist activity.
2479 IAssistDataReceiver sendReceiver = null;
2480 Bundle sendBundle = null;
2481 synchronized (mGlobalLock) {
2482 buildAssistBundleLocked(pae, extras);
2483 boolean exists = mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002484 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002485 if (!exists) {
2486 // Timed out.
2487 return;
2488 }
2489
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002490 if ((sendReceiver = pae.receiver) != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002491 // Caller wants result sent back to them.
2492 sendBundle = new Bundle();
2493 sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
2494 sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
2495 sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
2496 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
2497 }
2498 }
2499 if (sendReceiver != null) {
2500 try {
2501 sendReceiver.onHandleAssistData(sendBundle);
2502 } catch (RemoteException e) {
2503 }
2504 return;
2505 }
2506
2507 final long ident = Binder.clearCallingIdentity();
2508 try {
2509 if (TextUtils.equals(pae.intent.getAction(),
2510 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
2511 pae.intent.putExtras(pae.extras);
2512 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
2513 } else {
2514 pae.intent.replaceExtras(pae.extras);
2515 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
2516 | Intent.FLAG_ACTIVITY_SINGLE_TOP
2517 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002518 mAmInternal.closeSystemDialogs("assist");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002519
2520 try {
2521 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
2522 } catch (ActivityNotFoundException e) {
2523 Slog.w(TAG, "No activity to handle assist action.", e);
2524 }
2525 }
2526 } finally {
2527 Binder.restoreCallingIdentity(ident);
2528 }
2529 }
2530
2531 @Override
2532 public int addAppTask(IBinder activityToken, Intent intent,
2533 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
2534 final int callingUid = Binder.getCallingUid();
2535 final long callingIdent = Binder.clearCallingIdentity();
2536
2537 try {
2538 synchronized (mGlobalLock) {
2539 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
2540 if (r == null) {
2541 throw new IllegalArgumentException("Activity does not exist; token="
2542 + activityToken);
2543 }
2544 ComponentName comp = intent.getComponent();
2545 if (comp == null) {
2546 throw new IllegalArgumentException("Intent " + intent
2547 + " must specify explicit component");
2548 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002549 if (thumbnail.getWidth() != mThumbnailWidth
2550 || thumbnail.getHeight() != mThumbnailHeight) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002551 throw new IllegalArgumentException("Bad thumbnail size: got "
2552 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002553 + mThumbnailWidth + "x" + mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002554 }
2555 if (intent.getSelector() != null) {
2556 intent.setSelector(null);
2557 }
2558 if (intent.getSourceBounds() != null) {
2559 intent.setSourceBounds(null);
2560 }
2561 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
2562 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
2563 // The caller has added this as an auto-remove task... that makes no
2564 // sense, so turn off auto-remove.
2565 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
2566 }
2567 }
2568 final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
2569 STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
2570 if (ainfo.applicationInfo.uid != callingUid) {
2571 throw new SecurityException(
2572 "Can't add task for another application: target uid="
2573 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
2574 }
2575
2576 final ActivityStack stack = r.getStack();
2577 final TaskRecord task = stack.createTaskRecord(
2578 mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent,
2579 null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002580 if (!mRecentTasks.addToBottom(task)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002581 // The app has too many tasks already and we can't add any more
2582 stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
2583 return INVALID_TASK_ID;
2584 }
2585 task.lastTaskDescription.copyFrom(description);
2586
2587 // TODO: Send the thumbnail to WM to store it.
2588
2589 return task.taskId;
2590 }
2591 } finally {
2592 Binder.restoreCallingIdentity(callingIdent);
2593 }
2594 }
2595
2596 @Override
2597 public Point getAppTaskThumbnailSize() {
2598 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002599 return new Point(mThumbnailWidth, mThumbnailHeight);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002600 }
2601 }
2602
2603 @Override
2604 public void setTaskResizeable(int taskId, int resizeableMode) {
2605 synchronized (mGlobalLock) {
2606 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
2607 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
2608 if (task == null) {
2609 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
2610 return;
2611 }
2612 task.setResizeMode(resizeableMode);
2613 }
2614 }
2615
2616 @Override
2617 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002618 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002619 long ident = Binder.clearCallingIdentity();
2620 try {
2621 synchronized (mGlobalLock) {
2622 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2623 if (task == null) {
2624 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
2625 return;
2626 }
2627 // Place the task in the right stack if it isn't there already based on
2628 // the requested bounds.
2629 // The stack transition logic is:
2630 // - a null bounds on a freeform task moves that task to fullscreen
2631 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
2632 // that task to freeform
2633 // - otherwise the task is not moved
2634 ActivityStack stack = task.getStack();
2635 if (!task.getWindowConfiguration().canResizeTask()) {
2636 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
2637 }
2638 if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
2639 stack = stack.getDisplay().getOrCreateStack(
2640 WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
2641 } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
2642 stack = stack.getDisplay().getOrCreateStack(
2643 WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
2644 }
2645
2646 // Reparent the task to the right stack if necessary
2647 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
2648 if (stack != task.getStack()) {
2649 // Defer resume until the task is resized below
2650 task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
2651 DEFER_RESUME, "resizeTask");
2652 preserveWindow = false;
2653 }
2654
2655 // After reparenting (which only resizes the task to the stack bounds), resize the
2656 // task to the actual bounds provided
2657 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
2658 }
2659 } finally {
2660 Binder.restoreCallingIdentity(ident);
2661 }
2662 }
2663
2664 @Override
2665 public boolean releaseActivityInstance(IBinder token) {
2666 synchronized (mGlobalLock) {
2667 final long origId = Binder.clearCallingIdentity();
2668 try {
2669 ActivityRecord r = ActivityRecord.isInStackLocked(token);
2670 if (r == null) {
2671 return false;
2672 }
2673 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
2674 } finally {
2675 Binder.restoreCallingIdentity(origId);
2676 }
2677 }
2678 }
2679
2680 @Override
2681 public void releaseSomeActivities(IApplicationThread appInt) {
2682 synchronized (mGlobalLock) {
2683 final long origId = Binder.clearCallingIdentity();
2684 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002685 WindowProcessController app =
2686 mAm.getRecordForAppLocked(appInt).getWindowProcessController();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002687 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
2688 } finally {
2689 Binder.restoreCallingIdentity(origId);
2690 }
2691 }
2692 }
2693
2694 @Override
2695 public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
2696 int secondaryDisplayShowing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002697 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002698 != PackageManager.PERMISSION_GRANTED) {
2699 throw new SecurityException("Requires permission "
2700 + android.Manifest.permission.DEVICE_POWER);
2701 }
2702
2703 synchronized (mGlobalLock) {
2704 long ident = Binder.clearCallingIdentity();
2705 if (mKeyguardShown != keyguardShowing) {
2706 mKeyguardShown = keyguardShowing;
2707 reportCurKeyguardUsageEventLocked(keyguardShowing);
2708 }
2709 try {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002710 mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002711 secondaryDisplayShowing);
2712 } finally {
2713 Binder.restoreCallingIdentity(ident);
2714 }
2715 }
2716
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002717 mH.post(() -> {
2718 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2719 mScreenObservers.get(i).onKeyguardStateChanged(keyguardShowing);
2720 }
2721 });
2722 }
2723
2724 void onScreenAwakeChanged(boolean isAwake) {
2725 mH.post(() -> {
2726 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2727 mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2728 }
2729 });
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002730 }
2731
2732 @Override
2733 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002734 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
2735 userId, "getTaskDescriptionIcon");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002736
2737 final File passedIconFile = new File(filePath);
2738 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
2739 passedIconFile.getName());
2740 if (!legitIconFile.getPath().equals(filePath)
2741 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
2742 throw new IllegalArgumentException("Bad file path: " + filePath
2743 + " passed for userId " + userId);
2744 }
Wale Ogunwale16e505a2018-05-07 15:00:49 -07002745 return mRecentTasks.getTaskDescriptionIcon(filePath);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002746 }
2747
2748 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002749 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002750 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
2751 final ActivityOptions activityOptions = safeOptions != null
2752 ? safeOptions.getOptions(mStackSupervisor)
2753 : null;
2754 if (activityOptions == null
2755 || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
2756 || activityOptions.getCustomInPlaceResId() == 0) {
2757 throw new IllegalArgumentException("Expected in-place ActivityOption " +
2758 "with valid animation");
2759 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002760 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
2761 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002762 activityOptions.getCustomInPlaceResId());
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002763 mWindowManager.executeAppTransition();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002764 }
2765
2766 @Override
2767 public void removeStack(int stackId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002768 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002769 synchronized (mGlobalLock) {
2770 final long ident = Binder.clearCallingIdentity();
2771 try {
2772 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2773 if (stack == null) {
2774 Slog.w(TAG, "removeStack: No stack with id=" + stackId);
2775 return;
2776 }
2777 if (!stack.isActivityTypeStandardOrUndefined()) {
2778 throw new IllegalArgumentException(
2779 "Removing non-standard stack is not allowed.");
2780 }
2781 mStackSupervisor.removeStack(stack);
2782 } finally {
2783 Binder.restoreCallingIdentity(ident);
2784 }
2785 }
2786 }
2787
2788 @Override
2789 public void moveStackToDisplay(int stackId, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002790 mAmInternal.enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002791
2792 synchronized (mGlobalLock) {
2793 final long ident = Binder.clearCallingIdentity();
2794 try {
2795 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
2796 + " to displayId=" + displayId);
2797 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
2798 } finally {
2799 Binder.restoreCallingIdentity(ident);
2800 }
2801 }
2802 }
2803
2804 @Override
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002805 public void exitFreeformMode(IBinder token) {
2806 synchronized (mGlobalLock) {
2807 long ident = Binder.clearCallingIdentity();
2808 try {
2809 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2810 if (r == null) {
2811 throw new IllegalArgumentException(
2812 "exitFreeformMode: No activity record matching token=" + token);
2813 }
2814
2815 final ActivityStack stack = r.getStack();
2816 if (stack == null || !stack.inFreeformWindowingMode()) {
2817 throw new IllegalStateException(
2818 "exitFreeformMode: You can only go fullscreen from freeform.");
2819 }
2820
2821 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
2822 } finally {
2823 Binder.restoreCallingIdentity(ident);
2824 }
2825 }
2826 }
2827
2828 /** Sets the task stack listener that gets callbacks when a task stack changes. */
2829 @Override
2830 public void registerTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002831 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002832 "registerTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002833 mTaskChangeNotificationController.registerTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002834 }
2835
2836 /** Unregister a task stack listener so that it stops receiving callbacks. */
2837 @Override
2838 public void unregisterTaskStackListener(ITaskStackListener listener) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002839 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002840 "unregisterTaskStackListener()");
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002841 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002842 }
2843
2844 private void reportCurKeyguardUsageEventLocked(boolean keyguardShowing) {
2845 mAm.reportGlobalUsageEventLocked(keyguardShowing
2846 ? UsageEvents.Event.KEYGUARD_SHOWN
2847 : UsageEvents.Event.KEYGUARD_HIDDEN);
2848 }
2849
2850 @Override
2851 public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
2852 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
2853 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
2854 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
2855 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
2856 }
2857
2858 @Override
2859 public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
2860 IBinder activityToken, int flags) {
2861 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
2862 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
2863 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
2864 }
2865
2866 @Override
2867 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
2868 Bundle args) {
2869 return enqueueAssistContext(requestType, intent, hint, null, null, null,
2870 true /* focused */, true /* newSessionId */, userHandle, args,
2871 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
2872 }
2873
2874 @Override
2875 public Bundle getAssistContextExtras(int requestType) {
2876 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
2877 null, null, true /* focused */, true /* newSessionId */,
2878 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
2879 if (pae == null) {
2880 return null;
2881 }
2882 synchronized (pae) {
2883 while (!pae.haveResult) {
2884 try {
2885 pae.wait();
2886 } catch (InterruptedException e) {
2887 }
2888 }
2889 }
2890 synchronized (mGlobalLock) {
2891 buildAssistBundleLocked(pae, pae.result);
2892 mPendingAssistExtras.remove(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002893 mUiHandler.removeCallbacks(pae);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002894 }
2895 return pae.extras;
2896 }
2897
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002898 /**
2899 * Binder IPC calls go through the public entry point.
2900 * This can be called with or without the global lock held.
2901 */
2902 private static int checkCallingPermission(String permission) {
2903 return checkPermission(
2904 permission, Binder.getCallingPid(), UserHandle.getAppId(Binder.getCallingUid()));
2905 }
2906
2907 /** This can be called with or without the global lock held. */
2908 void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
2909 if (!getRecentTasks().isCallerRecents(Binder.getCallingUid())) {
2910 mAmInternal.enforceCallingPermission(permission, func);
2911 }
2912 }
2913
2914 @VisibleForTesting
2915 int checkGetTasksPermission(String permission, int pid, int uid) {
2916 return checkPermission(permission, pid, uid);
2917 }
2918
2919 static int checkPermission(String permission, int pid, int uid) {
2920 if (permission == null) {
2921 return PackageManager.PERMISSION_DENIED;
2922 }
2923 return checkComponentPermission(permission, pid, uid, -1, true);
2924 }
2925
2926 boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
2927 if (getRecentTasks().isCallerRecents(callingUid)) {
2928 // Always allow the recents component to get tasks
2929 return true;
2930 }
2931
2932 boolean allowed = checkGetTasksPermission(android.Manifest.permission.REAL_GET_TASKS,
2933 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
2934 if (!allowed) {
2935 if (checkGetTasksPermission(android.Manifest.permission.GET_TASKS,
2936 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
2937 // Temporary compatibility: some existing apps on the system image may
2938 // still be requesting the old permission and not switched to the new
2939 // one; if so, we'll still allow them full access. This means we need
2940 // to see if they are holding the old permission and are a system app.
2941 try {
2942 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
2943 allowed = true;
2944 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
2945 + " is using old GET_TASKS but privileged; allowing");
2946 }
2947 } catch (RemoteException e) {
2948 }
2949 }
2950 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
2951 + " does not hold REAL_GET_TASKS; limiting output");
2952 }
2953 return allowed;
2954 }
2955
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002956 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
2957 IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
2958 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
2959 int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002960 mAmInternal.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002961 "enqueueAssistContext()");
2962
2963 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07002964 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002965 if (activity == null) {
2966 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
2967 return null;
2968 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002969 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002970 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
2971 return null;
2972 }
2973 if (focused) {
2974 if (activityToken != null) {
2975 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
2976 if (activity != caller) {
2977 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
2978 + " is not current top " + activity);
2979 return null;
2980 }
2981 }
2982 } else {
2983 activity = ActivityRecord.forTokenLocked(activityToken);
2984 if (activity == null) {
2985 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
2986 + " couldn't be found");
2987 return null;
2988 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002989 if (!activity.attachedToProcess()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002990 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
2991 return null;
2992 }
2993 }
2994
2995 PendingAssistExtras pae;
2996 Bundle extras = new Bundle();
2997 if (args != null) {
2998 extras.putAll(args);
2999 }
3000 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003001 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.mUid);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003002
3003 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
3004 userHandle);
3005 pae.isHome = activity.isActivityTypeHome();
3006
3007 // Increment the sessionId if necessary
3008 if (newSessionId) {
3009 mViSessionId++;
3010 }
3011 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003012 activity.app.getThread().requestAssistContextExtras(activity.appToken, pae,
3013 requestType, mViSessionId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003014 mPendingAssistExtras.add(pae);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003015 mUiHandler.postDelayed(pae, timeout);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003016 } catch (RemoteException e) {
3017 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
3018 return null;
3019 }
3020 return pae;
3021 }
3022 }
3023
3024 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
3025 if (result != null) {
3026 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
3027 }
3028 if (pae.hint != null) {
3029 pae.extras.putBoolean(pae.hint, true);
3030 }
3031 }
3032
3033 private void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
3034 IAssistDataReceiver receiver;
3035 synchronized (mGlobalLock) {
3036 mPendingAssistExtras.remove(pae);
3037 receiver = pae.receiver;
3038 }
3039 if (receiver != null) {
3040 // Caller wants result sent back to them.
3041 Bundle sendBundle = new Bundle();
3042 // At least return the receiver extras
3043 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
3044 try {
3045 pae.receiver.onHandleAssistData(sendBundle);
3046 } catch (RemoteException e) {
3047 }
3048 }
3049 }
3050
3051 public class PendingAssistExtras extends Binder implements Runnable {
3052 public final ActivityRecord activity;
3053 public boolean isHome;
3054 public final Bundle extras;
3055 public final Intent intent;
3056 public final String hint;
3057 public final IAssistDataReceiver receiver;
3058 public final int userHandle;
3059 public boolean haveResult = false;
3060 public Bundle result = null;
3061 public AssistStructure structure = null;
3062 public AssistContent content = null;
3063 public Bundle receiverExtras;
3064
3065 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
3066 String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
3067 int _userHandle) {
3068 activity = _activity;
3069 extras = _extras;
3070 intent = _intent;
3071 hint = _hint;
3072 receiver = _receiver;
3073 receiverExtras = _receiverExtras;
3074 userHandle = _userHandle;
3075 }
3076
3077 @Override
3078 public void run() {
3079 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
3080 synchronized (this) {
3081 haveResult = true;
3082 notifyAll();
3083 }
3084 pendingAssistExtrasTimedOut(this);
3085 }
3086 }
3087
3088 @Override
3089 public boolean isAssistDataAllowedOnCurrentActivity() {
3090 int userId;
3091 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003092 final ActivityStack focusedStack = getTopDisplayFocusedStack();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003093 if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
3094 return false;
3095 }
3096
3097 final ActivityRecord activity = focusedStack.getTopActivity();
3098 if (activity == null) {
3099 return false;
3100 }
3101 userId = activity.userId;
3102 }
3103 return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
3104 }
3105
3106 @Override
3107 public boolean showAssistFromActivity(IBinder token, Bundle args) {
3108 long ident = Binder.clearCallingIdentity();
3109 try {
3110 synchronized (mGlobalLock) {
3111 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003112 ActivityRecord top = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003113 if (top != caller) {
3114 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3115 + " is not current top " + top);
3116 return false;
3117 }
3118 if (!top.nowVisible) {
3119 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
3120 + " is not visible");
3121 return false;
3122 }
3123 }
3124 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
3125 token);
3126 } finally {
3127 Binder.restoreCallingIdentity(ident);
3128 }
3129 }
3130
3131 @Override
3132 public boolean isRootVoiceInteraction(IBinder token) {
3133 synchronized (mGlobalLock) {
3134 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3135 if (r == null) {
3136 return false;
3137 }
3138 return r.rootVoiceInteraction;
3139 }
3140 }
3141
Wale Ogunwalef6733932018-06-27 05:14:34 -07003142 private void onLocalVoiceInteractionStartedLocked(IBinder activity,
3143 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
3144 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
3145 if (activityToCallback == null) return;
3146 activityToCallback.setVoiceSessionLocked(voiceSession);
3147
3148 // Inform the activity
3149 try {
3150 activityToCallback.app.getThread().scheduleLocalVoiceInteractionStarted(activity,
3151 voiceInteractor);
3152 long token = Binder.clearCallingIdentity();
3153 try {
3154 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
3155 } finally {
3156 Binder.restoreCallingIdentity(token);
3157 }
3158 // TODO: VI Should we cache the activity so that it's easier to find later
3159 // rather than scan through all the stacks and activities?
3160 } catch (RemoteException re) {
3161 activityToCallback.clearVoiceSessionLocked();
3162 // TODO: VI Should this terminate the voice session?
3163 }
3164 }
3165
3166 private void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
3167 Slog.d(TAG, "<<< startRunningVoiceLocked()");
3168 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
3169 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
3170 boolean wasRunningVoice = mRunningVoice != null;
3171 mRunningVoice = session;
3172 if (!wasRunningVoice) {
3173 mVoiceWakeLock.acquire();
3174 updateSleepIfNeededLocked();
3175 }
3176 }
3177 }
3178
3179 void finishRunningVoiceLocked() {
3180 if (mRunningVoice != null) {
3181 mRunningVoice = null;
3182 mVoiceWakeLock.release();
3183 updateSleepIfNeededLocked();
3184 }
3185 }
3186
3187 @Override
3188 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3189 synchronized (mGlobalLock) {
3190 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3191 if (keepAwake) {
3192 mVoiceWakeLock.acquire();
3193 } else {
3194 mVoiceWakeLock.release();
3195 }
3196 }
3197 }
3198 }
3199
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003200 @Override
3201 public ComponentName getActivityClassForToken(IBinder token) {
3202 synchronized (mGlobalLock) {
3203 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3204 if (r == null) {
3205 return null;
3206 }
3207 return r.intent.getComponent();
3208 }
3209 }
3210
3211 @Override
3212 public String getPackageForToken(IBinder token) {
3213 synchronized (mGlobalLock) {
3214 ActivityRecord r = ActivityRecord.isInStackLocked(token);
3215 if (r == null) {
3216 return null;
3217 }
3218 return r.packageName;
3219 }
3220 }
3221
3222 @Override
3223 public void showLockTaskEscapeMessage(IBinder token) {
3224 synchronized (mGlobalLock) {
3225 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3226 if (r == null) {
3227 return;
3228 }
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003229 getLockTaskController().showLockTaskToast();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003230 }
3231 }
3232
3233 @Override
3234 public void keyguardGoingAway(int flags) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003235 enforceNotIsolatedCaller("keyguardGoingAway");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003236 final long token = Binder.clearCallingIdentity();
3237 try {
3238 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003239 mKeyguardController.keyguardGoingAway(flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003240 }
3241 } finally {
3242 Binder.restoreCallingIdentity(token);
3243 }
3244 }
3245
3246 /**
3247 * Try to place task to provided position. The final position might be different depending on
3248 * current user and stacks state. The task will be moved to target stack if it's currently in
3249 * different stack.
3250 */
3251 @Override
3252 public void positionTaskInStack(int taskId, int stackId, int position) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003253 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003254 synchronized (mGlobalLock) {
3255 long ident = Binder.clearCallingIdentity();
3256 try {
3257 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
3258 + taskId + " in stackId=" + stackId + " at position=" + position);
3259 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3260 if (task == null) {
3261 throw new IllegalArgumentException("positionTaskInStack: no task for id="
3262 + taskId);
3263 }
3264
3265 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3266
3267 if (stack == null) {
3268 throw new IllegalArgumentException("positionTaskInStack: no stack for id="
3269 + stackId);
3270 }
3271 if (!stack.isActivityTypeStandardOrUndefined()) {
3272 throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
3273 + " the position of task " + taskId + " in/to non-standard stack");
3274 }
3275
3276 // TODO: Have the callers of this API call a separate reparent method if that is
3277 // what they intended to do vs. having this method also do reparenting.
3278 if (task.getStack() == stack) {
3279 // Change position in current stack.
3280 stack.positionChildAt(task, position);
3281 } else {
3282 // Reparent to new stack.
3283 task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
3284 !DEFER_RESUME, "positionTaskInStack");
3285 }
3286 } finally {
3287 Binder.restoreCallingIdentity(ident);
3288 }
3289 }
3290 }
3291
3292 @Override
3293 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
3294 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
3295 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
3296 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
3297 synchronized (mGlobalLock) {
3298 ActivityRecord record = ActivityRecord.isInStackLocked(token);
3299 if (record == null) {
3300 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
3301 + "found for: " + token);
3302 }
3303 record.setSizeConfigurations(horizontalSizeConfiguration,
3304 verticalSizeConfigurations, smallestSizeConfigurations);
3305 }
3306 }
3307
3308 /**
3309 * Dismisses split-screen multi-window mode.
3310 * @param toTop If true the current primary split-screen stack will be placed or left on top.
3311 */
3312 @Override
3313 public void dismissSplitScreenMode(boolean toTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003314 enforceCallerIsRecentsOrHasPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003315 MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
3316 final long ident = Binder.clearCallingIdentity();
3317 try {
3318 synchronized (mGlobalLock) {
3319 final ActivityStack stack =
3320 mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
3321 if (stack == null) {
3322 Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
3323 return;
3324 }
3325
3326 if (toTop) {
3327 // Caller wants the current split-screen primary stack to be the top stack after
3328 // it goes fullscreen, so move it to the front.
3329 stack.moveToFront("dismissSplitScreenMode");
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003330 } else if (mStackSupervisor.isTopDisplayFocusedStack(stack)) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003331 // In this case the current split-screen primary stack shouldn't be the top
3332 // stack after it goes fullscreen, but it current has focus, so we move the
3333 // focus to the top-most split-screen secondary stack next to it.
3334 final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
3335 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
3336 if (otherStack != null) {
3337 otherStack.moveToFront("dismissSplitScreenMode_other");
3338 }
3339 }
3340
Evan Rosky10475742018-09-05 19:02:48 -07003341 stack.setWindowingMode(WINDOWING_MODE_UNDEFINED);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003342 }
3343 } finally {
3344 Binder.restoreCallingIdentity(ident);
3345 }
3346 }
3347
3348 /**
3349 * Dismisses Pip
3350 * @param animate True if the dismissal should be animated.
3351 * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
3352 * default animation duration should be used.
3353 */
3354 @Override
3355 public void dismissPip(boolean animate, int animationDuration) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003356 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003357 final long ident = Binder.clearCallingIdentity();
3358 try {
3359 synchronized (mGlobalLock) {
3360 final PinnedActivityStack stack =
3361 mStackSupervisor.getDefaultDisplay().getPinnedStack();
3362 if (stack == null) {
3363 Slog.w(TAG, "dismissPip: pinned stack not found.");
3364 return;
3365 }
3366 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
3367 throw new IllegalArgumentException("Stack: " + stack
3368 + " doesn't support animated resize.");
3369 }
3370 if (animate) {
3371 stack.animateResizePinnedStack(null /* sourceHintBounds */,
3372 null /* destBounds */, animationDuration, false /* fromFullscreen */);
3373 } else {
3374 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
3375 }
3376 }
3377 } finally {
3378 Binder.restoreCallingIdentity(ident);
3379 }
3380 }
3381
3382 @Override
3383 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003384 mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003385 synchronized (mGlobalLock) {
3386 mSuppressResizeConfigChanges = suppress;
3387 }
3388 }
3389
3390 /**
3391 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
3392 * animated the stack to the fullscreen, but can also be called if we are relaunching an
3393 * activity and clearing the task at the same time.
3394 */
3395 @Override
3396 // TODO: API should just be about changing windowing modes...
3397 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003398 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003399 "moveTasksToFullscreenStack()");
3400 synchronized (mGlobalLock) {
3401 final long origId = Binder.clearCallingIdentity();
3402 try {
3403 final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
3404 if (stack != null){
3405 if (!stack.isActivityTypeStandardOrUndefined()) {
3406 throw new IllegalArgumentException(
3407 "You can't move tasks from non-standard stacks.");
3408 }
3409 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
3410 }
3411 } finally {
3412 Binder.restoreCallingIdentity(origId);
3413 }
3414 }
3415 }
3416
3417 /**
3418 * Moves the top activity in the input stackId to the pinned stack.
3419 *
3420 * @param stackId Id of stack to move the top activity to pinned stack.
3421 * @param bounds Bounds to use for pinned stack.
3422 *
3423 * @return True if the top activity of the input stack was successfully moved to the pinned
3424 * stack.
3425 */
3426 @Override
3427 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003428 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003429 "moveTopActivityToPinnedStack()");
3430 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003431 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003432 throw new IllegalStateException("moveTopActivityToPinnedStack:"
3433 + "Device doesn't support picture-in-picture mode");
3434 }
3435
3436 long ident = Binder.clearCallingIdentity();
3437 try {
3438 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
3439 } finally {
3440 Binder.restoreCallingIdentity(ident);
3441 }
3442 }
3443 }
3444
3445 @Override
3446 public boolean isInMultiWindowMode(IBinder token) {
3447 final long origId = Binder.clearCallingIdentity();
3448 try {
3449 synchronized (mGlobalLock) {
3450 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3451 if (r == null) {
3452 return false;
3453 }
3454 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
3455 return r.inMultiWindowMode();
3456 }
3457 } finally {
3458 Binder.restoreCallingIdentity(origId);
3459 }
3460 }
3461
3462 @Override
3463 public boolean isInPictureInPictureMode(IBinder token) {
3464 final long origId = Binder.clearCallingIdentity();
3465 try {
3466 synchronized (mGlobalLock) {
3467 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
3468 }
3469 } finally {
3470 Binder.restoreCallingIdentity(origId);
3471 }
3472 }
3473
3474 private boolean isInPictureInPictureMode(ActivityRecord r) {
3475 if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
3476 || r.getStack().isInStackLocked(r) == null) {
3477 return false;
3478 }
3479
3480 // If we are animating to fullscreen then we have already dispatched the PIP mode
3481 // changed, so we should reflect that check here as well.
3482 final PinnedActivityStack stack = r.getStack();
3483 final PinnedStackWindowController windowController = stack.getWindowContainerController();
3484 return !windowController.isAnimatingBoundsToFullscreen();
3485 }
3486
3487 @Override
3488 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
3489 final long origId = Binder.clearCallingIdentity();
3490 try {
3491 synchronized (mGlobalLock) {
3492 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3493 "enterPictureInPictureMode", token, params);
3494
3495 // If the activity is already in picture in picture mode, then just return early
3496 if (isInPictureInPictureMode(r)) {
3497 return true;
3498 }
3499
3500 // Activity supports picture-in-picture, now check that we can enter PiP at this
3501 // point, if it is
3502 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
3503 false /* beforeStopping */)) {
3504 return false;
3505 }
3506
3507 final Runnable enterPipRunnable = () -> {
Wale Ogunwalef276a6f2018-06-15 08:26:07 -07003508 synchronized (mGlobalLock) {
3509 // Only update the saved args from the args that are set
3510 r.pictureInPictureArgs.copyOnlySet(params);
3511 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
3512 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
3513 // Adjust the source bounds by the insets for the transition down
3514 final Rect sourceBounds = new Rect(
3515 r.pictureInPictureArgs.getSourceRectHint());
3516 mStackSupervisor.moveActivityToPinnedStackLocked(
3517 r, sourceBounds, aspectRatio, "enterPictureInPictureMode");
3518 final PinnedActivityStack stack = r.getStack();
3519 stack.setPictureInPictureAspectRatio(aspectRatio);
3520 stack.setPictureInPictureActions(actions);
3521 MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
3522 r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
3523 logPictureInPictureArgs(params);
3524 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003525 };
3526
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003527 if (isKeyguardLocked()) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003528 // If the keyguard is showing or occluded, then try and dismiss it before
3529 // entering picture-in-picture (this will prompt the user to authenticate if the
3530 // device is currently locked).
3531 dismissKeyguard(token, new KeyguardDismissCallback() {
3532 @Override
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003533 public void onDismissSucceeded() {
3534 mH.post(enterPipRunnable);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003535 }
3536 }, null /* message */);
3537 } else {
3538 // Enter picture in picture immediately otherwise
3539 enterPipRunnable.run();
3540 }
3541 return true;
3542 }
3543 } finally {
3544 Binder.restoreCallingIdentity(origId);
3545 }
3546 }
3547
3548 @Override
3549 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
3550 final long origId = Binder.clearCallingIdentity();
3551 try {
3552 synchronized (mGlobalLock) {
3553 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
3554 "setPictureInPictureParams", token, params);
3555
3556 // Only update the saved args from the args that are set
3557 r.pictureInPictureArgs.copyOnlySet(params);
3558 if (r.inPinnedWindowingMode()) {
3559 // If the activity is already in picture-in-picture, update the pinned stack now
3560 // if it is not already expanding to fullscreen. Otherwise, the arguments will
3561 // be used the next time the activity enters PiP
3562 final PinnedActivityStack stack = r.getStack();
3563 if (!stack.isAnimatingBoundsToFullscreen()) {
3564 stack.setPictureInPictureAspectRatio(
3565 r.pictureInPictureArgs.getAspectRatio());
3566 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
3567 }
3568 }
3569 logPictureInPictureArgs(params);
3570 }
3571 } finally {
3572 Binder.restoreCallingIdentity(origId);
3573 }
3574 }
3575
3576 @Override
3577 public int getMaxNumPictureInPictureActions(IBinder token) {
3578 // Currently, this is a static constant, but later, we may change this to be dependent on
3579 // the context of the activity
3580 return 3;
3581 }
3582
3583 private void logPictureInPictureArgs(PictureInPictureParams params) {
3584 if (params.hasSetActions()) {
3585 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
3586 params.getActions().size());
3587 }
3588 if (params.hasSetAspectRatio()) {
3589 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
3590 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
3591 MetricsLogger.action(lm);
3592 }
3593 }
3594
3595 /**
3596 * Checks the state of the system and the activity associated with the given {@param token} to
3597 * verify that picture-in-picture is supported for that activity.
3598 *
3599 * @return the activity record for the given {@param token} if all the checks pass.
3600 */
3601 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
3602 IBinder token, PictureInPictureParams params) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003603 if (!mSupportsPictureInPicture) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003604 throw new IllegalStateException(caller
3605 + ": Device doesn't support picture-in-picture mode.");
3606 }
3607
3608 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
3609 if (r == null) {
3610 throw new IllegalStateException(caller
3611 + ": Can't find activity for token=" + token);
3612 }
3613
3614 if (!r.supportsPictureInPicture()) {
3615 throw new IllegalStateException(caller
3616 + ": Current activity does not support picture-in-picture.");
3617 }
3618
3619 if (params.hasSetAspectRatio()
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003620 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003621 params.getAspectRatio())) {
3622 final float minAspectRatio = mContext.getResources().getFloat(
3623 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
3624 final float maxAspectRatio = mContext.getResources().getFloat(
3625 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
3626 throw new IllegalArgumentException(String.format(caller
3627 + ": Aspect ratio is too extreme (must be between %f and %f).",
3628 minAspectRatio, maxAspectRatio));
3629 }
3630
3631 // Truncate the number of actions if necessary
3632 params.truncateActions(getMaxNumPictureInPictureActions(token));
3633
3634 return r;
3635 }
3636
3637 @Override
3638 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003639 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003640 synchronized (mGlobalLock) {
3641 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
3642 if (r == null) {
3643 throw new IllegalArgumentException("Activity does not exist; token="
3644 + activityToken);
3645 }
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07003646 return r.getUriPermissionsLocked().getExternalToken();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003647 }
3648 }
3649
3650 @Override
3651 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
3652 Rect tempDockedTaskInsetBounds,
3653 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003654 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003655 long ident = Binder.clearCallingIdentity();
3656 try {
3657 synchronized (mGlobalLock) {
3658 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
3659 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
3660 PRESERVE_WINDOWS);
3661 }
3662 } finally {
3663 Binder.restoreCallingIdentity(ident);
3664 }
3665 }
3666
3667 @Override
3668 public void setSplitScreenResizing(boolean resizing) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003669 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003670 final long ident = Binder.clearCallingIdentity();
3671 try {
3672 synchronized (mGlobalLock) {
3673 mStackSupervisor.setSplitScreenResizing(resizing);
3674 }
3675 } finally {
3676 Binder.restoreCallingIdentity(ident);
3677 }
3678 }
3679
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003680 /**
3681 * Check that we have the features required for VR-related API calls, and throw an exception if
3682 * not.
3683 */
3684 void enforceSystemHasVrFeature() {
3685 if (!mContext.getPackageManager().hasSystemFeature(
3686 PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
3687 throw new UnsupportedOperationException("VR mode not supported on this device!");
3688 }
3689 }
3690
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003691 @Override
3692 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003693 enforceSystemHasVrFeature();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003694
3695 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3696
3697 ActivityRecord r;
3698 synchronized (mGlobalLock) {
3699 r = ActivityRecord.isInStackLocked(token);
3700 }
3701
3702 if (r == null) {
3703 throw new IllegalArgumentException();
3704 }
3705
3706 int err;
3707 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
3708 VrManagerInternal.NO_ERROR) {
3709 return err;
3710 }
3711
3712 // Clear the binder calling uid since this path may call moveToTask().
3713 final long callingId = Binder.clearCallingIdentity();
3714 try {
3715 synchronized (mGlobalLock) {
3716 r.requestedVrComponent = (enabled) ? packageName : null;
3717
3718 // Update associated state if this activity is currently focused
Andrii Kulian52d255c2018-07-13 11:32:19 -07003719 if (r.isResumedActivityOnDisplay()) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003720 applyUpdateVrModeLocked(r);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003721 }
3722 return 0;
3723 }
3724 } finally {
3725 Binder.restoreCallingIdentity(callingId);
3726 }
3727 }
3728
3729 @Override
3730 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
3731 Slog.i(TAG, "Activity tried to startLocalVoiceInteraction");
3732 synchronized (mGlobalLock) {
Andrii Kulian5f750bc2018-07-17 08:57:23 -07003733 ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003734 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
3735 throw new SecurityException("Only focused activity can call startVoiceInteraction");
3736 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07003737 if (mRunningVoice != null || activity.getTask().voiceSession != null
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003738 || activity.voiceSession != null) {
3739 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
3740 return;
3741 }
3742 if (activity.pendingVoiceInteractionStart) {
3743 Slog.w(TAG, "Pending start of voice interaction already.");
3744 return;
3745 }
3746 activity.pendingVoiceInteractionStart = true;
3747 }
3748 LocalServices.getService(VoiceInteractionManagerInternal.class)
3749 .startLocalVoiceInteraction(callingActivity, options);
3750 }
3751
3752 @Override
3753 public void stopLocalVoiceInteraction(IBinder callingActivity) {
3754 LocalServices.getService(VoiceInteractionManagerInternal.class)
3755 .stopLocalVoiceInteraction(callingActivity);
3756 }
3757
3758 @Override
3759 public boolean supportsLocalVoiceInteraction() {
3760 return LocalServices.getService(VoiceInteractionManagerInternal.class)
3761 .supportsLocalVoiceInteraction();
3762 }
3763
3764 /** Notifies all listeners when the pinned stack animation starts. */
3765 @Override
3766 public void notifyPinnedStackAnimationStarted() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003767 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003768 }
3769
3770 /** Notifies all listeners when the pinned stack animation ends. */
3771 @Override
3772 public void notifyPinnedStackAnimationEnded() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003773 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003774 }
3775
3776 @Override
3777 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003778 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003779 final long ident = Binder.clearCallingIdentity();
3780 try {
3781 synchronized (mGlobalLock) {
3782 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
3783 }
3784 } finally {
3785 Binder.restoreCallingIdentity(ident);
3786 }
3787 }
3788
3789 @Override
3790 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003791 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003792
3793 synchronized (mGlobalLock) {
3794 // Check if display is initialized in AM.
3795 if (!mStackSupervisor.isDisplayAdded(displayId)) {
3796 // Call might come when display is not yet added or has already been removed.
3797 if (DEBUG_CONFIGURATION) {
3798 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
3799 + displayId);
3800 }
3801 return false;
3802 }
3803
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003804 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003805 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003806 values = mWindowManager.computeNewConfiguration(displayId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003807 }
3808
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003809 if (mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003810 // Update OOM levels based on display size.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003811 mAm.mProcessList.applyDisplaySize(mWindowManager);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003812 }
3813
3814 final long origId = Binder.clearCallingIdentity();
3815 try {
3816 if (values != null) {
3817 Settings.System.clearConfiguration(values);
3818 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003819 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003820 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
3821 return mTmpUpdateConfigurationResult.changes != 0;
3822 } finally {
3823 Binder.restoreCallingIdentity(origId);
3824 }
3825 }
3826 }
3827
3828 @Override
3829 public boolean updateConfiguration(Configuration values) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003830 mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003831
3832 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003833 if (values == null && mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003834 // sentinel: fetch the current configuration from the window manager
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003835 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003836 }
3837
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003838 if (mWindowManager != null) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003839 // Update OOM levels based on display size.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003840 mAm.mProcessList.applyDisplaySize(mWindowManager);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003841 }
3842
3843 final long origId = Binder.clearCallingIdentity();
3844 try {
3845 if (values != null) {
3846 Settings.System.clearConfiguration(values);
3847 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003848 updateConfigurationLocked(values, null, false, false /* persistent */,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003849 UserHandle.USER_NULL, false /* deferResume */,
3850 mTmpUpdateConfigurationResult);
3851 return mTmpUpdateConfigurationResult.changes != 0;
3852 } finally {
3853 Binder.restoreCallingIdentity(origId);
3854 }
3855 }
3856 }
3857
3858 @Override
3859 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
3860 CharSequence message) {
3861 if (message != null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003862 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003863 Manifest.permission.SHOW_KEYGUARD_MESSAGE, "dismissKeyguard()");
3864 }
3865 final long callingId = Binder.clearCallingIdentity();
3866 try {
3867 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07003868 mKeyguardController.dismissKeyguard(token, callback, message);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003869 }
3870 } finally {
3871 Binder.restoreCallingIdentity(callingId);
3872 }
3873 }
3874
3875 @Override
3876 public void cancelTaskWindowTransition(int taskId) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003877 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003878 "cancelTaskWindowTransition()");
3879 final long ident = Binder.clearCallingIdentity();
3880 try {
3881 synchronized (mGlobalLock) {
3882 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
3883 MATCH_TASK_IN_STACKS_ONLY);
3884 if (task == null) {
3885 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
3886 return;
3887 }
3888 task.cancelWindowTransition();
3889 }
3890 } finally {
3891 Binder.restoreCallingIdentity(ident);
3892 }
3893 }
3894
3895 @Override
3896 public ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003897 enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003898 final long ident = Binder.clearCallingIdentity();
3899 try {
3900 final TaskRecord task;
3901 synchronized (mGlobalLock) {
3902 task = mStackSupervisor.anyTaskForIdLocked(taskId,
3903 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
3904 if (task == null) {
3905 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
3906 return null;
3907 }
3908 }
3909 // Don't call this while holding the lock as this operation might hit the disk.
3910 return task.getSnapshot(reducedResolution);
3911 } finally {
3912 Binder.restoreCallingIdentity(ident);
3913 }
3914 }
3915
3916 @Override
3917 public void setDisablePreviewScreenshots(IBinder token, boolean disable) {
3918 synchronized (mGlobalLock) {
3919 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3920 if (r == null) {
3921 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
3922 + token);
3923 return;
3924 }
3925 final long origId = Binder.clearCallingIdentity();
3926 try {
3927 r.setDisablePreviewScreenshots(disable);
3928 } finally {
3929 Binder.restoreCallingIdentity(origId);
3930 }
3931 }
3932 }
3933
3934 /** Return the user id of the last resumed activity. */
3935 @Override
3936 public @UserIdInt
3937 int getLastResumedActivityUserId() {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003938 mAmInternal.enforceCallingPermission(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003939 Manifest.permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
3940 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07003941 if (mLastResumedActivity == null) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003942 return getCurrentUserId();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003943 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07003944 return mLastResumedActivity.userId;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003945 }
3946 }
3947
3948 @Override
3949 public void updateLockTaskFeatures(int userId, int flags) {
3950 final int callingUid = Binder.getCallingUid();
3951 if (callingUid != 0 && callingUid != SYSTEM_UID) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003952 mAmInternal.enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003953 "updateLockTaskFeatures()");
3954 }
3955 synchronized (mGlobalLock) {
3956 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
3957 Integer.toHexString(flags));
Wale Ogunwaled95c06b2018-05-08 10:35:38 -07003958 getLockTaskController().updateLockTaskFeatures(userId, flags);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003959 }
3960 }
3961
3962 @Override
3963 public void setShowWhenLocked(IBinder token, boolean showWhenLocked) {
3964 synchronized (mGlobalLock) {
3965 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3966 if (r == null) {
3967 return;
3968 }
3969 final long origId = Binder.clearCallingIdentity();
3970 try {
3971 r.setShowWhenLocked(showWhenLocked);
3972 } finally {
3973 Binder.restoreCallingIdentity(origId);
3974 }
3975 }
3976 }
3977
3978 @Override
3979 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) {
3980 synchronized (mGlobalLock) {
3981 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
3982 if (r == null) {
3983 return;
3984 }
3985 final long origId = Binder.clearCallingIdentity();
3986 try {
3987 r.setTurnScreenOn(turnScreenOn);
3988 } finally {
3989 Binder.restoreCallingIdentity(origId);
3990 }
3991 }
3992 }
3993
3994 @Override
3995 public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07003996 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07003997 "registerRemoteAnimations");
3998 definition.setCallingPid(Binder.getCallingPid());
3999 synchronized (mGlobalLock) {
4000 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
4001 if (r == null) {
4002 return;
4003 }
4004 final long origId = Binder.clearCallingIdentity();
4005 try {
4006 r.registerRemoteAnimations(definition);
4007 } finally {
4008 Binder.restoreCallingIdentity(origId);
4009 }
4010 }
4011 }
4012
4013 @Override
4014 public void registerRemoteAnimationForNextActivityStart(String packageName,
4015 RemoteAnimationAdapter adapter) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004016 mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004017 "registerRemoteAnimationForNextActivityStart");
4018 adapter.setCallingPid(Binder.getCallingPid());
4019 synchronized (mGlobalLock) {
4020 final long origId = Binder.clearCallingIdentity();
4021 try {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07004022 getActivityStartController().registerRemoteAnimationForNextActivityStart(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004023 packageName, adapter);
4024 } finally {
4025 Binder.restoreCallingIdentity(origId);
4026 }
4027 }
4028 }
4029
4030 /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
4031 @Override
4032 public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
4033 synchronized (mGlobalLock) {
4034 final long origId = Binder.clearCallingIdentity();
4035 try {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004036 mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07004037 } finally {
4038 Binder.restoreCallingIdentity(origId);
4039 }
4040 }
4041 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07004042
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004043 @Override
4044 public void setVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004045 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004046 synchronized (mGlobalLock) {
4047 synchronized (mAm.mPidsSelfLocked) {
4048 final int pid = Binder.getCallingPid();
4049 final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004050 mVrController.setVrThreadLocked(tid, pid, proc.getWindowProcessController());
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004051 }
4052 }
4053 }
4054
4055 @Override
4056 public void setPersistentVrThread(int tid) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004057 if (checkCallingPermission(Manifest.permission.RESTRICTED_VR_ACCESS)
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004058 != PERMISSION_GRANTED) {
4059 final String msg = "Permission Denial: setPersistentVrThread() from pid="
4060 + Binder.getCallingPid()
4061 + ", uid=" + Binder.getCallingUid()
4062 + " requires " + Manifest.permission.RESTRICTED_VR_ACCESS;
4063 Slog.w(TAG, msg);
4064 throw new SecurityException(msg);
4065 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004066 enforceSystemHasVrFeature();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004067 synchronized (mGlobalLock) {
4068 synchronized (mAm.mPidsSelfLocked) {
4069 final int pid = Binder.getCallingPid();
4070 final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
4071 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
4072 }
4073 }
4074 }
4075
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004076 @Override
4077 public void stopAppSwitches() {
4078 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
4079 synchronized (mGlobalLock) {
4080 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME;
4081 mDidAppSwitch = false;
4082 getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
4083 }
4084 }
4085
4086 @Override
4087 public void resumeAppSwitches() {
4088 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
4089 synchronized (mGlobalLock) {
4090 // Note that we don't execute any pending app switches... we will
4091 // let those wait until either the timeout, or the next start
4092 // activity request.
4093 mAppSwitchesAllowedTime = 0;
4094 }
4095 }
4096
4097 void onStartActivitySetDidAppSwitch() {
4098 if (mDidAppSwitch) {
4099 // This is the second allowed switch since we stopped switches, so now just generally
4100 // allow switches. Use case:
4101 // - user presses home (switches disabled, switch to home, mDidAppSwitch now true);
4102 // - user taps a home icon (coming from home so allowed, we hit here and now allow
4103 // anyone to switch again).
4104 mAppSwitchesAllowedTime = 0;
4105 } else {
4106 mDidAppSwitch = true;
4107 }
4108 }
4109
4110 /** @return whether the system should disable UI modes incompatible with VR mode. */
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004111 boolean shouldDisableNonVrUiLocked() {
4112 return mVrController.shouldDisableNonVrUiLocked();
4113 }
4114
4115 void applyUpdateVrModeLocked(ActivityRecord r) {
4116 // VR apps are expected to run in a main display. If an app is turning on VR for
4117 // itself, but lives in a dynamic stack, then make sure that it is moved to the main
4118 // fullscreen stack before enabling VR Mode.
4119 // TODO: The goal of this code is to keep the VR app on the main display. When the
4120 // stack implementation changes in the future, keep in mind that the use of the fullscreen
4121 // stack is a means to move the activity to the main display and a moveActivityToDisplay()
4122 // option would be a better choice here.
4123 if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
4124 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
4125 + " to main stack for VR");
4126 final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
4127 WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
4128 moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
4129 }
4130 mH.post(() -> {
4131 if (!mVrController.onVrModeChanged(r)) {
4132 return;
4133 }
4134 synchronized (mGlobalLock) {
4135 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
4136 mWindowManager.disableNonVrUi(disableNonVrUi);
4137 if (disableNonVrUi) {
4138 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
4139 // then remove the pinned stack.
4140 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
4141 }
4142 }
4143 });
4144 }
4145
Andrii Kulian5f750bc2018-07-17 08:57:23 -07004146 ActivityStack getTopDisplayFocusedStack() {
4147 return mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004148 }
4149
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004150 /** Pokes the task persister. */
4151 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
4152 mRecentTasks.notifyTaskPersisterLocked(task, flush);
4153 }
4154
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004155 void onTopProcChangedLocked(WindowProcessController proc) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004156 mVrController.onTopProcChangedLocked(proc);
4157 }
4158
4159 boolean isKeyguardLocked() {
4160 return mKeyguardController.isKeyguardLocked();
4161 }
4162
4163 boolean isNextTransitionForward() {
4164 int transit = mWindowManager.getPendingAppTransition();
4165 return transit == TRANSIT_ACTIVITY_OPEN
4166 || transit == TRANSIT_TASK_OPEN
4167 || transit == TRANSIT_TASK_TO_FRONT;
4168 }
4169
Wale Ogunwalef6733932018-06-27 05:14:34 -07004170 void dumpSleepStates(PrintWriter pw, boolean testPssMode) {
4171 synchronized (mGlobalLock) {
4172 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
4173 if (mRunningVoice != null) {
4174 pw.println(" mRunningVoice=" + mRunningVoice);
4175 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
4176 }
4177 pw.println(" mSleeping=" + mSleeping);
4178 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + testPssMode);
4179 pw.println(" mVrController=" + mVrController);
4180 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004181 }
4182
Wale Ogunwalef6733932018-06-27 05:14:34 -07004183 void writeSleepStateToProto(ProtoOutputStream proto) {
4184 for (ActivityTaskManagerInternal.SleepToken st : mStackSupervisor.mSleepTokens) {
4185 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS,
4186 st.toString());
4187 }
4188
4189 if (mRunningVoice != null) {
4190 final long vrToken = proto.start(
4191 ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
4192 proto.write(ActivityManagerServiceDumpProcessesProto.Voice.SESSION,
4193 mRunningVoice.toString());
4194 mVoiceWakeLock.writeToProto(
4195 proto, ActivityManagerServiceDumpProcessesProto.Voice.WAKELOCK);
4196 proto.end(vrToken);
4197 }
4198
4199 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
4200 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN,
4201 mShuttingDown);
4202 mVrController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004203 }
4204
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004205 int getCurrentUserId() {
4206 return mAmInternal.getCurrentUserId();
4207 }
4208
4209 private void enforceNotIsolatedCaller(String caller) {
4210 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4211 throw new SecurityException("Isolated process not allowed to call " + caller);
4212 }
4213 }
4214
Wale Ogunwalef6733932018-06-27 05:14:34 -07004215 public Configuration getConfiguration() {
4216 Configuration ci;
4217 synchronized(mGlobalLock) {
4218 ci = new Configuration(getGlobalConfiguration());
4219 ci.userSetLocale = false;
4220 }
4221 return ci;
4222 }
4223
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004224 /**
4225 * Current global configuration information. Contains general settings for the entire system,
4226 * also corresponds to the merged configuration of the default display.
4227 */
4228 Configuration getGlobalConfiguration() {
4229 return mStackSupervisor.getConfiguration();
4230 }
4231
4232 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4233 boolean initLocale) {
4234 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
4235 }
4236
4237 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4238 boolean initLocale, boolean deferResume) {
4239 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
4240 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
4241 UserHandle.USER_NULL, deferResume);
4242 }
4243
4244 void updatePersistentConfiguration(Configuration values, @UserIdInt int userId) {
4245 final long origId = Binder.clearCallingIdentity();
4246 try {
4247 synchronized (mGlobalLock) {
4248 updateConfigurationLocked(values, null, false, true, userId,
4249 false /* deferResume */);
4250 }
4251 } finally {
4252 Binder.restoreCallingIdentity(origId);
4253 }
4254 }
4255
4256 void updateUserConfiguration() {
4257 synchronized (mGlobalLock) {
4258 final Configuration configuration = new Configuration(getGlobalConfiguration());
4259 final int currentUserId = mAmInternal.getCurrentUserId();
4260 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
4261 currentUserId, Settings.System.canWrite(mContext));
4262 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
4263 false /* persistent */, currentUserId, false /* deferResume */);
4264 }
4265 }
4266
4267 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4268 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
4269 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
4270 deferResume, null /* result */);
4271 }
4272
4273 /**
4274 * Do either or both things: (1) change the current configuration, and (2)
4275 * make sure the given activity is running with the (now) current
4276 * configuration. Returns true if the activity has been left running, or
4277 * false if <var>starting</var> is being destroyed to match the new
4278 * configuration.
4279 *
4280 * @param userId is only used when persistent parameter is set to true to persist configuration
4281 * for that particular user
4282 */
4283 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
4284 boolean initLocale, boolean persistent, int userId, boolean deferResume,
4285 ActivityTaskManagerService.UpdateConfigurationResult result) {
4286 int changes = 0;
4287 boolean kept = true;
4288
4289 if (mWindowManager != null) {
4290 mWindowManager.deferSurfaceLayout();
4291 }
4292 try {
4293 if (values != null) {
4294 changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
4295 deferResume);
4296 }
4297
4298 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4299 } finally {
4300 if (mWindowManager != null) {
4301 mWindowManager.continueSurfaceLayout();
4302 }
4303 }
4304
4305 if (result != null) {
4306 result.changes = changes;
4307 result.activityRelaunched = !kept;
4308 }
4309 return kept;
4310 }
4311
4312 /**
4313 * Returns true if this configuration change is interesting enough to send an
4314 * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
4315 */
4316 private static boolean isSplitConfigurationChange(int configDiff) {
4317 return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
4318 }
4319
4320 /** Update default (global) configuration and notify listeners about changes. */
4321 private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
4322 boolean persistent, int userId, boolean deferResume) {
4323 mTempConfig.setTo(getGlobalConfiguration());
4324 final int changes = mTempConfig.updateFrom(values);
4325 if (changes == 0) {
4326 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
4327 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
4328 // performDisplayOverrideConfigUpdate in order to send the new display configuration
4329 // (even if there are no actual changes) to unfreeze the window.
4330 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
4331 return 0;
4332 }
4333
4334 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
4335 "Updating global configuration to: " + values);
4336
4337 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
4338 StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
4339 values.colorMode,
4340 values.densityDpi,
4341 values.fontScale,
4342 values.hardKeyboardHidden,
4343 values.keyboard,
4344 values.keyboardHidden,
4345 values.mcc,
4346 values.mnc,
4347 values.navigation,
4348 values.navigationHidden,
4349 values.orientation,
4350 values.screenHeightDp,
4351 values.screenLayout,
4352 values.screenWidthDp,
4353 values.smallestScreenWidthDp,
4354 values.touchscreen,
4355 values.uiMode);
4356
4357
4358 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
4359 final LocaleList locales = values.getLocales();
4360 int bestLocaleIndex = 0;
4361 if (locales.size() > 1) {
4362 if (mSupportedSystemLocales == null) {
4363 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
4364 }
4365 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
4366 }
4367 SystemProperties.set("persist.sys.locale",
4368 locales.get(bestLocaleIndex).toLanguageTag());
4369 LocaleList.setDefault(locales, bestLocaleIndex);
4370 mAm.mHandler.sendMessage(mAm.mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
4371 locales.get(bestLocaleIndex)));
4372 }
4373
4374 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
4375 mTempConfig.seq = mConfigurationSeq;
4376
4377 // Update stored global config and notify everyone about the change.
4378 mStackSupervisor.onConfigurationChanged(mTempConfig);
4379
4380 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
4381 // TODO(multi-display): Update UsageEvents#Event to include displayId.
4382 mAm.mUsageStatsService.reportConfigurationChange(
4383 mTempConfig, mAmInternal.getCurrentUserId());
4384
4385 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
Wale Ogunwalef6733932018-06-27 05:14:34 -07004386 updateShouldShowDialogsLocked(mTempConfig);
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004387
4388 AttributeCache ac = AttributeCache.instance();
4389 if (ac != null) {
4390 ac.updateConfiguration(mTempConfig);
4391 }
4392
4393 // Make sure all resources in our process are updated right now, so that anyone who is going
4394 // to retrieve resource values after we return will be sure to get the new ones. This is
4395 // especially important during boot, where the first config change needs to guarantee all
4396 // resources have that config before following boot code is executed.
4397 mAm.mSystemThread.applyConfigurationToResources(mTempConfig);
4398
4399 // We need another copy of global config because we're scheduling some calls instead of
4400 // running them in place. We need to be sure that object we send will be handled unchanged.
4401 final Configuration configCopy = new Configuration(mTempConfig);
4402 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
4403 Message msg = mAm.mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
4404 msg.obj = configCopy;
4405 msg.arg1 = userId;
4406 mAm.mHandler.sendMessage(msg);
4407 }
4408
4409 for (int i = mAm.mLruProcesses.size() - 1; i >= 0; i--) {
4410 ProcessRecord app = mAm.mLruProcesses.get(i);
4411 try {
4412 if (app.thread != null) {
4413 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
4414 + app.processName + " new config " + configCopy);
4415 getLifecycleManager().scheduleTransaction(app.thread,
4416 ConfigurationChangeItem.obtain(configCopy));
4417 }
4418 } catch (Exception e) {
4419 Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
4420 }
4421 }
4422
4423 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
4424 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
4425 | Intent.FLAG_RECEIVER_FOREGROUND
4426 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4427 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4428 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4429 UserHandle.USER_ALL);
4430 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
4431 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
4432 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
4433 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
4434 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4435 if (initLocale || !mAm.mProcessesReady) {
4436 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
4437 }
4438 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
4439 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
4440 UserHandle.USER_ALL);
4441 }
4442
4443 // Send a broadcast to PackageInstallers if the configuration change is interesting
4444 // for the purposes of installing additional splits.
4445 if (!initLocale && isSplitConfigurationChange(changes)) {
4446 intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
4447 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
4448 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
4449
4450 // Typically only app stores will have this permission.
4451 String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES };
4452 mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions,
4453 OP_NONE, null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
4454 }
4455
4456 // Override configuration of the default display duplicates global config, so we need to
4457 // update it also. This will also notify WindowManager about changes.
4458 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
4459 DEFAULT_DISPLAY);
4460
4461 return changes;
4462 }
4463
4464 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
4465 boolean deferResume, int displayId) {
4466 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
4467 displayId, null /* result */);
4468 }
4469
4470 /**
4471 * Updates override configuration specific for the selected display. If no config is provided,
4472 * new one will be computed in WM based on current display info.
4473 */
4474 boolean updateDisplayOverrideConfigurationLocked(Configuration values,
4475 ActivityRecord starting, boolean deferResume, int displayId,
4476 ActivityTaskManagerService.UpdateConfigurationResult result) {
4477 int changes = 0;
4478 boolean kept = true;
4479
4480 if (mWindowManager != null) {
4481 mWindowManager.deferSurfaceLayout();
4482 }
4483 try {
4484 if (values != null) {
4485 if (displayId == DEFAULT_DISPLAY) {
4486 // Override configuration of the default display duplicates global config, so
4487 // we're calling global config update instead for default display. It will also
4488 // apply the correct override config.
4489 changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
4490 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
4491 } else {
4492 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
4493 }
4494 }
4495
4496 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
4497 } finally {
4498 if (mWindowManager != null) {
4499 mWindowManager.continueSurfaceLayout();
4500 }
4501 }
4502
4503 if (result != null) {
4504 result.changes = changes;
4505 result.activityRelaunched = !kept;
4506 }
4507 return kept;
4508 }
4509
4510 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
4511 int displayId) {
4512 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
4513 final int changes = mTempConfig.updateFrom(values);
4514 if (changes != 0) {
4515 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
4516 + mTempConfig + " for displayId=" + displayId);
4517 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
4518
4519 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
4520 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
Wale Ogunwale008163e2018-07-23 23:11:08 -07004521 mAppWarnings.onDensityChanged();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004522
4523 mAm.killAllBackgroundProcessesExcept(N,
4524 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
4525 }
4526 }
4527
4528 // Update the configuration with WM first and check if any of the stacks need to be resized
4529 // due to the configuration change. If so, resize the stacks now and do any relaunches if
4530 // necessary. This way we don't need to relaunch again afterwards in
4531 // ensureActivityConfiguration().
4532 if (mWindowManager != null) {
4533 final int[] resizedStacks =
4534 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
4535 if (resizedStacks != null) {
4536 for (int stackId : resizedStacks) {
4537 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
4538 }
4539 }
4540 }
4541
4542 return changes;
4543 }
4544
Wale Ogunwalef6733932018-06-27 05:14:34 -07004545 private void updateEventDispatchingLocked(boolean booted) {
4546 mWindowManager.setEventDispatching(booted && !mShuttingDown);
4547 }
4548
4549 void enableScreenAfterBoot(boolean booted) {
4550 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4551 SystemClock.uptimeMillis());
4552 mWindowManager.enableScreenAfterBoot();
4553
4554 synchronized (mGlobalLock) {
4555 updateEventDispatchingLocked(booted);
4556 }
4557 }
4558
4559 boolean canShowErrorDialogs() {
4560 return mShowDialogs && !mSleeping && !mShuttingDown
4561 && !mKeyguardController.isKeyguardOrAodShowing(DEFAULT_DISPLAY)
4562 && !hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
Wale Ogunwale86b74462018-07-02 08:42:43 -07004563 mAmInternal.getCurrentUserId())
Wale Ogunwalef6733932018-06-27 05:14:34 -07004564 && !(UserManager.isDeviceInDemoMode(mContext)
Wale Ogunwale86b74462018-07-02 08:42:43 -07004565 && mAmInternal.getCurrentUser().isDemo());
Wale Ogunwalef6733932018-06-27 05:14:34 -07004566 }
4567
Wale Ogunwale906f9c62018-07-23 11:23:44 -07004568 static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
4569 if (r == null || !r.hasProcess()) {
4570 return KEY_DISPATCHING_TIMEOUT_MS;
4571 }
4572 return getInputDispatchingTimeoutLocked(r.app);
4573 }
4574
4575 private static long getInputDispatchingTimeoutLocked(WindowProcessController r) {
4576 if (r != null && (r.isInstrumenting() || r.isUsingWrapper())) {
4577 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS;
4578 }
4579 return KEY_DISPATCHING_TIMEOUT_MS;
4580 }
4581
4582 long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
4583 if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
4584 throw new SecurityException("Requires permission " + FILTER_EVENTS);
4585 }
4586 WindowProcessController proc;
4587 long timeout;
4588 synchronized (mGlobalLock) {
4589 proc = mPidMap.get(pid);
4590 timeout = getInputDispatchingTimeoutLocked(proc);
4591 }
4592
4593 if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
4594 return -1;
4595 }
4596
4597 return timeout;
4598 }
4599
4600 /**
4601 * Handle input dispatching timeouts.
4602 * Returns whether input dispatching should be aborted or not.
4603 */
4604 boolean inputDispatchingTimedOut(final WindowProcessController proc,
4605 final ActivityRecord activity, final ActivityRecord parent,
4606 final boolean aboveSystem, String reason) {
4607 if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
4608 throw new SecurityException("Requires permission " + FILTER_EVENTS);
4609 }
4610
4611 final String annotation;
4612 if (reason == null) {
4613 annotation = "Input dispatching timed out";
4614 } else {
4615 annotation = "Input dispatching timed out (" + reason + ")";
4616 }
4617
4618 if (proc != null) {
4619 synchronized (mGlobalLock) {
4620 if (proc.isDebugging()) {
4621 return false;
4622 }
4623
4624 if (proc.isInstrumenting()) {
4625 Bundle info = new Bundle();
4626 info.putString("shortMsg", "keyDispatchingTimedOut");
4627 info.putString("longMsg", annotation);
4628 mAm.finishInstrumentationLocked(
4629 (ProcessRecord) proc.mOwner, Activity.RESULT_CANCELED, info);
4630 return true;
4631 }
4632 }
4633 mH.post(() -> {
4634 mAm.mAppErrors.appNotResponding(
4635 (ProcessRecord) proc.mOwner, activity, parent, aboveSystem, annotation);
4636 });
4637 }
4638
4639 return true;
4640 }
4641
Wale Ogunwalef6733932018-06-27 05:14:34 -07004642 /**
4643 * Decide based on the configuration whether we should show the ANR,
4644 * crash, etc dialogs. The idea is that if there is no affordance to
4645 * press the on-screen buttons, or the user experience would be more
4646 * greatly impacted than the crash itself, we shouldn't show the dialog.
4647 *
4648 * A thought: SystemUI might also want to get told about this, the Power
4649 * dialog / global actions also might want different behaviors.
4650 */
4651 private void updateShouldShowDialogsLocked(Configuration config) {
4652 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
4653 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
4654 && config.navigation == Configuration.NAVIGATION_NONAV);
4655 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
4656 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
4657 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
4658 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
4659 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
4660 final boolean hideDialogsSet = Settings.Global.getInt(mContext.getContentResolver(),
4661 HIDE_ERROR_DIALOGS, 0) != 0;
4662 mShowDialogs = inputMethodExists && uiModeSupportsDialogs && !hideDialogsSet;
4663 }
4664
4665 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
4666 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
4667 FONT_SCALE, 1.0f, userId);
4668
4669 synchronized (this) {
4670 if (getGlobalConfiguration().fontScale == scaleFactor) {
4671 return;
4672 }
4673
4674 final Configuration configuration
4675 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
4676 configuration.fontScale = scaleFactor;
4677 updatePersistentConfiguration(configuration, userId);
4678 }
4679 }
4680
4681 // Actually is sleeping or shutting down or whatever else in the future
4682 // is an inactive state.
4683 boolean isSleepingOrShuttingDownLocked() {
4684 return isSleepingLocked() || mShuttingDown;
4685 }
4686
4687 boolean isSleepingLocked() {
4688 return mSleeping;
4689 }
4690
Riddle Hsu16567132018-08-16 21:37:47 +08004691 /** Update AMS states when an activity is resumed. */
Wale Ogunwalef6733932018-06-27 05:14:34 -07004692 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
4693 final TaskRecord task = r.getTask();
4694 if (task.isActivityTypeStandard()) {
4695 if (mCurAppTimeTracker != r.appTimeTracker) {
4696 // We are switching app tracking. Complete the current one.
4697 if (mCurAppTimeTracker != null) {
4698 mCurAppTimeTracker.stop();
4699 mH.obtainMessage(
4700 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
4701 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
4702 mCurAppTimeTracker = null;
4703 }
4704 if (r.appTimeTracker != null) {
4705 mCurAppTimeTracker = r.appTimeTracker;
4706 startTimeTrackingFocusedActivityLocked();
4707 }
4708 } else {
4709 startTimeTrackingFocusedActivityLocked();
4710 }
4711 } else {
4712 r.appTimeTracker = null;
4713 }
4714 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
4715 // TODO: Probably not, because we don't want to resume voice on switching
4716 // back to this activity
4717 if (task.voiceInteractor != null) {
4718 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
4719 } else {
4720 finishRunningVoiceLocked();
4721
4722 if (mLastResumedActivity != null) {
4723 final IVoiceInteractionSession session;
4724
4725 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
4726 if (lastResumedActivityTask != null
4727 && lastResumedActivityTask.voiceSession != null) {
4728 session = lastResumedActivityTask.voiceSession;
4729 } else {
4730 session = mLastResumedActivity.voiceSession;
4731 }
4732
4733 if (session != null) {
4734 // We had been in a voice interaction session, but now focused has
4735 // move to something different. Just finish the session, we can't
4736 // return to it and retain the proper state and synchronization with
4737 // the voice interaction service.
4738 finishVoiceTask(session);
4739 }
4740 }
4741 }
4742
4743 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
4744 mAmInternal.sendForegroundProfileChanged(r.userId);
4745 }
4746 updateResumedAppTrace(r);
4747 mLastResumedActivity = r;
4748
Riddle Hsu3026e8d2018-08-03 15:50:53 +08004749 // TODO(b/111361570): Support multiple focused apps in WM
Wale Ogunwalef6733932018-06-27 05:14:34 -07004750 mWindowManager.setFocusedApp(r.appToken, true);
4751
4752 applyUpdateLockStateLocked(r);
4753 applyUpdateVrModeLocked(r);
4754
4755 EventLogTags.writeAmSetResumedActivity(
4756 r == null ? -1 : r.userId,
4757 r == null ? "NULL" : r.shortComponentName,
4758 reason);
4759 }
4760
4761 ActivityTaskManagerInternal.SleepToken acquireSleepToken(String tag, int displayId) {
4762 synchronized (mGlobalLock) {
4763 final ActivityTaskManagerInternal.SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
4764 updateSleepIfNeededLocked();
4765 return token;
4766 }
4767 }
4768
4769 void updateSleepIfNeededLocked() {
4770 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
4771 final boolean wasSleeping = mSleeping;
4772 boolean updateOomAdj = false;
4773
4774 if (!shouldSleep) {
4775 // If wasSleeping is true, we need to wake up activity manager state from when
4776 // we started sleeping. In either case, we need to apply the sleep tokens, which
4777 // will wake up stacks or put them to sleep as appropriate.
4778 if (wasSleeping) {
4779 mSleeping = false;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07004780 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
4781 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__AWAKE);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004782 startTimeTrackingFocusedActivityLocked();
4783 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
4784 mStackSupervisor.comeOutOfSleepIfNeededLocked();
4785 }
4786 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
4787 if (wasSleeping) {
4788 updateOomAdj = true;
4789 }
4790 } else if (!mSleeping && shouldSleep) {
4791 mSleeping = true;
Chenjie Yubd1a28f2018-07-17 14:55:19 -07004792 StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
4793 StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__ASLEEP);
Wale Ogunwalef6733932018-06-27 05:14:34 -07004794 if (mCurAppTimeTracker != null) {
4795 mCurAppTimeTracker.stop();
4796 }
4797 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
4798 mStackSupervisor.goingToSleepLocked();
4799 updateResumedAppTrace(null /* resumed */);
4800 updateOomAdj = true;
4801 }
4802 if (updateOomAdj) {
4803 mH.post(mAmInternal::updateOomAdj);
4804 }
4805 }
4806
4807 void updateOomAdj() {
4808 mH.post(mAmInternal::updateOomAdj);
4809 }
4810
Andrii Kulian52d255c2018-07-13 11:32:19 -07004811 // TODO(b/111541062): Update app time tracking to make it aware of multiple resumed activities
Wale Ogunwalef6733932018-06-27 05:14:34 -07004812 private void startTimeTrackingFocusedActivityLocked() {
Andrii Kulian52d255c2018-07-13 11:32:19 -07004813 final ActivityRecord resumedActivity = mStackSupervisor.getTopResumedActivity();
Wale Ogunwalef6733932018-06-27 05:14:34 -07004814 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
4815 mCurAppTimeTracker.start(resumedActivity.packageName);
4816 }
4817 }
4818
4819 private void updateResumedAppTrace(@Nullable ActivityRecord resumed) {
4820 if (mTracedResumedActivity != null) {
4821 Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER,
4822 constructResumedTraceName(mTracedResumedActivity.packageName), 0);
4823 }
4824 if (resumed != null) {
4825 Trace.asyncTraceBegin(TRACE_TAG_ACTIVITY_MANAGER,
4826 constructResumedTraceName(resumed.packageName), 0);
4827 }
4828 mTracedResumedActivity = resumed;
4829 }
4830
4831 private String constructResumedTraceName(String packageName) {
4832 return "focused app: " + packageName;
4833 }
4834
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004835 /** Helper method that requests bounds from WM and applies them to stack. */
4836 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
4837 final Rect newStackBounds = new Rect();
4838 final ActivityStack stack = mStackSupervisor.getStack(stackId);
4839
4840 // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
4841 if (stack == null) {
4842 final StringWriter writer = new StringWriter();
4843 final PrintWriter printWriter = new PrintWriter(writer);
4844 mStackSupervisor.dumpDisplays(printWriter);
4845 printWriter.flush();
4846
4847 Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
4848 }
4849
4850 stack.getBoundsForNewConfiguration(newStackBounds);
4851 mStackSupervisor.resizeStackLocked(
4852 stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
4853 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
4854 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
4855 }
4856
4857 /** Applies latest configuration and/or visibility updates if needed. */
4858 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
4859 boolean kept = true;
Andrii Kulian5f750bc2018-07-17 08:57:23 -07004860 final ActivityStack mainStack = mStackSupervisor.getTopDisplayFocusedStack();
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004861 // mainStack is null during startup.
4862 if (mainStack != null) {
4863 if (changes != 0 && starting == null) {
4864 // If the configuration changed, and the caller is not already
4865 // in the process of starting an activity, then find the top
4866 // activity to check if its configuration needs to change.
4867 starting = mainStack.topRunningActivityLocked();
4868 }
4869
4870 if (starting != null) {
4871 kept = starting.ensureActivityConfiguration(changes,
4872 false /* preserveWindow */);
4873 // And we need to make sure at this point that all other activities
4874 // are made visible with the correct configuration.
4875 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
4876 !PRESERVE_WINDOWS);
4877 }
4878 }
4879
4880 return kept;
4881 }
4882
Wale Ogunwale906f9c62018-07-23 11:23:44 -07004883 void scheduleAppGcsLocked() {
4884 mH.post(() -> mAmInternal.scheduleAppGcs());
4885 }
4886
4887 /**
4888 * Returns the PackageManager. Used by classes hosted by {@link ActivityTaskManagerService}. The
4889 * PackageManager could be unavailable at construction time and therefore needs to be accessed
4890 * on demand.
4891 */
4892 IPackageManager getPackageManager() {
4893 return AppGlobals.getPackageManager();
4894 }
4895
4896 PackageManagerInternal getPackageManagerInternalLocked() {
4897 if (mPmInternal == null) {
4898 mPmInternal = LocalServices.getService(PackageManagerInternal.class);
4899 }
4900 return mPmInternal;
4901 }
4902
Wale Ogunwale008163e2018-07-23 23:11:08 -07004903 AppWarnings getAppWarningsLocked() {
4904 return mAppWarnings;
4905 }
4906
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004907 void logAppTooSlow(WindowProcessController app, long startTime, String msg) {
4908 if (true || Build.IS_USER) {
4909 return;
4910 }
4911
4912 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4913 StrictMode.allowThreadDiskWrites();
4914 try {
4915 File tracesDir = new File("/data/anr");
4916 File tracesFile = null;
4917 try {
4918 tracesFile = File.createTempFile("app_slow", null, tracesDir);
4919
4920 StringBuilder sb = new StringBuilder();
4921 Time tobj = new Time();
4922 tobj.set(System.currentTimeMillis());
4923 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4924 sb.append(": ");
4925 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4926 sb.append(" since ");
4927 sb.append(msg);
4928 FileOutputStream fos = new FileOutputStream(tracesFile);
4929 fos.write(sb.toString().getBytes());
4930 if (app == null) {
4931 fos.write("\n*** No application process!".getBytes());
4932 }
4933 fos.close();
4934 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4935 } catch (IOException e) {
4936 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesFile, e);
4937 return;
4938 }
4939
4940 if (app != null && app.getPid() > 0) {
4941 ArrayList<Integer> firstPids = new ArrayList<Integer>();
4942 firstPids.add(app.getPid());
4943 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, null, null);
4944 }
4945
4946 File lastTracesFile = null;
4947 File curTracesFile = null;
4948 for (int i=9; i>=0; i--) {
4949 String name = String.format(Locale.US, "slow%02d.txt", i);
4950 curTracesFile = new File(tracesDir, name);
4951 if (curTracesFile.exists()) {
4952 if (lastTracesFile != null) {
4953 curTracesFile.renameTo(lastTracesFile);
4954 } else {
4955 curTracesFile.delete();
4956 }
4957 }
4958 lastTracesFile = curTracesFile;
4959 }
4960 tracesFile.renameTo(curTracesFile);
4961 } finally {
4962 StrictMode.setThreadPolicy(oldPolicy);
4963 }
4964 }
4965
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004966 final class H extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07004967 static final int REPORT_TIME_TRACKER_MSG = 1;
4968
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004969 public H(Looper looper) {
4970 super(looper, null, true);
4971 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004972
4973 @Override
4974 public void handleMessage(Message msg) {
4975 switch (msg.what) {
4976 case REPORT_TIME_TRACKER_MSG: {
4977 AppTimeTracker tracker = (AppTimeTracker) msg.obj;
4978 tracker.deliverResult(mContext);
4979 } break;
4980 }
4981 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07004982 }
4983
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004984 final class UiHandler extends Handler {
Wale Ogunwalef6733932018-06-27 05:14:34 -07004985 static final int DISMISS_DIALOG_UI_MSG = 1;
Wale Ogunwalea6191b42018-05-09 07:41:32 -07004986
4987 public UiHandler() {
4988 super(com.android.server.UiThread.get().getLooper(), null, true);
4989 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07004990
4991 @Override
4992 public void handleMessage(Message msg) {
4993 switch (msg.what) {
4994 case DISMISS_DIALOG_UI_MSG: {
4995 final Dialog d = (Dialog) msg.obj;
4996 d.dismiss();
4997 break;
4998 }
4999 }
5000 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005001 }
5002
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005003 final class LocalService extends ActivityTaskManagerInternal {
5004 @Override
5005 public SleepToken acquireSleepToken(String tag, int displayId) {
5006 Preconditions.checkNotNull(tag);
Wale Ogunwalef6733932018-06-27 05:14:34 -07005007 return ActivityTaskManagerService.this.acquireSleepToken(tag, displayId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005008 }
5009
5010 @Override
5011 public ComponentName getHomeActivityForUser(int userId) {
5012 synchronized (mGlobalLock) {
5013 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
5014 return homeActivity == null ? null : homeActivity.realActivity;
5015 }
5016 }
5017
5018 @Override
5019 public void onLocalVoiceInteractionStarted(IBinder activity,
5020 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
5021 synchronized (mGlobalLock) {
Wale Ogunwalef6733932018-06-27 05:14:34 -07005022 onLocalVoiceInteractionStartedLocked(activity, voiceSession, voiceInteractor);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005023 }
5024 }
5025
5026 @Override
5027 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
5028 synchronized (mGlobalLock) {
5029 mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
5030 reasons, timestamp);
5031 }
5032 }
5033
5034 @Override
5035 public void notifyAppTransitionFinished() {
5036 synchronized (mGlobalLock) {
5037 mStackSupervisor.notifyAppTransitionDone();
5038 }
5039 }
5040
5041 @Override
5042 public void notifyAppTransitionCancelled() {
5043 synchronized (mGlobalLock) {
5044 mStackSupervisor.notifyAppTransitionDone();
5045 }
5046 }
5047
5048 @Override
5049 public List<IBinder> getTopVisibleActivities() {
5050 synchronized (mGlobalLock) {
5051 return mStackSupervisor.getTopVisibleActivities();
5052 }
5053 }
5054
5055 @Override
5056 public void notifyDockedStackMinimizedChanged(boolean minimized) {
5057 synchronized (mGlobalLock) {
5058 mStackSupervisor.setDockedStackMinimized(minimized);
5059 }
5060 }
5061
5062 @Override
5063 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
5064 Bundle bOptions) {
5065 Preconditions.checkNotNull(intents, "intents");
5066 final String[] resolvedTypes = new String[intents.length];
5067
5068 // UID of the package on user userId.
5069 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
5070 // packageUid may not be initialized.
5071 int packageUid = 0;
5072 final long ident = Binder.clearCallingIdentity();
5073
5074 try {
5075 for (int i = 0; i < intents.length; i++) {
5076 resolvedTypes[i] =
5077 intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
5078 }
5079
5080 packageUid = AppGlobals.getPackageManager().getPackageUid(
5081 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
5082 } catch (RemoteException e) {
5083 // Shouldn't happen.
5084 } finally {
5085 Binder.restoreCallingIdentity(ident);
5086 }
5087
5088 synchronized (mGlobalLock) {
Wale Ogunwale5fa8a8c2018-05-08 13:43:21 -07005089 return getActivityStartController().startActivitiesInPackage(
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005090 packageUid, packageName,
5091 intents, resolvedTypes, null /* resultTo */,
5092 SafeActivityOptions.fromBundle(bOptions), userId,
Michal Karpinski201bc0c2018-07-20 15:32:00 +01005093 false /* validateIncomingUser */, null /* originatingPendingIntent */);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005094 }
5095 }
5096
5097 @Override
5098 public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
5099 Intent intent, Bundle options, int userId) {
5100 return ActivityTaskManagerService.this.startActivityAsUser(
5101 caller, callerPacakge, intent,
5102 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
5103 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
5104 false /*validateIncomingUser*/);
5105 }
5106
5107 @Override
5108 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
5109 synchronized (mGlobalLock) {
5110
5111 // We might change the visibilities here, so prepare an empty app transition which
5112 // might be overridden later if we actually change visibilities.
5113 final boolean wasTransitionSet =
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005114 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005115 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005116 mWindowManager.prepareAppTransition(TRANSIT_NONE,
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005117 false /* alwaysKeepCurrent */);
5118 }
5119 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5120
5121 // If there was a transition set already we don't want to interfere with it as we
5122 // might be starting it too early.
5123 if (!wasTransitionSet) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005124 mWindowManager.executeAppTransition();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005125 }
5126 }
5127 if (callback != null) {
5128 callback.run();
5129 }
5130 }
5131
5132 @Override
5133 public void notifyKeyguardTrustedChanged() {
5134 synchronized (mGlobalLock) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005135 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005136 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5137 }
5138 }
5139 }
5140
5141 /**
5142 * Called after virtual display Id is updated by
5143 * {@link com.android.server.vr.Vr2dDisplay} with a specific
5144 * {@param vrVr2dDisplayId}.
5145 */
5146 @Override
5147 public void setVr2dDisplayId(int vr2dDisplayId) {
5148 if (DEBUG_STACK) Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
5149 synchronized (mGlobalLock) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005150 mVr2dDisplayId = vr2dDisplayId;
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005151 }
5152 }
5153
5154 @Override
5155 public void setFocusedActivity(IBinder token) {
5156 synchronized (mGlobalLock) {
5157 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
5158 if (r == null) {
5159 throw new IllegalArgumentException(
5160 "setFocusedActivity: No activity record matching token=" + token);
5161 }
5162 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
5163 r, "setFocusedActivity")) {
Andrii Kulianab132ee2018-07-24 22:10:21 +08005164 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005165 }
5166 }
5167 }
5168
5169 @Override
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005170 public void registerScreenObserver(ScreenObserver observer) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005171 mScreenObservers.add(observer);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005172 }
5173
5174 @Override
5175 public boolean isCallerRecents(int callingUid) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005176 return getRecentTasks().isCallerRecents(callingUid);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005177 }
5178
5179 @Override
5180 public boolean isRecentsComponentHomeActivity(int userId) {
Wale Ogunwale16e505a2018-05-07 15:00:49 -07005181 return getRecentTasks().isRecentsComponentHomeActivity(userId);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005182 }
5183
5184 @Override
5185 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
5186 ActivityTaskManagerService.this.cancelRecentsAnimation(restoreHomeStackPosition);
5187 }
5188
5189 @Override
5190 public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005191 ActivityTaskManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005192 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07005193
5194 @Override
5195 public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
5196 synchronized (mGlobalLock) {
5197 mActiveVoiceInteractionServiceComponent = component;
5198 }
5199 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -07005200
5201 @Override
5202 public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
5203 if (!mAmInternal.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
5204 return;
5205 }
5206 synchronized (mGlobalLock) {
5207 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
5208 if (types == null) {
5209 if (uid < 0) {
5210 return;
5211 }
5212 types = new ArrayMap<>();
5213 mAllowAppSwitchUids.put(userId, types);
5214 }
5215 if (uid < 0) {
5216 types.remove(type);
5217 } else {
5218 types.put(type, uid);
5219 }
5220 }
5221 }
5222
5223 @Override
5224 public void onUserStopped(int userId) {
5225 synchronized (mGlobalLock) {
5226 getRecentTasks().unloadUserDataFromMemoryLocked(userId);
5227 mAllowAppSwitchUids.remove(userId);
5228 }
5229 }
5230
5231 @Override
5232 public boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
5233 synchronized (mGlobalLock) {
5234 return ActivityTaskManagerService.this.isGetTasksAllowed(
5235 caller, callingPid, callingUid);
5236 }
5237 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07005238
5239 @Override
5240 public void onProcessAdded(WindowProcessController proc) {
5241 synchronized (mGlobalLock) {
5242 mProcessNames.put(proc.mName, proc.mUid, proc);
5243 }
5244 }
5245
5246 @Override
5247 public void onProcessRemoved(String name, int uid) {
5248 synchronized (mGlobalLock) {
5249 mProcessNames.remove(name, uid);
5250 }
5251 }
5252
5253 @Override
5254 public void onCleanUpApplicationRecord(WindowProcessController proc) {
5255 synchronized (mGlobalLock) {
5256 if (proc == mHomeProcess) {
5257 mHomeProcess = null;
5258 }
5259 if (proc == mPreviousProcess) {
5260 mPreviousProcess = null;
5261 }
5262 }
5263 }
Wale Ogunwalef6733932018-06-27 05:14:34 -07005264
5265 @Override
5266 public int getTopProcessState() {
5267 synchronized (mGlobalLock) {
5268 return mTopProcessState;
5269 }
5270 }
5271
5272 @Override
5273 public boolean isSleeping() {
5274 synchronized (mGlobalLock) {
5275 return isSleepingLocked();
5276 }
5277 }
5278
5279 @Override
5280 public boolean isShuttingDown() {
5281 synchronized (mGlobalLock) {
5282 return mShuttingDown;
5283 }
5284 }
5285
5286 @Override
5287 public boolean shuttingDown(boolean booted, int timeout) {
5288 synchronized (mGlobalLock) {
5289 mShuttingDown = true;
5290 mStackSupervisor.prepareForShutdownLocked();
5291 updateEventDispatchingLocked(booted);
5292 return mStackSupervisor.shutdownLocked(timeout);
5293 }
5294 }
5295
5296 @Override
5297 public void enableScreenAfterBoot(boolean booted) {
5298 synchronized (mGlobalLock) {
5299 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5300 SystemClock.uptimeMillis());
5301 mWindowManager.enableScreenAfterBoot();
5302 updateEventDispatchingLocked(booted);
5303 }
5304 }
5305
5306 @Override
5307 public boolean showStrictModeViolationDialog() {
5308 synchronized (mGlobalLock) {
5309 return mShowDialogs && !mSleeping && !mShuttingDown;
5310 }
5311 }
5312
5313 @Override
5314 public void showSystemReadyErrorDialogsIfNeeded() {
5315 synchronized (mGlobalLock) {
5316 try {
5317 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
5318 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
5319 + " data partition or your device will be unstable.");
5320 mUiHandler.post(() -> {
5321 if (mShowDialogs) {
5322 AlertDialog d = new BaseErrorDialog(mUiContext);
5323 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5324 d.setCancelable(false);
5325 d.setTitle(mUiContext.getText(R.string.android_system_label));
5326 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
5327 d.setButton(DialogInterface.BUTTON_POSITIVE,
5328 mUiContext.getText(R.string.ok),
5329 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5330 d.show();
5331 }
5332 });
5333 }
5334 } catch (RemoteException e) {
5335 }
5336
5337 if (!Build.isBuildConsistent()) {
5338 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
5339 mUiHandler.post(() -> {
5340 if (mShowDialogs) {
5341 AlertDialog d = new BaseErrorDialog(mUiContext);
5342 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
5343 d.setCancelable(false);
5344 d.setTitle(mUiContext.getText(R.string.android_system_label));
5345 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
5346 d.setButton(DialogInterface.BUTTON_POSITIVE,
5347 mUiContext.getText(R.string.ok),
5348 mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
5349 d.show();
5350 }
5351 });
5352 }
5353 }
5354 }
Wale Ogunwale906f9c62018-07-23 11:23:44 -07005355
5356 @Override
5357 public long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason) {
5358 synchronized (mGlobalLock) {
5359 return ActivityTaskManagerService.this.inputDispatchingTimedOut(
5360 pid, aboveSystem, reason);
5361 }
5362 }
5363
5364 @Override
5365 public void onProcessMapped(int pid, WindowProcessController proc) {
5366 synchronized (mGlobalLock) {
5367 mPidMap.put(pid, proc);
5368 }
5369 }
5370
5371 @Override
5372 public void onProcessUnMapped(int pid) {
5373 synchronized (mGlobalLock) {
5374 mPidMap.remove(pid);
5375 }
5376 }
Wale Ogunwale008163e2018-07-23 23:11:08 -07005377
5378 @Override
5379 public void onPackageDataCleared(String name) {
5380 synchronized (mGlobalLock) {
5381 mAppWarnings.onPackageDataCleared(name);
5382 }
5383 }
5384
5385 @Override
5386 public void onPackageUninstalled(String name) {
5387 synchronized (mGlobalLock) {
5388 mAppWarnings.onPackageUninstalled(name);
5389 }
5390 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07005391 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07005392}