Add setFrameRateCategory surface API

Bug: 284911776
Test: atest CtsSurfaceControlTestsStaging
Test: atest libsurfaceflinger_unittest
Change-Id: Ia804a63198ff096d1e5ffedf6046a0350963b8ed
diff --git a/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
index f64ba2a..93438d8 100644
--- a/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
+++ b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
@@ -335,6 +335,17 @@
         mLifecycleManager.applyTransactions(transactions);
     }
 
+    void setFrameRateCategory(uint32_t id, int8_t frameRateCategory) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+
+        transactions.back().states.front().state.what = layer_state_t::eFrameRateCategoryChanged;
+        transactions.back().states.front().layerId = id;
+        transactions.back().states.front().state.frameRateCategory = frameRateCategory;
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
     void setRoundedCorners(uint32_t id, float radius) {
         std::vector<TransactionState> transactions;
         transactions.emplace_back();
diff --git a/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp b/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp
index 85d86a7..51b5b05 100644
--- a/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp
@@ -437,6 +437,117 @@
     EXPECT_EQ(0, frequentLayerCount(time));
 }
 
+TEST_F(LayerHistoryTest, oneLayerExplicitCategory) {
+    auto layer = createLayer();
+    EXPECT_CALL(*layer, isVisible()).WillRepeatedly(Return(true));
+    EXPECT_CALL(*layer, getFrameRateForLayerTree())
+            .WillRepeatedly(
+                    Return(Layer::FrameRate(0_Hz, Layer::FrameRateCompatibility::Default,
+                                            Seamlessness::OnlySeamless, FrameRateCategory::High)));
+
+    EXPECT_EQ(1, layerCount());
+    EXPECT_EQ(0, activeLayerCount());
+
+    nsecs_t time = systemTime();
+    for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE; i++) {
+        history().record(layer->getSequence(), layer->getLayerProps(), time, time,
+                         LayerHistory::LayerUpdateType::Buffer);
+        time += HI_FPS_PERIOD;
+    }
+
+    ASSERT_EQ(1, summarizeLayerHistory(time).size());
+    EXPECT_EQ(1, activeLayerCount());
+    EXPECT_EQ(1, frequentLayerCount(time));
+    // First LayerRequirement is the frame rate specification
+    EXPECT_EQ(LayerHistory::LayerVoteType::ExplicitCategory, summarizeLayerHistory(time)[0].vote);
+    EXPECT_EQ(0_Hz, summarizeLayerHistory(time)[0].desiredRefreshRate);
+    EXPECT_EQ(FrameRateCategory::High, summarizeLayerHistory(time)[0].frameRateCategory);
+
+    // layer became inactive, but the vote stays
+    setDefaultLayerVote(layer.get(), LayerHistory::LayerVoteType::Heuristic);
+    time += MAX_ACTIVE_LAYER_PERIOD_NS.count();
+    ASSERT_EQ(1, summarizeLayerHistory(time).size());
+    EXPECT_EQ(1, activeLayerCount());
+    EXPECT_EQ(0, frequentLayerCount(time));
+    EXPECT_EQ(LayerHistory::LayerVoteType::ExplicitCategory, summarizeLayerHistory(time)[0].vote);
+    EXPECT_EQ(0_Hz, summarizeLayerHistory(time)[0].desiredRefreshRate);
+    EXPECT_EQ(FrameRateCategory::High, summarizeLayerHistory(time)[0].frameRateCategory);
+}
+
+// This test case should be the same as oneLayerNoVote except instead of layer vote is NoVote,
+// the category is NoPreference.
+TEST_F(LayerHistoryTest, oneLayerCategoryNoPreference) {
+    auto layer = createLayer();
+    EXPECT_CALL(*layer, isVisible()).WillRepeatedly(Return(true));
+    EXPECT_CALL(*layer, getFrameRateForLayerTree())
+            .WillRepeatedly(Return(Layer::FrameRate(0_Hz, Layer::FrameRateCompatibility::Default,
+                                                    Seamlessness::OnlySeamless,
+                                                    FrameRateCategory::NoPreference)));
+
+    EXPECT_EQ(1, layerCount());
+    EXPECT_EQ(0, activeLayerCount());
+
+    nsecs_t time = systemTime();
+    for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE; i++) {
+        history().record(layer->getSequence(), layer->getLayerProps(), time, time,
+                         LayerHistory::LayerUpdateType::Buffer);
+        time += HI_FPS_PERIOD;
+    }
+
+    ASSERT_TRUE(summarizeLayerHistory(time).empty());
+    EXPECT_EQ(1, activeLayerCount());
+    EXPECT_EQ(1, frequentLayerCount(time));
+
+    // layer became inactive
+    time += MAX_ACTIVE_LAYER_PERIOD_NS.count();
+    ASSERT_TRUE(summarizeLayerHistory(time).empty());
+    EXPECT_EQ(0, activeLayerCount());
+    EXPECT_EQ(0, frequentLayerCount(time));
+}
+
+TEST_F(LayerHistoryTest, oneLayerExplicitVoteWithCategory) {
+    auto layer = createLayer();
+    EXPECT_CALL(*layer, isVisible()).WillRepeatedly(Return(true));
+    EXPECT_CALL(*layer, getFrameRateForLayerTree())
+            .WillRepeatedly(
+                    Return(Layer::FrameRate(73.4_Hz, Layer::FrameRateCompatibility::Default,
+                                            Seamlessness::OnlySeamless, FrameRateCategory::High)));
+
+    EXPECT_EQ(1, layerCount());
+    EXPECT_EQ(0, activeLayerCount());
+
+    nsecs_t time = systemTime();
+    for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE; i++) {
+        history().record(layer->getSequence(), layer->getLayerProps(), time, time,
+                         LayerHistory::LayerUpdateType::Buffer);
+        time += HI_FPS_PERIOD;
+    }
+
+    // There are 2 LayerRequirement's due to the frame rate category.
+    ASSERT_EQ(2, summarizeLayerHistory(time).size());
+    EXPECT_EQ(1, activeLayerCount());
+    EXPECT_EQ(1, frequentLayerCount(time));
+    // First LayerRequirement is the layer's category specification
+    EXPECT_EQ(LayerHistory::LayerVoteType::ExplicitCategory, summarizeLayerHistory(time)[0].vote);
+    EXPECT_EQ(73.4_Hz, summarizeLayerHistory(time)[0].desiredRefreshRate);
+    EXPECT_EQ(FrameRateCategory::High, summarizeLayerHistory(time)[0].frameRateCategory);
+
+    // Second LayerRequirement is the frame rate specification
+    EXPECT_EQ(LayerHistory::LayerVoteType::ExplicitDefault, summarizeLayerHistory(time)[1].vote);
+    EXPECT_EQ(73.4_Hz, summarizeLayerHistory(time)[1].desiredRefreshRate);
+    EXPECT_EQ(FrameRateCategory::High, summarizeLayerHistory(time)[1].frameRateCategory);
+
+    // layer became inactive, but the vote stays
+    setDefaultLayerVote(layer.get(), LayerHistory::LayerVoteType::Heuristic);
+    time += MAX_ACTIVE_LAYER_PERIOD_NS.count();
+    ASSERT_EQ(2, summarizeLayerHistory(time).size());
+    EXPECT_EQ(1, activeLayerCount());
+    EXPECT_EQ(0, frequentLayerCount(time));
+    EXPECT_EQ(LayerHistory::LayerVoteType::ExplicitCategory, summarizeLayerHistory(time)[0].vote);
+    EXPECT_EQ(73.4_Hz, summarizeLayerHistory(time)[0].desiredRefreshRate);
+    EXPECT_EQ(FrameRateCategory::High, summarizeLayerHistory(time)[0].frameRateCategory);
+}
+
 TEST_F(LayerHistoryTest, multipleLayers) {
     auto layer1 = createLayer("A");
     auto layer2 = createLayer("B");
diff --git a/services/surfaceflinger/tests/unittests/LayerInfoTest.cpp b/services/surfaceflinger/tests/unittests/LayerInfoTest.cpp
index 5c2d2e1..e0133d6 100644
--- a/services/surfaceflinger/tests/unittests/LayerInfoTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerInfoTest.cpp
@@ -24,13 +24,23 @@
 #include "FpsOps.h"
 #include "Scheduler/LayerHistory.h"
 #include "Scheduler/LayerInfo.h"
+#include "TestableScheduler.h"
+#include "TestableSurfaceFlinger.h"
+#include "mock/MockSchedulerCallback.h"
 
 namespace android::scheduler {
 
+using android::mock::createDisplayMode;
+
 class LayerInfoTest : public testing::Test {
 protected:
     using FrameTimeData = LayerInfo::FrameTimeData;
 
+    static constexpr Fps LO_FPS = 30_Hz;
+    static constexpr Fps HI_FPS = 90_Hz;
+
+    LayerInfoTest() { mFlinger.resetScheduler(mScheduler); }
+
     void setFrameTimes(const std::deque<FrameTimeData>& frameTimes) {
         layerInfo.mFrameTimes = frameTimes;
     }
@@ -43,6 +53,16 @@
     auto calculateAverageFrameTime() { return layerInfo.calculateAverageFrameTime(); }
 
     LayerInfo layerInfo{"TestLayerInfo", 0, LayerHistory::LayerVoteType::Heuristic};
+
+    std::shared_ptr<RefreshRateSelector> mSelector =
+            std::make_shared<RefreshRateSelector>(makeModes(createDisplayMode(DisplayModeId(0),
+                                                                              LO_FPS),
+                                                            createDisplayMode(DisplayModeId(1),
+                                                                              HI_FPS)),
+                                                  DisplayModeId(0));
+    mock::SchedulerCallback mSchedulerCallback;
+    TestableScheduler* mScheduler = new TestableScheduler(mSelector, mSchedulerCallback);
+    TestableSurfaceFlinger mFlinger;
 };
 
 namespace {
@@ -171,5 +191,63 @@
     ASSERT_EQ(kExpectedFps, Fps::fromPeriodNsecs(*averageFrameTime));
 }
 
+TEST_F(LayerInfoTest, getRefreshRateVote_explicitVote) {
+    LayerInfo::LayerVote vote = {.type = LayerHistory::LayerVoteType::ExplicitDefault,
+                                 .fps = 20_Hz};
+    layerInfo.setLayerVote(vote);
+
+    auto actualVotes =
+            layerInfo.getRefreshRateVote(*mScheduler->refreshRateSelector(), systemTime());
+    ASSERT_EQ(actualVotes.size(), 1u);
+    ASSERT_EQ(actualVotes[0].type, vote.type);
+    ASSERT_EQ(actualVotes[0].fps, vote.fps);
+    ASSERT_EQ(actualVotes[0].seamlessness, vote.seamlessness);
+    ASSERT_EQ(actualVotes[0].category, vote.category);
+}
+
+TEST_F(LayerInfoTest, getRefreshRateVote_explicitVoteWithCategory) {
+    LayerInfo::LayerVote vote = {.type = LayerHistory::LayerVoteType::ExplicitDefault,
+                                 .fps = 20_Hz,
+                                 .category = FrameRateCategory::High};
+    layerInfo.setLayerVote(vote);
+
+    auto actualVotes =
+            layerInfo.getRefreshRateVote(*mScheduler->refreshRateSelector(), systemTime());
+    ASSERT_EQ(actualVotes.size(), 2u);
+    ASSERT_EQ(actualVotes[0].type, LayerHistory::LayerVoteType::ExplicitCategory);
+    ASSERT_EQ(actualVotes[0].category, vote.category);
+    ASSERT_EQ(actualVotes[1].type, vote.type);
+    ASSERT_EQ(actualVotes[1].fps, vote.fps);
+    ASSERT_EQ(actualVotes[1].seamlessness, vote.seamlessness);
+    ASSERT_EQ(actualVotes[1].category, vote.category);
+}
+
+TEST_F(LayerInfoTest, getRefreshRateVote_explicitCategory) {
+    // When a layer only has a category set, the LayerVoteType should be the LayerInfo's default.
+    // The most common case should be Heuristic.
+    LayerInfo::LayerVote vote = {.type = LayerHistory::LayerVoteType::ExplicitDefault,
+                                 .category = FrameRateCategory::High};
+    layerInfo.setLayerVote(vote);
+
+    auto actualVotes =
+            layerInfo.getRefreshRateVote(*mScheduler->refreshRateSelector(), systemTime());
+    ASSERT_EQ(actualVotes.size(), 1u);
+    ASSERT_EQ(actualVotes[0].type, LayerHistory::LayerVoteType::ExplicitCategory);
+    ASSERT_EQ(actualVotes[0].category, vote.category);
+}
+
+TEST_F(LayerInfoTest, getRefreshRateVote_noData) {
+    LayerInfo::LayerVote vote = {
+            .type = LayerHistory::LayerVoteType::Heuristic,
+    };
+    layerInfo.setLayerVote(vote);
+
+    auto actualVotes =
+            layerInfo.getRefreshRateVote(*mScheduler->refreshRateSelector(), systemTime());
+    ASSERT_EQ(actualVotes.size(), 1u);
+    ASSERT_EQ(actualVotes[0].type, LayerHistory::LayerVoteType::Max);
+    ASSERT_EQ(actualVotes[0].fps, vote.fps);
+}
+
 } // namespace
 } // namespace android::scheduler
