Merge "Add TaskSurfaceHelper/Controller in WMShell to plumb game mode to SF" into sc-dev

This commit is contained in:
Adithya Srinivasan
2021-06-02 22:00:09 +00:00
committed by Android (Google) Code Review
9 changed files with 195 additions and 4 deletions

View File

@@ -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;
@@ -646,6 +645,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.

View File

@@ -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;

View File

@@ -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) {}
}

View File

@@ -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);
});
}
}
}

View File

@@ -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);
}
}

View File

@@ -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) {

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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;
@@ -252,6 +254,24 @@ public abstract class WMShellBaseModule {
mainHandler));
}
//
// 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)
//