Pass StatsdConfigOptions to MetricProducers

Bug: 328659716
Test: atest statsd_test
Change-Id: Ib52389bb07da25b841c387bdf6df2b984a8bb1ef
diff --git a/statsd/src/config/ConfigMetadataProvider.h b/statsd/src/config/ConfigMetadataProvider.h
new file mode 100644
index 0000000..451503a
--- /dev/null
+++ b/statsd/src/config/ConfigMetadataProvider.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <utils/RefBase.h>
+
+namespace android {
+namespace os {
+namespace statsd {
+
+class ConfigMetadataProvider : virtual public RefBase {
+public:
+    virtual ~ConfigMetadataProvider() {
+    }
+
+    virtual bool useV2SoftMemoryCalculation() = 0;
+};
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/statsd/src/metrics/CountMetricProducer.cpp b/statsd/src/metrics/CountMetricProducer.cpp
index 879b40e..fb5f488 100644
--- a/statsd/src/metrics/CountMetricProducer.cpp
+++ b/statsd/src/metrics/CountMetricProducer.cpp
@@ -74,13 +74,14 @@
         const ConfigKey& key, const CountMetric& metric, const int conditionIndex,
         const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
         const uint64_t protoHash, const int64_t timeBaseNs, const int64_t startTimeNs,
+        const wp<ConfigMetadataProvider> configMetadataProvider,
         const unordered_map<int, shared_ptr<Activation>>& eventActivationMap,
         const unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap,
         const vector<int>& slicedStateAtoms,
         const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap)
     : MetricProducer(metric.id(), key, timeBaseNs, conditionIndex, initialConditionCache, wizard,
                      protoHash, eventActivationMap, eventDeactivationMap, slicedStateAtoms,
-                     stateGroupMap, getAppUpgradeBucketSplit(metric)),
+                     stateGroupMap, getAppUpgradeBucketSplit(metric), configMetadataProvider),
       mDimensionGuardrailHit(false),
       mDimensionHardLimit(
               StatsdStats::clampDimensionKeySizeLimit(metric.max_dimensions_per_bucket())) {
diff --git a/statsd/src/metrics/CountMetricProducer.h b/statsd/src/metrics/CountMetricProducer.h
index 7fa463f..757dad2 100644
--- a/statsd/src/metrics/CountMetricProducer.h
+++ b/statsd/src/metrics/CountMetricProducer.h
@@ -47,6 +47,7 @@
             const ConfigKey& key, const CountMetric& countMetric, int conditionIndex,
             const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
             const uint64_t protoHash, int64_t timeBaseNs, int64_t startTimeNs,
+            const wp<ConfigMetadataProvider> configMetadataProvider,
             const std::unordered_map<int, std::shared_ptr<Activation>>& eventActivationMap = {},
             const std::unordered_map<int, std::vector<std::shared_ptr<Activation>>>&
                     eventDeactivationMap = {},
diff --git a/statsd/src/metrics/DurationMetricProducer.cpp b/statsd/src/metrics/DurationMetricProducer.cpp
index c96f608..e18f83c 100644
--- a/statsd/src/metrics/DurationMetricProducer.cpp
+++ b/statsd/src/metrics/DurationMetricProducer.cpp
@@ -74,13 +74,14 @@
         const int startIndex, const int stopIndex, const int stopAllIndex, const bool nesting,
         const sp<ConditionWizard>& wizard, const uint64_t protoHash,
         const FieldMatcher& internalDimensions, const int64_t timeBaseNs, const int64_t startTimeNs,
+        const wp<ConfigMetadataProvider> configMetadataProvider,
         const unordered_map<int, shared_ptr<Activation>>& eventActivationMap,
         const unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap,
         const vector<int>& slicedStateAtoms,
         const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap)
     : MetricProducer(metric.id(), key, timeBaseNs, conditionIndex, initialConditionCache, wizard,
                      protoHash, eventActivationMap, eventDeactivationMap, slicedStateAtoms,
-                     stateGroupMap, getAppUpgradeBucketSplit(metric)),
+                     stateGroupMap, getAppUpgradeBucketSplit(metric), configMetadataProvider),
       mAggregationType(metric.aggregation_type()),
       mStartIndex(startIndex),
       mStopIndex(stopIndex),
diff --git a/statsd/src/metrics/DurationMetricProducer.h b/statsd/src/metrics/DurationMetricProducer.h
index 2f3d859..b7bc29a 100644
--- a/statsd/src/metrics/DurationMetricProducer.h
+++ b/statsd/src/metrics/DurationMetricProducer.h
@@ -44,6 +44,7 @@
             const int startIndex, int stopIndex, int stopAllIndex, const bool nesting,
             const sp<ConditionWizard>& wizard, const uint64_t protoHash,
             const FieldMatcher& internalDimensions, int64_t timeBaseNs, const int64_t startTimeNs,
+            const wp<ConfigMetadataProvider> configMetadataProvider,
             const unordered_map<int, shared_ptr<Activation>>& eventActivationMap = {},
             const unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap = {},
             const vector<int>& slicedStateAtoms = {},
diff --git a/statsd/src/metrics/EventMetricProducer.cpp b/statsd/src/metrics/EventMetricProducer.cpp
index 5b682e0..a8f4539 100644
--- a/statsd/src/metrics/EventMetricProducer.cpp
+++ b/statsd/src/metrics/EventMetricProducer.cpp
@@ -61,13 +61,14 @@
         const ConfigKey& key, const EventMetric& metric, const int conditionIndex,
         const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
         const uint64_t protoHash, const int64_t startTimeNs,
+        const wp<ConfigMetadataProvider> configMetadataProvider,
         const unordered_map<int, shared_ptr<Activation>>& eventActivationMap,
         const unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap,
         const vector<int>& slicedStateAtoms,
         const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap)
     : MetricProducer(metric.id(), key, startTimeNs, conditionIndex, initialConditionCache, wizard,
                      protoHash, eventActivationMap, eventDeactivationMap, slicedStateAtoms,
-                     stateGroupMap, /*splitBucketForAppUpgrade=*/nullopt),
+                     stateGroupMap, /*splitBucketForAppUpgrade=*/nullopt, configMetadataProvider),
       mSamplingPercentage(metric.sampling_percentage()) {
     if (metric.links().size() > 0) {
         for (const auto& link : metric.links()) {
diff --git a/statsd/src/metrics/EventMetricProducer.h b/statsd/src/metrics/EventMetricProducer.h
index 6e02659..aed4358 100644
--- a/statsd/src/metrics/EventMetricProducer.h
+++ b/statsd/src/metrics/EventMetricProducer.h
@@ -38,6 +38,7 @@
             const ConfigKey& key, const EventMetric& eventMetric, int conditionIndex,
             const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
             const uint64_t protoHash, int64_t startTimeNs,
+            const wp<ConfigMetadataProvider> configMetadataProvider,
             const std::unordered_map<int, std::shared_ptr<Activation>>& eventActivationMap = {},
             const std::unordered_map<int, std::vector<std::shared_ptr<Activation>>>&
                     eventDeactivationMap = {},
diff --git a/statsd/src/metrics/GaugeMetricProducer.cpp b/statsd/src/metrics/GaugeMetricProducer.cpp
index 974c9ae..f82f04e 100644
--- a/statsd/src/metrics/GaugeMetricProducer.cpp
+++ b/statsd/src/metrics/GaugeMetricProducer.cpp
@@ -81,12 +81,14 @@
         const sp<EventMatcherWizard>& matcherWizard, const int pullTagId, const int triggerAtomId,
         const int atomId, const int64_t timeBaseNs, const int64_t startTimeNs,
         const sp<StatsPullerManager>& pullerManager,
+        const wp<ConfigMetadataProvider> configMetadataProvider,
         const unordered_map<int, shared_ptr<Activation>>& eventActivationMap,
         const unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap,
         const size_t dimensionSoftLimit, const size_t dimensionHardLimit)
     : MetricProducer(metric.id(), key, timeBaseNs, conditionIndex, initialConditionCache, wizard,
                      protoHash, eventActivationMap, eventDeactivationMap, /*slicedStateAtoms=*/{},
-                     /*stateGroupMap=*/{}, getAppUpgradeBucketSplit(metric)),
+                     /*stateGroupMap=*/{}, getAppUpgradeBucketSplit(metric),
+                     configMetadataProvider),
       mWhatMatcherIndex(whatMatcherIndex),
       mEventMatcherWizard(matcherWizard),
       mPullerManager(pullerManager),
diff --git a/statsd/src/metrics/GaugeMetricProducer.h b/statsd/src/metrics/GaugeMetricProducer.h
index 6563ab5..fbcab81 100644
--- a/statsd/src/metrics/GaugeMetricProducer.h
+++ b/statsd/src/metrics/GaugeMetricProducer.h
@@ -66,6 +66,7 @@
             const int whatMatcherIndex, const sp<EventMatcherWizard>& matcherWizard,
             const int pullTagId, int triggerAtomId, int atomId, const int64_t timeBaseNs,
             int64_t startTimeNs, const sp<StatsPullerManager>& pullerManager,
+            const wp<ConfigMetadataProvider> configMetadataProvider,
             const std::unordered_map<int, std::shared_ptr<Activation>>& eventActivationMap = {},
             const std::unordered_map<int, std::vector<std::shared_ptr<Activation>>>&
                     eventDeactivationMap = {},
diff --git a/statsd/src/metrics/KllMetricProducer.cpp b/statsd/src/metrics/KllMetricProducer.cpp
index 8e50567..26aafa4 100644
--- a/statsd/src/metrics/KllMetricProducer.cpp
+++ b/statsd/src/metrics/KllMetricProducer.cpp
@@ -58,9 +58,11 @@
                                      const ConditionOptions& conditionOptions,
                                      const StateOptions& stateOptions,
                                      const ActivationOptions& activationOptions,
-                                     const GuardrailOptions& guardrailOptions)
+                                     const GuardrailOptions& guardrailOptions,
+                                     const wp<ConfigMetadataProvider> configMetadataProvider)
     : ValueMetricProducer(metric.id(), key, protoHash, pullOptions, bucketOptions, whatOptions,
-                          conditionOptions, stateOptions, activationOptions, guardrailOptions) {
+                          conditionOptions, stateOptions, activationOptions, guardrailOptions,
+                          configMetadataProvider) {
 }
 
 KllMetricProducer::DumpProtoFields KllMetricProducer::getDumpProtoFields() const {
diff --git a/statsd/src/metrics/KllMetricProducer.h b/statsd/src/metrics/KllMetricProducer.h
index 43ca6a4..16c1e2a 100644
--- a/statsd/src/metrics/KllMetricProducer.h
+++ b/statsd/src/metrics/KllMetricProducer.h
@@ -48,7 +48,8 @@
                       const PullOptions& pullOptions, const BucketOptions& bucketOptions,
                       const WhatOptions& whatOptions, const ConditionOptions& conditionOptions,
                       const StateOptions& stateOptions, const ActivationOptions& activationOptions,
-                      const GuardrailOptions& guardrailOptions);
+                      const GuardrailOptions& guardrailOptions,
+                      const wp<ConfigMetadataProvider> configMetadataProvider);
 
     inline MetricType getMetricType() const override {
         return METRIC_TYPE_KLL;
diff --git a/statsd/src/metrics/MetricProducer.cpp b/statsd/src/metrics/MetricProducer.cpp
index 55c9adf..14c07a8 100644
--- a/statsd/src/metrics/MetricProducer.cpp
+++ b/statsd/src/metrics/MetricProducer.cpp
@@ -53,7 +53,8 @@
                 eventDeactivationMap,
         const vector<int>& slicedStateAtoms,
         const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap,
-        const optional<bool> splitBucketForAppUpgrade)
+        const optional<bool> splitBucketForAppUpgrade,
+        const wp<ConfigMetadataProvider> configMetadataProvider)
     : mMetricId(metricId),
       mProtoHash(protoHash),
       mConfigKey(key),
@@ -78,7 +79,8 @@
       mSplitBucketForAppUpgrade(splitBucketForAppUpgrade),
       mHasHitGuardrail(false),
       mSampledWhatFields({}),
-      mShardCount(0) {
+      mShardCount(0),
+      mConfigMetadataProvider(configMetadataProvider) {
 }
 
 optional<InvalidConfigReason> MetricProducer::onConfigUpdatedLocked(
diff --git a/statsd/src/metrics/MetricProducer.h b/statsd/src/metrics/MetricProducer.h
index 133aa32..eee2006 100644
--- a/statsd/src/metrics/MetricProducer.h
+++ b/statsd/src/metrics/MetricProducer.h
@@ -27,6 +27,7 @@
 #include "condition/ConditionTimer.h"
 #include "condition/ConditionWizard.h"
 #include "config/ConfigKey.h"
+#include "config/ConfigMetadataProvider.h"
 #include "guardrail/StatsdStats.h"
 #include "matchers/EventMatcherWizard.h"
 #include "matchers/matcher_util.h"
@@ -136,7 +137,8 @@
                            eventDeactivationMap,
                    const vector<int>& slicedStateAtoms,
                    const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap,
-                   const optional<bool> splitBucketForAppUpgrade);
+                   const optional<bool> splitBucketForAppUpgrade,
+                   const wp<ConfigMetadataProvider> configMetadataProvider);
 
     virtual ~MetricProducer(){};
 
