Merge "Add basic ANR test" into rvc-dev
diff --git a/services/surfaceflinger/Scheduler/LayerHistoryV2.cpp b/services/surfaceflinger/Scheduler/LayerHistoryV2.cpp
index afc8c4f..6570b1a 100644
--- a/services/surfaceflinger/Scheduler/LayerHistoryV2.cpp
+++ b/services/surfaceflinger/Scheduler/LayerHistoryV2.cpp
@@ -62,13 +62,17 @@
     const auto layer = weak.promote();
     if (!layer) return;
 
-    const auto& name = layer->getName();
-    const auto noVoteTag = "LFPS NoVote " + name;
-    const auto heuristicVoteTag = "LFPS Heuristic " + name;
-    const auto explicitDefaultVoteTag = "LFPS ExplicitDefault" + name;
-    const auto explicitExactOrMultipleVoteTag = "LFPS ExplicitExactOrMultiple" + name;
-    const auto minVoteTag = "LFPS Min " + name;
-    const auto maxVoteTag = "LFPS Max " + name;
+    const auto makeTag = [layer](LayerHistory::LayerVoteType vote) {
+        return "LFPS " + RefreshRateConfigs::layerVoteTypeString(vote) + " " + layer->getName();
+    };
+
+    const auto noVoteTag = makeTag(LayerHistory::LayerVoteType::NoVote);
+    const auto heuristicVoteTag = makeTag(LayerHistory::LayerVoteType::Heuristic);
+    const auto explicitDefaultVoteTag = makeTag(LayerHistory::LayerVoteType::ExplicitDefault);
+    const auto explicitExactOrMultipleVoteTag =
+            makeTag(LayerHistory::LayerVoteType::ExplicitExactOrMultiple);
+    const auto minVoteTag = makeTag(LayerHistory::LayerVoteType::Min);
+    const auto maxVoteTag = makeTag(LayerHistory::LayerVoteType::Max);
 
     ATRACE_INT(noVoteTag.c_str(), type == LayerHistory::LayerVoteType::NoVote ? 1 : 0);
     ATRACE_INT(heuristicVoteTag.c_str(), type == LayerHistory::LayerVoteType::Heuristic ? fps : 0);
@@ -79,7 +83,7 @@
     ATRACE_INT(minVoteTag.c_str(), type == LayerHistory::LayerVoteType::Min ? 1 : 0);
     ATRACE_INT(maxVoteTag.c_str(), type == LayerHistory::LayerVoteType::Max ? 1 : 0);
 
-    ALOGD("%s: %s @ %d Hz", __FUNCTION__, name.c_str(), fps);
+    ALOGD("%s: %s @ %d Hz", __FUNCTION__, layer->getName().c_str(), fps);
 }
 } // namespace
 
@@ -188,7 +192,7 @@
             trace(weak, LayerHistory::LayerVoteType::NoVote, 0);
         }
 
-        info->clearHistory();
+        info->onLayerInactive(now);
         std::swap(mLayerInfos[i], mLayerInfos[--mActiveLayersEnd]);
     }
 
@@ -209,7 +213,7 @@
     std::lock_guard lock(mLock);
 
     for (const auto& [layer, info] : activeLayers()) {
-        info->clearHistory();
+        info->clearHistory(systemTime());
     }
 }
 } // namespace android::scheduler::impl
diff --git a/services/surfaceflinger/Scheduler/LayerInfoV2.cpp b/services/surfaceflinger/Scheduler/LayerInfoV2.cpp
index 78f4433..25dca39 100644
--- a/services/surfaceflinger/Scheduler/LayerInfoV2.cpp
+++ b/services/surfaceflinger/Scheduler/LayerInfoV2.cpp
@@ -50,28 +50,35 @@
     }
 }
 
