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

Commit 24a64eac authored by Xiang Wang's avatar Xiang Wang
Browse files

Guard the mode configs map in GamePackageConfiguration with lock

Synchronizes the getter and setter of GameModeConfiguration as the sub
fields can be read/write by different callers

Bug: b/240335717
Test: atest GameManagerServiceTests
Change-Id: Iac718a6a5d91e7aa3452b5cdb9aaee587f6f7773
parent 4262f949
Loading
Loading
Loading
Loading
+67 −93
Original line number Diff line number Diff line
@@ -554,7 +554,9 @@ public final class GameManagerService extends IGameManagerService.Stub {

        private static final String GAME_MODE_CONFIG_NODE_NAME = "game-mode-config";
        private final String mPackageName;
        private final ArrayMap<Integer, GameModeConfiguration> mModeConfigs;
        private final Object mModeConfigLock = new Object();
        @GuardedBy("mModeConfigLock")
        private final ArrayMap<Integer, GameModeConfiguration> mModeConfigs = new ArrayMap<>();
        private boolean mPerfModeOptedIn;
        private boolean mBatteryModeOptedIn;
        private boolean mAllowDownscale;
@@ -563,7 +565,6 @@ public final class GameManagerService extends IGameManagerService.Stub {

        GamePackageConfiguration(String packageName, int userId) {
            mPackageName = packageName;
            mModeConfigs = new ArrayMap<>();
            try {
                final ApplicationInfo ai = mPackageManager.getApplicationInfoAsUser(packageName,
                        PackageManager.GET_META_DATA, userId);
@@ -695,11 +696,11 @@ public final class GameManagerService extends IGameManagerService.Stub {
                return mGameMode;
            }

            public String getScaling() {
            public synchronized String getScaling() {
                return mScaling;
            }

            public int getFps() {
            public synchronized int getFps() {
                return GameManagerService.getFpsInt(mFps);
            }

@@ -711,11 +712,11 @@ public final class GameManagerService extends IGameManagerService.Stub {
                return mLoadingBoostDuration;
            }

            public void setScaling(String scaling) {
            public synchronized void setScaling(String scaling) {
                mScaling = scaling;
            }

            public void setFpsStr(String fpsStr) {
            public synchronized void setFpsStr(String fpsStr) {
                mFps = fpsStr;
            }

@@ -762,9 +763,11 @@ public final class GameManagerService extends IGameManagerService.Stub {

        private int getAvailableGameModesBitfield() {
            int field = 0;
            synchronized (mModeConfigLock) {
                for (final int mode : mModeConfigs.keySet()) {
                    field |= modeToBitmask(mode);
                }
            }
            if (mBatteryModeOptedIn) {
                field |= modeToBitmask(GameManager.GAME_MODE_BATTERY);
            }
@@ -804,15 +807,19 @@ public final class GameManagerService extends IGameManagerService.Stub {
         * @return The package's GameModeConfiguration for the provided mode or null if absent
         */
        public GameModeConfiguration getGameModeConfiguration(@GameMode int gameMode) {
            synchronized (mModeConfigLock) {
                return mModeConfigs.get(gameMode);
            }
        }

        /**
         * Insert a new GameModeConfiguration
         */
        public void addModeConfig(GameModeConfiguration config) {
            if (config.isActive()) {
                synchronized (mModeConfigLock) {
                    mModeConfigs.put(config.getGameMode(), config);
                }
            } else {
                Slog.w(TAG, "Attempt to add inactive game mode config for "
                        + mPackageName + ":" + config.toString());
@@ -820,13 +827,17 @@ public final class GameManagerService extends IGameManagerService.Stub {
        }

        public boolean isActive() {
            synchronized (mModeConfigLock) {
                return mModeConfigs.size() > 0 || mBatteryModeOptedIn || mPerfModeOptedIn;
            }
        }

        public String toString() {
            synchronized (mModeConfigLock) {
                return "[Name:" + mPackageName + " Modes: " + mModeConfigs.toString() + "]";
            }
        }
    }

    /**
     * SystemService lifecycle for GameService.
@@ -895,15 +906,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
    }

    private @GameMode int[] getAvailableGameModesUnchecked(String packageName) {
        GamePackageConfiguration config = null;
        synchronized (mOverrideConfigLock) {
            config = mOverrideConfigs.get(packageName);
        }
        if (config == null) {
            synchronized (mDeviceConfigLock) {
                config = mConfigs.get(packageName);
            }
        }
        final GamePackageConfiguration config = getConfig(packageName);
        if (config == null) {
            return new int[]{};
        }
@@ -1056,12 +1059,13 @@ public final class GameManagerService extends IGameManagerService.Stub {
        if (gameMode == GameManager.GAME_MODE_UNSUPPORTED) {
            return false;
        }

        final GamePackageConfiguration config;
        synchronized (mDeviceConfigLock) {
            final GamePackageConfiguration config = mConfigs.get(packageName);
            config = mConfigs.get(packageName);
            if (config == null) {
                return false;
            }
        }
        GamePackageConfiguration.GameModeConfiguration gameModeConfiguration =
                config.getGameModeConfiguration(gameMode);
        if (gameModeConfiguration == null) {
@@ -1069,7 +1073,6 @@ public final class GameManagerService extends IGameManagerService.Stub {
        }
        return gameModeConfiguration.getUseAngle();
    }
    }

    /**
     * If loading boost is applicable for the package for the currently enabled game mode, return
@@ -1083,9 +1086,10 @@ public final class GameManagerService extends IGameManagerService.Stub {
        if (gameMode == GameManager.GAME_MODE_UNSUPPORTED) {
            return -1;
        }

        final GamePackageConfiguration config;
        synchronized (mDeviceConfigLock) {
            final GamePackageConfiguration config = mConfigs.get(packageName);
            config = mConfigs.get(packageName);
        }
        if (config == null) {
            return -1;
        }
@@ -1096,7 +1100,6 @@ public final class GameManagerService extends IGameManagerService.Stub {
        }
        return gameModeConfiguration.getLoadingBoostDuration();
    }
    }

    /**
     * If loading boost is enabled, invoke it.
@@ -1365,18 +1368,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
            resetFps(packageName, userId);
            return;
        }
        GamePackageConfiguration packageConfig = null;

        synchronized (mOverrideConfigLock) {
            packageConfig = mOverrideConfigs.get(packageName);
        }

        if (packageConfig == null) {
            synchronized (mDeviceConfigLock) {
                packageConfig = mConfigs.get(packageName);
            }
        }

        final GamePackageConfiguration packageConfig = getConfig(packageName);
        if (packageConfig == null) {
            disableCompatScale(packageName);
            Slog.v(TAG, "Package configuration not found for " + packageName);
@@ -1405,14 +1397,15 @@ public final class GameManagerService extends IGameManagerService.Stub {
            }
        }
        // Adding override game mode configuration of the given package name
        GamePackageConfiguration overrideConfig;
        synchronized (mOverrideConfigLock) {
            // look for the existing override GamePackageConfiguration
            GamePackageConfiguration overrideConfig = mOverrideConfigs.get(packageName);
            overrideConfig = mOverrideConfigs.get(packageName);
            if (overrideConfig == null) {
                overrideConfig = new GamePackageConfiguration(packageName, userId);
                mOverrideConfigs.put(packageName, overrideConfig);
            }

        }
        // modify GameModeConfiguration intervention settings
        GamePackageConfiguration.GameModeConfiguration overrideModeConfig =
                overrideConfig.getGameModeConfiguration(gameMode);
@@ -1432,7 +1425,6 @@ public final class GameManagerService extends IGameManagerService.Stub {
        Slog.i(TAG, "Package Name: " + packageName
                + " FPS: " + String.valueOf(overrideModeConfig.getFps())
                + " Scaling: " + overrideModeConfig.getScaling());
        }
        setGameMode(packageName, gameMode, userId);
    }

@@ -1498,15 +1490,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
        // If not, set the game mode to standard
        int gameMode = getGameMode(packageName, userId);

        GamePackageConfiguration config = null;
        synchronized (mOverrideConfigLock) {
            config = mOverrideConfigs.get(packageName);
        }
        if (config == null) {
            synchronized (mDeviceConfigLock) {
                config = mConfigs.get(packageName);
            }
        }
        final GamePackageConfiguration config = getConfig(packageName);
        final int newGameMode = getNewGameMode(gameMode, config);
        if (gameMode != newGameMode) {
            setGameMode(packageName, GameManager.GAME_MODE_STANDARD, userId);
@@ -1545,18 +1529,8 @@ public final class GameManagerService extends IGameManagerService.Stub {
     * Returns the string listing all the interventions currently set to a game.
     */
    public String getInterventionList(String packageName) {
        GamePackageConfiguration packageConfig = null;
        synchronized (mOverrideConfigLock) {
            packageConfig = mOverrideConfigs.get(packageName);
        }

        if (packageConfig == null) {
            synchronized (mDeviceConfigLock) {
                packageConfig = mConfigs.get(packageName);
            }
        }

        StringBuilder listStrSb = new StringBuilder();
        final GamePackageConfiguration packageConfig = getConfig(packageName);
        final StringBuilder listStrSb = new StringBuilder();
        if (packageConfig == null) {
            listStrSb.append("\n No intervention found for package ")
                    .append(packageName);