Reset FPS when device config resets or app opts in to a game mode

Bug: b/253100682
Test: atest GameManagerServiceTests
Change-Id: If537a25e75be963ef5871a0383230d2ab13ff85a
This commit is contained in:
Xiang Wang
2022-10-12 18:06:43 -07:00
parent 4f62571e78
commit 018d453493
3 changed files with 114 additions and 13 deletions

View File

@@ -1336,7 +1336,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;
}
@@ -1368,7 +1368,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;
}
@@ -1377,18 +1377,18 @@ public final class GameManagerService extends IGameManagerService.Stub {
private void updateInterventions(String packageName,
@GameMode int gameMode, @UserIdInt int userId) {
if (gameMode == GameManager.GAME_MODE_STANDARD
|| gameMode == GameManager.GAME_MODE_UNSUPPORTED) {
resetFps(packageName, userId);
return;
}
final GamePackageConfiguration packageConfig = getConfig(packageName, userId);
if (packageConfig == null) {
Slog.v(TAG, "Package configuration not found for " + packageName);
return;
}
if (packageConfig.willGamePerformOptimizations(gameMode)) {
return;
if (gameMode == GameManager.GAME_MODE_STANDARD
|| gameMode == GameManager.GAME_MODE_UNSUPPORTED || packageConfig == null
|| packageConfig.willGamePerformOptimizations(gameMode)) {
resetFps(packageName, userId);
// resolution scaling does not need to be reset as it's now read dynamically on game
// restart, see #getResolutionScalingFactor and CompatModePackages#getCompatScale.
// TODO: reset Angle intervention here once implemented
if (packageConfig == null) {
Slog.v(TAG, "Package configuration not found for " + packageName);
return;
}
}
updateFps(packageConfig, packageName, gameMode, userId);
updateUseAngle(packageName, gameMode);
@@ -1809,6 +1809,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
*/

View File

@@ -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"
/>

View File

@@ -73,7 +73,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;
@@ -93,6 +95,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;
@@ -207,6 +210,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);
}
@@ -387,6 +392,12 @@ public class GameManagerServiceTests {
"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"
@@ -1623,6 +1634,82 @@ public class GameManagerServiceTests {
assertFalse(gameManagerService.mHandler.hasEqualMessages(WRITE_SETTINGS, USER_ID_1));
}
@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));
}
private static void deleteFolder(File folder) {
File[] files = folder.listFiles();
if (files != null) {