@@ -577,6 +579,12 @@
 
     int mShardCount;
 
+    inline wp<ConfigMetadataProvider> getConfigMetadataProvider() const {
+        return mConfigMetadataProvider;
+    }
+
+    wp<ConfigMetadataProvider> mConfigMetadataProvider;
+
     FRIEND_TEST(CountMetricE2eTest, TestSlicedState);
     FRIEND_TEST(CountMetricE2eTest, TestSlicedStateWithMap);
     FRIEND_TEST(CountMetricE2eTest, TestMultipleSlicedStates);
diff --git a/statsd/src/metrics/MetricsManager.cpp b/statsd/src/metrics/MetricsManager.cpp
index 6ce8bce..12a3f27 100644
--- a/statsd/src/metrics/MetricsManager.cpp
+++ b/statsd/src/metrics/MetricsManager.cpp
@@ -78,7 +78,8 @@
       mPullerManager(pullerManager),
       mWhitelistedAtomIds(config.whitelisted_atom_ids().begin(),
                           config.whitelisted_atom_ids().end()),
-      mShouldPersistHistory(config.persist_locally()) {
+      mShouldPersistHistory(config.persist_locally()),
+      mUseV2SoftMemoryCalculation(config.statsd_config_options().use_v2_soft_memory_limit()) {
     if (!isAtLeastU() && config.has_restricted_metrics_delegate_package_name()) {
         mInvalidConfigReason =
                 InvalidConfigReason(INVALID_CONFIG_REASON_RESTRICTED_METRIC_NOT_ENABLED);
@@ -91,7 +92,7 @@
     refreshTtl(timeBaseNs);
     mInvalidConfigReason = initStatsdConfig(
             key, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
-            timeBaseNs, currentTimeNs, mTagIdsToMatchersMap, mAllAtomMatchingTrackers,
+            timeBaseNs, currentTimeNs, this, mTagIdsToMatchersMap, mAllAtomMatchingTrackers,
             mAtomMatchingTrackerMap, mAllConditionTrackers, mConditionTrackerMap,
             mAllMetricProducers, mMetricProducerMap, mAllAnomalyTrackers, mAllPeriodicAlarmTrackers,
             mConditionToMetricMap, mTrackerToMetricMap, mTrackerToConditionMap,
@@ -162,7 +163,7 @@
             mConfigKey, config, mUidMap, mPullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
             timeBaseNs, currentTimeNs, mAllAtomMatchingTrackers, mAtomMatchingTrackerMap,
             mAllConditionTrackers, mConditionTrackerMap, mAllMetricProducers, mMetricProducerMap,
-            mAllAnomalyTrackers, mAlertTrackerMap, mStateProtoHashes, mTagIdsToMatchersMap,
+            mAllAnomalyTrackers, mAlertTrackerMap, mStateProtoHashes, this, mTagIdsToMatchersMap,
             newAtomMatchingTrackers, newAtomMatchingTrackerMap, newConditionTrackers,
             newConditionTrackerMap, newMetricProducers, newMetricProducerMap, newAnomalyTrackers,
             newAlertTrackerMap, newPeriodicAlarmTrackers, mConditionToMetricMap,
@@ -191,6 +192,7 @@
                                config.whitelisted_atom_ids().end());
     mShouldPersistHistory = config.persist_locally();
     mPackageCertificateHashSizeBytes = config.package_certificate_hash_size_bytes();
+    mUseV2SoftMemoryCalculation = config.statsd_config_options().use_v2_soft_memory_limit();
 
     // Store the sub-configs used.
     mAnnotations.clear();
@@ -442,6 +444,10 @@
     return uids;
 }
 
+bool MetricsManager::useV2SoftMemoryCalculation() {
+    return mUseV2SoftMemoryCalculation;
+}
+
 void MetricsManager::dumpStates(int out, bool verbose) {
     dprintf(out, "ConfigKey %s, allowed source:", mConfigKey.ToString().c_str());
     {
diff --git a/statsd/src/metrics/MetricsManager.h b/statsd/src/metrics/MetricsManager.h
index 4ccee56..3b28b6a 100644
--- a/statsd/src/metrics/MetricsManager.h
+++ b/statsd/src/metrics/MetricsManager.h
@@ -23,6 +23,7 @@
 #include "anomaly/AnomalyTracker.h"
 #include "condition/ConditionTracker.h"
 #include "config/ConfigKey.h"
+#include "config/ConfigMetadataProvider.h"
 #include "external/StatsPullerManager.h"
 #include "guardrail/StatsdStats.h"
 #include "logd/LogEvent.h"
@@ -37,7 +38,9 @@
 namespace statsd {
 
 // A MetricsManager is responsible for managing metrics from one single config source.
-class MetricsManager : public virtual RefBase, public virtual PullUidProvider {
+class MetricsManager : public virtual RefBase,
+                       public virtual PullUidProvider,
+                       public virtual ConfigMetadataProvider {
 public:
     MetricsManager(const ConfigKey& configKey, const StatsdConfig& config, int64_t timeBaseNs,
                    const int64_t currentTimeNs, const sp<UidMap>& uidMap,
@@ -78,6 +81,8 @@
 
     vector<int32_t> getPullAtomUids(int32_t atomId) override;
 
+    bool useV2SoftMemoryCalculation() override;
+
     bool shouldWriteToDisk() const {
         return mNoReportMetricIds.size() != mAllMetricProducers.size();
     }
@@ -247,6 +252,7 @@
     std::list<std::pair<const int64_t, const int32_t>> mAnnotations;
 
     bool mShouldPersistHistory;
+    bool mUseV2SoftMemoryCalculation;
 
     // All event tags that are interesting to config metrics matchers.
     std::unordered_map<int, std::vector<int>> mTagIdsToMatchersMap;
diff --git a/statsd/src/metrics/NumericValueMetricProducer.cpp b/statsd/src/metrics/NumericValueMetricProducer.cpp
index 88c4d16..53a1901 100644
--- a/statsd/src/metrics/NumericValueMetricProducer.cpp
+++ b/statsd/src/metrics/NumericValueMetricProducer.cpp
@@ -67,9 +67,11 @@
         const PullOptions& pullOptions, const BucketOptions& bucketOptions,
         const WhatOptions& whatOptions, const ConditionOptions& conditionOptions,
         const StateOptions& stateOptions, const ActivationOptions& activationOptions,
-        const GuardrailOptions& guardrailOptions)
+        const GuardrailOptions& guardrailOptions,
+        const wp<ConfigMetadataProvider> configMetadataProvider)
     : ValueMetricProducer(metric.id(), key, protoHash, pullOptions, bucketOptions, whatOptions,
-                          conditionOptions, stateOptions, activationOptions, guardrailOptions),
+                          conditionOptions, stateOptions, activationOptions, guardrailOptions,
+                          configMetadataProvider),
       mUseAbsoluteValueOnReset(metric.use_absolute_value_on_reset()),
       mAggregationTypes(whatOptions.aggregationTypes),
       mIncludeSampleSize(metric.has_include_sample_size()
diff --git a/statsd/src/metrics/NumericValueMetricProducer.h b/statsd/src/metrics/NumericValueMetricProducer.h
index 9c123f6..103f404 100644
--- a/statsd/src/metrics/NumericValueMetricProducer.h
+++ b/statsd/src/metrics/NumericValueMetricProducer.h
@@ -36,7 +36,8 @@
                                const ConditionOptions& conditionOptions,
                                const StateOptions& stateOptions,
                                const ActivationOptions& activationOptions,
-                               const GuardrailOptions& guardrailOptions);
+                               const GuardrailOptions& guardrailOptions,
+                               const wp<ConfigMetadataProvider> configMetadataProvider);
 
     // Process data pulled on bucket boundary.
     void onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& allData, PullResult pullResult,
diff --git a/statsd/src/metrics/RestrictedEventMetricProducer.cpp b/statsd/src/metrics/RestrictedEventMetricProducer.cpp
index f38e835..83454fb 100644
--- a/statsd/src/metrics/RestrictedEventMetricProducer.cpp
+++ b/statsd/src/metrics/RestrictedEventMetricProducer.cpp
@@ -35,13 +35,14 @@
         const ConfigKey& key, const EventMetric& metric, const int conditionIndex,
         const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
         const uint64_t protoHash, const int64_t startTimeNs,
+        const wp<ConfigMetadataProvider> configMetadataProvider,
         const unordered_map<int, shared_ptr<Activation>>& eventActivationMap,
         const unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap,
         const vector<int>& slicedStateAtoms,
         const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap)
     : EventMetricProducer(key, metric, conditionIndex, initialConditionCache, wizard, protoHash,
-                          startTimeNs, eventActivationMap, eventDeactivationMap, slicedStateAtoms,
-                          stateGroupMap),
+                          startTimeNs, configMetadataProvider, eventActivationMap,
+                          eventDeactivationMap, slicedStateAtoms, stateGroupMap),
       mRestrictedDataCategory(CATEGORY_UNKNOWN) {
 }
 
diff --git a/statsd/src/metrics/RestrictedEventMetricProducer.h b/statsd/src/metrics/RestrictedEventMetricProducer.h
index 1f68387..7f9a5eb 100644
--- a/statsd/src/metrics/RestrictedEventMetricProducer.h
+++ b/statsd/src/metrics/RestrictedEventMetricProducer.h
@@ -16,6 +16,7 @@
             const ConfigKey& key, const EventMetric& eventMetric, const int conditionIndex,
             const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
             const uint64_t protoHash, int64_t startTimeNs,
+            const wp<ConfigMetadataProvider> configMetadataProvider,
             const std::unordered_map<int, std::shared_ptr<Activation>>& eventActivationMap = {},
             const std::unordered_map<int, std::vector<std::shared_ptr<Activation>>>&
                     eventDeactivationMap = {},
diff --git a/statsd/src/metrics/ValueMetricProducer.cpp b/statsd/src/metrics/ValueMetricProducer.cpp
index fac3d17..7937c69 100644
--- a/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/statsd/src/metrics/ValueMetricProducer.cpp
@@ -77,12 +77,14 @@
         const PullOptions& pullOptions, const BucketOptions& bucketOptions,
         const WhatOptions& whatOptions, const ConditionOptions& conditionOptions,
         const StateOptions& stateOptions, const ActivationOptions& activationOptions,
-        const GuardrailOptions& guardrailOptions)
+        const GuardrailOptions& guardrailOptions,
+        const wp<ConfigMetadataProvider> configMetadataProvider)
     : MetricProducer(metricId, key, bucketOptions.timeBaseNs, conditionOptions.conditionIndex,
                      conditionOptions.initialConditionCache, conditionOptions.conditionWizard,
                      protoHash, activationOptions.eventActivationMap,
                      activationOptions.eventDeactivationMap, stateOptions.slicedStateAtoms,
-                     stateOptions.stateGroupMap, bucketOptions.splitBucketForAppUpgrade),
+                     stateOptions.stateGroupMap, bucketOptions.splitBucketForAppUpgrade,
+                     configMetadataProvider),
       mWhatMatcherIndex(whatOptions.whatMatcherIndex),
       mEventMatcherWizard(whatOptions.matcherWizard),
       mPullerManager(pullOptions.pullerManager),
diff --git a/statsd/src/metrics/ValueMetricProducer.h b/statsd/src/metrics/ValueMetricProducer.h
index d10fc09..bfde6a0 100644
--- a/statsd/src/metrics/ValueMetricProducer.h
+++ b/statsd/src/metrics/ValueMetricProducer.h
@@ -139,7 +139,8 @@
                         const WhatOptions& whatOptions, const ConditionOptions& conditionOptions,
                         const StateOptions& stateOptions,
                         const ActivationOptions& activationOptions,
