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

Commit 018d4534 authored by Xiang Wang's avatar Xiang Wang
Browse files

Reset FPS when device config resets or app opts in to a game mode

Bug: b/253100682
Test: atest GameManagerServiceTests
Change-Id: If537a25e75be963ef5871a0383230d2ab13ff85a
parent 4f62571e
Loading
Loading
Loading
Loading
+17 −12
Original line number Diff line number Diff line
@@ -1336,7 +1336,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
        try {
            final float fps = 0.0f;
            final int uid = mPackageManager.getPackageUidAsUser(packageName, userId);
            nativeSetOverrideFrameRate(uid, fps);
            setOverrideFrameRate(uid, fps);
        } catch (PackageManager.NameNotFoundException e) {
            return;
        }
@@ -1368,7 +1368,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
        try {
            final float fps = modeConfig.getFps();
            final int uid = mPackageManager.getPackageUidAsUser(packageName, userId);
            nativeSetOverrideFrameRate(uid, fps);
            setOverrideFrameRate(uid, fps);
        } catch (PackageManager.NameNotFoundException e) {
            return;
        }
@@ -1377,18 +1377,18 @@ public final class GameManagerService extends IGameManagerService.Stub {

    private void updateInterventions(String packageName,
            @GameMode int gameMode, @UserIdInt int userId) {
        final GamePackageConfiguration packageConfig = getConfig(packageName, userId);
        if (gameMode == GameManager.GAME_MODE_STANDARD
                || gameMode == GameManager.GAME_MODE_UNSUPPORTED) {
                || gameMode == GameManager.GAME_MODE_UNSUPPORTED || packageConfig == null
                || packageConfig.willGamePerformOptimizations(gameMode)) {
            resetFps(packageName, userId);
            return;
        }
        final GamePackageConfiguration packageConfig = getConfig(packageName, userId);
            // resolution scaling does not need to be reset as it's now read dynamically on game
            // restart, see #getResolutionScalingFactor and CompatModePackages#getCompatScale.
            // TODO: reset Angle intervention here once implemented
            if (packageConfig == null) {
                Slog.v(TAG, "Package configuration not found for " + packageName);
                return;
            }
        if (packageConfig.willGamePerformOptimizations(gameMode)) {
            return;
        }
        updateFps(packageConfig, packageName, gameMode, userId);
        updateUseAngle(packageName, gameMode);
@@ -1809,6 +1809,11 @@ public final class GameManagerService extends IGameManagerService.Stub {
        return handlerThread;
    }

    @VisibleForTesting
    void setOverrideFrameRate(int uid, float frameRate) {
        nativeSetOverrideFrameRate(uid, frameRate);
    }

    /**
     * load dynamic library for frame rate overriding JNI calls
     */
+9 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="UTF-8"?>
<game-mode-config
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:supportsPerformanceGameMode="true"
    android:supportsBatteryGameMode="true"
    android:allowGameAngleDriver="true"
    android:allowGameDownscaling="true"
    android:allowGameFpsOverride="true"
/>
 No newline at end of file
+87 −0
Original line number Diff line number Diff line
@@ -73,7 +73,9 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentMatchers;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoSession;
import org.mockito.quality.Strictness;

@@ -93,6 +95,7 @@ public class GameManagerServiceTests {
    private static final String PACKAGE_NAME_INVALID = "com.android.app";
    private static final int USER_ID_1 = 1001;
    private static final int USER_ID_2 = 1002;
    private static final int DEFAULT_PACKAGE_UID = 12345;

    private MockitoSession mMockingSession;
    private String mPackageName;
@@ -207,6 +210,8 @@ public class GameManagerServiceTests {
                .thenReturn(packages);
        when(mMockPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
                .thenReturn(applicationInfo);
        when(mMockPackageManager.getPackageUidAsUser(mPackageName, USER_ID_1)).thenReturn(
                DEFAULT_PACKAGE_UID);
        LocalServices.addService(PowerManagerInternal.class, mMockPowerManager);
    }

@@ -387,6 +392,12 @@ public class GameManagerServiceTests {
                "res/xml/game_manager_service_metadata_config_interventions_enabled_no_opt_in.xml");
    }

    private void mockInterventionsEnabledAllOptInFromXml() throws Exception {
        seedGameManagerServiceMetaDataFromFile(mPackageName, 123,
                "res/xml/game_manager_service_metadata_config_interventions_enabled_all_opt_in"
                        + ".xml");
    }

    private void mockInterventionsDisabledNoOptInFromXml() throws Exception {
        seedGameManagerServiceMetaDataFromFile(mPackageName, 123,
                "res/xml/game_manager_service_metadata_config_interventions_disabled_no_opt_in"
@@ -1623,6 +1634,82 @@ public class GameManagerServiceTests {
        assertFalse(gameManagerService.mHandler.hasEqualMessages(WRITE_SETTINGS, USER_ID_1));
    }

    @Test
    public void testResetInterventions_onDeviceConfigReset() throws Exception {
        mockModifyGameModeGranted();
        String configStringBefore =
                "mode=2,downscaleFactor=1.0,fps=90";
        when(DeviceConfig.getProperty(anyString(), anyString()))
                .thenReturn(configStringBefore);
        mockInterventionsEnabledNoOptInFromXml();
        GameManagerService gameManagerService = Mockito.spy(new GameManagerService(mMockContext,
                mTestLooper.getLooper()));
        startUser(gameManagerService, USER_ID_1);
        gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE, USER_ID_1);
        Mockito.verify(gameManagerService).setOverrideFrameRate(
                ArgumentMatchers.eq(DEFAULT_PACKAGE_UID),
                ArgumentMatchers.eq(90.0f));
        checkFps(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 90);

        String configStringAfter = "";
        when(DeviceConfig.getProperty(anyString(), anyString()))
                .thenReturn(configStringAfter);
        gameManagerService.updateConfigsForUser(USER_ID_1, false, mPackageName);
        Mockito.verify(gameManagerService).setOverrideFrameRate(
                ArgumentMatchers.eq(DEFAULT_PACKAGE_UID),
                ArgumentMatchers.eq(0.0f));
    }

    @Test
    public void testResetInterventions_onInterventionsDisabled() throws Exception {
        mockModifyGameModeGranted();
        String configStringBefore =
                "mode=2,downscaleFactor=1.0,fps=90";
        when(DeviceConfig.getProperty(anyString(), anyString()))
                .thenReturn(configStringBefore);
        mockInterventionsEnabledNoOptInFromXml();
        GameManagerService gameManagerService = Mockito.spy(new GameManagerService(mMockContext,
                mTestLooper.getLooper()));
        startUser(gameManagerService, USER_ID_1);
        gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE, USER_ID_1);
        Mockito.verify(gameManagerService).setOverrideFrameRate(
                ArgumentMatchers.eq(DEFAULT_PACKAGE_UID),
                ArgumentMatchers.eq(90.0f));
        checkFps(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 90);

        mockInterventionsDisabledNoOptInFromXml();
        gameManagerService.updateConfigsForUser(USER_ID_1, false, mPackageName);
        Mockito.verify(gameManagerService).setOverrideFrameRate(
                ArgumentMatchers.eq(DEFAULT_PACKAGE_UID),
                ArgumentMatchers.eq(0.0f));
        checkFps(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 0);
    }

    @Test
    public void testResetInterventions_onGameModeOptedIn() throws Exception {
        mockModifyGameModeGranted();
        String configStringBefore =
                "mode=2,downscaleFactor=1.0,fps=90";
        when(DeviceConfig.getProperty(anyString(), anyString()))
                .thenReturn(configStringBefore);
        mockInterventionsEnabledNoOptInFromXml();
        GameManagerService gameManagerService = Mockito.spy(new GameManagerService(mMockContext,
                mTestLooper.getLooper()));
        startUser(gameManagerService, USER_ID_1);

        gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE, USER_ID_1);
        Mockito.verify(gameManagerService).setOverrideFrameRate(
                ArgumentMatchers.eq(DEFAULT_PACKAGE_UID),
                ArgumentMatchers.eq(90.0f));
        checkFps(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 90);

        mockInterventionsEnabledAllOptInFromXml();
        gameManagerService.updateConfigsForUser(USER_ID_1, false, mPackageName);
        Mockito.verify(gameManagerService).setOverrideFrameRate(
                ArgumentMatchers.eq(DEFAULT_PACKAGE_UID),
                ArgumentMatchers.eq(0.0f));
    }

    private static void deleteFolder(File folder) {
        File[] files = folder.listFiles();
        if (files != null) {