blob: cb20eac3b6bb209a454da1baad6e353d9e072f04 [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
19import android.app.ITaskStackListener;
20import android.app.ActivityManager.TaskDescription;
21import android.content.ComponentName;
Yorke Lee13294072017-01-06 14:59:58 -080022import android.os.Binder;
Yorke Leebd54c2a2016-10-25 13:49:23 -070023import android.os.Handler;
24import android.os.Looper;
25import android.os.Message;
26import android.os.RemoteCallbackList;
27import android.os.RemoteException;
28
Yorke Lee13294072017-01-06 14:59:58 -080029import java.util.ArrayList;
30
Yorke Leebd54c2a2016-10-25 13:49:23 -070031class TaskChangeNotificationController {
32 static final int LOG_STACK_STATE_MSG = 1;
33 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 2;
34 static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 3;
35 static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 4;
36 static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 5;
37 static final int NOTIFY_FORCED_RESIZABLE_MSG = 6;
38 static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 7;
39 static final int NOTIFY_TASK_ADDED_LISTENERS_MSG = 8;
40 static final int NOTIFY_TASK_REMOVED_LISTENERS_MSG = 9;
41 static final int NOTIFY_TASK_MOVED_TO_FRONT_LISTENERS_MSG = 10;
42 static final int NOTIFY_TASK_DESCRIPTION_CHANGED_LISTENERS_MSG = 11;
43 static final int NOTIFY_ACTIVITY_REQUESTED_ORIENTATION_CHANGED_LISTENERS = 12;
44 static final int NOTIFY_TASK_REMOVAL_STARTED_LISTENERS = 13;
Robin Leec41f6ec2017-01-10 17:02:34 +000045 static final int NOTIFY_TASK_PROFILE_LOCKED_LISTENERS_MSG = 14;
Yorke Leebd54c2a2016-10-25 13:49:23 -070046
47 // Delay in notifying task stack change listeners (in millis)
48 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
49
50 private final ActivityManagerService mService;
51 private final ActivityStackSupervisor mStackSupervisor;
52 private final Handler mHandler;
53
Yorke Lee13294072017-01-06 14:59:58 -080054 // Task stack change listeners in a remote process.
55 private final RemoteCallbackList<ITaskStackListener> mRemoteTaskStackListeners =
56 new RemoteCallbackList<>();
57
58 /*
59 * Task stack change listeners in a local process. Tracked separately so that they can be
60 * called on the same thread.
61 */
62 private final ArrayList<ITaskStackListener> mLocalTaskStackListeners = new ArrayList<>();
63
64 private final TaskStackConsumer mNotifyTaskStackChanged = (l, m) -> {
65 l.onTaskStackChanged();
66 };
67
68 private final TaskStackConsumer mNotifyTaskCreated = (l, m) -> {
69 l.onTaskCreated(m.arg1, (ComponentName) m.obj);
70 };
71
72 private final TaskStackConsumer mNotifyTaskRemoved = (l, m) -> {
73 l.onTaskRemoved(m.arg1);
74 };
75
76 private final TaskStackConsumer mNotifyTaskMovedToFront = (l, m) -> {
77 l.onTaskMovedToFront(m.arg1);
78 };
79
80 private final TaskStackConsumer mNotifyTaskDescriptionChanged = (l, m) -> {
81 l.onTaskDescriptionChanged(m.arg1, (TaskDescription) m.obj);
82 };
83
84 private final TaskStackConsumer mNotifyActivityRequestedOrientationChanged = (l, m) -> {
85 l.onActivityRequestedOrientationChanged(m.arg1, m.arg2);
86 };
87
88 private final TaskStackConsumer mNotifyTaskRemovalStarted = (l, m) -> {
89 l.onTaskRemovalStarted(m.arg1);
90 };
91
92 private final TaskStackConsumer mNotifyActivityPinned = (l, m) -> {
93 l.onActivityPinned();
94 };
95
96 private final TaskStackConsumer mNotifyPinnedActivityRestartAttempt = (l, m) -> {
97 l.onPinnedActivityRestartAttempt();
98 };
99
100 private final TaskStackConsumer mNotifyPinnedStackAnimationEnded = (l, m) -> {
101 l.onPinnedStackAnimationEnded();
102 };
103
104 private final TaskStackConsumer mNotifyActivityForcedResizable = (l, m) -> {
105 l.onActivityForcedResizable((String) m.obj, m.arg1);
106 };
107
108 private final TaskStackConsumer mNotifyActivityDismissingDockedStack = (l, m) -> {
109 l.onActivityDismissingDockedStack();
110 };
111
112 private final TaskStackConsumer mNotifyTaskProfileLocked = (l, m) -> {
113 l.onTaskProfileLocked(m.arg1, m.arg2);
114 };
Yorke Leebd54c2a2016-10-25 13:49:23 -0700115
116 @FunctionalInterface
Yorke Lee13294072017-01-06 14:59:58 -0800117 public interface TaskStackConsumer {
118 void accept(ITaskStackListener t, Message m) throws RemoteException;
Yorke Leebd54c2a2016-10-25 13:49:23 -0700119 }
120
121 private class MainHandler extends Handler {
122 public MainHandler(Looper looper) {
123 super(looper);
124 }
125
126 @Override
127 public void handleMessage(Message msg) {
128 switch (msg.what) {
129 case LOG_STACK_STATE_MSG: {
130 synchronized (mService) {
131 mStackSupervisor.logStackState();
132 }
133 break;
134 }
135 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG:
Yorke Lee13294072017-01-06 14:59:58 -0800136 forAllRemoteListeners(mNotifyTaskStackChanged, msg);
Yorke Leebd54c2a2016-10-25 13:49:23 -0700137 break;
138 case NOTIFY_TASK_ADDED_LISTENERS_MSG:
Yorke Lee13294072017-01-06 14:59:58 -0800139 forAllRemoteListeners(mNotifyTaskCreated, msg);
Yorke Leebd54c2a2016-10-25 13:49:23 -0700140 break;
141 case NOTIFY_TASK_REMOVED_LISTENERS_MSG:
Yorke Lee13294072017-01-06 14:59:58 -0800142 forAllRemoteListeners(mNotifyTaskRemoved, msg);
Yorke Leebd54c2a2016-10-25 13:49:23 -0700143 break;
144 case NOTIFY_TASK_MOVED_TO_FRONT_LISTENERS_MSG:
Yorke Lee13294072017-01-06 14:59:58 -0800145 forAllRemoteListeners(mNotifyTaskMovedToFront, msg);
Yorke Leebd54c2a2016-10-25 13:49:23 -0700146 break;
147 case NOTIFY_TASK_DESCRIPTION_CHANGED_LISTENERS_MSG:
Yorke Lee13294072017-01-06 14:59:58 -0800148 forAllRemoteListeners(mNotifyTaskDescriptionChanged, msg);
Yorke Leebd54c2a2016-10-25 13:49:23 -0700149 break;
150 case NOTIFY_ACTIVITY_REQUESTED_ORIENTATION_CHANGED_LISTENERS:
Yorke Lee13294072017-01-06 14:59:58 -0800151 forAllRemoteListeners(mNotifyActivityRequestedOrientationChanged, msg);
Yorke Lee64fd1ce2017-01-05 17:15:20 -0800152 break;
Yorke Leebd54c2a2016-10-25 13:49:23 -0700153 case NOTIFY_TASK_REMOVAL_STARTED_LISTENERS:
Yorke Lee13294072017-01-06 14:59:58 -0800154 forAllRemoteListeners(mNotifyTaskRemovalStarted, msg);
Yorke Leebd54c2a2016-10-25 13:49:23 -0700155 break;
156 case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG:
Yorke Lee13294072017-01-06 14:59:58 -0800157 forAllRemoteListeners(mNotifyActivityPinned, msg);
Yorke Leebd54c2a2016-10-25 13:49:23 -0700158 break;
159 case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG:
Yorke Lee13294072017-01-06 14:59:58 -0800160 forAllRemoteListeners(mNotifyPinnedActivityRestartAttempt, msg);
Yorke Leebd54c2a2016-10-25 13:49:23 -0700161 break;
162 case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG:
Yorke Lee13294072017-01-06 14:59:58 -0800163 forAllRemoteListeners(mNotifyPinnedStackAnimationEnded, msg);
Yorke Leebd54c2a2016-10-25 13:49:23 -0700164 break;
165 case NOTIFY_FORCED_RESIZABLE_MSG:
Yorke Lee13294072017-01-06 14:59:58 -0800166 forAllRemoteListeners(mNotifyActivityForcedResizable, msg);
Yorke Leebd54c2a2016-10-25 13:49:23 -0700167 break;
168 case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG:
Yorke Lee13294072017-01-06 14:59:58 -0800169 forAllRemoteListeners(mNotifyActivityDismissingDockedStack, msg);
Yorke Leebd54c2a2016-10-25 13:49:23 -0700170 break;
Robin Leec41f6ec2017-01-10 17:02:34 +0000171 case NOTIFY_TASK_PROFILE_LOCKED_LISTENERS_MSG:
Yorke Lee13294072017-01-06 14:59:58 -0800172 forAllRemoteListeners(mNotifyTaskProfileLocked, msg);
173
Robin Leec41f6ec2017-01-10 17:02:34 +0000174 break;
Yorke Leebd54c2a2016-10-25 13:49:23 -0700175 }
176 }
177 }
178
179 public TaskChangeNotificationController(ActivityManagerService service,
180 ActivityStackSupervisor stackSupervisor, Handler handler) {
181 mService = service;
182 mStackSupervisor = stackSupervisor;
183 mHandler = new MainHandler(handler.getLooper());
184 }
185
186 public void registerTaskStackListener(ITaskStackListener listener) {
187 synchronized (mService) {
188 if (listener != null) {
Yorke Lee13294072017-01-06 14:59:58 -0800189 if (Binder.getCallingPid() == android.os.Process.myPid()) {
190 if (!mLocalTaskStackListeners.contains(listener)) {
191 mLocalTaskStackListeners.add(listener);
192 }
193 } else {
194 mRemoteTaskStackListeners.register(listener);
195 }
Yorke Leebd54c2a2016-10-25 13:49:23 -0700196 }
197 }
198 }
199
200 public void unregisterTaskStackListener(ITaskStackListener listener) {
201 synchronized (mService) {
202 if (listener != null) {
Yorke Lee13294072017-01-06 14:59:58 -0800203 if (Binder.getCallingPid() == android.os.Process.myPid()) {
204 mLocalTaskStackListeners.remove(listener);
205 } else {
206 mRemoteTaskStackListeners.unregister(listener);
207 }
Yorke Leebd54c2a2016-10-25 13:49:23 -0700208 }
209 }
210 }
211
Yorke Lee13294072017-01-06 14:59:58 -0800212 void forAllRemoteListeners(TaskStackConsumer callback, Message message) {
Yorke Leebd54c2a2016-10-25 13:49:23 -0700213 synchronized (mService) {
Yorke Lee13294072017-01-06 14:59:58 -0800214 for (int i = mRemoteTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
Yorke Leebd54c2a2016-10-25 13:49:23 -0700215 try {
216 // Make a one-way callback to the listener
Yorke Lee13294072017-01-06 14:59:58 -0800217 callback.accept(mRemoteTaskStackListeners.getBroadcastItem(i), message);
Yorke Leebd54c2a2016-10-25 13:49:23 -0700218 } catch (RemoteException e) {
219 // Handled by the RemoteCallbackList.
220 }
221 }
Yorke Lee13294072017-01-06 14:59:58 -0800222 mRemoteTaskStackListeners.finishBroadcast();
223 }
224 }
225
226 void forAllLocalListeners(TaskStackConsumer callback, Message message) {
227 synchronized (mService) {
228 for (int i = mLocalTaskStackListeners.size() - 1; i >= 0; i--) {
229 try {
230 callback.accept(mLocalTaskStackListeners.get(i), message);
231 } catch (RemoteException e) {
232 // Never thrown since this is called locally.
233 }
234 }
235 }
236 }
Yorke Leebd54c2a2016-10-25 13:49:23 -0700237
238 /** Notifies all listeners when the task stack has changed. */
239 void notifyTaskStackChanged() {
240 mHandler.sendEmptyMessage(LOG_STACK_STATE_MSG);
241 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
Yorke Lee13294072017-01-06 14:59:58 -0800242 final Message msg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
243 forAllLocalListeners(mNotifyTaskStackChanged, msg);
Yorke Leebd54c2a2016-10-25 13:49:23 -0700244 // Only the main task stack change notification requires a delay.
245 mHandler.sendMessageDelayed(msg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
246 }
247
248 /** Notifies all listeners when an Activity is pinned. */
249 void notifyActivityPinned() {
250 mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
Yorke Lee13294072017-01-06 14:59:58 -0800251 final Message msg = mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
252 forAllLocalListeners(mNotifyActivityPinned, msg);
253 msg.sendToTarget();
Yorke Leebd54c2a2016-10-25 13:49:23 -0700254 }
255
256 /**
257 * Notifies all listeners when an attempt was made to start an an activity that is already
258 * running in the pinned stack and the activity was not actually started, but the task is
259 * either brought to the front or a new Intent is delivered to it.
260 */
261 void notifyPinnedActivityRestartAttempt() {
262 mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
Yorke Lee13294072017-01-06 14:59:58 -0800263 final Message msg =
264 mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
265 forAllLocalListeners(mNotifyPinnedActivityRestartAttempt, msg);
266 msg.sendToTarget();
Yorke Leebd54c2a2016-10-25 13:49:23 -0700267 }
268
269 /** Notifies all listeners when the pinned stack animation ends. */
270 void notifyPinnedStackAnimationEnded() {
271 mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
Yorke Lee13294072017-01-06 14:59:58 -0800272 final Message msg =
273 mHandler.obtainMessage(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
274 forAllLocalListeners(mNotifyPinnedStackAnimationEnded, msg);
275 msg.sendToTarget();
Yorke Leebd54c2a2016-10-25 13:49:23 -0700276 }
277
278 void notifyActivityDismissingDockedStack() {
279 mHandler.removeMessages(NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG);
Yorke Lee13294072017-01-06 14:59:58 -0800280 final Message message = mHandler.obtainMessage(NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG);
281 forAllLocalListeners(mNotifyActivityDismissingDockedStack, message);
Yorke Leebd54c2a2016-10-25 13:49:23 -0700282 }
283
284 void notifyActivityForcedResizable(int taskId, String packageName) {
285 mHandler.removeMessages(NOTIFY_FORCED_RESIZABLE_MSG);
Yorke Lee13294072017-01-06 14:59:58 -0800286 final Message msg = mHandler.obtainMessage(NOTIFY_FORCED_RESIZABLE_MSG, taskId,
287 0 /* unused */, packageName);
288 forAllLocalListeners(mNotifyActivityForcedResizable, msg);
289 msg.sendToTarget();
Yorke Leebd54c2a2016-10-25 13:49:23 -0700290 }
291
292 void notifyTaskCreated(int taskId, ComponentName componentName) {
Yorke Lee13294072017-01-06 14:59:58 -0800293 final Message msg = mHandler.obtainMessage(NOTIFY_TASK_ADDED_LISTENERS_MSG,
294 taskId, 0 /* unused */, componentName);
295 forAllLocalListeners(mNotifyTaskCreated, msg);
296 msg.sendToTarget();
Yorke Leebd54c2a2016-10-25 13:49:23 -0700297 }
298
299 void notifyTaskRemoved(int taskId) {
Yorke Lee13294072017-01-06 14:59:58 -0800300 final Message msg = mHandler.obtainMessage(NOTIFY_TASK_REMOVED_LISTENERS_MSG,
301 taskId, 0 /* unused */);
302 forAllLocalListeners(mNotifyTaskRemoved, msg);
303 msg.sendToTarget();
Yorke Leebd54c2a2016-10-25 13:49:23 -0700304 }
305
306 void notifyTaskMovedToFront(int taskId) {
Yorke Lee13294072017-01-06 14:59:58 -0800307 final Message msg = mHandler.obtainMessage(NOTIFY_TASK_MOVED_TO_FRONT_LISTENERS_MSG,
308 taskId, 0 /* unused */);
309 forAllLocalListeners(mNotifyTaskMovedToFront, msg);
310 msg.sendToTarget();
Yorke Leebd54c2a2016-10-25 13:49:23 -0700311 }
312
313 void notifyTaskDescriptionChanged(int taskId, TaskDescription taskDescription) {
Yorke Lee13294072017-01-06 14:59:58 -0800314 final Message msg = mHandler.obtainMessage(NOTIFY_TASK_DESCRIPTION_CHANGED_LISTENERS_MSG,
315 taskId, 0 /* unused */, taskDescription);
316 forAllLocalListeners(mNotifyTaskDescriptionChanged, msg);
317 msg.sendToTarget();
318
Yorke Leebd54c2a2016-10-25 13:49:23 -0700319 }
320
321 void notifyActivityRequestedOrientationChanged(int taskId, int orientation) {
Yorke Lee13294072017-01-06 14:59:58 -0800322 final Message msg = mHandler.obtainMessage(
323 NOTIFY_ACTIVITY_REQUESTED_ORIENTATION_CHANGED_LISTENERS, taskId, orientation);
324 forAllLocalListeners(mNotifyActivityRequestedOrientationChanged, msg);
325 msg.sendToTarget();
Yorke Leebd54c2a2016-10-25 13:49:23 -0700326 }
327
328 /**
329 * Notify listeners that the task is about to be finished before its surfaces are removed from
330 * the window manager. This allows interested parties to perform relevant animations before
331 * the window disappears.
332 */
333 void notifyTaskRemovalStarted(int taskId) {
Yorke Lee13294072017-01-06 14:59:58 -0800334 final Message msg = mHandler.obtainMessage(NOTIFY_TASK_REMOVAL_STARTED_LISTENERS, taskId,
335 0 /* unused */);
336 forAllLocalListeners(mNotifyTaskRemovalStarted, msg);
337 msg.sendToTarget();
338
Yorke Leebd54c2a2016-10-25 13:49:23 -0700339 }
Robin Leec41f6ec2017-01-10 17:02:34 +0000340
341 /**
342 * Notify listeners that the task has been put in a locked state because one or more of the
343 * activities inside it belong to a managed profile user that has been locked.
344 */
345 void notifyTaskProfileLocked(int taskId, int userId) {
Yorke Lee13294072017-01-06 14:59:58 -0800346 final Message msg = mHandler.obtainMessage(NOTIFY_TASK_PROFILE_LOCKED_LISTENERS_MSG, taskId,
347 userId);
348 forAllLocalListeners(mNotifyTaskProfileLocked, msg);
349 msg.sendToTarget();
Robin Leec41f6ec2017-01-10 17:02:34 +0000350 }
Yorke Leebd54c2a2016-10-25 13:49:23 -0700351}