-                        const GuardrailOptions& guardrailOptions);
+                        const GuardrailOptions& guardrailOptions,
+                        const wp<ConfigMetadataProvider> configMetadataProvider);
 
     void onMatchedLogEventInternalLocked(
             const size_t matcherIndex, const MetricDimensionKey& eventKey,
diff --git a/statsd/src/metrics/parsing_utils/config_update_utils.cpp b/statsd/src/metrics/parsing_utils/config_update_utils.cpp
index 18d7a32..a296dad 100644
--- a/statsd/src/metrics/parsing_utils/config_update_utils.cpp
+++ b/statsd/src/metrics/parsing_utils/config_update_utils.cpp
@@ -730,6 +730,7 @@
         const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
         const set<int64_t>& replacedStates, const unordered_map<int64_t, int>& oldMetricProducerMap,
         const vector<sp<MetricProducer>>& oldMetricProducers,
+        const wp<ConfigMetadataProvider> configMetadataProvider,
         unordered_map<int64_t, int>& newMetricProducerMap,
         vector<sp<MetricProducer>>& newMetricProducers,
         unordered_map<int, vector<int>>& conditionToMetricMap,
@@ -802,7 +803,7 @@
                         allStateGroupMaps, metricToActivationMap, trackerToMetricMap,
                         conditionToMetricMap, activationAtomTrackerToMetricMap,
                         deactivationAtomTrackerToMetricMap, metricsWithActivation,
-                        invalidConfigReason);
+                        invalidConfigReason, configMetadataProvider);
                 break;
             }
             default: {
@@ -844,7 +845,7 @@
                         allStateGroupMaps, metricToActivationMap, trackerToMetricMap,
                         conditionToMetricMap, activationAtomTrackerToMetricMap,
                         deactivationAtomTrackerToMetricMap, metricsWithActivation,
-                        invalidConfigReason);
+                        invalidConfigReason, configMetadataProvider);
                 break;
             }
             default: {
@@ -885,7 +886,7 @@
                         initialConditionCache, wizard, metricToActivationMap, trackerToMetricMap,
                         conditionToMetricMap, activationAtomTrackerToMetricMap,
                         deactivationAtomTrackerToMetricMap, metricsWithActivation,
-                        invalidConfigReason);
+                        invalidConfigReason, configMetadataProvider);
                 break;
             }
             default: {
@@ -928,7 +929,7 @@
                         stateAtomIdMap, allStateGroupMaps, metricToActivationMap,
                         trackerToMetricMap, conditionToMetricMap, activationAtomTrackerToMetricMap,
                         deactivationAtomTrackerToMetricMap, metricsWithActivation,
-                        invalidConfigReason);
+                        invalidConfigReason, configMetadataProvider);
                 break;
             }
             default: {
@@ -970,7 +971,7 @@
                         conditionTrackerMap, initialConditionCache, wizard, matcherWizard,
                         metricToActivationMap, trackerToMetricMap, conditionToMetricMap,
                         activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
-                        metricsWithActivation, invalidConfigReason);
+                        metricsWithActivation, invalidConfigReason, configMetadataProvider);
                 break;
             }
             default: {
@@ -1014,7 +1015,7 @@
                         stateAtomIdMap, allStateGroupMaps, metricToActivationMap,
                         trackerToMetricMap, conditionToMetricMap, activationAtomTrackerToMetricMap,
                         deactivationAtomTrackerToMetricMap, metricsWithActivation,
-                        invalidConfigReason);
+                        invalidConfigReason, configMetadataProvider);
                 break;
             }
             default: {
@@ -1207,6 +1208,7 @@
         const vector<sp<AnomalyTracker>>& oldAnomalyTrackers,
         const unordered_map<int64_t, int>& oldAlertTrackerMap,
         const map<int64_t, uint64_t>& oldStateProtoHashes,
+        const wp<ConfigMetadataProvider> configMetadataProvider,
         std::unordered_map<int, std::vector<int>>& allTagIdsToMatchersMap,
         vector<sp<AtomMatchingTracker>>& newAtomMatchingTrackers,
         unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
@@ -1268,9 +1270,10 @@
             newAtomMatchingTrackerMap, replacedMatchers, newAtomMatchingTrackers,
             newConditionTrackerMap, replacedConditions, newConditionTrackers, conditionCache,
             stateAtomIdMap, allStateGroupMaps, replacedStates, oldMetricProducerMap,
-            oldMetricProducers, newMetricProducerMap, newMetricProducers, conditionToMetricMap,
-            trackerToMetricMap, noReportMetricIds, activationTrackerToMetricMap,
-            deactivationTrackerToMetricMap, metricsWithActivation, replacedMetrics);
+            oldMetricProducers, configMetadataProvider, newMetricProducerMap, newMetricProducers,
+            conditionToMetricMap, trackerToMetricMap, noReportMetricIds,
+            activationTrackerToMetricMap, deactivationTrackerToMetricMap, metricsWithActivation,
+            replacedMetrics);
     if (invalidConfigReason.has_value()) {
         ALOGE("updateMetrics failed");
         return invalidConfigReason;
diff --git a/statsd/src/metrics/parsing_utils/config_update_utils.h b/statsd/src/metrics/parsing_utils/config_update_utils.h
index 8b6c784..a8915c2 100644
--- a/statsd/src/metrics/parsing_utils/config_update_utils.h
+++ b/statsd/src/metrics/parsing_utils/config_update_utils.h
@@ -21,6 +21,7 @@
 #include "anomaly/AlarmMonitor.h"
 #include "anomaly/AlarmTracker.h"
 #include "condition/ConditionTracker.h"
+#include "config/ConfigMetadataProvider.h"
 #include "external/StatsPullerManager.h"
 #include "matchers/AtomMatchingTracker.h"
 #include "metrics/MetricProducer.h"
@@ -179,6 +180,7 @@
         const std::set<int64_t>& replacedStates,
         const std::unordered_map<int64_t, int>& oldMetricProducerMap,
         const std::vector<sp<MetricProducer>>& oldMetricProducers,
+        const wp<ConfigMetadataProvider> configMetadataProvider,
         std::unordered_map<int64_t, int>& newMetricProducerMap,
         std::vector<sp<MetricProducer>>& newMetricProducers,
         std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
@@ -245,6 +247,7 @@
         const std::vector<sp<AnomalyTracker>>& oldAnomalyTrackers,
         const std::unordered_map<int64_t, int>& oldAlertTrackerMap,
         const std::map<int64_t, uint64_t>& oldStateProtoHashes,
+        const wp<ConfigMetadataProvider> configMetadataProvider,
         std::unordered_map<int, std::vector<int>>& allTagIdsToMatchersMap,
         std::vector<sp<AtomMatchingTracker>>& newAtomMatchingTrackers,
         std::unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
diff --git a/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp b/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp
index dfdcc65..43744d3 100644
--- a/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp
+++ b/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp
@@ -509,7 +509,8 @@
         unordered_map<int, vector<int>>& conditionToMetricMap,
         unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
         unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
-        vector<int>& metricsWithActivation, optional<InvalidConfigReason>& invalidConfigReason) {
+        vector<int>& metricsWithActivation, optional<InvalidConfigReason>& invalidConfigReason,
+        const wp<ConfigMetadataProvider> configMetadataProvider) {
     if (!metric.has_id() || !metric.has_what()) {
         ALOGE("cannot find metric id or \"what\" in CountMetric \"%lld\"", (long long)metric.id());
         invalidConfigReason =
@@ -597,10 +598,10 @@
         return nullopt;
     }
 
-    sp<MetricProducer> metricProducer =
-            new CountMetricProducer(key, metric, conditionIndex, initialConditionCache, wizard,
-                                    metricHash, timeBaseNs, currentTimeNs, eventActivationMap,
-                                    eventDeactivationMap, slicedStateAtoms, stateGroupMap);
+    sp<MetricProducer> metricProducer = new CountMetricProducer(
+            key, metric, conditionIndex, initialConditionCache, wizard, metricHash, timeBaseNs,
+            currentTimeNs, configMetadataProvider, eventActivationMap, eventDeactivationMap,
+            slicedStateAtoms, stateGroupMap);
 
     SamplingInfo samplingInfo;
     if (metric.has_dimensional_sampling_info()) {
@@ -630,7 +631,8 @@
         unordered_map<int, vector<int>>& conditionToMetricMap,
         unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
         unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
-        vector<int>& metricsWithActivation, optional<InvalidConfigReason>& invalidConfigReason) {
+        vector<int>& metricsWithActivation, optional<InvalidConfigReason>& invalidConfigReason,
+        const wp<ConfigMetadataProvider> configMetadataProvider) {
     if (!metric.has_id() || !metric.has_what()) {
         ALOGE("cannot find metric id or \"what\" in DurationMetric \"%lld\"",
               (long long)metric.id());
@@ -778,8 +780,8 @@
     sp<MetricProducer> metricProducer = new DurationMetricProducer(
             key, metric, conditionIndex, initialConditionCache, whatIndex, startIndex, stopIndex,
             stopAllIndex, nesting, wizard, metricHash, internalDimensions, timeBaseNs,
-            currentTimeNs, eventActivationMap, eventDeactivationMap, slicedStateAtoms,
-            stateGroupMap);
+            currentTimeNs, configMetadataProvider, eventActivationMap, eventDeactivationMap,
+            slicedStateAtoms, stateGroupMap);
     if (!metricProducer->isValid()) {
         // TODO: Remove once invalidConfigReason is added to the DurationMetricProducer constructor
         invalidConfigReason = InvalidConfigReason(
@@ -813,7 +815,8 @@
         unordered_map<int, vector<int>>& conditionToMetricMap,
         unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
         unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
-        vector<int>& metricsWithActivation, optional<InvalidConfigReason>& invalidConfigReason) {
+        vector<int>& metricsWithActivation, optional<InvalidConfigReason>& invalidConfigReason,
+        const wp<ConfigMetadataProvider> configMetadataProvider) {
     if (!metric.has_id() || !metric.has_what()) {
         ALOGE("cannot find the metric name or what in config");
         invalidConfigReason =
@@ -869,11 +872,11 @@
     if (config.has_restricted_metrics_delegate_package_name()) {
         return {new RestrictedEventMetricProducer(
                 key, metric, conditionIndex, initialConditionCache, wizard, metricHash, timeBaseNs,
-                eventActivationMap, eventDeactivationMap)};
+                configMetadataProvider, eventActivationMap, eventDeactivationMap)};
     }
     return {new EventMetricProducer(key, metric, conditionIndex, initialConditionCache, wizard,
-                                    metricHash, timeBaseNs, eventActivationMap,
-                                    eventDeactivationMap)};
+                                    metricHash, timeBaseNs, configMetadataProvider,
+                                    eventActivationMap, eventDeactivationMap)};
 }
 
 optional<sp<MetricProducer>> createNumericValueMetricProducerAndUpdateMetadata(
@@ -893,7 +896,8 @@
         unordered_map<int, vector<int>>& conditionToMetricMap,
         unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
         unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
-        vector<int>& metricsWithActivation, optional<InvalidConfigReason>& invalidConfigReason) {
+        vector<int>& metricsWithActivation, optional<InvalidConfigReason>& invalidConfigReason,
+        const wp<ConfigMetadataProvider> configMetadataProvider) {
     if (!metric.has_id() || !metric.has_what()) {
         ALOGE("cannot find metric id or \"what\" in ValueMetric \"%lld\"", (long long)metric.id());
         invalidConfigReason =
@@ -1043,7 +1047,8 @@
              matcherWizard, metric.dimensions_in_what(), fieldMatchers, aggregationTypes},
             {conditionIndex, metric.links(), initialConditionCache, wizard},
             {metric.state_link(), slicedStateAtoms, stateGroupMap},
-            {eventActivationMap, eventDeactivationMap}, {dimensionSoftLimit, dimensionHardLimit});
+            {eventActivationMap, eventDeactivationMap}, {dimensionSoftLimit, dimensionHardLimit},
+            configMetadataProvider);
 
     SamplingInfo samplingInfo;
     if (metric.has_dimensional_sampling_info()) {
@@ -1075,7 +1080,8 @@
         unordered_map<int, vector<int>>& conditionToMetricMap,
         unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
         unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
-        vector<int>& metricsWithActivation, optional<InvalidConfigReason>& invalidConfigReason) {
+        vector<int>& metricsWithActivation, optional<InvalidConfigReason>& invalidConfigReason,
+        const wp<ConfigMetadataProvider> configMetadataProvider) {
     if (!metric.has_id() || !metric.has_what()) {
         ALOGE("cannot find metric id or \"what\" in KllMetric \"%lld\"", (long long)metric.id());
         invalidConfigReason =
@@ -1201,7 +1207,8 @@
              {}},
             {conditionIndex, metric.links(), initialConditionCache, wizard},
             {metric.state_link(), slicedStateAtoms, stateGroupMap},
-            {eventActivationMap, eventDeactivationMap}, {dimensionSoftLimit, dimensionHardLimit});
+            {eventActivationMap, eventDeactivationMap}, {dimensionSoftLimit, dimensionHardLimit},
+            configMetadataProvider);
 
     SamplingInfo samplingInfo;
     if (metric.has_dimensional_sampling_info()) {
@@ -1231,7 +1238,8 @@
         unordered_map<int, vector<int>>& conditionToMetricMap,
         unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
         unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
-        vector<int>& metricsWithActivation, optional<InvalidConfigReason>& invalidConfigReason) {
+        vector<int>& metricsWithActivation, optional<InvalidConfigReason>& invalidConfigReason,
+        const wp<ConfigMetadataProvider> configMetadataProvider) {
     if (!metric.has_id() || !metric.has_what()) {
         ALOGE("cannot find metric id or \"what\" in GaugeMetric \"%lld\"", (long long)metric.id());
         invalidConfigReason =
@@ -1370,8 +1378,8 @@
     sp<MetricProducer> metricProducer = new GaugeMetricProducer(
             key, metric, conditionIndex, initialConditionCache, wizard, metricHash, trackerIndex,
             matcherWizard, pullTagId, triggerAtomId, atomTagId, timeBaseNs, currentTimeNs,
-            pullerManager, eventActivationMap, eventDeactivationMap, dimensionSoftLimit,
-            dimensionHardLimit);
+            pullerManager, configMetadataProvider, eventActivationMap, eventDeactivationMap,
+            dimensionSoftLimit, dimensionHardLimit);
 
     SamplingInfo samplingInfo;
     std::vector<Matcher> dimensionsInWhat;
@@ -1579,7 +1587,8 @@
         std::set<int64_t>& noReportMetricIds,
         unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
         unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
-        vector<int>& metricsWithActivation) {
+        vector<int>& metricsWithActivation,
+        const wp<ConfigMetadataProvider> configMetadataProvider) {
     sp<ConditionWizard> wizard = new ConditionWizard(allConditionTrackers);
     sp<EventMatcherWizard> matcherWizard = new EventMatcherWizard(allAtomMatchingTrackers);
     const int allMetricsCount = config.count_metric_size() + config.duration_metric_size() +
@@ -1620,7 +1629,7 @@
                 conditionTrackerMap, initialConditionCache, wizard, stateAtomIdMap,
                 allStateGroupMaps, metricToActivationMap, trackerToMetricMap, conditionToMetricMap,
                 activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
-                metricsWithActivation, invalidConfigReason);
+                metricsWithActivation, invalidConfigReason, configMetadataProvider);
         if (!producer) {
             return invalidConfigReason;
         }
