Add atom logging for intervention framework
Bug: b/243448953
Test: atest GameManagerStatsTests
Change-Id: Ib9548fd6cb74def937a618cbe77654ed7a381802
diff --git a/services/core/java/com/android/server/app/GameManagerService.java b/services/core/java/com/android/server/app/GameManagerService.java
index a954164..7877b65 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.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.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.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
/**
* Service to manage game related features.
@@ -932,6 +935,7 @@
public void onBootPhase(int phase) {
if (phase == PHASE_BOOT_COMPLETED) {
mService.onBootCompleted();
+ mService.registerStatsCallbacks();
}
}
@@ -1150,6 +1154,15 @@
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 @@
}
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 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 @@
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 out.toString();
+ 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;
+ }
}
private static int gameStateModeToStatsdGameState(int mode) {