Change peak_refresh_rate value stats reporting
peak_refresh_rate setting could be saved in settings as "Infinity". This setting is for the state when system has no limits of display refresh rate. "Infinity" also allow to share the setting between devices with different max refresh rate limit. After this change SETTING_SNAPSHOT atom will not send "inf" value for this setting. Instead, the atom will have the max refresh rate of all the built-in/physical displays on the device.
Test: previz 10080
Test: Manual tests with different Displays (not built-in, but HDMI, Virtual)
Test: Manual tests with devices that have different amount of built-in displays
Flag: EXEMPT bugfix
Bug: 339667489
Change-Id: Ibc9c4dfab90efa1cccafbfe78567b902cb630df4
Change-Id: I79f5326335a1d5905457028e75ab118b2af79f2e
diff --git a/core/java/com/android/internal/display/RefreshRateSettingsUtils.java b/core/java/com/android/internal/display/RefreshRateSettingsUtils.java
index c23a501..47e4943 100644
--- a/core/java/com/android/internal/display/RefreshRateSettingsUtils.java
+++ b/core/java/com/android/internal/display/RefreshRateSettingsUtils.java
@@ -83,4 +83,32 @@
}
return maxRefreshRate;
}
+
+ /**
+ * Find the highest refresh rate among all the modes of all the built-in/physical displays.
+ *
+ * This method will acquire DisplayManager.mLock, so calling it while holding other locks
+ * should be done with care.
+ * @param context The context
+ * @return The highest refresh rate
+ */
+ public static float findHighestRefreshRateAmongAllBuiltInDisplays(Context context) {
+ final DisplayManager dm = context.getSystemService(DisplayManager.class);
+ final Display[] displays = dm.getDisplays(DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED);
+ if (displays.length == 0) {
+ Log.w(TAG, "No valid display devices");
+ return DEFAULT_REFRESH_RATE;
+ }
+
+ float maxRefreshRate = DEFAULT_REFRESH_RATE;
+ for (Display display : displays) {
+ if (display.getType() != Display.TYPE_INTERNAL) continue;
+ for (Display.Mode mode : display.getSupportedModes()) {
+ if (mode.getRefreshRate() > maxRefreshRate) {
+ maxRefreshRate = mode.getRefreshRate();
+ }
+ }
+ }
+ return maxRefreshRate;
+ }
}
diff --git a/services/core/java/com/android/server/stats/pull/RawSettingsTelemetryUtil.java b/services/core/java/com/android/server/stats/pull/RawSettingsTelemetryUtil.java
new file mode 100644
index 0000000..905f38a
--- /dev/null
+++ b/services/core/java/com/android/server/stats/pull/RawSettingsTelemetryUtil.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.stats.pull;
+
+import static android.provider.Settings.System.PEAK_REFRESH_RATE;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.util.Log;
+
+import com.android.internal.display.RefreshRateSettingsUtils;
+
+/**
+ * Utility methods for processing raw settings values to the format that
+ * is acceptable for telemetry system.
+ * For instance, raw setting values could be hard to visualize on dashboards, etc.
+ */
+public final class RawSettingsTelemetryUtil {
+
+ private static final String TAG = "SettingsTelemetryUtil";
+
+ /**
+ * Get string that should be written as a value of settingKey and should be sent to telemetry
+ * system.
+ *
+ * @param context The context
+ * @param key The setting key
+ * @param value The setting raw value that was parsed from Settings.
+ * @return The setting string value that should be sent to telemetry system.
+ */
+ @Nullable
+ public static String getTelemetrySettingFromRawVal(Context context, String key, String value) {
+ if (key == null) {
+ return null;
+ }
+
+ if (key.equals(PEAK_REFRESH_RATE)) {
+ return getPeakRefreshRateSetting(context, value);
+ }
+
+ return value;
+ }
+
+ /**
+ * Get string that should be written as a value of "peak_refresh_setting" setting
+ * and should be sent to telemetry.
+ * system.
+ *
+ * @param context The context
+ * @param settingRawValue The setting raw value that was parsed from Settings.
+ * @return The "peak_refresh_setting" string value that should be sent to telemetry system.
+ */
+ @Nullable
+ private static String getPeakRefreshRateSetting(Context context, String settingRawValue) {
+ if (settingRawValue == null) {
+ Log.e(TAG, "PEAK_REFRESH_RATE value is null");
+ return null;
+ }
+
+ String floatInfinityStr = Float.toString(Float.POSITIVE_INFINITY);
+ if (settingRawValue.equals(floatInfinityStr)) {
+ float max_refresh_rate =
+ RefreshRateSettingsUtils.findHighestRefreshRateAmongAllBuiltInDisplays(context);
+ return Float.toString(max_refresh_rate);
+ }
+
+ return settingRawValue;
+ }
+}
diff --git a/services/core/java/com/android/server/stats/pull/SettingsStatsUtil.java b/services/core/java/com/android/server/stats/pull/SettingsStatsUtil.java
index 7cdb84b..2a4a39c 100644
--- a/services/core/java/com/android/server/stats/pull/SettingsStatsUtil.java
+++ b/services/core/java/com/android/server/stats/pull/SettingsStatsUtil.java
@@ -107,7 +107,9 @@
}
for (String key : proto.element) {
final String value = Settings.System.getStringForUser(resolver, key, userId);
- output.add(createStatsEvent(atomTag, key, value, userId,
+ final String telemetryValue =
+ RawSettingsTelemetryUtil.getTelemetrySettingFromRawVal(context, key, value);
+ output.add(createStatsEvent(atomTag, key, telemetryValue, userId,
flagsData.mDataType));
}
}