blob: 2990dffd8e5caa359f375b79b6e94ba9959b7bd1 [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) -> {
Winson Chung3535df22017-01-17 18:43:39 -0800100 l.onPinnedActivityRestartAttempt((ComponentName) m.obj);
Yorke Lee13294072017-01-06 14:59:58 -0800101 };
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 */
Winson Chung3535df22017-01-17 18:43:39 -0800270 void notifyPinnedActivityRestartAttempt(ComponentName sourceComponent) {
Yorke Leebd54c2a2016-10-25 13:49:23 -0700271 mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
Yorke Lee13294072017-01-06 14:59:58 -0800272 final Message msg =
Winson Chung3535df22017-01-17 18:43:39 -0800273 mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG,
274 sourceComponent);
Yorke Lee13294072017-01-06 14:59:58 -0800275 forAllLocalListeners(mNotifyPinnedActivityRestartAttempt, msg);
276 msg.sendToTarget();
Yorke Leebd54c2a2016-10-25 13:49:23 -0700277 }
278
279 /** Notifies all listeners when the pinned stack animation ends. */
280 void notifyPinnedStackAnimationEnded() {
281 mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
Yorke Lee13294072017-01-06 14:59:58 -0800282 final Message msg =
283 mHandler.obtainMessage(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
284 forAllLocalListeners(mNotifyPinnedStackAnimationEnded, msg);
285 msg.sendToTarget();
Yorke Leebd54c2a2016-10-25 13:49:23 -0700286 }
287
288 void notifyActivityDismissingDockedStack() {
289 mHandler.removeMessages(NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG);
Yorke Lee13294072017-01-06 14:59:58 -0800290 final Message message = mHandler.obtainMessage(NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG);
291 forAllLocalListeners(mNotifyActivityDismissingDockedStack, message);
Yorke Leebd54c2a2016-10-25 13:49:23 -0700292 }
293
294 void notifyActivityForcedResizable(int taskId, String packageName) {
295 mHandler.removeMessages(NOTIFY_FORCED_RESIZABLE_MSG);
Yorke Lee13294072017-01-06 14:59:58 -0800296 final Message msg = mHandler.obtainMessage(NOTIFY_FORCED_RESIZABLE_MSG, taskId,
297 0 /* unused */, packageName);
298 forAllLocalListeners(mNotifyActivityForcedResizable, msg);
299 msg.sendToTarget();
Yorke Leebd54c2a2016-10-25 13:49:23 -0700300 }
301
302 void notifyTaskCreated(int taskId, ComponentName componentName) {
Yorke Lee13294072017-01-06 14:59:58 -0800303 final Message msg = mHandler.obtainMessage(NOTIFY_TASK_ADDED_LISTENERS_MSG,
304 taskId, 0 /* unused */, componentName);
305 forAllLocalListeners(mNotifyTaskCreated, msg);
306 msg.sendToTarget();
Yorke Leebd54c2a2016-10-25 13:49:23 -0700307 }
308
309 void notifyTaskRemoved(int taskId) {
Yorke Lee13294072017-01-06 14:59:58 -0800310 final Message msg = mHandler.obtainMessage(NOTIFY_TASK_REMOVED_LISTENERS_MSG,
311 taskId, 0 /* unused */);
312 forAllLocalListeners(mNotifyTaskRemoved, msg);
313 msg.sendToTarget();
Yorke Leebd54c2a2016-10-25 13:49:23 -0700314 }
315
316 void notifyTaskMovedToFront(int taskId) {
Yorke Lee13294072017-01-06 14:59:58 -0800317 final Message msg = mHandler.obtainMessage(NOTIFY_TASK_MOVED_TO_FRONT_LISTENERS_MSG,
318 taskId, 0 /* unused */);
319 forAllLocalListeners(mNotifyTaskMovedToFront, msg);
320 msg.sendToTarget();
Yorke Leebd54c2a2016-10-25 13:49:23 -0700321 }
322
323 void notifyTaskDescriptionChanged(int taskId, TaskDescription taskDescription) {
Yorke Lee13294072017-01-06 14:59:58 -0800324 final Message msg = mHandler.obtainMessage(NOTIFY_TASK_DESCRIPTION_CHANGED_LISTENERS_MSG,
325 taskId, 0 /* unused */, taskDescription);
326 forAllLocalListeners(mNotifyTaskDescriptionChanged, msg);
327 msg.sendToTarget();
328
Yorke Leebd54c2a2016-10-25 13:49:23 -0700329 }
330
331 void notifyActivityRequestedOrientationChanged(int taskId, int orientation) {
Yorke Lee13294072017-01-06 14:59:58 -0800332 final Message msg = mHandler.obtainMessage(
333 NOTIFY_ACTIVITY_REQUESTED_ORIENTATION_CHANGED_LISTENERS, taskId, orientation);
334 forAllLocalListeners(mNotifyActivityRequestedOrientationChanged, msg);
335 msg.sendToTarget();
Yorke Leebd54c2a2016-10-25 13:49:23 -0700336 }
337
338 /**
339 * Notify listeners that the task is about to be finished before its surfaces are removed from
340 * the window manager. This allows interested parties to perform relevant animations before
341 * the window disappears.
342 */
343 void notifyTaskRemovalStarted(int taskId) {
Yorke Lee13294072017-01-06 14:59:58 -0800344 final Message msg = mHandler.obtainMessage(NOTIFY_TASK_REMOVAL_STARTED_LISTENERS, taskId,
345 0 /* unused */);
346 forAllLocalListeners(mNotifyTaskRemovalStarted, msg);
347 msg.sendToTarget();
348
Yorke Leebd54c2a2016-10-25 13:49:23 -0700349 }
Robin Leec41f6ec2017-01-10 17:02:34 +0000350
351 /**
352 * Notify listeners that the task has been put in a locked state because one or more of the
353 * activities inside it belong to a managed profile user that has been locked.
354 */
355 void notifyTaskProfileLocked(int taskId, int userId) {
Yorke Lee13294072017-01-06 14:59:58 -0800356 final Message msg = mHandler.obtainMessage(NOTIFY_TASK_PROFILE_LOCKED_LISTENERS_MSG, taskId,
357 userId);
358 forAllLocalListeners(mNotifyTaskProfileLocked, msg);
359 msg.sendToTarget();
Robin Leec41f6ec2017-01-10 17:02:34 +0000360 }
Jorim Jaggifb9d78a2017-01-05 18:57:12 +0100361
362 /**
363 * Notify listeners that the snapshot of a task has changed.
364 */
365 void notifyTaskSnapshotChanged(int taskId, TaskSnapshot snapshot) {
366 final Message msg = mHandler.obtainMessage(NOTIFY_TASK_SNAPSHOT_CHANGED_LISTENERS_MSG,
367 taskId, 0, snapshot);
368 forAllLocalListeners(mNotifyTaskSnapshotChanged, msg);
369 msg.sendToTarget();
370 }
Yorke Leebd54c2a2016-10-25 13:49:23 -0700371}