From 4571cdb5788159dac01998aa554ce67b6c845d6a Mon Sep 17 00:00:00 2001 From: Xiang Wang Date: Mon, 14 Nov 2022 14:42:38 -0800 Subject: [PATCH] Add atom logging for intervention framework Bug: b/243448953 Test: atest GameManagerStatsTests Change-Id: Ib9548fd6cb74def937a618cbe77654ed7a381802 --- .../server/app/GameManagerService.java | 128 ++++++++++++++++-- 1 file changed, 116 insertions(+), 12 deletions(-) diff --git a/services/core/java/com/android/server/app/GameManagerService.java b/services/core/java/com/android/server/app/GameManagerService.java index a954164fb79f6..7877b65b8c60e 100644 --- a/services/core/java/com/android/server/app/GameManagerService.java +++ b/services/core/java/com/android/server/app/GameManagerService.java @@ -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 data) { + if (atomTag == FrameworkStatsLog.GAME_MODE_INFO + || atomTag == FrameworkStatsLog.GAME_MODE_CONFIGURATION) { + int userId = ActivityManager.getCurrentUser(); + Set 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) {