Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4e8a1a05 authored by Adithya Srinivasan's avatar Adithya Srinivasan
Browse files

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
parent 19c430b1
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -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.
+13 −0
Original line number Diff line number Diff line
@@ -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;
+26 −0
Original line number Diff line number Diff line
/*
 * 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) {}
}
+60 −0
Original line number Diff line number Diff line
/*
 * 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);
            });
        }
    }
}
+58 −0
Original line number Diff line number Diff line
/*
 * 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);
    }
}
Loading