diff --git a/core/java/android/app/ITaskStackListener.aidl b/core/java/android/app/ITaskStackListener.aidl index 3f6880fc26258..650147b45bd24 100644 --- a/core/java/android/app/ITaskStackListener.aidl +++ b/core/java/android/app/ITaskStackListener.aidl @@ -177,4 +177,12 @@ oneway interface ITaskStackListener { * @param displayId the id of the display on which contents are drawn. */ void onSingleTaskDisplayDrawn(int displayId); + + /** + * Called when a task is reparented to a stack on a different display. + * + * @param taskId id of the task which was moved to a different display. + * @param newDisplayId id of the new display. + */ + void onTaskDisplayChanged(int taskId, int newDisplayId); } diff --git a/core/java/android/app/TaskStackListener.java b/core/java/android/app/TaskStackListener.java index 36daf32234dba..b63feb590ad13 100644 --- a/core/java/android/app/TaskStackListener.java +++ b/core/java/android/app/TaskStackListener.java @@ -26,6 +26,7 @@ import android.os.RemoteException; /** * Classes interested in observing only a subset of changes using ITaskStackListener can extend * this class to avoid having to implement all the methods. + * * @hide */ public abstract class TaskStackListener extends ITaskStackListener.Stub { @@ -177,4 +178,8 @@ public abstract class TaskStackListener extends ITaskStackListener.Stub { @Override public void onSingleTaskDisplayDrawn(int displayId) throws RemoteException { } + + @Override + public void onTaskDisplayChanged(int taskId, int newDisplayId) throws RemoteException { + } } diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java index f298b597bb766..18a41ba6b9af3 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java @@ -346,7 +346,7 @@ public class CarStatusBar extends StatusBar implements CarSystemUIFactory factory = SystemUIFactory.getInstance(); mCarFacetButtonController = factory.getCarDependencyComponent() - .getCarFacetButtonController(); + .getCarFacetButtonController(); mNotificationPanelBackground = getDefaultWallpaper(); mScrimController.setScrimBehindDrawable(mNotificationPanelBackground); @@ -924,6 +924,16 @@ public class CarStatusBar extends StatusBar implements Log.e(TAG, "Getting StackInfo from activity manager failed", e); } } + + @Override + public void onTaskDisplayChanged(int taskId, int newDisplayId) { + try { + mCarFacetButtonController.taskChanged( + ActivityTaskManager.getService().getAllStackInfos()); + } catch (Exception e) { + Log.e(TAG, "Getting StackInfo from activity manager failed", e); + } + } } private void onDrivingStateChanged(CarDrivingStateEvent notUsed) { diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java index bd2b19c0ddfe3..c215d0fc13d64 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java @@ -86,6 +86,14 @@ public abstract class TaskStackChangeListener { public void onBackPressedOnTaskRoot(RunningTaskInfo taskInfo) { } + /** + * Called when a task is reparented to a stack on a different display. + * + * @param taskId id of the task which was moved to a different display. + * @param newDisplayId id of the new display. + */ + public void onTaskDisplayChanged(int taskId, int newDisplayId) { } + /** * Checks that the current user matches the process. Since * {@link android.app.ITaskStackListener} is not multi-user aware, handlers of diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java index c89f2ab7f172c..d570a586f9613 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java @@ -112,7 +112,7 @@ public class TaskStackChangeListeners extends TaskStackListener { @Override public void onPinnedActivityRestartAttempt(boolean clearedTask) - throws RemoteException{ + throws RemoteException { mHandler.removeMessages(H.ON_PINNED_ACTIVITY_RESTART_ATTEMPT); mHandler.obtainMessage(H.ON_PINNED_ACTIVITY_RESTART_ATTEMPT, clearedTask ? 1 : 0, 0) .sendToTarget(); @@ -154,7 +154,7 @@ public class TaskStackChangeListeners extends TaskStackListener { public void onActivityLaunchOnSecondaryDisplayRerouted(RunningTaskInfo taskInfo, int requestedDisplayId) throws RemoteException { mHandler.obtainMessage(H.ON_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_REROUTED, - requestedDisplayId, 0 /* unused */, taskInfo).sendToTarget(); + requestedDisplayId, 0 /* unused */, taskInfo).sendToTarget(); } @Override @@ -208,6 +208,11 @@ public class TaskStackChangeListeners extends TaskStackListener { 0 /* unused */).sendToTarget(); } + @Override + public void onTaskDisplayChanged(int taskId, int newDisplayId) throws RemoteException { + mHandler.obtainMessage(H.ON_TASK_DISPLAY_CHANGED, taskId, newDisplayId).sendToTarget(); + } + private final class H extends Handler { private static final int ON_TASK_STACK_CHANGED = 1; private static final int ON_TASK_SNAPSHOT_CHANGED = 2; @@ -228,6 +233,7 @@ public class TaskStackChangeListeners extends TaskStackListener { private static final int ON_SIZE_COMPAT_MODE_ACTIVITY_CHANGED = 17; private static final int ON_BACK_PRESSED_ON_TASK_ROOT = 18; private static final int ON_SINGLE_TASK_DISPLAY_DRAWN = 19; + private static final int ON_TASK_DISPLAY_CHANGED = 20; public H(Looper looper) { @@ -313,7 +319,7 @@ public class TaskStackChangeListeners extends TaskStackListener { final RunningTaskInfo info = (RunningTaskInfo) msg.obj; for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) { mTaskStackListeners.get(i) - .onActivityLaunchOnSecondaryDisplayRerouted(info); + .onActivityLaunchOnSecondaryDisplayRerouted(info); } break; } @@ -370,6 +376,12 @@ public class TaskStackChangeListeners extends TaskStackListener { } break; } + case ON_TASK_DISPLAY_CHANGED: { + for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) { + mTaskStackListeners.get(i).onTaskDisplayChanged(msg.arg1, msg.arg2); + } + break; + } } } } diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 38201069ebca1..fd86faa6d0355 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -348,6 +348,9 @@ class Task extends WindowContainer implements ConfigurationConta void onDisplayChanged(DisplayContent dc) { adjustBoundsForDisplayChangeIfNeeded(dc); super.onDisplayChanged(dc); + final int displayId = (dc != null) ? dc.getDisplayId() : Display.INVALID_DISPLAY; + mWmService.mAtmService.getTaskChangeNotificationController().notifyTaskDisplayChanged( + mTaskId, displayId); } /** diff --git a/services/core/java/com/android/server/wm/TaskChangeNotificationController.java b/services/core/java/com/android/server/wm/TaskChangeNotificationController.java index 27175c7068126..f776062b31a11 100644 --- a/services/core/java/com/android/server/wm/TaskChangeNotificationController.java +++ b/services/core/java/com/android/server/wm/TaskChangeNotificationController.java @@ -55,6 +55,7 @@ class TaskChangeNotificationController { private static final int NOTIFY_SIZE_COMPAT_MODE_ACTIVITY_CHANGED_MSG = 20; private static final int NOTIFY_BACK_PRESSED_ON_TASK_ROOT = 21; private static final int NOTIFY_SINGLE_TASK_DISPLAY_DRAWN = 22; + private static final int NOTIFY_TASK_DISPLAY_CHANGED_LISTENERS_MSG = 23; // Delay in notifying task stack change listeners (in millis) private static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100; @@ -159,6 +160,10 @@ class TaskChangeNotificationController { l.onSingleTaskDisplayDrawn(m.arg1); }; + private final TaskStackConsumer mNotifyTaskDisplayChanged = (l, m) -> { + l.onTaskDisplayChanged(m.arg1, m.arg2); + }; + @FunctionalInterface public interface TaskStackConsumer { void accept(ITaskStackListener t, Message m) throws RemoteException; @@ -241,6 +246,9 @@ class TaskChangeNotificationController { case NOTIFY_SINGLE_TASK_DISPLAY_DRAWN: forAllRemoteListeners(mNotifySingleTaskDisplayDrawn, msg); break; + case NOTIFY_TASK_DISPLAY_CHANGED_LISTENERS_MSG: + forAllRemoteListeners(mNotifyTaskDisplayChanged, msg); + break; } } } @@ -495,4 +503,14 @@ class TaskChangeNotificationController { forAllLocalListeners(mNotifySingleTaskDisplayDrawn, msg); msg.sendToTarget(); } + + /** + * Notify listeners that a task is reparented to another display. + */ + void notifyTaskDisplayChanged(int taskId, int newDisplayId) { + final Message msg = mHandler.obtainMessage(NOTIFY_TASK_DISPLAY_CHANGED_LISTENERS_MSG, + taskId, newDisplayId); + forAllLocalListeners(mNotifyTaskStackChanged, msg); + msg.sendToTarget(); + } } diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java index 366aceafd7bf4..d0ee634352804 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java +++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java @@ -162,6 +162,9 @@ public class SystemServicesTestRule implements TestRule { } final ActivityTaskManagerService atms = mock(ActivityTaskManagerService.class); + final TaskChangeNotificationController taskChangeNotificationController = mock( + TaskChangeNotificationController.class); + doReturn(taskChangeNotificationController).when(atms).getTaskChangeNotificationController(); final WindowManagerGlobalLock wmLock = new WindowManagerGlobalLock(); doReturn(wmLock).when(atms).getGlobalLock();