Loading core/api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -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 core/java/android/app/GameManager.java +44 −6 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 { Loading Loading @@ -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( Loading @@ -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 */ Loading @@ -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; } /** Loading core/tests/GameManagerTests/src/android/app/GameManagerTests.java +8 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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)); } } Loading
core/api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -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
core/java/android/app/GameManager.java +44 −6 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 { Loading Loading @@ -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( Loading @@ -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 */ Loading @@ -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; } /** Loading
core/tests/GameManagerTests/src/android/app/GameManagerTests.java +8 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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)); } }