diff options
| author | 2021-05-21 22:18:37 +0000 | |
|---|---|---|
| committer | 2021-05-27 20:12:08 +0000 | |
| commit | 4e8a1a05b1b9ed35357aa0555722bb24afd07dcb (patch) | |
| tree | af618a2edf6104e2b44e72e578ec080b42536d50 | |
| parent | 19c430b187696b1858a7f5d4a62573f6f31e3814 (diff) | |
Add TaskSurfaceHelper/Controller in WMShell to plumb game mode to SF
TaskSurfaceHelper(Controller) will be used as an interface to communicate
with the SurfaceControl of the underlying Task. This change adds a function
to set the game mode metadata for the task layer.
Bug: 186025682
Test: atest TaskSurfaceControllerTest
Change-Id: I136b65636b98e1883eaf9e4f4f0b34c61350d4e4
9 files changed, 195 insertions, 4 deletions
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 45c49352afff..f34cd8f9de50 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -34,7 +34,6 @@ import android.annotation.Size; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Bitmap; -import android.graphics.BLASTBufferQueue; import android.graphics.ColorSpace; import android.graphics.GraphicBuffer; import android.graphics.Matrix; @@ -647,6 +646,12 @@ public final class SurfaceControl implements Parcelable { public static final int METADATA_OWNER_PID = 6; /** + * game mode for the layer - used for metrics + * @hide + */ + public static final int METADATA_GAME_MODE = 8; + + /** * A wrapper around HardwareBuffer that contains extra information about how to * interpret the screenshot HardwareBuffer. * diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java index 94d13eab4299..a88be3198502 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java @@ -399,6 +399,19 @@ public class ShellTaskOrganizer extends TaskOrganizer { } } + /** Helper to set int metadata on the Surface corresponding to the task id. */ + public void setSurfaceMetadata(int taskId, int key, int value) { + synchronized (mLock) { + final TaskAppearedInfo info = mTasks.get(taskId); + if (info == null || info.getLeash() == null) { + return; + } + SurfaceControl.Transaction t = new SurfaceControl.Transaction(); + t.setMetadata(info.getLeash(), key, value); + t.apply(); + } + } + private boolean updateTaskListenerIfNeeded(RunningTaskInfo taskInfo, SurfaceControl leash, TaskListener oldListener, TaskListener newListener) { if (oldListener == newListener) return false; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/tasksurfacehelper/TaskSurfaceHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/tasksurfacehelper/TaskSurfaceHelper.java new file mode 100644 index 000000000000..fbbd09faee9b --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/tasksurfacehelper/TaskSurfaceHelper.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wm.shell.tasksurfacehelper; + +/** + * Interface to communicate with a Task's SurfaceControl. + */ +public interface TaskSurfaceHelper { + + /** Sets the METADATA_GAME_MODE for the layer corresponding to the task **/ + default void setGameModeForTask(int taskId, int gameMode) {} +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/tasksurfacehelper/TaskSurfaceHelperController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/tasksurfacehelper/TaskSurfaceHelperController.java new file mode 100644 index 000000000000..b459b9fcd0b2 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/tasksurfacehelper/TaskSurfaceHelperController.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wm.shell.tasksurfacehelper; + +import android.view.SurfaceControl; + +import com.android.wm.shell.ShellTaskOrganizer; +import com.android.wm.shell.common.ShellExecutor; + +/** + * Intermediary controller that communicates with {@link ShellTaskOrganizer} to send commands + * to SurfaceControl. + */ +public class TaskSurfaceHelperController { + + private final ShellTaskOrganizer mTaskOrganizer; + private final ShellExecutor mMainExecutor; + private final TaskSurfaceHelperImpl mImpl = new TaskSurfaceHelperImpl(); + + public TaskSurfaceHelperController(ShellTaskOrganizer taskOrganizer, + ShellExecutor mainExecutor) { + mTaskOrganizer = taskOrganizer; + mMainExecutor = mainExecutor; + } + + public TaskSurfaceHelper asTaskSurfaceHelper() { + return mImpl; + } + + /** + * Sends a Transaction to set the game mode metadata on the + * corresponding SurfaceControl + */ + public void setGameModeForTask(int taskId, int gameMode) { + mTaskOrganizer.setSurfaceMetadata(taskId, SurfaceControl.METADATA_GAME_MODE, gameMode); + } + + private class TaskSurfaceHelperImpl implements TaskSurfaceHelper { + @Override + public void setGameModeForTask(int taskId, int gameMode) { + mMainExecutor.execute(() -> { + TaskSurfaceHelperController.this.setGameModeForTask(taskId, gameMode); + }); + } + } +} diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/tasksurfacehelper/TaskSurfaceHelperControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/tasksurfacehelper/TaskSurfaceHelperControllerTest.java new file mode 100644 index 000000000000..d6142753b48a --- /dev/null +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/tasksurfacehelper/TaskSurfaceHelperControllerTest.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wm.shell.tasksurfacehelper; + +import static org.mockito.Mockito.verify; + +import android.platform.test.annotations.Presubmit; +import android.testing.AndroidTestingRunner; +import android.view.SurfaceControl; + +import androidx.test.filters.SmallTest; + +import com.android.wm.shell.ShellTaskOrganizer; +import com.android.wm.shell.common.ShellExecutor; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +@Presubmit +@RunWith(AndroidTestingRunner.class) +@SmallTest +public class TaskSurfaceHelperControllerTest { + private TaskSurfaceHelperController mTaskSurfaceHelperController; + @Mock + private ShellTaskOrganizer mMockTaskOrganizer; + @Mock + private ShellExecutor mMockShellExecutor; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + mTaskSurfaceHelperController = new TaskSurfaceHelperController( + mMockTaskOrganizer, mMockShellExecutor); + } + + @Test + public void testSetGameModeForTask() { + mTaskSurfaceHelperController.setGameModeForTask(/*taskId*/1, /*gameMode*/3); + verify(mMockTaskOrganizer).setSurfaceMetadata(1, SurfaceControl.METADATA_GAME_MODE, 3); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java index e6fe0600b9b8..a28223de2bf1 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java @@ -117,7 +117,8 @@ public class SystemUIFactory { .setAppPairs(mWMComponent.getAppPairs()) .setTaskViewFactory(mWMComponent.getTaskViewFactory()) .setTransitions(mWMComponent.getTransitions()) - .setStartingSurface(mWMComponent.getStartingSurface()); + .setStartingSurface(mWMComponent.getStartingSurface()) + .setTaskSurfaceHelper(mWMComponent.getTaskSurfaceHelper()); } else { // TODO: Call on prepareSysUIComponentBuilder but not with real components. Other option // is separating this logic into newly creating SystemUITestsFactory. @@ -132,8 +133,8 @@ public class SystemUIFactory { .setAppPairs(Optional.ofNullable(null)) .setTaskViewFactory(Optional.ofNullable(null)) .setTransitions(Transitions.createEmptyForTesting()) - .setStartingSurface(Optional.ofNullable(null)); - + .setStartingSurface(Optional.ofNullable(null)) + .setTaskSurfaceHelper(Optional.ofNullable(null)); } mSysUIComponent = builder.build(); if (mInitializeComponents) { diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java index c04201caa182..0fdc4d8e86a7 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java @@ -36,6 +36,7 @@ import com.android.wm.shell.onehanded.OneHanded; import com.android.wm.shell.pip.Pip; import com.android.wm.shell.splitscreen.SplitScreen; import com.android.wm.shell.startingsurface.StartingSurface; +import com.android.wm.shell.tasksurfacehelper.TaskSurfaceHelper; import com.android.wm.shell.transition.ShellTransitions; import java.util.Optional; @@ -94,6 +95,9 @@ public interface SysUIComponent { @BindsInstance Builder setStartingSurface(Optional<StartingSurface> s); + @BindsInstance + Builder setTaskSurfaceHelper(Optional<TaskSurfaceHelper> t); + SysUIComponent build(); } diff --git a/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java index bbd95b4d0c90..442d351729d7 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java @@ -33,6 +33,7 @@ import com.android.wm.shell.onehanded.OneHanded; import com.android.wm.shell.pip.Pip; import com.android.wm.shell.splitscreen.SplitScreen; import com.android.wm.shell.startingsurface.StartingSurface; +import com.android.wm.shell.tasksurfacehelper.TaskSurfaceHelper; import com.android.wm.shell.transition.ShellTransitions; import java.util.Optional; @@ -102,4 +103,7 @@ public interface WMComponent { @WMSingleton Optional<StartingSurface> getStartingSurface(); + + @WMSingleton + Optional<TaskSurfaceHelper> getTaskSurfaceHelper(); } diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java index 6c306743e4ce..6ef74505a681 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java @@ -73,6 +73,8 @@ import com.android.wm.shell.splitscreen.SplitScreenController; import com.android.wm.shell.startingsurface.StartingSurface; import com.android.wm.shell.startingsurface.StartingWindowController; import com.android.wm.shell.startingsurface.StartingWindowTypeAlgorithm; +import com.android.wm.shell.tasksurfacehelper.TaskSurfaceHelper; +import com.android.wm.shell.tasksurfacehelper.TaskSurfaceHelperController; import com.android.wm.shell.transition.ShellTransitions; import com.android.wm.shell.transition.Transitions; @@ -253,6 +255,24 @@ public abstract class WMShellBaseModule { } // + // Task to Surface communication + // + + @WMSingleton + @Provides + static Optional<TaskSurfaceHelper> provideTaskSurfaceHelper( + Optional<TaskSurfaceHelperController> taskSurfaceController) { + return taskSurfaceController.map((controller) -> controller.asTaskSurfaceHelper()); + } + + @WMSingleton + @Provides + static Optional<TaskSurfaceHelperController> provideTaskSurfaceHelperController( + ShellTaskOrganizer taskOrganizer, @ShellMainThread ShellExecutor mainExecutor) { + return Optional.ofNullable(new TaskSurfaceHelperController(taskOrganizer, mainExecutor)); + } + + // // Pip (optional feature) // |