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

Commit 4ab05d06 authored by Xiang Wang's avatar Xiang Wang
Browse files

Add updateCustomGameModeConfiguration system API

Bug: b/243448953
Test: atest GameManagerTests GameManagerServiceTests
Change-Id: I0317cf08e146fa7da623ada670223dc63106b266
parent 1418f411
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -811,6 +811,7 @@ package android.app {
  public final class GameManager {
    method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_GAME_MODE) public android.app.GameModeInfo getGameModeInfo(@NonNull String);
    method @RequiresPermission(android.Manifest.permission.MANAGE_GAME_MODE) public void setGameMode(@NonNull String, int);
    method @RequiresPermission(android.Manifest.permission.MANAGE_GAME_MODE) public void updateCustomGameModeConfiguration(@NonNull String, @NonNull android.app.GameModeConfiguration);
  }
  public final class GameModeConfiguration implements android.os.Parcelable {
+21 −0
Original line number Diff line number Diff line
@@ -279,4 +279,25 @@ public final class GameManager {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Updates the config for the game's {@link #GAME_MODE_CUSTOM} mode.
     * <p>
     * The caller must have {@link android.Manifest.permission#MANAGE_GAME_MODE}.
     *
     * @param gameModeConfig The configuration to use for game mode interventions
     * @hide
     */
    @SystemApi
    @UserHandleAware
    @RequiresPermission(Manifest.permission.MANAGE_GAME_MODE)
    public void updateCustomGameModeConfiguration(@NonNull String packageName,
            @NonNull GameModeConfiguration gameModeConfig) {
        try {
            mService.updateCustomGameModeConfiguration(packageName, gameModeConfig,
                    mContext.getUserId());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
}
+2 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.app;

import android.app.GameModeConfiguration;
import android.app.GameModeInfo;
import android.app.GameState;

@@ -33,4 +34,5 @@ interface IGameManagerService {
    void setGameServiceProvider(String packageName);
    void updateResolutionScalingFactor(String packageName, int gameMode, float scalingFactor, int userId);
    float getResolutionScalingFactor(String packageName, int gameMode, int userId);
    void updateCustomGameModeConfiguration(String packageName, in GameModeConfiguration gameModeConfig, int userId);
}
+28 −0
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package android.app;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;

import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertNull;

import android.content.Context;
import android.platform.test.annotations.Presubmit;
@@ -86,4 +88,30 @@ public final class GameManagerTests {
        assertEquals(GameManager.GAME_MODE_CUSTOM,
                mGameManager.getGameMode(mPackageName));
    }

    @Test
    public void testUpdateCustomGameModeConfiguration() {
        GameModeInfo gameModeInfo = mGameManager.getGameModeInfo(mPackageName);
        assertNotNull(gameModeInfo);
        assertNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_CUSTOM));
        GameModeConfiguration unsupportedFpsConfig =
                new GameModeConfiguration.Builder().setFpsOverride(
                        70).setScalingFactor(0.5f).build();
        mGameManager.updateCustomGameModeConfiguration(mPackageName, unsupportedFpsConfig);
        gameModeInfo = mGameManager.getGameModeInfo(mPackageName);
        assertNotNull(gameModeInfo);
        // TODO(b/243448953): update to non-zero FPS when matching is implemented
        assertEquals(new GameModeConfiguration.Builder().setFpsOverride(
                        GameModeConfiguration.FPS_OVERRIDE_NONE).setScalingFactor(0.5f).build(),
                gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_CUSTOM));

        GameModeConfiguration supportedFpsConfig =
                new GameModeConfiguration.Builder().setFpsOverride(
                        60).setScalingFactor(0.5f).build();
        mGameManager.updateCustomGameModeConfiguration(mPackageName, supportedFpsConfig);
        gameModeInfo = mGameManager.getGameModeInfo(mPackageName);
        assertNotNull(gameModeInfo);
        assertEquals(supportedFpsConfig,
                gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_CUSTOM));
    }
}
+75 −3
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import android.app.ActivityManager;
import android.app.GameManager;
import android.app.GameManager.GameMode;
import android.app.GameManagerInternal;
import android.app.GameModeConfiguration;
import android.app.GameModeInfo;
import android.app.GameState;
import android.app.IGameManagerService;
@@ -399,6 +400,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
    // Turn the raw string to the corresponding fps int.
    // Return 0 when disabling, -1 for invalid fps.
    static int getFpsInt(String raw) {
        // TODO(b/243448953): make sure this translates to proper values based on current display
        switch (raw) {
            case "30":
                return FrameRate.FPS_30.fps;
@@ -695,6 +697,22 @@ public final class GameManagerService extends IGameManagerService.Stub {
                        && !willGamePerformOptimizations(mGameMode);
            }

            android.app.GameModeConfiguration toPublicGameModeConfig() {
                int fpsOverride = getFpsInt(mFps);
                // TODO(b/243448953): match to proper value in case of display change?
                fpsOverride = fpsOverride > 0 ? fpsOverride
                        : android.app.GameModeConfiguration.FPS_OVERRIDE_NONE;
                final float scaling = mScaling == DEFAULT_SCALING ? 1.0f : mScaling;
                return new android.app.GameModeConfiguration.Builder()
                        .setScalingFactor(scaling)
                        .setFpsOverride(fpsOverride).build();
            }

            void updateFromPublicGameModeConfig(android.app.GameModeConfiguration config) {
                mScaling = config.getScalingFactor();
                mFps = String.valueOf(config.getFpsOverride());
            }

            /**
             * @hide
             */
@@ -1041,13 +1059,23 @@ public final class GameManagerService extends IGameManagerService.Stub {
        if (config != null) {
            final @GameMode int[] optedInGameModes = config.getOptedInGameModes();
            final @GameMode int[] availableGameModes = config.getAvailableGameModes();
            return new GameModeInfo.Builder()
            GameModeInfo.Builder gameModeInfoBuilder = new GameModeInfo.Builder()
                    .setActiveGameMode(activeGameMode)
                    .setAvailableGameModes(availableGameModes)
                    .setOptedInGameModes(optedInGameModes)
                    .setDownscalingAllowed(config.mAllowDownscale)
                    .setFpsOverrideAllowed(config.mAllowFpsOverride)
                    .build();
                    .setFpsOverrideAllowed(config.mAllowFpsOverride);
            for (int gameMode : availableGameModes) {
                if (!config.willGamePerformOptimizations(gameMode)) {
                    GamePackageConfiguration.GameModeConfiguration gameModeConfig =
                            config.getGameModeConfiguration(gameMode);
                    if (gameModeConfig != null) {
                        gameModeInfoBuilder.setGameModeConfiguration(gameMode,
                                gameModeConfig.toPublicGameModeConfig());
                    }
                }
            }
            return gameModeInfoBuilder.build();
        } else {
            return new GameModeInfo.Builder().setActiveGameMode(activeGameMode).build();
        }
@@ -1262,6 +1290,50 @@ public final class GameManagerService extends IGameManagerService.Stub {
        return GamePackageConfiguration.GameModeConfiguration.DEFAULT_SCALING;
    }

    /**
     * Updates the config for the game's {@link GameManager#GAME_MODE_CUSTOM} mode.
     *
     * @throws SecurityException        if caller doesn't have
     *                                  {@link android.Manifest.permission#MANAGE_GAME_MODE}
     *                                  permission.
     * @throws IllegalArgumentException if the user ID provided doesn't exist.
     */
    @Override
    @RequiresPermission(Manifest.permission.MANAGE_GAME_MODE)
    public void updateCustomGameModeConfiguration(String packageName,
            GameModeConfiguration gameModeConfig, int userId)
            throws SecurityException, IllegalArgumentException {
        checkPermission(Manifest.permission.MANAGE_GAME_MODE);
        synchronized (mLock) {
            if (!mSettings.containsKey(userId)) {
                throw new IllegalArgumentException("User " + userId + " wasn't started");
            }
        }
        // TODO(b/243448953): add validation on gameModeConfig provided
        // Adding game mode config override of the given package name
        GamePackageConfiguration configOverride;
        synchronized (mLock) {
            if (!mSettings.containsKey(userId)) {
                return;
            }
            final GameManagerSettings settings = mSettings.get(userId);
            // look for the existing GamePackageConfiguration override
            configOverride = settings.getConfigOverride(packageName);
            if (configOverride == null) {
                configOverride = new GamePackageConfiguration(packageName);
                settings.setConfigOverride(packageName, configOverride);
            }

        }
        GamePackageConfiguration.GameModeConfiguration internalConfig =
                configOverride.getOrAddDefaultGameModeConfiguration(GameManager.GAME_MODE_CUSTOM);
        internalConfig.updateFromPublicGameModeConfig(gameModeConfig);

        Slog.i(TAG, "Updated custom game mode config for package: " + packageName
                + " with FPS=" + internalConfig.getFps() + ";Scaling="
                + internalConfig.getScaling());
    }

    /**
     * Notified when boot is completed.
     */
Loading