@@ -1639,7 +1648,7 @@
                 conditionTrackerMap, initialConditionCache, wizard, stateAtomIdMap,
                 allStateGroupMaps, metricToActivationMap, trackerToMetricMap, conditionToMetricMap,
                 activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
-                metricsWithActivation, invalidConfigReason);
+                metricsWithActivation, invalidConfigReason, configMetadataProvider);
         if (!producer) {
             return invalidConfigReason;
         }
@@ -1656,7 +1665,8 @@
                 atomMatchingTrackerMap, allConditionTrackers, conditionTrackerMap,
                 initialConditionCache, wizard, metricToActivationMap, trackerToMetricMap,
                 conditionToMetricMap, activationAtomTrackerToMetricMap,
-                deactivationAtomTrackerToMetricMap, metricsWithActivation, invalidConfigReason);
+                deactivationAtomTrackerToMetricMap, metricsWithActivation, invalidConfigReason,
+                configMetadataProvider);
         if (!producer) {
             return invalidConfigReason;
         }
@@ -1674,7 +1684,7 @@
                 conditionTrackerMap, initialConditionCache, wizard, matcherWizard, stateAtomIdMap,
                 allStateGroupMaps, metricToActivationMap, trackerToMetricMap, conditionToMetricMap,
                 activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
-                metricsWithActivation, invalidConfigReason);
+                metricsWithActivation, invalidConfigReason, configMetadataProvider);
         if (!producer) {
             return invalidConfigReason;
         }
@@ -1692,7 +1702,7 @@
                 conditionTrackerMap, initialConditionCache, wizard, matcherWizard, stateAtomIdMap,
                 allStateGroupMaps, metricToActivationMap, trackerToMetricMap, conditionToMetricMap,
                 activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
-                metricsWithActivation, invalidConfigReason);
+                metricsWithActivation, invalidConfigReason, configMetadataProvider);
         if (!producer) {
             return invalidConfigReason;
         }
@@ -1710,7 +1720,7 @@
                 conditionTrackerMap, initialConditionCache, wizard, matcherWizard,
                 metricToActivationMap, trackerToMetricMap, conditionToMetricMap,
                 activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
-                metricsWithActivation, invalidConfigReason);
+                metricsWithActivation, invalidConfigReason, configMetadataProvider);
         if (!producer) {
             return invalidConfigReason;
         }
@@ -1798,7 +1808,7 @@
         const ConfigKey& key, const StatsdConfig& config, const sp<UidMap>& uidMap,
         const sp<StatsPullerManager>& pullerManager, const sp<AlarmMonitor>& anomalyAlarmMonitor,
         const sp<AlarmMonitor>& periodicAlarmMonitor, const int64_t timeBaseNs,
-        const int64_t currentTimeNs,
+        const int64_t currentTimeNs, const wp<ConfigMetadataProvider> configMetadataProvider,
         std::unordered_map<int, std::vector<int>>& allTagIdsToMatchersMap,
         vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
         unordered_map<int64_t, int>& atomMatchingTrackerMap,
@@ -1854,7 +1864,7 @@
             allConditionTrackers, initialConditionCache, allMetricProducers, conditionToMetricMap,
             trackerToMetricMap, metricProducerMap, noReportMetricIds,
             activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
-            metricsWithActivation);
+            metricsWithActivation, configMetadataProvider);
     if (invalidConfigReason.has_value()) {
         ALOGE("initMetricProducers failed");
         return invalidConfigReason;
diff --git a/statsd/src/metrics/parsing_utils/metrics_manager_util.h b/statsd/src/metrics/parsing_utils/metrics_manager_util.h
index 41e8dc7..8a73ff0 100644
--- a/statsd/src/metrics/parsing_utils/metrics_manager_util.h
+++ b/statsd/src/metrics/parsing_utils/metrics_manager_util.h
@@ -22,6 +22,7 @@
 
 #include "anomaly/AlarmTracker.h"
 #include "condition/ConditionTracker.h"
+#include "config/ConfigMetadataProvider.h"
 #include "external/StatsPullerManager.h"
 #include "matchers/AtomMatchingTracker.h"
 #include "metrics/MetricProducer.h"
@@ -111,8 +112,8 @@
         std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
         std::unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
         std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
-        std::vector<int>& metricsWithActivation,
-        optional<InvalidConfigReason>& invalidConfigReason);
+        std::vector<int>& metricsWithActivation, optional<InvalidConfigReason>& invalidConfigReason,
+        const wp<ConfigMetadataProvider> configMetadataProvider);
 
 // Creates a DurationMetricProducer and updates the vectors/maps used by MetricsManager with
 // the appropriate indices. Returns an sp to the producer, or nullopt if there was an error.
@@ -131,8 +132,8 @@
         std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
         std::unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
         std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
-        std::vector<int>& metricsWithActivation,
-        optional<InvalidConfigReason>& invalidConfigReason);
+        std::vector<int>& metricsWithActivation, optional<InvalidConfigReason>& invalidConfigReason,
+        const wp<ConfigMetadataProvider> configMetadataProvider);
 
 // Creates an EventMetricProducer and updates the vectors/maps used by MetricsManager with
 // the appropriate indices. Returns an sp to the producer, or nullopt if there was an error.
@@ -149,8 +150,8 @@
         std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
         std::unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
         std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
-        std::vector<int>& metricsWithActivation,
-        optional<InvalidConfigReason>& invalidConfigReason);
+        std::vector<int>& metricsWithActivation, optional<InvalidConfigReason>& invalidConfigReason,
+        const wp<ConfigMetadataProvider> configMetadataProvider);
 
 // Creates a NumericValueMetricProducer and updates the vectors/maps used by MetricsManager with
 // the appropriate indices. Returns an sp to the producer, or nullopt if there was an error.
@@ -171,8 +172,8 @@
         std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
         std::unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
         std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
-        std::vector<int>& metricsWithActivation,
-        optional<InvalidConfigReason>& invalidConfigReason);
+        std::vector<int>& metricsWithActivation, optional<InvalidConfigReason>& invalidConfigReason,
+        const wp<ConfigMetadataProvider> configMetadataProvider);
 
 // Creates a GaugeMetricProducer and updates the vectors/maps used by MetricsManager with
 // the appropriate indices. Returns an sp to the producer, or nullopt if there was an error.
@@ -191,8 +192,8 @@
         std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
         std::unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
         std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
-        std::vector<int>& metricsWithActivation,
-        optional<InvalidConfigReason>& invalidConfigReason);
+        std::vector<int>& metricsWithActivation, optional<InvalidConfigReason>& invalidConfigReason,
+        const wp<ConfigMetadataProvider> configMetadataProvider);
 
 // Creates a KllMetricProducer and updates the vectors/maps used by MetricsManager with
 // the appropriate indices. Returns an sp to the producer, or nullopt if there was an error.
@@ -213,7 +214,8 @@
         unordered_map<int, vector<int>>& conditionToMetricMap,
         unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
         unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
-        vector<int>& metricsWithActivation, optional<InvalidConfigReason>& invalidConfigReason);
+        vector<int>& metricsWithActivation, optional<InvalidConfigReason>& invalidConfigReason,
+        const wp<ConfigMetadataProvider> configMetadataProvider);
 
 // Creates an AnomalyTracker and adds it to the appropriate metric.
 // Returns an sp to the AnomalyTracker, or nullopt if there was an error.
@@ -353,7 +355,8 @@
         std::set<int64_t>& noReportMetricIds,
         std::unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
         std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
-        std::vector<int>& metricsWithActivation);
+        std::vector<int>& metricsWithActivation,
+        const wp<ConfigMetadataProvider> configMetadataProvider);
 
 // Initialize alarms
 // Is called both on initialize new configs and config updates since alarms do not have any state.
@@ -368,7 +371,7 @@
         const ConfigKey& key, const StatsdConfig& config, const sp<UidMap>& uidMap,
         const sp<StatsPullerManager>& pullerManager, const sp<AlarmMonitor>& anomalyAlarmMonitor,
         const sp<AlarmMonitor>& periodicAlarmMonitor, int64_t timeBaseNs,
-        const int64_t currentTimeNs,
+        const int64_t currentTimeNs, const wp<ConfigMetadataProvider> configMetadataProvider,
         std::unordered_map<int, std::vector<int>>& allTagIdsToMatchersMap,
         std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
         std::unordered_map<int64_t, int>& atomMatchingTrackerMap,
diff --git a/statsd/src/statsd_config.proto b/statsd/src/statsd_config.proto
index cbd60ee..8d48df0 100644
--- a/statsd/src/statsd_config.proto
+++ b/statsd/src/statsd_config.proto
@@ -642,6 +642,12 @@
 
   optional int32 soft_metrics_memory_kb = 29;
 
+  message StatsdConfigOptions {
+    optional bool use_v2_soft_memory_limit = 1;
+  }
+
+  optional StatsdConfigOptions statsd_config_options = 30;
+
   // Do not use.
   reserved 1000, 1001;
 }
diff --git a/statsd/tests/metrics/CountMetricProducer_test.cpp b/statsd/tests/metrics/CountMetricProducer_test.cpp
index 32c48b0..8db5bce 100644
--- a/statsd/tests/metrics/CountMetricProducer_test.cpp
+++ b/statsd/tests/metrics/CountMetricProducer_test.cpp
@@ -75,8 +75,10 @@
     metric.set_bucket(ONE_MINUTE);
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
 
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
     CountMetricProducer countProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
-                                      wizard, protoHash, 5, 600 * NS_PER_SEC + NS_PER_SEC / 2);
+                                      wizard, protoHash, 5, 600 * NS_PER_SEC + NS_PER_SEC / 2,
+                                      provider);
     EXPECT_EQ(600500000000, countProducer.mCurrentBucketStartTimeNs);
     EXPECT_EQ(10, countProducer.mCurrentBucketNum);
     EXPECT_EQ(660000000005, countProducer.getCurrentBucketEndTimeNs());
@@ -94,9 +96,10 @@
     metric.set_bucket(ONE_MINUTE);
 
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
     CountMetricProducer countProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
-                                      wizard, protoHash, bucketStartTimeNs, bucketStartTimeNs);
+                                      wizard, protoHash, bucketStartTimeNs, bucketStartTimeNs,
+                                      provider);
 
     // 2 events in bucket 1.
     LogEvent event1(/*uid=*/0, /*pid=*/0);
@@ -158,8 +161,9 @@
 
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
 
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
     CountMetricProducer countProducer(kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard,
-                                      protoHash, bucketStartTimeNs, bucketStartTimeNs);
+                                      protoHash, bucketStartTimeNs, bucketStartTimeNs, provider);
     assertConditionTimer(countProducer.mConditionTimer, false, 0, 0);
 
     countProducer.onConditionChanged(true, bucketStartTimeNs);
@@ -229,9 +233,10 @@
 
     EXPECT_CALL(*wizard, query(_, key2, _)).WillOnce(Return(ConditionState::kTrue));
 
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
     CountMetricProducer countProducer(kConfigKey, metric, 0 /*condition tracker index*/,
                                       {ConditionState::kUnknown}, wizard, protoHash,
-                                      bucketStartTimeNs, bucketStartTimeNs);
+                                      bucketStartTimeNs, bucketStartTimeNs, provider);
 
     countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
     countProducer.flushIfNeededLocked(bucketStartTimeNs + 1);
@@ -268,9 +273,9 @@
     alert.set_trigger_if_sum_gt(2);
 
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
     CountMetricProducer countProducer(kConfigKey, metric, -1 /* no condition */, {}, wizard,
-                                      protoHash, bucketStartTimeNs, bucketStartTimeNs);
+                                      protoHash, bucketStartTimeNs, bucketStartTimeNs, provider);
 
     sp<AnomalyTracker> anomalyTracker =
             countProducer.addAnomalyTracker(alert, alarmMonitor, UPDATE_NEW, bucketStartTimeNs);
@@ -337,9 +342,9 @@
     metric.set_split_bucket_for_app_upgrade(true);
 
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
     CountMetricProducer countProducer(kConfigKey, metric, -1 /* no condition */, {}, wizard,
-                                      protoHash, bucketStartTimeNs, bucketStartTimeNs);
+                                      protoHash, bucketStartTimeNs, bucketStartTimeNs, provider);
 
     // Bucket is flushed yet.
     LogEvent event1(/*uid=*/0, /*pid=*/0);
@@ -399,8 +404,9 @@
     alert.set_trigger_if_sum_gt(2);
 
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
     CountMetricProducer countProducer(kConfigKey, metric, -1 /* no condition */, {}, wizard,
-                                      protoHash, bucketStartTimeNs, bucketStartTimeNs);
+                                      protoHash, bucketStartTimeNs, bucketStartTimeNs, provider);
 
     sp<AnomalyTracker> anomalyTracker =
             countProducer.addAnomalyTracker(alert, alarmMonitor, UPDATE_NEW, bucketStartTimeNs);
