blob: d035fa9d94c96286b94a512c33db5456e1ff64cd [file] [log] [blame]
Yorke Leebd54c2a2016-10-25 13:49:23 -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 */
16
17package com.android.server.am;
18
Jorim Jaggifb9d78a2017-01-05 18:57:12 +010019import android.app.ActivityManager;
20import android.app.ActivityManager.TaskSnapshot;
Yorke Leebd54c2a2016-10-25 13:49:23 -070021import android.app.ITaskStackListener;
22import android.app.ActivityManager.TaskDescription;
23import android.content.ComponentName;
Yorke Lee13294072017-01-06 14:59:58 -080024import android.os.Binder;
Yorke Leebd54c2a2016-10-25 13:49:23 -070025import android.os.Handler;
26import android.os.Looper;
27import android.os.Message;
28import android.os.RemoteCallbackList;
29import android.os.RemoteException;
30
Yorke Lee13294072017-01-06 14:59:58 -080031import java.util.ArrayList;
32
Yorke Leebd54c2a2016-10-25 13:49:23 -070033class TaskChangeNotificationController {
34 static final int LOG_STACK_STATE_MSG = 1;
35 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 2;
36 static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 3;
37 static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 4;
38 static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 5;
39 static final int NOTIFY_FORCED_RESIZABLE_MSG = 6;
40 static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 7;
41 static final int NOTIFY_TASK_ADDED_LISTENERS_MSG = 8;
42 static final int NOTIFY_TASK_REMOVED_LISTENERS_MSG = 9;
43 static final int NOTIFY_TASK_MOVED_TO_FRONT_LISTENERS_MSG = 10;
44 static final int NOTIFY_TASK_DESCRIPTION_CHANGED_LISTENERS_MSG = 11;
45 static final int NOTIFY_ACTIVITY_REQUESTED_ORIENTATION_CHANGED_LISTENERS = 12;
46 static final int NOTIFY_TASK_REMOVAL_STARTED_LISTENERS = 13;
Robin Leec41f6ec2017-01-10 17:02:34 +000047 static final int NOTIFY_TASK_PROFILE_LOCKED_LISTENERS_MSG = 14;
Jorim Jaggifb9d78a2017-01-05 18:57:12 +010048 static final int NOTIFY_TASK_SNAPSHOT_CHANGED_LISTENERS_MSG = 15;
Yorke Leebd54c2a2016-10-25 13:49:23 -070049
50 // Delay in notifying task stack change listeners (in millis)
51 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
52
53 private final ActivityManagerService mService;
54 private final ActivityStackSupervisor mStackSupervisor;
55 private final Handler mHandler;
56
Yorke Lee13294072017-01-06 14:59:58 -080057 // Task stack change listeners in a remote process.
58 private final RemoteCallbackList<ITaskStackListener> mRemoteTaskStackListeners =
59 new RemoteCallbackList<>();
60
61 /*
62 * Task stack change listeners in a local process. Tracked separately so that they can be
63 * called on the same thread.
64 */
65 private final ArrayList<ITaskStackListener> mLocalTaskStackListeners = new ArrayList<>();
66
67 private final TaskStackConsumer mNotifyTaskStackChanged = (l, m) -> {
68 l.onTaskStackChanged();
69 };
70
71 private final TaskStackConsumer mNotifyTaskCreated = (l, m) -> {
72 l.onTaskCreated(m.arg1, (ComponentName) m.obj);
73 };
74
75 private final TaskStackConsumer mNotifyTaskRemoved = (l, m) -> {
76 l.onTaskRemoved(m.arg1);
77 };
78
79 private final TaskStackConsumer mNotifyTaskMovedToFront = (l, m) -> {
80 l.onTaskMovedToFront(m.arg1);
81 };
82
83 private final TaskStackConsumer mNotifyTaskDescriptionChanged = (l, m) -> {
84 l.onTaskDescriptionChanged(m.arg1, (TaskDescription) m.obj);
85 };
86
87 private final TaskStackConsumer mNotifyActivityRequestedOrientationChanged = (l, m) -> {
88 l.onActivityRequestedOrientationChanged(m.arg1, m.arg2);
89 };
90
91 private final TaskStackConsumer mNotifyTaskRemovalStarted = (l, m) -> {
92 l.onTaskRemovalStarted(m.arg1);
93 };
94
95 private final TaskStackConsumer mNotifyActivityPinned = (l, m) -> {
96 l.onActivityPinned();
97 };
98
99 private final TaskStackConsumer mNotifyPinnedActivityRestartAttempt = (l, m) -> {
100 l.onPinnedActivityRestartAttempt();
101 };
102
103 private final TaskStackConsumer mNotifyPinnedStackAnimationEnded = (l, m) -> {
104 l.onPinnedStackAnimationEnded();
105 };
106
107 private final TaskStackConsumer mNotifyActivityForcedResizable = (l, m) -> {
108 l.onActivityForcedResizable((String) m.obj, m.arg1);
109 };
110
111 private final TaskStackConsumer mNotifyActivityDismissingDockedStack = (l, m) -> {
112 l.onActivityDismissingDockedStack();
113 };
114
115 private final TaskStackConsumer mNotifyTaskProfileLocked = (l, m) -> {
116 l.onTaskProfileLocked(m.arg1, m.arg2);
117 };
Yorke Leebd54c2a2016-10-25 13:49:23 -0700118
Jorim Jaggifb9d78a2017-01-05 18:57:12 +0100119 private final TaskStackConsumer mNotifyTaskSnapshotChanged = (l, m) -> {
120 l.onTaskSnapshotChanged(m.arg1, (TaskSnapshot) m.obj);
121 };
122
Yorke Leebd54c2a2016-10-25 13:49:23 -0700123 @FunctionalInterface
Yorke Lee13294072017-01-06 14:59:58 -0800124 public interface TaskStackConsumer {
125 void accept(ITaskStackListener t, Message m) throws RemoteException;
Yorke Leebd54c2a2016-10-25 13:49:23 -0700126 }
127
128 private class MainHandler extends Handler {
129 public MainHandler(Looper looper) {
130 super(looper);
131 }
132
133 @Override
134 public void handleMessage(Message msg) {
135 switch (msg.what) {
136 case LOG_STACK_STATE_MSG: {
137 synchronized (mService) {
138 mStackSupervisor.logStackState();
139 }
140 break;
141 }
142 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG:
Yorke Lee13294072017-01-06 14:59:58 -0800143 forAllRemoteListeners(mNotifyTaskStackChanged, msg);
Yorke Leebd54c2a2016-10-25 13:49:23 -0700144 break;
145 case NOTIFY_TASK_ADDED_LISTENERS_MSG:
Yorke Lee13294072017-01-06 14:59:58 -0800146 forAllRemoteListeners(mNotifyTaskCreated, msg);
Yorke Leebd54c2a2016-10-25 13:49:23 -0700147 break;
148 case NOTIFY_TASK_REMOVED_LISTENERS_MSG:
Yorke Lee13294072017-01-06 14:59:58 -0800149 forAllRemoteListeners(mNotifyTaskRemoved, msg);
Yorke Leebd54c2a2016-10-25 13:49:23 -0700150 break;
151 case NOTIFY_TASK_MOVED_TO_FRONT_LISTENERS_MSG:
Yorke Lee13294072017-01-06 14:59:58 -0800152 forAllRemoteListeners(mNotifyTaskMovedToFront, msg);
Yorke Leebd54c2a2016-10-25 13:49:23 -0700153 break;
154 case NOTIFY_TASK_DESCRIPTION_CHANGED_LISTENERS_MSG:
Yorke Lee13294072017-01-06 14:59:58 -0800155 forAllRemoteListeners(mNotifyTaskDescriptionChanged, msg);
Yorke Leebd54c2a2016-10-25 13:49:23 -0700156 break;
157 case NOTIFY_ACTIVITY_REQUESTED_ORIENTATION_CHANGED_LISTENERS:
Yorke Lee13294072017-01-06 14:59:58 -0800158 forAllRemoteListeners(mNotifyActivityRequestedOrientationChanged, msg);
Yorke Lee64fd1ce2017-01-05 17:15:20 -0800159 break;
Yorke Leebd54c2a2016-10-25 13:49:23 -0700160 case NOTIFY_TASK_REMOVAL_STARTED_LISTENERS:
Yorke Lee13294072017-01-06 14:59:58 -0800161 forAllRemoteListeners(mNotifyTaskRemovalStarted, msg);
Yorke Leebd54c2a2016-10-25 13:49:23 -0700162 break;
163 case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG:
Yorke Lee13294072017-01-06 14:59:58 -0800164 forAllRemoteListeners(mNotifyActivityPinned, msg);
Yorke Leebd54c2a2016-10-25 13:49:23 -0700165 break;
166 case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG:
Yorke Lee13294072017-01-06 14:59:58 -0800167 forAllRemoteListeners(mNotifyPinnedActivityRestartAttempt, msg);
Yorke Leebd54c2a2016-10-25 13:49:23 -0700168 break;
169 case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG:
Yorke Lee13294072017-01-06 14:59:58 -0800170 forAllRemoteListeners(mNotifyPinnedStackAnimationEnded, msg);
Yorke Leebd54c2a2016-10-25 13:49:23 -0700171 break;
172 case NOTIFY_FORCED_RESIZABLE_MSG:
Yorke Lee13294072017-01-06 14:59:58 -0800173 forAllRemoteListeners(mNotifyActivityForcedResizable, msg);
Yorke Leebd54c2a2016-10-25 13:49:23 -0700174 break;
175 case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG:
Yorke Lee13294072017-01-06 14:59:58 -0800176 forAllRemoteListeners(mNotifyActivityDismissingDockedStack, msg);
Yorke Leebd54c2a2016-10-25 13:49:23 -0700177 break;
Robin Leec41f6ec2017-01-10 17:02:34 +0000178 case NOTIFY_TASK_PROFILE_LOCKED_LISTENERS_MSG:
Yorke Lee13294072017-01-06 14:59:58 -0800179 forAllRemoteListeners(mNotifyTaskProfileLocked, msg);
Jorim Jaggifb9d78a2017-01-05 18:57:12 +0100180 break;
181 case NOTIFY_TASK_SNAPSHOT_CHANGED_LISTENERS_MSG:
182 forAllRemoteListeners(mNotifyTaskSnapshotChanged, msg);
Robin Leec41f6ec2017-01-10 17:02:34 +0000183 break;
Yorke Leebd54c2a2016-10-25 13:49:23 -0700184 }
185 }
186 }
187
188 public TaskChangeNotificationController(ActivityManagerService service,
189 ActivityStackSupervisor stackSupervisor, Handler handler) {
190 mService = service;
191 mStackSupervisor = stackSupervisor;
192 mHandler = new MainHandler(handler.getLooper());
193 }
194
195 public void registerTaskStackListener(ITaskStackListener listener) {
196 synchronized (mService) {
197 if (listener != null) {
Yorke Lee13294072017-01-06 14:59:58 -0800198 if (Binder.getCallingPid() == android.os.Process.myPid()) {
199 if (!mLocalTaskStackListeners.contains(listener)) {
200 mLocalTaskStackListeners.add(listener);
201 }
202 } else {
203 mRemoteTaskStackListeners.register(listener);
204 }
Yorke Leebd54c2a2016-10-25 13:49:23 -0700205 }
206 }
207 }
208
209 public void unregisterTaskStackListener(ITaskStackListener listener) {
210 synchronized (mService) {
211 if (listener != null) {
Yorke Lee13294072017-01-06 14:59:58 -0800212 if (Binder.getCallingPid() == android.os.Process.myPid()) {
213 mLocalTaskStackListeners.remove(listener);
214 } else {
215 mRemoteTaskStackListeners.unregister(listener);
216 }
Yorke Leebd54c2a2016-10-25 13:49:23 -0700217 }
218 }
219 }
220
Yorke Lee13294072017-01-06 14:59:58 -0800221 void forAllRemoteListeners(TaskStackConsumer callback, Message message) {
Yorke Leebd54c2a2016-10-25 13:49:23 -0700222 synchronized (mService) {
Yorke Lee13294072017-01-06 14:59:58 -0800223 for (int i = mRemoteTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
Yorke Leebd54c2a2016-10-25 13:49:23 -0700224 try {
225 // Make a one-way callback to the listener
Yorke Lee13294072017-01-06 14:59:58 -0800226 callback.accept(mRemoteTaskStackListeners.getBroadcastItem(i), message);
Yorke Leebd54c2a2016-10-25 13:49:23 -0700227 } catch (RemoteException e) {
228 // Handled by the RemoteCallbackList.
229 }
230 }
Yorke Lee13294072017-01-06 14:59:58 -0800231 mRemoteTaskStackListeners.finishBroadcast();
232 }
233 }
234
235 void forAllLocalListeners(TaskStackConsumer callback, Message message) {
236 synchronized (mService) {
237 for (int i = mLocalTaskStackListeners.size() - 1; i >= 0; i--) {
238 try {
239 callback.accept(mLocalTaskStackListeners.get(i), message);
240 } catch (RemoteException e) {
241 // Never thrown since this is called locally.
242 }
243 }
244 }
245 }
Yorke Leebd54c2a2016-10-25 13:49:23 -0700246
247 /** Notifies all listeners when the task stack has changed. */
248 void notifyTaskStackChanged() {
249 mHandler.sendEmptyMessage(LOG_STACK_STATE_MSG);
250 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
Yorke Lee13294072017-01-06 14:59:58 -0800251 final Message msg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
252 forAllLocalListeners(mNotifyTaskStackChanged, msg);
Yorke Leebd54c2a2016-10-25 13:49:23 -0700253 // Only the main task stack change notification requires a delay.
254 mHandler.sendMessageDelayed(msg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
255 }
256
257 /** Notifies all listeners when an Activity is pinned. */
258 void notifyActivityPinned() {
259 mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
Yorke Lee13294072017-01-06 14:59:58 -0800260 final Message msg = mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
261 forAllLocalListeners(mNotifyActivityPinned, msg);
262 msg.sendToTarget();
Yorke Leebd54c2a2016-10-25 13:49:23 -0700263 }
264
265 /**
266 * Notifies all listeners when an attempt was made to start an an activity that is already
267 * running in the pinned stack and the activity was not actually started, but the task is
268 * either brought to the front or a new Intent is delivered to it.
269 */
270 void notifyPinnedActivityRestartAttempt() {
271 mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
Yorke Lee13294072017-01-06 14:59:58 -0800272 final Message msg =
273 mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
274 forAllLocalListeners(mNotifyPinnedActivityRestartAttempt, msg);
275 msg.sendToTarget();
Yorke Leebd54c2a2016-10-25 13:49:23 -0700276 }
277
278 /** Notifies all listeners when the pinned stack animation ends. */
279 void notifyPinnedStackAnimationEnded() {
280 mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
Yorke Lee13294072017-01-06 14:59:58 -0800281 final Message msg =
282 mHandler.obtainMessage(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
283 forAllLocalListeners(mNotifyPinnedStackAnimationEnded, msg);
284 msg.sendToTarget();
Yorke Leebd54c2a2016-10-25 13:49:23 -0700285 }
286
287 void notifyActivityDismissingDockedStack() {
288 mHandler.removeMessages(NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG);
Yorke Lee13294072017-01-06 14:59:58 -0800289 final Message message = mHandler.obtainMessage(NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG);
290 forAllLocalListeners(mNotifyActivityDismissingDockedStack, message);
Yorke Leebd54c2a2016-10-25 13:49:23 -0700291 }
292
293 void notifyActivityForcedResizable(int taskId, String packageName) {
294 mHandler.removeMessages(NOTIFY_FORCED_RESIZABLE_MSG);
Yorke Lee13294072017-01-06 14:59:58 -0800295 final Message msg = mHandler.obtainMessage(NOTIFY_FORCED_RESIZABLE_MSG, taskId,
296 0 /* unused */, packageName);
297 forAllLocalListeners(mNotifyActivityForcedResizable, msg);
298 msg.sendToTarget();
Yorke Leebd54c2a2016-10-25 13:49:23 -0700299 }
300
301 void notifyTaskCreated(int taskId, ComponentName componentName) {
Yorke Lee13294072017-01-06 14:59:58 -0800302 final Message msg = mHandler.obtainMessage(NOTIFY_TASK_ADDED_LISTENERS_MSG,
303 taskId, 0 /* unused */, componentName);
304 forAllLocalListeners(mNotifyTaskCreated, msg);
305 msg.sendToTarget();
Yorke Leebd54c2a2016-10-25 13:49:23 -0700306 }
307
308 void notifyTaskRemoved(int taskId) {
Yorke Lee13294072017-01-06 14:59:58 -0800309 final Message msg = mHandler.obtainMessage(NOTIFY_TASK_REMOVED_LISTENERS_MSG,
310 taskId, 0 /* unused */);
311 forAllLocalListeners(mNotifyTaskRemoved, msg);
312 msg.sendToTarget();
Yorke Leebd54c2a2016-10-25 13:49:23 -0700313 }
314
315 void notifyTaskMovedToFront(int taskId) {
Yorke Lee13294072017-01-06 14:59:58 -0800316 final Message msg = mHandler.obtainMessage(NOTIFY_TASK_MOVED_TO_FRONT_LISTENERS_MSG,
317 taskId, 0 /* unused */);
318 forAllLocalListeners(mNotifyTaskMovedToFront, msg);
319 msg.sendToTarget();
Yorke Leebd54c2a2016-10-25 13:49:23 -0700320 }
321
322 void notifyTaskDescriptionChanged(int taskId, TaskDescription taskDescription) {
Yorke Lee13294072017-01-06 14:59:58 -0800323 final Message msg = mHandler.obtainMessage(NOTIFY_TASK_DESCRIPTION_CHANGED_LISTENERS_MSG,
324 taskId, 0 /* unused */, taskDescription);
325 forAllLocalListeners(mNotifyTaskDescriptionChanged, msg);
326 msg.sendToTarget();
327
Yorke Leebd54c2a2016-10-25 13:49:23 -0700328 }
329
330 void notifyActivityRequestedOrientationChanged(int taskId, int orientation) {
Yorke Lee13294072017-01-06 14:59:58 -0800331 final Message msg = mHandler.obtainMessage(
332 NOTIFY_ACTIVITY_REQUESTED_ORIENTATION_CHANGED_LISTENERS, taskId, orientation);
333 forAllLocalListeners(mNotifyActivityRequestedOrientationChanged, msg);
334 msg.sendToTarget();
Yorke Leebd54c2a2016-10-25 13:49:23 -0700335 }
336
337 /**
338 * Notify listeners that the task is about to be finished before its surfaces are removed from
339 * the window manager. This allows interested parties to perform relevant animations before
340 * the window disappears.
341 */
342 void notifyTaskRemovalStarted(int taskId) {
Yorke Lee13294072017-01-06 14:59:58 -0800343 final Message msg = mHandler.obtainMessage(NOTIFY_TASK_REMOVAL_STARTED_LISTENERS, taskId,
344 0 /* unused */);
345 forAllLocalListeners(mNotifyTaskRemovalStarted, msg);
346 msg.sendToTarget();
347
Yorke Leebd54c2a2016-10-25 13:49:23 -0700348 }
Robin Leec41f6ec2017-01-10 17:02:34 +0000349
350 /**
351 * Notify listeners that the task has been put in a locked state because one or more of the
352 * activities inside it belong to a managed profile user that has been locked.
353 */
354 void notifyTaskProfileLocked(int taskId, int userId) {
Yorke Lee13294072017-01-06 14:59:58 -0800355 final Message msg = mHandler.obtainMessage(NOTIFY_TASK_PROFILE_LOCKED_LISTENERS_MSG, taskId,
356 userId);
357 forAllLocalListeners(mNotifyTaskProfileLocked, msg);
358 msg.sendToTarget();
Robin Leec41f6ec2017-01-10 17:02:34 +0000359 }
Jorim Jaggifb9d78a2017-01-05 18:57:12 +0100360
361 /**
362 * Notify listeners that the snapshot of a task has changed.
363 */
364 void notifyTaskSnapshotChanged(int taskId, TaskSnapshot snapshot) {
365 final Message msg = mHandler.obtainMessage(NOTIFY_TASK_SNAPSHOT_CHANGED_LISTENERS_MSG,
366 taskId, 0, snapshot);
367 forAllLocalListeners(mNotifyTaskSnapshotChanged, msg);
368 msg.sendToTarget();
369 }
Yorke Leebd54c2a2016-10-25 13:49:23 -0700370}