Merge changes from topic "getsuggestedframerate" into main

* changes:
  Adds getSuggestedFrameRate api
  Adds support for getSuggestedFrameRate api
  adds a flag for getSuggestedFrameRates api
diff --git a/core/api/current.txt b/core/api/current.txt
index 8bd4367..bebf98a 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -51080,6 +51080,7 @@
     method @NonNull public android.view.DisplayShape getShape();
     method @Deprecated public void getSize(android.graphics.Point);
     method public int getState();
+    method @FlaggedApi("com.android.server.display.feature.flags.enable_get_suggested_frame_rate") public float getSuggestedFrameRate(int);
     method public android.view.Display.Mode[] getSupportedModes();
     method @Deprecated public float[] getSupportedRefreshRates();
     method @Deprecated public int getWidth();
@@ -51097,6 +51098,8 @@
     field public static final int FLAG_ROUND = 16; // 0x10
     field public static final int FLAG_SECURE = 2; // 0x2
     field public static final int FLAG_SUPPORTS_PROTECTED_BUFFERS = 1; // 0x1
+    field @FlaggedApi("com.android.server.display.feature.flags.enable_get_suggested_frame_rate") public static final int FRAME_RATE_CATEGORY_HIGH = 1; // 0x1
+    field @FlaggedApi("com.android.server.display.feature.flags.enable_get_suggested_frame_rate") public static final int FRAME_RATE_CATEGORY_NORMAL = 0; // 0x0
     field public static final int INVALID_DISPLAY = -1; // 0xffffffff
     field public static final int STATE_DOZE = 3; // 0x3
     field public static final int STATE_DOZE_SUSPEND = 4; // 0x4
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index e940e55bd..910e644 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -22,6 +22,7 @@
 
 import static com.android.server.display.feature.flags.Flags.FLAG_HIGHEST_HDR_SDR_RATIO_API;
 import static com.android.server.display.feature.flags.Flags.FLAG_ENABLE_HAS_ARR_SUPPORT;
+import static com.android.server.display.feature.flags.Flags.FLAG_ENABLE_GET_SUGGESTED_FRAME_RATE;
 
 import android.Manifest;
 import android.annotation.FlaggedApi;
@@ -1278,6 +1279,60 @@
         }
     }
 