@@ -467,9 +473,10 @@
     metric.set_bucket(ONE_MINUTE);
 
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
     CountMetricProducer countProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
-                                      wizard, protoHash, bucketStartTimeNs, bucketStartTimeNs);
+                                      wizard, protoHash, bucketStartTimeNs, bucketStartTimeNs,
+                                      provider);
 
     sp<AnomalyTracker> anomalyTracker =
             countProducer.addAnomalyTracker(alert, alarmMonitor, UPDATE_NEW, bucketStartTimeNs);
@@ -531,8 +538,9 @@
     int64_t oneDayNs = 24 * 60 * 60 * 1e9;
     int64_t fiveWeeksNs = 5 * 7 * oneDayNs;
 
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
     CountMetricProducer countProducer(kConfigKey, metric, -1 /* meaning no condition */, {}, wizard,
-                                      protoHash, oneDayNs, fiveWeeksNs);
+                                      protoHash, oneDayNs, fiveWeeksNs, provider);
 
     int64_t fiveWeeksOneDayNs = fiveWeeksNs + oneDayNs;
 
diff --git a/statsd/tests/metrics/DurationMetricProducer_test.cpp b/statsd/tests/metrics/DurationMetricProducer_test.cpp
index 3b24d85..5cf0221 100644
--- a/statsd/tests/metrics/DurationMetricProducer_test.cpp
+++ b/statsd/tests/metrics/DurationMetricProducer_test.cpp
@@ -71,11 +71,12 @@
     metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
 
     FieldMatcher dimensions;
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
 
     DurationMetricProducer durationProducer(
             kConfigKey, metric, -1 /*no condition*/, {}, -1 /*what index not needed*/,
             1 /* start index */, 2 /* stop index */, 3 /* stop_all index */, false /*nesting*/,
-            wizard, protoHash, dimensions, 5, 600 * NS_PER_SEC + NS_PER_SEC / 2);
+            wizard, protoHash, dimensions, 5, 600 * NS_PER_SEC + NS_PER_SEC / 2, provider);
 
     EXPECT_EQ(600500000000, durationProducer.mCurrentBucketStartTimeNs);
     EXPECT_EQ(10, durationProducer.mCurrentBucketNum);
@@ -99,11 +100,12 @@
     makeLogEvent(&event2, bucketStartTimeNs + bucketSizeNs + 2, tagId);
 
     FieldMatcher dimensions;
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
 
     DurationMetricProducer durationProducer(
             kConfigKey, metric, -1 /*no condition*/, {}, -1 /*what index not needed*/,
             1 /* start index */, 2 /* stop index */, 3 /* stop_all index */, false /*nesting*/,
-            wizard, protoHash, dimensions, bucketStartTimeNs, bucketStartTimeNs);
+            wizard, protoHash, dimensions, bucketStartTimeNs, bucketStartTimeNs, provider);
 
     durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
     durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
@@ -142,12 +144,13 @@
     makeLogEvent(&event4, bucketStartTimeNs + bucketSizeNs + 3, tagId);
 
     FieldMatcher dimensions;
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
 
     DurationMetricProducer durationProducer(
             kConfigKey, metric, 0 /* condition index */, {ConditionState::kUnknown},
             -1 /*what index not needed*/, 1 /* start index */, 2 /* stop index */,
             3 /* stop_all index */, false /*nesting*/, wizard, protoHash, dimensions,
-            bucketStartTimeNs, bucketStartTimeNs);
+            bucketStartTimeNs, bucketStartTimeNs, provider);
     durationProducer.mCondition = ConditionState::kFalse;
 
     assertConditionTimer(durationProducer.mConditionTimer, false, 0, 0);
@@ -200,12 +203,13 @@
     makeLogEvent(&event4, bucketStartTimeNs + bucketSizeNs + 3, tagId);
 
     FieldMatcher dimensions;
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
 
     DurationMetricProducer durationProducer(
             kConfigKey, metric, 0 /* condition index */, {ConditionState::kUnknown},
             -1 /*what index not needed*/, 1 /* start index */, 2 /* stop index */,
             3 /* stop_all index */, false /*nesting*/, wizard, protoHash, dimensions,
-            bucketStartTimeNs, bucketStartTimeNs);
+            bucketStartTimeNs, bucketStartTimeNs, provider);
 
     EXPECT_EQ(ConditionState::kUnknown, durationProducer.mCondition);
     EXPECT_FALSE(durationProducer.isConditionSliced());
@@ -248,11 +252,12 @@
     metric.set_split_bucket_for_app_upgrade(true);
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
     FieldMatcher dimensions;
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
 
     DurationMetricProducer durationProducer(
             kConfigKey, metric, -1 /* no condition */, {}, -1 /*what index not needed*/,
             1 /* start index */, 2 /* stop index */, 3 /* stop_all index */, false /*nesting*/,
-            wizard, protoHash, dimensions, bucketStartTimeNs, bucketStartTimeNs);
+            wizard, protoHash, dimensions, bucketStartTimeNs, bucketStartTimeNs, provider);
 
     int64_t startTimeNs = bucketStartTimeNs + 1 * NS_PER_SEC;
     LogEvent event1(/*uid=*/0, /*pid=*/0);
@@ -312,11 +317,12 @@
     metric.set_split_bucket_for_app_upgrade(true);
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
     FieldMatcher dimensions;
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
 
     DurationMetricProducer durationProducer(
             kConfigKey, metric, -1 /* no condition */, {}, -1 /*what index not needed*/,
             1 /* start index */, 2 /* stop index */, 3 /* stop_all index */, false /*nesting*/,
-            wizard, protoHash, dimensions, bucketStartTimeNs, bucketStartTimeNs);
+            wizard, protoHash, dimensions, bucketStartTimeNs, bucketStartTimeNs, provider);
 
     int64_t startTimeNs = bucketStartTimeNs + 1 * NS_PER_SEC;
     LogEvent event1(/*uid=*/0, /*pid=*/0);
@@ -377,11 +383,12 @@
 
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
     FieldMatcher dimensions;
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
 
     DurationMetricProducer durationProducer(
             kConfigKey, metric, -1 /* no condition */, {}, -1 /*what index not needed*/,
             1 /* start index */, 2 /* stop index */, 3 /* stop_all index */, false /*nesting*/,
-            wizard, protoHash, dimensions, bucketStartTimeNs, bucketStartTimeNs);
+            wizard, protoHash, dimensions, bucketStartTimeNs, bucketStartTimeNs, provider);
 
     sp<AnomalyTracker> anomalyTracker =
             durationProducer.addAnomalyTracker(alert, alarmMonitor, UPDATE_NEW, bucketStartTimeNs);
@@ -425,11 +432,12 @@
 
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
     FieldMatcher dimensions;
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
 
     DurationMetricProducer durationProducer(
             kConfigKey, metric, -1 /* no condition */, {}, -1 /*what index not needed*/,
             1 /* start index */, 2 /* stop index */, 3 /* stop_all index */, false /*nesting*/,
-            wizard, protoHash, dimensions, bucketStartTimeNs, bucketStartTimeNs);
+            wizard, protoHash, dimensions, bucketStartTimeNs, bucketStartTimeNs, provider);
 
     int64_t startTimeNs = bucketStartTimeNs + 1;
     LogEvent event1(/*uid=*/0, /*pid=*/0);
@@ -480,11 +488,12 @@
 
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
     FieldMatcher dimensions;
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
 
     DurationMetricProducer durationProducer(
             kConfigKey, metric, -1 /* no condition */, {}, -1 /*what index not needed*/,
             1 /* start index */, 2 /* stop index */, 3 /* stop_all index */, false /*nesting*/,
-            wizard, protoHash, dimensions, bucketStartTimeNs, bucketStartTimeNs);
+            wizard, protoHash, dimensions, bucketStartTimeNs, bucketStartTimeNs, provider);
 
     int64_t startTimeNs = bucketStartTimeNs + 1;
     LogEvent event1(/*uid=*/0, /*pid=*/0);
@@ -542,11 +551,12 @@
     metric.set_split_bucket_for_app_upgrade(false);
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
     FieldMatcher dimensions;
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
 
     DurationMetricProducer durationProducer(
             kConfigKey, metric, -1 /* no condition */, {}, -1 /*what index not needed*/,
             1 /* start index */, 2 /* stop index */, 3 /* stop_all index */, false /*nesting*/,
-            wizard, protoHash, dimensions, bucketStartTimeNs, bucketStartTimeNs);
+            wizard, protoHash, dimensions, bucketStartTimeNs, bucketStartTimeNs, provider);
 
     int64_t startTimeNs = bucketStartTimeNs + 1 * NS_PER_SEC;
     LogEvent event1(/*uid=*/0, /*pid=*/0);
@@ -585,6 +595,7 @@
     metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
     FieldMatcher dimensions;
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
 
     LogEvent event1(/*uid=*/0, /*pid=*/0);
     makeLogEvent(&event1, bucketStartTimeNs + 50, tagId);
@@ -599,7 +610,7 @@
             kConfigKey, metric, 0 /* condition index */, {ConditionState::kUnknown},
             -1 /*what index not needed*/, 1 /* start index */, 2 /* stop index */,
             3 /* stop_all index */, false /*nesting*/, wizard, protoHash, dimensions,
-            bucketStartTimeNs, bucketStartTimeNs);
+            bucketStartTimeNs, bucketStartTimeNs, provider);
 
     durationProducer.onConditionChanged(true /* condition */, bucketStartTimeNs + 5);
     durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
diff --git a/statsd/tests/metrics/EventMetricProducer_test.cpp b/statsd/tests/metrics/EventMetricProducer_test.cpp
index d5fe932..6e25f79 100644
--- a/statsd/tests/metrics/EventMetricProducer_test.cpp
+++ b/statsd/tests/metrics/EventMetricProducer_test.cpp
@@ -80,9 +80,10 @@
     CreateNoValuesLogEvent(&event2, 1 /*tagId*/, bucketStartTimeNs + 2);
 
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
 
     EventMetricProducer eventProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
-                                      wizard, protoHash, bucketStartTimeNs);
+                                      wizard, protoHash, bucketStartTimeNs, provider);
 
     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event2);
@@ -117,10 +118,11 @@
     CreateNoValuesLogEvent(&event2, 1 /*tagId*/, bucketStartTimeNs + 10);
 
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
 
     EventMetricProducer eventProducer(kConfigKey, metric, 0 /*condition index*/,
                                       {ConditionState::kUnknown}, wizard, protoHash,
-                                      bucketStartTimeNs);
+                                      bucketStartTimeNs, provider);
 
     eventProducer.onConditionChanged(true /*condition*/, bucketStartTimeNs);
     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
@@ -174,10 +176,11 @@
     EXPECT_CALL(*wizard, query(_, key1, _)).WillOnce(Return(ConditionState::kFalse));
     // Condition is true for second event.
     EXPECT_CALL(*wizard, query(_, key2, _)).WillOnce(Return(ConditionState::kTrue));
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
 
     EventMetricProducer eventProducer(kConfigKey, metric, 0 /*condition index*/,
                                       {ConditionState::kUnknown}, wizard, protoHash,
-                                      bucketStartTimeNs);
+                                      bucketStartTimeNs, provider);
 
     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event2);
@@ -213,8 +216,9 @@
     makeLogEvent(&event4, tagId, bucketStartTimeNs + 40, "222");
 
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
     EventMetricProducer eventProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
-                                      wizard, protoHash, bucketStartTimeNs);
+                                      wizard, protoHash, bucketStartTimeNs, provider);
 
     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event2);
@@ -265,8 +269,9 @@
     makeLogEvent(&event4, tagId, bucketStartTimeNs + 40, "111", &bytesField2);
 
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
     EventMetricProducer eventProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
-                                      wizard, protoHash, bucketStartTimeNs);
+                                      wizard, protoHash, bucketStartTimeNs, provider);
 
     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event2);
@@ -314,8 +319,9 @@
     makeLogEvent(&event3, tagId2, bucketStartTimeNs + 40, "222");
 
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
     EventMetricProducer eventProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
-                                      wizard, protoHash, bucketStartTimeNs);
+                                      wizard, protoHash, bucketStartTimeNs, provider);
 
     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event2);
@@ -343,6 +349,7 @@
         }
     }
 }
+
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
diff --git a/statsd/tests/metrics/GaugeMetricProducer_test.cpp b/statsd/tests/metrics/GaugeMetricProducer_test.cpp
index aa8af8f..ff3d8d1 100644
--- a/statsd/tests/metrics/GaugeMetricProducer_test.cpp
+++ b/statsd/tests/metrics/GaugeMetricProducer_test.cpp
@@ -98,13 +98,14 @@
             createEventMatcherWizard(tagId, logEventMatcherIndex);
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
 
     // statsd started long ago.
     // The metric starts in the middle of the bucket
     GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
                                       wizard, protoHash, logEventMatcherIndex, eventMatcherWizard,
                                       -1, -1, tagId, 5, 600 * NS_PER_SEC + NS_PER_SEC / 2,
