Merge "Merge "BT: Remove dead code in BluetoothHeadset" am: ea7363402c am: 38ae4d2fce am: aa9829a85a"
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index fa7fe0c..dc12efb 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -72,7 +72,7 @@
 
 // ======================================================================
 StatsService::StatsService(const sp<Looper>& handlerLooper)
-    : mAnomalyMonitor(new AnomalyMonitor(2))  // TODO: Put this comment somewhere better
+    : mAnomalyMonitor(new AnomalyMonitor(MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS))
 {
     mUidMap = new UidMap();
     mConfigManager = new ConfigManager();
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
index bdae1ef..e434f65 100644
--- a/cmds/statsd/src/StatsService.h
+++ b/cmds/statsd/src/StatsService.h
@@ -46,6 +46,10 @@
     StatsService(const sp<Looper>& handlerLooper);
     virtual ~StatsService();
 
+    /** The anomaly alarm registered with AlarmManager won't be updated by less than this. */
+    // TODO: Consider making this configurable. And choose a good number.
+    const uint32_t MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS = 5;
+
     virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
     virtual status_t dump(int fd, const Vector<String16>& args);
     virtual status_t command(FILE* in, FILE* out, FILE* err, Vector<String8>& args);
diff --git a/cmds/statsd/src/anomaly/AnomalyMonitor.cpp b/cmds/statsd/src/anomaly/AnomalyMonitor.cpp
index 2b2bcfc..4912648 100644
--- a/cmds/statsd/src/anomaly/AnomalyMonitor.cpp
+++ b/cmds/statsd/src/anomaly/AnomalyMonitor.cpp
@@ -18,6 +18,7 @@
 #include "Log.h"
 
 #include "anomaly/AnomalyMonitor.h"
+#include "guardrail/StatsdStats.h"
 
 namespace android {
 namespace os {
@@ -76,10 +77,7 @@
     if (!wasPresent) return;
     if (mPq.empty()) {
         if (DEBUG) ALOGD("Queue is empty. Cancel any alarm.");
-        mRegisteredAlarmTimeSec = 0;
-        if (mStatsCompanionService != nullptr) {
-            mStatsCompanionService->cancelAnomalyAlarm();
-        }
+        cancelRegisteredAlarmTime_l();
         return;
     }
     uint32_t soonestAlarmTimeSec = mPq.top()->timestampSec;
@@ -106,10 +104,7 @@
     if (!oldAlarms.empty()) {
         if (mPq.empty()) {
             if (DEBUG) ALOGD("Queue is empty. Cancel any alarm.");
-            mRegisteredAlarmTimeSec = 0;
-            if (mStatsCompanionService != nullptr) {
-                mStatsCompanionService->cancelAnomalyAlarm();
-            }
+            cancelRegisteredAlarmTime_l();
         } else {
             // Always update the registered alarm in this case (unlike remove()).
             updateRegisteredAlarmTime_l(mPq.top()->timestampSec);
@@ -123,6 +118,16 @@
     mRegisteredAlarmTimeSec = timestampSec;
     if (mStatsCompanionService != nullptr) {
         mStatsCompanionService->setAnomalyAlarm(secToMs(mRegisteredAlarmTimeSec));
+        StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged();
+    }
+}
+
+void AnomalyMonitor::cancelRegisteredAlarmTime_l() {
+    if (DEBUG) ALOGD("Cancelling reg alarm.");
+    mRegisteredAlarmTimeSec = 0;
+    if (mStatsCompanionService != nullptr) {
+        mStatsCompanionService->cancelAnomalyAlarm();
+        StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged();
     }
 }
 
diff --git a/cmds/statsd/src/anomaly/AnomalyMonitor.h b/cmds/statsd/src/anomaly/AnomalyMonitor.h
index e19c469..7acc7904 100644
--- a/cmds/statsd/src/anomaly/AnomalyMonitor.h
+++ b/cmds/statsd/src/anomaly/AnomalyMonitor.h
@@ -138,6 +138,12 @@
      */
     void updateRegisteredAlarmTime_l(uint32_t timestampSec);
 
+    /**
+     * Cancels the alarm registered with StatsCompanionService.
+     * Also correspondingly sets mRegisteredAlarmTimeSec to 0.
+     */
+    void cancelRegisteredAlarmTime_l();
+
     /** Converts uint32 timestamp in seconds to a Java long in msec. */
     int64_t secToMs(uint32_t timeSec);
 };
diff --git a/cmds/statsd/src/anomaly/AnomalyTracker.cpp b/cmds/statsd/src/anomaly/AnomalyTracker.cpp
index 7bacb44..e8b4083 100644
--- a/cmds/statsd/src/anomaly/AnomalyTracker.cpp
+++ b/cmds/statsd/src/anomaly/AnomalyTracker.cpp
@@ -18,6 +18,7 @@
 #include "Log.h"
 
 #include "AnomalyTracker.h"
+#include "guardrail/StatsdStats.h"
 
 #include <android/os/IIncidentManager.h>
 #include <android/os/IncidentReportArgs.h>
@@ -31,8 +32,9 @@
 // TODO: Separate DurationAnomalyTracker as a separate subclass and let each MetricProducer
 //       decide and let which one it wants.
 // TODO: Get rid of bucketNumbers, and return to the original circular array method.
-AnomalyTracker::AnomalyTracker(const Alert& alert)
+AnomalyTracker::AnomalyTracker(const Alert& alert, const ConfigKey& configKey)
     : mAlert(alert),
+      mConfigKey(configKey),
       mNumOfPastBuckets(mAlert.number_of_buckets() - 1) {
     VLOG("AnomalyTracker() called");
     if (mAlert.number_of_buckets() <= 0) {
@@ -220,6 +222,8 @@
     } else {
         ALOGW("An anomaly has occurred! (But informing incidentd not requested.)");
     }
+
+    StatsdStats::getInstance().noteAnomalyDeclared(mConfigKey, mAlert.name());
 }
 
 void AnomalyTracker::declareAnomalyIfAlarmExpired(const HashableDimensionKey& dimensionKey,
diff --git a/cmds/statsd/src/anomaly/AnomalyTracker.h b/cmds/statsd/src/anomaly/AnomalyTracker.h
index 49e8323..874add2 100644
--- a/cmds/statsd/src/anomaly/AnomalyTracker.h
+++ b/cmds/statsd/src/anomaly/AnomalyTracker.h
@@ -18,6 +18,7 @@
 
 #include <gtest/gtest_prod.h>
 #include "AnomalyMonitor.h"
+#include "config/ConfigKey.h"
 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"  // Alert
 #include "stats_util.h"  // HashableDimensionKey and DimToValMap
 
@@ -35,7 +36,7 @@
 // Does NOT allow negative values.
 class AnomalyTracker : public virtual RefBase {
 public:
-    AnomalyTracker(const Alert& alert);
+    AnomalyTracker(const Alert& alert, const ConfigKey& configKey);
 
     virtual ~AnomalyTracker();
 
@@ -107,9 +108,13 @@
 
 protected:
     void flushPastBuckets(const int64_t& currBucketNum);
+
     // statsd_config.proto Alert message that defines this tracker.
     const Alert mAlert;
 
+    // A reference to the Alert's config key.
+    const ConfigKey& mConfigKey;
+
     // Number of past buckets. One less than the total number of buckets needed
     // for the anomaly detection (since the current bucket is not in the past).
     int mNumOfPastBuckets;
diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp
index 2957457..b02b9da 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.cpp
+++ b/cmds/statsd/src/guardrail/StatsdStats.cpp
@@ -41,11 +41,9 @@
 const int FIELD_ID_BEGIN_TIME = 1;
 const int FIELD_ID_END_TIME = 2;
 const int FIELD_ID_CONFIG_STATS = 3;
-const int FIELD_ID_MATCHER_STATS = 4;
-const int FIELD_ID_CONDITION_STATS = 5;
-const int FIELD_ID_METRIC_STATS = 6;
 const int FIELD_ID_ATOM_STATS = 7;
 const int FIELD_ID_UIDMAP_STATS = 8;
+const int FIELD_ID_ANOMALY_ALARM_STATS = 9;
 
 const int FIELD_ID_MATCHER_STATS_NAME = 1;
 const int FIELD_ID_MATCHER_STATS_COUNT = 2;
@@ -59,6 +57,8 @@
 const int FIELD_ID_ATOM_STATS_TAG = 1;
 const int FIELD_ID_ATOM_STATS_COUNT = 2;
 
+const int FIELD_ID_ANOMALY_ALARMS_REGISTERED = 1;
+
 // TODO: add stats for pulled atoms.
 StatsdStats::StatsdStats() {
     mPushedAtomStats.resize(android::util::kMaxPushedAtomId + 1);
@@ -101,11 +101,12 @@
     if (it != mConfigStats.end()) {
         int32_t nowTimeSec = time(nullptr);
         it->second.set_deletion_time_sec(nowTimeSec);
-        // Add condition stats, metrics stats, matcher stats
-        addSubStatsToConfig(key, it->second);
+        // Add condition stats, metrics stats, matcher stats, alert stats
+        addSubStatsToConfigLocked(key, it->second);
         // Remove them after they are added to the config stats.
         mMatcherStats.erase(key);
         mMetricsStats.erase(key);
+        mAlertStats.erase(key);
         mConditionStats.erase(key);
         mIceBox.push_back(it->second);
         mConfigStats.erase(it);
@@ -219,6 +220,17 @@
     matcherStats[name]++;
 }
 
+void StatsdStats::noteAnomalyDeclared(const ConfigKey& key, const string& name) {
+    lock_guard<std::mutex> lock(mLock);
+    auto& alertStats = mAlertStats[key];
+    alertStats[name]++;
+}
+
+void StatsdStats::noteRegisteredAnomalyAlarmChanged() {
+    lock_guard<std::mutex> lock(mLock);
+    mAnomalyAlarmRegisteredStats++;
+}
+
 void StatsdStats::noteAtomLogged(int atomId, int32_t timeSec) {
     lock_guard<std::mutex> lock(mLock);
 
@@ -246,6 +258,8 @@
     mConditionStats.clear();
     mMetricsStats.clear();
     std::fill(mPushedAtomStats.begin(), mPushedAtomStats.end(), 0);
+    mAlertStats.clear();
+    mAnomalyAlarmRegisteredStats = 0;
     mMatcherStats.clear();
     for (auto& config : mConfigStats) {
         config.second.clear_broadcast_sent_time_sec();
@@ -254,10 +268,11 @@
         config.second.clear_matcher_stats();
         config.second.clear_condition_stats();
         config.second.clear_metric_stats();
+        config.second.clear_alert_stats();
     }
 }
 
-void StatsdStats::addSubStatsToConfig(const ConfigKey& key,
+void StatsdStats::addSubStatsToConfigLocked(const ConfigKey& key,
                                       StatsdStatsReport_ConfigStats& configStats) {
     // Add matcher stats
     if (mMatcherStats.find(key) != mMatcherStats.end()) {
@@ -289,6 +304,16 @@
             VLOG("metrics %s max output tuple size %d", stats.first.c_str(), stats.second);
         }
     }
+    // Add anomaly detection alert stats
+    if (mAlertStats.find(key) != mAlertStats.end()) {
+        const auto& alertStats = mAlertStats[key];
+        for (const auto& stats : alertStats) {
+            auto output = configStats.add_alert_stats();
+            output->set_name(stats.first);
+            output->set_declared_times(stats.second);
+            VLOG("alert %s declared %d times", stats.first.c_str(), stats.second);
+        }
+    }
 }
 
 void StatsdStats::dumpStats(std::vector<uint8_t>* output, bool reset) {
@@ -358,7 +383,7 @@
             }
         }
 
-        addSubStatsToConfig(pair.first, configStats);
+        addSubStatsToConfigLocked(pair.first, configStats);
 
         const int numBytes = configStats.ByteSize();
         vector<char> buffer(numBytes);
@@ -370,6 +395,7 @@
         configStats.clear_matcher_stats();
         configStats.clear_condition_stats();
         configStats.clear_metric_stats();
+        configStats.clear_alert_stats();
     }
 
     VLOG("********Atom stats***********");
@@ -386,6 +412,15 @@
         }
     }
 
+    if (mAnomalyAlarmRegisteredStats > 0) {
+        VLOG("********AnomalyAlarmStats stats***********");
+        long long token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_ANOMALY_ALARM_STATS);
+        proto.write(FIELD_TYPE_INT32 | FIELD_ID_ANOMALY_ALARMS_REGISTERED,
+                    mAnomalyAlarmRegisteredStats);
+        proto.end(token);
+        VLOG("Anomaly alarm registrations: %d", mAnomalyAlarmRegisteredStats);
+    }
+
     const int numBytes = mUidMapStats.ByteSize();
     vector<char> buffer(numBytes);
     mUidMapStats.SerializeToArray(&buffer[0], numBytes);
diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h
index d6f6566..3940563 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.h
+++ b/cmds/statsd/src/guardrail/StatsdStats.h
@@ -112,11 +112,24 @@
     void noteMatcherMatched(const ConfigKey& key, const std::string& name);
 
     /**
+     * Report that an anomaly detection alert has been declared.
+     *
+     * [key]: The config key that this alert belongs to.
+     * [name]: The name of the alert.
+     */
+    void noteAnomalyDeclared(const ConfigKey& key, const std::string& name);
+
+    /**
      * Report an atom event has been logged.
      */
     void noteAtomLogged(int atomId, int32_t timeSec);
 
     /**
+     * Report that statsd modified the anomaly alarm registered with StatsCompanionService.
+     */
+    void noteRegisteredAnomalyAlarmChanged();
+
+    /**
      * Records the number of snapshot and delta entries that are being dropped from the uid map.
      */
     void noteUidMapDropped(int snapshots, int deltas);
@@ -174,6 +187,14 @@
     // This is a vector, not a map because it will be accessed A LOT -- for each stats log.
     std::vector<int> mPushedAtomStats;
 
+    // Stores the number of times statsd modified the anomaly alarm registered with
+    // StatsCompanionService.
+    int mAnomalyAlarmRegisteredStats = 0;
+
+    // Stores the number of times an anomaly detection alert has been declared
+    // (per config, per alert name).
+    std::map<const ConfigKey, std::map<const std::string, int>> mAlertStats;
+
     // Stores how many times a matcher have been matched.
     std::map<const ConfigKey, std::map<const std::string, int>> mMatcherStats;
 
@@ -181,7 +202,8 @@
 
     void resetInternalLocked();
 
-    void addSubStatsToConfig(const ConfigKey& key, StatsdStatsReport_ConfigStats& configStats);
+    void addSubStatsToConfigLocked(const ConfigKey& key,
+                                   StatsdStatsReport_ConfigStats& configStats);
 
     void noteDataDropped(const ConfigKey& key, int32_t timeSec);
 
@@ -195,6 +217,7 @@
     FRIEND_TEST(StatsdStatsTest, TestSubStats);
     FRIEND_TEST(StatsdStatsTest, TestAtomLog);
     FRIEND_TEST(StatsdStatsTest, TestTimestampThreshold);
+    FRIEND_TEST(StatsdStatsTest, TestAnomalyMonitor);
 };
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
index fd484c2..cedea30 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
@@ -111,7 +111,7 @@
         return nullptr;
     }
     // TODO: return a DurationAnomalyTracker (which should sublclass AnomalyTracker)