+    @FlaggedApi(FLAG_ENABLE_GET_SUGGESTED_FRAME_RATE)
+    public static final int FRAME_RATE_CATEGORY_NORMAL = 0;
+    @FlaggedApi(FLAG_ENABLE_GET_SUGGESTED_FRAME_RATE)
+    public static final int FRAME_RATE_CATEGORY_HIGH = 1;
+
+    /**
+     * @hide
+     */
+    @IntDef(prefix = {"FRAME_RATE_CATEGORY_"},
+            value = {
+                FRAME_RATE_CATEGORY_NORMAL,
+                FRAME_RATE_CATEGORY_HIGH
+            })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FrameRateCategory {}
+
+    /**
+     * <p> Gets the display-defined frame rate given a descriptive frame rate category. </p>
+     *
+     * <p> For example, an animation that does not require fast render rates can use
+     * the {@link #FRAME_RATE_CATEGORY_NORMAL} to get the suggested frame rate.
+     * The suggested frame rate then can be used in the
+     * {@link Surface.FrameRateParams.Builder#setDesiredRateRange} for desiredMinRate.
+     *
+     * <pre>{@code
+     *  float desiredMinRate = display.getSuggestedFrameRate(FRAME_RATE_CATEGORY_NORMAL);
+     *  Surface.FrameRateParams params = new Surface.FrameRateParams.Builder().
+     *                                      setDesiredRateRange(desiredMinRate, Float.MAX).build();
+     *  surface.setFrameRate(params);
+     * }</pre>
+     * </p>
+     *
+     * @param category either {@link #FRAME_RATE_CATEGORY_NORMAL}
+     *                 or {@link #FRAME_RATE_CATEGORY_HIGH}
+     *
+     * @see Surface#setFrameRate(Surface.FrameRateParams)
+     * @see SurfaceControl.Transaction#setFrameRate(SurfaceControl, Surface.FrameRateParams)
+     * @throws IllegalArgumentException when category is not {@link #FRAME_RATE_CATEGORY_NORMAL}
+     * or {@link #FRAME_RATE_CATEGORY_HIGH}
+     */
+    @FlaggedApi(FLAG_ENABLE_GET_SUGGESTED_FRAME_RATE)
+    public float getSuggestedFrameRate(@FrameRateCategory int category) {
+        synchronized (mLock) {
+            updateDisplayInfoLocked();
+            if (category == FRAME_RATE_CATEGORY_HIGH) {
+                return mDisplayInfo.frameRateCategoryRate.getHigh();
+            } else if (category == FRAME_RATE_CATEGORY_NORMAL) {
+                return mDisplayInfo.frameRateCategoryRate.getNormal();
+            } else {
+                throw new IllegalArgumentException("Invalid FrameRateCategory provided");
+            }
+        }
+    }
+
     /**
      * <p> Returns true if the connected display can be switched into a mode with minimal
      * post processing. </p>
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index 26fce90..8f112f3 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -204,6 +204,12 @@
     public boolean hasArrSupport;
 
     /**
+     * Represents frame rate for the FrameRateCategory Normal and High.
+     * @see android.view.Display#getSuggestedFrameRate(int) for more details.
+     */
+    public FrameRateCategoryRate frameRateCategoryRate;
+
+    /**
      * The default display mode.
      */
     public int defaultModeId;
@@ -443,6 +449,7 @@
                 && modeId == other.modeId
                 && renderFrameRate == other.renderFrameRate
                 && hasArrSupport == other.hasArrSupport
+                && Objects.equals(frameRateCategoryRate, other.frameRateCategoryRate)
                 && defaultModeId == other.defaultModeId
                 && userPreferredModeId == other.userPreferredModeId
                 && Arrays.equals(supportedModes, other.supportedModes)
@@ -505,6 +512,7 @@
         modeId = other.modeId;
         renderFrameRate = other.renderFrameRate;
         hasArrSupport = other.hasArrSupport;
+        frameRateCategoryRate = other.frameRateCategoryRate;
         defaultModeId = other.defaultModeId;
         userPreferredModeId = other.userPreferredModeId;
         supportedModes = Arrays.copyOf(other.supportedModes, other.supportedModes.length);
@@ -562,6 +570,8 @@
         modeId = source.readInt();
         renderFrameRate = source.readFloat();
         hasArrSupport = source.readBoolean();
+        frameRateCategoryRate = source.readParcelable(null,
+                android.view.FrameRateCategoryRate.class);
         defaultModeId = source.readInt();
         userPreferredModeId = source.readInt();
         int nModes = source.readInt();
@@ -636,6 +646,7 @@
         dest.writeInt(modeId);
         dest.writeFloat(renderFrameRate);
         dest.writeBoolean(hasArrSupport);
+        dest.writeParcelable(frameRateCategoryRate, flags);
         dest.writeInt(defaultModeId);
         dest.writeInt(userPreferredModeId);
         dest.writeInt(supportedModes.length);
@@ -883,6 +894,8 @@
         sb.append(renderFrameRate);
         sb.append(", hasArrSupport ");
         sb.append(hasArrSupport);
+        sb.append(", frameRateCategoryRate ");
+        sb.append(frameRateCategoryRate);
         sb.append(", defaultMode ");
         sb.append(defaultModeId);
         sb.append(", userPreferredModeId ");
