Merge "log when waiting on a servicemanager" into rvc-dev
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 912d470..a9f2d73 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -85,8 +85,8 @@
     sp<AidlServiceManager> mTheRealServiceManager;
 };
 
-static std::once_flag gSmOnce;
-static sp<IServiceManager> gDefaultServiceManager;
+[[clang::no_destroy]] static std::once_flag gSmOnce;
+[[clang::no_destroy]] static sp<IServiceManager> gDefaultServiceManager;
 
 sp<IServiceManager> defaultServiceManager()
 {
diff --git a/libs/binder/include/binder/IInterface.h b/libs/binder/include/binder/IInterface.h
index 3a401ad..7116154 100644
--- a/libs/binder/include/binder/IInterface.h
+++ b/libs/binder/include/binder/IInterface.h
@@ -20,6 +20,8 @@
 
 #include <binder/Binder.h>
 
+#include <assert.h>
+
 namespace android {
 
 // ----------------------------------------------------------------------
@@ -155,7 +157,11 @@
     std::unique_ptr<I##INTERFACE> I##INTERFACE::default_impl;           \
     bool I##INTERFACE::setDefaultImpl(std::unique_ptr<I##INTERFACE> impl)\
     {                                                                   \
-        if (!I##INTERFACE::default_impl && impl) {                      \
+        /* Only one user of this interface can use this function     */ \
+        /* at a time. This is a heuristic to detect if two different */ \
+        /* users in the same process use this function.              */ \
+        assert(!I##INTERFACE::default_impl);                            \
+        if (impl) {                                                     \
             I##INTERFACE::default_impl = std::move(impl);               \
             return true;                                                \
         }                                                               \
diff --git a/libs/gralloc/types/Android.bp b/libs/gralloc/types/Android.bp
index 00f7484..66fb295 100644
--- a/libs/gralloc/types/Android.bp
+++ b/libs/gralloc/types/Android.bp
@@ -27,6 +27,11 @@
         enabled: true,
         support_system_process: true,
     },
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.media.swcodec",
+    ],
+    min_sdk_version: "29",
 
     srcs: [
         "Gralloc4.cpp"
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index 7976ecb..4a4510e 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -130,6 +130,11 @@
 cc_library_static {
     name: "libgui_bufferqueue_static",
     vendor_available: true,
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.media.swcodec",
+    ],
+    min_sdk_version: "29",
 
     cflags: [
         "-DNO_BUFFERHUB",
diff --git a/libs/math/Android.bp b/libs/math/Android.bp
index 693bace..3b1edcb 100644
--- a/libs/math/Android.bp
+++ b/libs/math/Android.bp
@@ -16,6 +16,14 @@
     name: "libmath",
     host_supported: true,
     vendor_available: true,
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.media",
+        "com.android.media.swcodec",
+        "com.android.neuralnetworks",
+    ],
+    min_sdk_version: "29",
+
     export_include_dirs: ["include"],
 }
 
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index 0182937..a790d0b 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -38,7 +38,6 @@
         "libbinder",
         "libbufferhubqueue",
         "libcutils",
-        "libdl",
         "libEGL",
         "libfmq",
         "libGLESv1_CM",
@@ -73,7 +72,6 @@
         "librenderengine",
         "libserviceutils",
         "libtrace_proto",
-        "libvr_manager",
         "libvrflinger",
     ],
     header_libs: [
diff --git a/services/surfaceflinger/CompositionEngine/Android.bp b/services/surfaceflinger/CompositionEngine/Android.bp
index fda451b..b3b9fe5 100644
--- a/services/surfaceflinger/CompositionEngine/Android.bp
+++ b/services/surfaceflinger/CompositionEngine/Android.bp
@@ -21,7 +21,6 @@
         "liblog",
         "libnativewindow",
         "libprotobuf-cpp-lite",
-        "libsync",
         "libtimestats",
         "libui",
         "libutils",
diff --git a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
index 660baff..4084653 100644
--- a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
@@ -28,7 +28,6 @@
 
 #include <log/log.h>
 #include <renderengine/RenderEngine.h>
-#include <sync/sync.h>
 #include <system/window.h>
 #include <ui/GraphicBuffer.h>
 #include <ui/Rect.h>
diff --git a/services/surfaceflinger/Scheduler/LayerHistoryV2.cpp b/services/surfaceflinger/Scheduler/LayerHistoryV2.cpp
index e6c5cc9..120a60f 100644
--- a/services/surfaceflinger/Scheduler/LayerHistoryV2.cpp
+++ b/services/surfaceflinger/Scheduler/LayerHistoryV2.cpp
@@ -90,7 +90,7 @@
 void LayerHistoryV2::registerLayer(Layer* layer, float /*lowRefreshRate*/, float highRefreshRate,
                                    LayerVoteType type) {
     const nsecs_t highRefreshRatePeriod = static_cast<nsecs_t>(1e9f / highRefreshRate);
-    auto info = std::make_unique<LayerInfoV2>(highRefreshRatePeriod, type);
+    auto info = std::make_unique<LayerInfoV2>(layer->getName(), highRefreshRatePeriod, type);
     std::lock_guard lock(mLock);
     mLayerInfos.emplace_back(layer, std::move(info));
 }
diff --git a/services/surfaceflinger/Scheduler/LayerInfoV2.cpp b/services/surfaceflinger/Scheduler/LayerInfoV2.cpp
index b7d0bdd..255eac6 100644
--- a/services/surfaceflinger/Scheduler/LayerInfoV2.cpp
+++ b/services/surfaceflinger/Scheduler/LayerInfoV2.cpp
@@ -27,8 +27,10 @@
 
 namespace android::scheduler {
 
-LayerInfoV2::LayerInfoV2(nsecs_t highRefreshRatePeriod, LayerHistory::LayerVoteType defaultVote)
-      : mHighRefreshRatePeriod(highRefreshRatePeriod),
+LayerInfoV2::LayerInfoV2(const std::string& name, nsecs_t highRefreshRatePeriod,
+                         LayerHistory::LayerVoteType defaultVote)
+      : mName(name),
+        mHighRefreshRatePeriod(highRefreshRatePeriod),
         mDefaultVote(defaultVote),
         mLayerVote({defaultVote, 0.0f}) {}
 
@@ -45,42 +47,23 @@
     }
 }
 
-bool LayerInfoV2::isFrameTimeValid(const FrameTimeData& frameTime) const {
-    return frameTime.queueTime >= std::chrono::duration_cast<std::chrono::nanoseconds>(
-                                          mFrameTimeValidSince.time_since_epoch())
-                                          .count();
-}
-
 bool LayerInfoV2::isFrequent(nsecs_t now) const {
-    // Find the first valid frame time
-    auto it = mFrameTimes.begin();
-    for (; it != mFrameTimes.end(); ++it) {
-        if (isFrameTimeValid(*it)) {
-            break;
+    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;
+        }
+
+        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;
         }
     }
 
-    // If we know nothing about this layer we consider it as frequent as it might be the start
-    // of an animation.
-    if (std::distance(it, mFrameTimes.end()) < FREQUENT_LAYER_WINDOW_SIZE) {
-        return true;
-    }
-
-    // Find the first active frame
-    for (; it != mFrameTimes.end(); ++it) {
-        if (it->queueTime >= getActiveLayerThreshold(now)) {
-            break;
-        }
-    }
-
-    const auto numFrames = std::distance(it, mFrameTimes.end());
-    if (numFrames < FREQUENT_LAYER_WINDOW_SIZE) {
-        return false;
-    }
-
-    // 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;
+    ALOGV("%s infrequent (not enough frames %zu)", mName.c_str(), mFrameTimes.size());
+    return false;
 }
 
 bool LayerInfoV2::hasEnoughDataForHeuristic() const {
@@ -89,10 +72,6 @@
         return false;
     }
 
-    if (!isFrameTimeValid(mFrameTimes.front())) {
-        return false;
-    }
-
     if (mFrameTimes.size() < HISTORY_SIZE &&
         mFrameTimes.back().queueTime - mFrameTimes.front().queueTime < HISTORY_TIME.count()) {
         return false;
@@ -167,18 +146,22 @@
 
 std::pair<LayerHistory::LayerVoteType, float> LayerInfoV2::getRefreshRate(nsecs_t now) {
     if (mLayerVote.type != LayerHistory::LayerVoteType::Heuristic) {
+        ALOGV("%s voted %d ", mName.c_str(), static_cast<int>(mLayerVote.type));
         return {mLayerVote.type, mLayerVote.fps};
     }
 
     if (!isFrequent(now)) {
+        ALOGV("%s is infrequent", mName.c_str());
         return {LayerHistory::LayerVoteType::Min, 0};
     }
 
     auto refreshRate = calculateRefreshRateIfPossible();
     if (refreshRate.has_value()) {
+        ALOGV("%s calculated refresh rate: %.2f", mName.c_str(), refreshRate.value());
         return {LayerHistory::LayerVoteType::Heuristic, refreshRate.value()};
     }
 
+    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 e36b7f7..97c7017 100644
--- a/services/surfaceflinger/Scheduler/LayerInfoV2.h
+++ b/services/surfaceflinger/Scheduler/LayerInfoV2.h
@@ -54,7 +54,8 @@
     friend class LayerHistoryTestV2;
 
 public:
-    LayerInfoV2(nsecs_t highRefreshRatePeriod, LayerHistory::LayerVoteType defaultVote);
+    LayerInfoV2(const std::string& name, nsecs_t highRefreshRatePeriod,
+                LayerHistory::LayerVoteType defaultVote);
 
     LayerInfoV2(const LayerInfo&) = delete;
     LayerInfoV2& operator=(const LayerInfoV2&) = delete;
@@ -83,11 +84,7 @@
     nsecs_t getLastUpdatedTime() const { return mLastUpdatedTime; }
 
     void clearHistory() {
-        // 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.
-        mFrameTimeValidSince = std::chrono::steady_clock::now();
+        mFrameTimes.clear();
         mLastReportedRefreshRate = 0.0f;
     }
 
@@ -101,7 +98,8 @@
     bool isFrequent(nsecs_t now) const;
     bool hasEnoughDataForHeuristic() const;
     std::optional<float> calculateRefreshRateIfPossible();
-    bool isFrameTimeValid(const FrameTimeData&) const;
+
+    const std::string mName;
 
     // Used for sanitizing the heuristic data
     const nsecs_t mHighRefreshRatePeriod;
@@ -118,8 +116,6 @@
     } 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 8d958df..4a4f9c8 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
@@ -103,7 +103,7 @@
     ATRACE_CALL();
     ALOGV("getRefreshRateForContent %zu layers", layers.size());
 
-    *touchConsidered = false;
+    if (touchConsidered) *touchConsidered = false;
     std::lock_guard lock(mLock);
 
     int noVoteLayers = 0;
@@ -131,7 +131,8 @@
     // Consider the touch event if there are no Explicit* layers. Otherwise wait until after we've
     // selected a refresh rate to see if we should apply touch boost.
     if (touchActive && explicitDefaultVoteLayers == 0 && explicitExactOrMultipleVoteLayers == 0) {
-        *touchConsidered = true;
+        ALOGV("TouchBoost - choose %s", getMaxRefreshRateByPolicyLocked().getName().c_str());
+        if (touchConsidered) *touchConsidered = true;
         return getMaxRefreshRateByPolicyLocked();
     }
 
@@ -139,12 +140,13 @@
         return getMinRefreshRateByPolicyLocked();
     }
 
-    if (layers.empty()) {
-        return getCurrentRefreshRateByPolicyLocked();
+    if (layers.empty() || noVoteLayers == layers.size()) {
+        return getMaxRefreshRateByPolicyLocked();
     }
 
     // Only if all layers want Min we should return Min
     if (noVoteLayers + minVoteLayers == layers.size()) {
+        ALOGV("all layers Min - choose %s", getMinRefreshRateByPolicyLocked().getName().c_str());
         return getMinRefreshRateByPolicyLocked();
     }
 
@@ -243,9 +245,11 @@
 
                     return 1.0f / iter;
                 }();
-                ALOGV("%s (ExplicitExactOrMultiple, weight %.2f) %.2fHz gives %s score of %.2f",
-                      layer.name.c_str(), weight, 1e9f / layerPeriod, scores[i].first->name.c_str(),
-                      layerScore);
+                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);
                 scores[i].second += weight * layerScore;
                 continue;
             }
