Refactor task listeners mapping in ShellTaskOrganiser
Stop using windowing modes as keys for task listerners mapping to allow adding multiple listeners for one windowing mode. Fix: 170209272 Test: go/wm-smoke Change-Id: I31c20a00f8747a8510a5fab9e54efa63173aab6a
This commit is contained in:
@@ -1,6 +1,12 @@
|
||||
{
|
||||
"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",
|
||||
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
@@ -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";
|
||||
|
||||
/**
|
||||
@@ -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)
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
@@ -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
|
||||
@@ -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));
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
Reference in New Issue
Block a user