-    return new AnomalyTracker(alert);
+    return new AnomalyTracker(alert, mConfigKey);
 }
 
 void DurationMetricProducer::startNewProtoOutputStreamLocked(long long startTime) {
diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h
index e7e84ab..adeb3cd 100644
--- a/cmds/statsd/src/metrics/MetricProducer.h
+++ b/cmds/statsd/src/metrics/MetricProducer.h
@@ -94,7 +94,7 @@
     }
 
     virtual sp<AnomalyTracker> createAnomalyTracker(const Alert &alert) {
-        return new AnomalyTracker(alert);
+        return new AnomalyTracker(alert, mConfigKey);
     }
 
     void addAnomalyTracker(sp<AnomalyTracker> tracker) {
diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto
index 60d9a3d..f8b91fe 100644
--- a/cmds/statsd/src/stats_log.proto
+++ b/cmds/statsd/src/stats_log.proto
@@ -193,6 +193,11 @@
         optional int32 max_tuple_counts = 2;
     }
 
+    message AlertStats {
+        optional string name = 1;
+        optional int32 declared_times = 2;
+    }
+
     message ConfigStats {
         optional int32 uid = 1;
         optional string name = 2;
@@ -210,6 +215,7 @@
         repeated MatcherStats matcher_stats = 13;
         repeated ConditionStats condition_stats = 14;
         repeated MetricStats metric_stats = 15;
+        repeated AlertStats alert_stats = 16;
     }
 
     repeated ConfigStats config_stats = 3;
