blob: 897fde381f93a240f4f2058b2d8a1354d5e58b3b [file] [log] [blame]
Keun-young Park4727da32016-05-31 10:00:51 -07001/*
2 * Copyright (C) 2016 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 */
16package com.android.car;
17
Yao, Yuxingd525de12019-05-06 15:11:48 -070018import static com.android.car.pm.CarPackageManagerService.BLOCKING_INTENT_EXTRA_DISPLAY_ID;
19
Sudheer Shankaa4f49aa2016-11-10 16:39:13 -080020import android.app.ActivityManager;
Yao, Yuxingcfcc59f2019-03-05 16:35:47 -080021import android.app.ActivityOptions;
Louis Chang3bf2f202020-08-18 13:04:28 +080022import android.app.ActivityTaskManager.RootTaskInfo;
Keun-young Park4727da32016-05-31 10:00:51 -070023import android.app.IActivityManager;
24import android.app.IProcessObserver;
Yorke Leec1265de2016-10-27 11:25:25 -070025import android.app.TaskStackListener;
Keun-young Park4727da32016-05-31 10:00:51 -070026import android.content.ComponentName;
27import android.content.Context;
28import android.content.Intent;
29import android.os.Handler;
30import android.os.HandlerThread;
31import android.os.Looper;
32import android.os.Message;
33import android.os.RemoteException;
34import android.os.UserHandle;
Yao Chened8609e2016-10-07 09:49:13 -070035import android.util.ArrayMap;
Keun-young Park4727da32016-05-31 10:00:51 -070036import android.util.ArraySet;
Felipe Leme176a5fd2021-01-20 15:48:33 -080037import android.util.IndentingPrintWriter;
Keun-young Park4727da32016-05-31 10:00:51 -070038import android.util.Log;
39import android.util.Pair;
Eric Jeongbd5fb562020-12-21 13:49:40 -080040import android.util.Slog;
Keun-young Park4727da32016-05-31 10:00:51 -070041import android.util.SparseArray;
Yao, Yuxingcfcc59f2019-03-05 16:35:47 -080042import android.view.Display;
Keun-young Park4727da32016-05-31 10:00:51 -070043
Yuncheol Heo8b5ab802020-04-09 12:13:44 -070044import com.android.internal.annotations.GuardedBy;
45
Keun young Parkb241d022020-04-20 20:31:34 -070046import java.lang.ref.WeakReference;
Keun-young Park4727da32016-05-31 10:00:51 -070047import java.util.Arrays;
Keun-young Park4727da32016-05-31 10:00:51 -070048import java.util.LinkedList;
49import java.util.List;
50import java.util.Map;
Yao Chened8609e2016-10-07 09:49:13 -070051import java.util.Objects;
Keun-young Park4727da32016-05-31 10:00:51 -070052import java.util.Set;
53
54/**
55 * Service to monitor AMS for new Activity or Service launching.
56 */
57public class SystemActivityMonitoringService implements CarServiceBase {
58
59 /**
60 * Container to hold info on top task in an Activity stack
61 */
62 public static class TopTaskInfoContainer {
63 public final ComponentName topActivity;
64 public final int taskId;
Yao, Yuxingcfcc59f2019-03-05 16:35:47 -080065 public final int displayId;
Yao, Yuxing4ddb2c62019-02-04 11:26:46 -080066 public final int position;
Louis Chang3bf2f202020-08-18 13:04:28 +080067 public final RootTaskInfo taskInfo;
Keun-young Park4727da32016-05-31 10:00:51 -070068
Yao, Yuxing4ddb2c62019-02-04 11:26:46 -080069 private TopTaskInfoContainer(ComponentName topActivity, int taskId,
Louis Chang3bf2f202020-08-18 13:04:28 +080070 int displayId, int position, RootTaskInfo taskInfo) {
Keun-young Park4727da32016-05-31 10:00:51 -070071 this.topActivity = topActivity;
72 this.taskId = taskId;
Yao, Yuxingcfcc59f2019-03-05 16:35:47 -080073 this.displayId = displayId;
Yao, Yuxing4ddb2c62019-02-04 11:26:46 -080074 this.position = position;
Louis Chang3bf2f202020-08-18 13:04:28 +080075 this.taskInfo = taskInfo;
Keun-young Park4727da32016-05-31 10:00:51 -070076 }
77
Yao Chened8609e2016-10-07 09:49:13 -070078 public boolean isMatching(TopTaskInfoContainer taskInfo) {
79 return taskInfo != null
80 && Objects.equals(this.topActivity, taskInfo.topActivity)
81 && this.taskId == taskInfo.taskId
Yao, Yuxingcfcc59f2019-03-05 16:35:47 -080082 && this.displayId == taskInfo.displayId
Yao, Yuxing4ddb2c62019-02-04 11:26:46 -080083 && this.position == taskInfo.position
Louis Chang3bf2f202020-08-18 13:04:28 +080084 && this.taskInfo.userId == taskInfo.taskInfo.userId;
Keun-young Park4727da32016-05-31 10:00:51 -070085 }
86
87 @Override
88 public String toString() {
89 return String.format(
Yao, Yuxing4ddb2c62019-02-04 11:26:46 -080090 "TaskInfoContainer [topActivity=%s, taskId=%d, stackId=%d, userId=%d, "
91 + "displayId=%d, position=%d",
Louis Chang3bf2f202020-08-18 13:04:28 +080092 topActivity, taskId, taskInfo.taskId, taskInfo.userId, displayId, position);
Keun-young Park4727da32016-05-31 10:00:51 -070093 }
94 }
95
96 public interface ActivityLaunchListener {
97 /**
98 * Notify launch of activity.
99 * @param topTask Task information for what is currently launched.
100 */
101 void onActivityLaunch(TopTaskInfoContainer topTask);
102 }
103
Michal Palczewski7684dbb2018-11-13 18:36:06 -0800104 private static final int INVALID_STACK_ID = -1;
Keun-young Park4727da32016-05-31 10:00:51 -0700105 private final Context mContext;
106 private final IActivityManager mAm;
107 private final ProcessObserver mProcessObserver;
108 private final TaskListener mTaskListener;
109
Keun young Parkb241d022020-04-20 20:31:34 -0700110 private final HandlerThread mMonitorHandlerThread = CarServiceUtils.getHandlerThread(
111 getClass().getSimpleName());
112 private final ActivityMonitorHandler mHandler = new ActivityMonitorHandler(
113 mMonitorHandlerThread.getLooper(), this);
Keun-young Park4727da32016-05-31 10:00:51 -0700114
Yuncheol Heo8b5ab802020-04-09 12:13:44 -0700115 private final Object mLock = new Object();
116
Yao, Yuxingd525de12019-05-06 15:11:48 -0700117 /** K: display id, V: top task */
Yuncheol Heo8b5ab802020-04-09 12:13:44 -0700118 @GuardedBy("mLock")
Keun-young Park4727da32016-05-31 10:00:51 -0700119 private final SparseArray<TopTaskInfoContainer> mTopTasks = new SparseArray<>();
120 /** K: uid, V : list of pid */
Yuncheol Heo8b5ab802020-04-09 12:13:44 -0700121 @GuardedBy("mLock")
Yao Chened8609e2016-10-07 09:49:13 -0700122 private final Map<Integer, Set<Integer>> mForegroundUidPids = new ArrayMap<>();
Yuncheol Heo8b5ab802020-04-09 12:13:44 -0700123 @GuardedBy("mLock")
Keun-young Park4727da32016-05-31 10:00:51 -0700124 private ActivityLaunchListener mActivityLaunchListener;
125
126 public SystemActivityMonitoringService(Context context) {
127 mContext = context;
Keun-young Park4727da32016-05-31 10:00:51 -0700128 mProcessObserver = new ProcessObserver();
129 mTaskListener = new TaskListener();
Sudheer Shankaa4f49aa2016-11-10 16:39:13 -0800130 mAm = ActivityManager.getService();
Yuncheol Heob2c78992020-04-28 16:24:56 -0700131 }
132
133 @Override
134 public void init() {
Keun-young Park4727da32016-05-31 10:00:51 -0700135 // Monitoring both listeners are necessary as there are cases where one listener cannot
136 // monitor activity change.
137 try {
138 mAm.registerProcessObserver(mProcessObserver);
139 mAm.registerTaskStackListener(mTaskListener);
140 } catch (RemoteException e) {
Eric Jeongbd5fb562020-12-21 13:49:40 -0800141 Slog.e(CarLog.TAG_AM, "cannot register activity monitoring", e);
Keun-young Park4727da32016-05-31 10:00:51 -0700142 throw new RuntimeException(e);
143 }
144 updateTasks();
145 }
146
147 @Override
Keun-young Park4727da32016-05-31 10:00:51 -0700148 public void release() {
Yuncheol Heob2c78992020-04-28 16:24:56 -0700149 try {
150 mAm.unregisterProcessObserver(mProcessObserver);
151 mAm.unregisterTaskStackListener(mTaskListener);
152 } catch (RemoteException e) {
Eric Jeongbd5fb562020-12-21 13:49:40 -0800153 Slog.e(CarLog.TAG_AM, "Failed to unregister listeners", e);
Yuncheol Heob2c78992020-04-28 16:24:56 -0700154 }
Keun-young Park4727da32016-05-31 10:00:51 -0700155 }
156
157 @Override
Felipe Leme176a5fd2021-01-20 15:48:33 -0800158 public void dump(IndentingPrintWriter writer) {
Keun-young Park4727da32016-05-31 10:00:51 -0700159 writer.println("*SystemActivityMonitoringService*");
Yao, Yuxing4ddb2c62019-02-04 11:26:46 -0800160 writer.println(" Top Tasks per display:");
Yuncheol Heo8b5ab802020-04-09 12:13:44 -0700161 synchronized (mLock) {
Keun-young Park4727da32016-05-31 10:00:51 -0700162 for (int i = 0; i < mTopTasks.size(); i++) {
Yao, Yuxing4ddb2c62019-02-04 11:26:46 -0800163 int displayId = mTopTasks.keyAt(i);
Keun-young Park4727da32016-05-31 10:00:51 -0700164 TopTaskInfoContainer info = mTopTasks.valueAt(i);
165 if (info != null) {
Yao, Yuxing4ddb2c62019-02-04 11:26:46 -0800166 writer.println("display id " + displayId + ": " + info);
Keun-young Park4727da32016-05-31 10:00:51 -0700167 }
168 }
Yao, Yuxing4ddb2c62019-02-04 11:26:46 -0800169 writer.println(" Foreground uid-pids:");
Keun-young Park4727da32016-05-31 10:00:51 -0700170 for (Integer key : mForegroundUidPids.keySet()) {
171 Set<Integer> pids = mForegroundUidPids.get(key);
172 if (pids == null) {
173 continue;
174 }
175 writer.println("uid:" + key + ", pids:" + Arrays.toString(pids.toArray()));
176 }
Keun-young Park4727da32016-05-31 10:00:51 -0700177 }
178 }
179
180 /**
181 * Block the current task: Launch new activity with given Intent and finish the current task.
182 * @param currentTask task to finish
183 * @param newActivityIntent Intent for new Activity
184 */
185 public void blockActivity(TopTaskInfoContainer currentTask, Intent newActivityIntent) {
186 mHandler.requestBlockActivity(currentTask, newActivityIntent);
187 }
188
189 public List<TopTaskInfoContainer> getTopTasks() {
190 LinkedList<TopTaskInfoContainer> tasks = new LinkedList<>();
Yuncheol Heo8b5ab802020-04-09 12:13:44 -0700191 synchronized (mLock) {
Keun-young Park4727da32016-05-31 10:00:51 -0700192 for (int i = 0; i < mTopTasks.size(); i++) {
Yao, Yuxing2646cff2019-04-23 17:01:26 -0700193 TopTaskInfoContainer topTask = mTopTasks.valueAt(i);
194 if (topTask == null) {
Eric Jeongbd5fb562020-12-21 13:49:40 -0800195 Slog.e(CarLog.TAG_AM, "Top tasks contains null. Full content is: "
Yao, Yuxing2646cff2019-04-23 17:01:26 -0700196 + mTopTasks.toString());
197 continue;
198 }
199 tasks.add(topTask);
Keun-young Park4727da32016-05-31 10:00:51 -0700200 }
201 }
202 return tasks;
203 }
204
205 public boolean isInForeground(int pid, int uid) {
Yuncheol Heo8b5ab802020-04-09 12:13:44 -0700206 synchronized (mLock) {
Keun-young Park4727da32016-05-31 10:00:51 -0700207 Set<Integer> pids = mForegroundUidPids.get(uid);
208 if (pids == null) {
209 return false;
210 }
211 if (pids.contains(pid)) {
212 return true;
213 }
214 }
215 return false;
216 }
217
Yao, Yuxingd1d6a372018-05-08 10:37:43 -0700218 /**
219 * Attempts to restart a task.
220 *
221 * <p>Restarts a task by sending an empty intent with flag
222 * {@link Intent#FLAG_ACTIVITY_CLEAR_TASK} to its root activity. If the task does not exist,
223 * do nothing.
224 *
225 * @param taskId id of task to be restarted.
226 */
227 public void restartTask(int taskId) {
228 String rootActivityName = null;
229 int userId = 0;
230 try {
231 findRootActivityName:
Louis Chang3bf2f202020-08-18 13:04:28 +0800232 for (RootTaskInfo info : mAm.getAllRootTaskInfos()) {
233 for (int i = 0; i < info.childTaskIds.length; i++) {
234 if (info.childTaskIds[i] == taskId) {
235 rootActivityName = info.childTaskNames[i];
Yao, Yuxingd1d6a372018-05-08 10:37:43 -0700236 userId = info.userId;
237 if (Log.isLoggable(CarLog.TAG_AM, Log.DEBUG)) {
Eric Jeongbd5fb562020-12-21 13:49:40 -0800238 Slog.d(CarLog.TAG_AM, "Root activity is " + rootActivityName);
239 Slog.d(CarLog.TAG_AM, "User id is " + userId);
Yao, Yuxingd1d6a372018-05-08 10:37:43 -0700240 }
241 // Break out of nested loop.
242 break findRootActivityName;
243 }
244 }
245 }
246 } catch (RemoteException e) {
Eric Jeongbd5fb562020-12-21 13:49:40 -0800247 Slog.e(CarLog.TAG_AM, "Could not get stack info", e);
Yao, Yuxingd1d6a372018-05-08 10:37:43 -0700248 return;
249 }
250
251 if (rootActivityName == null) {
Eric Jeongbd5fb562020-12-21 13:49:40 -0800252 Slog.e(CarLog.TAG_AM, "Could not find root activity with task id " + taskId);
Yao, Yuxingd1d6a372018-05-08 10:37:43 -0700253 return;
254 }
255
256 Intent rootActivityIntent = new Intent();
257 rootActivityIntent.setComponent(ComponentName.unflattenFromString(rootActivityName));
258 // Clear the task the root activity is running in and start it in a new task.
259 // Effectively restart root activity.
260 rootActivityIntent.addFlags(
261 Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
262
263 if (Log.isLoggable(CarLog.TAG_AM, Log.INFO)) {
Eric Jeongbd5fb562020-12-21 13:49:40 -0800264 Slog.i(CarLog.TAG_AM, "restarting root activity with user id " + userId);
Yao, Yuxingd1d6a372018-05-08 10:37:43 -0700265 }
266 mContext.startActivityAsUser(rootActivityIntent, new UserHandle(userId));
267 }
268
Keun-young Park4727da32016-05-31 10:00:51 -0700269 public void registerActivityLaunchListener(ActivityLaunchListener listener) {
Yuncheol Heo8b5ab802020-04-09 12:13:44 -0700270 synchronized (mLock) {
Keun-young Park4727da32016-05-31 10:00:51 -0700271 mActivityLaunchListener = listener;
272 }
273 }
274
275 private void updateTasks() {
Louis Chang3bf2f202020-08-18 13:04:28 +0800276 List<RootTaskInfo> infos;
Keun-young Park4727da32016-05-31 10:00:51 -0700277 try {
Louis Chang3bf2f202020-08-18 13:04:28 +0800278 infos = mAm.getAllRootTaskInfos();
Keun-young Park4727da32016-05-31 10:00:51 -0700279 } catch (RemoteException e) {
Eric Jeongbd5fb562020-12-21 13:49:40 -0800280 Slog.e(CarLog.TAG_AM, "cannot getTasks", e);
Keun-young Park4727da32016-05-31 10:00:51 -0700281 return;
282 }
tadvana3b9ed202019-07-17 19:21:28 -0700283
284 if (infos == null) {
285 return;
286 }
287
Michal Palczewski7684dbb2018-11-13 18:36:06 -0800288 int focusedStackId = INVALID_STACK_ID;
Keun-young Park4727da32016-05-31 10:00:51 -0700289 try {
Wale Ogunwale9a000b92017-09-26 11:05:02 -0700290 // TODO(b/66955160): Someone on the Auto-team should probably re-work the code in the
291 // synchronized block below based on this new API.
Louis Chang3bf2f202020-08-18 13:04:28 +0800292 final RootTaskInfo focusedTaskInfo = mAm.getFocusedRootTaskInfo();
293 if (focusedTaskInfo != null) {
294 focusedStackId = focusedTaskInfo.taskId;
Wale Ogunwale9a000b92017-09-26 11:05:02 -0700295 }
Keun-young Park4727da32016-05-31 10:00:51 -0700296 } catch (RemoteException e) {
Eric Jeongbd5fb562020-12-21 13:49:40 -0800297 Slog.e(CarLog.TAG_AM, "cannot getFocusedStackId", e);
Keun-young Park4727da32016-05-31 10:00:51 -0700298 return;
299 }
Yao, Yuxing4ddb2c62019-02-04 11:26:46 -0800300
301 SparseArray<TopTaskInfoContainer> topTasks = new SparseArray<>();
Keun-young Park4727da32016-05-31 10:00:51 -0700302 ActivityLaunchListener listener;
Yuncheol Heo8b5ab802020-04-09 12:13:44 -0700303 synchronized (mLock) {
304 mTopTasks.clear();
Keun-young Park4727da32016-05-31 10:00:51 -0700305 listener = mActivityLaunchListener;
Yao, Yuxingf4ed5282019-04-09 13:37:59 -0700306
Louis Chang3bf2f202020-08-18 13:04:28 +0800307 for (RootTaskInfo info : infos) {
Yao, Yuxing4ddb2c62019-02-04 11:26:46 -0800308 int displayId = info.displayId;
Louis Chang3bf2f202020-08-18 13:04:28 +0800309 if (info.childTaskNames.length == 0
310 || !info.visible) { // empty stack or not shown
Keun-young Park4727da32016-05-31 10:00:51 -0700311 continue;
312 }
Yao Chened8609e2016-10-07 09:49:13 -0700313 TopTaskInfoContainer newTopTaskInfo = new TopTaskInfoContainer(
Louis Chang3bf2f202020-08-18 13:04:28 +0800314 info.topActivity, info.childTaskIds[info.childTaskIds.length - 1],
Yao, Yuxing4ddb2c62019-02-04 11:26:46 -0800315 info.displayId, info.position, info);
316 TopTaskInfoContainer currentTopTaskInfo = topTasks.get(displayId);
Yao Chened8609e2016-10-07 09:49:13 -0700317
Keun-young Park4727da32016-05-31 10:00:51 -0700318 if (currentTopTaskInfo == null ||
Yao, Yuxing4ddb2c62019-02-04 11:26:46 -0800319 newTopTaskInfo.position > currentTopTaskInfo.position) {
320 topTasks.put(displayId, newTopTaskInfo);
Yao, Yuxingd1d6a372018-05-08 10:37:43 -0700321 if (Log.isLoggable(CarLog.TAG_AM, Log.INFO)) {
Eric Jeongbd5fb562020-12-21 13:49:40 -0800322 Slog.i(CarLog.TAG_AM, "Updating top task to: " + newTopTaskInfo);
Keun-young Park4727da32016-05-31 10:00:51 -0700323 }
324 }
325 }
Yao, Yuxing4ddb2c62019-02-04 11:26:46 -0800326 // Assuming displays remains the same.
327 for (int i = 0; i < topTasks.size(); i++) {
Yao, Yuxing2646cff2019-04-23 17:01:26 -0700328 TopTaskInfoContainer topTask = topTasks.valueAt(i);
Yao, Yuxingf4ed5282019-04-09 13:37:59 -0700329
Yao, Yuxing4ddb2c62019-02-04 11:26:46 -0800330 int displayId = topTasks.keyAt(i);
Yao, Yuxingf4ed5282019-04-09 13:37:59 -0700331 mTopTasks.put(displayId, topTask);
Michal Palczewski7684dbb2018-11-13 18:36:06 -0800332 }
Keun-young Park4727da32016-05-31 10:00:51 -0700333 }
334 if (listener != null) {
Yao, Yuxingf4ed5282019-04-09 13:37:59 -0700335 for (int i = 0; i < topTasks.size(); i++) {
336 TopTaskInfoContainer topTask = topTasks.valueAt(i);
337
Yao, Yuxingd1d6a372018-05-08 10:37:43 -0700338 if (Log.isLoggable(CarLog.TAG_AM, Log.INFO)) {
Eric Jeongbd5fb562020-12-21 13:49:40 -0800339 Slog.i(CarLog.TAG_AM, "Notifying about top task: " + topTask.toString());
Keun-young Park4727da32016-05-31 10:00:51 -0700340 }
341 listener.onActivityLaunch(topTask);
342 }
343 }
344 }
345
Louis Chang3bf2f202020-08-18 13:04:28 +0800346 public RootTaskInfo getFocusedStackForTopActivity(ComponentName activity) {
347 RootTaskInfo focusedStack;
Keun-young Park4727da32016-05-31 10:00:51 -0700348 try {
Louis Chang3bf2f202020-08-18 13:04:28 +0800349 focusedStack = mAm.getFocusedRootTaskInfo();
Keun-young Park4727da32016-05-31 10:00:51 -0700350 } catch (RemoteException e) {
Eric Jeongbd5fb562020-12-21 13:49:40 -0800351 Slog.e(CarLog.TAG_AM, "cannot getFocusedStackId", e);
Keun-young Park4727da32016-05-31 10:00:51 -0700352 return null;
353 }
Louis Chang3bf2f202020-08-18 13:04:28 +0800354 if (focusedStack.childTaskNames.length == 0) { // nothing in focused stack
Keun-young Park4727da32016-05-31 10:00:51 -0700355 return null;
356 }
357 ComponentName topActivity = ComponentName.unflattenFromString(
Louis Chang3bf2f202020-08-18 13:04:28 +0800358 focusedStack.childTaskNames[focusedStack.childTaskNames.length - 1]);
Keun-young Park4727da32016-05-31 10:00:51 -0700359 if (topActivity.equals(activity)) {
360 return focusedStack;
361 } else {
362 return null;
363 }
364 }
365
366 private void handleForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
Yuncheol Heo8b5ab802020-04-09 12:13:44 -0700367 synchronized (mLock) {
Keun-young Park4727da32016-05-31 10:00:51 -0700368 if (foregroundActivities) {
369 Set<Integer> pids = mForegroundUidPids.get(uid);
370 if (pids == null) {
371 pids = new ArraySet<Integer>();
372 mForegroundUidPids.put(uid, pids);
373 }
374 pids.add(pid);
375 } else {
376 doHandlePidGoneLocked(pid, uid);
377 }
378 }
379 }
380
381 private void handleProcessDied(int pid, int uid) {
Yuncheol Heo8b5ab802020-04-09 12:13:44 -0700382 synchronized (mLock) {
Keun-young Park4727da32016-05-31 10:00:51 -0700383 doHandlePidGoneLocked(pid, uid);
384 }
385 }
386
387 private void doHandlePidGoneLocked(int pid, int uid) {
388 Set<Integer> pids = mForegroundUidPids.get(uid);
389 if (pids != null) {
390 pids.remove(pid);
391 if (pids.isEmpty()) {
392 mForegroundUidPids.remove(uid);
393 }
394 }
395 }
396
Ram Periathiruvadiffcdb842018-04-16 17:17:39 -0700397 /**
398 * block the current task with the provided new activity.
399 */
Keun-young Park4727da32016-05-31 10:00:51 -0700400 private void handleBlockActivity(TopTaskInfoContainer currentTask, Intent newActivityIntent) {
Yao, Yuxingd525de12019-05-06 15:11:48 -0700401 int displayId = newActivityIntent.getIntExtra(BLOCKING_INTENT_EXTRA_DISPLAY_ID,
402 Display.DEFAULT_DISPLAY);
403 if (Log.isLoggable(CarLog.TAG_AM, Log.DEBUG)) {
Eric Jeongbd5fb562020-12-21 13:49:40 -0800404 Slog.d(CarLog.TAG_AM, "Launching blocking activity on display: " + displayId);
Yao, Yuxingd525de12019-05-06 15:11:48 -0700405 }
Yao, Yuxingcfcc59f2019-03-05 16:35:47 -0800406
Yao, Yuxingd525de12019-05-06 15:11:48 -0700407 ActivityOptions options = ActivityOptions.makeBasic();
408 options.setLaunchDisplayId(displayId);
Yao, Yuxingcfcc59f2019-03-05 16:35:47 -0800409 mContext.startActivityAsUser(newActivityIntent, options.toBundle(),
Louis Chang3bf2f202020-08-18 13:04:28 +0800410 new UserHandle(currentTask.taskInfo.userId));
Yao, Yuxingd1d6a372018-05-08 10:37:43 -0700411 // Now make stack with new activity focused.
Keun-young Park4727da32016-05-31 10:00:51 -0700412 findTaskAndGrantFocus(newActivityIntent.getComponent());
Keun-young Park4727da32016-05-31 10:00:51 -0700413 }
414
415 private void findTaskAndGrantFocus(ComponentName activity) {
Louis Chang3bf2f202020-08-18 13:04:28 +0800416 List<RootTaskInfo> infos;
Keun-young Park4727da32016-05-31 10:00:51 -0700417 try {
Louis Chang3bf2f202020-08-18 13:04:28 +0800418 infos = mAm.getAllRootTaskInfos();
Keun-young Park4727da32016-05-31 10:00:51 -0700419 } catch (RemoteException e) {
Eric Jeongbd5fb562020-12-21 13:49:40 -0800420 Slog.e(CarLog.TAG_AM, "cannot getTasks", e);
Keun-young Park4727da32016-05-31 10:00:51 -0700421 return;
422 }
Louis Chang3bf2f202020-08-18 13:04:28 +0800423 for (RootTaskInfo info : infos) {
424 if (info.childTaskNames.length == 0) {
Keun-young Park4727da32016-05-31 10:00:51 -0700425 continue;
426 }
427 ComponentName topActivity = ComponentName.unflattenFromString(
Louis Chang3bf2f202020-08-18 13:04:28 +0800428 info.childTaskNames[info.childTaskNames.length - 1]);
Keun-young Park4727da32016-05-31 10:00:51 -0700429 if (activity.equals(topActivity)) {
430 try {
Louis Chang0b8c2022020-09-23 21:42:40 +0800431 mAm.setFocusedRootTask(info.taskId);
Keun-young Park4727da32016-05-31 10:00:51 -0700432 } catch (RemoteException e) {
Eric Jeongbd5fb562020-12-21 13:49:40 -0800433 Slog.e(CarLog.TAG_AM, "cannot setFocusedRootTask to task:" + info.taskId, e);
Keun-young Park4727da32016-05-31 10:00:51 -0700434 }
435 return;
436 }
437 }
Eric Jeongbd5fb562020-12-21 13:49:40 -0800438 Slog.i(CarLog.TAG_AM, "cannot give focus, cannot find Activity:" + activity);
Keun-young Park4727da32016-05-31 10:00:51 -0700439 }
440
441 private class ProcessObserver extends IProcessObserver.Stub {
442 @Override
443 public void onForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
Yao, Yuxingd1d6a372018-05-08 10:37:43 -0700444 if (Log.isLoggable(CarLog.TAG_AM, Log.INFO)) {
Eric Jeongbd5fb562020-12-21 13:49:40 -0800445 Slog.i(CarLog.TAG_AM,
Keun-young Park4727da32016-05-31 10:00:51 -0700446 String.format("onForegroundActivitiesChanged uid %d pid %d fg %b",
447 uid, pid, foregroundActivities));
448 }
449 mHandler.requestForegroundActivitiesChanged(pid, uid, foregroundActivities);
450 }
451
452 @Override
Narayan Kamath4291a192019-03-15 18:49:29 +0000453 public void onForegroundServicesChanged(int pid, int uid, int fgServiceTypes) {
454 }
455
456 @Override
Keun-young Park4727da32016-05-31 10:00:51 -0700457 public void onProcessDied(int pid, int uid) {
458 mHandler.requestProcessDied(pid, uid);
459 }
460 }
461
Yorke Leec1265de2016-10-27 11:25:25 -0700462 private class TaskListener extends TaskStackListener {
Keun-young Park4727da32016-05-31 10:00:51 -0700463 @Override
464 public void onTaskStackChanged() {
Yao, Yuxingd1d6a372018-05-08 10:37:43 -0700465 if (Log.isLoggable(CarLog.TAG_AM, Log.INFO)) {
Eric Jeongbd5fb562020-12-21 13:49:40 -0800466 Slog.i(CarLog.TAG_AM, "onTaskStackChanged");
Keun-young Park4727da32016-05-31 10:00:51 -0700467 }
468 mHandler.requestUpdatingTask();
469 }
Keun-young Park4727da32016-05-31 10:00:51 -0700470 }
471
Keun young Parkb241d022020-04-20 20:31:34 -0700472 private static final class ActivityMonitorHandler extends Handler {
473 private static final String TAG = ActivityMonitorHandler.class.getSimpleName();
474
Keun-young Park4727da32016-05-31 10:00:51 -0700475 private static final int MSG_UPDATE_TASKS = 0;
476 private static final int MSG_FOREGROUND_ACTIVITIES_CHANGED = 1;
477 private static final int MSG_PROCESS_DIED = 2;
478 private static final int MSG_BLOCK_ACTIVITY = 3;
479
Keun young Parkb241d022020-04-20 20:31:34 -0700480 private final WeakReference<SystemActivityMonitoringService> mService;
481
482 private ActivityMonitorHandler(Looper looper, SystemActivityMonitoringService service) {
Keun-young Park4727da32016-05-31 10:00:51 -0700483 super(looper);
Keun young Parkb241d022020-04-20 20:31:34 -0700484 mService = new WeakReference<SystemActivityMonitoringService>(service);
Keun-young Park4727da32016-05-31 10:00:51 -0700485 }
486
487 private void requestUpdatingTask() {
488 Message msg = obtainMessage(MSG_UPDATE_TASKS);
489 sendMessage(msg);
490 }
491
492 private void requestForegroundActivitiesChanged(int pid, int uid,
493 boolean foregroundActivities) {
494 Message msg = obtainMessage(MSG_FOREGROUND_ACTIVITIES_CHANGED, pid, uid,
495 Boolean.valueOf(foregroundActivities));
496 sendMessage(msg);
497 }
498
499 private void requestProcessDied(int pid, int uid) {
500 Message msg = obtainMessage(MSG_PROCESS_DIED, pid, uid);
501 sendMessage(msg);
502 }
503
504 private void requestBlockActivity(TopTaskInfoContainer currentTask,
505 Intent newActivityIntent) {
506 Message msg = obtainMessage(MSG_BLOCK_ACTIVITY,
507 new Pair<TopTaskInfoContainer, Intent>(currentTask, newActivityIntent));
508 sendMessage(msg);
509 }
510
511 @Override
512 public void handleMessage(Message msg) {
Keun young Parkb241d022020-04-20 20:31:34 -0700513 SystemActivityMonitoringService service = mService.get();
514 if (service == null) {
Eric Jeongbd5fb562020-12-21 13:49:40 -0800515 Slog.i(TAG, "handleMessage null service");
Keun young Parkb241d022020-04-20 20:31:34 -0700516 return;
517 }
Keun-young Park4727da32016-05-31 10:00:51 -0700518 switch (msg.what) {
519 case MSG_UPDATE_TASKS:
Keun young Parkb241d022020-04-20 20:31:34 -0700520 service.updateTasks();
Keun-young Park4727da32016-05-31 10:00:51 -0700521 break;
522 case MSG_FOREGROUND_ACTIVITIES_CHANGED:
Keun young Parkb241d022020-04-20 20:31:34 -0700523 service.handleForegroundActivitiesChanged(msg.arg1, msg.arg2,
524 (Boolean) msg.obj);
525 service.updateTasks();
Keun-young Park4727da32016-05-31 10:00:51 -0700526 break;
527 case MSG_PROCESS_DIED:
Keun young Parkb241d022020-04-20 20:31:34 -0700528 service.handleProcessDied(msg.arg1, msg.arg2);
Keun-young Park4727da32016-05-31 10:00:51 -0700529 break;
530 case MSG_BLOCK_ACTIVITY:
531 Pair<TopTaskInfoContainer, Intent> pair =
532 (Pair<TopTaskInfoContainer, Intent>) msg.obj;
Keun young Parkb241d022020-04-20 20:31:34 -0700533 service.handleBlockActivity(pair.first, pair.second);
Keun-young Park4727da32016-05-31 10:00:51 -0700534 break;
535 }
536 }
537 }
538}