Loading services/core/java/com/android/server/app/GameManagerService.java +50 −32 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static android.content.Intent.ACTION_PACKAGE_ADDED; import static android.content.Intent.ACTION_PACKAGE_REMOVED; import static android.content.Intent.EXTRA_REPLACING; import static android.server.app.Flags.gameDefaultFrameRate; import static android.server.app.Flags.disableGameModeWhenAppTop; import static com.android.internal.R.styleable.GameModeConfig_allowGameAngleDriver; import static com.android.internal.R.styleable.GameModeConfig_allowGameDownscaling; Loading Loading @@ -181,7 +182,9 @@ public final class GameManagerService extends IGameManagerService.Stub { @Nullable final MyUidObserver mUidObserver; @GuardedBy("mUidObserverLock") private final Set<Integer> mForegroundGameUids = new HashSet<>(); private final Set<Integer> mGameForegroundUids = new HashSet<>(); @GuardedBy("mUidObserverLock") private final Set<Integer> mNonGameForegroundUids = new HashSet<>(); private final GameManagerServiceSystemPropertiesWrapper mSysProps; private float mGameDefaultFrameRateValue; Loading Loading @@ -238,12 +241,10 @@ public final class GameManagerService extends IGameManagerService.Stub { FileUtils.S_IRUSR | FileUtils.S_IWUSR | FileUtils.S_IRGRP | FileUtils.S_IWGRP, -1, -1); if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_GAME_SERVICE)) { if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_GAME_SERVICE)) { mGameServiceController = new GameServiceController( context, BackgroundThread.getExecutor(), new GameServiceProviderSelectorImpl( context.getResources(), context.getPackageManager()), new GameServiceProviderSelectorImpl(context.getResources(), mPackageManager), new GameServiceProviderInstanceFactoryImpl(context)); } else { mGameServiceController = null; Loading Loading @@ -2245,7 +2246,7 @@ public final class GameManagerService extends IGameManagerService.Stub { // Update all foreground games' frame rate. synchronized (mUidObserverLock) { for (int uid : mForegroundGameUids) { for (int uid : mGameForegroundUids) { setGameDefaultFrameRateOverride(uid, getGameDefaultFrameRate(isEnabled)); } } Loading @@ -2261,31 +2262,44 @@ public final class GameManagerService extends IGameManagerService.Stub { @Override public void onUidGone(int uid, boolean disabled) { synchronized (mUidObserverLock) { disableGameMode(uid); handleUidMovedOffTop(uid); } } @Override public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) { synchronized (mUidObserverLock) { if (procState != ActivityManager.PROCESS_STATE_TOP) { disableGameMode(uid); switch (procState) { case ActivityManager.PROCESS_STATE_TOP: handleUidMovedToTop(uid); return; default: handleUidMovedOffTop(uid); } } final String[] packages = mContext.getPackageManager().getPackagesForUid(uid); private void handleUidMovedToTop(int uid) { final String[] packages = mPackageManager.getPackagesForUid(uid); if (packages == null || packages.length == 0) { return; } final int userId = mContext.getUserId(); if (!Arrays.stream(packages).anyMatch(p -> isPackageGame(p, userId))) { final boolean isNotGame = Arrays.stream(packages).noneMatch( p -> isPackageGame(p, userId)); synchronized (mUidObserverLock) { if (isNotGame) { if (disableGameModeWhenAppTop()) { if (!mGameForegroundUids.isEmpty() && mNonGameForegroundUids.isEmpty()) { Slog.v(TAG, "Game power mode OFF (first non-game in foreground)"); mPowerManagerInternal.setPowerMode(Mode.GAME, false); } mNonGameForegroundUids.add(uid); } return; } if (mForegroundGameUids.isEmpty()) { Slog.v(TAG, "Game power mode ON (process state was changed to foreground)"); if (mGameForegroundUids.isEmpty() && (!disableGameModeWhenAppTop() || mNonGameForegroundUids.isEmpty())) { Slog.v(TAG, "Game power mode ON (first game in foreground)"); mPowerManagerInternal.setPowerMode(Mode.GAME, true); } final boolean isGameDefaultFrameRateDisabled = Loading @@ -2293,22 +2307,26 @@ public final class GameManagerService extends IGameManagerService.Stub { PROPERTY_DEBUG_GFX_GAME_DEFAULT_FRAME_RATE_DISABLED, false); setGameDefaultFrameRateOverride(uid, getGameDefaultFrameRate(!isGameDefaultFrameRateDisabled)); mForegroundGameUids.add(uid); mGameForegroundUids.add(uid); } } private void disableGameMode(int uid) { private void handleUidMovedOffTop(int uid) { synchronized (mUidObserverLock) { if (!mForegroundGameUids.contains(uid)) { return; if (mGameForegroundUids.contains(uid)) { mGameForegroundUids.remove(uid); if (mGameForegroundUids.isEmpty() && (!disableGameModeWhenAppTop() || mNonGameForegroundUids.isEmpty())) { Slog.v(TAG, "Game power mode OFF (no games in foreground)"); mPowerManagerInternal.setPowerMode(Mode.GAME, false); } } else if (disableGameModeWhenAppTop() && mNonGameForegroundUids.contains(uid)) { mNonGameForegroundUids.remove(uid); if (mNonGameForegroundUids.isEmpty() && !mGameForegroundUids.isEmpty()) { Slog.v(TAG, "Game power mode ON (only games in foreground)"); mPowerManagerInternal.setPowerMode(Mode.GAME, true); } mForegroundGameUids.remove(uid); if (!mForegroundGameUids.isEmpty()) { return; } Slog.v(TAG, "Game power mode OFF (process remomved or state changed to background)"); mPowerManagerInternal.setPowerMode(Mode.GAME, false); } } } Loading services/core/java/com/android/server/app/flags.aconfig +8 −1 Original line number Diff line number Diff line Loading @@ -7,3 +7,10 @@ flag { bug: "286084594" is_fixed_read_only: true } flag { name: "disable_game_mode_when_app_top" namespace: "game" description: "Disable game power mode when a non-game app is also top and visible" bug: "299295925" } services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java +200 −88 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
services/core/java/com/android/server/app/GameManagerService.java +50 −32 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static android.content.Intent.ACTION_PACKAGE_ADDED; import static android.content.Intent.ACTION_PACKAGE_REMOVED; import static android.content.Intent.EXTRA_REPLACING; import static android.server.app.Flags.gameDefaultFrameRate; import static android.server.app.Flags.disableGameModeWhenAppTop; import static com.android.internal.R.styleable.GameModeConfig_allowGameAngleDriver; import static com.android.internal.R.styleable.GameModeConfig_allowGameDownscaling; Loading Loading @@ -181,7 +182,9 @@ public final class GameManagerService extends IGameManagerService.Stub { @Nullable final MyUidObserver mUidObserver; @GuardedBy("mUidObserverLock") private final Set<Integer> mForegroundGameUids = new HashSet<>(); private final Set<Integer> mGameForegroundUids = new HashSet<>(); @GuardedBy("mUidObserverLock") private final Set<Integer> mNonGameForegroundUids = new HashSet<>(); private final GameManagerServiceSystemPropertiesWrapper mSysProps; private float mGameDefaultFrameRateValue; Loading Loading @@ -238,12 +241,10 @@ public final class GameManagerService extends IGameManagerService.Stub { FileUtils.S_IRUSR | FileUtils.S_IWUSR | FileUtils.S_IRGRP | FileUtils.S_IWGRP, -1, -1); if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_GAME_SERVICE)) { if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_GAME_SERVICE)) { mGameServiceController = new GameServiceController( context, BackgroundThread.getExecutor(), new GameServiceProviderSelectorImpl( context.getResources(), context.getPackageManager()), new GameServiceProviderSelectorImpl(context.getResources(), mPackageManager), new GameServiceProviderInstanceFactoryImpl(context)); } else { mGameServiceController = null; Loading Loading @@ -2245,7 +2246,7 @@ public final class GameManagerService extends IGameManagerService.Stub { // Update all foreground games' frame rate. synchronized (mUidObserverLock) { for (int uid : mForegroundGameUids) { for (int uid : mGameForegroundUids) { setGameDefaultFrameRateOverride(uid, getGameDefaultFrameRate(isEnabled)); } } Loading @@ -2261,31 +2262,44 @@ public final class GameManagerService extends IGameManagerService.Stub { @Override public void onUidGone(int uid, boolean disabled) { synchronized (mUidObserverLock) { disableGameMode(uid); handleUidMovedOffTop(uid); } } @Override public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) { synchronized (mUidObserverLock) { if (procState != ActivityManager.PROCESS_STATE_TOP) { disableGameMode(uid); switch (procState) { case ActivityManager.PROCESS_STATE_TOP: handleUidMovedToTop(uid); return; default: handleUidMovedOffTop(uid); } } final String[] packages = mContext.getPackageManager().getPackagesForUid(uid); private void handleUidMovedToTop(int uid) { final String[] packages = mPackageManager.getPackagesForUid(uid); if (packages == null || packages.length == 0) { return; } final int userId = mContext.getUserId(); if (!Arrays.stream(packages).anyMatch(p -> isPackageGame(p, userId))) { final boolean isNotGame = Arrays.stream(packages).noneMatch( p -> isPackageGame(p, userId)); synchronized (mUidObserverLock) { if (isNotGame) { if (disableGameModeWhenAppTop()) { if (!mGameForegroundUids.isEmpty() && mNonGameForegroundUids.isEmpty()) { Slog.v(TAG, "Game power mode OFF (first non-game in foreground)"); mPowerManagerInternal.setPowerMode(Mode.GAME, false); } mNonGameForegroundUids.add(uid); } return; } if (mForegroundGameUids.isEmpty()) { Slog.v(TAG, "Game power mode ON (process state was changed to foreground)"); if (mGameForegroundUids.isEmpty() && (!disableGameModeWhenAppTop() || mNonGameForegroundUids.isEmpty())) { Slog.v(TAG, "Game power mode ON (first game in foreground)"); mPowerManagerInternal.setPowerMode(Mode.GAME, true); } final boolean isGameDefaultFrameRateDisabled = Loading @@ -2293,22 +2307,26 @@ public final class GameManagerService extends IGameManagerService.Stub { PROPERTY_DEBUG_GFX_GAME_DEFAULT_FRAME_RATE_DISABLED, false); setGameDefaultFrameRateOverride(uid, getGameDefaultFrameRate(!isGameDefaultFrameRateDisabled)); mForegroundGameUids.add(uid); mGameForegroundUids.add(uid); } } private void disableGameMode(int uid) { private void handleUidMovedOffTop(int uid) { synchronized (mUidObserverLock) { if (!mForegroundGameUids.contains(uid)) { return; if (mGameForegroundUids.contains(uid)) { mGameForegroundUids.remove(uid); if (mGameForegroundUids.isEmpty() && (!disableGameModeWhenAppTop() || mNonGameForegroundUids.isEmpty())) { Slog.v(TAG, "Game power mode OFF (no games in foreground)"); mPowerManagerInternal.setPowerMode(Mode.GAME, false); } } else if (disableGameModeWhenAppTop() && mNonGameForegroundUids.contains(uid)) { mNonGameForegroundUids.remove(uid); if (mNonGameForegroundUids.isEmpty() && !mGameForegroundUids.isEmpty()) { Slog.v(TAG, "Game power mode ON (only games in foreground)"); mPowerManagerInternal.setPowerMode(Mode.GAME, true); } mForegroundGameUids.remove(uid); if (!mForegroundGameUids.isEmpty()) { return; } Slog.v(TAG, "Game power mode OFF (process remomved or state changed to background)"); mPowerManagerInternal.setPowerMode(Mode.GAME, false); } } } Loading
services/core/java/com/android/server/app/flags.aconfig +8 −1 Original line number Diff line number Diff line Loading @@ -7,3 +7,10 @@ flag { bug: "286084594" is_fixed_read_only: true } flag { name: "disable_game_mode_when_app_top" namespace: "game" description: "Disable game power mode when a non-game app is also top and visible" bug: "299295925" }
services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java +200 −88 File changed.Preview size limit exceeded, changes collapsed. Show changes