-bool LayerInfoV2::isFrequent(nsecs_t now) {
-    mLastReportedIsFrequent = [&] {
-        for (auto it = mFrameTimes.crbegin(); it != mFrameTimes.crend(); ++it) {
-            if (now - it->queueTime >= MAX_FREQUENT_LAYER_PERIOD_NS.count()) {
-                ALOGV("%s infrequent (last frame is %.2fms ago)", mName.c_str(),
-                      (now - mFrameTimes.back().queueTime) / 1e6f);
-                return false;
-            }
+bool LayerInfoV2::isFrameTimeValid(const FrameTimeData& frameTime) const {
+    return frameTime.queueTime >= std::chrono::duration_cast<std::chrono::nanoseconds>(
+                                          mFrameTimeValidSince.time_since_epoch())
+                                          .count();
+}
 
-            const auto numFrames = std::distance(mFrameTimes.crbegin(), it + 1);
-            if (numFrames >= FREQUENT_LAYER_WINDOW_SIZE) {
-                ALOGV("%s frequent (burst of %zu frames)", mName.c_str(), numFrames);
-                return true;
-            }
+bool LayerInfoV2::isFrequent(nsecs_t now) const {
+    // If we know nothing about this layer we consider it as frequent as it might be the start
+    // of an animation.
+    if (mFrameTimes.size() < FREQUENT_LAYER_WINDOW_SIZE) {
+        return true;
+    }
+
+    // Find the first active frame
+    auto it = mFrameTimes.begin();
+    for (; it != mFrameTimes.end(); ++it) {
+        if (it->queueTime >= getActiveLayerThreshold(now)) {
+            break;
         }
+    }
 
-        ALOGV("%s %sfrequent (not enough frames %zu)", mName.c_str(),
-              mLastReportedIsFrequent ? "" : "in", mFrameTimes.size());
-        return mLastReportedIsFrequent;
-    }();
+    const auto numFrames = std::distance(it, mFrameTimes.end());
+    if (numFrames < FREQUENT_LAYER_WINDOW_SIZE) {
+        return false;
+    }
 
-    return mLastReportedIsFrequent;
+    // Layer is considered frequent if the average frame rate is higher than the threshold
+    const auto totalTime = mFrameTimes.back().queueTime - it->queueTime;
+    return (1e9f * (numFrames - 1)) / totalTime >= MIN_FPS_FOR_FREQUENT_LAYER;
 }
 
 bool LayerInfoV2::hasEnoughDataForHeuristic() const {
@@ -80,6 +87,10 @@
         return false;
     }
 
+    if (!isFrameTimeValid(mFrameTimes.front())) {
+        return false;
+    }
+
     if (mFrameTimes.size() < HISTORY_SIZE &&
         mFrameTimes.back().queueTime - mFrameTimes.front().queueTime < HISTORY_TIME.count()) {
         return false;
@@ -190,7 +201,7 @@
         return {LayerHistory::LayerVoteType::Heuristic, refreshRate.value()};
     }
 
-    ALOGV("%s Max (can't resolve refresh rate", mName.c_str());
+    ALOGV("%s Max (can't resolve refresh rate)", mName.c_str());
     return {LayerHistory::LayerVoteType::Max, 0};
 }
 
diff --git a/services/surfaceflinger/Scheduler/LayerInfoV2.h b/services/surfaceflinger/Scheduler/LayerInfoV2.h
index 82da7e3..5f50d5a 100644
--- a/services/surfaceflinger/Scheduler/LayerInfoV2.h
+++ b/services/surfaceflinger/Scheduler/LayerInfoV2.h
@@ -47,7 +47,9 @@
     // is within a threshold. If a layer is infrequent, its average refresh rate is disregarded in
     // favor of a low refresh rate.
     static constexpr size_t FREQUENT_LAYER_WINDOW_SIZE = 3;
-    static constexpr std::chrono::nanoseconds MAX_FREQUENT_LAYER_PERIOD_NS = 150ms;
+    static constexpr float MIN_FPS_FOR_FREQUENT_LAYER = 10.0f;
+    static constexpr auto MAX_FREQUENT_LAYER_PERIOD_NS =
+            std::chrono::nanoseconds(static_cast<nsecs_t>(1e9f / MIN_FPS_FOR_FREQUENT_LAYER)) + 1ms;
 
     friend class LayerHistoryTestV2;
 
@@ -81,11 +83,21 @@
     // updated time, the updated time is the present time.
     nsecs_t getLastUpdatedTime() const { return mLastUpdatedTime; }
 
-    void clearHistory() {
-        mFrameTimes.clear();
+    void onLayerInactive(nsecs_t now) {
+        // Mark mFrameTimeValidSince to now to ignore all previous frame times.
+        // We are not deleting the old frame to keep track of whether we should treat the first
+        // buffer as Max as we don't know anything about this layer or Min as this layer is
+        // posting infrequent updates.
+        const auto timePoint = std::chrono::nanoseconds(now);
+        mFrameTimeValidSince = std::chrono::time_point<std::chrono::steady_clock>(timePoint);
         mLastReportedRefreshRate = 0.0f;
     }
 
+    void clearHistory(nsecs_t now) {
+        onLayerInactive(now);
+        mFrameTimes.clear();
+    }
+
 private:
     // Used to store the layer timestamps
     struct FrameTimeData {
@@ -94,11 +106,12 @@
         bool pendingConfigChange;
     };
 
-    bool isFrequent(nsecs_t now);
+    bool isFrequent(nsecs_t now) const;
     bool hasEnoughDataForHeuristic() const;
     std::optional<float> calculateRefreshRateIfPossible();
     std::pair<nsecs_t, bool> calculateAverageFrameTime() const;
     bool isRefreshRateStable(nsecs_t averageFrameTime, bool missingPresentTime) const;
+    bool isFrameTimeValid(const FrameTimeData&) const;
 
     const std::string mName;
 
@@ -110,13 +123,6 @@
 
     float mLastReportedRefreshRate = 0.0f;
 
-    // Used to determine whether a layer should be considered frequent or
-    // not when we don't have enough frames. This member will not be cleared
-    // as part of clearHistory() to remember whether this layer was frequent
-    // or not before we processed touch boost (or anything else that would
-    // clear layer history).
-    bool mLastReportedIsFrequent = true;
-
     // Holds information about the layer vote
     struct {
         LayerHistory::LayerVoteType type;
@@ -124,6 +130,8 @@
     } mLayerVote;
 
     std::deque<FrameTimeData> mFrameTimes;
+    std::chrono::time_point<std::chrono::steady_clock> mFrameTimeValidSince =
+            std::chrono::steady_clock::now();
     static constexpr size_t HISTORY_SIZE = 90;
     static constexpr std::chrono::nanoseconds HISTORY_TIME = 1s;
 };
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
index e181c12..3c8bd68 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
@@ -31,6 +31,23 @@
 using AllRefreshRatesMapType = RefreshRateConfigs::AllRefreshRatesMapType;
 using RefreshRate = RefreshRateConfigs::RefreshRate;
 
+std::string RefreshRateConfigs::layerVoteTypeString(LayerVoteType vote) {
+    switch (vote) {
+        case LayerVoteType::NoVote:
+            return "NoVote";
+        case LayerVoteType::Min:
+            return "Min";
+        case LayerVoteType::Max:
+            return "Max";
+        case LayerVoteType::Heuristic:
+            return "Heuristic";
+        case LayerVoteType::ExplicitDefault:
+            return "ExplicitDefault";
+        case LayerVoteType::ExplicitExactOrMultiple:
+            return "ExplicitExactOrMultiple";
+    }
+}
+
 const RefreshRate& RefreshRateConfigs::getRefreshRateForContent(
         const std::vector<LayerRequirement>& layers) const {
     std::lock_guard lock(mLock);
@@ -146,6 +163,7 @@
     const bool primaryRangeIsSingleRate = policy->primaryRange.min == policy->primaryRange.max;
 
     if (!touchActive && idle && !(primaryRangeIsSingleRate && hasExplicitVoteLayers)) {
+        ALOGV("Idle - choose %s", getMinRefreshRateByPolicyLocked().getName().c_str());
         return getMinRefreshRateByPolicyLocked();
     }
 
@@ -168,7 +186,8 @@
     }
 
     for (const auto& layer : layers) {
-        ALOGV("Calculating score for %s (type: %d)", layer.name.c_str(), layer.vote);
+        ALOGV("Calculating score for %s (%s, weight %.2f)", layer.name.c_str(),
+              layerVoteTypeString(layer.vote).c_str(), layer.weight);
         if (layer.vote == LayerVoteType::NoVote || layer.vote == LayerVoteType::Min) {
             continue;
         }
@@ -254,10 +273,8 @@
                     return 1.0f / iter;
                 }();
                 ALOGV("%s (%s, weight %.2f) %.2fHz gives %s score of %.2f", layer.name.c_str(),
-                      layer.vote == LayerVoteType::ExplicitExactOrMultiple
-                              ? "ExplicitExactOrMultiple"
-                              : "Heuristic",
-                      weight, 1e9f / layerPeriod, scores[i].first->name.c_str(), layerScore);
+                      layerVoteTypeString(layer.vote).c_str(), weight, 1e9f / layerPeriod,
+                      scores[i].first->name.c_str(), layerScore);
                 scores[i].second += weight * layerScore;
                 continue;
             }
