Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 36a9b7e4 authored by Xiang Wang's avatar Xiang Wang Committed by Android (Google) Code Review
Browse files

Merge changes If537a25e,Iee14d6ee,Iac718a6a,I0aae9bb4 into tm-qpr-dev

* changes:
  Reset FPS when device config resets or app opts in to a game mode
  Override config should trigger intervention ignoring opt-in info
  Guard the mode configs map in GamePackageConfiguration with lock
  Check if it's game package before updating configs
parents 1d2c085a e8d4d360
Loading
Loading
Loading
Loading
+168 −125
Original line number Diff line number Diff line
@@ -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,9 +784,11 @@ public final class GameManagerService extends IGameManagerService.Stub {

        private int getAvailableGameModesBitfield() {
            int field = 0;
            synchronized (mModeConfigLock) {
                for (final int mode : mModeConfigs.keySet()) {
                    field |= modeToBitmask(mode);
                }
            }
            if (mBatteryModeOptedIn) {
                field |= modeToBitmask(GameManager.GAME_MODE_BATTERY);
            }
@@ -802,29 +828,73 @@ 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) {
            synchronized (mModeConfigLock) {
                return mModeConfigs.get(gameMode);
            }
        }

        /**
         * Insert a new GameModeConfiguration
         */
        public void addModeConfig(GameModeConfiguration config) {
            if (config.isValid()) {
            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() {
        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() {
            synchronized (mModeConfigLock) {
                return "[Name:" + mPackageName + " Modes: " + mModeConfigs.toString() + "]";
            }
        }
    }

    /**
     * SystemService lifecycle for GameService.
@@ -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,12 +1116,13 @@ 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) {
@@ -1067,7 +1130,6 @@ public final class GameManagerService extends IGameManagerService.Stub {
        }
        return gameModeConfiguration.getUseAngle();
    }
    }

    /**
     * If loading boost is applicable for the package for the currently enabled game mode, return
@@ -1081,9 +1143,10 @@ 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);
            config = mConfigs.get(packageName);
        }
        if (config == null) {
            return -1;
        }
@@ -1094,7 +1157,6 @@ public final class GameManagerService extends IGameManagerService.Stub {
        }
        return gameModeConfiguration.getLoadingBoostDuration();
    }
    }

    /**
     * If loading boost is enabled, invoke it.
@@ -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,31 +1419,16 @@ 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) {
            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);
@@ -1403,17 +1450,18 @@ 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.getGameModeConfiguration(gameMode);
                overrideConfig.getOrAddDefaultGameModeConfiguration(gameMode);

        if (fpsStr != null) {
            overrideModeConfig.setFpsStr(fpsStr);
@@ -1430,7 +1478,6 @@ public final class GameManagerService extends IGameManagerService.Stub {
        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 "
                        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;
        synchronized (mOverrideConfigLock) {
            packageConfig = mOverrideConfigs.get(packageName);
        }
        if (packageConfig == null) {
        GamePackageConfiguration overrideConfig = null;
        GamePackageConfiguration config;
        synchronized (mDeviceConfigLock) {
                packageConfig = mConfigs.get(packageName);
            config = mConfigs.get(packageName);
        }
        synchronized (mOverrideConfigLock) {
            overrideConfig = mOverrideConfigs.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
     */
+9 −0
Original line number Diff line number Diff line
<?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
+0 −0

File moved.

+9 −0
Original line number Diff line number Diff line
<?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
+0 −0

File moved.

Loading