diff options
| author | 2022-03-07 14:30:51 +0000 | |
|---|---|---|
| committer | 2022-03-31 20:38:29 +0000 | |
| commit | ac10e4a396d6e3200f0c42f78b0e950472aba94c (patch) | |
| tree | 00d80d138b88fa6f972ab024f9c292e41335fce0 | |
| parent | 7320750e8db778d85cfd2dcbcc64ceec6ae60e13 (diff) | |
Add loading boost intervention for games.
Bug: 207845905
Test: atest com.android.server.app.GameManagerServiceTests
Change-Id: I2d0b4988797fe21bd7aec6d5351273757ae1a3ce
5 files changed, 148 insertions, 1 deletions
diff --git a/core/java/android/app/GameManager.java b/core/java/android/app/GameManager.java index a138fa1f6fd5..a5adaa4e0196 100644 --- a/core/java/android/app/GameManager.java +++ b/core/java/android/app/GameManager.java @@ -200,6 +200,21 @@ public final class GameManager { } /** + * Set up the automatic power boost if appropriate. + * + * @hide + */ + @RequiresPermission(Manifest.permission.MANAGE_GAME_MODE) + public void notifyGraphicsEnvironmentSetup() { + try { + mService.notifyGraphicsEnvironmentSetup( + mContext.getPackageName(), mContext.getUserId()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * Called by games to communicate the current state to the platform. * @param gameState An object set to the current state. */ diff --git a/core/java/android/app/IGameManagerService.aidl b/core/java/android/app/IGameManagerService.aidl index 7035ac078334..e60a74acdc1c 100644 --- a/core/java/android/app/IGameManagerService.aidl +++ b/core/java/android/app/IGameManagerService.aidl @@ -27,6 +27,7 @@ interface IGameManagerService { void setGameMode(String packageName, int gameMode, int userId); int[] getAvailableGameModes(String packageName); boolean isAngleEnabled(String packageName, int userId); + void notifyGraphicsEnvironmentSetup(String packageName, int userId); void setGameState(String packageName, in GameState gameState, int userId); GameModeInfo getGameModeInfo(String packageName, int userId); void setGameServiceProvider(String packageName); diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java index 0c3514fce76e..c6cf09789899 100644 --- a/core/java/android/os/GraphicsEnvironment.java +++ b/core/java/android/os/GraphicsEnvironment.java @@ -157,6 +157,13 @@ public class GraphicsEnvironment { } } Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS); + + Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "notifyGraphicsEnvironmentSetup"); + if (mGameManager != null + && appInfoWithMetaData.category == ApplicationInfo.CATEGORY_GAME) { + mGameManager.notifyGraphicsEnvironmentSetup(); + } + Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS); } /** diff --git a/services/core/java/com/android/server/app/GameManagerService.java b/services/core/java/com/android/server/app/GameManagerService.java index 4fa1ba1c8158..1c1d72685cf4 100644 --- a/services/core/java/com/android/server/app/GameManagerService.java +++ b/services/core/java/com/android/server/app/GameManagerService.java @@ -572,11 +572,13 @@ public final class GameManagerService extends IGameManagerService.Stub { public static final String DEFAULT_SCALING = "1.0"; public static final String DEFAULT_FPS = ""; public static final String ANGLE_KEY = "useAngle"; + public static final String LOADING_BOOST_KEY = "loadingBoost"; private final @GameMode int mGameMode; private String mScaling; private String mFps; private final boolean mUseAngle; + private final int mLoadingBoostDuration; GameModeConfiguration(KeyValueListParser parser) { mGameMode = parser.getInt(MODE_KEY, GameManager.GAME_MODE_UNSUPPORTED); @@ -595,6 +597,9 @@ public final class GameManagerService extends IGameManagerService.Stub { // - The Phenotype config has enabled it. mUseAngle = mAllowAngle && !willGamePerformOptimizations(mGameMode) && parser.getBoolean(ANGLE_KEY, false); + + mLoadingBoostDuration = willGamePerformOptimizations(mGameMode) ? -1 + : parser.getInt(LOADING_BOOST_KEY, -1); } public int getGameMode() { @@ -613,6 +618,10 @@ public final class GameManagerService extends IGameManagerService.Stub { return mUseAngle; } + public int getLoadingBoostDuration() { + return mLoadingBoostDuration; + } + public void setScaling(String scaling) { mScaling = scaling; } @@ -633,7 +642,8 @@ public final class GameManagerService extends IGameManagerService.Stub { */ public String toString() { return "[Game Mode:" + mGameMode + ",Scaling:" + mScaling + ",Use Angle:" - + mUseAngle + ",Fps:" + mFps + "]"; + + mUseAngle + ",Fps:" + mFps + ",Loading Boost Duration:" + + mLoadingBoostDuration + "]"; } /** @@ -968,6 +978,63 @@ public final class GameManagerService extends IGameManagerService.Stub { } /** + * If loading boost is applicable for the package for the currently enabled game mode, return + * 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); + if (gameMode == GameManager.GAME_MODE_UNSUPPORTED) { + return -1; + } + + synchronized (mDeviceConfigLock) { + final GamePackageConfiguration config = mConfigs.get(packageName); + if (config == null) { + return -1; + } + GamePackageConfiguration.GameModeConfiguration gameModeConfiguration = + config.getGameModeConfiguration(gameMode); + if (gameModeConfiguration == null) { + return -1; + } + return gameModeConfiguration.getLoadingBoostDuration(); + } + } + + /** + * If loading boost is enabled, invoke it. + */ + @Override + @RequiresPermission(Manifest.permission.MANAGE_GAME_MODE) + @GameMode public void notifyGraphicsEnvironmentSetup(String packageName, int userId) + throws SecurityException { + userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), + Binder.getCallingUid(), userId, false, true, "notifyGraphicsEnvironmentSetup", + "com.android.server.app.GameManagerService"); + + // Restrict to games only. + if (!isPackageGame(packageName, userId)) { + return; + } + + if (!isValidPackageName(packageName, userId)) { + return; + } + + final int gameMode = getGameMode(packageName, userId); + if (gameMode == GameManager.GAME_MODE_UNSUPPORTED) { + return; + } + final int loadingBoostDuration = getLoadingBoostDuration(packageName, userId); + if (loadingBoostDuration != -1) { + mPowerManagerInternal.setPowerBoost(Mode.GAME_LOADING, loadingBoostDuration); + } + } + + /** * Sets the game service provider to a given package, meant for testing. * * <p>This setting persists until the next call or until the next reboot. diff --git a/services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java b/services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java index 023608c68ee3..09565b42e515 100644 --- a/services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java +++ b/services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java @@ -231,6 +231,14 @@ public class GameManagerServiceTests { .thenReturn(configString); } + // Loading boost will be disabled for most apps, so treat enabling loading boost as a special + // case. + private void mockDeviceConfigPerformanceEnableLoadingBoost() { + String configString = "mode=2,downscaleFactor=0.5,loadingBoost=0"; + when(DeviceConfig.getProperty(anyString(), anyString())) + .thenReturn(configString); + } + private void mockDeviceConfigBattery() { String configString = "mode=3,downscaleFactor=0.7,fps=30"; when(DeviceConfig.getProperty(anyString(), anyString())) @@ -566,6 +574,21 @@ public class GameManagerServiceTests { assertEquals(gameManagerService.isAngleEnabled(mPackageName, USER_ID_1), angleEnabled); } + private void checkLoadingBoost(GameManagerService gameManagerService, int gameMode, + int loadingBoost) { + gameManagerService.updateConfigsForUser(USER_ID_1, mPackageName); + + // Validate GamePackageConfiguration returns the correct value. + GameManagerService.GamePackageConfiguration config = + gameManagerService.getConfig(mPackageName); + assertEquals( + loadingBoost, config.getGameModeConfiguration(gameMode).getLoadingBoostDuration()); + + // Validate GameManagerService.getLoadingBoostDuration() returns the correct value. + assertEquals( + loadingBoost, gameManagerService.getLoadingBoostDuration(mPackageName, USER_ID_1)); + } + private void checkFps(GameManagerService gameManagerService, int gameMode, int fps) { if (gameManagerService == null) { gameManagerService = new GameManagerService(mMockContext, mTestLooper.getLooper()); @@ -922,6 +945,21 @@ public class GameManagerServiceTests { } /** + * PERFORMANCE game mode is configured through Phenotype. The app hasn't specified any + * metadata. + */ + @Test + public void testInterventionAllowLoadingBoostDefault() throws Exception { + GameManagerService gameManagerService = new GameManagerService( + mMockContext, mTestLooper.getLooper()); + + startUser(gameManagerService, USER_ID_1); + mockDeviceConfigPerformance(); + mockModifyGameModeGranted(); + checkLoadingBoost(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, -1); + } + + /** * PERFORMANCE game mode is configured through Phenotype. The app has opted-out of ANGLE. */ @Test @@ -955,6 +993,25 @@ public class GameManagerServiceTests { checkAngleEnabled(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, true); } + /** + * PERFORMANCE game mode is configured through Phenotype. The app has redundantly specified the + * Loading Boost metadata default value of "true". + */ + @Test + public void testInterventionAllowLoadingBoost() throws Exception { + mockDeviceConfigPerformanceEnableLoadingBoost(); + + GameManagerService gameManagerService = + new GameManagerService(mMockContext, mTestLooper.getLooper()); + startUser(gameManagerService, USER_ID_1); + mockModifyGameModeGranted(); + gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE, USER_ID_1); + assertEquals(GameManager.GAME_MODE_PERFORMANCE, + gameManagerService.getGameMode(mPackageName, USER_ID_1)); + mockInterventionsEnabledFromXml(); + checkLoadingBoost(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 0); + } + @Test public void testGameModeConfigAllowFpsTrue() throws Exception { mockDeviceConfigAll(); |