OSDN Git Service

Merge "docs: Add documentation for equals() method" into qt-dev
[android-x86/frameworks-base.git] / packages / SystemUI / shared / src / com / android / systemui / shared / system / TaskStackChangeListeners.java
1 /*
2  * Copyright (C) 2017 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
17 package com.android.systemui.shared.system;
18
19 import android.app.ActivityManager.RunningTaskInfo;
20 import android.app.ActivityManager.TaskSnapshot;
21 import android.app.ActivityTaskManager;
22 import android.app.IActivityManager;
23 import android.app.TaskStackListener;
24 import android.content.ComponentName;
25 import android.os.Handler;
26 import android.os.IBinder;
27 import android.os.Looper;
28 import android.os.Message;
29 import android.os.RemoteException;
30 import android.os.Trace;
31 import android.util.Log;
32
33 import com.android.systemui.shared.recents.model.ThumbnailData;
34
35 import java.util.ArrayList;
36 import java.util.List;
37
38 /**
39  * Tracks all the task stack listeners
40  */
41 public class TaskStackChangeListeners extends TaskStackListener {
42
43     private static final String TAG = TaskStackChangeListeners.class.getSimpleName();
44
45     /**
46      * List of {@link TaskStackChangeListener} registered from {@link #addListener}.
47      */
48     private final List<TaskStackChangeListener> mTaskStackListeners = new ArrayList<>();
49     private final List<TaskStackChangeListener> mTmpListeners = new ArrayList<>();
50
51     private final Handler mHandler;
52     private boolean mRegistered;
53
54     public TaskStackChangeListeners(Looper looper) {
55         mHandler = new H(looper);
56     }
57
58     public void addListener(IActivityManager am, TaskStackChangeListener listener) {
59         mTaskStackListeners.add(listener);
60         if (!mRegistered) {
61             // Register mTaskStackListener to IActivityManager only once if needed.
62             try {
63                 ActivityTaskManager.getService().registerTaskStackListener(this);
64                 mRegistered = true;
65             } catch (Exception e) {
66                 Log.w(TAG, "Failed to call registerTaskStackListener", e);
67             }
68         }
69     }
70
71     public void removeListener(TaskStackChangeListener listener) {
72         mTaskStackListeners.remove(listener);
73         if (mTaskStackListeners.isEmpty() && mRegistered) {
74             // Unregister mTaskStackListener once we have no more listeners
75             try {
76                 ActivityTaskManager.getService().unregisterTaskStackListener(this);
77                 mRegistered = false;
78             } catch (Exception e) {
79                 Log.w(TAG, "Failed to call unregisterTaskStackListener", e);
80             }
81         }
82     }
83
84     @Override
85     public void onTaskStackChanged() throws RemoteException {
86         // Call the task changed callback for the non-ui thread listeners first
87         synchronized (mTaskStackListeners) {
88             mTmpListeners.clear();
89             mTmpListeners.addAll(mTaskStackListeners);
90         }
91         for (int i = mTmpListeners.size() - 1; i >= 0; i--) {
92             mTmpListeners.get(i).onTaskStackChangedBackground();
93         }
94
95         mHandler.removeMessages(H.ON_TASK_STACK_CHANGED);
96         mHandler.sendEmptyMessage(H.ON_TASK_STACK_CHANGED);
97     }
98
99     @Override
100     public void onActivityPinned(String packageName, int userId, int taskId, int stackId)
101             throws RemoteException {
102         mHandler.removeMessages(H.ON_ACTIVITY_PINNED);
103         mHandler.obtainMessage(H.ON_ACTIVITY_PINNED,
104                 new PinnedActivityInfo(packageName, userId, taskId, stackId)).sendToTarget();
105     }
106
107     @Override
108     public void onActivityUnpinned() throws RemoteException {
109         mHandler.removeMessages(H.ON_ACTIVITY_UNPINNED);
110         mHandler.sendEmptyMessage(H.ON_ACTIVITY_UNPINNED);
111     }
112
113     @Override
114     public void onPinnedActivityRestartAttempt(boolean clearedTask)
115             throws RemoteException {
116         mHandler.removeMessages(H.ON_PINNED_ACTIVITY_RESTART_ATTEMPT);
117         mHandler.obtainMessage(H.ON_PINNED_ACTIVITY_RESTART_ATTEMPT, clearedTask ? 1 : 0, 0)
118                 .sendToTarget();
119     }
120
121     @Override
122     public void onPinnedStackAnimationStarted() throws RemoteException {
123         mHandler.removeMessages(H.ON_PINNED_STACK_ANIMATION_STARTED);
124         mHandler.sendEmptyMessage(H.ON_PINNED_STACK_ANIMATION_STARTED);
125     }
126
127     @Override
128     public void onPinnedStackAnimationEnded() throws RemoteException {
129         mHandler.removeMessages(H.ON_PINNED_STACK_ANIMATION_ENDED);
130         mHandler.sendEmptyMessage(H.ON_PINNED_STACK_ANIMATION_ENDED);
131     }
132
133     @Override
134     public void onActivityForcedResizable(String packageName, int taskId, int reason)
135             throws RemoteException {
136         mHandler.obtainMessage(H.ON_ACTIVITY_FORCED_RESIZABLE, taskId, reason, packageName)
137                 .sendToTarget();
138     }
139
140     @Override
141     public void onActivityDismissingDockedStack() throws RemoteException {
142         mHandler.sendEmptyMessage(H.ON_ACTIVITY_DISMISSING_DOCKED_STACK);
143     }
144
145     @Override
146     public void onActivityLaunchOnSecondaryDisplayFailed(RunningTaskInfo taskInfo,
147             int requestedDisplayId) throws RemoteException {
148         mHandler.obtainMessage(H.ON_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED, requestedDisplayId,
149                 0 /* unused */,
150                 taskInfo).sendToTarget();
151     }
152
153     @Override
154     public void onActivityLaunchOnSecondaryDisplayRerouted(RunningTaskInfo taskInfo,
155             int requestedDisplayId) throws RemoteException {
156         mHandler.obtainMessage(H.ON_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_REROUTED,
157                 requestedDisplayId, 0 /* unused */, taskInfo).sendToTarget();
158     }
159
160     @Override
161     public void onTaskProfileLocked(int taskId, int userId) throws RemoteException {
162         mHandler.obtainMessage(H.ON_TASK_PROFILE_LOCKED, taskId, userId).sendToTarget();
163     }
164
165     @Override
166     public void onTaskSnapshotChanged(int taskId, TaskSnapshot snapshot) throws RemoteException {
167         mHandler.obtainMessage(H.ON_TASK_SNAPSHOT_CHANGED, taskId, 0, snapshot).sendToTarget();
168     }
169
170     @Override
171     public void onTaskCreated(int taskId, ComponentName componentName) throws RemoteException {
172         mHandler.obtainMessage(H.ON_TASK_CREATED, taskId, 0, componentName).sendToTarget();
173     }
174
175     @Override
176     public void onTaskRemoved(int taskId) throws RemoteException {
177         mHandler.obtainMessage(H.ON_TASK_REMOVED, taskId, 0).sendToTarget();
178     }
179
180     @Override
181     public void onTaskMovedToFront(RunningTaskInfo taskInfo)
182             throws RemoteException {
183         mHandler.obtainMessage(H.ON_TASK_MOVED_TO_FRONT, taskInfo).sendToTarget();
184     }
185
186     @Override
187     public void onBackPressedOnTaskRoot(RunningTaskInfo taskInfo) throws RemoteException {
188         mHandler.obtainMessage(H.ON_BACK_PRESSED_ON_TASK_ROOT, taskInfo).sendToTarget();
189     }
190
191     @Override
192     public void onActivityRequestedOrientationChanged(int taskId, int requestedOrientation)
193             throws RemoteException {
194         mHandler.obtainMessage(H.ON_ACTIVITY_REQUESTED_ORIENTATION_CHANGE, taskId,
195                 requestedOrientation).sendToTarget();
196     }
197
198     @Override
199     public void onSizeCompatModeActivityChanged(int displayId, IBinder activityToken) {
200         mHandler.obtainMessage(H.ON_SIZE_COMPAT_MODE_ACTIVITY_CHANGED, displayId, 0 /* unused */,
201                 activityToken).sendToTarget();
202     }
203
204     @Override
205     public void onTaskDisplayChanged(int taskId, int newDisplayId) throws RemoteException {
206         mHandler.obtainMessage(H.ON_TASK_DISPLAY_CHANGED, taskId, newDisplayId).sendToTarget();
207     }
208
209     private final class H extends Handler {
210         private static final int ON_TASK_STACK_CHANGED = 1;
211         private static final int ON_TASK_SNAPSHOT_CHANGED = 2;
212         private static final int ON_ACTIVITY_PINNED = 3;
213         private static final int ON_PINNED_ACTIVITY_RESTART_ATTEMPT = 4;
214         private static final int ON_PINNED_STACK_ANIMATION_ENDED = 5;
215         private static final int ON_ACTIVITY_FORCED_RESIZABLE = 6;
216         private static final int ON_ACTIVITY_DISMISSING_DOCKED_STACK = 7;
217         private static final int ON_TASK_PROFILE_LOCKED = 8;
218         private static final int ON_PINNED_STACK_ANIMATION_STARTED = 9;
219         private static final int ON_ACTIVITY_UNPINNED = 10;
220         private static final int ON_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED = 11;
221         private static final int ON_TASK_CREATED = 12;
222         private static final int ON_TASK_REMOVED = 13;
223         private static final int ON_TASK_MOVED_TO_FRONT = 14;
224         private static final int ON_ACTIVITY_REQUESTED_ORIENTATION_CHANGE = 15;
225         private static final int ON_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_REROUTED = 16;
226         private static final int ON_SIZE_COMPAT_MODE_ACTIVITY_CHANGED = 17;
227         private static final int ON_BACK_PRESSED_ON_TASK_ROOT = 18;
228         private static final int ON_TASK_DISPLAY_CHANGED = 19;
229
230
231         public H(Looper looper) {
232             super(looper);
233         }
234
235         @Override
236         public void handleMessage(Message msg) {
237             synchronized (mTaskStackListeners) {
238                 switch (msg.what) {
239                     case ON_TASK_STACK_CHANGED: {
240                         Trace.beginSection("onTaskStackChanged");
241                         for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
242                             mTaskStackListeners.get(i).onTaskStackChanged();
243                         }
244                         Trace.endSection();
245                         break;
246                     }
247                     case ON_TASK_SNAPSHOT_CHANGED: {
248                         Trace.beginSection("onTaskSnapshotChanged");
249                         for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
250                             mTaskStackListeners.get(i).onTaskSnapshotChanged(msg.arg1,
251                                     new ThumbnailData((TaskSnapshot) msg.obj));
252                         }
253                         Trace.endSection();
254                         break;
255                     }
256                     case ON_ACTIVITY_PINNED: {
257                         final PinnedActivityInfo info = (PinnedActivityInfo) msg.obj;
258                         for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
259                             mTaskStackListeners.get(i).onActivityPinned(
260                                     info.mPackageName, info.mUserId, info.mTaskId, info.mStackId);
261                         }
262                         break;
263                     }
264                     case ON_ACTIVITY_UNPINNED: {
265                         for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
266                             mTaskStackListeners.get(i).onActivityUnpinned();
267                         }
268                         break;
269                     }
270                     case ON_PINNED_ACTIVITY_RESTART_ATTEMPT: {
271                         for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
272                             mTaskStackListeners.get(i).onPinnedActivityRestartAttempt(
273                                     msg.arg1 != 0);
274                         }
275                         break;
276                     }
277                     case ON_PINNED_STACK_ANIMATION_STARTED: {
278                         for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
279                             mTaskStackListeners.get(i).onPinnedStackAnimationStarted();
280                         }
281                         break;
282                     }
283                     case ON_PINNED_STACK_ANIMATION_ENDED: {
284                         for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
285                             mTaskStackListeners.get(i).onPinnedStackAnimationEnded();
286                         }
287                         break;
288                     }
289                     case ON_ACTIVITY_FORCED_RESIZABLE: {
290                         for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
291                             mTaskStackListeners.get(i).onActivityForcedResizable(
292                                     (String) msg.obj, msg.arg1, msg.arg2);
293                         }
294                         break;
295                     }
296                     case ON_ACTIVITY_DISMISSING_DOCKED_STACK: {
297                         for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
298                             mTaskStackListeners.get(i).onActivityDismissingDockedStack();
299                         }
300                         break;
301                     }
302                     case ON_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED: {
303                         final RunningTaskInfo info = (RunningTaskInfo) msg.obj;
304                         for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
305                             mTaskStackListeners.get(i)
306                                     .onActivityLaunchOnSecondaryDisplayFailed(info);
307                         }
308                         break;
309                     }
310                     case ON_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_REROUTED: {
311                         final RunningTaskInfo info = (RunningTaskInfo) msg.obj;
312                         for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
313                             mTaskStackListeners.get(i)
314                                     .onActivityLaunchOnSecondaryDisplayRerouted(info);
315                         }
316                         break;
317                     }
318                     case ON_TASK_PROFILE_LOCKED: {
319                         for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
320                             mTaskStackListeners.get(i).onTaskProfileLocked(msg.arg1, msg.arg2);
321                         }
322                         break;
323                     }
324                     case ON_TASK_CREATED: {
325                         for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
326                             mTaskStackListeners.get(i).onTaskCreated(msg.arg1,
327                                     (ComponentName) msg.obj);
328                         }
329                         break;
330                     }
331                     case ON_TASK_REMOVED: {
332                         for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
333                             mTaskStackListeners.get(i).onTaskRemoved(msg.arg1);
334                         }
335                         break;
336                     }
337                     case ON_TASK_MOVED_TO_FRONT: {
338                         final RunningTaskInfo info = (RunningTaskInfo) msg.obj;
339                         for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
340                             mTaskStackListeners.get(i).onTaskMovedToFront(info);
341                         }
342                         break;
343                     }
344                     case ON_ACTIVITY_REQUESTED_ORIENTATION_CHANGE: {
345                         for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
346                             mTaskStackListeners.get(i)
347                                     .onActivityRequestedOrientationChanged(msg.arg1, msg.arg2);
348                         }
349                         break;
350                     }
351                     case ON_SIZE_COMPAT_MODE_ACTIVITY_CHANGED: {
352                         for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
353                             mTaskStackListeners.get(i).onSizeCompatModeActivityChanged(
354                                     msg.arg1, (IBinder) msg.obj);
355                         }
356                         break;
357                     }
358                     case ON_BACK_PRESSED_ON_TASK_ROOT: {
359                         for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
360                             mTaskStackListeners.get(i).onBackPressedOnTaskRoot(
361                                     (RunningTaskInfo) msg.obj);
362                         }
363                         break;
364                     }
365                     case ON_TASK_DISPLAY_CHANGED: {
366                         for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
367                             mTaskStackListeners.get(i).onTaskDisplayChanged(msg.arg1, msg.arg2);
368                         }
369                         break;
370                     }
371                 }
372             }
373         }
374     }
375
376     private static class PinnedActivityInfo {
377         final String mPackageName;
378         final int mUserId;
379         final int mTaskId;
380         final int mStackId;
381
382         PinnedActivityInfo(String packageName, int userId, int taskId, int stackId) {
383             mPackageName = packageName;
384             mUserId = userId;
385             mTaskId = taskId;
386             mStackId = stackId;
387         }
388     }
389 }