@@ -229,4 +235,9 @@
         optional int32 dropped_changes = 5;
     }
     optional UidMapStats uidmap_stats = 8;
+
+    message AnomalyAlarmStats {
+        optional int32 alarms_registered = 1;
+    }
+    optional AnomalyAlarmStats anomaly_alarm_stats = 9;
 }
\ No newline at end of file
diff --git a/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp b/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp
index 65c2a05..f385763 100644
--- a/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp
+++ b/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp
@@ -30,6 +30,8 @@
 namespace os {
 namespace statsd {
 
+const ConfigKey kConfigKey(0, "test");
+
 void AddValueToBucket(const std::vector<std::pair<string, long>>& key_value_pair_list,
                       std::shared_ptr<DimToValMap> bucket) {
     for (auto itr = key_value_pair_list.begin(); itr != key_value_pair_list.end(); itr++) {
@@ -51,7 +53,7 @@
     alert.set_refractory_period_secs(2 * bucketSizeNs / NS_PER_SEC);
     alert.set_trigger_if_sum_gt(2);
 
-    AnomalyTracker anomalyTracker(alert);
+    AnomalyTracker anomalyTracker(alert, kConfigKey);
 
     std::shared_ptr<DimToValMap> bucket0 = MockBucket({{"a", 1}, {"b", 2}, {"c", 1}});
     int64_t eventTimestamp0 = 10;
@@ -168,7 +170,7 @@
     alert.set_refractory_period_secs(2 * bucketSizeNs / NS_PER_SEC);
     alert.set_trigger_if_sum_gt(2);
 
-    AnomalyTracker anomalyTracker(alert);
+    AnomalyTracker anomalyTracker(alert, kConfigKey);
 
     std::shared_ptr<DimToValMap> bucket9 = MockBucket({{"a", 1}, {"b", 2}, {"c", 1}});
     std::shared_ptr<DimToValMap> bucket16 = MockBucket({{"b", 4}});
diff --git a/cmds/statsd/tests/guardrail/StatsdStats_test.cpp b/cmds/statsd/tests/guardrail/StatsdStats_test.cpp
index a8193dd..9fed4f8 100644
--- a/cmds/statsd/tests/guardrail/StatsdStats_test.cpp
+++ b/cmds/statsd/tests/guardrail/StatsdStats_test.cpp
@@ -118,6 +118,10 @@
     stats.noteMetricDimensionSize(key, "metric1", 201);
     stats.noteMetricDimensionSize(key, "metric1", 202);
 
+    stats.noteAnomalyDeclared(key, "alert1");
+    stats.noteAnomalyDeclared(key, "alert1");
+    stats.noteAnomalyDeclared(key, "alert2");
+
     // broadcast-> 2
     stats.noteBroadcastSent(key);
     stats.noteBroadcastSent(key);
@@ -142,7 +146,6 @@
     EXPECT_EQ(3, configReport.dump_report_time_sec_size());
 
     EXPECT_EQ(2, configReport.matcher_stats_size());
-
     // matcher1 is the first in the list
     if (!configReport.matcher_stats(0).name().compare("matcher1")) {
         EXPECT_EQ(2, configReport.matcher_stats(0).matched_times());
@@ -157,6 +160,13 @@
         EXPECT_EQ("matcher1", configReport.matcher_stats(1).name());
     }
 
+    EXPECT_EQ(2, configReport.alert_stats_size());
+    bool alert1first = !configReport.alert_stats(0).name().compare("alert1");
+    EXPECT_EQ("alert1", configReport.alert_stats(alert1first ? 0 : 1).name());
+    EXPECT_EQ(2, configReport.alert_stats(alert1first ? 0 : 1).declared_times());
+    EXPECT_EQ("alert2", configReport.alert_stats(alert1first ? 1 : 0).name());
+    EXPECT_EQ(1, configReport.alert_stats(alert1first ? 1 : 0).declared_times());
+
     EXPECT_EQ(1, configReport.condition_stats_size());
     EXPECT_EQ("condition1", configReport.condition_stats(0).name());
     EXPECT_EQ(250, configReport.condition_stats(0).max_tuple_counts());
@@ -169,6 +179,7 @@
     stats.noteMatcherMatched(key, "matcher99");
     stats.noteConditionDimensionSize(key, "condition99", 300);
     stats.noteMetricDimensionSize(key, "metric99", 270);
+    stats.noteAnomalyDeclared(key, "alert99");
 
     // now the config stats should only contain the stats about the new event.
     stats.dumpStats(&output, false);
@@ -187,6 +198,10 @@
     EXPECT_EQ(1, configReport2.metric_stats_size());
     EXPECT_EQ("metric99", configReport2.metric_stats(0).name());
     EXPECT_EQ(270, configReport2.metric_stats(0).max_tuple_counts());
+
+    EXPECT_EQ(1, configReport2.alert_stats_size());
+    EXPECT_EQ("alert99", configReport2.alert_stats(0).name());
+    EXPECT_EQ(1, configReport2.alert_stats(0).declared_times());
 }
 
 TEST(StatsdStatsTest, TestAtomLog) {
@@ -224,6 +239,21 @@
     EXPECT_TRUE(sensorAtomGood);
 }
 
+
+TEST(StatsdStatsTest, TestAnomalyMonitor) {
+    StatsdStats stats;
+    stats.noteRegisteredAnomalyAlarmChanged();
+    stats.noteRegisteredAnomalyAlarmChanged();
+
+    vector<uint8_t> output;
+    stats.dumpStats(&output, false);
+    StatsdStatsReport report;
+    bool good = report.ParseFromArray(&output[0], output.size());
+    EXPECT_TRUE(good);
+
+    EXPECT_EQ(2, report.anomaly_alarm_stats().alarms_registered());
+}
+
 TEST(StatsdStatsTest, TestTimestampThreshold) {
     StatsdStats stats;
     vector<int32_t> timestamps;
diff --git a/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp b/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
index 9b94099..d973ba1 100644
--- a/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
@@ -196,7 +196,7 @@
     int64_t bucket2StartTimeNs = bucketStartTimeNs + bucketSizeNs;
     int64_t bucket3StartTimeNs = bucketStartTimeNs + 2 * bucketSizeNs;
 
-    sp<AnomalyTracker> anomalyTracker = new AnomalyTracker(alert);
+    sp<AnomalyTracker> anomalyTracker = new AnomalyTracker(alert, kConfigKey);
 
     CountMetric metric;
     metric.set_name("1");
diff --git a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
index ed13db2..59475d2 100644
--- a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
@@ -33,6 +33,8 @@
 namespace os {
 namespace statsd {
 
+const ConfigKey kConfigKey(0, "test");
+
 TEST(GaugeMetricProducerTest, TestWithCondition) {
     int64_t bucketStartTimeNs = 10000000000;
     int64_t bucketSizeNs = 60 * 1000 * 1000 * 1000LL;
@@ -148,7 +150,7 @@
     alert.set_metric_name("1");
     alert.set_trigger_if_sum_gt(25);
     alert.set_number_of_buckets(2);
-    sp<AnomalyTracker> anomalyTracker = new AnomalyTracker(alert);
+    sp<AnomalyTracker> anomalyTracker = new AnomalyTracker(alert, kConfigKey);
     gaugeProducer.addAnomalyTracker(anomalyTracker);
 
     std::shared_ptr<LogEvent> event1 = std::make_shared<LogEvent>(1, bucketStartTimeNs + 1);
diff --git a/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp b/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp
index 1adcc11..4e5e0d6 100644
--- a/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp
+++ b/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp
@@ -208,7 +208,7 @@
     uint64_t eventStartTimeNs = bucketStartTimeNs + NS_PER_SEC + 1;
     uint64_t bucketSizeNs = 30 * NS_PER_SEC;
 
-    sp<AnomalyTracker> anomalyTracker = new AnomalyTracker(alert);
+    sp<AnomalyTracker> anomalyTracker = new AnomalyTracker(alert, kConfigKey);
     MaxDurationTracker tracker(kConfigKey, "metric", eventKey, wizard, -1, true, bucketStartTimeNs,
                                bucketSizeNs, {anomalyTracker});
 
diff --git a/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp b/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp
index fa7b9a7..99d3e05 100644
--- a/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp
+++ b/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp
@@ -269,7 +269,7 @@
     uint64_t eventStartTimeNs = bucketStartTimeNs + NS_PER_SEC + 1;
     uint64_t bucketSizeNs = 30 * NS_PER_SEC;
 
-    sp<AnomalyTracker> anomalyTracker = new AnomalyTracker(alert);
+    sp<AnomalyTracker> anomalyTracker = new AnomalyTracker(alert, kConfigKey);
     OringDurationTracker tracker(kConfigKey, "metric", eventKey, wizard, 1, true, bucketStartTimeNs,
                                  bucketSizeNs, {anomalyTracker});
 
@@ -331,7 +331,7 @@
     uint64_t eventStartTimeNs = bucketStartTimeNs + NS_PER_SEC + 1;
     uint64_t bucketSizeNs = 30 * NS_PER_SEC;
 
-    sp<AnomalyTracker> anomalyTracker = new AnomalyTracker(alert);
+    sp<AnomalyTracker> anomalyTracker = new AnomalyTracker(alert, kConfigKey);
     OringDurationTracker tracker(kConfigKey, "metric", eventKey, wizard, 1, true /*nesting*/,
                                  bucketStartTimeNs, bucketSizeNs, {anomalyTracker});