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;
|
||||||
import android.provider.DeviceConfig.Properties;
|
import android.provider.DeviceConfig.Properties;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
import android.util.ArraySet;
|
|
||||||
import android.util.KeyValueListParser;
|
import android.util.KeyValueListParser;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
|
|
||||||
@@ -363,19 +362,42 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
|||||||
|| (mPerfModeOptedIn && gameMode == GameManager.GAME_MODE_PERFORMANCE);
|
|| (mPerfModeOptedIn && gameMode == GameManager.GAME_MODE_PERFORMANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public @GameMode int[] getAvailableGameModes() {
|
private int getAvailableGameModesBitfield() {
|
||||||
ArraySet<Integer> modeSet = new ArraySet<>(mModeConfigs.keySet());
|
int field = 0;
|
||||||
|
for (final int mode : mModeConfigs.keySet()) {
|
||||||
|
field |= modeToBitmask(mode);
|
||||||
|
}
|
||||||
if (mBatteryModeOptedIn) {
|
if (mBatteryModeOptedIn) {
|
||||||
modeSet.add(GameManager.GAME_MODE_BATTERY);
|
field |= modeToBitmask(GameManager.GAME_MODE_BATTERY);
|
||||||
}
|
}
|
||||||
if (mPerfModeOptedIn) {
|
if (mPerfModeOptedIn) {
|
||||||
modeSet.add(GameManager.GAME_MODE_PERFORMANCE);
|
field |= modeToBitmask(GameManager.GAME_MODE_PERFORMANCE);
|
||||||
}
|
}
|
||||||
if (modeSet.size() > 0) {
|
// The lowest bit is reserved for UNSUPPORTED, STANDARD is supported if we support any
|
||||||
modeSet.add(GameManager.GAME_MODE_STANDARD);
|
// other mode.
|
||||||
return modeSet.stream().mapToInt(Integer::intValue).toArray();
|
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
|
* @hide
|
||||||
*/
|
*/
|
||||||
@@ -703,8 +733,8 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
|||||||
public void updateConfigsForUser(int userId, String ...packageNames) {
|
public void updateConfigsForUser(int userId, String ...packageNames) {
|
||||||
try {
|
try {
|
||||||
synchronized (mDeviceConfigLock) {
|
synchronized (mDeviceConfigLock) {
|
||||||
for (String packageName : packageNames) {
|
for (final String packageName : packageNames) {
|
||||||
GamePackageConfiguration config =
|
final GamePackageConfiguration config =
|
||||||
new GamePackageConfiguration(packageName, userId);
|
new GamePackageConfiguration(packageName, userId);
|
||||||
if (config.isValid()) {
|
if (config.isValid()) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
@@ -718,13 +748,42 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (String packageName : packageNames) {
|
for (final String packageName : packageNames) {
|
||||||
synchronized (mLock) {
|
if (mSettings.containsKey(userId)) {
|
||||||
if (mSettings.containsKey(userId)) {
|
int gameMode = getGameMode(packageName, userId);
|
||||||
GameManagerSettings userSettings = mSettings.get(userId);
|
int newGameMode = gameMode;
|
||||||
updateCompatModeDownscale(packageName,
|
// Make sure the user settings and package configs don't conflict. I.e. the
|
||||||
userSettings.getGameModeLocked(packageName));
|
// 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) {
|
} catch (Exception e) {
|
||||||
|
|||||||
@@ -299,11 +299,13 @@ public class GameManagerServiceTests {
|
|||||||
public void testGameMode() {
|
public void testGameMode() {
|
||||||
GameManagerService gameManagerService = new GameManagerService(mMockContext);
|
GameManagerService gameManagerService = new GameManagerService(mMockContext);
|
||||||
gameManagerService.onUserStarting(USER_ID_1);
|
gameManagerService.onUserStarting(USER_ID_1);
|
||||||
|
gameManagerService.updateConfigsForUser(USER_ID_1, mPackageName);
|
||||||
mockModifyGameModeGranted();
|
mockModifyGameModeGranted();
|
||||||
|
|
||||||
assertEquals(GameManager.GAME_MODE_UNSUPPORTED,
|
assertEquals(GameManager.GAME_MODE_UNSUPPORTED,
|
||||||
gameManagerService.getGameMode(mPackageName, USER_ID_1));
|
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);
|
gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_STANDARD, USER_ID_1);
|
||||||
assertEquals(GameManager.GAME_MODE_STANDARD,
|
assertEquals(GameManager.GAME_MODE_STANDARD,
|
||||||
gameManagerService.getGameMode(mPackageName, USER_ID_1));
|
gameManagerService.getGameMode(mPackageName, USER_ID_1));
|
||||||
@@ -370,11 +372,13 @@ public class GameManagerServiceTests {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGameModeMultipleUsers() {
|
public void testGameModeMultipleUsers() {
|
||||||
|
mockModifyGameModeGranted();
|
||||||
|
mockDeviceConfigAll();
|
||||||
GameManagerService gameManagerService = new GameManagerService(mMockContext);
|
GameManagerService gameManagerService = new GameManagerService(mMockContext);
|
||||||
gameManagerService.onUserStarting(USER_ID_1);
|
gameManagerService.onUserStarting(USER_ID_1);
|
||||||
gameManagerService.onUserStarting(USER_ID_2);
|
gameManagerService.onUserStarting(USER_ID_2);
|
||||||
|
gameManagerService.updateConfigsForUser(USER_ID_1, mPackageName);
|
||||||
mockModifyGameModeGranted();
|
gameManagerService.updateConfigsForUser(USER_ID_2, mPackageName);
|
||||||
|
|
||||||
// Set User 1 to Standard
|
// Set User 1 to Standard
|
||||||
gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_STANDARD, USER_ID_1);
|
gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_STANDARD, USER_ID_1);
|
||||||
@@ -603,4 +607,52 @@ public class GameManagerServiceTests {
|
|||||||
gameManagerService.getConfig(mPackageName);
|
gameManagerService.getConfig(mPackageName);
|
||||||
assertNull(config.getGameModeConfiguration(GameManager.GAME_MODE_PERFORMANCE));
|
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