Merge "Change peak_refresh_rate value stats reporting" into main
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));
             }
         }