summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/app/GameManagerService.java293
-rw-r--r--services/tests/mockingservicestests/res/xml/game_manager_service_metadata_config_interventions_disabled_all_opt_in.xml9
-rw-r--r--services/tests/mockingservicestests/res/xml/game_manager_service_metadata_config_interventions_disabled_no_opt_in.xml (renamed from services/tests/mockingservicestests/res/xml/gama_manager_service_metadata_config_disabled.xml)0
-rw-r--r--services/tests/mockingservicestests/res/xml/game_manager_service_metadata_config_interventions_enabled_all_opt_in.xml9
-rw-r--r--services/tests/mockingservicestests/res/xml/game_manager_service_metadata_config_interventions_enabled_no_opt_in.xml (renamed from services/tests/mockingservicestests/res/xml/gama_manager_service_metadata_config_enabled.xml)0
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java238
6 files changed, 385 insertions, 164 deletions
diff --git a/services/core/java/com/android/server/app/GameManagerService.java b/services/core/java/com/android/server/app/GameManagerService.java
index 15c569e246f7..4013acefa366 100644
--- a/services/core/java/com/android/server/app/GameManagerService.java
+++ b/services/core/java/com/android/server/app/GameManagerService.java
@@ -117,6 +117,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
/**
* Service to manage game related features.
@@ -333,7 +334,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
removeMessages(POPULATE_GAME_MODE_SETTINGS, msg.obj);
final int userId = (int) msg.obj;
final String[] packageNames = getInstalledGamePackageNames(userId);
- updateConfigsForUser(userId, packageNames);
+ updateConfigsForUser(userId, false /*checkGamePackage*/, packageNames);
break;
}
case SET_GAME_STATE: {
@@ -402,7 +403,8 @@ public final class GameManagerService extends IGameManagerService.Stub {
@Override
public void onPropertiesChanged(Properties properties) {
final String[] packageNames = properties.getKeyset().toArray(new String[0]);
- updateConfigsForUser(ActivityManager.getCurrentUser(), packageNames);
+ updateConfigsForUser(ActivityManager.getCurrentUser(), true /*checkGamePackage*/,
+ packageNames);
}
@Override
@@ -553,16 +555,23 @@ public final class GameManagerService extends IGameManagerService.Stub {
private static final String GAME_MODE_CONFIG_NODE_NAME = "game-mode-config";
private final String mPackageName;
- private final ArrayMap<Integer, GameModeConfiguration> mModeConfigs;
+ private final Object mModeConfigLock = new Object();
+ @GuardedBy("mModeConfigLock")
+ private final ArrayMap<Integer, GameModeConfiguration> mModeConfigs = new ArrayMap<>();
+ // if adding new properties or make any of the below overridable, the method
+ // copyAndApplyOverride should be updated accordingly
private boolean mPerfModeOptedIn = false;
private boolean mBatteryModeOptedIn = false;
private boolean mAllowDownscale = true;
private boolean mAllowAngle = true;
private boolean mAllowFpsOverride = true;
+ GamePackageConfiguration(String packageName) {
+ mPackageName = packageName;
+ }
+
GamePackageConfiguration(String packageName, int userId) {
mPackageName = packageName;
- mModeConfigs = new ArrayMap<>();
try {
final ApplicationInfo ai = mPackageManager.getApplicationInfoAsUser(packageName,
@@ -646,6 +655,13 @@ public final class GameManagerService extends IGameManagerService.Stub {
return xmlFound;
}
+ GameModeConfiguration getOrAddDefaultGameModeConfiguration(int gameMode) {
+ synchronized (mModeConfigLock) {
+ mModeConfigs.putIfAbsent(gameMode, new GameModeConfiguration(gameMode));
+ return mModeConfigs.get(gameMode);
+ }
+ }
+
/**
* GameModeConfiguration contains all the values for all the interventions associated with
* a game mode.
@@ -658,15 +674,23 @@ public final class GameManagerService extends IGameManagerService.Stub {
public static final String FPS_KEY = "fps";
public static final String DEFAULT_SCALING = "1.0";
public static final String DEFAULT_FPS = "";
+ public static final boolean DEFAULT_USE_ANGLE = false;
+ public static final int DEFAULT_LOADING_BOOST_DURATION = -1;
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 String mScaling = DEFAULT_SCALING;
+ private String mFps = DEFAULT_FPS;
private final boolean mUseAngle;
private final int mLoadingBoostDuration;
+ GameModeConfiguration(int gameMode) {
+ mGameMode = gameMode;
+ mUseAngle = DEFAULT_USE_ANGLE;
+ mLoadingBoostDuration = DEFAULT_LOADING_BOOST_DURATION;
+ }
+
GameModeConfiguration(KeyValueListParser parser) {
mGameMode = parser.getInt(MODE_KEY, GameManager.GAME_MODE_UNSUPPORTED);
// isGameModeOptedIn() returns if an app will handle all of the changes necessary
@@ -693,11 +717,11 @@ public final class GameManagerService extends IGameManagerService.Stub {
return mGameMode;
}
- public String getScaling() {
+ public synchronized String getScaling() {
return mScaling;
}
- public int getFps() {
+ public synchronized int getFps() {
return GameManagerService.getFpsInt(mFps);
}
@@ -709,15 +733,15 @@ public final class GameManagerService extends IGameManagerService.Stub {
return mLoadingBoostDuration;
}
- public void setScaling(String scaling) {
+ public synchronized void setScaling(String scaling) {
mScaling = scaling;
}
- public void setFpsStr(String fpsStr) {
+ public synchronized void setFpsStr(String fpsStr) {
mFps = fpsStr;
}
- public boolean isValid() {
+ public boolean isActive() {
return (mGameMode == GameManager.GAME_MODE_STANDARD
|| mGameMode == GameManager.GAME_MODE_PERFORMANCE
|| mGameMode == GameManager.GAME_MODE_BATTERY)
@@ -760,8 +784,10 @@ public final class GameManagerService extends IGameManagerService.Stub {
private int getAvailableGameModesBitfield() {
int field = 0;
- for (final int mode : mModeConfigs.keySet()) {
- field |= modeToBitmask(mode);
+ synchronized (mModeConfigLock) {
+ for (final int mode : mModeConfigs.keySet()) {
+ field |= modeToBitmask(mode);
+ }
}
if (mBatteryModeOptedIn) {
field |= modeToBitmask(GameManager.GAME_MODE_BATTERY);
@@ -802,27 +828,71 @@ public final class GameManagerService extends IGameManagerService.Stub {
* @return The package's GameModeConfiguration for the provided mode or null if absent
*/
public GameModeConfiguration getGameModeConfiguration(@GameMode int gameMode) {
- return mModeConfigs.get(gameMode);
+ synchronized (mModeConfigLock) {
+ return mModeConfigs.get(gameMode);
+ }
}
/**
* Insert a new GameModeConfiguration
*/
public void addModeConfig(GameModeConfiguration config) {
- if (config.isValid()) {
- mModeConfigs.put(config.getGameMode(), config);
+ if (config.isActive()) {
+ synchronized (mModeConfigLock) {
+ mModeConfigs.put(config.getGameMode(), config);
+ }
} else {
- Slog.w(TAG, "Invalid game mode config for "
+ Slog.w(TAG, "Attempt to add inactive game mode config for "
+ mPackageName + ":" + config.toString());
}
}
- public boolean isValid() {
- return mModeConfigs.size() > 0 || mBatteryModeOptedIn || mPerfModeOptedIn;
+ public boolean isActive() {
+ synchronized (mModeConfigLock) {
+ return mModeConfigs.size() > 0 || mBatteryModeOptedIn || mPerfModeOptedIn;
+ }
+ }
+
+ GamePackageConfiguration copyAndApplyOverride(GamePackageConfiguration overrideConfig) {
+ GamePackageConfiguration copy = new GamePackageConfiguration(mPackageName);
+ // if a game mode is overridden, we treat it with the highest priority and reset any
+ // opt-in game modes so that interventions are always executed.
+ copy.mPerfModeOptedIn = mPerfModeOptedIn && !(overrideConfig != null
+ && overrideConfig.getGameModeConfiguration(GameManager.GAME_MODE_PERFORMANCE)
+ != null);
+ copy.mBatteryModeOptedIn = mBatteryModeOptedIn && !(overrideConfig != null
+ && overrideConfig.getGameModeConfiguration(GameManager.GAME_MODE_BATTERY)
+ != null);
+
+ // if any game mode is overridden, we will consider all interventions forced-active,
+ // this can be done more granular by checking if a specific intervention is
+ // overridden under each game mode override, but only if necessary.
+ copy.mAllowDownscale = mAllowDownscale || overrideConfig != null;
+ copy.mAllowAngle = mAllowAngle || overrideConfig != null;
+ copy.mAllowFpsOverride = mAllowFpsOverride || overrideConfig != null;
+ if (overrideConfig != null) {
+ synchronized (copy.mModeConfigLock) {
+ synchronized (mModeConfigLock) {
+ for (Map.Entry<Integer, GameModeConfiguration> entry :
+ mModeConfigs.entrySet()) {
+ copy.mModeConfigs.put(entry.getKey(), entry.getValue());
+ }
+ }
+ synchronized (overrideConfig.mModeConfigLock) {
+ for (Map.Entry<Integer, GameModeConfiguration> entry :
+ overrideConfig.mModeConfigs.entrySet()) {
+ copy.mModeConfigs.put(entry.getKey(), entry.getValue());
+ }
+ }
+ }
+ }
+ return copy;
}
public String toString() {
- return "[Name:" + mPackageName + " Modes: " + mModeConfigs.toString() + "]";
+ synchronized (mModeConfigLock) {
+ return "[Name:" + mPackageName + " Modes: " + mModeConfigs.toString() + "]";
+ }
}
}
@@ -893,15 +963,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
}
private @GameMode int[] getAvailableGameModesUnchecked(String packageName) {
- GamePackageConfiguration config = null;
- synchronized (mOverrideConfigLock) {
- config = mOverrideConfigs.get(packageName);
- }
- if (config == null) {
- synchronized (mDeviceConfigLock) {
- config = mConfigs.get(packageName);
- }
- }
+ final GamePackageConfiguration config = getConfig(packageName);
if (config == null) {
return new int[]{};
}
@@ -1054,19 +1116,19 @@ public final class GameManagerService extends IGameManagerService.Stub {
if (gameMode == GameManager.GAME_MODE_UNSUPPORTED) {
return false;
}
-
+ final GamePackageConfiguration config;
synchronized (mDeviceConfigLock) {
- final GamePackageConfiguration config = mConfigs.get(packageName);
+ config = mConfigs.get(packageName);
if (config == null) {
return false;
}
- GamePackageConfiguration.GameModeConfiguration gameModeConfiguration =
- config.getGameModeConfiguration(gameMode);
- if (gameModeConfiguration == null) {
- return false;
- }
- return gameModeConfiguration.getUseAngle();
}
+ GamePackageConfiguration.GameModeConfiguration gameModeConfiguration =
+ config.getGameModeConfiguration(gameMode);
+ if (gameModeConfiguration == null) {
+ return false;
+ }
+ return gameModeConfiguration.getUseAngle();
}
/**
@@ -1081,19 +1143,19 @@ public final class GameManagerService extends IGameManagerService.Stub {
if (gameMode == GameManager.GAME_MODE_UNSUPPORTED) {
return -1;
}
-
+ final GamePackageConfiguration config;
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();
+ config = mConfigs.get(packageName);
+ }
+ if (config == null) {
+ return -1;
+ }
+ GamePackageConfiguration.GameModeConfiguration gameModeConfiguration =
+ config.getGameModeConfiguration(gameMode);
+ if (gameModeConfiguration == null) {
+ return -1;
}
+ return gameModeConfiguration.getLoadingBoostDuration();
}
/**
@@ -1262,7 +1324,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
try {
final float fps = 0.0f;
final int uid = mPackageManager.getPackageUidAsUser(packageName, userId);
- nativeSetOverrideFrameRate(uid, fps);
+ setOverrideFrameRate(uid, fps);
} catch (PackageManager.NameNotFoundException e) {
return;
}
@@ -1348,7 +1410,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
try {
final float fps = modeConfig.getFps();
final int uid = mPackageManager.getPackageUidAsUser(packageName, userId);
- nativeSetOverrideFrameRate(uid, fps);
+ setOverrideFrameRate(uid, fps);
} catch (PackageManager.NameNotFoundException e) {
return;
}
@@ -1357,32 +1419,17 @@ public final class GameManagerService extends IGameManagerService.Stub {
private void updateInterventions(String packageName,
@GameMode int gameMode, @UserIdInt int userId) {
+ final GamePackageConfiguration packageConfig = getConfig(packageName);
if (gameMode == GameManager.GAME_MODE_STANDARD
- || gameMode == GameManager.GAME_MODE_UNSUPPORTED) {
+ || gameMode == GameManager.GAME_MODE_UNSUPPORTED || packageConfig == null
+ || packageConfig.willGamePerformOptimizations(gameMode)) {
disableCompatScale(packageName);
resetFps(packageName, userId);
- return;
- }
- GamePackageConfiguration packageConfig = null;
-
- synchronized (mOverrideConfigLock) {
- packageConfig = mOverrideConfigs.get(packageName);
- }
-
- if (packageConfig == null) {
- synchronized (mDeviceConfigLock) {
- packageConfig = mConfigs.get(packageName);
+ if (packageConfig == null) {
+ Slog.v(TAG, "Package configuration not found for " + packageName);
+ return;
}
}
-
- if (packageConfig == null) {
- disableCompatScale(packageName);
- Slog.v(TAG, "Package configuration not found for " + packageName);
- return;
- }
- if (packageConfig.willGamePerformOptimizations(gameMode)) {
- return;
- }
updateCompatModeDownscale(packageConfig, packageName, gameMode);
updateFps(packageConfig, packageName, gameMode, userId);
updateUseAngle(packageName, gameMode);
@@ -1403,34 +1450,34 @@ public final class GameManagerService extends IGameManagerService.Stub {
}
}
// Adding override game mode configuration of the given package name
+ GamePackageConfiguration overrideConfig;
synchronized (mOverrideConfigLock) {
// look for the existing override GamePackageConfiguration
- GamePackageConfiguration overrideConfig = mOverrideConfigs.get(packageName);
+ overrideConfig = mOverrideConfigs.get(packageName);
if (overrideConfig == null) {
- overrideConfig = new GamePackageConfiguration(packageName, userId);
+ overrideConfig = new GamePackageConfiguration(packageName);
mOverrideConfigs.put(packageName, overrideConfig);
}
+ }
+ // modify GameModeConfiguration intervention settings
+ GamePackageConfiguration.GameModeConfiguration overrideModeConfig =
+ overrideConfig.getOrAddDefaultGameModeConfiguration(gameMode);
- // modify GameModeConfiguration intervention settings
- GamePackageConfiguration.GameModeConfiguration overrideModeConfig =
- overrideConfig.getGameModeConfiguration(gameMode);
-
- if (fpsStr != null) {
- overrideModeConfig.setFpsStr(fpsStr);
- } else {
- overrideModeConfig.setFpsStr(
- GamePackageConfiguration.GameModeConfiguration.DEFAULT_FPS);
- }
- if (scaling != null) {
- overrideModeConfig.setScaling(scaling);
- } else {
- overrideModeConfig.setScaling(
- GamePackageConfiguration.GameModeConfiguration.DEFAULT_SCALING);
- }
- Slog.i(TAG, "Package Name: " + packageName
- + " FPS: " + String.valueOf(overrideModeConfig.getFps())
- + " Scaling: " + overrideModeConfig.getScaling());
+ if (fpsStr != null) {
+ overrideModeConfig.setFpsStr(fpsStr);
+ } else {
+ overrideModeConfig.setFpsStr(
+ GamePackageConfiguration.GameModeConfiguration.DEFAULT_FPS);
}
+ if (scaling != null) {
+ overrideModeConfig.setScaling(scaling);
+ } else {
+ overrideModeConfig.setScaling(
+ GamePackageConfiguration.GameModeConfiguration.DEFAULT_SCALING);
+ }
+ Slog.i(TAG, "Package Name: " + packageName
+ + " FPS: " + String.valueOf(overrideModeConfig.getFps())
+ + " Scaling: " + overrideModeConfig.getScaling());
setGameMode(packageName, gameMode, userId);
}
@@ -1496,15 +1543,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
// If not, set the game mode to standard
int gameMode = getGameMode(packageName, userId);
- GamePackageConfiguration config = null;
- synchronized (mOverrideConfigLock) {
- config = mOverrideConfigs.get(packageName);
- }
- if (config == null) {
- synchronized (mDeviceConfigLock) {
- config = mConfigs.get(packageName);
- }
- }
+ final GamePackageConfiguration config = getConfig(packageName);
final int newGameMode = getNewGameMode(gameMode, config);
if (gameMode != newGameMode) {
setGameMode(packageName, GameManager.GAME_MODE_STANDARD, userId);
@@ -1543,18 +1582,8 @@ public final class GameManagerService extends IGameManagerService.Stub {
* Returns the string listing all the interventions currently set to a game.
*/
public String getInterventionList(String packageName) {
- GamePackageConfiguration packageConfig = null;
- synchronized (mOverrideConfigLock) {
- packageConfig = mOverrideConfigs.get(packageName);
- }
-
- if (packageConfig == null) {
- synchronized (mDeviceConfigLock) {
- packageConfig = mConfigs.get(packageName);
- }
- }
-
- StringBuilder listStrSb = new StringBuilder();
+ final GamePackageConfiguration packageConfig = getConfig(packageName);
+ final StringBuilder listStrSb = new StringBuilder();
if (packageConfig == null) {
listStrSb.append("\n No intervention found for package ")
.append(packageName);
@@ -1569,20 +1598,27 @@ public final class GameManagerService extends IGameManagerService.Stub {
* @hide
*/
@VisibleForTesting
- void updateConfigsForUser(@UserIdInt int userId, String... packageNames) {
+ void updateConfigsForUser(@UserIdInt int userId, boolean checkGamePackage,
+ String... packageNames) {
+ if (checkGamePackage) {
+ packageNames = Arrays.stream(packageNames).filter(
+ p -> isPackageGame(p, userId)).toArray(String[]::new);
+ }
try {
synchronized (mDeviceConfigLock) {
for (final String packageName : packageNames) {
final GamePackageConfiguration config =
new GamePackageConfiguration(packageName, userId);
- if (config.isValid()) {
+ if (config.isActive()) {
if (DEBUG) {
Slog.i(TAG, "Adding config: " + config.toString());
}
mConfigs.put(packageName, config);
} else {
- Slog.w(TAG, "Invalid package config for "
- + config.getPackageName() + ":" + config.toString());
+ if (DEBUG) {
+ Slog.w(TAG, "Inactive package config for "
+ + config.getPackageName() + ":" + config.toString());
+ }
mConfigs.remove(packageName);
}
}
@@ -1721,16 +1757,18 @@ public final class GameManagerService extends IGameManagerService.Stub {
*/
@VisibleForTesting
public GamePackageConfiguration getConfig(String packageName) {
- GamePackageConfiguration packageConfig = null;
+ GamePackageConfiguration overrideConfig = null;
+ GamePackageConfiguration config;
+ synchronized (mDeviceConfigLock) {
+ config = mConfigs.get(packageName);
+ }
synchronized (mOverrideConfigLock) {
- packageConfig = mOverrideConfigs.get(packageName);
+ overrideConfig = mOverrideConfigs.get(packageName);
}
- if (packageConfig == null) {
- synchronized (mDeviceConfigLock) {
- packageConfig = mConfigs.get(packageName);
- }
+ if (overrideConfig == null || config == null) {
+ return overrideConfig == null ? config : overrideConfig;
}
- return packageConfig;
+ return config.copyAndApplyOverride(overrideConfig);
}
private void registerPackageReceiver() {
@@ -1760,7 +1798,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
}
switch (intent.getAction()) {
case ACTION_PACKAGE_ADDED:
- updateConfigsForUser(userId, packageName);
+ updateConfigsForUser(userId, true /*checkGamePackage*/, packageName);
break;
case ACTION_PACKAGE_REMOVED:
disableCompatScale(packageName);
@@ -1834,6 +1872,11 @@ public final class GameManagerService extends IGameManagerService.Stub {
return handlerThread;
}
+ @VisibleForTesting
+ void setOverrideFrameRate(int uid, float frameRate) {
+ nativeSetOverrideFrameRate(uid, frameRate);
+ }
+
/**
* load dynamic library for frame rate overriding JNI calls
*/
diff --git a/services/tests/mockingservicestests/res/xml/game_manager_service_metadata_config_interventions_disabled_all_opt_in.xml b/services/tests/mockingservicestests/res/xml/game_manager_service_metadata_config_interventions_disabled_all_opt_in.xml
new file mode 100644
index 000000000000..77fe786f812f
--- /dev/null
+++ b/services/tests/mockingservicestests/res/xml/game_manager_service_metadata_config_interventions_disabled_all_opt_in.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<game-mode-config
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:supportsPerformanceGameMode="true"
+ android:supportsBatteryGameMode="true"
+ android:allowGameAngleDriver="false"
+ android:allowGameDownscaling="false"
+ android:allowGameFpsOverride="false"
+/> \ No newline at end of file
diff --git a/services/tests/mockingservicestests/res/xml/gama_manager_service_metadata_config_disabled.xml b/services/tests/mockingservicestests/res/xml/game_manager_service_metadata_config_interventions_disabled_no_opt_in.xml
index eb154518c911..eb154518c911 100644
--- a/services/tests/mockingservicestests/res/xml/gama_manager_service_metadata_config_disabled.xml
+++ b/services/tests/mockingservicestests/res/xml/game_manager_service_metadata_config_interventions_disabled_no_opt_in.xml
diff --git a/services/tests/mockingservicestests/res/xml/game_manager_service_metadata_config_interventions_enabled_all_opt_in.xml b/services/tests/mockingservicestests/res/xml/game_manager_service_metadata_config_interventions_enabled_all_opt_in.xml
new file mode 100644
index 000000000000..96d28785ba0a
--- /dev/null
+++ b/services/tests/mockingservicestests/res/xml/game_manager_service_metadata_config_interventions_enabled_all_opt_in.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<game-mode-config
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:supportsPerformanceGameMode="true"
+ android:supportsBatteryGameMode="true"
+ android:allowGameAngleDriver="true"
+ android:allowGameDownscaling="true"
+ android:allowGameFpsOverride="true"
+/> \ No newline at end of file
diff --git a/services/tests/mockingservicestests/res/xml/gama_manager_service_metadata_config_enabled.xml b/services/tests/mockingservicestests/res/xml/game_manager_service_metadata_config_interventions_enabled_no_opt_in.xml
index 65b7467b80f5..65b7467b80f5 100644
--- a/services/tests/mockingservicestests/res/xml/gama_manager_service_metadata_config_enabled.xml
+++ b/services/tests/mockingservicestests/res/xml/game_manager_service_metadata_config_interventions_enabled_no_opt_in.xml
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 d675b0aa4973..cfb80148f166 100644
--- a/services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java
@@ -19,6 +19,7 @@ package com.android.server.app;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
@@ -67,7 +68,9 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentMatchers;
import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.MockitoSession;
import org.mockito.quality.Strictness;
@@ -87,6 +90,7 @@ public class GameManagerServiceTests {
private static final String PACKAGE_NAME_INVALID = "com.android.app";
private static final int USER_ID_1 = 1001;
private static final int USER_ID_2 = 1002;
+ private static final int DEFAULT_PACKAGE_UID = 12345;
private MockitoSession mMockingSession;
private String mPackageName;
@@ -194,6 +198,8 @@ public class GameManagerServiceTests {
.thenReturn(packages);
when(mMockPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
.thenReturn(applicationInfo);
+ when(mMockPackageManager.getPackageUidAsUser(mPackageName, USER_ID_1)).thenReturn(
+ DEFAULT_PACKAGE_UID);
LocalServices.addService(PowerManagerInternal.class, mMockPowerManager);
}
@@ -369,38 +375,41 @@ public class GameManagerServiceTests {
.thenReturn(applicationInfo);
}
- private void mockInterventionsEnabledFromXml() throws Exception {
- final ApplicationInfo applicationInfo = mMockPackageManager.getApplicationInfoAsUser(
- mPackageName, PackageManager.GET_META_DATA, USER_ID_1);
- Bundle metaDataBundle = new Bundle();
- final int resId = 123;
- metaDataBundle.putInt(
- GameManagerService.GamePackageConfiguration.METADATA_GAME_MODE_CONFIG, resId);
- applicationInfo.metaData = metaDataBundle;
- when(mMockPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
- .thenReturn(applicationInfo);
- seedGameManagerServiceMetaDataFromFile(mPackageName, resId,
- "res/xml/gama_manager_service_metadata_config_enabled.xml");
+ private void mockInterventionsEnabledNoOptInFromXml() throws Exception {
+ seedGameManagerServiceMetaDataFromFile(mPackageName, 123,
+ "res/xml/game_manager_service_metadata_config_interventions_enabled_no_opt_in.xml");
+ }
+
+ private void mockInterventionsEnabledAllOptInFromXml() throws Exception {
+ seedGameManagerServiceMetaDataFromFile(mPackageName, 123,
+ "res/xml/game_manager_service_metadata_config_interventions_enabled_all_opt_in"
+ + ".xml");
+ }
+
+ private void mockInterventionsDisabledNoOptInFromXml() throws Exception {
+ seedGameManagerServiceMetaDataFromFile(mPackageName, 123,
+ "res/xml/game_manager_service_metadata_config_interventions_disabled_no_opt_in"
+ + ".xml");
+ }
+
+ private void mockInterventionsDisabledAllOptInFromXml() throws Exception {
+ seedGameManagerServiceMetaDataFromFile(mPackageName, 123,
+ "res/xml/game_manager_service_metadata_config_interventions_disabled_all_opt_in"
+ + ".xml");
}
- private void mockInterventionsDisabledFromXml() throws Exception {
+
+ private void seedGameManagerServiceMetaDataFromFile(String packageName, int resId,
+ String fileName)
+ throws Exception {
final ApplicationInfo applicationInfo = mMockPackageManager.getApplicationInfoAsUser(
mPackageName, PackageManager.GET_META_DATA, USER_ID_1);
Bundle metaDataBundle = new Bundle();
- final int resId = 123;
metaDataBundle.putInt(
GameManagerService.GamePackageConfiguration.METADATA_GAME_MODE_CONFIG, resId);
applicationInfo.metaData = metaDataBundle;
when(mMockPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
.thenReturn(applicationInfo);
- seedGameManagerServiceMetaDataFromFile(mPackageName, resId,
- "res/xml/gama_manager_service_metadata_config_disabled.xml");
- }
-
-
- private void seedGameManagerServiceMetaDataFromFile(String packageName, int resId,
- String fileName)
- throws Exception {
AssetManager assetManager =
InstrumentationRegistry.getInstrumentation().getContext().getAssets();
XmlResourceParser xmlResourceParser =
@@ -450,13 +459,13 @@ public class GameManagerServiceTests {
startUser(gameManagerService, USER_ID_1);
- gameManagerService.updateConfigsForUser(USER_ID_1, mPackageName);
+ gameManagerService.updateConfigsForUser(USER_ID_1, true, 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.updateConfigsForUser(USER_ID_1, true, mPackageName);
gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_STANDARD, USER_ID_1);
assertEquals(GameManager.GAME_MODE_STANDARD,
gameManagerService.getGameMode(mPackageName, USER_ID_1));
@@ -534,8 +543,8 @@ public class GameManagerServiceTests {
startUser(gameManagerService, USER_ID_1);
startUser(gameManagerService, USER_ID_2);
- gameManagerService.updateConfigsForUser(USER_ID_1, mPackageName);
- gameManagerService.updateConfigsForUser(USER_ID_2, mPackageName);
+ gameManagerService.updateConfigsForUser(USER_ID_1, true, mPackageName);
+ gameManagerService.updateConfigsForUser(USER_ID_2, true, mPackageName);
// Set User 1 to Standard
gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_STANDARD, USER_ID_1);
@@ -563,7 +572,7 @@ public class GameManagerServiceTests {
if (gameManagerService == null) {
gameManagerService = new GameManagerService(mMockContext, mTestLooper.getLooper());
startUser(gameManagerService, USER_ID_1);
- gameManagerService.updateConfigsForUser(USER_ID_1, mPackageName);
+ gameManagerService.updateConfigsForUser(USER_ID_1, true, mPackageName);
}
ArraySet<Integer> reportedModes = new ArraySet<>();
int[] modes = gameManagerService.getAvailableGameModes(mPackageName);
@@ -582,7 +591,7 @@ public class GameManagerServiceTests {
if (gameManagerService == null) {
gameManagerService = new GameManagerService(mMockContext, mTestLooper.getLooper());
startUser(gameManagerService, USER_ID_1);
- gameManagerService.updateConfigsForUser(USER_ID_1, mPackageName);
+ gameManagerService.updateConfigsForUser(USER_ID_1, true, mPackageName);
}
GameManagerService.GamePackageConfiguration config =
gameManagerService.getConfig(mPackageName);
@@ -591,7 +600,7 @@ public class GameManagerServiceTests {
private void checkAngleEnabled(GameManagerService gameManagerService, int gameMode,
boolean angleEnabled) {
- gameManagerService.updateConfigsForUser(USER_ID_1, mPackageName);
+ gameManagerService.updateConfigsForUser(USER_ID_1, true, mPackageName);
// Validate GamePackageConfiguration returns the correct value.
GameManagerService.GamePackageConfiguration config =
@@ -604,7 +613,7 @@ public class GameManagerServiceTests {
private void checkLoadingBoost(GameManagerService gameManagerService, int gameMode,
int loadingBoost) {
- gameManagerService.updateConfigsForUser(USER_ID_1, mPackageName);
+ gameManagerService.updateConfigsForUser(USER_ID_1, true, mPackageName);
// Validate GamePackageConfiguration returns the correct value.
GameManagerService.GamePackageConfiguration config =
@@ -621,13 +630,19 @@ public class GameManagerServiceTests {
if (gameManagerService == null) {
gameManagerService = new GameManagerService(mMockContext, mTestLooper.getLooper());
startUser(gameManagerService, USER_ID_1);
- gameManagerService.updateConfigsForUser(USER_ID_1, mPackageName);
+ gameManagerService.updateConfigsForUser(USER_ID_1, true, mPackageName);
}
GameManagerService.GamePackageConfiguration config =
gameManagerService.getConfig(mPackageName);
assertEquals(fps, config.getGameModeConfiguration(gameMode).getFps());
}
+ private boolean checkOptedIn(GameManagerService gameManagerService, int gameMode) {
+ GameManagerService.GamePackageConfiguration config =
+ gameManagerService.getConfig(mPackageName);
+ return config.willGamePerformOptimizations(gameMode);
+ }
+
/**
* Phenotype device config exists, but is only propagating the default value.
*/
@@ -743,7 +758,7 @@ public class GameManagerServiceTests {
* Override device configs for both battery and performance modes exists and are valid.
*/
@Test
- public void testSetDeviceOverrideConfigAll() {
+ public void testSetDeviceConfigOverrideAll() {
mockDeviceConfigAll();
mockModifyGameModeGranted();
@@ -763,6 +778,75 @@ public class GameManagerServiceTests {
checkFps(gameManagerService, GameManager.GAME_MODE_BATTERY, 60);
}
+ @Test
+ public void testSetBatteryModeConfigOverride_thenUpdateAllDeviceConfig() throws Exception {
+ mockModifyGameModeGranted();
+ String configStringBefore =
+ "mode=2,downscaleFactor=1.0,fps=90:mode=3,downscaleFactor=0.1,fps=30";
+ when(DeviceConfig.getProperty(anyString(), anyString()))
+ .thenReturn(configStringBefore);
+ mockInterventionsEnabledNoOptInFromXml();
+ GameManagerService gameManagerService = new GameManagerService(mMockContext,
+ mTestLooper.getLooper());
+ startUser(gameManagerService, USER_ID_1);
+
+ checkDownscaling(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, "1.0");
+ checkFps(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 90);
+ checkDownscaling(gameManagerService, GameManager.GAME_MODE_BATTERY, "0.1");
+ checkFps(gameManagerService, GameManager.GAME_MODE_BATTERY, 30);
+
+ gameManagerService.setGameModeConfigOverride(mPackageName, USER_ID_1, 3, "40",
+ "0.2");
+
+ checkFps(gameManagerService, GameManager.GAME_MODE_BATTERY, 40);
+ checkDownscaling(gameManagerService, GameManager.GAME_MODE_BATTERY, "0.2");
+
+ String configStringAfter =
+ "mode=2,downscaleFactor=0.9,fps=60:mode=3,downscaleFactor=0.3,fps=50";
+ when(DeviceConfig.getProperty(anyString(), anyString()))
+ .thenReturn(configStringAfter);
+ gameManagerService.updateConfigsForUser(USER_ID_1, false, mPackageName);
+
+ // performance mode was not overridden thus it should be updated
+ checkDownscaling(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, "0.9");
+ checkFps(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 60);
+
+ // battery mode was overridden thus it should be the same as the override
+ checkDownscaling(gameManagerService, GameManager.GAME_MODE_BATTERY, "0.2");
+ checkFps(gameManagerService, GameManager.GAME_MODE_BATTERY, 40);
+ }
+
+ @Test
+ public void testSetBatteryModeConfigOverride_thenOptInBatteryMode() throws Exception {
+ mockModifyGameModeGranted();
+ String configStringBefore =
+ "mode=2,downscaleFactor=1.0,fps=90:mode=3,downscaleFactor=0.1,fps=30";
+ when(DeviceConfig.getProperty(anyString(), anyString()))
+ .thenReturn(configStringBefore);
+ mockInterventionsDisabledNoOptInFromXml();
+ GameManagerService gameManagerService = new GameManagerService(mMockContext,
+ mTestLooper.getLooper());
+ startUser(gameManagerService, USER_ID_1);
+
+ assertFalse(checkOptedIn(gameManagerService, GameManager.GAME_MODE_PERFORMANCE));
+ assertFalse(checkOptedIn(gameManagerService, GameManager.GAME_MODE_BATTERY));
+ checkFps(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 0);
+
+ gameManagerService.setGameModeConfigOverride(mPackageName, USER_ID_1, 3, "40",
+ "0.2");
+ checkFps(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 0);
+ // override will enable the interventions
+ checkDownscaling(gameManagerService, GameManager.GAME_MODE_BATTERY, "0.2");
+ checkFps(gameManagerService, GameManager.GAME_MODE_BATTERY, 40);
+
+ mockInterventionsDisabledAllOptInFromXml();
+ gameManagerService.updateConfigsForUser(USER_ID_1, false, mPackageName);
+
+ assertTrue(checkOptedIn(gameManagerService, GameManager.GAME_MODE_PERFORMANCE));
+ // opt-in is still false for battery mode as override exists
+ assertFalse(checkOptedIn(gameManagerService, GameManager.GAME_MODE_BATTERY));
+ }
+
/**
* Override device config for performance mode exists and is valid.
*/
@@ -1037,7 +1121,7 @@ public class GameManagerServiceTests {
gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE, USER_ID_1);
assertEquals(GameManager.GAME_MODE_PERFORMANCE,
gameManagerService.getGameMode(mPackageName, USER_ID_1));
- mockInterventionsEnabledFromXml();
+ mockInterventionsEnabledNoOptInFromXml();
checkLoadingBoost(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 0);
}
@@ -1045,7 +1129,7 @@ public class GameManagerServiceTests {
public void testGameModeConfigAllowFpsTrue() throws Exception {
mockDeviceConfigAll();
mockModifyGameModeGranted();
- mockInterventionsEnabledFromXml();
+ mockInterventionsEnabledNoOptInFromXml();
GameManagerService gameManagerService = new GameManagerService(mMockContext,
mTestLooper.getLooper());
startUser(gameManagerService, USER_ID_1);
@@ -1060,7 +1144,7 @@ public class GameManagerServiceTests {
public void testGameModeConfigAllowFpsFalse() throws Exception {
mockDeviceConfigAll();
mockModifyGameModeGranted();
- mockInterventionsDisabledFromXml();
+ mockInterventionsDisabledNoOptInFromXml();
GameManagerService gameManagerService = new GameManagerService(mMockContext,
mTestLooper.getLooper());
startUser(gameManagerService, USER_ID_1);
@@ -1091,7 +1175,7 @@ public class GameManagerServiceTests {
GameManagerService gameManagerService =
new GameManagerService(mMockContext, mTestLooper.getLooper());
startUser(gameManagerService, USER_ID_1);
- gameManagerService.updateConfigsForUser(USER_ID_1, mPackageName);
+ gameManagerService.updateConfigsForUser(USER_ID_1, true, mPackageName);
GameManagerService.GamePackageConfiguration config =
gameManagerService.getConfig(mPackageName);
assertNull(config.getGameModeConfiguration(GameManager.GAME_MODE_PERFORMANCE));
@@ -1109,7 +1193,7 @@ public class GameManagerServiceTests {
new GameManagerService(mMockContext, mTestLooper.getLooper());
startUser(gameManagerService, USER_ID_1);
gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE, USER_ID_1);
- gameManagerService.updateConfigsForUser(USER_ID_1, mPackageName);
+ gameManagerService.updateConfigsForUser(USER_ID_1, true, mPackageName);
assertEquals(GameManager.GAME_MODE_UNSUPPORTED,
gameManagerService.getGameMode(mPackageName, USER_ID_1));
}
@@ -1126,7 +1210,7 @@ public class GameManagerServiceTests {
new GameManagerService(mMockContext, mTestLooper.getLooper());
startUser(gameManagerService, USER_ID_1);
gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_BATTERY, USER_ID_1);
- gameManagerService.updateConfigsForUser(USER_ID_1, mPackageName);
+ gameManagerService.updateConfigsForUser(USER_ID_1, true, mPackageName);
assertEquals(GameManager.GAME_MODE_STANDARD,
gameManagerService.getGameMode(mPackageName, USER_ID_1));
}
@@ -1143,7 +1227,7 @@ public class GameManagerServiceTests {
new GameManagerService(mMockContext, mTestLooper.getLooper());
startUser(gameManagerService, USER_ID_1);
gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_UNSUPPORTED, USER_ID_1);
- gameManagerService.updateConfigsForUser(USER_ID_1, mPackageName);
+ gameManagerService.updateConfigsForUser(USER_ID_1, true, mPackageName);
assertEquals(GameManager.GAME_MODE_STANDARD,
gameManagerService.getGameMode(mPackageName, USER_ID_1));
}
@@ -1404,4 +1488,80 @@ public class GameManagerServiceTests {
assertEquals(splitLine[6], "angle=0,scaling=0.7,fps=30");
}
+
+ @Test
+ public void testResetInterventions_onDeviceConfigReset() throws Exception {
+ mockModifyGameModeGranted();
+ String configStringBefore =
+ "mode=2,downscaleFactor=1.0,fps=90";
+ when(DeviceConfig.getProperty(anyString(), anyString()))
+ .thenReturn(configStringBefore);
+ mockInterventionsEnabledNoOptInFromXml();
+ GameManagerService gameManagerService = Mockito.spy(new GameManagerService(mMockContext,
+ mTestLooper.getLooper()));
+ startUser(gameManagerService, USER_ID_1);
+ gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE, USER_ID_1);
+ Mockito.verify(gameManagerService).setOverrideFrameRate(
+ ArgumentMatchers.eq(DEFAULT_PACKAGE_UID),
+ ArgumentMatchers.eq(90.0f));
+ checkFps(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 90);
+
+ String configStringAfter = "";
+ when(DeviceConfig.getProperty(anyString(), anyString()))
+ .thenReturn(configStringAfter);
+ gameManagerService.updateConfigsForUser(USER_ID_1, false, mPackageName);
+ Mockito.verify(gameManagerService).setOverrideFrameRate(
+ ArgumentMatchers.eq(DEFAULT_PACKAGE_UID),
+ ArgumentMatchers.eq(0.0f));
+ }
+
+ @Test
+ public void testResetInterventions_onInterventionsDisabled() throws Exception {
+ mockModifyGameModeGranted();
+ String configStringBefore =
+ "mode=2,downscaleFactor=1.0,fps=90";
+ when(DeviceConfig.getProperty(anyString(), anyString()))
+ .thenReturn(configStringBefore);
+ mockInterventionsEnabledNoOptInFromXml();
+ GameManagerService gameManagerService = Mockito.spy(new GameManagerService(mMockContext,
+ mTestLooper.getLooper()));
+ startUser(gameManagerService, USER_ID_1);
+ gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE, USER_ID_1);
+ Mockito.verify(gameManagerService).setOverrideFrameRate(
+ ArgumentMatchers.eq(DEFAULT_PACKAGE_UID),
+ ArgumentMatchers.eq(90.0f));
+ checkFps(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 90);
+
+ mockInterventionsDisabledNoOptInFromXml();
+ gameManagerService.updateConfigsForUser(USER_ID_1, false, mPackageName);
+ Mockito.verify(gameManagerService).setOverrideFrameRate(
+ ArgumentMatchers.eq(DEFAULT_PACKAGE_UID),
+ ArgumentMatchers.eq(0.0f));
+ checkFps(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 0);
+ }
+
+ @Test
+ public void testResetInterventions_onGameModeOptedIn() throws Exception {
+ mockModifyGameModeGranted();
+ String configStringBefore =
+ "mode=2,downscaleFactor=1.0,fps=90";
+ when(DeviceConfig.getProperty(anyString(), anyString()))
+ .thenReturn(configStringBefore);
+ mockInterventionsEnabledNoOptInFromXml();
+ GameManagerService gameManagerService = Mockito.spy(new GameManagerService(mMockContext,
+ mTestLooper.getLooper()));
+ startUser(gameManagerService, USER_ID_1);
+
+ gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE, USER_ID_1);
+ Mockito.verify(gameManagerService).setOverrideFrameRate(
+ ArgumentMatchers.eq(DEFAULT_PACKAGE_UID),
+ ArgumentMatchers.eq(90.0f));
+ checkFps(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 90);
+
+ mockInterventionsEnabledAllOptInFromXml();
+ gameManagerService.updateConfigsForUser(USER_ID_1, false, mPackageName);
+ Mockito.verify(gameManagerService).setOverrideFrameRate(
+ ArgumentMatchers.eq(DEFAULT_PACKAGE_UID),
+ ArgumentMatchers.eq(0.0f));
+ }
}