Merge changes Ia3905cd1,Ibcedd393,Id145fe3a
* changes: Send writing file messages on shutdown with no delay Persist game mode configs in settings file Support per user game config override
This commit is contained in:
@@ -99,6 +99,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Service to manage game related features.
|
||||
@@ -119,7 +120,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
static final int SET_GAME_STATE = 4;
|
||||
static final int CANCEL_GAME_LOADING_MODE = 5;
|
||||
static final int WRITE_GAME_MODE_INTERVENTION_LIST_FILE = 6;
|
||||
static final int WRITE_SETTINGS_DELAY = 10 * 1000; // 10 seconds
|
||||
static final int WRITE_DELAY_MILLIS = 10 * 1000; // 10 seconds
|
||||
static final int LOADING_BOOST_MAX_DURATION = 5 * 1000; // 5 seconds
|
||||
|
||||
private static final String PACKAGE_NAME_MSG_KEY = "packageName";
|
||||
@@ -130,8 +131,8 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
private final Context mContext;
|
||||
private final Object mLock = new Object();
|
||||
private final Object mDeviceConfigLock = new Object();
|
||||
private final Object mOverrideConfigLock = new Object();
|
||||
private final Handler mHandler;
|
||||
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
|
||||
final Handler mHandler;
|
||||
private final PackageManager mPackageManager;
|
||||
private final UserManager mUserManager;
|
||||
private final PowerManagerInternal mPowerManagerInternal;
|
||||
@@ -143,8 +144,6 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
private final ArrayMap<Integer, GameManagerSettings> mSettings = new ArrayMap<>();
|
||||
@GuardedBy("mDeviceConfigLock")
|
||||
private final ArrayMap<String, GamePackageConfiguration> mConfigs = new ArrayMap<>();
|
||||
@GuardedBy("mOverrideConfigLock")
|
||||
private final ArrayMap<String, GamePackageConfiguration> mOverrideConfigs = new ArrayMap<>();
|
||||
@Nullable
|
||||
private final GameServiceController mGameServiceController;
|
||||
|
||||
@@ -236,7 +235,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
final int userId = ActivityManager.getCurrentUser();
|
||||
String[] packageList = getInstalledGamePackageNames(userId);
|
||||
for (final String packageName : packageList) {
|
||||
pw.println(getInterventionList(packageName));
|
||||
pw.println(getInterventionList(packageName, userId));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,14 +257,13 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
if (userId < 0) {
|
||||
Slog.wtf(TAG, "Attempt to write settings for invalid user: " + userId);
|
||||
synchronized (mLock) {
|
||||
removeMessages(WRITE_SETTINGS, msg.obj);
|
||||
removeEqualMessages(WRITE_SETTINGS, msg.obj);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
|
||||
synchronized (mLock) {
|
||||
removeMessages(WRITE_SETTINGS, msg.obj);
|
||||
removeEqualMessages(WRITE_SETTINGS, msg.obj);
|
||||
if (mSettings.containsKey(userId)) {
|
||||
GameManagerSettings userSettings = mSettings.get(userId);
|
||||
userSettings.writePersistentDataLocked();
|
||||
@@ -279,8 +277,8 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
if (userId < 0) {
|
||||
Slog.wtf(TAG, "Attempt to write settings for invalid user: " + userId);
|
||||
synchronized (mLock) {
|
||||
removeMessages(WRITE_SETTINGS, msg.obj);
|
||||
removeMessages(REMOVE_SETTINGS, msg.obj);
|
||||
removeEqualMessages(WRITE_SETTINGS, msg.obj);
|
||||
removeEqualMessages(REMOVE_SETTINGS, msg.obj);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -288,8 +286,8 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
synchronized (mLock) {
|
||||
// Since the user was removed, ignore previous write message
|
||||
// and do write here.
|
||||
removeMessages(WRITE_SETTINGS, msg.obj);
|
||||
removeMessages(REMOVE_SETTINGS, msg.obj);
|
||||
removeEqualMessages(WRITE_SETTINGS, msg.obj);
|
||||
removeEqualMessages(REMOVE_SETTINGS, msg.obj);
|
||||
if (mSettings.containsKey(userId)) {
|
||||
final GameManagerSettings userSettings = mSettings.get(userId);
|
||||
mSettings.remove(userId);
|
||||
@@ -299,7 +297,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
break;
|
||||
}
|
||||
case POPULATE_GAME_MODE_SETTINGS: {
|
||||
removeMessages(POPULATE_GAME_MODE_SETTINGS, msg.obj);
|
||||
removeEqualMessages(POPULATE_GAME_MODE_SETTINGS, msg.obj);
|
||||
final int userId = (int) msg.obj;
|
||||
final String[] packageNames = getInstalledGamePackageNames(userId);
|
||||
updateConfigsForUser(userId, false /*checkGamePackage*/, packageNames);
|
||||
@@ -345,13 +343,13 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
if (userId < 0) {
|
||||
Slog.wtf(TAG, "Attempt to write setting for invalid user: " + userId);
|
||||
synchronized (mLock) {
|
||||
removeMessages(WRITE_GAME_MODE_INTERVENTION_LIST_FILE, null);
|
||||
removeEqualMessages(WRITE_GAME_MODE_INTERVENTION_LIST_FILE, msg.obj);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
|
||||
removeMessages(WRITE_GAME_MODE_INTERVENTION_LIST_FILE, null);
|
||||
removeEqualMessages(WRITE_GAME_MODE_INTERVENTION_LIST_FILE, msg.obj);
|
||||
writeGameModeInterventionsToFile(userId);
|
||||
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
|
||||
break;
|
||||
@@ -446,8 +444,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";
|
||||
|
||||
/**
|
||||
@@ -499,12 +496,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);
|
||||
@@ -538,16 +539,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;
|
||||
@@ -596,7 +598,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";
|
||||
@@ -613,8 +614,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;
|
||||
@@ -657,11 +658,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;
|
||||
}
|
||||
|
||||
@@ -673,6 +678,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
|
||||
@@ -759,7 +772,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a new GameModeConfiguration
|
||||
* Inserts a new GameModeConfiguration.
|
||||
*/
|
||||
public void addModeConfig(GameModeConfiguration config) {
|
||||
if (config.isActive()) {
|
||||
@@ -772,6 +785,15 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the GameModeConfiguration.
|
||||
*/
|
||||
public void removeModeConfig(int mode) {
|
||||
synchronized (mModeConfigLock) {
|
||||
mModeConfigs.remove(mode);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
synchronized (mModeConfigLock) {
|
||||
return mModeConfigs.size() > 0 || mBatteryModeOptedIn || mPerfModeOptedIn;
|
||||
@@ -823,7 +845,8 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
|
||||
@Override
|
||||
public void onUserStarting(@NonNull TargetUser user) {
|
||||
mService.onUserStarting(user);
|
||||
mService.onUserStarting(user,
|
||||
Environment.getDataSystemDeDirectory(user.getUserIdentifier()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -860,7 +883,10 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
}
|
||||
|
||||
private @GameMode int[] getAvailableGameModesUnchecked(String packageName) {
|
||||
final GamePackageConfiguration config = getConfig(packageName);
|
||||
final GamePackageConfiguration config;
|
||||
synchronized (mDeviceConfigLock) {
|
||||
config = mConfigs.get(packageName);
|
||||
}
|
||||
if (config == null) {
|
||||
return new int[]{};
|
||||
}
|
||||
@@ -987,18 +1013,11 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
}
|
||||
GameManagerSettings userSettings = mSettings.get(userId);
|
||||
userSettings.setGameModeLocked(packageName, gameMode);
|
||||
final Message msg = mHandler.obtainMessage(WRITE_SETTINGS);
|
||||
msg.obj = userId;
|
||||
if (!mHandler.hasEqualMessages(WRITE_SETTINGS, userId)) {
|
||||
mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
|
||||
}
|
||||
}
|
||||
updateInterventions(packageName, gameMode, userId);
|
||||
final Message 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);
|
||||
}
|
||||
sendUserMessage(userId, WRITE_SETTINGS, "SET_GAME_MODE", WRITE_DELAY_MILLIS);
|
||||
sendUserMessage(userId, WRITE_GAME_MODE_INTERVENTION_LIST_FILE,
|
||||
"SET_GAME_MODE", 0 /*delayMillis*/);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1033,7 +1052,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);
|
||||
@@ -1165,7 +1183,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
}
|
||||
|
||||
float getResolutionScalingFactorInternal(String packageName, int gameMode, int userId) {
|
||||
final GamePackageConfiguration packageConfig = getConfig(packageName);
|
||||
final GamePackageConfiguration packageConfig = getConfig(packageName, userId);
|
||||
if (packageConfig == null) {
|
||||
return GamePackageConfiguration.GameModeConfiguration.DEFAULT_SCALING;
|
||||
}
|
||||
@@ -1186,22 +1204,46 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
if (mGameServiceController != null) {
|
||||
mGameServiceController.onBootComplete();
|
||||
}
|
||||
mContext.registerReceiver(new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
|
||||
synchronized (mLock) {
|
||||
// Note that the max wait time of broadcast is 10s (see
|
||||
// {@ShutdownThread#MAX_BROADCAST_TIMEMAX_BROADCAST_TIME}) currently so
|
||||
// this can be optional only if we have message delay plus processing
|
||||
// time significant smaller to prevent data loss.
|
||||
for (Map.Entry<Integer, GameManagerSettings> entry : mSettings.entrySet()) {
|
||||
final int userId = entry.getKey();
|
||||
sendUserMessage(userId, WRITE_SETTINGS,
|
||||
Intent.ACTION_SHUTDOWN, 0 /*delayMillis*/);
|
||||
sendUserMessage(userId,
|
||||
WRITE_GAME_MODE_INTERVENTION_LIST_FILE, Intent.ACTION_SHUTDOWN,
|
||||
0 /*delayMillis*/);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, new IntentFilter(Intent.ACTION_SHUTDOWN));
|
||||
}
|
||||
|
||||
void onUserStarting(@NonNull TargetUser user) {
|
||||
final int userId = user.getUserIdentifier();
|
||||
private void sendUserMessage(int userId, int what, String eventForLog, int delayMillis) {
|
||||
Message msg = mHandler.obtainMessage(what, userId);
|
||||
if (!mHandler.sendMessageDelayed(msg, delayMillis)) {
|
||||
Slog.e(TAG, "Failed to send user message " + what + " on " + eventForLog);
|
||||
}
|
||||
}
|
||||
|
||||
void onUserStarting(@NonNull TargetUser user, File settingDataDir) {
|
||||
final int userId = user.getUserIdentifier();
|
||||
synchronized (mLock) {
|
||||
if (!mSettings.containsKey(userId)) {
|
||||
GameManagerSettings userSettings =
|
||||
new GameManagerSettings(Environment.getDataSystemDeDirectory(userId));
|
||||
GameManagerSettings userSettings = new GameManagerSettings(settingDataDir);
|
||||
mSettings.put(userId, userSettings);
|
||||
userSettings.readPersistentDataLocked();
|
||||
}
|
||||
}
|
||||
final Message msg = mHandler.obtainMessage(POPULATE_GAME_MODE_SETTINGS);
|
||||
msg.obj = userId;
|
||||
mHandler.sendMessage(msg);
|
||||
sendUserMessage(userId, POPULATE_GAME_MODE_SETTINGS, "ON_USER_STARTING", 0 /*delayMillis*/);
|
||||
|
||||
if (mGameServiceController != null) {
|
||||
mGameServiceController.notifyUserStarted(user);
|
||||
@@ -1221,9 +1263,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
if (!mSettings.containsKey(userId)) {
|
||||
return;
|
||||
}
|
||||
final Message msg = mHandler.obtainMessage(REMOVE_SETTINGS);
|
||||
msg.obj = userId;
|
||||
mHandler.sendMessage(msg);
|
||||
sendUserMessage(userId, REMOVE_SETTINGS, "ON_USER_STOPPING", 0 /*delayMillis*/);
|
||||
}
|
||||
|
||||
if (mGameServiceController != null) {
|
||||
@@ -1237,15 +1277,14 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
synchronized (mLock) {
|
||||
final int fromUserId = from.getUserIdentifier();
|
||||
if (mSettings.containsKey(fromUserId)) {
|
||||
final Message msg = mHandler.obtainMessage(REMOVE_SETTINGS);
|
||||
msg.obj = fromUserId;
|
||||
mHandler.sendMessage(msg);
|
||||
sendUserMessage(fromUserId, REMOVE_SETTINGS, "ON_USER_SWITCHING",
|
||||
0 /*delayMillis*/);
|
||||
}
|
||||
}
|
||||
}
|
||||
final Message msg = mHandler.obtainMessage(POPULATE_GAME_MODE_SETTINGS);
|
||||
msg.obj = toUserId;
|
||||
mHandler.sendMessage(msg);
|
||||
|
||||
sendUserMessage(toUserId, POPULATE_GAME_MODE_SETTINGS, "ON_USER_SWITCHING",
|
||||
0 /*delayMillis*/);
|
||||
|
||||
if (mGameServiceController != null) {
|
||||
mGameServiceController.notifyNewForegroundUser(to);
|
||||
@@ -1265,7 +1304,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
private int modeToBitmask(@GameMode int gameMode) {
|
||||
private static int modeToBitmask(@GameMode int gameMode) {
|
||||
return (1 << gameMode);
|
||||
}
|
||||
|
||||
@@ -1305,7 +1344,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
resetFps(packageName, userId);
|
||||
return;
|
||||
}
|
||||
final GamePackageConfiguration packageConfig = getConfig(packageName);
|
||||
final GamePackageConfiguration packageConfig = getConfig(packageName, userId);
|
||||
if (packageConfig == null) {
|
||||
Slog.v(TAG, "Package configuration not found for " + packageName);
|
||||
return;
|
||||
@@ -1318,7 +1357,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the override Game Mode Configuration.
|
||||
* Set the Game Mode Configuration override.
|
||||
* Update the config if exists, create one if not.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
@@ -1326,95 +1365,86 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
public void setGameModeConfigOverride(String packageName, @UserIdInt int userId,
|
||||
@GameMode int gameMode, String fpsStr, String scaling) throws SecurityException {
|
||||
checkPermission(Manifest.permission.MANAGE_GAME_MODE);
|
||||
// Adding game mode config override of the given package name
|
||||
GamePackageConfiguration configOverride;
|
||||
synchronized (mLock) {
|
||||
if (!mSettings.containsKey(userId)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Adding override game mode configuration of the given package name
|
||||
GamePackageConfiguration overrideConfig;
|
||||
synchronized (mOverrideConfigLock) {
|
||||
// look for the existing override GamePackageConfiguration
|
||||
overrideConfig = mOverrideConfigs.get(packageName);
|
||||
if (overrideConfig == null) {
|
||||
overrideConfig = new GamePackageConfiguration(packageName, userId);
|
||||
mOverrideConfigs.put(packageName, overrideConfig);
|
||||
final GameManagerSettings settings = mSettings.get(userId);
|
||||
// look for the existing GamePackageConfiguration override
|
||||
configOverride = settings.getConfigOverride(packageName);
|
||||
if (configOverride == null) {
|
||||
configOverride = new GamePackageConfiguration(mPackageManager, packageName, userId);
|
||||
settings.setConfigOverride(packageName, configOverride);
|
||||
}
|
||||
}
|
||||
// modify GameModeConfiguration intervention settings
|
||||
GamePackageConfiguration.GameModeConfiguration overrideModeConfig =
|
||||
overrideConfig.getOrAddDefaultGameModeConfiguration(gameMode);
|
||||
GamePackageConfiguration.GameModeConfiguration modeConfigOverride =
|
||||
configOverride.getOrAddDefaultGameModeConfiguration(gameMode);
|
||||
|
||||
if (fpsStr != null) {
|
||||
overrideModeConfig.setFpsStr(fpsStr);
|
||||
modeConfigOverride.setFpsStr(fpsStr);
|
||||
} else {
|
||||
overrideModeConfig.setFpsStr(
|
||||
modeConfigOverride.setFpsStr(
|
||||
GamePackageConfiguration.GameModeConfiguration.DEFAULT_FPS);
|
||||
}
|
||||
if (scaling != null) {
|
||||
overrideModeConfig.setScaling(Float.parseFloat(scaling));
|
||||
modeConfigOverride.setScaling(Float.parseFloat(scaling));
|
||||
}
|
||||
Slog.i(TAG, "Package Name: " + packageName
|
||||
+ " FPS: " + String.valueOf(overrideModeConfig.getFps())
|
||||
+ " Scaling: " + overrideModeConfig.getScaling());
|
||||
+ " FPS: " + String.valueOf(modeConfigOverride.getFps())
|
||||
+ " Scaling: " + modeConfigOverride.getScaling());
|
||||
setGameMode(packageName, gameMode, userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the overridden gameModeConfiguration of the given mode.
|
||||
* Remove the override config if game mode is not specified.
|
||||
* Remove the config override if game mode is not specified.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
@RequiresPermission(Manifest.permission.MANAGE_GAME_MODE)
|
||||
public void resetGameModeConfigOverride(String packageName, @UserIdInt int userId,
|
||||
@GameMode int gameModeToReset) throws SecurityException {
|
||||
checkPermission(Manifest.permission.MANAGE_GAME_MODE);
|
||||
synchronized (mLock) {
|
||||
if (!mSettings.containsKey(userId)) {
|
||||
return;
|
||||
}
|
||||
final GamePackageConfiguration deviceConfig;
|
||||
synchronized (mDeviceConfigLock) {
|
||||
deviceConfig = mConfigs.get(packageName);
|
||||
}
|
||||
|
||||
// resets GamePackageConfiguration of a given packageName.
|
||||
// If a gameMode is specified, only reset the GameModeConfiguration of the gameMode.
|
||||
if (gameModeToReset != -1) {
|
||||
GamePackageConfiguration overrideConfig = null;
|
||||
synchronized (mOverrideConfigLock) {
|
||||
overrideConfig = mOverrideConfigs.get(packageName);
|
||||
}
|
||||
|
||||
GamePackageConfiguration config = null;
|
||||
synchronized (mDeviceConfigLock) {
|
||||
config = mConfigs.get(packageName);
|
||||
}
|
||||
|
||||
int[] modes = overrideConfig.getAvailableGameModes();
|
||||
|
||||
// First check if the mode to reset exists
|
||||
boolean isGameModeExist = false;
|
||||
for (int mode : modes) {
|
||||
if (gameModeToReset == mode) {
|
||||
isGameModeExist = true;
|
||||
}
|
||||
}
|
||||
if (!isGameModeExist) {
|
||||
synchronized (mLock) {
|
||||
if (!mSettings.containsKey(userId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the game mode to reset is the only mode other than standard mode,
|
||||
// the override config is removed.
|
||||
if (modes.length <= 2) {
|
||||
synchronized (mOverrideConfigLock) {
|
||||
mOverrideConfigs.remove(packageName);
|
||||
final GameManagerSettings settings = mSettings.get(userId);
|
||||
if (gameModeToReset != -1) {
|
||||
final GamePackageConfiguration configOverride = settings.getConfigOverride(
|
||||
packageName);
|
||||
if (configOverride == null) {
|
||||
return;
|
||||
}
|
||||
final int modesBitfield = configOverride.getAvailableGameModesBitfield();
|
||||
if (!bitFieldContainsModeBitmask(modesBitfield, gameModeToReset)) {
|
||||
return;
|
||||
}
|
||||
// if the game mode to reset is the only mode other than standard mode or there
|
||||
// is device config, the config override is removed.
|
||||
if (Integer.bitCount(modesBitfield) <= 2 || deviceConfig == null) {
|
||||
settings.removeConfigOverride(packageName);
|
||||
} else {
|
||||
final GamePackageConfiguration.GameModeConfiguration defaultModeConfig =
|
||||
deviceConfig.getGameModeConfiguration(gameModeToReset);
|
||||
// otherwise we reset the mode by copying the original config.
|
||||
if (defaultModeConfig == null) {
|
||||
configOverride.removeModeConfig(gameModeToReset);
|
||||
} else {
|
||||
configOverride.addModeConfig(defaultModeConfig);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// otherwise we reset the mode by copying the original config.
|
||||
overrideConfig.addModeConfig(config.getGameModeConfiguration(gameModeToReset));
|
||||
}
|
||||
} else {
|
||||
synchronized (mOverrideConfigLock) {
|
||||
// remove override config if there is one
|
||||
mOverrideConfigs.remove(packageName);
|
||||
settings.removeConfigOverride(packageName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1422,7 +1452,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
// If not, set the game mode to standard
|
||||
int gameMode = getGameMode(packageName, userId);
|
||||
|
||||
final GamePackageConfiguration config = getConfig(packageName);
|
||||
final GamePackageConfiguration config = getConfig(packageName, userId);
|
||||
final int newGameMode = getNewGameMode(gameMode, config);
|
||||
if (gameMode != newGameMode) {
|
||||
setGameMode(packageName, GameManager.GAME_MODE_STANDARD, userId);
|
||||
@@ -1460,8 +1490,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) {
|
||||
final GamePackageConfiguration packageConfig = getConfig(packageName);
|
||||
public String getInterventionList(String packageName, int userId) {
|
||||
final GamePackageConfiguration packageConfig = getConfig(packageName, userId);
|
||||
final StringBuilder listStrSb = new StringBuilder();
|
||||
if (packageConfig == null) {
|
||||
listStrSb.append("\n No intervention found for package ")
|
||||
@@ -1487,7 +1517,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());
|
||||
@@ -1526,15 +1556,11 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
updateInterventions(packageName, gameMode, userId);
|
||||
}
|
||||
}
|
||||
sendUserMessage(userId, WRITE_GAME_MODE_INTERVENTION_LIST_FILE,
|
||||
"UPDATE_CONFIGS_FOR_USERS", 0 /*delayMillis*/);
|
||||
} catch (Exception e) {
|
||||
Slog.e(TAG, "Failed to update configs for user " + userId + ": " + e);
|
||||
}
|
||||
|
||||
final Message 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);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1556,7 +1582,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
final List<String> installedGamesList = getInstalledGamePackageNamesByAllUsers(userId);
|
||||
for (final String packageName : installedGamesList) {
|
||||
GamePackageConfiguration packageConfig = getConfig(packageName);
|
||||
GamePackageConfiguration packageConfig = getConfig(packageName, userId);
|
||||
if (packageConfig == null) {
|
||||
continue;
|
||||
}
|
||||
@@ -1634,11 +1660,12 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public GamePackageConfiguration getConfig(String packageName) {
|
||||
public GamePackageConfiguration getConfig(String packageName, int userId) {
|
||||
GamePackageConfiguration packageConfig = null;
|
||||
synchronized (mOverrideConfigLock) {
|
||||
packageConfig = mOverrideConfigs.get(packageName);
|
||||
synchronized (mLock) {
|
||||
if (mSettings.containsKey(userId)) {
|
||||
packageConfig = mSettings.get(userId).getConfigOverride(packageName);
|
||||
}
|
||||
}
|
||||
if (packageConfig == null) {
|
||||
synchronized (mDeviceConfigLock) {
|
||||
@@ -1679,9 +1706,6 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
break;
|
||||
case ACTION_PACKAGE_REMOVED:
|
||||
if (!intent.getBooleanExtra(EXTRA_REPLACING, false)) {
|
||||
synchronized (mOverrideConfigLock) {
|
||||
mOverrideConfigs.remove(packageName);
|
||||
}
|
||||
synchronized (mDeviceConfigLock) {
|
||||
mConfigs.remove(packageName);
|
||||
}
|
||||
@@ -1689,6 +1713,11 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
if (mSettings.containsKey(userId)) {
|
||||
mSettings.get(userId).removeGame(packageName);
|
||||
}
|
||||
sendUserMessage(userId, WRITE_SETTINGS,
|
||||
Intent.ACTION_PACKAGE_REMOVED, WRITE_DELAY_MILLIS);
|
||||
sendUserMessage(userId,
|
||||
WRITE_GAME_MODE_INTERVENTION_LIST_FILE,
|
||||
Intent.ACTION_PACKAGE_REMOVED, WRITE_DELAY_MILLIS);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -27,6 +27,8 @@ 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;
|
||||
@@ -39,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>
|
||||
@@ -53,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
|
||||
@@ -62,6 +71,8 @@ public class GameManagerSettings {
|
||||
|
||||
// PackageName -> GameMode
|
||||
private final ArrayMap<String, Integer> mGameModes = new ArrayMap<>();
|
||||
// PackageName -> GamePackageConfiguration
|
||||
private final ArrayMap<String, GamePackageConfiguration> mConfigOverrides = new ArrayMap<>();
|
||||
|
||||
GameManagerSettings(File dataDir) {
|
||||
mSystemDir = new File(dataDir, "system");
|
||||
@@ -74,7 +85,7 @@ public class GameManagerSettings {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the game mode of a given package.
|
||||
* Returns the game mode of a given package.
|
||||
* This operation must be synced with an external lock.
|
||||
*/
|
||||
int getGameModeLocked(String packageName) {
|
||||
@@ -85,7 +96,7 @@ public class GameManagerSettings {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the game mode of a given package.
|
||||
* Sets the game mode of a given package.
|
||||
* This operation must be synced with an external lock.
|
||||
*/
|
||||
void setGameModeLocked(String packageName, int gameMode) {
|
||||
@@ -93,15 +104,40 @@ public class GameManagerSettings {
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the game mode of a given package.
|
||||
* Removes all game settings of a given package.
|
||||
* This operation must be synced with an external lock.
|
||||
*/
|
||||
void removeGame(String packageName) {
|
||||
mGameModes.remove(packageName);
|
||||
mConfigOverrides.remove(packageName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write all current game service settings into disk.
|
||||
* Returns the game config override of a given package or null if absent.
|
||||
* This operation must be synced with an external lock.
|
||||
*/
|
||||
GamePackageConfiguration getConfigOverride(String packageName) {
|
||||
return mConfigOverrides.get(packageName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the game config override of a given package.
|
||||
* This operation must be synced with an external lock.
|
||||
*/
|
||||
void setConfigOverride(String packageName, GamePackageConfiguration configOverride) {
|
||||
mConfigOverrides.put(packageName, configOverride);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the game mode config override of a given package.
|
||||
* This operation must be synced with an external lock.
|
||||
*/
|
||||
void removeConfigOverride(String packageName) {
|
||||
mConfigOverrides.remove(packageName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes all current game service settings into disk.
|
||||
* This operation must be synced with an external lock.
|
||||
*/
|
||||
void writePersistentDataLocked() {
|
||||
@@ -115,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);
|
||||
@@ -133,20 +171,41 @@ 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read game service settings from the disk.
|
||||
* Reads game service settings from the disk.
|
||||
* This operation must be synced with an external lock.
|
||||
*/
|
||||
boolean readPersistentDataLocked() {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -160,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;
|
||||
}
|
||||
|
||||
@@ -173,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,8 @@ public class GameManagerShellCommand extends ShellCommand {
|
||||
final GameManagerService gameManagerService = (GameManagerService)
|
||||
ServiceManager.getService(Context.GAME_SERVICE);
|
||||
|
||||
final String listStr = gameManagerService.getInterventionList(packageName);
|
||||
final String listStr = gameManagerService.getInterventionList(packageName,
|
||||
ActivityManager.getCurrentUser());
|
||||
|
||||
if (listStr == null) {
|
||||
pw.println("No interventions found for " + packageName);
|
||||
|
||||
@@ -17,8 +17,10 @@
|
||||
package com.android.server.app;
|
||||
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
|
||||
import static com.android.server.app.GameManagerService.WRITE_SETTINGS;
|
||||
|
||||
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.assertThrows;
|
||||
@@ -35,11 +37,15 @@ import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.GameManager;
|
||||
import android.app.GameModeInfo;
|
||||
import android.app.GameState;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
@@ -97,6 +103,7 @@ public class GameManagerServiceTests {
|
||||
private PowerManagerInternal mMockPowerManager;
|
||||
@Mock
|
||||
private UserManager mMockUserManager;
|
||||
private BroadcastReceiver mShutDownActionReceiver;
|
||||
|
||||
// Stolen from ConnectivityServiceTest.MockContext
|
||||
class MockContext extends ContextWrapper {
|
||||
@@ -165,6 +172,12 @@ public class GameManagerServiceTests {
|
||||
}
|
||||
throw new UnsupportedOperationException("Couldn't find system service: " + name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Intent registerReceiver(@Nullable BroadcastReceiver receiver, IntentFilter filter) {
|
||||
mShutDownActionReceiver = receiver;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
@@ -200,15 +213,16 @@ public class GameManagerServiceTests {
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
LocalServices.removeServiceForTest(PowerManagerInternal.class);
|
||||
GameManagerService gameManagerService = new GameManagerService(mMockContext);
|
||||
if (mMockingSession != null) {
|
||||
mMockingSession.finishMocking();
|
||||
}
|
||||
deleteFolder(InstrumentationRegistry.getTargetContext().getFilesDir());
|
||||
}
|
||||
|
||||
private void startUser(GameManagerService gameManagerService, int userId) {
|
||||
UserInfo userInfo = new UserInfo(userId, "name", 0);
|
||||
gameManagerService.onUserStarting(new SystemService.TargetUser(userInfo));
|
||||
gameManagerService.onUserStarting(new SystemService.TargetUser(userInfo),
|
||||
InstrumentationRegistry.getContext().getFilesDir());
|
||||
mTestLooper.dispatchAll();
|
||||
}
|
||||
|
||||
@@ -584,7 +598,7 @@ public class GameManagerServiceTests {
|
||||
gameManagerService.updateConfigsForUser(USER_ID_1, true, mPackageName);
|
||||
}
|
||||
GameManagerService.GamePackageConfiguration config =
|
||||
gameManagerService.getConfig(mPackageName);
|
||||
gameManagerService.getConfig(mPackageName, USER_ID_1);
|
||||
assertEquals(scaling, config.getGameModeConfiguration(gameMode).getScaling(), 0.01f);
|
||||
}
|
||||
|
||||
@@ -594,7 +608,7 @@ public class GameManagerServiceTests {
|
||||
|
||||
// Validate GamePackageConfiguration returns the correct value.
|
||||
GameManagerService.GamePackageConfiguration config =
|
||||
gameManagerService.getConfig(mPackageName);
|
||||
gameManagerService.getConfig(mPackageName, USER_ID_1);
|
||||
assertEquals(config.getGameModeConfiguration(gameMode).getUseAngle(), angleEnabled);
|
||||
|
||||
// Validate GameManagerService.isAngleEnabled() returns the correct value.
|
||||
@@ -607,7 +621,7 @@ public class GameManagerServiceTests {
|
||||
|
||||
// Validate GamePackageConfiguration returns the correct value.
|
||||
GameManagerService.GamePackageConfiguration config =
|
||||
gameManagerService.getConfig(mPackageName);
|
||||
gameManagerService.getConfig(mPackageName, USER_ID_1);
|
||||
assertEquals(
|
||||
loadingBoost, config.getGameModeConfiguration(gameMode).getLoadingBoostDuration());
|
||||
|
||||
@@ -623,7 +637,7 @@ public class GameManagerServiceTests {
|
||||
gameManagerService.updateConfigsForUser(USER_ID_1, true, mPackageName);
|
||||
}
|
||||
GameManagerService.GamePackageConfiguration config =
|
||||
gameManagerService.getConfig(mPackageName);
|
||||
gameManagerService.getConfig(mPackageName, USER_ID_1);
|
||||
assertEquals(fps, config.getGameModeConfiguration(gameMode).getFps());
|
||||
}
|
||||
|
||||
@@ -1049,7 +1063,7 @@ public class GameManagerServiceTests {
|
||||
mTestLooper.getLooper());
|
||||
startUser(gameManagerService, USER_ID_1);
|
||||
GameManagerService.GamePackageConfiguration config =
|
||||
gameManagerService.getConfig(mPackageName);
|
||||
gameManagerService.getConfig(mPackageName, USER_ID_1);
|
||||
assertEquals(90,
|
||||
config.getGameModeConfiguration(GameManager.GAME_MODE_PERFORMANCE).getFps());
|
||||
assertEquals(30, config.getGameModeConfiguration(GameManager.GAME_MODE_BATTERY).getFps());
|
||||
@@ -1064,7 +1078,7 @@ public class GameManagerServiceTests {
|
||||
mTestLooper.getLooper());
|
||||
startUser(gameManagerService, USER_ID_1);
|
||||
GameManagerService.GamePackageConfiguration config =
|
||||
gameManagerService.getConfig(mPackageName);
|
||||
gameManagerService.getConfig(mPackageName, USER_ID_1);
|
||||
assertEquals(0,
|
||||
config.getGameModeConfiguration(GameManager.GAME_MODE_PERFORMANCE).getFps());
|
||||
assertEquals(0, config.getGameModeConfiguration(GameManager.GAME_MODE_BATTERY).getFps());
|
||||
@@ -1092,7 +1106,7 @@ public class GameManagerServiceTests {
|
||||
startUser(gameManagerService, USER_ID_1);
|
||||
gameManagerService.updateConfigsForUser(USER_ID_1, true, mPackageName);
|
||||
GameManagerService.GamePackageConfiguration config =
|
||||
gameManagerService.getConfig(mPackageName);
|
||||
gameManagerService.getConfig(mPackageName, USER_ID_1);
|
||||
assertNull(config.getGameModeConfiguration(GameManager.GAME_MODE_PERFORMANCE));
|
||||
}
|
||||
|
||||
@@ -1339,10 +1353,15 @@ public class GameManagerServiceTests {
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
/* Expected fileOutput (order may vary)
|
||||
# user 1001:
|
||||
com.android.app2 <UID> 0 2 angle=0,scaling=0.5,fps=90 3 angle=0,scaling=0.5,fps=60
|
||||
com.android.app1 <UID> 1 2 angle=0,scaling=0.5,fps=90 3 angle=0,scaling=0.7,fps=30
|
||||
com.android.app0 <UID> 0 2 angle=0,scaling=0.6,fps=120 3 angle=0,scaling=0.7,fps=30
|
||||
|
||||
# user 1002:
|
||||
com.android.app2 <UID> 0 2 angle=0,scaling=0.5,fps=90 3 angle=0,scaling=0.7,fps=30
|
||||
com.android.app1 <UID> 1 2 angle=0,scaling=0.5,fps=90 3 angle=0,scaling=0.7,fps=30
|
||||
com.android.app0 <UID> 0 2 angle=0,scaling=0.5,fps=90 3 angle=0,scaling=0.7,fps=30
|
||||
The current game mode would only be set to non-zero if the current user have that game
|
||||
installed.
|
||||
*/
|
||||
@@ -1386,7 +1405,7 @@ public class GameManagerServiceTests {
|
||||
assertEquals(splitLine[3], "2");
|
||||
assertEquals(splitLine[4], "angle=0,scaling=0.5,fps=90");
|
||||
assertEquals(splitLine[5], "3");
|
||||
assertEquals(splitLine[6], "angle=0,scaling=0.5,fps=60");
|
||||
assertEquals(splitLine[6], "angle=0,scaling=0.7,fps=30");
|
||||
splitLine = fileOutput.get(1).split("\\s+");
|
||||
assertEquals(splitLine[0], "com.android.app1");
|
||||
assertEquals(splitLine[2], "3");
|
||||
@@ -1398,7 +1417,7 @@ public class GameManagerServiceTests {
|
||||
assertEquals(splitLine[0], "com.android.app0");
|
||||
assertEquals(splitLine[2], "0");
|
||||
assertEquals(splitLine[3], "2");
|
||||
assertEquals(splitLine[4], "angle=0,scaling=0.6,fps=120");
|
||||
assertEquals(splitLine[4], "angle=0,scaling=0.5,fps=90");
|
||||
assertEquals(splitLine[5], "3");
|
||||
assertEquals(splitLine[6], "angle=0,scaling=0.7,fps=30");
|
||||
|
||||
@@ -1493,12 +1512,52 @@ public class GameManagerServiceTests {
|
||||
|
||||
@Test
|
||||
public void testGetResolutionScalingFactor_noUserId() {
|
||||
mockModifyGameModeDenied();
|
||||
mockModifyGameModeGranted();
|
||||
mockDeviceConfigAll();
|
||||
GameManagerService gameManagerService =
|
||||
new GameManagerService(mMockContext, mTestLooper.getLooper());
|
||||
startUser(gameManagerService, USER_ID_2);
|
||||
assertEquals(-1f, gameManagerService.getResolutionScalingFactor(mPackageName,
|
||||
GameManager.GAME_MODE_BATTERY, USER_ID_1), 0.001f);
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
gameManagerService.getResolutionScalingFactor(mPackageName,
|
||||
GameManager.GAME_MODE_BATTERY, USER_ID_1);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWritingSettingFile_onShutdown() throws InterruptedException {
|
||||
mockModifyGameModeGranted();
|
||||
mockDeviceConfigAll();
|
||||
GameManagerService gameManagerService = new GameManagerService(mMockContext);
|
||||
gameManagerService.onBootCompleted();
|
||||
startUser(gameManagerService, USER_ID_1);
|
||||
Thread.sleep(500);
|
||||
gameManagerService.setGameModeConfigOverride("com.android.app1", USER_ID_1,
|
||||
GameManager.GAME_MODE_BATTERY, "60", "0.5");
|
||||
gameManagerService.setGameMode("com.android.app1", USER_ID_1,
|
||||
GameManager.GAME_MODE_PERFORMANCE);
|
||||
GameManagerSettings settings = new GameManagerSettings(
|
||||
InstrumentationRegistry.getContext().getFilesDir());
|
||||
Thread.sleep(500);
|
||||
// no data written as delayed messages are queued
|
||||
assertFalse(settings.readPersistentDataLocked());
|
||||
assertTrue(gameManagerService.mHandler.hasEqualMessages(WRITE_SETTINGS, USER_ID_1));
|
||||
Intent shutdown = new Intent();
|
||||
shutdown.setAction(Intent.ACTION_SHUTDOWN);
|
||||
mShutDownActionReceiver.onReceive(mMockContext, shutdown);
|
||||
Thread.sleep(500);
|
||||
// data is written on processing new message with no delay on shutdown,
|
||||
// and all queued messages should be removed
|
||||
assertTrue(settings.readPersistentDataLocked());
|
||||
assertFalse(gameManagerService.mHandler.hasEqualMessages(WRITE_SETTINGS, USER_ID_1));
|
||||
}
|
||||
|
||||
private static void deleteFolder(File folder) {
|
||||
File[] files = folder.listFiles();
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
deleteFolder(file);
|
||||
}
|
||||
}
|
||||
folder.delete();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user