@@ -276,6 +293,8 @@
         // range instead of picking a random score from the app range.
         if (std::all_of(scores.begin(), scores.end(),
                         [](std::pair<const RefreshRate*, float> p) { return p.second == 0; })) {
+            ALOGV("layers not scored - choose %s",
+                  getMaxRefreshRateByPolicyLocked().getName().c_str());
             return getMaxRefreshRateByPolicyLocked();
         } else {
             return *bestRefreshRate;
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
index 2657dee..ff1eabd 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
@@ -255,6 +255,9 @@
     // Stores the current configId the device operates at
     void setCurrentConfigId(HwcConfigIndexType configId) EXCLUDES(mLock);
 
+    // Returns a string that represents the layer vote type
+    static std::string layerVoteTypeString(LayerVoteType vote);
+
     RefreshRateConfigs(const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs,
                        HwcConfigIndexType currentConfigId);
 
diff --git a/services/surfaceflinger/tests/unittests/LayerHistoryTestV2.cpp b/services/surfaceflinger/tests/unittests/LayerHistoryTestV2.cpp
index 09ef06a..dc705ed 100644
--- a/services/surfaceflinger/tests/unittests/LayerHistoryTestV2.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerHistoryTestV2.cpp
@@ -37,6 +37,7 @@
     static constexpr auto PRESENT_TIME_HISTORY_SIZE = LayerInfoV2::HISTORY_SIZE;
     static constexpr auto MAX_FREQUENT_LAYER_PERIOD_NS = LayerInfoV2::MAX_FREQUENT_LAYER_PERIOD_NS;
     static constexpr auto FREQUENT_LAYER_WINDOW_SIZE = LayerInfoV2::FREQUENT_LAYER_WINDOW_SIZE;
+    static constexpr auto PRESENT_TIME_HISTORY_TIME = LayerInfoV2::HISTORY_TIME;
 
     static constexpr float LO_FPS = 30.f;
     static constexpr auto LO_FPS_PERIOD = static_cast<nsecs_t>(1e9f / LO_FPS);
@@ -71,6 +72,9 @@
     }
 
     auto createLayer() { return sp<mock::MockLayer>(new mock::MockLayer(mFlinger.flinger())); }