@@ -266,7 +270,8 @@
     const RefreshRate& touchRefreshRate = getMaxRefreshRateByPolicyLocked();
     if (touchActive && explicitDefaultVoteLayers == 0 &&
         bestRefreshRate->fps < touchRefreshRate.fps) {
-        *touchConsidered = true;
+        if (touchConsidered) *touchConsidered = true;
+        ALOGV("TouchBoost - choose %s", touchRefreshRate.getName().c_str());
         return touchRefreshRate;
     }
 
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index f87c1f8..4eef81d 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -385,38 +385,33 @@
 void Scheduler::registerLayer(Layer* layer) {
     if (!mLayerHistory) return;
 
-    // If the content detection feature is off, all layers are registered at NoVote. We still
-    // keep the layer history, since we use it for other features (like Frame Rate API), so layers
-    // still need to be registered.
-    if (!mUseContentDetection) {
-        mLayerHistory->registerLayer(layer, mRefreshRateConfigs.getMinRefreshRate().getFps(),
-                                     mRefreshRateConfigs.getMaxRefreshRate().getFps(),
+    const auto minFps = mRefreshRateConfigs.getMinRefreshRate().getFps();
+    const auto maxFps = mRefreshRateConfigs.getMaxRefreshRate().getFps();
+
+    if (layer->getWindowType() == InputWindowInfo::TYPE_STATUS_BAR) {
+        mLayerHistory->registerLayer(layer, minFps, maxFps,
                                      scheduler::LayerHistory::LayerVoteType::NoVote);
-        return;
-    }
+    } else if (!mUseContentDetection) {
+        // If the content detection feature is off, all layers are registered at Max. We still keep
+        // the layer history, since we use it for other features (like Frame Rate API), so layers
+        // still need to be registered.
+        mLayerHistory->registerLayer(layer, minFps, maxFps,
+                                     scheduler::LayerHistory::LayerVoteType::Max);
+    } else if (!mUseContentDetectionV2) {
+        // In V1 of content detection, all layers are registered as Heuristic (unless it's
+        // wallpaper).
+        const auto highFps =
+                layer->getWindowType() == InputWindowInfo::TYPE_WALLPAPER ? minFps : maxFps;
 
-    // In V1 of content detection, all layers are registered as Heuristic (unless it's wallpaper).
-    if (!mUseContentDetectionV2) {
-        const auto lowFps = mRefreshRateConfigs.getMinRefreshRate().getFps();
-        const auto highFps = layer->getWindowType() == InputWindowInfo::TYPE_WALLPAPER
-                ? lowFps
-                : mRefreshRateConfigs.getMaxRefreshRate().getFps();
-
-        mLayerHistory->registerLayer(layer, lowFps, highFps,
+        mLayerHistory->registerLayer(layer, minFps, highFps,
                                      scheduler::LayerHistory::LayerVoteType::Heuristic);
     } else {
         if (layer->getWindowType() == InputWindowInfo::TYPE_WALLPAPER) {
             // Running Wallpaper at Min is considered as part of content detection.
-            mLayerHistory->registerLayer(layer, mRefreshRateConfigs.getMinRefreshRate().getFps(),
-                                         mRefreshRateConfigs.getMaxRefreshRate().getFps(),
+            mLayerHistory->registerLayer(layer, minFps, maxFps,
                                          scheduler::LayerHistory::LayerVoteType::Min);
-        } else if (layer->getWindowType() == InputWindowInfo::TYPE_STATUS_BAR) {
-            mLayerHistory->registerLayer(layer, mRefreshRateConfigs.getMinRefreshRate().getFps(),
-                                         mRefreshRateConfigs.getMaxRefreshRate().getFps(),
-                                         scheduler::LayerHistory::LayerVoteType::NoVote);
         } else {
-            mLayerHistory->registerLayer(layer, mRefreshRateConfigs.getMinRefreshRate().getFps(),
-                                         mRefreshRateConfigs.getMaxRefreshRate().getFps(),
+            mLayerHistory->registerLayer(layer, minFps, maxFps,
                                          scheduler::LayerHistory::LayerVoteType::Heuristic);
         }
     }
@@ -526,7 +521,9 @@
 
 void Scheduler::touchTimerCallback(TimerState state) {
     const TouchState touch = state == TimerState::Reset ? TouchState::Active : TouchState::Inactive;
-    handleTimerStateChanged(&mFeatures.touch, touch, true /* eventOnContentDetection */);
+    if (handleTimerStateChanged(&mFeatures.touch, touch, true /* eventOnContentDetection */)) {
+        mLayerHistory->clear();
+    }
     ATRACE_INT("TouchState", static_cast<int>(touch));
 }
 
@@ -549,18 +546,19 @@
 }
 
 template <class T>
-void Scheduler::handleTimerStateChanged(T* currentState, T newState, bool eventOnContentDetection) {
+bool Scheduler::handleTimerStateChanged(T* currentState, T newState, bool eventOnContentDetection) {
     ConfigEvent event = ConfigEvent::None;
     HwcConfigIndexType newConfigId;
+    bool touchConsidered = false;
     {
         std::lock_guard<std::mutex> lock(mFeatureStateLock);
         if (*currentState == newState) {
-            return;
+            return touchConsidered;
         }
         *currentState = newState;
-        newConfigId = calculateRefreshRateConfigIndexType();
+        newConfigId = calculateRefreshRateConfigIndexType(&touchConsidered);
         if (mFeatures.configId == newConfigId) {
-            return;
+            return touchConsidered;
         }
         mFeatures.configId = newConfigId;
         if (eventOnContentDetection && !mFeatures.contentRequirements.empty()) {
@@ -569,10 +567,12 @@
     }
     const RefreshRate& newRefreshRate = mRefreshRateConfigs.getRefreshRateFromConfigId(newConfigId);
     mSchedulerCallback.changeRefreshRate(newRefreshRate, event);
+    return touchConsidered;
 }
 
-HwcConfigIndexType Scheduler::calculateRefreshRateConfigIndexType() {
+HwcConfigIndexType Scheduler::calculateRefreshRateConfigIndexType(bool* touchConsidered) {
     ATRACE_CALL();
+    if (touchConsidered) *touchConsidered = false;
 
     // If Display Power is not in normal operation we want to be in performance mode. When coming
     // back to normal mode, a grace period is given with DisplayPowerTimer.
@@ -607,18 +607,9 @@
                 .getConfigId();
     }
 
-    bool touchConsidered;
-    const auto& ret = mRefreshRateConfigs
-                              .getBestRefreshRate(mFeatures.contentRequirements, touchActive, idle,
-                                                  &touchConsidered)
-                              .getConfigId();
-    if (touchConsidered) {
-        // Clear layer history if refresh rate was selected based on touch to allow
-        // the hueristic to pick up with the new rate.
-        mLayerHistory->clear();
-    }
-
-    return ret;
+    return mRefreshRateConfigs
+            .getBestRefreshRate(mFeatures.contentRequirements, touchActive, idle, touchConsidered)
+            .getConfigId();
 }
 
 std::optional<HwcConfigIndexType> Scheduler::getPreferredConfigId() {
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index 4a0280f..6eabfd2 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -177,14 +177,15 @@
 
     // handles various timer features to change the refresh rate.
     template <class T>
-    void handleTimerStateChanged(T* currentState, T newState, bool eventOnContentDetection);
+    bool handleTimerStateChanged(T* currentState, T newState, bool eventOnContentDetection);
 
     void setVsyncPeriod(nsecs_t period);
 
     // This function checks whether individual features that are affecting the refresh rate
     // selection were initialized, prioritizes them, and calculates the HwcConfigIndexType
     // for the suggested refresh rate.
-    HwcConfigIndexType calculateRefreshRateConfigIndexType() REQUIRES(mFeatureStateLock);
+    HwcConfigIndexType calculateRefreshRateConfigIndexType(bool* touchConsidered = nullptr)
+            REQUIRES(mFeatureStateLock);
 
     // Stores EventThread associated with a given VSyncSource, and an initial EventThreadConnection.
     struct Connection {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index e65b80a..18f789e 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1943,13 +1943,9 @@
             const nsecs_t jankDuration = currentTime - mMissedFrameJankStart;
             if (jankDuration > kMinJankyDuration && jankDuration < kMaxJankyDuration) {
                 ATRACE_NAME("Jank detected");
-                ALOGD("Detected janky event. Missed frames: %d", mMissedFrameJankCount);
                 const int32_t jankyDurationMillis = jankDuration / (1000 * 1000);
-                {
-                    ATRACE_NAME("Pushing to statsd");
-                    android::util::stats_write(android::util::DISPLAY_JANK_REPORTED,
-                                               jankyDurationMillis, mMissedFrameJankCount);
-                }
+                android::util::stats_write(android::util::DISPLAY_JANK_REPORTED,
+                                           jankyDurationMillis, mMissedFrameJankCount);
             }
 
             // We either reported a jank event or we missed the trace
diff --git a/services/surfaceflinger/tests/unittests/LayerHistoryTestV2.cpp b/services/surfaceflinger/tests/unittests/LayerHistoryTestV2.cpp
index 431cf0f..d55648a 100644
--- a/services/surfaceflinger/tests/unittests/LayerHistoryTestV2.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerHistoryTestV2.cpp
@@ -103,12 +103,22 @@
     EXPECT_TRUE(history().summarize(time).empty());
     EXPECT_EQ(0, activeLayerCount());
 
+    // The first few updates are considered infrequent
+    for (int i = 0; i < FREQUENT_LAYER_WINDOW_SIZE - 1; i++) {
+        history().record(layer.get(), 0, time);
+        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));
+    }
+
     // Max returned if active layers have insufficient history.
-    for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE - 1; i++) {
+    for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE - FREQUENT_LAYER_WINDOW_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.
@@ -117,6 +127,7 @@
         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));
     }
 }
 
@@ -134,7 +145,7 @@
     auto summary = history().summarize(time);
     ASSERT_EQ(1, history().summarize(time).size());
     // Layer is still considered inactive so we expect to get Min
-    EXPECT_EQ(LayerHistory::LayerVoteType::Max, history().summarize(time)[0].vote);
+    EXPECT_EQ(LayerHistory::LayerVoteType::Min, history().summarize(time)[0].vote);
     EXPECT_EQ(1, activeLayerCount());
 
     EXPECT_CALL(*layer, isVisible()).WillRepeatedly(Return(false));
@@ -464,28 +475,15 @@
 
     nsecs_t time = systemTime();
 
-    // the very first updates makes the layer frequent
+    // The first few updates are considered infrequent
     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());
+        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(LayerHistory::LayerVoteType::Min, history().summarize(time)[0].vote);
         EXPECT_EQ(1, activeLayerCount());
-        EXPECT_EQ(1, frequentLayerCount(time));
+        EXPECT_EQ(0, 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();
 
@@ -528,9 +526,11 @@
 
     nsecs_t time = systemTime();
 
-    // Post a buffer to the layers to make them active
-    history().record(explicitVisiblelayer.get(), time, time);
-    history().record(explicitInvisiblelayer.get(), time, time);
+    // 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);
+    }
 
     EXPECT_EQ(2, layerCount());
     ASSERT_EQ(1, history().summarize(time).size());
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
index 2b168b2..692f71f 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
@@ -340,15 +340,14 @@
             std::make_unique<RefreshRateConfigs>(m60_72_90Device, /*currentConfigId=*/
                                                  HWC_CONFIG_ID_72);
 
-    // If there are not layers, there is not content detection, so return the current
-    // refresh rate.
+    // If there are no layers we select the default frame rate, which is the max of the primary
+    // range.
     auto layers = std::vector<LayerRequirement>{};
-    EXPECT_EQ(mExpected72Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/
                                                      false, /*idle*/ false, &ignored));
 
-    // Current refresh rate can always be changed.
-    refreshRateConfigs->setCurrentConfigId(HWC_CONFIG_ID_60);
+    ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, {60, 60}}), 0);
     EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/
                                                      false, /*idle*/ false, &ignored));