Merge "Add custom game mode"

This commit is contained in:
Xiang Wang
2022-11-21 18:15:16 +00:00
committed by Android (Google) Code Review
3 changed files with 53 additions and 6 deletions

View File

@@ -5612,6 +5612,7 @@ package android.app {
method public int getGameMode();
method public void setGameState(@NonNull android.app.GameState);
field public static final int GAME_MODE_BATTERY = 3; // 0x3
field public static final int GAME_MODE_CUSTOM = 4; // 0x4
field public static final int GAME_MODE_PERFORMANCE = 2; // 0x2
field public static final int GAME_MODE_STANDARD = 1; // 0x1
field public static final int GAME_MODE_UNSUPPORTED = 0; // 0x0

View File

@@ -26,6 +26,9 @@ import android.annotation.SystemService;
import android.annotation.TestApi;
import android.annotation.UserHandleAware;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Handler;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -51,6 +54,7 @@ public final class GameManager {
GAME_MODE_STANDARD, // 1
GAME_MODE_PERFORMANCE, // 2
GAME_MODE_BATTERY, // 3
GAME_MODE_CUSTOM, // 4
})
@Retention(RetentionPolicy.SOURCE)
public @interface GameMode {
@@ -79,6 +83,15 @@ public final class GameManager {
*/
public static final int GAME_MODE_BATTERY = 3;
/**
* Custom game mode that has user-provided configuration overrides.
* <p>
* Custom game mode is expected to be handled only by the platform using users'
* preferred config. It is currently not allowed to opt in custom mode in game mode XML file nor
* expected to perform app-based optimizations when activated.
*/
public static final int GAME_MODE_CUSTOM = 4;
GameManager(Context context, Handler handler) throws ServiceNotFoundException {
mContext = context;
mService = IGameManagerService.Stub.asInterface(
@@ -93,19 +106,23 @@ public final class GameManager {
* application is not a game, always return {@link #GAME_MODE_UNSUPPORTED}.
* <p>
* Developers should call this API every time the application is resumed.
* <p>
* If a game's <code>targetSdkVersion</code> is {@link android.os.Build.VERSION_CODES#TIRAMISU}
* or lower, and when the game mode is set to {@link #GAME_MODE_CUSTOM} which is available in
* {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} or newer, this API will return
* {@link #GAME_MODE_STANDARD} instead for backward compatibility.
*/
public @GameMode int getGameMode() {
try {
return mService.getGameMode(mContext.getPackageName(), mContext.getUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
return getGameModeImpl(mContext.getPackageName(),
mContext.getApplicationInfo().targetSdkVersion);
}
/**
* Gets the game mode for the given package.
* <p>
* The caller must have {@link android.Manifest.permission#MANAGE_GAME_MODE}.
* <p>
* Also see {@link #getGameMode()} on how it handles SDK version compatibility.
*
* @hide
*/
@@ -113,11 +130,32 @@ public final class GameManager {
@UserHandleAware
@RequiresPermission(Manifest.permission.MANAGE_GAME_MODE)
public @GameMode int getGameMode(@NonNull String packageName) {
final int targetSdkVersion;
try {
return mService.getGameMode(packageName, mContext.getUserId());
final ApplicationInfo applicationInfo = mContext.getPackageManager().getApplicationInfo(
packageName, PackageManager.ApplicationInfoFlags.of(0));
targetSdkVersion = applicationInfo.targetSdkVersion;
} catch (PackageManager.NameNotFoundException ex) {
return GAME_MODE_UNSUPPORTED;
}
return getGameModeImpl(packageName, targetSdkVersion);
}
// This target SDK version check can be performed against any game by a privileged app, and
// we don't want a binder call each time to check on behalf of an app using CompatChange.
@SuppressWarnings("AndroidFrameworkCompatChange")
private @GameMode int getGameModeImpl(@NonNull String packageName, int targetSdkVersion) {
final int gameMode;
try {
gameMode = mService.getGameMode(packageName,
mContext.getUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
if (gameMode == GAME_MODE_CUSTOM && targetSdkVersion <= Build.VERSION_CODES.TIRAMISU) {
return GAME_MODE_STANDARD;
}
return gameMode;
}
/**

View File

@@ -63,6 +63,10 @@ public final class GameManagerTests {
mGameManager.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE);
assertEquals(GameManager.GAME_MODE_PERFORMANCE,
mGameManager.getGameMode());
mGameManager.setGameMode(mPackageName, GameManager.GAME_MODE_CUSTOM);
assertEquals(GameManager.GAME_MODE_CUSTOM,
mGameManager.getGameMode());
}
@Test
@@ -77,5 +81,9 @@ public final class GameManagerTests {
mGameManager.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE);
assertEquals(GameManager.GAME_MODE_PERFORMANCE,
mGameManager.getGameMode(mPackageName));
mGameManager.setGameMode(mPackageName, GameManager.GAME_MODE_CUSTOM);
assertEquals(GameManager.GAME_MODE_CUSTOM,
mGameManager.getGameMode(mPackageName));
}
}