+    auto createLayer(std::string name) {
+        return sp<mock::MockLayer>(new mock::MockLayer(mFlinger.flinger(), std::move(name)));
+    }
 
     Hwc2::mock::Display mDisplay;
     RefreshRateConfigs mConfigs{{HWC2::Display::Config::Builder(mDisplay, 0)
@@ -103,13 +107,12 @@
     EXPECT_TRUE(history().summarize(time).empty());
     EXPECT_EQ(0, activeLayerCount());
 
-    // The first few updates are considered frequent
+    // Max returned if active layers have insufficient history.
     for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE - 1; i++) {
         history().record(layer.get(), 0, time);
         ASSERT_EQ(1, history().summarize(time).size());
         EXPECT_EQ(LayerHistory::LayerVoteType::Max, history().summarize(time)[0].vote);
         EXPECT_EQ(1, activeLayerCount());
-        EXPECT_EQ(1, frequentLayerCount(time));
     }
 
     // Max is returned since we have enough history but there is no timestamp votes.
@@ -118,7 +121,6 @@
         ASSERT_EQ(1, history().summarize(time).size());
         EXPECT_EQ(LayerHistory::LayerVoteType::Max, history().summarize(time)[0].vote);
         EXPECT_EQ(1, activeLayerCount());
-        EXPECT_EQ(1, frequentLayerCount(time));
     }
 }
 
@@ -135,7 +137,7 @@
     history().record(layer.get(), 0, time);
     auto summary = history().summarize(time);
     ASSERT_EQ(1, history().summarize(time).size());
-    // Layer is still considered active so we expect to get Max
+    // Layer is still considered inactive so we expect to get Min
     EXPECT_EQ(LayerHistory::LayerVoteType::Max, history().summarize(time)[0].vote);
     EXPECT_EQ(1, activeLayerCount());
 
