summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author jimblackler <jimblackler@google.com> 2022-03-07 14:30:51 +0000
committer jimblackler <jimblackler@google.com> 2022-03-31 20:38:29 +0000
commitac10e4a396d6e3200f0c42f78b0e950472aba94c (patch)
tree00d80d138b88fa6f972ab024f9c292e41335fce0
parent7320750e8db778d85cfd2dcbcc64ceec6ae60e13 (diff)
Add loading boost intervention for games.
Bug: 207845905 Test: atest com.android.server.app.GameManagerServiceTests Change-Id: I2d0b4988797fe21bd7aec6d5351273757ae1a3ce
-rw-r--r--core/java/android/app/GameManager.java15
-rw-r--r--core/java/android/app/IGameManagerService.aidl1
-rw-r--r--core/java/android/os/GraphicsEnvironment.java7
-rw-r--r--services/core/java/com/android/server/app/GameManagerService.java69
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java57
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();