Persist game mode configs in settings file

Bug: b/240335717
Test: atest GameManagerServiceTests GameManagerServiceSettingsTests
Change-Id: Ibcedd393e3fcd46bba0f63aebb7ca3cefb2d4ab1
This commit is contained in:
Xiang Wang
2022-08-10 15:18:59 -07:00
parent 3815e9c2c0
commit 4b3c928df0
3 changed files with 310 additions and 55 deletions

View File

@@ -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;

View File

@@ -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:
// <?xml>
// <packages>
@@ -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<String, Integer> 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);
}
}
}
}

View File

@@ -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 {
+ " <package name=\"com.android.app1\" gameMode=\"1\">\n"
+ " </package>\n"
+ " <package name=\"com.android.app2\" gameMode=\"2\">\n"
+ " <gameModeConfig gameMode=\"2\" scaling=\"0.99\" "
+ "useAngle=\"true\" fps=\"90\" loadingBoost=\"123\"></gameModeConfig>\n"
+ " <gameModeConfig gameMode=\"3\"></gameModeConfig>\n"
+ " </package>\n"
+ " <package name=\"com.android.app3\" gameMode=\"3\">\n"
+ " </package>\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"),
("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
+ "<packages>\n"
+ " <package name=\"com.android.app1\" gameMode=\"1\">\n"
+ " <gameModeConfig gameMode=\"3\" scaling=\"invalid\" "
+ "useAngle=\"invalid\" fps=\"invalid\" "
+ "loadingBoost=\"invalid\"></gameModeConfig>\n"
+ " </package>\n"
+ "</packages>\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"),
("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
+ "<packages>\n"
+ " <package gameMode=\"1\">\n"
+ " </package>\n"
+ " <package name=\"com.android.app2\" gameMode=\"2\">\n"
+ " <unknown></unknown>"
+ " <gameModeConfig gameMode=\"3\" fps=\"90\"></gameModeConfig>\n"
+ " foo bar"
+ " </package>\n"
+ " <unknownTag></unknownTag>\n"
+ " foo bar\n"
+ " <package name=\"com.android.app3\" gameMode=\"3\">\n"
+ " </package>\n"
+ "</packages>\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());
}
}