@@ -466,15 +468,28 @@
 
     nsecs_t time = systemTime();
 
-    // The first few updates are considered frequent
-    for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE - 1; i++) {
-        history().record(layer.get(), 0, time);
+    // the very first updates makes the layer frequent
+    for (int i = 0; i < FREQUENT_LAYER_WINDOW_SIZE - 1; i++) {
+        history().record(layer.get(), time, time);
+        time += MAX_FREQUENT_LAYER_PERIOD_NS.count();
+
+        EXPECT_EQ(1, layerCount());
         ASSERT_EQ(1, history().summarize(time).size());
         EXPECT_EQ(LayerHistory::LayerVoteType::Max, history().summarize(time)[0].vote);
         EXPECT_EQ(1, activeLayerCount());
         EXPECT_EQ(1, frequentLayerCount(time));
     }
 
+    // the next update with the MAX_FREQUENT_LAYER_PERIOD_NS will get us to infrequent
+    history().record(layer.get(), time, time);
+    time += MAX_FREQUENT_LAYER_PERIOD_NS.count();
+
+    EXPECT_EQ(1, layerCount());
+    ASSERT_EQ(1, history().summarize(time).size());
+    EXPECT_EQ(LayerHistory::LayerVoteType::Min, history().summarize(time)[0].vote);
+    EXPECT_EQ(1, activeLayerCount());
+    EXPECT_EQ(0, frequentLayerCount(time));
+
     // advance the time for the previous frame to be inactive
     time += MAX_ACTIVE_LAYER_PERIOD_NS.count();
 
@@ -499,36 +514,6 @@
     EXPECT_EQ(LayerHistory::LayerVoteType::Max, history().summarize(time)[0].vote);
     EXPECT_EQ(1, activeLayerCount());
     EXPECT_EQ(1, frequentLayerCount(time));
-
-    // advance the time for the previous frame to be inactive
-    time += MAX_ACTIVE_LAYER_PERIOD_NS.count();
-
-    // Now event if we post a quick few frame we should stay infrequent
-    for (int i = 0; i < FREQUENT_LAYER_WINDOW_SIZE - 1; i++) {
-        history().record(layer.get(), time, time);
-        time += HI_FPS_PERIOD;
-
-        EXPECT_EQ(1, layerCount());
-        ASSERT_EQ(1, history().summarize(time).size());
-        EXPECT_EQ(LayerHistory::LayerVoteType::Min, history().summarize(time)[0].vote);
-        EXPECT_EQ(1, activeLayerCount());
-        EXPECT_EQ(0, frequentLayerCount(time));
-    }
-
-    // clear the history
-    history().clear();
-
-    // Now event if we post a quick few frame we should stay infrequent
-    for (int i = 0; i < FREQUENT_LAYER_WINDOW_SIZE - 1; i++) {
-        history().record(layer.get(), time, time);
-        time += HI_FPS_PERIOD;
-
-        EXPECT_EQ(1, layerCount());
-        ASSERT_EQ(1, history().summarize(time).size());
-        EXPECT_EQ(LayerHistory::LayerVoteType::Min, history().summarize(time)[0].vote);
-        EXPECT_EQ(1, activeLayerCount());
-        EXPECT_EQ(0, frequentLayerCount(time));
-    }
 }
 
 TEST_F(LayerHistoryTestV2, invisibleExplicitLayer) {
@@ -547,11 +532,9 @@
 
     nsecs_t time = systemTime();
 
-    // Post a few buffers to the layers to make them active
-    for (int i = 0; i < FREQUENT_LAYER_WINDOW_SIZE; i++) {
-        history().record(explicitVisiblelayer.get(), time, time);
-        history().record(explicitInvisiblelayer.get(), time, time);
-    }
+    // Post a buffer to the layers to make them active
+    history().record(explicitVisiblelayer.get(), time, time);
+    history().record(explicitInvisiblelayer.get(), time, time);
 
     EXPECT_EQ(2, layerCount());
     ASSERT_EQ(1, history().summarize(time).size());
@@ -562,5 +545,75 @@
     EXPECT_EQ(2, frequentLayerCount(time));
 }
 