diff --git a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
index 84c3775..67cd4c6 100644
--- a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
@@ -314,13 +314,15 @@
     mLifecycleManager.applyTransactions(transactions);
     UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
 
-    EXPECT_EQ(getSnapshot(11)->frameRate.rate.getIntValue(), 90);
-    EXPECT_EQ(getSnapshot(11)->frameRate.type, scheduler::LayerInfo::FrameRateCompatibility::Exact);
-    EXPECT_EQ(getSnapshot(111)->frameRate.rate.getIntValue(), 90);
-    EXPECT_EQ(getSnapshot(111)->frameRate.type,
+    EXPECT_EQ(getSnapshot(11)->frameRate.vote.rate.getIntValue(), 90);
+    EXPECT_EQ(getSnapshot(11)->frameRate.vote.type,
               scheduler::LayerInfo::FrameRateCompatibility::Exact);
-    EXPECT_EQ(getSnapshot(1)->frameRate.rate.getIntValue(), 0);
-    EXPECT_EQ(getSnapshot(1)->frameRate.type, scheduler::LayerInfo::FrameRateCompatibility::NoVote);
+    EXPECT_EQ(getSnapshot(111)->frameRate.vote.rate.getIntValue(), 90);
+    EXPECT_EQ(getSnapshot(111)->frameRate.vote.type,
+              scheduler::LayerInfo::FrameRateCompatibility::Exact);
+    EXPECT_EQ(getSnapshot(1)->frameRate.vote.rate.getIntValue(), 0);
+    EXPECT_EQ(getSnapshot(1)->frameRate.vote.type,
+              scheduler::LayerInfo::FrameRateCompatibility::NoVote);
 }
 
 TEST_F(LayerSnapshotTest, CanCropTouchableRegion) {
@@ -525,21 +527,21 @@
 
     UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
     // verify parent is gets no vote
-    EXPECT_FALSE(getSnapshot({.id = 1})->frameRate.rate.isValid());
-    EXPECT_EQ(getSnapshot({.id = 1})->frameRate.type,
+    EXPECT_FALSE(getSnapshot({.id = 1})->frameRate.vote.rate.isValid());
+    EXPECT_EQ(getSnapshot({.id = 1})->frameRate.vote.type,
               scheduler::LayerInfo::FrameRateCompatibility::NoVote);
     EXPECT_TRUE(getSnapshot({.id = 1})->changes.test(RequestedLayerState::Changes::FrameRate));
 
     // verify layer and children get the requested votes
-    EXPECT_TRUE(getSnapshot({.id = 11})->frameRate.rate.isValid());
-    EXPECT_EQ(getSnapshot({.id = 11})->frameRate.rate.getValue(), 244.f);
-    EXPECT_EQ(getSnapshot({.id = 11})->frameRate.type,
+    EXPECT_TRUE(getSnapshot({.id = 11})->frameRate.vote.rate.isValid());
+    EXPECT_EQ(getSnapshot({.id = 11})->frameRate.vote.rate.getValue(), 244.f);
+    EXPECT_EQ(getSnapshot({.id = 11})->frameRate.vote.type,
               scheduler::LayerInfo::FrameRateCompatibility::Default);
     EXPECT_TRUE(getSnapshot({.id = 11})->changes.test(RequestedLayerState::Changes::FrameRate));
 
-    EXPECT_TRUE(getSnapshot({.id = 111})->frameRate.rate.isValid());
-    EXPECT_EQ(getSnapshot({.id = 111})->frameRate.rate.getValue(), 244.f);
-    EXPECT_EQ(getSnapshot({.id = 111})->frameRate.type,
+    EXPECT_TRUE(getSnapshot({.id = 111})->frameRate.vote.rate.isValid());
+    EXPECT_EQ(getSnapshot({.id = 111})->frameRate.vote.rate.getValue(), 244.f);
+    EXPECT_EQ(getSnapshot({.id = 111})->frameRate.vote.type,
               scheduler::LayerInfo::FrameRateCompatibility::Default);
     EXPECT_TRUE(getSnapshot({.id = 111})->changes.test(RequestedLayerState::Changes::FrameRate));
 
@@ -549,24 +551,24 @@
     std::vector<uint32_t> expected = {1, 11, 111, 122, 1221, 12, 121, 13, 2};
     UPDATE_AND_VERIFY(mSnapshotBuilder, expected);
     // verify parent is gets no vote
-    EXPECT_FALSE(getSnapshot({.id = 1})->frameRate.rate.isValid());
-    EXPECT_EQ(getSnapshot({.id = 1})->frameRate.type,
+    EXPECT_FALSE(getSnapshot({.id = 1})->frameRate.vote.rate.isValid());
+    EXPECT_EQ(getSnapshot({.id = 1})->frameRate.vote.type,
               scheduler::LayerInfo::FrameRateCompatibility::NoVote);
 
     // verify layer and children get the requested votes
-    EXPECT_TRUE(getSnapshot({.id = 11})->frameRate.rate.isValid());
-    EXPECT_EQ(getSnapshot({.id = 11})->frameRate.rate.getValue(), 244.f);
-    EXPECT_EQ(getSnapshot({.id = 11})->frameRate.type,
+    EXPECT_TRUE(getSnapshot({.id = 11})->frameRate.vote.rate.isValid());
+    EXPECT_EQ(getSnapshot({.id = 11})->frameRate.vote.rate.getValue(), 244.f);
+    EXPECT_EQ(getSnapshot({.id = 11})->frameRate.vote.type,
               scheduler::LayerInfo::FrameRateCompatibility::Default);
 
-    EXPECT_TRUE(getSnapshot({.id = 111})->frameRate.rate.isValid());
-    EXPECT_EQ(getSnapshot({.id = 111})->frameRate.rate.getValue(), 244.f);
-    EXPECT_EQ(getSnapshot({.id = 111})->frameRate.type,
+    EXPECT_TRUE(getSnapshot({.id = 111})->frameRate.vote.rate.isValid());
+    EXPECT_EQ(getSnapshot({.id = 111})->frameRate.vote.rate.getValue(), 244.f);
+    EXPECT_EQ(getSnapshot({.id = 111})->frameRate.vote.type,
               scheduler::LayerInfo::FrameRateCompatibility::Default);
 
-    EXPECT_TRUE(getSnapshot({.id = 122})->frameRate.rate.isValid());
-    EXPECT_EQ(getSnapshot({.id = 122})->frameRate.rate.getValue(), 244.f);
-    EXPECT_EQ(getSnapshot({.id = 122})->frameRate.type,
+    EXPECT_TRUE(getSnapshot({.id = 122})->frameRate.vote.rate.isValid());
+    EXPECT_EQ(getSnapshot({.id = 122})->frameRate.vote.rate.getValue(), 244.f);
+    EXPECT_EQ(getSnapshot({.id = 122})->frameRate.vote.type,
               scheduler::LayerInfo::FrameRateCompatibility::Default);
     EXPECT_TRUE(getSnapshot({.id = 122})->changes.test(RequestedLayerState::Changes::FrameRate));
 
@@ -576,31 +578,31 @@
     UPDATE_AND_VERIFY(mSnapshotBuilder, expected);
 
     // verify old parent has invalid framerate (default)
-    EXPECT_FALSE(getSnapshot({.id = 1})->frameRate.rate.isValid());
-    EXPECT_EQ(getSnapshot({.id = 1})->frameRate.type,
+    EXPECT_FALSE(getSnapshot({.id = 1})->frameRate.vote.rate.isValid());
+    EXPECT_EQ(getSnapshot({.id = 1})->frameRate.vote.type,
               scheduler::LayerInfo::FrameRateCompatibility::Default);
     EXPECT_TRUE(getSnapshot({.id = 1})->changes.test(RequestedLayerState::Changes::FrameRate));
 
     // verify new parent get no vote
-    EXPECT_FALSE(getSnapshot({.id = 2})->frameRate.rate.isValid());
-    EXPECT_EQ(getSnapshot({.id = 2})->frameRate.type,
+    EXPECT_FALSE(getSnapshot({.id = 2})->frameRate.vote.rate.isValid());
+    EXPECT_EQ(getSnapshot({.id = 2})->frameRate.vote.type,
               scheduler::LayerInfo::FrameRateCompatibility::NoVote);
     EXPECT_TRUE(getSnapshot({.id = 2})->changes.test(RequestedLayerState::Changes::FrameRate));
 
     // verify layer and children get the requested votes (unchanged)
-    EXPECT_TRUE(getSnapshot({.id = 11})->frameRate.rate.isValid());
-    EXPECT_EQ(getSnapshot({.id = 11})->frameRate.rate.getValue(), 244.f);
-    EXPECT_EQ(getSnapshot({.id = 11})->frameRate.type,
+    EXPECT_TRUE(getSnapshot({.id = 11})->frameRate.vote.rate.isValid());
+    EXPECT_EQ(getSnapshot({.id = 11})->frameRate.vote.rate.getValue(), 244.f);
+    EXPECT_EQ(getSnapshot({.id = 11})->frameRate.vote.type,
               scheduler::LayerInfo::FrameRateCompatibility::Default);
 
-    EXPECT_TRUE(getSnapshot({.id = 111})->frameRate.rate.isValid());
-    EXPECT_EQ(getSnapshot({.id = 111})->frameRate.rate.getValue(), 244.f);
-    EXPECT_EQ(getSnapshot({.id = 111})->frameRate.type,
+    EXPECT_TRUE(getSnapshot({.id = 111})->frameRate.vote.rate.isValid());
+    EXPECT_EQ(getSnapshot({.id = 111})->frameRate.vote.rate.getValue(), 244.f);
+    EXPECT_EQ(getSnapshot({.id = 111})->frameRate.vote.type,
               scheduler::LayerInfo::FrameRateCompatibility::Default);
 
-    EXPECT_TRUE(getSnapshot({.id = 122})->frameRate.rate.isValid());
-    EXPECT_EQ(getSnapshot({.id = 122})->frameRate.rate.getValue(), 244.f);
-    EXPECT_EQ(getSnapshot({.id = 122})->frameRate.type,
+    EXPECT_TRUE(getSnapshot({.id = 122})->frameRate.vote.rate.isValid());
+    EXPECT_EQ(getSnapshot({.id = 122})->frameRate.vote.rate.getValue(), 244.f);
+    EXPECT_EQ(getSnapshot({.id = 122})->frameRate.vote.type,
               scheduler::LayerInfo::FrameRateCompatibility::Default);
 }
 
@@ -610,6 +612,112 @@
     EXPECT_EQ(getSnapshot({.id = 1})->dataspace, ui::Dataspace::V0_SRGB);
 }
 
+// This test is similar to "frameRate" test case but checks that the setFrameRateCategory API
+// interaction also works correctly with the setFrameRate API within SF frontend.
+TEST_F(LayerSnapshotTest, frameRateWithCategory) {
+    // ROOT
+    // ├── 1
+    // │   ├── 11 (frame rate set to 244.f)
+    // │   │   └── 111
+    // │   ├── 12
+    // │   │   ├── 121
+    // │   │   └── 122 (frame rate category set to Normal)
+    // │   │       └── 1221
+    // │   └── 13
+    // └── 2
+    setFrameRate(11, 244.f, 0, 0);
+    setFrameRateCategory(122, 3 /* Normal */);
+
+    UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
+    // verify parent 1 gets no vote
+    EXPECT_FALSE(getSnapshot({.id = 1})->frameRate.vote.rate.isValid());
+    EXPECT_EQ(getSnapshot({.id = 1})->frameRate.vote.type,
+              scheduler::LayerInfo::FrameRateCompatibility::NoVote);
+    EXPECT_TRUE(getSnapshot({.id = 1})->changes.test(RequestedLayerState::Changes::FrameRate));
+
+    // verify layer 11 and children 111 get the requested votes
+    EXPECT_TRUE(getSnapshot({.id = 11})->frameRate.vote.rate.isValid());
+    EXPECT_EQ(getSnapshot({.id = 11})->frameRate.vote.rate.getValue(), 244.f);
+    EXPECT_EQ(getSnapshot({.id = 11})->frameRate.vote.type,
+              scheduler::LayerInfo::FrameRateCompatibility::Default);
+    EXPECT_TRUE(getSnapshot({.id = 11})->changes.test(RequestedLayerState::Changes::FrameRate));
+
+    EXPECT_TRUE(getSnapshot({.id = 111})->frameRate.vote.rate.isValid());
+    EXPECT_EQ(getSnapshot({.id = 111})->frameRate.vote.rate.getValue(), 244.f);
+    EXPECT_EQ(getSnapshot({.id = 111})->frameRate.vote.type,
+              scheduler::LayerInfo::FrameRateCompatibility::Default);
+    EXPECT_TRUE(getSnapshot({.id = 111})->changes.test(RequestedLayerState::Changes::FrameRate));
+
+    // verify parent 12 gets no vote
+    EXPECT_FALSE(getSnapshot({.id = 12})->frameRate.vote.rate.isValid());
+    EXPECT_EQ(getSnapshot({.id = 12})->frameRate.vote.type,
+              scheduler::LayerInfo::FrameRateCompatibility::NoVote);
+    EXPECT_TRUE(getSnapshot({.id = 12})->changes.test(RequestedLayerState::Changes::FrameRate));
+
+    // verify layer 122 and children 1221 get the requested votes
+    EXPECT_FALSE(getSnapshot({.id = 122})->frameRate.vote.rate.isValid());
+    EXPECT_TRUE(getSnapshot({.id = 122})->frameRate.isValid());
+    EXPECT_EQ(getSnapshot({.id = 122})->frameRate.vote.type,
+              scheduler::LayerInfo::FrameRateCompatibility::Default);
+    EXPECT_EQ(getSnapshot({.id = 122})->frameRate.category, FrameRateCategory::Normal);
+    EXPECT_TRUE(getSnapshot({.id = 122})->changes.test(RequestedLayerState::Changes::FrameRate));
+
+    EXPECT_FALSE(getSnapshot({.id = 1221})->frameRate.vote.rate.isValid());
+    EXPECT_TRUE(getSnapshot({.id = 1221})->frameRate.isValid());
+    EXPECT_EQ(getSnapshot({.id = 1221})->frameRate.vote.type,
+              scheduler::LayerInfo::FrameRateCompatibility::Default);
+    EXPECT_EQ(getSnapshot({.id = 1221})->frameRate.category, FrameRateCategory::Normal);
+    EXPECT_TRUE(getSnapshot({.id = 1221})->changes.test(RequestedLayerState::Changes::FrameRate));
+
+    // reparent and verify the child does NOT get the new parent's framerate because it already has
+    // the frame rate category specified.
+    // ROOT
+    //  ├─1
+    //  │  ├─11 (frame rate set to 244.f)
+    //  │  │  ├─111
+    //  │  │  └─122 (frame rate category set to Normal)
+    //  │  │     └─1221
+    //  │  ├─12
+    //  │  │  └─121
+    //  │  └─13
+    //  └─2
+    reparentLayer(122, 11);
+
+    std::vector<uint32_t> expected = {1, 11, 111, 122, 1221, 12, 121, 13, 2};
+    UPDATE_AND_VERIFY(mSnapshotBuilder, expected);
+    // verify parent is gets no vote
+    EXPECT_FALSE(getSnapshot({.id = 1})->frameRate.vote.rate.isValid());
+    EXPECT_EQ(getSnapshot({.id = 1})->frameRate.vote.type,
+              scheduler::LayerInfo::FrameRateCompatibility::NoVote);
+
+    // verify layer 11 and children 111 get the requested votes
+    EXPECT_TRUE(getSnapshot({.id = 11})->frameRate.vote.rate.isValid());
+    EXPECT_EQ(getSnapshot({.id = 11})->frameRate.vote.rate.getValue(), 244.f);
+    EXPECT_EQ(getSnapshot({.id = 11})->frameRate.vote.type,
+              scheduler::LayerInfo::FrameRateCompatibility::Default);
+
+    EXPECT_TRUE(getSnapshot({.id = 111})->frameRate.vote.rate.isValid());
+    EXPECT_EQ(getSnapshot({.id = 111})->frameRate.vote.rate.getValue(), 244.f);
+    EXPECT_EQ(getSnapshot({.id = 111})->frameRate.vote.type,
+              scheduler::LayerInfo::FrameRateCompatibility::Default);
+
+    // verify layer 122 and children 1221 get the requested category vote (unchanged from
+    // reparenting)
+    EXPECT_FALSE(getSnapshot({.id = 122})->frameRate.vote.rate.isValid());
+    EXPECT_TRUE(getSnapshot({.id = 122})->frameRate.isValid());
+    EXPECT_EQ(getSnapshot({.id = 122})->frameRate.vote.type,
+              scheduler::LayerInfo::FrameRateCompatibility::Default);
+    EXPECT_EQ(getSnapshot({.id = 122})->frameRate.category, FrameRateCategory::Normal);
+    EXPECT_TRUE(getSnapshot({.id = 122})->changes.test(RequestedLayerState::Changes::FrameRate));
+
+    EXPECT_FALSE(getSnapshot({.id = 1221})->frameRate.vote.rate.isValid());
+    EXPECT_TRUE(getSnapshot({.id = 1221})->frameRate.isValid());
+    EXPECT_EQ(getSnapshot({.id = 1221})->frameRate.vote.type,
+              scheduler::LayerInfo::FrameRateCompatibility::Default);
+    EXPECT_EQ(getSnapshot({.id = 1221})->frameRate.category, FrameRateCategory::Normal);
+    EXPECT_TRUE(getSnapshot({.id = 1221})->changes.test(RequestedLayerState::Changes::FrameRate));
+}
+
 TEST_F(LayerSnapshotTest, skipRoundCornersWhenProtected) {
     setRoundedCorners(1, 42.f);
     setRoundedCorners(2, 42.f);
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp
index aaf55fb..dc6b700 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp
@@ -26,6 +26,7 @@
 #include <log/log.h>
 #include <ui/Size.h>
 
+#include <scheduler/Fps.h>
 #include <scheduler/FrameRateMode.h>
 #include "DisplayHardware/HWC2.h"
 #include "FpsOps.h"
@@ -1381,6 +1382,120 @@
     EXPECT_FALSE(signals.touch);
 }
 
+TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_withFrameRateCategory_30_60_90_120) {
+    auto selector = createSelector(makeModes(kMode30, kMode60, kMode90, kMode120), kModeId60);
+
+    std::vector<LayerRequirement> layers = {{.vote = LayerVoteType::ExplicitDefault, .weight = 1.f},
+                                            {.vote = LayerVoteType::ExplicitCategory,
+                                             .weight = 1.f}};
+    auto& lr = layers[0];
+
+    struct Case {
+        // Params
+        Fps desiredFrameRate = 0_Hz;
+        FrameRateCategory frameRateCategory = FrameRateCategory::Default;
+
+        // Expected result
+        Fps expectedFrameRate = 0_Hz;
+    };
+
+    // Prepare a table with the vote and the expected refresh rate
+    const std::initializer_list<Case> testCases = {
+            // Cases that only have frame rate category requirements, but no desired frame rate.
+            // When frame rates get an equal score, the lower is chosen, unless there are Max votes.
+            {0_Hz, FrameRateCategory::High, 90_Hz},
+            {0_Hz, FrameRateCategory::Normal, 60_Hz},
+            {0_Hz, FrameRateCategory::Low, 30_Hz},
+            {0_Hz, FrameRateCategory::NoPreference, 60_Hz},
+
+            // Cases that have both desired frame rate and frame rate category requirements.
+            {24_Hz, FrameRateCategory::High, 120_Hz},
+            {30_Hz, FrameRateCategory::High, 90_Hz},
+            {12_Hz, FrameRateCategory::Normal, 60_Hz},
+            {30_Hz, FrameRateCategory::NoPreference, 30_Hz},
+
+            // Cases that only have desired frame rate.
+            {30_Hz, FrameRateCategory::Default, 30_Hz},
+    };
+
+    for (auto testCase : testCases) {
+        ALOGI("**** %s: Testing desiredFrameRate=%s, frameRateCategory=%s", __func__,
+              to_string(testCase.desiredFrameRate).c_str(),
+              ftl::enum_string(testCase.frameRateCategory).c_str());
+
+        lr.desiredRefreshRate = testCase.desiredFrameRate;
+
+        std::stringstream ss;
+        ss << to_string(testCase.desiredFrameRate)
+           << ", category=" << ftl::enum_string(testCase.frameRateCategory);
+        lr.name = ss.str();
+
+        if (testCase.frameRateCategory != FrameRateCategory::Default) {
+            layers[1].frameRateCategory = testCase.frameRateCategory;
+        }
+
+        EXPECT_EQ(testCase.expectedFrameRate, selector.getBestFrameRateMode(layers)->getFps())
+                << "did not get expected frame rate for " << lr.name;
+    }
+}
+
+TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_withFrameRateCategory_60_120) {
+    auto selector = createSelector(makeModes(kMode60, kMode120), kModeId60);
+
+    std::vector<LayerRequirement> layers = {{.vote = LayerVoteType::ExplicitDefault, .weight = 1.f},
+                                            {.vote = LayerVoteType::ExplicitCategory,
+                                             .weight = 1.f}};
+    auto& lr = layers[0];
+
+    struct Case {
+        // Params
+        Fps desiredFrameRate = 0_Hz;
+        FrameRateCategory frameRateCategory = FrameRateCategory::Default;
+
+        // Expected result
+        Fps expectedFrameRate = 0_Hz;
+    };
+
+    // Prepare a table with the vote and the expected refresh rate
+    const std::initializer_list<Case> testCases = {
+            // Cases that only have frame rate category requirements, but no desired frame rate.
+            // When frame rates get an equal score, the lower is chosen, unless there are Max votes.
+            {0_Hz, FrameRateCategory::High, 120_Hz},
+            {0_Hz, FrameRateCategory::Normal, 60_Hz},
+            {0_Hz, FrameRateCategory::Low, 60_Hz},
+            {0_Hz, FrameRateCategory::NoPreference, 60_Hz},
+
+            // Cases that have both desired frame rate and frame rate category requirements.
+            {24_Hz, FrameRateCategory::High, 120_Hz},
+            {30_Hz, FrameRateCategory::High, 120_Hz},
+            {12_Hz, FrameRateCategory::Normal, 60_Hz},
+            {30_Hz, FrameRateCategory::NoPreference, 60_Hz},
+
+            // Cases that only have desired frame rate.
+            {30_Hz, FrameRateCategory::Default, 60_Hz},
+    };
+
+    for (auto testCase : testCases) {
+        ALOGI("**** %s: Testing desiredFrameRate=%s, frameRateCategory=%s", __func__,
+              to_string(testCase.desiredFrameRate).c_str(),
+              ftl::enum_string(testCase.frameRateCategory).c_str());
+
+        lr.desiredRefreshRate = testCase.desiredFrameRate;
+
+        std::stringstream ss;
+        ss << to_string(testCase.desiredFrameRate)
+           << ", category=" << ftl::enum_string(testCase.frameRateCategory);
+        lr.name = ss.str();
+
+        if (testCase.frameRateCategory != FrameRateCategory::Default) {
+            layers[1].frameRateCategory = testCase.frameRateCategory;
+        }
+
+        EXPECT_EQ(testCase.expectedFrameRate, selector.getBestFrameRateMode(layers)->getFps())
+                << "did not get expected frame rate for " << lr.name;
+    }
+}
+
 TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_ExplicitDefault) {
     auto selector = createSelector(kModes_60_90_72_120, kModeId60);
 
diff --git a/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp b/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
index a1e4e25..608fa76 100644
--- a/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
@@ -97,7 +97,7 @@
     const auto& layerFactory = GetParam();
 
     auto layer = mLayers.emplace_back(layerFactory->createLayer(mFlinger));
-    layer->setFrameRate(FRAME_RATE_VOTE1);
+    layer->setFrameRate(FRAME_RATE_VOTE1.vote);
     commitTransaction();
     EXPECT_EQ(FRAME_RATE_VOTE1, layer->getFrameRateForLayerTree());
 }
@@ -114,13 +114,13 @@
     addChild(parent, child1);
     addChild(child1, child2);
 
-    child2->setFrameRate(FRAME_RATE_VOTE1);
+    child2->setFrameRate(FRAME_RATE_VOTE1.vote);
     commitTransaction();
     EXPECT_EQ(FRAME_RATE_TREE, parent->getFrameRateForLayerTree());
     EXPECT_EQ(FRAME_RATE_TREE, child1->getFrameRateForLayerTree());
     EXPECT_EQ(FRAME_RATE_VOTE1, child2->getFrameRateForLayerTree());
 
-    child2->setFrameRate(FRAME_RATE_NO_VOTE);
+    child2->setFrameRate(FRAME_RATE_NO_VOTE.vote);
     commitTransaction();
     EXPECT_EQ(FRAME_RATE_NO_VOTE, parent->getFrameRateForLayerTree());
     EXPECT_EQ(FRAME_RATE_NO_VOTE, child1->getFrameRateForLayerTree());
@@ -139,27 +139,27 @@
     addChild(parent, child1);
     addChild(child1, child2);
 
-    child2->setFrameRate(FRAME_RATE_VOTE1);
-    child1->setFrameRate(FRAME_RATE_VOTE2);
-    parent->setFrameRate(FRAME_RATE_VOTE3);
+    child2->setFrameRate(FRAME_RATE_VOTE1.vote);
+    child1->setFrameRate(FRAME_RATE_VOTE2.vote);
+    parent->setFrameRate(FRAME_RATE_VOTE3.vote);
     commitTransaction();
     EXPECT_EQ(FRAME_RATE_VOTE3, parent->getFrameRateForLayerTree());
     EXPECT_EQ(FRAME_RATE_VOTE2, child1->getFrameRateForLayerTree());
     EXPECT_EQ(FRAME_RATE_VOTE1, child2->getFrameRateForLayerTree());
 
-    child2->setFrameRate(FRAME_RATE_NO_VOTE);
+    child2->setFrameRate(FRAME_RATE_NO_VOTE.vote);
     commitTransaction();
     EXPECT_EQ(FRAME_RATE_VOTE3, parent->getFrameRateForLayerTree());
     EXPECT_EQ(FRAME_RATE_VOTE2, child1->getFrameRateForLayerTree());
     EXPECT_EQ(FRAME_RATE_VOTE2, child2->getFrameRateForLayerTree());
 
-    child1->setFrameRate(FRAME_RATE_NO_VOTE);
+    child1->setFrameRate(FRAME_RATE_NO_VOTE.vote);
     commitTransaction();
     EXPECT_EQ(FRAME_RATE_VOTE3, parent->getFrameRateForLayerTree());
     EXPECT_EQ(FRAME_RATE_VOTE3, child1->getFrameRateForLayerTree());
     EXPECT_EQ(FRAME_RATE_VOTE3, child2->getFrameRateForLayerTree());
 
-    parent->setFrameRate(FRAME_RATE_NO_VOTE);
+    parent->setFrameRate(FRAME_RATE_NO_VOTE.vote);
     commitTransaction();
     EXPECT_EQ(FRAME_RATE_NO_VOTE, parent->getFrameRateForLayerTree());
     EXPECT_EQ(FRAME_RATE_NO_VOTE, child1->getFrameRateForLayerTree());
@@ -178,13 +178,13 @@
     addChild(parent, child1);
     addChild(child1, child2);
 
-    parent->setFrameRate(FRAME_RATE_VOTE1);
+    parent->setFrameRate(FRAME_RATE_VOTE1.vote);
     commitTransaction();
     EXPECT_EQ(FRAME_RATE_VOTE1, parent->getFrameRateForLayerTree());
     EXPECT_EQ(FRAME_RATE_VOTE1, child1->getFrameRateForLayerTree());
     EXPECT_EQ(FRAME_RATE_VOTE1, child2->getFrameRateForLayerTree());
 
-    parent->setFrameRate(FRAME_RATE_NO_VOTE);
+    parent->setFrameRate(FRAME_RATE_NO_VOTE.vote);
     commitTransaction();
     EXPECT_EQ(FRAME_RATE_NO_VOTE, parent->getFrameRateForLayerTree());
     EXPECT_EQ(FRAME_RATE_NO_VOTE, child1->getFrameRateForLayerTree());
@@ -203,27 +203,27 @@
     addChild(parent, child1);
     addChild(child1, child2);
 
-    child2->setFrameRate(FRAME_RATE_VOTE1);
-    child1->setFrameRate(FRAME_RATE_VOTE2);
-    parent->setFrameRate(FRAME_RATE_VOTE3);
+    child2->setFrameRate(FRAME_RATE_VOTE1.vote);
+    child1->setFrameRate(FRAME_RATE_VOTE2.vote);
+    parent->setFrameRate(FRAME_RATE_VOTE3.vote);
     commitTransaction();
     EXPECT_EQ(FRAME_RATE_VOTE3, parent->getFrameRateForLayerTree());
     EXPECT_EQ(FRAME_RATE_VOTE2, child1->getFrameRateForLayerTree());
     EXPECT_EQ(FRAME_RATE_VOTE1, child2->getFrameRateForLayerTree());
 
-    parent->setFrameRate(FRAME_RATE_NO_VOTE);
+    parent->setFrameRate(FRAME_RATE_NO_VOTE.vote);
     commitTransaction();
     EXPECT_EQ(FRAME_RATE_TREE, parent->getFrameRateForLayerTree());
     EXPECT_EQ(FRAME_RATE_VOTE2, child1->getFrameRateForLayerTree());
     EXPECT_EQ(FRAME_RATE_VOTE1, child2->getFrameRateForLayerTree());
 
-    child1->setFrameRate(FRAME_RATE_NO_VOTE);
+    child1->setFrameRate(FRAME_RATE_NO_VOTE.vote);
     commitTransaction();
     EXPECT_EQ(FRAME_RATE_TREE, parent->getFrameRateForLayerTree());
     EXPECT_EQ(FRAME_RATE_TREE, child1->getFrameRateForLayerTree());
     EXPECT_EQ(FRAME_RATE_VOTE1, child2->getFrameRateForLayerTree());
 
-    child2->setFrameRate(FRAME_RATE_NO_VOTE);
+    child2->setFrameRate(FRAME_RATE_NO_VOTE.vote);
     commitTransaction();
     EXPECT_EQ(FRAME_RATE_NO_VOTE, parent->getFrameRateForLayerTree());
     EXPECT_EQ(FRAME_RATE_NO_VOTE, child1->getFrameRateForLayerTree());
@@ -241,7 +241,7 @@
 
     addChild(parent, child1);
 
-    parent->setFrameRate(FRAME_RATE_VOTE1);
+    parent->setFrameRate(FRAME_RATE_VOTE1.vote);
     commitTransaction();
     EXPECT_EQ(FRAME_RATE_VOTE1, parent->getFrameRateForLayerTree());
     EXPECT_EQ(FRAME_RATE_VOTE1, child1->getFrameRateForLayerTree());
@@ -253,7 +253,7 @@
     EXPECT_EQ(FRAME_RATE_VOTE1, child1->getFrameRateForLayerTree());
     EXPECT_EQ(FRAME_RATE_VOTE1, child2->getFrameRateForLayerTree());
 
-    parent->setFrameRate(FRAME_RATE_NO_VOTE);
+    parent->setFrameRate(FRAME_RATE_NO_VOTE.vote);
     commitTransaction();
     EXPECT_EQ(FRAME_RATE_NO_VOTE, parent->getFrameRateForLayerTree());
     EXPECT_EQ(FRAME_RATE_NO_VOTE, child1->getFrameRateForLayerTree());
@@ -272,7 +272,7 @@
     addChild(parent, child1);
     addChild(child1, child2);
 
-    parent->setFrameRate(FRAME_RATE_VOTE1);
+    parent->setFrameRate(FRAME_RATE_VOTE1.vote);
     commitTransaction();
     EXPECT_EQ(FRAME_RATE_VOTE1, parent->getFrameRateForLayerTree());
     EXPECT_EQ(FRAME_RATE_VOTE1, child1->getFrameRateForLayerTree());
@@ -284,7 +284,7 @@
     EXPECT_EQ(FRAME_RATE_VOTE1, child1->getFrameRateForLayerTree());
     EXPECT_EQ(FRAME_RATE_NO_VOTE, child2->getFrameRateForLayerTree());
 
-    parent->setFrameRate(FRAME_RATE_NO_VOTE);
+    parent->setFrameRate(FRAME_RATE_NO_VOTE.vote);
     commitTransaction();
     EXPECT_EQ(FRAME_RATE_NO_VOTE, parent->getFrameRateForLayerTree());
     EXPECT_EQ(FRAME_RATE_NO_VOTE, child1->getFrameRateForLayerTree());
@@ -305,14 +305,14 @@
     addChild(child1, child2);
     addChild(child1, child2_1);
 
-    child2->setFrameRate(FRAME_RATE_VOTE1);
+    child2->setFrameRate(FRAME_RATE_VOTE1.vote);
     commitTransaction();
     EXPECT_EQ(FRAME_RATE_TREE, parent->getFrameRateForLayerTree());
     EXPECT_EQ(FRAME_RATE_TREE, child1->getFrameRateForLayerTree());
     EXPECT_EQ(FRAME_RATE_VOTE1, child2->getFrameRateForLayerTree());
     EXPECT_EQ(FRAME_RATE_NO_VOTE, child2_1->getFrameRateForLayerTree());
 
-    child2->setFrameRate(FRAME_RATE_NO_VOTE);
+    child2->setFrameRate(FRAME_RATE_NO_VOTE.vote);
     commitTransaction();
     EXPECT_EQ(FRAME_RATE_NO_VOTE, parent->getFrameRateForLayerTree());
     EXPECT_EQ(FRAME_RATE_NO_VOTE, child1->getFrameRateForLayerTree());
@@ -375,7 +375,7 @@
     auto child = mLayers.emplace_back(layerFactory->createLayer(mFlinger));
     addChild(parent, child);
 
-    parent->setFrameRate(FRAME_RATE_VOTE1);
+    parent->setFrameRate(FRAME_RATE_VOTE1.vote);
     commitTransaction();
 
     auto& history = mFlinger.mutableScheduler().mutableLayerHistory();
@@ -388,8 +388,8 @@
     const auto summary = history.summarize(*selectorPtr, 0);
 
     ASSERT_EQ(2u, summary.size());
-    EXPECT_EQ(FRAME_RATE_VOTE1.rate, summary[0].desiredRefreshRate);
-    EXPECT_EQ(FRAME_RATE_VOTE1.rate, summary[1].desiredRefreshRate);
+    EXPECT_EQ(FRAME_RATE_VOTE1.vote.rate, summary[0].desiredRefreshRate);
+    EXPECT_EQ(FRAME_RATE_VOTE1.vote.rate, summary[1].desiredRefreshRate);
 }
 
 TEST_P(SetFrameRateTest, addChildForParentWithTreeVote) {
@@ -405,7 +405,7 @@
     addChild(parent, child1);
     addChild(child1, childOfChild1);
 
-    childOfChild1->setFrameRate(FRAME_RATE_VOTE1);
+    childOfChild1->setFrameRate(FRAME_RATE_VOTE1.vote);
     commitTransaction();
     EXPECT_EQ(FRAME_RATE_TREE, parent->getFrameRateForLayerTree());
     EXPECT_EQ(FRAME_RATE_TREE, child1->getFrameRateForLayerTree());
@@ -419,7 +419,7 @@
     EXPECT_EQ(FRAME_RATE_VOTE1, childOfChild1->getFrameRateForLayerTree());
     EXPECT_EQ(FRAME_RATE_NO_VOTE, child2->getFrameRateForLayerTree());
 
-    childOfChild1->setFrameRate(FRAME_RATE_NO_VOTE);
+    childOfChild1->setFrameRate(FRAME_RATE_NO_VOTE.vote);
     commitTransaction();
     EXPECT_EQ(FRAME_RATE_NO_VOTE, parent->getFrameRateForLayerTree());
     EXPECT_EQ(FRAME_RATE_NO_VOTE, child1->getFrameRateForLayerTree());