-                                      pullerManager);
+                                      pullerManager, provider);
     gaugeProducer.prepareFirstBucket();
 
     EXPECT_EQ(600500000000, gaugeProducer.mCurrentBucketStartTimeNs);
@@ -140,10 +141,12 @@
                 return true;
             }));
 
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
+
     GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
                                       wizard, protoHash, logEventMatcherIndex, eventMatcherWizard,
                                       tagId, -1, tagId, bucketStartTimeNs, bucketStartTimeNs,
-                                      pullerManager);
+                                      pullerManager, provider);
     gaugeProducer.prepareFirstBucket();
 
     vector<shared_ptr<LogEvent>> allData;
@@ -228,10 +231,12 @@
     sp<EventMatcherWizard> eventMatcherWizard =
             createEventMatcherWizard(tagId, logEventMatcherIndex);
 
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
+
     GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
                                       wizard, protoHash, logEventMatcherIndex, eventMatcherWizard,
                                       -1 /* -1 means no pulling */, -1, tagId, bucketStartTimeNs,
-                                      bucketStartTimeNs, pullerManager);
+                                      bucketStartTimeNs, pullerManager, provider);
     gaugeProducer.prepareFirstBucket();
 
     sp<AnomalyTracker> anomalyTracker =
@@ -310,6 +315,8 @@
     sp<EventMatcherWizard> eventMatcherWizard =
             createEventMatcherWizard(tagId, logEventMatcherIndex);
 
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
+
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
     EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
     EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
@@ -326,7 +333,7 @@
     GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
                                       wizard, protoHash, logEventMatcherIndex, eventMatcherWizard,
                                       tagId, -1, tagId, bucketStartTimeNs, bucketStartTimeNs,
-                                      pullerManager);
+                                      pullerManager, provider);
     gaugeProducer.prepareFirstBucket();
 
     vector<shared_ptr<LogEvent>> allData;
@@ -392,10 +399,12 @@
     EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
             .WillOnce(Return(false));
 
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
+
     GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
                                       wizard, protoHash, logEventMatcherIndex, eventMatcherWizard,
                                       tagId, -1, tagId, bucketStartTimeNs, bucketStartTimeNs,
-                                      pullerManager);
+                                      pullerManager, provider);
     gaugeProducer.prepareFirstBucket();
 
     vector<shared_ptr<LogEvent>> allData;
@@ -446,10 +455,12 @@
                 return true;
             }));
 
-    GaugeMetricProducer gaugeProducer(kConfigKey, metric, 0 /*condition index*/,
-                                      {ConditionState::kUnknown}, wizard, protoHash,
-                                      logEventMatcherIndex, eventMatcherWizard, tagId, -1, tagId,
-                                      bucketStartTimeNs, bucketStartTimeNs, pullerManager);
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
+
+    GaugeMetricProducer gaugeProducer(
+            kConfigKey, metric, 0 /*condition index*/, {ConditionState::kUnknown}, wizard,
+            protoHash, logEventMatcherIndex, eventMatcherWizard, tagId, -1, tagId,
+            bucketStartTimeNs, bucketStartTimeNs, pullerManager, provider);
     gaugeProducer.prepareFirstBucket();
 
     gaugeProducer.onConditionChanged(true, conditionChangeNs);
@@ -534,10 +545,12 @@
                 return true;
             }));
 
-    GaugeMetricProducer gaugeProducer(kConfigKey, metric, 0 /*condition index*/,
-                                      {ConditionState::kUnknown}, wizard, protoHash,
-                                      logEventMatcherIndex, eventMatcherWizard, tagId, -1, tagId,
-                                      bucketStartTimeNs, bucketStartTimeNs, pullerManager);
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
+
+    GaugeMetricProducer gaugeProducer(
+            kConfigKey, metric, 0 /*condition index*/, {ConditionState::kUnknown}, wizard,
+            protoHash, logEventMatcherIndex, eventMatcherWizard, tagId, -1, tagId,
+            bucketStartTimeNs, bucketStartTimeNs, pullerManager, provider);
     gaugeProducer.prepareFirstBucket();
 
     gaugeProducer.onSlicedConditionMayChange(true, sliceConditionChangeNs);
@@ -579,10 +592,12 @@
     sp<EventMatcherWizard> eventMatcherWizard =
             createEventMatcherWizard(tagId, logEventMatcherIndex);
 
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
+
     GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
                                       wizard, protoHash, logEventMatcherIndex, eventMatcherWizard,
                                       tagId, -1, tagId, bucketStartTimeNs, bucketStartTimeNs,
-                                      pullerManager);
+                                      pullerManager, provider);
     gaugeProducer.prepareFirstBucket();
 
     Alert alert;
@@ -679,10 +694,12 @@
             .WillOnce(Return(true));
 
     int triggerId = 5;
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
+
     GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
                                       wizard, protoHash, logEventMatcherIndex, eventMatcherWizard,
                                       tagId, triggerId, tagId, bucketStartTimeNs, bucketStartTimeNs,
-                                      pullerManager);
+                                      pullerManager, provider);
     gaugeProducer.prepareFirstBucket();
 
     ASSERT_EQ(0UL, gaugeProducer.mCurrentSlicedBucket->size());
@@ -737,10 +754,12 @@
                 return true;
             }));
 
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
+
     GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
                                       wizard, protoHash, logEventMatcherIndex, eventMatcherWizard,
                                       tagId, /*triggerId=*/-1, tagId, bucketStartTimeNs,
-                                      bucketStartTimeNs, pullerManager);
+                                      bucketStartTimeNs, pullerManager, provider);
 
     EXPECT_EQ(0UL, gaugeProducer.mCurrentSlicedBucket->size());
     gaugeProducer.prepareFirstBucket();
@@ -808,10 +827,12 @@
             .WillOnce(Return(true));
 
     int triggerId = 5;
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
+
     GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
                                       wizard, protoHash, logEventMatcherIndex, eventMatcherWizard,
                                       tagId, triggerId, tagId, bucketStartTimeNs, bucketStartTimeNs,
-                                      pullerManager);
+                                      pullerManager, provider);
     gaugeProducer.prepareFirstBucket();
 
     LogEvent triggerEvent(/*uid=*/0, /*pid=*/0);
@@ -878,10 +899,12 @@
             }));
 
     int triggerId = 5;
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
+
     GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
                                       wizard, protoHash, logEventMatcherIndex, eventMatcherWizard,
                                       tagId, triggerId, tagId, bucketStartTimeNs, bucketStartTimeNs,
-                                      pullerManager);
+                                      pullerManager, provider);
     gaugeProducer.prepareFirstBucket();
 
     LogEvent triggerEvent(/*uid=*/0, /*pid=*/0);
@@ -950,11 +973,11 @@
                 data->push_back(makeUidLogEvent(tagId, bucketStartTimeNs + 20, 1003, 18, 10));
                 return true;
             }));
-
-    GaugeMetricProducer gaugeProducer(kConfigKey, sampledGaugeMetric,
-                                      -1 /*-1 meaning no condition*/, {}, wizard, protoHash,
-                                      logEventMatcherIndex, eventMatcherWizard, tagId, triggerId,
-                                      tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
+    GaugeMetricProducer gaugeProducer(
+            kConfigKey, sampledGaugeMetric, -1 /*-1 meaning no condition*/, {}, wizard, protoHash,
+            logEventMatcherIndex, eventMatcherWizard, tagId, triggerId, tagId, bucketStartTimeNs,
+            bucketStartTimeNs, pullerManager, provider);
     SamplingInfo samplingInfo;
     samplingInfo.shardCount = shardCount;
     translateFieldMatcher(sampledGaugeMetric.dimensional_sampling_info().sampled_what_field(),
diff --git a/statsd/tests/metrics/KllMetricProducer_test.cpp b/statsd/tests/metrics/KllMetricProducer_test.cpp
index 0e2d4c2..58d8a73 100644
--- a/statsd/tests/metrics/KllMetricProducer_test.cpp
+++ b/statsd/tests/metrics/KllMetricProducer_test.cpp
@@ -137,6 +137,7 @@
             initialConditionCache.push_back(initialCondition.value());
         }
 
+        sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
         return new KllMetricProducer(
                 kConfigKey, metric, protoHash, {/*pullAtomId=*/-1, /*pullerManager=*/nullptr},
                 {timeBaseNs, startTimeNs, bucketSizeNs, metric.min_bucket_size_nanos(),
@@ -147,7 +148,7 @@
                 {conditionIndex, metric.links(), initialConditionCache, wizard},
                 {metric.state_link(), slicedStateAtoms, stateGroupMap},
                 {/*eventActivationMap=*/{}, /*eventDeactivationMap=*/{}},
-                {dimensionSoftLimit, dimensionHardLimit});
+                {dimensionSoftLimit, dimensionHardLimit}, provider);
     }
 
     static KllMetric createMetric() {
diff --git a/statsd/tests/metrics/NumericValueMetricProducer_test.cpp b/statsd/tests/metrics/NumericValueMetricProducer_test.cpp
index 356eab9..972dc85 100644
--- a/statsd/tests/metrics/NumericValueMetricProducer_test.cpp
+++ b/statsd/tests/metrics/NumericValueMetricProducer_test.cpp
@@ -224,6 +224,7 @@
             aggregationTypes.push_back(metric.aggregation_type());
         }
 
+        sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
         sp<NumericValueMetricProducer> valueProducer = new NumericValueMetricProducer(
                 kConfigKey, metric, protoHash, {pullAtomId, pullerManager},
                 {timeBaseNs, startTimeNs, bucketSizeNs, metric.min_bucket_size_nanos(),
@@ -234,7 +235,7 @@
                 {conditionIndex, metric.links(), initialConditionCache, wizard},
                 {metric.state_link(), slicedStateAtoms, stateGroupMap},
                 {/*eventActivationMap=*/{}, /*eventDeactivationMap=*/{}},
-                {dimensionSoftLimit, dimensionHardLimit});
+                {dimensionSoftLimit, dimensionHardLimit}, provider);
 
         valueProducer->prepareFirstBucket();
         if (conditionAfterFirstBucketPrepared) {
diff --git a/statsd/tests/metrics/RestrictedEventMetricProducer_test.cpp b/statsd/tests/metrics/RestrictedEventMetricProducer_test.cpp
index 44b812f..2085e11 100644
--- a/statsd/tests/metrics/RestrictedEventMetricProducer_test.cpp
+++ b/statsd/tests/metrics/RestrictedEventMetricProducer_test.cpp
@@ -54,11 +54,12 @@
 TEST_F(RestrictedEventMetricProducerTest, TestOnMatchedLogEventMultipleEvents) {
     EventMetric metric;
     metric.set_id(metricId1);
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
     RestrictedEventMetricProducer producer(configKey, metric,
                                            /*conditionIndex=*/-1,
                                            /*initialConditionCache=*/{}, new ConditionWizard(),
                                            /*protoHash=*/0x1234567890,
-                                           /*startTimeNs=*/0);
+                                           /*startTimeNs=*/0, provider);
     std::unique_ptr<LogEvent> event1 = CreateRestrictedLogEvent(/*atomTag=*/123, /*timestampNs=*/1);
     std::unique_ptr<LogEvent> event2 = CreateRestrictedLogEvent(/*atomTag=*/123, /*timestampNs=*/3);
 
@@ -87,11 +88,12 @@
 TEST_F(RestrictedEventMetricProducerTest, TestOnMatchedLogEventMultipleFields) {
     EventMetric metric;
     metric.set_id(metricId2);
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
     RestrictedEventMetricProducer producer(configKey, metric,
                                            /*conditionIndex=*/-1,
                                            /*initialConditionCache=*/{}, new ConditionWizard(),
                                            /*protoHash=*/0x1234567890,
-                                           /*startTimeNs=*/0);
+                                           /*startTimeNs=*/0, provider);
     AStatsEvent* statsEvent = AStatsEvent_obtain();
     AStatsEvent_setAtomId(statsEvent, 1);
     AStatsEvent_addInt32Annotation(statsEvent, ASTATSLOG_ANNOTATION_ID_RESTRICTION_CATEGORY,
@@ -129,12 +131,13 @@
     EventMetric metric;
     metric.set_id(metricId1);
     metric.set_condition(StringToId("SCREEN_ON"));
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
     RestrictedEventMetricProducer producer(configKey, metric,
                                            /*conditionIndex=*/0,
                                            /*initialConditionCache=*/{ConditionState::kUnknown},
                                            new ConditionWizard(),
                                            /*protoHash=*/0x1234567890,
-                                           /*startTimeNs=*/0);
+                                           /*startTimeNs=*/0, provider);
     std::unique_ptr<LogEvent> event1 = CreateRestrictedLogEvent(/*atomTag=*/123, /*timestampNs=*/1);
     std::unique_ptr<LogEvent> event2 = CreateRestrictedLogEvent(/*atomTag=*/123, /*timestampNs=*/3);
 
@@ -162,11 +165,12 @@
 TEST_F(RestrictedEventMetricProducerTest, TestOnDumpReportNoOp) {
     EventMetric metric;
     metric.set_id(metricId1);
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
     RestrictedEventMetricProducer producer(configKey, metric,
                                            /*conditionIndex=*/-1,
                                            /*initialConditionCache=*/{}, new ConditionWizard(),
                                            /*protoHash=*/0x1234567890,
-                                           /*startTimeNs=*/0);
+                                           /*startTimeNs=*/0, provider);
     std::unique_ptr<LogEvent> event1 = CreateRestrictedLogEvent(/*timestampNs=*/1);
     producer.onMatchedLogEvent(/*matcherIndex=*/1, *event1);
     ProtoOutputStream output;
@@ -182,11 +186,12 @@
 TEST_F(RestrictedEventMetricProducerTest, TestOnMetricRemove) {
     EventMetric metric;
     metric.set_id(metricId1);
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
     RestrictedEventMetricProducer producer(configKey, metric,
                                            /*conditionIndex=*/-1,
                                            /*initialConditionCache=*/{}, new ConditionWizard(),
                                            /*protoHash=*/0x1234567890,
-                                           /*startTimeNs=*/0);
+                                           /*startTimeNs=*/0, provider);
     EXPECT_FALSE(metricTableExist(metricId1));
 
     std::unique_ptr<LogEvent> event1 = CreateRestrictedLogEvent(/*timestampNs=*/1);
@@ -201,11 +206,12 @@
 TEST_F(RestrictedEventMetricProducerTest, TestRestrictedEventMetricTtlDeletesFirstEvent) {
     EventMetric metric;
     metric.set_id(metricId1);
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
     RestrictedEventMetricProducer producer(configKey, metric,
                                            /*conditionIndex=*/-1,
                                            /*initialConditionCache=*/{}, new ConditionWizard(),
                                            /*protoHash=*/0x1234567890,
-                                           /*startTimeNs=*/0);
+                                           /*startTimeNs=*/0, provider);
 
     int64_t currentTimeNs = getWallClockNs();
     int64_t eightDaysAgo = currentTimeNs - 8 * 24 * 3600 * NS_PER_SEC;
@@ -243,11 +249,12 @@
     metricMetadata.set_restricted_category(1);  // CATEGORY_DIAGNOSTIC
     EventMetric metric;
     metric.set_id(metricId1);
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
     RestrictedEventMetricProducer producer(configKey, metric,
                                            /*conditionIndex=*/-1,
                                            /*initialConditionCache=*/{}, new ConditionWizard(),
                                            /*protoHash=*/0x1234567890,
-                                           /*startTimeNs=*/0);
+                                           /*startTimeNs=*/0, provider);
 
     producer.loadMetricMetadataFromProto(metricMetadata);
 
