Loading libs/WindowManager/Shell/res/raw/wm_shell_protolog.json +6 −6 Original line number Diff line number Diff line { "version": "1.0.0", "messages": { "-1823823103": { "message": "Add listener for types=%s listener=%s", "level": "VERBOSE", "group": "WM_SHELL_TASK_ORG", "at": "com\/android\/wm\/shell\/ShellTaskOrganizer.java" }, "-1534364071": { "message": "onTransitionReady %s: %s", "level": "VERBOSE", Loading Loading @@ -37,12 +43,6 @@ "group": "WM_SHELL_TASK_ORG", "at": "com\/android\/wm\/shell\/ShellTaskOrganizer.java" }, "-242812822": { "message": "Add listener for modes=%s listener=%s", "level": "VERBOSE", "group": "WM_SHELL_TASK_ORG", "at": "com\/android\/wm\/shell\/ShellTaskOrganizer.java" }, "-191422040": { "message": "Transition animations finished, notifying core %s", "level": "VERBOSE", Loading libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java +75 −28 Original line number Diff line number Diff line Loading @@ -16,9 +16,17 @@ package com.android.wm.shell; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import android.annotation.IntDef; import android.app.ActivityManager.RunningTaskInfo; import android.app.WindowConfiguration.WindowingMode; import android.util.Log; import android.util.Pair; import android.util.SparseArray; Loading @@ -33,7 +41,6 @@ import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.TransactionPool; import com.android.wm.shell.protolog.ShellProtoLogGroup; import java.util.ArrayList; import java.util.Arrays; /** Loading @@ -42,6 +49,23 @@ import java.util.Arrays; */ public class ShellTaskOrganizer extends TaskOrganizer { // Intentionally using negative numbers here so the positive numbers can be used // for task id specific listeners that will be added later. public static final int TASK_LISTENER_TYPE_UNDEFINED = -1; public static final int TASK_LISTENER_TYPE_FULLSCREEN = -2; public static final int TASK_LISTENER_TYPE_MULTI_WINDOW = -3; public static final int TASK_LISTENER_TYPE_PIP = -4; public static final int TASK_LISTENER_TYPE_SPLIT_SCREEN = -5; @IntDef(prefix = {"TASK_LISTENER_TYPE_"}, value = { TASK_LISTENER_TYPE_UNDEFINED, TASK_LISTENER_TYPE_FULLSCREEN, TASK_LISTENER_TYPE_MULTI_WINDOW, TASK_LISTENER_TYPE_PIP, TASK_LISTENER_TYPE_SPLIT_SCREEN, }) public @interface TaskListenerType {} private static final String TAG = "ShellTaskOrganizer"; /** Loading @@ -54,7 +78,7 @@ public class ShellTaskOrganizer extends TaskOrganizer { default void onBackPressedOnTaskRoot(RunningTaskInfo taskInfo) {} } private final SparseArray<TaskListener> mListenerByWindowingMode = new SparseArray<>(); private final SparseArray<TaskListener> mTaskListenersByType = new SparseArray<>(); // Keeps track of all the tasks reported to this organizer (changes in windowing mode will // require us to report to both old and new listeners) Loading @@ -73,29 +97,29 @@ public class ShellTaskOrganizer extends TaskOrganizer { SyncTransactionQueue syncQueue, TransactionPool transactionPool, ShellExecutor mainExecutor, ShellExecutor animExecutor) { super(taskOrganizerController); addListener(new FullscreenTaskListener(syncQueue), WINDOWING_MODE_FULLSCREEN); addListener(new FullscreenTaskListener(syncQueue), TASK_LISTENER_TYPE_FULLSCREEN); mTransitions = new Transitions(this, transactionPool, mainExecutor, animExecutor); if (Transitions.ENABLE_SHELL_TRANSITIONS) registerTransitionPlayer(mTransitions); } /** * Adds a listener for tasks in a specific windowing mode. * Adds a listener for tasks with given types. */ public void addListener(TaskListener listener, int... windowingModes) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Add listener for modes=%s listener=%s", Arrays.toString(windowingModes), listener); for (int winMode : windowingModes) { if (mListenerByWindowingMode.get(winMode) != null) { throw new IllegalArgumentException("Listener for winMode=" + winMode public void addListener(TaskListener listener, @TaskListenerType int... taskListenerTypes) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Add listener for types=%s listener=%s", Arrays.toString(taskListenerTypes), listener); for (int listenerType : taskListenerTypes) { if (mTaskListenersByType.get(listenerType) != null) { throw new IllegalArgumentException("Listener for listenerType=" + listenerType + " already exists"); } mListenerByWindowingMode.put(winMode, listener); mTaskListenersByType.put(listenerType, listener); // Notify the listener of all existing tasks in that windowing mode // Notify the listener of all existing tasks with the given type. for (int i = mTasks.size() - 1; i >= 0; i--) { Pair<RunningTaskInfo, SurfaceControl> data = mTasks.valueAt(i); int taskWinMode = data.first.configuration.windowConfiguration.getWindowingMode(); if (taskWinMode == winMode) { final @TaskListenerType int taskListenerType = getTaskListenerType(data.first); if (taskListenerType == listenerType) { listener.onTaskAppeared(data.first, data.second); } } Loading @@ -107,12 +131,12 @@ public class ShellTaskOrganizer extends TaskOrganizer { */ public void removeListener(TaskListener listener) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Remove listener=%s", listener); final int index = mListenerByWindowingMode.indexOfValue(listener); final int index = mTaskListenersByType.indexOfValue(listener); if (index == -1) { Log.w(TAG, "No registered listener found"); return; } mListenerByWindowingMode.removeAt(index); mTaskListenersByType.removeAt(index); } @Override Loading @@ -120,7 +144,7 @@ public class ShellTaskOrganizer extends TaskOrganizer { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Task appeared taskId=%d", taskInfo.taskId); mTasks.put(taskInfo.taskId, new Pair<>(taskInfo, leash)); final TaskListener listener = mListenerByWindowingMode.get(getWindowingMode(taskInfo)); final TaskListener listener = mTaskListenersByType.get(getTaskListenerType(taskInfo)); if (listener != null) { listener.onTaskAppeared(taskInfo, leash); } Loading @@ -131,23 +155,23 @@ public class ShellTaskOrganizer extends TaskOrganizer { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Task info changed taskId=%d", taskInfo.taskId); final Pair<RunningTaskInfo, SurfaceControl> data = mTasks.get(taskInfo.taskId); final int winMode = getWindowingMode(taskInfo); final int prevWinMode = getWindowingMode(data.first); final @TaskListenerType int listenerType = getTaskListenerType(taskInfo); final @TaskListenerType int prevListenerType = getTaskListenerType(data.first); mTasks.put(taskInfo.taskId, new Pair<>(taskInfo, data.second)); if (prevWinMode != -1 && prevWinMode != winMode) { // TODO: We currently send vanished/appeared as the task moves between win modes, but if (prevListenerType != listenerType) { // TODO: We currently send vanished/appeared as the task moves between types, but // we should consider adding a different mode-changed callback TaskListener listener = mListenerByWindowingMode.get(prevWinMode); TaskListener listener = mTaskListenersByType.get(prevListenerType); if (listener != null) { listener.onTaskVanished(taskInfo); } listener = mListenerByWindowingMode.get(winMode); listener = mTaskListenersByType.get(listenerType); if (listener != null) { SurfaceControl leash = data.second; listener.onTaskAppeared(taskInfo, leash); } } else { final TaskListener listener = mListenerByWindowingMode.get(winMode); final TaskListener listener = mTaskListenersByType.get(listenerType); if (listener != null) { listener.onTaskInfoChanged(taskInfo); } Loading @@ -158,7 +182,7 @@ public class ShellTaskOrganizer extends TaskOrganizer { public void onBackPressedOnTaskRoot(RunningTaskInfo taskInfo) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Task root back pressed taskId=%d", taskInfo.taskId); final TaskListener listener = mListenerByWindowingMode.get(getWindowingMode(taskInfo)); final TaskListener listener = mTaskListenersByType.get(getTaskListenerType(taskInfo)); if (listener != null) { listener.onBackPressedOnTaskRoot(taskInfo); } Loading @@ -168,15 +192,38 @@ public class ShellTaskOrganizer extends TaskOrganizer { public void onTaskVanished(RunningTaskInfo taskInfo) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Task vanished taskId=%d", taskInfo.taskId); final int prevWinMode = getWindowingMode(mTasks.get(taskInfo.taskId).first); final @TaskListenerType int prevListenerType = getTaskListenerType(mTasks.get(taskInfo.taskId).first); mTasks.remove(taskInfo.taskId); final TaskListener listener = mListenerByWindowingMode.get(prevWinMode); final TaskListener listener = mTaskListenersByType.get(prevListenerType); if (listener != null) { listener.onTaskVanished(taskInfo); } } private int getWindowingMode(RunningTaskInfo taskInfo) { @TaskListenerType private static int getTaskListenerType(RunningTaskInfo runningTaskInfo) { // Right now it's N:1 mapping but in the future different task listerners // may be triggered by one windowing mode depending on task parameters. switch (getWindowingMode(runningTaskInfo)) { case WINDOWING_MODE_FULLSCREEN: return TASK_LISTENER_TYPE_FULLSCREEN; case WINDOWING_MODE_MULTI_WINDOW: return TASK_LISTENER_TYPE_MULTI_WINDOW; case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY: case WINDOWING_MODE_SPLIT_SCREEN_SECONDARY: return TASK_LISTENER_TYPE_SPLIT_SCREEN; case WINDOWING_MODE_PINNED: return TASK_LISTENER_TYPE_PIP; case WINDOWING_MODE_FREEFORM: case WINDOWING_MODE_UNDEFINED: default: return TASK_LISTENER_TYPE_UNDEFINED; } } @WindowingMode private static int getWindowingMode(RunningTaskInfo taskInfo) { return taskInfo.configuration.windowConfiguration.getWindowingMode(); } } libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java +2 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_PIP; import static com.android.wm.shell.pip.PipAnimationController.ANIM_TYPE_ALPHA; import static com.android.wm.shell.pip.PipAnimationController.ANIM_TYPE_BOUNDS; import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTION_LEAVE_PIP; Loading Loading @@ -282,7 +283,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, if (!PipUtils.hasSystemFeature(context)) { Log.w(TAG, "Device not support PIP feature"); } else { mTaskOrganizer.addListener(this, WINDOWING_MODE_PINNED); mTaskOrganizer.addListener(this, TASK_LISTENER_TYPE_PIP); displayController.addDisplayWindowListener(this); } } Loading libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTaskOrganizer.java +5 −5 Original line number Diff line number Diff line Loading @@ -23,8 +23,9 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMAR import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.view.Display.DEFAULT_DISPLAY; import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_SPLIT_SCREEN; import android.app.ActivityManager.RunningTaskInfo; import android.app.WindowConfiguration; import android.graphics.Rect; import android.os.RemoteException; import android.util.Log; Loading Loading @@ -56,17 +57,16 @@ class SplitScreenTaskOrganizer implements ShellTaskOrganizer.TaskListener { ShellTaskOrganizer shellTaskOrganizer) { mSplitScreenController = splitScreenController; mTaskOrganizer = shellTaskOrganizer; mTaskOrganizer.addListener(this, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY); mTaskOrganizer.addListener(this, TASK_LISTENER_TYPE_SPLIT_SCREEN); } void init() throws RemoteException { synchronized (this) { try { mPrimary = mTaskOrganizer.createRootTask(Display.DEFAULT_DISPLAY, WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); mSecondary = mTaskOrganizer.createRootTask(Display.DEFAULT_DISPLAY, WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY); WINDOWING_MODE_SPLIT_SCREEN_SECONDARY); } catch (Exception e) { // teardown to prevent callbacks mTaskOrganizer.removeListener(this); Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java +10 −7 Original line number Diff line number Diff line Loading @@ -19,6 +19,9 @@ package com.android.wm.shell; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_MULTI_WINDOW; import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_PIP; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; Loading Loading @@ -102,10 +105,10 @@ public class ShellTaskOrganizerTests { } @Test public void testOneListenerPerMode() { mOrganizer.addListener(new TrackingTaskListener(), WINDOWING_MODE_MULTI_WINDOW); public void testOneListenerPerType() { mOrganizer.addListener(new TrackingTaskListener(), TASK_LISTENER_TYPE_MULTI_WINDOW); try { mOrganizer.addListener(new TrackingTaskListener(), WINDOWING_MODE_MULTI_WINDOW); mOrganizer.addListener(new TrackingTaskListener(), TASK_LISTENER_TYPE_MULTI_WINDOW); fail("Expected exception due to already registered listener"); } catch (Exception e) { // Expected failure Loading @@ -116,7 +119,7 @@ public class ShellTaskOrganizerTests { public void testAppearedVanished() { RunningTaskInfo taskInfo = createTaskInfo(WINDOWING_MODE_MULTI_WINDOW); TrackingTaskListener listener = new TrackingTaskListener(); mOrganizer.addListener(listener, WINDOWING_MODE_MULTI_WINDOW); mOrganizer.addListener(listener, TASK_LISTENER_TYPE_MULTI_WINDOW); mOrganizer.onTaskAppeared(taskInfo, null); assertTrue(listener.appeared.contains(taskInfo)); Loading @@ -130,7 +133,7 @@ public class ShellTaskOrganizerTests { mOrganizer.onTaskAppeared(taskInfo, null); TrackingTaskListener listener = new TrackingTaskListener(); mOrganizer.addListener(listener, WINDOWING_MODE_MULTI_WINDOW); mOrganizer.addListener(listener, TASK_LISTENER_TYPE_MULTI_WINDOW); assertTrue(listener.appeared.contains(taskInfo)); } Loading @@ -139,8 +142,8 @@ public class ShellTaskOrganizerTests { RunningTaskInfo taskInfo = createTaskInfo(WINDOWING_MODE_MULTI_WINDOW); TrackingTaskListener mwListener = new TrackingTaskListener(); TrackingTaskListener pipListener = new TrackingTaskListener(); mOrganizer.addListener(mwListener, WINDOWING_MODE_MULTI_WINDOW); mOrganizer.addListener(pipListener, WINDOWING_MODE_PINNED); mOrganizer.addListener(mwListener, TASK_LISTENER_TYPE_MULTI_WINDOW); mOrganizer.addListener(pipListener, TASK_LISTENER_TYPE_PIP); mOrganizer.onTaskAppeared(taskInfo, null); assertTrue(mwListener.appeared.contains(taskInfo)); assertTrue(pipListener.appeared.isEmpty()); Loading Loading
libs/WindowManager/Shell/res/raw/wm_shell_protolog.json +6 −6 Original line number Diff line number Diff line { "version": "1.0.0", "messages": { "-1823823103": { "message": "Add listener for types=%s listener=%s", "level": "VERBOSE", "group": "WM_SHELL_TASK_ORG", "at": "com\/android\/wm\/shell\/ShellTaskOrganizer.java" }, "-1534364071": { "message": "onTransitionReady %s: %s", "level": "VERBOSE", Loading Loading @@ -37,12 +43,6 @@ "group": "WM_SHELL_TASK_ORG", "at": "com\/android\/wm\/shell\/ShellTaskOrganizer.java" }, "-242812822": { "message": "Add listener for modes=%s listener=%s", "level": "VERBOSE", "group": "WM_SHELL_TASK_ORG", "at": "com\/android\/wm\/shell\/ShellTaskOrganizer.java" }, "-191422040": { "message": "Transition animations finished, notifying core %s", "level": "VERBOSE", Loading
libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java +75 −28 Original line number Diff line number Diff line Loading @@ -16,9 +16,17 @@ package com.android.wm.shell; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import android.annotation.IntDef; import android.app.ActivityManager.RunningTaskInfo; import android.app.WindowConfiguration.WindowingMode; import android.util.Log; import android.util.Pair; import android.util.SparseArray; Loading @@ -33,7 +41,6 @@ import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.TransactionPool; import com.android.wm.shell.protolog.ShellProtoLogGroup; import java.util.ArrayList; import java.util.Arrays; /** Loading @@ -42,6 +49,23 @@ import java.util.Arrays; */ public class ShellTaskOrganizer extends TaskOrganizer { // Intentionally using negative numbers here so the positive numbers can be used // for task id specific listeners that will be added later. public static final int TASK_LISTENER_TYPE_UNDEFINED = -1; public static final int TASK_LISTENER_TYPE_FULLSCREEN = -2; public static final int TASK_LISTENER_TYPE_MULTI_WINDOW = -3; public static final int TASK_LISTENER_TYPE_PIP = -4; public static final int TASK_LISTENER_TYPE_SPLIT_SCREEN = -5; @IntDef(prefix = {"TASK_LISTENER_TYPE_"}, value = { TASK_LISTENER_TYPE_UNDEFINED, TASK_LISTENER_TYPE_FULLSCREEN, TASK_LISTENER_TYPE_MULTI_WINDOW, TASK_LISTENER_TYPE_PIP, TASK_LISTENER_TYPE_SPLIT_SCREEN, }) public @interface TaskListenerType {} private static final String TAG = "ShellTaskOrganizer"; /** Loading @@ -54,7 +78,7 @@ public class ShellTaskOrganizer extends TaskOrganizer { default void onBackPressedOnTaskRoot(RunningTaskInfo taskInfo) {} } private final SparseArray<TaskListener> mListenerByWindowingMode = new SparseArray<>(); private final SparseArray<TaskListener> mTaskListenersByType = new SparseArray<>(); // Keeps track of all the tasks reported to this organizer (changes in windowing mode will // require us to report to both old and new listeners) Loading @@ -73,29 +97,29 @@ public class ShellTaskOrganizer extends TaskOrganizer { SyncTransactionQueue syncQueue, TransactionPool transactionPool, ShellExecutor mainExecutor, ShellExecutor animExecutor) { super(taskOrganizerController); addListener(new FullscreenTaskListener(syncQueue), WINDOWING_MODE_FULLSCREEN); addListener(new FullscreenTaskListener(syncQueue), TASK_LISTENER_TYPE_FULLSCREEN); mTransitions = new Transitions(this, transactionPool, mainExecutor, animExecutor); if (Transitions.ENABLE_SHELL_TRANSITIONS) registerTransitionPlayer(mTransitions); } /** * Adds a listener for tasks in a specific windowing mode. * Adds a listener for tasks with given types. */ public void addListener(TaskListener listener, int... windowingModes) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Add listener for modes=%s listener=%s", Arrays.toString(windowingModes), listener); for (int winMode : windowingModes) { if (mListenerByWindowingMode.get(winMode) != null) { throw new IllegalArgumentException("Listener for winMode=" + winMode public void addListener(TaskListener listener, @TaskListenerType int... taskListenerTypes) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Add listener for types=%s listener=%s", Arrays.toString(taskListenerTypes), listener); for (int listenerType : taskListenerTypes) { if (mTaskListenersByType.get(listenerType) != null) { throw new IllegalArgumentException("Listener for listenerType=" + listenerType + " already exists"); } mListenerByWindowingMode.put(winMode, listener); mTaskListenersByType.put(listenerType, listener); // Notify the listener of all existing tasks in that windowing mode // Notify the listener of all existing tasks with the given type. for (int i = mTasks.size() - 1; i >= 0; i--) { Pair<RunningTaskInfo, SurfaceControl> data = mTasks.valueAt(i); int taskWinMode = data.first.configuration.windowConfiguration.getWindowingMode(); if (taskWinMode == winMode) { final @TaskListenerType int taskListenerType = getTaskListenerType(data.first); if (taskListenerType == listenerType) { listener.onTaskAppeared(data.first, data.second); } } Loading @@ -107,12 +131,12 @@ public class ShellTaskOrganizer extends TaskOrganizer { */ public void removeListener(TaskListener listener) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Remove listener=%s", listener); final int index = mListenerByWindowingMode.indexOfValue(listener); final int index = mTaskListenersByType.indexOfValue(listener); if (index == -1) { Log.w(TAG, "No registered listener found"); return; } mListenerByWindowingMode.removeAt(index); mTaskListenersByType.removeAt(index); } @Override Loading @@ -120,7 +144,7 @@ public class ShellTaskOrganizer extends TaskOrganizer { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Task appeared taskId=%d", taskInfo.taskId); mTasks.put(taskInfo.taskId, new Pair<>(taskInfo, leash)); final TaskListener listener = mListenerByWindowingMode.get(getWindowingMode(taskInfo)); final TaskListener listener = mTaskListenersByType.get(getTaskListenerType(taskInfo)); if (listener != null) { listener.onTaskAppeared(taskInfo, leash); } Loading @@ -131,23 +155,23 @@ public class ShellTaskOrganizer extends TaskOrganizer { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Task info changed taskId=%d", taskInfo.taskId); final Pair<RunningTaskInfo, SurfaceControl> data = mTasks.get(taskInfo.taskId); final int winMode = getWindowingMode(taskInfo); final int prevWinMode = getWindowingMode(data.first); final @TaskListenerType int listenerType = getTaskListenerType(taskInfo); final @TaskListenerType int prevListenerType = getTaskListenerType(data.first); mTasks.put(taskInfo.taskId, new Pair<>(taskInfo, data.second)); if (prevWinMode != -1 && prevWinMode != winMode) { // TODO: We currently send vanished/appeared as the task moves between win modes, but if (prevListenerType != listenerType) { // TODO: We currently send vanished/appeared as the task moves between types, but // we should consider adding a different mode-changed callback TaskListener listener = mListenerByWindowingMode.get(prevWinMode); TaskListener listener = mTaskListenersByType.get(prevListenerType); if (listener != null) { listener.onTaskVanished(taskInfo); } listener = mListenerByWindowingMode.get(winMode); listener = mTaskListenersByType.get(listenerType); if (listener != null) { SurfaceControl leash = data.second; listener.onTaskAppeared(taskInfo, leash); } } else { final TaskListener listener = mListenerByWindowingMode.get(winMode); final TaskListener listener = mTaskListenersByType.get(listenerType); if (listener != null) { listener.onTaskInfoChanged(taskInfo); } Loading @@ -158,7 +182,7 @@ public class ShellTaskOrganizer extends TaskOrganizer { public void onBackPressedOnTaskRoot(RunningTaskInfo taskInfo) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Task root back pressed taskId=%d", taskInfo.taskId); final TaskListener listener = mListenerByWindowingMode.get(getWindowingMode(taskInfo)); final TaskListener listener = mTaskListenersByType.get(getTaskListenerType(taskInfo)); if (listener != null) { listener.onBackPressedOnTaskRoot(taskInfo); } Loading @@ -168,15 +192,38 @@ public class ShellTaskOrganizer extends TaskOrganizer { public void onTaskVanished(RunningTaskInfo taskInfo) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Task vanished taskId=%d", taskInfo.taskId); final int prevWinMode = getWindowingMode(mTasks.get(taskInfo.taskId).first); final @TaskListenerType int prevListenerType = getTaskListenerType(mTasks.get(taskInfo.taskId).first); mTasks.remove(taskInfo.taskId); final TaskListener listener = mListenerByWindowingMode.get(prevWinMode); final TaskListener listener = mTaskListenersByType.get(prevListenerType); if (listener != null) { listener.onTaskVanished(taskInfo); } } private int getWindowingMode(RunningTaskInfo taskInfo) { @TaskListenerType private static int getTaskListenerType(RunningTaskInfo runningTaskInfo) { // Right now it's N:1 mapping but in the future different task listerners // may be triggered by one windowing mode depending on task parameters. switch (getWindowingMode(runningTaskInfo)) { case WINDOWING_MODE_FULLSCREEN: return TASK_LISTENER_TYPE_FULLSCREEN; case WINDOWING_MODE_MULTI_WINDOW: return TASK_LISTENER_TYPE_MULTI_WINDOW; case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY: case WINDOWING_MODE_SPLIT_SCREEN_SECONDARY: return TASK_LISTENER_TYPE_SPLIT_SCREEN; case WINDOWING_MODE_PINNED: return TASK_LISTENER_TYPE_PIP; case WINDOWING_MODE_FREEFORM: case WINDOWING_MODE_UNDEFINED: default: return TASK_LISTENER_TYPE_UNDEFINED; } } @WindowingMode private static int getWindowingMode(RunningTaskInfo taskInfo) { return taskInfo.configuration.windowConfiguration.getWindowingMode(); } }
libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java +2 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_PIP; import static com.android.wm.shell.pip.PipAnimationController.ANIM_TYPE_ALPHA; import static com.android.wm.shell.pip.PipAnimationController.ANIM_TYPE_BOUNDS; import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTION_LEAVE_PIP; Loading Loading @@ -282,7 +283,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, if (!PipUtils.hasSystemFeature(context)) { Log.w(TAG, "Device not support PIP feature"); } else { mTaskOrganizer.addListener(this, WINDOWING_MODE_PINNED); mTaskOrganizer.addListener(this, TASK_LISTENER_TYPE_PIP); displayController.addDisplayWindowListener(this); } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTaskOrganizer.java +5 −5 Original line number Diff line number Diff line Loading @@ -23,8 +23,9 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMAR import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.view.Display.DEFAULT_DISPLAY; import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_SPLIT_SCREEN; import android.app.ActivityManager.RunningTaskInfo; import android.app.WindowConfiguration; import android.graphics.Rect; import android.os.RemoteException; import android.util.Log; Loading Loading @@ -56,17 +57,16 @@ class SplitScreenTaskOrganizer implements ShellTaskOrganizer.TaskListener { ShellTaskOrganizer shellTaskOrganizer) { mSplitScreenController = splitScreenController; mTaskOrganizer = shellTaskOrganizer; mTaskOrganizer.addListener(this, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY); mTaskOrganizer.addListener(this, TASK_LISTENER_TYPE_SPLIT_SCREEN); } void init() throws RemoteException { synchronized (this) { try { mPrimary = mTaskOrganizer.createRootTask(Display.DEFAULT_DISPLAY, WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); mSecondary = mTaskOrganizer.createRootTask(Display.DEFAULT_DISPLAY, WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY); WINDOWING_MODE_SPLIT_SCREEN_SECONDARY); } catch (Exception e) { // teardown to prevent callbacks mTaskOrganizer.removeListener(this); Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java +10 −7 Original line number Diff line number Diff line Loading @@ -19,6 +19,9 @@ package com.android.wm.shell; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_MULTI_WINDOW; import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_PIP; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; Loading Loading @@ -102,10 +105,10 @@ public class ShellTaskOrganizerTests { } @Test public void testOneListenerPerMode() { mOrganizer.addListener(new TrackingTaskListener(), WINDOWING_MODE_MULTI_WINDOW); public void testOneListenerPerType() { mOrganizer.addListener(new TrackingTaskListener(), TASK_LISTENER_TYPE_MULTI_WINDOW); try { mOrganizer.addListener(new TrackingTaskListener(), WINDOWING_MODE_MULTI_WINDOW); mOrganizer.addListener(new TrackingTaskListener(), TASK_LISTENER_TYPE_MULTI_WINDOW); fail("Expected exception due to already registered listener"); } catch (Exception e) { // Expected failure Loading @@ -116,7 +119,7 @@ public class ShellTaskOrganizerTests { public void testAppearedVanished() { RunningTaskInfo taskInfo = createTaskInfo(WINDOWING_MODE_MULTI_WINDOW); TrackingTaskListener listener = new TrackingTaskListener(); mOrganizer.addListener(listener, WINDOWING_MODE_MULTI_WINDOW); mOrganizer.addListener(listener, TASK_LISTENER_TYPE_MULTI_WINDOW); mOrganizer.onTaskAppeared(taskInfo, null); assertTrue(listener.appeared.contains(taskInfo)); Loading @@ -130,7 +133,7 @@ public class ShellTaskOrganizerTests { mOrganizer.onTaskAppeared(taskInfo, null); TrackingTaskListener listener = new TrackingTaskListener(); mOrganizer.addListener(listener, WINDOWING_MODE_MULTI_WINDOW); mOrganizer.addListener(listener, TASK_LISTENER_TYPE_MULTI_WINDOW); assertTrue(listener.appeared.contains(taskInfo)); } Loading @@ -139,8 +142,8 @@ public class ShellTaskOrganizerTests { RunningTaskInfo taskInfo = createTaskInfo(WINDOWING_MODE_MULTI_WINDOW); TrackingTaskListener mwListener = new TrackingTaskListener(); TrackingTaskListener pipListener = new TrackingTaskListener(); mOrganizer.addListener(mwListener, WINDOWING_MODE_MULTI_WINDOW); mOrganizer.addListener(pipListener, WINDOWING_MODE_PINNED); mOrganizer.addListener(mwListener, TASK_LISTENER_TYPE_MULTI_WINDOW); mOrganizer.addListener(pipListener, TASK_LISTENER_TYPE_PIP); mOrganizer.onTaskAppeared(taskInfo, null); assertTrue(mwListener.appeared.contains(taskInfo)); assertTrue(pipListener.appeared.isEmpty()); Loading