diff --git a/core/java/android/view/FrameRateCategoryRate.java b/core/java/android/view/FrameRateCategoryRate.java
new file mode 100644
index 0000000..3c674b8
--- /dev/null
+++ b/core/java/android/view/FrameRateCategoryRate.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 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 android.view;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * A class to create and manage FrameRateCategoryRate for
+ * categories Normal and High.
+ * @hide
+ */
+public class FrameRateCategoryRate implements Parcelable {
+
+    private final float mNormal;
+    private final float mHigh;
+
+    /**
+     * Creates a FrameRateCategoryRate with the provided rates
+     * for the categories Normal and High respectively;
+     *
+     * @param normal rate for the category Normal.
+     * @param high rate for the category High.
+     * @hide
+     */
+    public FrameRateCategoryRate(float normal, float high) {
+        this.mNormal = normal;
+        this.mHigh = high;
+    }
+
+    /**
+     * @return the value for the category normal;
+     * @hide
+     */
+    public float getNormal() {
+        return mNormal;
+    }
+
+    /**
+     * @return the value for the category high;
+     * @hide
+     */
+    public float getHigh() {
+        return mHigh;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+        if (!(o instanceof FrameRateCategoryRate)) {
+            return false;
+        }
+        FrameRateCategoryRate that = (FrameRateCategoryRate) o;
+        return mNormal == that.mNormal && mHigh == that.mHigh;
+
+    }
+
+    @Override
+    public int hashCode() {
+        int result = 1;
+        result = 31 * result + Float.hashCode(mNormal);
+        result = 31 * result + Float.hashCode(mHigh);
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "FrameRateCategoryRate {"
+                + "normal=" + mNormal
+                + ", high=" + mHigh
+                + '}';
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeFloat(mNormal);
+        dest.writeFloat(mHigh);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final Creator<FrameRateCategoryRate> CREATOR =
+            new Creator<>() {
+                @Override
+                public FrameRateCategoryRate createFromParcel(Parcel in) {
+                    return new FrameRateCategoryRate(in.readFloat(), in.readFloat());
+                }
+
+                @Override
+                public FrameRateCategoryRate[] newArray(int size) {
+                    return new FrameRateCategoryRate[size];
+                }
+            };
+}
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index ece2a60..0d55544 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -1798,6 +1798,7 @@
         public int activeDisplayModeId;
         public float renderFrameRate;
         public boolean hasArrSupport;
+        public FrameRateCategoryRate frameRateCategoryRate;
 
         public int[] supportedColorModes;
         public int activeColorMode;
@@ -1816,6 +1817,7 @@
                     + ", activeDisplayModeId=" + activeDisplayModeId
                     + ", renderFrameRate=" + renderFrameRate
                     + ", hasArrSupport=" + hasArrSupport
+                    + ", frameRateCategoryRate=" + frameRateCategoryRate
                     + ", supportedColorModes=" + Arrays.toString(supportedColorModes)
                     + ", activeColorMode=" + activeColorMode
                     + ", hdrCapabilities=" + hdrCapabilities
@@ -1836,13 +1838,15 @@
                 && activeColorMode == that.activeColorMode
                 && Objects.equals(hdrCapabilities, that.hdrCapabilities)
                 && preferredBootDisplayMode == that.preferredBootDisplayMode
-                && hasArrSupport == that.hasArrSupport;
+                && hasArrSupport == that.hasArrSupport
+                && Objects.equals(frameRateCategoryRate, that.frameRateCategoryRate);
         }
 
         @Override
         public int hashCode() {
             return Objects.hash(Arrays.hashCode(supportedDisplayModes), activeDisplayModeId,
-                    renderFrameRate, activeColorMode, hdrCapabilities, hasArrSupport);
+                    renderFrameRate, activeColorMode, hdrCapabilities, hasArrSupport,
+                    frameRateCategoryRate);
         }
     }
 
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index f162b74..7fefe17 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -117,6 +117,7 @@
     jfieldID activeDisplayModeId;
     jfieldID renderFrameRate;
     jfieldID hasArrSupport;