diff --git a/statsd/tests/metrics/parsing_utils/config_update_utils_test.cpp b/statsd/tests/metrics/parsing_utils/config_update_utils_test.cpp
index b32d5d3..0861812 100644
--- a/statsd/tests/metrics/parsing_utils/config_update_utils_test.cpp
+++ b/statsd/tests/metrics/parsing_utils/config_update_utils_test.cpp
@@ -64,6 +64,7 @@
         /*minDiffToUpdateRegisteredAlarmTimeSec=*/0,
         [](const shared_ptr<IStatsCompanionService>&, int64_t) {},
         [](const shared_ptr<IStatsCompanionService>&) {});
+sp<ConfigMetadataProvider> configMetadataProvider;
 unordered_map<int, vector<int>> allTagIdsToMatchersMap;
 vector<sp<AtomMatchingTracker>> oldAtomMatchingTrackers;
 unordered_map<int64_t, int> oldAtomMatchingTrackerMap;
@@ -87,10 +88,11 @@
     // initStatsdConfig returns nullopt if config is valid
     return !initStatsdConfig(
                     key, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
-                    timeBaseNs, timeBaseNs, allTagIdsToMatchersMap, oldAtomMatchingTrackers,
-                    oldAtomMatchingTrackerMap, oldConditionTrackers, oldConditionTrackerMap,
-                    oldMetricProducers, oldMetricProducerMap, oldAnomalyTrackers, oldAlarmTrackers,
-                    tmpConditionToMetricMap, tmpTrackerToMetricMap, tmpTrackerToConditionMap,
+                    timeBaseNs, timeBaseNs, configMetadataProvider, allTagIdsToMatchersMap,
+                    oldAtomMatchingTrackers, oldAtomMatchingTrackerMap, oldConditionTrackers,
+                    oldConditionTrackerMap, oldMetricProducers, oldMetricProducerMap,
+                    oldAnomalyTrackers, oldAlarmTrackers, tmpConditionToMetricMap,
+                    tmpTrackerToMetricMap, tmpTrackerToConditionMap,
                     tmpActivationAtomTrackerToMetricMap, tmpDeactivationAtomTrackerToMetricMap,
                     oldAlertTrackerMap, metricsWithActivation, oldStateHashes, noReportMetricIds)
                     .has_value();