+class LayerHistoryTestV2Parameterized
+      : public LayerHistoryTestV2,
+        public testing::WithParamInterface<std::chrono::nanoseconds> {};
+
+TEST_P(LayerHistoryTestV2Parameterized, HeuristicLayerWithInfrequentLayer) {
+    std::chrono::nanoseconds infrequentUpdateDelta = GetParam();
+    auto heuristicLayer = createLayer("HeuristicLayer");
+
+    EXPECT_CALL(*heuristicLayer, isVisible()).WillRepeatedly(Return(true));
+    EXPECT_CALL(*heuristicLayer, getFrameRateForLayerTree())
+            .WillRepeatedly(Return(Layer::FrameRate()));
+
+    auto infrequentLayer = createLayer("InfrequentLayer");
+    EXPECT_CALL(*infrequentLayer, isVisible()).WillRepeatedly(Return(true));
+    EXPECT_CALL(*infrequentLayer, getFrameRateForLayerTree())
+            .WillRepeatedly(Return(Layer::FrameRate()));
+
+    const nsecs_t startTime = systemTime();
+
+    const std::chrono::nanoseconds heuristicUpdateDelta = 41'666'667ns;
+    history().record(heuristicLayer.get(), startTime, startTime);
+    history().record(infrequentLayer.get(), startTime, startTime);
+
+    nsecs_t time = startTime;
+    nsecs_t lastInfrequentUpdate = startTime;
+    const int totalInfrequentLayerUpdates = FREQUENT_LAYER_WINDOW_SIZE * 5;
+    int infrequentLayerUpdates = 0;
+    while (infrequentLayerUpdates <= totalInfrequentLayerUpdates) {
+        time += heuristicUpdateDelta.count();
+        history().record(heuristicLayer.get(), time, time);
+
+        if (time - lastInfrequentUpdate >= infrequentUpdateDelta.count()) {
+            ALOGI("submitting infrequent frame [%d/%d]", infrequentLayerUpdates,
+                  totalInfrequentLayerUpdates);
+            lastInfrequentUpdate = time;
+            history().record(infrequentLayer.get(), time, time);
+            infrequentLayerUpdates++;
+        }
+
+        if (time - startTime > PRESENT_TIME_HISTORY_TIME.count()) {
+            ASSERT_NE(0, history().summarize(time).size());
+            ASSERT_GE(2, history().summarize(time).size());
+
+            bool max = false;
+            bool min = false;
+            float heuristic = 0;
+            for (const auto& layer : history().summarize(time)) {
+                if (layer.vote == LayerHistory::LayerVoteType::Heuristic) {
+                    heuristic = layer.desiredRefreshRate;
+                } else if (layer.vote == LayerHistory::LayerVoteType::Max) {
+                    max = true;
+                } else if (layer.vote == LayerHistory::LayerVoteType::Min) {
+                    min = true;
+                }
+            }
+
+            if (infrequentLayerUpdates > FREQUENT_LAYER_WINDOW_SIZE) {
+                EXPECT_FLOAT_EQ(24.0f, heuristic);
+                EXPECT_FALSE(max);
+                if (history().summarize(time).size() == 2) {
+                    EXPECT_TRUE(min);
+                }
+            }
+        }
+    }
+}
+
+INSTANTIATE_TEST_CASE_P(LeapYearTests, LayerHistoryTestV2Parameterized,
+                        ::testing::Values(1s, 2s, 3s, 4s, 5s));
+
 } // namespace
 } // namespace android::scheduler
diff --git a/services/surfaceflinger/tests/unittests/mock/MockLayer.h b/services/surfaceflinger/tests/unittests/mock/MockLayer.h
index 119f580..078d8e07 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockLayer.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockLayer.h
@@ -24,8 +24,9 @@
 
 class MockLayer : public Layer {
 public:
-    explicit MockLayer(SurfaceFlinger* flinger)
-          : Layer(LayerCreationArgs(flinger, nullptr, "TestLayer", 800, 600, 0, {})) {}
+    MockLayer(SurfaceFlinger* flinger, std::string name)
+          : Layer(LayerCreationArgs(flinger, nullptr, std::move(name), 800, 600, 0, {})) {}
+    explicit MockLayer(SurfaceFlinger* flinger) : MockLayer(flinger, "TestLayer") {}
 
     MOCK_CONST_METHOD0(getType, const char*());
     MOCK_METHOD0(getFrameSelectionPriority, int32_t());