diff --git a/services/core/java/com/android/server/app/GameManagerService.java b/services/core/java/com/android/server/app/GameManagerService.java index a8d209c6ab2bd..db44568eaf5f9 100644 --- a/services/core/java/com/android/server/app/GameManagerService.java +++ b/services/core/java/com/android/server/app/GameManagerService.java @@ -259,7 +259,6 @@ public final class GameManagerService extends IGameManagerService.Stub { } break; } - Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); synchronized (mLock) { removeMessages(WRITE_SETTINGS, msg.obj); @@ -443,8 +442,7 @@ public final class GameManagerService extends IGameManagerService.Stub { /** * GamePackageConfiguration manages all game mode config details for its associated package. */ - @VisibleForTesting - public class GamePackageConfiguration { + public static class GamePackageConfiguration { public static final String TAG = "GameManagerService_GamePackageConfiguration"; /** @@ -496,12 +494,16 @@ public final class GameManagerService extends IGameManagerService.Stub { private boolean mAllowAngle; private boolean mAllowFpsOverride; - GamePackageConfiguration(String packageName, int userId) { + GamePackageConfiguration(String packageName) { + mPackageName = packageName; + } + + GamePackageConfiguration(PackageManager packageManager, String packageName, int userId) { mPackageName = packageName; try { - final ApplicationInfo ai = mPackageManager.getApplicationInfoAsUser(packageName, + final ApplicationInfo ai = packageManager.getApplicationInfoAsUser(packageName, PackageManager.GET_META_DATA, userId); - if (!parseInterventionFromXml(ai, packageName)) { + if (!parseInterventionFromXml(packageManager, ai, packageName)) { if (ai.metaData != null) { mPerfModeOptedIn = ai.metaData.getBoolean(METADATA_PERFORMANCE_MODE_ENABLE); mBatteryModeOptedIn = ai.metaData.getBoolean(METADATA_BATTERY_MODE_ENABLE); @@ -535,16 +537,17 @@ public final class GameManagerService extends IGameManagerService.Stub { } } - private boolean parseInterventionFromXml(ApplicationInfo ai, String packageName) { + private boolean parseInterventionFromXml(PackageManager packageManager, ApplicationInfo ai, + String packageName) { boolean xmlFound = false; - try (XmlResourceParser parser = ai.loadXmlMetaData(mPackageManager, + try (XmlResourceParser parser = ai.loadXmlMetaData(packageManager, METADATA_GAME_MODE_CONFIG)) { if (parser == null) { Slog.v(TAG, "No " + METADATA_GAME_MODE_CONFIG + " meta-data found for package " + mPackageName); } else { xmlFound = true; - final Resources resources = mPackageManager.getResourcesForApplication( + final Resources resources = packageManager.getResourcesForApplication( packageName); final AttributeSet attributeSet = Xml.asAttributeSet(parser); int type; @@ -593,7 +596,6 @@ public final class GameManagerService extends IGameManagerService.Stub { * GameModeConfiguration contains all the values for all the interventions associated with * a game mode. */ - @VisibleForTesting public class GameModeConfiguration { public static final String TAG = "GameManagerService_GameModeConfiguration"; public static final String MODE_KEY = "mode"; @@ -610,8 +612,8 @@ public final class GameManagerService extends IGameManagerService.Stub { private final @GameMode int mGameMode; private float mScaling = DEFAULT_SCALING; private String mFps = DEFAULT_FPS; - private final boolean mUseAngle; - private final int mLoadingBoostDuration; + private boolean mUseAngle; + private int mLoadingBoostDuration; GameModeConfiguration(int gameMode) { mGameMode = gameMode; @@ -654,11 +656,15 @@ public final class GameManagerService extends IGameManagerService.Stub { return GameManagerService.getFpsInt(mFps); } - public boolean getUseAngle() { + synchronized String getFpsStr() { + return mFps; + } + + public synchronized boolean getUseAngle() { return mUseAngle; } - public int getLoadingBoostDuration() { + public synchronized int getLoadingBoostDuration() { return mLoadingBoostDuration; } @@ -670,6 +676,14 @@ public final class GameManagerService extends IGameManagerService.Stub { mFps = fpsStr; } + public synchronized void setUseAngle(boolean useAngle) { + mUseAngle = useAngle; + } + + public synchronized void setLoadingBoostDuration(int loadingBoostDuration) { + mLoadingBoostDuration = loadingBoostDuration; + } + public boolean isActive() { return (mGameMode == GameManager.GAME_MODE_STANDARD || mGameMode == GameManager.GAME_MODE_PERFORMANCE @@ -1042,7 +1056,6 @@ public final class GameManagerService extends IGameManagerService.Stub { * the boost duration. If no configuration is available for the selected package or mode, the * default is returned. */ - @VisibleForTesting public int getLoadingBoostDuration(String packageName, int userId) throws SecurityException { final int gameMode = getGameMode(packageName, userId); @@ -1274,7 +1287,7 @@ public final class GameManagerService extends IGameManagerService.Stub { } } - private int modeToBitmask(@GameMode int gameMode) { + private static int modeToBitmask(@GameMode int gameMode) { return (1 << gameMode); } @@ -1345,7 +1358,7 @@ public final class GameManagerService extends IGameManagerService.Stub { // look for the existing GamePackageConfiguration override configOverride = settings.getConfigOverride(packageName); if (configOverride == null) { - configOverride = new GamePackageConfiguration(packageName, userId); + configOverride = new GamePackageConfiguration(mPackageManager, packageName, userId); settings.setConfigOverride(packageName, configOverride); } } @@ -1487,7 +1500,7 @@ public final class GameManagerService extends IGameManagerService.Stub { synchronized (mDeviceConfigLock) { for (final String packageName : packageNames) { final GamePackageConfiguration config = - new GamePackageConfiguration(packageName, userId); + new GamePackageConfiguration(mPackageManager, packageName, userId); if (config.isActive()) { if (DEBUG) { Slog.i(TAG, "Adding config: " + config.toString()); @@ -1634,7 +1647,6 @@ public final class GameManagerService extends IGameManagerService.Stub { /** * @hide */ - @VisibleForTesting public GamePackageConfiguration getConfig(String packageName, int userId) { GamePackageConfiguration packageConfig = null; synchronized (mLock) { @@ -1688,6 +1700,18 @@ public final class GameManagerService extends IGameManagerService.Stub { if (mSettings.containsKey(userId)) { mSettings.get(userId).removeGame(packageName); } + Message msg = mHandler.obtainMessage(WRITE_SETTINGS); + msg.obj = userId; + if (!mHandler.hasEqualMessages(WRITE_SETTINGS, userId)) { + mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY); + } + msg = mHandler.obtainMessage( + WRITE_GAME_MODE_INTERVENTION_LIST_FILE); + msg.obj = userId; + if (!mHandler.hasEqualMessages( + WRITE_GAME_MODE_INTERVENTION_LIST_FILE, userId)) { + mHandler.sendMessage(msg); + } } } break; diff --git a/services/core/java/com/android/server/app/GameManagerSettings.java b/services/core/java/com/android/server/app/GameManagerSettings.java index 62ff03bdb1fb5..116249895dcd8 100644 --- a/services/core/java/com/android/server/app/GameManagerSettings.java +++ b/services/core/java/com/android/server/app/GameManagerSettings.java @@ -28,6 +28,7 @@ import android.util.Xml; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.XmlUtils; import com.android.server.app.GameManagerService.GamePackageConfiguration; +import com.android.server.app.GameManagerService.GamePackageConfiguration.GameModeConfiguration; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -40,10 +41,11 @@ import java.util.Map; /** * Persists all GameService related settings. + * * @hide */ public class GameManagerSettings { - + public static final String TAG = "GameManagerService_GameManagerSettings"; // The XML file follows the below format: // // @@ -54,8 +56,14 @@ public class GameManagerSettings { private static final String TAG_PACKAGE = "package"; private static final String TAG_PACKAGES = "packages"; + private static final String TAG_GAME_MODE_CONFIG = "gameModeConfig"; + private static final String ATTR_NAME = "name"; private static final String ATTR_GAME_MODE = "gameMode"; + private static final String ATTR_SCALING = "scaling"; + private static final String ATTR_FPS = "fps"; + private static final String ATTR_USE_ANGLE = "useAngle"; + private static final String ATTR_LOADING_BOOST_DURATION = "loadingBoost"; private final File mSystemDir; @VisibleForTesting @@ -143,9 +151,11 @@ public class GameManagerSettings { serializer.startTag(null, TAG_PACKAGES); for (Map.Entry entry : mGameModes.entrySet()) { + String packageName = entry.getKey(); serializer.startTag(null, TAG_PACKAGE); - serializer.attribute(null, ATTR_NAME, entry.getKey()); + serializer.attribute(null, ATTR_NAME, packageName); serializer.attributeInt(null, ATTR_GAME_MODE, entry.getValue()); + writeGameModeConfigTags(serializer, mConfigOverrides.get(packageName)); serializer.endTag(null, TAG_PACKAGE); } serializer.endTag(null, TAG_PACKAGES); @@ -161,11 +171,32 @@ public class GameManagerSettings { return; } catch (java.io.IOException e) { mSettingsFile.failWrite(fstr); - Slog.wtf(GameManagerService.TAG, "Unable to write game manager service settings, " + Slog.wtf(TAG, "Unable to write game manager service settings, " + "current changes will be lost at reboot", e); } } + private void writeGameModeConfigTags(TypedXmlSerializer serializer, + GamePackageConfiguration config) throws IOException { + if (config == null) { + return; + } + final int[] gameModes = config.getAvailableGameModes(); + for (final int mode : gameModes) { + final GameModeConfiguration modeConfig = config.getGameModeConfiguration(mode); + if (modeConfig != null) { + serializer.startTag(null, TAG_GAME_MODE_CONFIG); + serializer.attributeInt(null, ATTR_GAME_MODE, mode); + serializer.attributeBoolean(null, ATTR_USE_ANGLE, modeConfig.getUseAngle()); + serializer.attribute(null, ATTR_FPS, modeConfig.getFpsStr()); + serializer.attributeFloat(null, ATTR_SCALING, modeConfig.getScaling()); + serializer.attributeInt(null, ATTR_LOADING_BOOST_DURATION, + modeConfig.getLoadingBoostDuration()); + serializer.endTag(null, TAG_GAME_MODE_CONFIG); + } + } + } + /** * Reads game service settings from the disk. * This operation must be synced with an external lock. @@ -174,7 +205,7 @@ public class GameManagerSettings { mGameModes.clear(); if (!mSettingsFile.exists()) { - Slog.v(GameManagerService.TAG, "Settings file doesn't exists, skip reading"); + Slog.v(TAG, "Settings file doesn't exist, skip reading"); return false; } @@ -188,8 +219,7 @@ public class GameManagerSettings { // Do nothing } if (type != XmlPullParser.START_TAG) { - Slog.wtf(GameManagerService.TAG, - "No start tag found in package manager settings"); + Slog.wtf(TAG, "No start tag found in package manager settings"); return false; } @@ -201,35 +231,107 @@ public class GameManagerSettings { } String tagName = parser.getName(); - if (tagName.equals(TAG_PACKAGE)) { + if (type == XmlPullParser.START_TAG && TAG_PACKAGE.equals(tagName)) { readPackage(parser); } else { - Slog.w(GameManagerService.TAG, "Unknown element: " + parser.getName()); XmlUtils.skipCurrentTag(parser); + Slog.w(TAG, "Unknown element under packages tag: " + tagName + " with type: " + + type); } } } catch (XmlPullParserException | java.io.IOException e) { - Slog.wtf(GameManagerService.TAG, "Error reading package manager settings", e); + Slog.wtf(TAG, "Error reading package manager settings", e); return false; } - return true; } + // this must be called on tag of type START_TAG. private void readPackage(TypedXmlPullParser parser) throws XmlPullParserException, IOException { - String name = null; + final String name = parser.getAttributeValue(null, ATTR_NAME); + if (name == null) { + Slog.wtf(TAG, "No package name found in package tag"); + XmlUtils.skipCurrentTag(parser); + return; + } int gameMode = GameManager.GAME_MODE_UNSUPPORTED; try { - name = parser.getAttributeValue(null, ATTR_NAME); gameMode = parser.getAttributeInt(null, ATTR_GAME_MODE); } catch (XmlPullParserException e) { - Slog.wtf(GameManagerService.TAG, "Error reading game mode", e); + Slog.wtf(TAG, "Invalid game mode in package tag: " + + parser.getAttributeValue(null, ATTR_GAME_MODE), e); + return; } - if (name != null) { - mGameModes.put(name, gameMode); - } else { - XmlUtils.skipCurrentTag(parser); + mGameModes.put(name, gameMode); + final int packageTagDepth = parser.getDepth(); + int type; + final GamePackageConfiguration config = new GamePackageConfiguration(name); + while ((type = parser.next()) != XmlPullParser.END_DOCUMENT + && (type != XmlPullParser.END_TAG + || parser.getDepth() > packageTagDepth)) { + if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { + continue; + } + final String tagName = parser.getName(); + if (type == XmlPullParser.START_TAG && TAG_GAME_MODE_CONFIG.equals(tagName)) { + readGameModeConfig(parser, config); + } else { + XmlUtils.skipCurrentTag(parser); + Slog.w(TAG, "Unknown element under package tag: " + tagName + " with type: " + + type); + } + } + if (config.getAvailableGameModes().length > 1) { + mConfigOverrides.put(name, config); + } + } + + // this must be called on tag of type START_TAG. + private void readGameModeConfig(TypedXmlPullParser parser, GamePackageConfiguration config) { + final int gameMode; + try { + gameMode = parser.getAttributeInt(null, ATTR_GAME_MODE); + } catch (XmlPullParserException e) { + Slog.wtf(TAG, "Invalid game mode value in config tag: " + parser.getAttributeValue(null, + ATTR_GAME_MODE), e); + return; + } + + final GameModeConfiguration modeConfig = config.getOrAddDefaultGameModeConfiguration( + gameMode); + try { + final float scaling = parser.getAttributeFloat(null, ATTR_SCALING); + modeConfig.setScaling(scaling); + } catch (XmlPullParserException e) { + final String rawScaling = parser.getAttributeValue(null, ATTR_SCALING); + if (rawScaling != null) { + Slog.wtf(TAG, "Invalid scaling value in config tag: " + rawScaling, e); + } + } + + final String fps = parser.getAttributeValue(null, ATTR_FPS); + modeConfig.setFpsStr(fps != null ? fps : GameModeConfiguration.DEFAULT_FPS); + + try { + final boolean useAngle = parser.getAttributeBoolean(null, ATTR_USE_ANGLE); + modeConfig.setUseAngle(useAngle); + } catch (XmlPullParserException e) { + final String rawUseAngle = parser.getAttributeValue(null, ATTR_USE_ANGLE); + if (rawUseAngle != null) { + Slog.wtf(TAG, "Invalid useAngle value in config tag: " + rawUseAngle, e); + } + } + try { + final int loadingBoostDuration = parser.getAttributeInt(null, + ATTR_LOADING_BOOST_DURATION); + modeConfig.setLoadingBoostDuration(loadingBoostDuration); + } catch (XmlPullParserException e) { + final String rawLoadingBoost = parser.getAttributeValue(null, + ATTR_LOADING_BOOST_DURATION); + if (rawLoadingBoost != null) { + Slog.wtf(TAG, "Invalid loading boost in config tag: " + rawLoadingBoost, e); + } } } } diff --git a/services/tests/servicestests/src/com/android/server/app/GameManagerServiceSettingsTests.java b/services/tests/servicestests/src/com/android/server/app/GameManagerServiceSettingsTests.java index 5be05d8aa55a7..e8dd541b05313 100644 --- a/services/tests/servicestests/src/com/android/server/app/GameManagerServiceSettingsTests.java +++ b/services/tests/servicestests/src/com/android/server/app/GameManagerServiceSettingsTests.java @@ -16,9 +16,13 @@ package com.android.server.app; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import android.app.GameManager; import android.content.Context; import android.platform.test.annotations.Presubmit; import android.util.AtomicFile; @@ -28,6 +32,9 @@ import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; +import com.android.server.app.GameManagerService.GamePackageConfiguration; +import com.android.server.app.GameManagerService.GamePackageConfiguration.GameModeConfiguration; + import org.junit.After; import org.junit.Test; import org.junit.runner.RunWith; @@ -66,6 +73,9 @@ public class GameManagerServiceSettingsTests { + " \n" + " \n" + " \n" + + " \n" + + " \n" + " \n" + " \n" + " \n" @@ -92,40 +102,159 @@ public class GameManagerServiceSettingsTests { writeGameServiceXml(); } - private void verifyGameServiceSettingsData(GameManagerSettings settings) { - assertThat(settings.getGameModeLocked(PACKAGE_NAME_1), is(1)); - assertThat(settings.getGameModeLocked(PACKAGE_NAME_2), is(2)); - assertThat(settings.getGameModeLocked(PACKAGE_NAME_3), is(3)); - } - @After public void tearDown() throws Exception { deleteFolder(InstrumentationRegistry.getTargetContext().getFilesDir()); } - /** read in data and verify */ @Test public void testReadGameServiceSettings() { - /* write out files and read */ writeOldFiles(); final Context context = InstrumentationRegistry.getContext(); GameManagerSettings settings = new GameManagerSettings(context.getFilesDir()); - assertThat(settings.readPersistentDataLocked(), is(true)); - verifyGameServiceSettingsData(settings); + assertTrue(settings.readPersistentDataLocked()); + + // test game modes + assertEquals(1, settings.getGameModeLocked(PACKAGE_NAME_1)); + assertEquals(2, settings.getGameModeLocked(PACKAGE_NAME_2)); + assertEquals(3, settings.getGameModeLocked(PACKAGE_NAME_3)); + + // test game mode configs + assertNull(settings.getConfigOverride(PACKAGE_NAME_1)); + assertNull(settings.getConfigOverride(PACKAGE_NAME_3)); + final GamePackageConfiguration config = settings.getConfigOverride(PACKAGE_NAME_2); + assertNotNull(config); + + assertNull(config.getGameModeConfiguration(GameManager.GAME_MODE_STANDARD)); + final GameModeConfiguration performanceConfig = config.getGameModeConfiguration( + GameManager.GAME_MODE_PERFORMANCE); + assertNotNull(performanceConfig); + assertEquals(performanceConfig.getScaling(), 0.99, 0.01f); + assertEquals(performanceConfig.getLoadingBoostDuration(), 123); + assertEquals(performanceConfig.getFpsStr(), "90"); + assertTrue(performanceConfig.getUseAngle()); + final GameModeConfiguration batteryConfig = config.getGameModeConfiguration( + GameManager.GAME_MODE_BATTERY); + assertNotNull(batteryConfig); + assertEquals(batteryConfig.getScaling(), GameModeConfiguration.DEFAULT_SCALING, 0.01f); + assertEquals(batteryConfig.getLoadingBoostDuration(), + GameModeConfiguration.DEFAULT_LOADING_BOOST_DURATION); + assertEquals(batteryConfig.getFpsStr(), GameModeConfiguration.DEFAULT_FPS); + assertFalse(batteryConfig.getUseAngle()); } - /** read in data, write it out, and read it back in. Verify same. */ + @Test + public void testReadGameServiceSettings_invalidConfigAttributes() { + writeFile(new File(InstrumentationRegistry.getContext().getFilesDir(), + "system/game-manager-service.xml"), + ("" + + "\n" + + " \n" + + " \n" + + " \n" + + "\n").getBytes()); + final Context context = InstrumentationRegistry.getContext(); + GameManagerSettings settings = new GameManagerSettings(context.getFilesDir()); + assertTrue(settings.readPersistentDataLocked()); + + final GamePackageConfiguration config = settings.getConfigOverride(PACKAGE_NAME_1); + assertNotNull(config); + final GameModeConfiguration batteryConfig = config.getGameModeConfiguration( + GameManager.GAME_MODE_BATTERY); + assertNotNull(batteryConfig); + assertEquals(batteryConfig.getScaling(), GameModeConfiguration.DEFAULT_SCALING, 0.01f); + assertEquals(batteryConfig.getLoadingBoostDuration(), + GameModeConfiguration.DEFAULT_LOADING_BOOST_DURATION); + assertEquals(batteryConfig.getFpsStr(), "invalid"); + assertFalse(batteryConfig.getUseAngle()); + } + + @Test + public void testReadGameServiceSettings_invalidTags() { + writeFile(new File(InstrumentationRegistry.getContext().getFilesDir(), + "system/game-manager-service.xml"), + ("" + + "\n" + + " \n" + + " \n" + + " \n" + + " " + + " \n" + + " foo bar" + + " \n" + + " \n" + + " foo bar\n" + + " \n" + + " \n" + + "\n").getBytes()); + final Context context = InstrumentationRegistry.getContext(); + GameManagerSettings settings = new GameManagerSettings(context.getFilesDir()); + assertTrue(settings.readPersistentDataLocked()); + assertEquals(0, settings.getGameModeLocked(PACKAGE_NAME_1)); + assertEquals(2, settings.getGameModeLocked(PACKAGE_NAME_2)); + assertEquals(3, settings.getGameModeLocked(PACKAGE_NAME_3)); + + final GamePackageConfiguration config = settings.getConfigOverride(PACKAGE_NAME_2); + assertNotNull(config); + final GameModeConfiguration batteryConfig = config.getGameModeConfiguration( + GameManager.GAME_MODE_BATTERY); + assertNotNull(batteryConfig); + assertEquals(batteryConfig.getFpsStr(), "90"); + } + + @Test public void testWriteGameServiceSettings() { - // write out files and read - writeOldFiles(); final Context context = InstrumentationRegistry.getContext(); GameManagerSettings settings = new GameManagerSettings(context.getFilesDir()); - assertThat(settings.readPersistentDataLocked(), is(true)); - // write out, read back in and verify the same + // set package settings and write out to file + settings.setGameModeLocked(PACKAGE_NAME_1, GameManager.GAME_MODE_BATTERY); + settings.setGameModeLocked(PACKAGE_NAME_2, GameManager.GAME_MODE_PERFORMANCE); + settings.setGameModeLocked(PACKAGE_NAME_3, GameManager.GAME_MODE_STANDARD); + GamePackageConfiguration config = new GamePackageConfiguration(PACKAGE_NAME_2); + GameModeConfiguration performanceConfig = config.getOrAddDefaultGameModeConfiguration( + GameManager.GAME_MODE_PERFORMANCE); + performanceConfig.setLoadingBoostDuration(321); + performanceConfig.setScaling(0.66f); + performanceConfig.setUseAngle(true); + performanceConfig.setFpsStr("60"); + GameModeConfiguration batteryConfig = config.getOrAddDefaultGameModeConfiguration( + GameManager.GAME_MODE_BATTERY); + batteryConfig.setScaling(0.77f); + settings.setConfigOverride(PACKAGE_NAME_2, config); settings.writePersistentDataLocked(); - assertThat(settings.readPersistentDataLocked(), is(true)); - verifyGameServiceSettingsData(settings); + + // clear the settings in memory + settings.removeGame(PACKAGE_NAME_1); + settings.removeGame(PACKAGE_NAME_2); + settings.removeGame(PACKAGE_NAME_3); + + // read back in and verify + assertTrue(settings.readPersistentDataLocked()); + assertEquals(3, settings.getGameModeLocked(PACKAGE_NAME_1)); + assertEquals(2, settings.getGameModeLocked(PACKAGE_NAME_2)); + assertEquals(1, settings.getGameModeLocked(PACKAGE_NAME_3)); + + config = settings.getConfigOverride(PACKAGE_NAME_1); + assertNull(config); + config = settings.getConfigOverride(PACKAGE_NAME_2); + assertNotNull(config); + batteryConfig = config.getGameModeConfiguration(GameManager.GAME_MODE_BATTERY); + assertNotNull(batteryConfig); + assertEquals(batteryConfig.getScaling(), 0.77f, 0.01f); + assertEquals(batteryConfig.getLoadingBoostDuration(), + GameModeConfiguration.DEFAULT_LOADING_BOOST_DURATION); + assertEquals(batteryConfig.getFpsStr(), GameModeConfiguration.DEFAULT_FPS); + assertFalse(batteryConfig.getUseAngle()); + + performanceConfig = config.getGameModeConfiguration(GameManager.GAME_MODE_PERFORMANCE); + assertNotNull(performanceConfig); + assertEquals(performanceConfig.getScaling(), 0.66f, 0.01f); + assertEquals(performanceConfig.getLoadingBoostDuration(), 321); + assertEquals(performanceConfig.getFpsStr(), "60"); + assertTrue(performanceConfig.getUseAngle()); } }