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

Commit 4571cdb5 authored by Xiang Wang's avatar Xiang Wang
Browse files

Add atom logging for intervention framework

Bug: b/243448953
Test: atest GameManagerStatsTests
Change-Id: Ib9548fd6cb74def937a618cbe77654ed7a381802
parent ae07cf71
Loading
Loading
Loading
Loading
+116 −12
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import android.app.GameModeInfo;
import android.app.GameState;
import android.app.IGameManagerService;
import android.app.IGameModeListener;
import android.app.StatsManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -76,6 +77,7 @@ import android.util.AtomicFile;
import android.util.AttributeSet;
import android.util.KeyValueListParser;
import android.util.Slog;
import android.util.StatsEvent;
import android.util.Xml;

import com.android.internal.annotations.GuardedBy;
@@ -104,6 +106,7 @@ import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Service to manage game related features.
@@ -932,6 +935,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
        public void onBootPhase(int phase) {
            if (phase == PHASE_BOOT_COMPLETED) {
                mService.onBootCompleted();
                mService.registerStatsCallbacks();
            }
        }

@@ -1150,6 +1154,15 @@ public final class GameManagerService extends IGameManagerService.Stub {
        sendUserMessage(userId, WRITE_SETTINGS, "SET_GAME_MODE", WRITE_DELAY_MILLIS);
        sendUserMessage(userId, WRITE_GAME_MODE_INTERVENTION_LIST_FILE,
                "SET_GAME_MODE", 0 /*delayMillis*/);
        int gameUid = -1;
        try {
            gameUid = mPackageManager.getPackageUidAsUser(packageName, userId);
        } catch (NameNotFoundException ex) {
            Slog.d(TAG, "Cannot find the UID for package " + packageName + " under user " + userId);
        }
        FrameworkStatsLog.write(FrameworkStatsLog.GAME_MODE_CHANGED, gameUid,
                Binder.getCallingUid(), gameModeToStatsdGameMode(fromGameMode),
                gameModeToStatsdGameMode(gameMode));
    }

    /**
@@ -1364,11 +1377,21 @@ public final class GameManagerService extends IGameManagerService.Stub {
        }
        GamePackageConfiguration.GameModeConfiguration internalConfig =
                configOverride.getOrAddDefaultGameModeConfiguration(GameManager.GAME_MODE_CUSTOM);
        int gameUid = -1;
        try {
            gameUid = mPackageManager.getPackageUidAsUser(packageName, userId);
        } catch (NameNotFoundException ex) {
            Slog.d(TAG, "Cannot find the UID for package " + packageName + " under user " + userId);
        }
        FrameworkStatsLog.write(FrameworkStatsLog.GAME_MODE_CONFIGURATION_CHANGED, gameUid,
                Binder.getCallingUid(), gameModeToStatsdGameMode(GameManager.GAME_MODE_CUSTOM),
                internalConfig.getScaling(), gameModeConfig.getScalingFactor(),
                internalConfig.getFps(), gameModeConfig.getFpsOverride());
        internalConfig.updateFromPublicGameModeConfig(gameModeConfig);

        Slog.i(TAG, "Updated custom game mode config for package: " + packageName
                + " with FPS=" + internalConfig.getFps() + ";Scaling="
                + internalConfig.getScaling());
                + internalConfig.getScaling() + " under user " + userId);
    }

    /**
@@ -1629,11 +1652,6 @@ public final class GameManagerService extends IGameManagerService.Stub {
    public void resetGameModeConfigOverride(String packageName, @UserIdInt int userId,
            @GameMode int gameModeToReset) throws SecurityException {
        checkPermission(Manifest.permission.MANAGE_GAME_MODE);
        final GamePackageConfiguration deviceConfig;
        synchronized (mDeviceConfigLock) {
            deviceConfig = mConfigs.get(packageName);
        }

        // resets GamePackageConfiguration of a given packageName.
        // If a gameMode is specified, only reset the GameModeConfiguration of the gameMode.
        synchronized (mLock) {
@@ -1949,13 +1967,99 @@ public final class GameManagerService extends IGameManagerService.Stub {
        LocalServices.addService(GameManagerInternal.class, new LocalService());
    }

    private String dumpDeviceConfigs() {
        StringBuilder out = new StringBuilder();
        for (String key : mConfigs.keySet()) {
            out.append("[\nName: ").append(key)
                    .append("\nConfig: ").append(mConfigs.get(key).toString()).append("\n]");
    private void registerStatsCallbacks() {
        final StatsManager statsManager = mContext.getSystemService(StatsManager.class);
        statsManager.setPullAtomCallback(
                FrameworkStatsLog.GAME_MODE_INFO,
                null, // use default PullAtomMetadata values
                BackgroundThread.getExecutor(),
                this::onPullAtom);
        statsManager.setPullAtomCallback(
                FrameworkStatsLog.GAME_MODE_CONFIGURATION,
                null, // use default PullAtomMetadata values
                BackgroundThread.getExecutor(),
                this::onPullAtom);
        statsManager.setPullAtomCallback(
                FrameworkStatsLog.GAME_MODE_LISTENER,
                null, // use default PullAtomMetadata values
                BackgroundThread.getExecutor(),
                this::onPullAtom);
    }

    private int onPullAtom(int atomTag, @NonNull List<StatsEvent> data) {
        if (atomTag == FrameworkStatsLog.GAME_MODE_INFO
                || atomTag == FrameworkStatsLog.GAME_MODE_CONFIGURATION) {
            int userId = ActivityManager.getCurrentUser();
            Set<String> packages;
            synchronized (mDeviceConfigLock) {
                packages = mConfigs.keySet();
            }
            for (String p : packages) {
                GamePackageConfiguration config = getConfig(p, userId);
                if (config == null) {
                    continue;
                }
                int uid = -1;
                try {
                    uid = mPackageManager.getPackageUidAsUser(p, userId);
                } catch (NameNotFoundException ex) {
                    Slog.d(TAG,
                            "Cannot find UID for package " + p + " under user handle id " + userId);
                }
                if (atomTag == FrameworkStatsLog.GAME_MODE_INFO) {
                    data.add(
                            FrameworkStatsLog.buildStatsEvent(FrameworkStatsLog.GAME_MODE_INFO, uid,
                                    gameModesToStatsdGameModes(config.getOptedInGameModes()),
                                    gameModesToStatsdGameModes(config.getAvailableGameModes())));
                } else if (atomTag == FrameworkStatsLog.GAME_MODE_CONFIGURATION) {
                    for (int gameMode : config.getAvailableGameModes()) {
                        GamePackageConfiguration.GameModeConfiguration modeConfig =
                                config.getGameModeConfiguration(gameMode);
                        if (modeConfig != null) {
                            data.add(FrameworkStatsLog.buildStatsEvent(
                                    FrameworkStatsLog.GAME_MODE_CONFIGURATION, uid,
                                    gameModeToStatsdGameMode(gameMode), modeConfig.getFps(),
                                    modeConfig.getScaling()));
                        }
                    }
                }
            }
        } else if (atomTag == FrameworkStatsLog.GAME_MODE_LISTENER) {
            synchronized (mGameModeListenerLock) {
                data.add(FrameworkStatsLog.buildStatsEvent(FrameworkStatsLog.GAME_MODE_LISTENER,
                        mGameModeListeners.size()));
            }
        }
        return android.app.StatsManager.PULL_SUCCESS;
    }

    private static int[] gameModesToStatsdGameModes(int[] modes) {
        if (modes == null) {
            return null;
        }
        int[] statsdModes = new int[modes.length];
        int i = 0;
        for (int mode : modes) {
            statsdModes[i++] = gameModeToStatsdGameMode(mode);
        }
        return statsdModes;
    }

    private static int gameModeToStatsdGameMode(int mode) {
        switch (mode) {
            case GameManager.GAME_MODE_BATTERY:
                return FrameworkStatsLog.GAME_MODE_CONFIGURATION__GAME_MODE__GAME_MODE_BATTERY;
            case GameManager.GAME_MODE_PERFORMANCE:
                return FrameworkStatsLog.GAME_MODE_CONFIGURATION__GAME_MODE__GAME_MODE_PERFORMANCE;
            case GameManager.GAME_MODE_CUSTOM:
                return FrameworkStatsLog.GAME_MODE_CONFIGURATION__GAME_MODE__GAME_MODE_CUSTOM;
            case GameManager.GAME_MODE_STANDARD:
                return FrameworkStatsLog.GAME_MODE_CONFIGURATION__GAME_MODE__GAME_MODE_STANDARD;
            case GameManager.GAME_MODE_UNSUPPORTED:
                return FrameworkStatsLog.GAME_MODE_CONFIGURATION__GAME_MODE__GAME_MODE_UNSUPPORTED;
            default:
                return FrameworkStatsLog.GAME_MODE_CONFIGURATION__GAME_MODE__GAME_MODE_UNSPECIFIED;
        }
        return out.toString();
    }

    private static int gameStateModeToStatsdGameState(int mode) {