@@ -1974,16 +1976,17 @@
     unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
     vector<int> metricsWithActivation;
     set<int64_t> replacedMetrics;
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
     EXPECT_EQ(updateMetrics(key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345,
                             new StatsPullerManager(), oldAtomMatchingTrackerMap,
                             newAtomMatchingTrackerMap, replacedMatchers, newAtomMatchingTrackers,
                             newConditionTrackerMap, replacedConditions, newConditionTrackers,
                             conditionCache, /*stateAtomIdMap=*/{}, /*allStateGroupMaps=*/{},
                             /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers,
-                            newMetricProducerMap, newMetricProducers, conditionToMetricMap,
-                            trackerToMetricMap, noReportMetricIds, activationAtomTrackerToMetricMap,
-                            deactivationAtomTrackerToMetricMap, metricsWithActivation,
-                            replacedMetrics),
+                            provider, newMetricProducerMap, newMetricProducers,
+                            conditionToMetricMap, trackerToMetricMap, noReportMetricIds,
+                            activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
+                            metricsWithActivation, replacedMetrics),
               nullopt);
 
     unordered_map<int64_t, int> expectedMetricProducerMap = {
@@ -2207,14 +2210,15 @@
     unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
     vector<int> metricsWithActivation;
     set<int64_t> replacedMetrics;
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
     EXPECT_EQ(updateMetrics(key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345,
                             new StatsPullerManager(), oldAtomMatchingTrackerMap,
                             newAtomMatchingTrackerMap, replacedMatchers, newAtomMatchingTrackers,
                             newConditionTrackerMap, /*replacedConditions=*/{}, newConditionTrackers,
                             conditionCache, stateAtomIdMap, allStateGroupMaps, replacedStates,
-                            oldMetricProducerMap, oldMetricProducers, newMetricProducerMap,
-                            newMetricProducers, conditionToMetricMap, trackerToMetricMap,
-                            noReportMetricIds, activationAtomTrackerToMetricMap,
+                            oldMetricProducerMap, oldMetricProducers, provider,
+                            newMetricProducerMap, newMetricProducers, conditionToMetricMap,
+                            trackerToMetricMap, noReportMetricIds, activationAtomTrackerToMetricMap,
                             deactivationAtomTrackerToMetricMap, metricsWithActivation,
                             replacedMetrics),
               nullopt);
@@ -2420,16 +2424,17 @@
     unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
     vector<int> metricsWithActivation;
     set<int64_t> replacedMetrics;
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
     EXPECT_EQ(updateMetrics(key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345,
                             new StatsPullerManager(), oldAtomMatchingTrackerMap,
                             newAtomMatchingTrackerMap, replacedMatchers, newAtomMatchingTrackers,
                             newConditionTrackerMap, /*replacedConditions=*/{}, newConditionTrackers,
                             conditionCache, /*stateAtomIdMap=*/{}, /*allStateGroupMaps=*/{},
                             /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers,
-                            newMetricProducerMap, newMetricProducers, conditionToMetricMap,
-                            trackerToMetricMap, noReportMetricIds, activationAtomTrackerToMetricMap,
-                            deactivationAtomTrackerToMetricMap, metricsWithActivation,
-                            replacedMetrics),
+                            provider, newMetricProducerMap, newMetricProducers,
+                            conditionToMetricMap, trackerToMetricMap, noReportMetricIds,
+                            activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
+                            metricsWithActivation, replacedMetrics),
               nullopt);
 
     unordered_map<int64_t, int> expectedMetricProducerMap = {
@@ -2743,12 +2748,13 @@
     unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
     vector<int> metricsWithActivation;
     set<int64_t> replacedMetrics;
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
     EXPECT_EQ(updateMetrics(key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345,
                             new StatsPullerManager(), oldAtomMatchingTrackerMap,
                             newAtomMatchingTrackerMap, /*replacedMatchers=*/{},
                             newAtomMatchingTrackers, newConditionTrackerMap, replacedConditions,
                             newConditionTrackers, conditionCache, stateAtomIdMap, allStateGroupMaps,
-                            replacedStates, oldMetricProducerMap, oldMetricProducers,
+                            replacedStates, oldMetricProducerMap, oldMetricProducers, provider,
                             newMetricProducerMap, newMetricProducers, conditionToMetricMap,
                             trackerToMetricMap, noReportMetricIds, activationAtomTrackerToMetricMap,
                             deactivationAtomTrackerToMetricMap, metricsWithActivation,
@@ -3011,12 +3017,13 @@
     unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
     vector<int> metricsWithActivation;
     set<int64_t> replacedMetrics;
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
     EXPECT_EQ(updateMetrics(key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345,
                             new StatsPullerManager(), oldAtomMatchingTrackerMap,
                             newAtomMatchingTrackerMap, /*replacedMatchers=*/{},
                             newAtomMatchingTrackers, newConditionTrackerMap, replacedConditions,
                             newConditionTrackers, conditionCache, stateAtomIdMap, allStateGroupMaps,
-                            replacedStates, oldMetricProducerMap, oldMetricProducers,
+                            replacedStates, oldMetricProducerMap, oldMetricProducers, provider,
                             newMetricProducerMap, newMetricProducers, conditionToMetricMap,
                             trackerToMetricMap, noReportMetricIds, activationAtomTrackerToMetricMap,
                             deactivationAtomTrackerToMetricMap, metricsWithActivation,
@@ -3228,13 +3235,14 @@
     unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
     vector<int> metricsWithActivation;
     set<int64_t> replacedMetrics;
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
     EXPECT_EQ(updateMetrics(
                       key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345,
                       new StatsPullerManager(), oldAtomMatchingTrackerMap,
                       newAtomMatchingTrackerMap, /*replacedMatchers=*/{}, newAtomMatchingTrackers,
                       newConditionTrackerMap, replacedConditions, newConditionTrackers,
                       conditionCache, /*stateAtomIdMap=*/{}, /*allStateGroupMaps=*/{},
-                      /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers,
+                      /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers, provider,
                       newMetricProducerMap, newMetricProducers, conditionToMetricMap,
                       trackerToMetricMap, noReportMetricIds, activationAtomTrackerToMetricMap,
                       deactivationAtomTrackerToMetricMap, metricsWithActivation, replacedMetrics),
@@ -3401,16 +3409,17 @@
     unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
     vector<int> metricsWithActivation;
     set<int64_t> replacedMetrics;
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
     EXPECT_EQ(updateMetrics(key, config, /*timeBaseNs=*/123, /*currentTimeNs=*/12345,
                             new StatsPullerManager(), oldAtomMatchingTrackerMap,
                             newAtomMatchingTrackerMap, replacedMatchers, newAtomMatchingTrackers,
                             newConditionTrackerMap, replacedConditions, newConditionTrackers,
                             conditionCache, /*stateAtomIdMap=*/{}, /*allStateGroupMaps=*/{},
                             /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers,
-                            newMetricProducerMap, newMetricProducers, conditionToMetricMap,
-                            trackerToMetricMap, noReportMetricIds, activationAtomTrackerToMetricMap,
-                            deactivationAtomTrackerToMetricMap, metricsWithActivation,
-                            replacedMetrics),
+                            provider, newMetricProducerMap, newMetricProducers,
+                            conditionToMetricMap, trackerToMetricMap, noReportMetricIds,
+                            activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
+                            metricsWithActivation, replacedMetrics),
               nullopt);
 
     // Verify event activation/deactivation maps.
@@ -3563,16 +3572,17 @@
     unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
     vector<int> metricsWithActivation;
     set<int64_t> replacedMetrics;
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
     EXPECT_EQ(updateMetrics(key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345,
                             new StatsPullerManager(), oldAtomMatchingTrackerMap,
                             newAtomMatchingTrackerMap, replacedMatchers, newAtomMatchingTrackers,
                             newConditionTrackerMap, /*replacedConditions=*/{}, newConditionTrackers,
                             conditionCache, /*stateAtomIdMap*/ {}, /*allStateGroupMaps=*/{},
                             /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers,
-                            newMetricProducerMap, newMetricProducers, conditionToMetricMap,
-                            trackerToMetricMap, noReportMetricIds, activationAtomTrackerToMetricMap,
-                            deactivationAtomTrackerToMetricMap, metricsWithActivation,
-                            replacedMetrics),
+                            provider, newMetricProducerMap, newMetricProducers,
+                            conditionToMetricMap, trackerToMetricMap, noReportMetricIds,
+                            activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
+                            metricsWithActivation, replacedMetrics),
               nullopt);
 
     unordered_map<int64_t, int> expectedMetricProducerMap = {
@@ -3794,13 +3804,14 @@
     vector<int> metricsWithActivation;
     set<int64_t> replacedMetrics;
     int64_t currentTimeNs = 12345;
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
     EXPECT_EQ(updateMetrics(
                       key, config, /*timeBaseNs=*/123, currentTimeNs, new StatsPullerManager(),
                       oldAtomMatchingTrackerMap, oldAtomMatchingTrackerMap, /*replacedMatchers*/ {},
                       oldAtomMatchingTrackers, oldConditionTrackerMap, /*replacedConditions=*/{},
                       oldConditionTrackers, {ConditionState::kUnknown}, /*stateAtomIdMap*/ {},
                       /*allStateGroupMaps=*/{},
-                      /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers,
+                      /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers, provider,
                       newMetricProducerMap, newMetricProducers, conditionToMetricMap,
                       trackerToMetricMap, noReportMetricIds, activationAtomTrackerToMetricMap,
                       deactivationAtomTrackerToMetricMap, metricsWithActivation, replacedMetrics),
@@ -3983,14 +3994,15 @@
     set<int64_t> replacedMatchers;
     set<int64_t> replacedConditions;
     set<int64_t> replacedStates;
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
     EXPECT_EQ(updateMetrics(key, config, /*timeBaseNs=*/123, /*currentTimeNs=*/12345,
                             new StatsPullerManager(), oldAtomMatchingTrackerMap,
                             newAtomMatchingTrackerMap, replacedMatchers, newAtomMatchingTrackers,
                             newConditionTrackerMap, replacedConditions, newConditionTrackers,
                             conditionCache, stateAtomIdMap, allStateGroupMaps, replacedStates,
-                            oldMetricProducerMap, oldMetricProducers, newMetricProducerMap,
-                            newMetricProducers, conditionToMetricMap, trackerToMetricMap,
-                            noReportMetricIds, activationAtomTrackerToMetricMap,
+                            oldMetricProducerMap, oldMetricProducers, provider,
+                            newMetricProducerMap, newMetricProducers, conditionToMetricMap,
+                            trackerToMetricMap, noReportMetricIds, activationAtomTrackerToMetricMap,
                             deactivationAtomTrackerToMetricMap, metricsWithActivation,
                             replacedMetrics),
               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_HAS_MULTIPLE_ACTIVATIONS, metricId));
@@ -4020,14 +4032,15 @@
     set<int64_t> replacedMatchers;
     set<int64_t> replacedConditions;
     set<int64_t> replacedStates;
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
     EXPECT_EQ(updateMetrics(key, config, /*timeBaseNs=*/123, /*currentTimeNs=*/12345,
                             new StatsPullerManager(), oldAtomMatchingTrackerMap,
                             newAtomMatchingTrackerMap, replacedMatchers, newAtomMatchingTrackers,
                             newConditionTrackerMap, replacedConditions, newConditionTrackers,
                             conditionCache, stateAtomIdMap, allStateGroupMaps, replacedStates,
-                            oldMetricProducerMap, oldMetricProducers, newMetricProducerMap,
-                            newMetricProducers, conditionToMetricMap, trackerToMetricMap,
-                            noReportMetricIds, activationAtomTrackerToMetricMap,
+                            oldMetricProducerMap, oldMetricProducers, provider,
+                            newMetricProducerMap, newMetricProducers, conditionToMetricMap,
+                            trackerToMetricMap, noReportMetricIds, activationAtomTrackerToMetricMap,
                             deactivationAtomTrackerToMetricMap, metricsWithActivation,
                             replacedMetrics),
               InvalidConfigReason(INVALID_CONFIG_REASON_NO_REPORT_METRIC_NOT_FOUND, metricId));
@@ -4064,6 +4077,7 @@
     set<int64_t> replacedMatchers;
     set<int64_t> replacedConditions;
     set<int64_t> replacedStates;
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
 
     newAtomMatchingTrackerMap[StringToId("ScreenTurnedOn")] = 0;
     stateAtomIdMap[StringToId("ScreenState")] = util::SCREEN_STATE_CHANGED;
@@ -4074,7 +4088,7 @@
                     replacedMatchers, newAtomMatchingTrackers, newConditionTrackerMap,
                     replacedConditions, newConditionTrackers, conditionCache, stateAtomIdMap,
                     allStateGroupMaps, replacedStates, oldMetricProducerMap, oldMetricProducers,
-                    newMetricProducerMap, newMetricProducers, conditionToMetricMap,
+                    provider, newMetricProducerMap, newMetricProducers, conditionToMetricMap,
                     trackerToMetricMap, noReportMetricIds, activationAtomTrackerToMetricMap,
                     deactivationAtomTrackerToMetricMap, metricsWithActivation, replacedMetrics),
             InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_SLICED_STATE_ATOM_ALLOWED_FROM_ANY_UID,
@@ -4145,15 +4159,16 @@
     set<int64_t> replacedMatchers;
     set<int64_t> replacedConditions;
     set<int64_t> replacedStates;
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
 
     EXPECT_EQ(updateMetrics(key, config, /*timeBaseNs=*/123, /*currentTimeNs=*/12345,
                             new StatsPullerManager(), oldAtomMatchingTrackerMap,
                             newAtomMatchingTrackerMap, replacedMatchers, newAtomMatchingTrackers,
                             newConditionTrackerMap, replacedConditions, newConditionTrackers,
                             conditionCache, stateAtomIdMap, allStateGroupMaps, replacedStates,
-                            oldMetricProducerMap, oldMetricProducers, newMetricProducerMap,
-                            newMetricProducers, conditionToMetricMap, trackerToMetricMap,
-                            noReportMetricIds, activationAtomTrackerToMetricMap,
+                            oldMetricProducerMap, oldMetricProducers, provider,
+                            newMetricProducerMap, newMetricProducers, conditionToMetricMap,
+                            trackerToMetricMap, noReportMetricIds, activationAtomTrackerToMetricMap,
                             deactivationAtomTrackerToMetricMap, metricsWithActivation,
                             replacedMetrics),
               InvalidConfigReason(INVALID_CONFIG_REASON_RESTRICTED_METRIC_NOT_SUPPORTED));
@@ -4196,13 +4211,14 @@
     vector<int> metricsWithActivation;
     vector<sp<MetricProducer>> newMetricProducers;
     set<int64_t> replacedMetrics;
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
     EXPECT_EQ(updateMetrics(
                       key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345,
                       new StatsPullerManager(), oldAtomMatchingTrackerMap,
                       oldAtomMatchingTrackerMap, /*replacedMatchers=*/{}, oldAtomMatchingTrackers,
                       oldConditionTrackerMap, /*replacedConditions=*/{}, oldConditionTrackers,
                       /*conditionCache=*/{}, /*stateAtomIdMap=*/{}, /*allStateGroupMaps=*/{},
-                      /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers,
+                      /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers, provider,
                       newMetricProducerMap, newMetricProducers, conditionToMetricMap,
                       trackerToMetricMap, noReportMetricIds, activationAtomTrackerToMetricMap,
                       deactivationAtomTrackerToMetricMap, metricsWithActivation, replacedMetrics),
diff --git a/statsd/tests/metrics/parsing_utils/metrics_manager_util_test.cpp b/statsd/tests/metrics/parsing_utils/metrics_manager_util_test.cpp
index 92eeee7..1a64c20 100644
--- a/statsd/tests/metrics/parsing_utils/metrics_manager_util_test.cpp
+++ b/statsd/tests/metrics/parsing_utils/metrics_manager_util_test.cpp
@@ -60,6 +60,7 @@
 sp<StatsPullerManager> pullerManager = new StatsPullerManager();
 sp<AlarmMonitor> anomalyAlarmMonitor;
 sp<AlarmMonitor> periodicAlarmMonitor;
+sp<ConfigMetadataProvider> configMetadataProvider;
 unordered_map<int, vector<int>> allTagIdsToMatchersMap;
 vector<sp<AtomMatchingTracker>> allAtomMatchingTrackers;
 unordered_map<int64_t, int> atomMatchingTrackerMap;
@@ -83,12 +84,12 @@
     // initStatsdConfig returns nullopt if config is valid
     return initStatsdConfig(
             kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
-            timeBaseSec, timeBaseSec, allTagIdsToMatchersMap, allAtomMatchingTrackers,
-            atomMatchingTrackerMap, allConditionTrackers, conditionTrackerMap, allMetricProducers,
-            metricProducerMap, allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
-            trackerToMetricMap, trackerToConditionMap, activationAtomTrackerToMetricMap,
-            deactivationAtomTrackerToMetricMap, alertTrackerMap, metricsWithActivation,
-            stateProtoHashes, noReportMetricIds);
+            timeBaseSec, timeBaseSec, configMetadataProvider, allTagIdsToMatchersMap,
+            allAtomMatchingTrackers, atomMatchingTrackerMap, allConditionTrackers,
+            conditionTrackerMap, allMetricProducers, metricProducerMap, allAnomalyTrackers,
+            allAlarmTrackers, conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
+            activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, alertTrackerMap,
+            metricsWithActivation, stateProtoHashes, noReportMetricIds);
 }
 
 StatsdConfig buildCircleMatchers() {
@@ -1538,8 +1539,10 @@
     metric.set_id(metricId);
     metric.set_bucket(ONE_MINUTE);
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    vector<sp<MetricProducer>> metricProducers({new CountMetricProducer(
-            kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard, 0x0123456789, 0, 0)});
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
+    vector<sp<MetricProducer>> metricProducers(
+            {new CountMetricProducer(kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard,
+                                     0x0123456789, 0, 0, provider)});
     sp<AlarmMonitor> anomalyAlarmMonitor;
     optional<InvalidConfigReason> invalidConfigReason;
     EXPECT_EQ(createAnomalyTracker(alert, anomalyAlarmMonitor, UPDATE_NEW, /*updateTime=*/123,
@@ -1561,8 +1564,10 @@
     metric.set_id(metricId);
     metric.set_bucket(ONE_MINUTE);
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    vector<sp<MetricProducer>> metricProducers({new CountMetricProducer(
-            kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard, 0x0123456789, 0, 0)});
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
+    vector<sp<MetricProducer>> metricProducers(
+            {new CountMetricProducer(kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard,
+                                     0x0123456789, 0, 0, provider)});
     sp<AlarmMonitor> anomalyAlarmMonitor;
     optional<InvalidConfigReason> invalidConfigReason;
     EXPECT_EQ(createAnomalyTracker(alert, anomalyAlarmMonitor, UPDATE_NEW, /*updateTime=*/123,
@@ -1585,8 +1590,10 @@
     metric.set_id(metricId);
     metric.set_bucket(ONE_MINUTE);
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    vector<sp<MetricProducer>> metricProducers({new CountMetricProducer(
-            kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard, 0x0123456789, 0, 0)});
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
+    vector<sp<MetricProducer>> metricProducers(
+            {new CountMetricProducer(kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard,
+                                     0x0123456789, 0, 0, provider)});
     sp<AlarmMonitor> anomalyAlarmMonitor;
     optional<InvalidConfigReason> invalidConfigReason;
     EXPECT_NE(createAnomalyTracker(alert, anomalyAlarmMonitor, UPDATE_NEW, /*updateTime=*/123,
@@ -1610,10 +1617,11 @@
     metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
     FieldMatcher dimensions;
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+    sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
     vector<sp<MetricProducer>> metricProducers({new DurationMetricProducer(
             kConfigKey, metric, -1 /*no condition*/, {}, -1 /* what index not needed*/,
             1 /* start index */, 2 /* stop index */, 3 /* stop_all index */, false /*nesting*/,
-            wizard, 0x0123456789, dimensions, 0, 0)});
+            wizard, 0x0123456789, dimensions, 0, 0, provider)});
     sp<AlarmMonitor> anomalyAlarmMonitor;
     optional<InvalidConfigReason> invalidConfigReason;
     EXPECT_EQ(createAnomalyTracker(alert, anomalyAlarmMonitor, UPDATE_NEW, /*updateTime=*/123,
diff --git a/statsd/tests/statsd_test_util.cpp b/statsd/tests/statsd_test_util.cpp
index 8e80a20..539c890 100644
--- a/statsd/tests/statsd_test_util.cpp
+++ b/statsd/tests/statsd_test_util.cpp
@@ -2314,6 +2314,13 @@
 
     return config;
 }
+
+sp<MockConfigMetadataProvider> makeMockConfigMetadataProvider(bool enabled) {
+    sp<MockConfigMetadataProvider> metadataProvider = new StrictMock<MockConfigMetadataProvider>();
+    EXPECT_CALL(*metadataProvider, useV2SoftMemoryCalculation()).Times(AnyNumber());
+    EXPECT_CALL(*metadataProvider, useV2SoftMemoryCalculation()).WillRepeatedly(Return(enabled));
+    return nullptr;
+}
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
diff --git a/statsd/tests/statsd_test_util.h b/statsd/tests/statsd_test_util.h
index d2d10b2..8fe6440 100644
--- a/statsd/tests/statsd_test_util.h
+++ b/statsd/tests/statsd_test_util.h
@@ -837,6 +837,13 @@
 
 StatsdConfig buildGoodConfig(int configId, int alertId);
 
+class MockConfigMetadataProvider : public ConfigMetadataProvider {
+public:
+    MOCK_METHOD(bool, useV2SoftMemoryCalculation, (), (override));
+};
+
+sp<MockConfigMetadataProvider> makeMockConfigMetadataProvider(bool enabled);
+
 }  // namespace statsd
 }  // namespace os
 }  // namespace android