+    jfieldID frameRateCategoryRate;
     jfieldID supportedColorModes;
     jfieldID activeColorMode;
     jfieldID hdrCapabilities;
@@ -292,6 +293,11 @@
     jfieldID frameNumber;
 } gStalledTransactionInfoClassInfo;
 
+static struct {
+    jclass clazz;
+    jmethodID ctor;
+} gFrameRateCategoryRateClassInfo;
+
 constexpr ui::Dataspace pickDataspaceFromColorMode(const ui::ColorMode colorMode) {
     switch (colorMode) {
         case ui::ColorMode::DISPLAY_P3:
@@ -1388,6 +1394,13 @@
     return object;
 }
 
+static jobject convertFrameRateCategoryRateToJavaObject(
+        JNIEnv* env, const ui::FrameRateCategoryRate& frameRateCategoryRate) {
+    return env->NewObject(gFrameRateCategoryRateClassInfo.clazz,
+                          gFrameRateCategoryRateClassInfo.ctor, frameRateCategoryRate.getNormal(),
+                          frameRateCategoryRate.getHigh());
+}
+
 static jobject convertDisplayModeToJavaObject(JNIEnv* env, const ui::DisplayMode& config) {
     jobject object = env->NewObject(gDisplayModeClassInfo.clazz, gDisplayModeClassInfo.ctor);
     env->SetIntField(object, gDisplayModeClassInfo.id, config.id);
@@ -1456,6 +1469,8 @@
                      info.activeDisplayModeId);
     env->SetFloatField(object, gDynamicDisplayInfoClassInfo.renderFrameRate, info.renderFrameRate);
     env->SetBooleanField(object, gDynamicDisplayInfoClassInfo.hasArrSupport, info.hasArrSupport);
+    env->SetObjectField(object, gDynamicDisplayInfoClassInfo.frameRateCategoryRate,
+                        convertFrameRateCategoryRateToJavaObject(env, info.frameRateCategoryRate));
     jintArray colorModesArray = env->NewIntArray(info.supportedColorModes.size());
     if (colorModesArray == NULL) {
         jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
@@ -2666,6 +2681,15 @@
             GetFieldIDOrDie(env, dynamicInfoClazz, "renderFrameRate", "F");
     gDynamicDisplayInfoClassInfo.hasArrSupport =
             GetFieldIDOrDie(env, dynamicInfoClazz, "hasArrSupport", "Z");
+
+    gDynamicDisplayInfoClassInfo.frameRateCategoryRate =
+            GetFieldIDOrDie(env, dynamicInfoClazz, "frameRateCategoryRate",
+                            "Landroid/view/FrameRateCategoryRate;");
+    jclass frameRateCategoryRateClazz = FindClassOrDie(env, "android/view/FrameRateCategoryRate");
+    gFrameRateCategoryRateClassInfo.clazz = MakeGlobalRefOrDie(env, frameRateCategoryRateClazz);
+    gFrameRateCategoryRateClassInfo.ctor =
+            GetMethodIDOrDie(env, frameRateCategoryRateClazz, "<init>", "(FF)V");
+
     gDynamicDisplayInfoClassInfo.supportedColorModes =
             GetFieldIDOrDie(env, dynamicInfoClazz, "supportedColorModes", "[I");
     gDynamicDisplayInfoClassInfo.activeColorMode =
diff --git a/services/core/java/com/android/server/display/DisplayDeviceInfo.java b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
index 0807c70..4ad7c10 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceInfo.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
@@ -26,6 +26,7 @@
 import android.view.DisplayCutout;
 import android.view.DisplayEventReceiver;
 import android.view.DisplayShape;
+import android.view.FrameRateCategoryRate;
 import android.view.RoundedCorners;
 import android.view.Surface;
 
@@ -300,6 +301,11 @@
     public boolean hasArrSupport;
 
     /**
+     * Represents frame rate for the FrameRateCategory Normal and High.
+     * @see android.view.Display#getSuggestedFrameRate(int) for more details.
+     */
+    public FrameRateCategoryRate frameRateCategoryRate;
+    /**
      * The default mode of the display.
      */
     public int defaultModeId;
@@ -548,7 +554,8 @@
                 || !Objects.equals(roundedCorners, other.roundedCorners)
                 || installOrientation != other.installOrientation
                 || !Objects.equals(displayShape, other.displayShape)
-                || hasArrSupport != other.hasArrSupport) {
+                || hasArrSupport != other.hasArrSupport
+                || !Objects.equals(frameRateCategoryRate, other.frameRateCategoryRate)) {
             diff |= DIFF_OTHER;
         }
         return diff;
@@ -567,6 +574,7 @@
         modeId = other.modeId;
         renderFrameRate = other.renderFrameRate;
         hasArrSupport = other.hasArrSupport;
+        frameRateCategoryRate = other.frameRateCategoryRate;
         defaultModeId = other.defaultModeId;
         userPreferredModeId = other.userPreferredModeId;
         supportedModes = other.supportedModes;
@@ -612,6 +620,7 @@
         sb.append(", modeId ").append(modeId);
         sb.append(", renderFrameRate ").append(renderFrameRate);
         sb.append(", hasArrSupport ").append(hasArrSupport);
+        sb.append(", frameRateCategoryRate ").append(frameRateCategoryRate);
         sb.append(", defaultModeId ").append(defaultModeId);
         sb.append(", userPreferredModeId ").append(userPreferredModeId);
         sb.append(", supportedModes ").append(Arrays.toString(supportedModes));
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index f9c3a46..a4bb8c3 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -45,6 +45,7 @@
 import android.view.DisplayCutout;
 import android.view.DisplayEventReceiver;
 import android.view.DisplayShape;
+import android.view.FrameRateCategoryRate;
 import android.view.RoundedCorners;
 import android.view.SurfaceControl;
 
@@ -247,6 +248,7 @@
         private boolean mDisplayModeSpecsInvalid;
         private int mActiveColorMode;
         private boolean mHasArrSupport;
+        private FrameRateCategoryRate mFrameRateCategoryRate;
         private Display.HdrCapabilities mHdrCapabilities;
         private boolean mAllmSupported;
         private boolean mGameContentTypeSupported;
@@ -313,6 +315,7 @@
             changed |= updateAllmSupport(dynamicInfo.autoLowLatencyModeSupported);
             changed |= updateGameContentTypeSupport(dynamicInfo.gameContentTypeSupported);
             changed |= updateHasArrSupportLocked(dynamicInfo.hasArrSupport);
+            changed |= updateFrameRateCategoryRatesLocked(dynamicInfo.frameRateCategoryRate);
 
             if (changed) {
                 mHavePendingChanges = true;
@@ -604,6 +607,15 @@
             return true;
         }
 
+        private boolean updateFrameRateCategoryRatesLocked(
+                FrameRateCategoryRate newFrameRateCategoryRate) {
+            if (Objects.equals(mFrameRateCategoryRate, newFrameRateCategoryRate)) {
+                return false;
+            }
+            mFrameRateCategoryRate = newFrameRateCategoryRate;
+            return true;
+        }
+
         private boolean updateHasArrSupportLocked(boolean newHasArrSupport) {
             if (mHasArrSupport == newHasArrSupport) {
                 return false;
@@ -695,6 +707,7 @@
                 }
                 mInfo.hdrCapabilities = mHdrCapabilities;
                 mInfo.hasArrSupport = mHasArrSupport;
+                mInfo.frameRateCategoryRate = mFrameRateCategoryRate;
                 mInfo.appVsyncOffsetNanos = mActiveSfDisplayMode.appVsyncOffsetNanos;
                 mInfo.presentationDeadlineNanos = mActiveSfDisplayMode.presentationDeadlineNanos;
                 mInfo.state = mState;
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java
index 074a4d8..7cfdcaf 100644
--- a/services/core/java/com/android/server/display/LogicalDisplay.java
+++ b/services/core/java/com/android/server/display/LogicalDisplay.java
@@ -507,6 +507,7 @@
             mBaseDisplayInfo.modeId = deviceInfo.modeId;
             mBaseDisplayInfo.renderFrameRate = deviceInfo.renderFrameRate;
             mBaseDisplayInfo.hasArrSupport = deviceInfo.hasArrSupport;
+            mBaseDisplayInfo.frameRateCategoryRate = deviceInfo.frameRateCategoryRate;
             mBaseDisplayInfo.defaultModeId = deviceInfo.defaultModeId;
             mBaseDisplayInfo.userPreferredModeId = deviceInfo.userPreferredModeId;
             mBaseDisplayInfo.supportedModes = Arrays.copyOf(
diff --git a/services/core/java/com/android/server/display/feature/display_flags.aconfig b/services/core/java/com/android/server/display/feature/display_flags.aconfig
index 36cadf5..f49608b 100644
--- a/services/core/java/com/android/server/display/feature/display_flags.aconfig
+++ b/services/core/java/com/android/server/display/feature/display_flags.aconfig
@@ -430,3 +430,11 @@
     bug: "350617205"
     is_fixed_read_only: true
 }
+
+flag {
+    name: "enable_get_suggested_frame_rate"
+    namespace: "core_graphics"
+    description: "Flag for an API to get suggested frame rates"
+    bug: "361433796"
+    is_fixed_read_only: true
+}
diff --git a/services/core/java/com/android/server/wm/DeferredDisplayUpdater.java b/services/core/java/com/android/server/wm/DeferredDisplayUpdater.java
index cbe3d79..6f8c17a 100644
--- a/services/core/java/com/android/server/wm/DeferredDisplayUpdater.java
+++ b/services/core/java/com/android/server/wm/DeferredDisplayUpdater.java
@@ -402,6 +402,7 @@
                 || first.modeId != second.modeId
                 || first.renderFrameRate != second.renderFrameRate
                 || first.hasArrSupport != second.hasArrSupport
+                || !Objects.equals(first.frameRateCategoryRate, second.frameRateCategoryRate)
                 || first.defaultModeId != second.defaultModeId
                 || first.userPreferredModeId != second.userPreferredModeId
                 || !Arrays.equals(first.supportedModes, second.supportedModes)
diff --git a/services/tests/wmtests/src/com/android/server/wm/DeferredDisplayUpdaterDiffTest.java b/services/tests/wmtests/src/com/android/server/wm/DeferredDisplayUpdaterDiffTest.java
index 44b69f1..c9c31df 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DeferredDisplayUpdaterDiffTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DeferredDisplayUpdaterDiffTest.java
@@ -39,6 +39,7 @@
 import android.view.DisplayCutout;
 import android.view.DisplayInfo;
 import android.view.DisplayShape;
+import android.view.FrameRateCategoryRate;
 import android.view.RoundedCorner;
 import android.view.RoundedCorners;
 import android.view.SurfaceControl.RefreshRateRange;
@@ -235,6 +236,9 @@
         } else if (type.isArray() && type.getComponentType().equals(Display.Mode.class)) {
             field.set(first, new Display.Mode[]{new Display.Mode(100, 200, 300)});
             field.set(second, new Display.Mode[]{new Display.Mode(10, 20, 30)});
+        } else if (type.equals(FrameRateCategoryRate.class)) {
+            field.set(first, new FrameRateCategoryRate(16666667, 11111111));
+            field.set(second, new FrameRateCategoryRate(11111111, 8333333));
         } else {
             throw new IllegalArgumentException("Field " + field
                     + " is not supported by this test, please add implementation of setting "