Loading services/core/java/com/android/server/app/GameManagerService.java +76 −17 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } // 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); } if (modeSet.size() > 0) { modeSet.add(GameManager.GAME_MODE_STANDARD); return modeSet.stream().mapToInt(Integer::intValue).toArray(); return field; } return new int[]{GameManager.GAME_MODE_UNSUPPORTED}; /** * 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; } /** Loading Loading @@ -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 */ Loading @@ -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) { Loading @@ -718,13 +748,42 @@ public final class GameManagerService extends IGameManagerService.Stub { } } } for (String packageName : packageNames) { synchronized (mLock) { for (final String packageName : packageNames) { if (mSettings.containsKey(userId)) { GameManagerSettings userSettings = mSettings.get(userId); updateCompatModeDownscale(packageName, userSettings.getGameModeLocked(packageName)); 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) { Loading services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java +56 −4 Original line number Diff line number Diff line Loading @@ -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)); Loading Loading @@ -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); Loading Loading @@ -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)); } } Loading
services/core/java/com/android/server/app/GameManagerService.java +76 −17 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } // 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); } if (modeSet.size() > 0) { modeSet.add(GameManager.GAME_MODE_STANDARD); return modeSet.stream().mapToInt(Integer::intValue).toArray(); return field; } return new int[]{GameManager.GAME_MODE_UNSUPPORTED}; /** * 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; } /** Loading Loading @@ -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 */ Loading @@ -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) { Loading @@ -718,13 +748,42 @@ public final class GameManagerService extends IGameManagerService.Stub { } } } for (String packageName : packageNames) { synchronized (mLock) { for (final String packageName : packageNames) { if (mSettings.containsKey(userId)) { GameManagerSettings userSettings = mSettings.get(userId); updateCompatModeDownscale(packageName, userSettings.getGameModeLocked(packageName)); 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) { Loading
services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java +56 −4 Original line number Diff line number Diff line Loading @@ -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)); Loading Loading @@ -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); Loading Loading @@ -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)); } }