Merge "Ensure the game mode setting doesn't conflict with available modes" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
6b843a1b8c
@@ -56,7 +56,6 @@ import android.os.ShellCallback;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.provider.DeviceConfig.Properties;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.KeyValueListParser;
|
||||
import android.util.Slog;
|
||||
|
||||
@@ -363,19 +362,42 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
|| (mPerfModeOptedIn && gameMode == GameManager.GAME_MODE_PERFORMANCE);
|
||||
}
|
||||
|
||||
public @GameMode int[] getAvailableGameModes() {
|
||||
ArraySet<Integer> modeSet = new ArraySet<>(mModeConfigs.keySet());
|
||||
private int getAvailableGameModesBitfield() {
|
||||
int field = 0;
|
||||
for (final int mode : mModeConfigs.keySet()) {
|
||||
field |= modeToBitmask(mode);
|
||||
}
|
||||
if (mBatteryModeOptedIn) {
|
||||
modeSet.add(GameManager.GAME_MODE_BATTERY);
|
||||
field |= modeToBitmask(GameManager.GAME_MODE_BATTERY);
|
||||
}
|
||||
if (mPerfModeOptedIn) {
|
||||
modeSet.add(GameManager.GAME_MODE_PERFORMANCE);
|
||||
field |= modeToBitmask(GameManager.GAME_MODE_PERFORMANCE);
|
||||
}
|
||||
if (modeSet.size() > 0) {
|
||||
modeSet.add(GameManager.GAME_MODE_STANDARD);
|
||||
return modeSet.stream().mapToInt(Integer::intValue).toArray();
|
||||
// The lowest bit is reserved for UNSUPPORTED, STANDARD is supported if we support any
|
||||
// other mode.
|
||||
if (field > 1) {
|
||||
field |= modeToBitmask(GameManager.GAME_MODE_STANDARD);
|
||||
} else {
|
||||
field |= modeToBitmask(GameManager.GAME_MODE_UNSUPPORTED);
|
||||
}
|
||||
return new int[]{GameManager.GAME_MODE_UNSUPPORTED};
|
||||
return field;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of a package's available game modes.
|
||||
*/
|
||||
public @GameMode int[] getAvailableGameModes() {
|
||||
|
||||
int modesBitfield = getAvailableGameModesBitfield();
|
||||
int sigBits = Integer.bitCount(modesBitfield);
|
||||
int[] modes = new int[sigBits];
|
||||
int i = 0;
|
||||
for (int mode = 0; mode < sigBits; ++mode) {
|
||||
if (((modesBitfield >> mode) & 1) != 0) {
|
||||
modes[i++] = mode;
|
||||
}
|
||||
}
|
||||
return modes;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -696,6 +718,14 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
private int modeToBitmask(@GameMode int gameMode) {
|
||||
return (1 << gameMode);
|
||||
}
|
||||
|
||||
private boolean bitFieldContainsModeBitmask(int bitField, @GameMode int gameMode) {
|
||||
return (bitField & modeToBitmask(gameMode)) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@@ -703,8 +733,8 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
public void updateConfigsForUser(int userId, String ...packageNames) {
|
||||
try {
|
||||
synchronized (mDeviceConfigLock) {
|
||||
for (String packageName : packageNames) {
|
||||
GamePackageConfiguration config =
|
||||
for (final String packageName : packageNames) {
|
||||
final GamePackageConfiguration config =
|
||||
new GamePackageConfiguration(packageName, userId);
|
||||
if (config.isValid()) {
|
||||
if (DEBUG) {
|
||||
@@ -718,13 +748,42 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
}
|
||||
}
|
||||
}
|
||||
for (String packageName : packageNames) {
|
||||
synchronized (mLock) {
|
||||
if (mSettings.containsKey(userId)) {
|
||||
GameManagerSettings userSettings = mSettings.get(userId);
|
||||
updateCompatModeDownscale(packageName,
|
||||
userSettings.getGameModeLocked(packageName));
|
||||
for (final String packageName : packageNames) {
|
||||
if (mSettings.containsKey(userId)) {
|
||||
int gameMode = getGameMode(packageName, userId);
|
||||
int newGameMode = gameMode;
|
||||
// Make sure the user settings and package configs don't conflict. I.e. the
|
||||
// user setting is set to a mode that no longer available due to config/manifest
|
||||
// changes. Most of the time we won't have to change anything.
|
||||
GamePackageConfiguration config;
|
||||
synchronized (mDeviceConfigLock) {
|
||||
config = mConfigs.get(packageName);
|
||||
}
|
||||
if (config != null) {
|
||||
int modesBitfield = config.getAvailableGameModesBitfield();
|
||||
// Remove UNSUPPORTED to simplify the logic here, since we really just
|
||||
// want to check if we support selectable game modes
|
||||
modesBitfield &= ~modeToBitmask(GameManager.GAME_MODE_UNSUPPORTED);
|
||||
if (!bitFieldContainsModeBitmask(modesBitfield, gameMode)) {
|
||||
if (bitFieldContainsModeBitmask(modesBitfield,
|
||||
GameManager.GAME_MODE_STANDARD)) {
|
||||
// If the current set mode isn't supported, but we support STANDARD,
|
||||
// then set the mode to STANDARD.
|
||||
newGameMode = GameManager.GAME_MODE_STANDARD;
|
||||
} else {
|
||||
// If we don't support any game modes, then set to UNSUPPORTED
|
||||
newGameMode = GameManager.GAME_MODE_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
} else if (gameMode != GameManager.GAME_MODE_UNSUPPORTED) {
|
||||
// If we have no config for the package, but the configured mode is not
|
||||
// UNSUPPORTED, then set to UNSUPPORTED
|
||||
newGameMode = GameManager.GAME_MODE_UNSUPPORTED;
|
||||
}
|
||||
if (newGameMode != gameMode) {
|
||||
setGameMode(packageName, newGameMode, userId);
|
||||
}
|
||||
updateCompatModeDownscale(packageName, gameMode);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -299,11 +299,13 @@ public class GameManagerServiceTests {
|
||||
public void testGameMode() {
|
||||
GameManagerService gameManagerService = new GameManagerService(mMockContext);
|
||||
gameManagerService.onUserStarting(USER_ID_1);
|
||||
|
||||
gameManagerService.updateConfigsForUser(USER_ID_1, mPackageName);
|
||||
mockModifyGameModeGranted();
|
||||
|
||||
assertEquals(GameManager.GAME_MODE_UNSUPPORTED,
|
||||
gameManagerService.getGameMode(mPackageName, USER_ID_1));
|
||||
// We need to make sure the mode is supported before setting it.
|
||||
mockDeviceConfigAll();
|
||||
gameManagerService.updateConfigsForUser(USER_ID_1, mPackageName);
|
||||
gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_STANDARD, USER_ID_1);
|
||||
assertEquals(GameManager.GAME_MODE_STANDARD,
|
||||
gameManagerService.getGameMode(mPackageName, USER_ID_1));
|
||||
@@ -370,11 +372,13 @@ public class GameManagerServiceTests {
|
||||
*/
|
||||
@Test
|
||||
public void testGameModeMultipleUsers() {
|
||||
mockModifyGameModeGranted();
|
||||
mockDeviceConfigAll();
|
||||
GameManagerService gameManagerService = new GameManagerService(mMockContext);
|
||||
gameManagerService.onUserStarting(USER_ID_1);
|
||||
gameManagerService.onUserStarting(USER_ID_2);
|
||||
|
||||
mockModifyGameModeGranted();
|
||||
gameManagerService.updateConfigsForUser(USER_ID_1, mPackageName);
|
||||
gameManagerService.updateConfigsForUser(USER_ID_2, mPackageName);
|
||||
|
||||
// Set User 1 to Standard
|
||||
gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_STANDARD, USER_ID_1);
|
||||
@@ -603,4 +607,52 @@ public class GameManagerServiceTests {
|
||||
gameManagerService.getConfig(mPackageName);
|
||||
assertNull(config.getGameModeConfiguration(GameManager.GAME_MODE_PERFORMANCE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that, if a game no longer supports any game modes, we set the game mode to
|
||||
* UNSUPPORTED
|
||||
*/
|
||||
@Test
|
||||
public void testUnsetInvalidGameMode() throws Exception {
|
||||
mockDeviceConfigNone();
|
||||
mockModifyGameModeGranted();
|
||||
GameManagerService gameManagerService = new GameManagerService(mMockContext);
|
||||
gameManagerService.onUserStarting(USER_ID_1);
|
||||
gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE, USER_ID_1);
|
||||
gameManagerService.updateConfigsForUser(USER_ID_1, mPackageName);
|
||||
assertEquals(GameManager.GAME_MODE_UNSUPPORTED,
|
||||
gameManagerService.getGameMode(mPackageName, USER_ID_1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that, if a game no longer supports a specific game mode, but supports STANDARD, we set
|
||||
* the game mode to STANDARD.
|
||||
*/
|
||||
@Test
|
||||
public void testResetInvalidGameMode() throws Exception {
|
||||
mockDeviceConfigPerformance();
|
||||
mockModifyGameModeGranted();
|
||||
GameManagerService gameManagerService = new GameManagerService(mMockContext);
|
||||
gameManagerService.onUserStarting(USER_ID_1);
|
||||
gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_BATTERY, USER_ID_1);
|
||||
gameManagerService.updateConfigsForUser(USER_ID_1, mPackageName);
|
||||
assertEquals(GameManager.GAME_MODE_STANDARD,
|
||||
gameManagerService.getGameMode(mPackageName, USER_ID_1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that if a game supports STANDARD, but is currently set to UNSUPPORTED, we set the game
|
||||
* mode to STANDARD
|
||||
*/
|
||||
@Test
|
||||
public void testSetValidGameMode() throws Exception {
|
||||
mockDeviceConfigPerformance();
|
||||
mockModifyGameModeGranted();
|
||||
GameManagerService gameManagerService = new GameManagerService(mMockContext);
|
||||
gameManagerService.onUserStarting(USER_ID_1);
|
||||
gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_UNSUPPORTED, USER_ID_1);
|
||||
gameManagerService.updateConfigsForUser(USER_ID_1, mPackageName);
|
||||
assertEquals(GameManager.GAME_MODE_STANDARD,
|
||||
gameManagerService.getGameMode(mPackageName, USER_ID_1));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user