Alarm: wakes up statsd and notifies the subscribers.

Test: manually tested it.
Change-Id: Id796a68976aeb1611183023ba4e9c6a8b8c44bb8
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
index 9c65371..16cac99 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
@@ -109,9 +109,11 @@
     VLOG("~DurationMetric() called");
 }
 
-sp<AnomalyTracker> DurationMetricProducer::addAnomalyTracker(const Alert &alert) {
+sp<AnomalyTracker> DurationMetricProducer::addAnomalyTracker(
+        const Alert &alert, const sp<AlarmMonitor>& anomalyAlarmMonitor) {
     std::lock_guard<std::mutex> lock(mMutex);
-    sp<DurationAnomalyTracker> anomalyTracker = new DurationAnomalyTracker(alert, mConfigKey);
+    sp<DurationAnomalyTracker> anomalyTracker =
+        new DurationAnomalyTracker(alert, mConfigKey, anomalyAlarmMonitor);
     if (anomalyTracker != nullptr) {
         mAnomalyTrackers.push_back(anomalyTracker);
     }
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.h b/cmds/statsd/src/metrics/DurationMetricProducer.h
index 5f29281..f41c278 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.h
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.h
@@ -46,7 +46,8 @@
 
     virtual ~DurationMetricProducer();
 
-    sp<AnomalyTracker> addAnomalyTracker(const Alert &alert) override;
+    sp<AnomalyTracker> addAnomalyTracker(const Alert &alert,
+                                         const sp<AlarmMonitor>& anomalyAlarmMonitor) override;
 
 protected:
     void onMatchedLogEventInternalLocked(
diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h
index 8663e5e..83e1740 100644
--- a/cmds/statsd/src/metrics/MetricProducer.h
+++ b/cmds/statsd/src/metrics/MetricProducer.h
@@ -124,7 +124,8 @@
     }
 
     /* If alert is valid, adds an AnomalyTracker and returns it. If invalid, returns nullptr. */
-    virtual sp<AnomalyTracker> addAnomalyTracker(const Alert &alert) {
+    virtual sp<AnomalyTracker> addAnomalyTracker(const Alert &alert,
+                                                 const sp<AlarmMonitor>& anomalyAlarmMonitor) {
         std::lock_guard<std::mutex> lock(mMutex);
         sp<AnomalyTracker> anomalyTracker = new AnomalyTracker(alert, mConfigKey);
         if (anomalyTracker != nullptr) {
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index e75b710..1c05214 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -49,13 +49,17 @@
 const int FIELD_ID_METRICS = 1;
 
 MetricsManager::MetricsManager(const ConfigKey& key, const StatsdConfig& config,
-                               const long timeBaseSec, sp<UidMap> uidMap)
+                               const long timeBaseSec,
+                               const sp<UidMap> &uidMap,
+                               const sp<AlarmMonitor>& anomalyAlarmMonitor,
+                               const sp<AlarmMonitor>& periodicAlarmMonitor)
     : mConfigKey(key), mUidMap(uidMap), mLastReportTimeNs(timeBaseSec * NS_PER_SEC) {
     mConfigValid =
-            initStatsdConfig(key, config, *uidMap, timeBaseSec, mTagIds, mAllAtomMatchers,
-                             mAllConditionTrackers,
-                             mAllMetricProducers, mAllAnomalyTrackers, mConditionToMetricMap,
-                             mTrackerToMetricMap, mTrackerToConditionMap, mNoReportMetricIds);
+            initStatsdConfig(key, config, *uidMap, anomalyAlarmMonitor, periodicAlarmMonitor,
+                             timeBaseSec, mTagIds, mAllAtomMatchers,
+                             mAllConditionTrackers, mAllMetricProducers, mAllAnomalyTrackers,
+                             mAllPeriodicAlarmTrackers, mConditionToMetricMap, mTrackerToMetricMap,
+                             mTrackerToConditionMap, mNoReportMetricIds);
 
     if (config.allowed_log_source_size() == 0) {
         // TODO(b/70794411): uncomment the following line and remove the hard coded log source
@@ -312,16 +316,19 @@
     }
 }
 
-void MetricsManager::onAnomalyAlarmFired(const uint64_t timestampNs,
-                         unordered_set<sp<const AnomalyAlarm>, SpHash<AnomalyAlarm>>& anomalySet) {
+void MetricsManager::onAnomalyAlarmFired(
+        const uint64_t timestampNs,
+        unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet) {
     for (const auto& itr : mAllAnomalyTrackers) {
-        itr->informAlarmsFired(timestampNs, anomalySet);
+        itr->informAlarmsFired(timestampNs, alarmSet);
     }
 }
 
-void MetricsManager::setAnomalyMonitor(const sp<AnomalyMonitor>& anomalyMonitor) {
-    for (auto& itr : mAllAnomalyTrackers) {
-        itr->setAnomalyMonitor(anomalyMonitor);
+void MetricsManager::onPeriodicAlarmFired(
+        const uint64_t timestampNs,
+        unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet) {
+    for (const auto& itr : mAllPeriodicAlarmTrackers) {
+        itr->informAlarmsFired(timestampNs, alarmSet);
     }
 }
 
diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h
index d4f844f..b50ef4a 100644
--- a/cmds/statsd/src/metrics/MetricsManager.h
+++ b/cmds/statsd/src/metrics/MetricsManager.h
@@ -16,7 +16,8 @@
 
 #pragma once
 
-#include "anomaly/AnomalyMonitor.h"
+#include "anomaly/AlarmMonitor.h"
+#include "anomaly/AlarmTracker.h"
 #include "anomaly/AnomalyTracker.h"
 #include "condition/ConditionTracker.h"
 #include "config/ConfigKey.h"
@@ -36,7 +37,8 @@
 class MetricsManager : public PackageInfoListener {
 public:
     MetricsManager(const ConfigKey& configKey, const StatsdConfig& config, const long timeBaseSec,
-                   sp<UidMap> uidMap);
+                   const sp<UidMap>& uidMap, const sp<AlarmMonitor>& anomalyAlarmMonitor,
+                   const sp<AlarmMonitor>& periodicAlarmMonitor);
 
     virtual ~MetricsManager();
 
@@ -47,9 +49,11 @@
 
     void onAnomalyAlarmFired(
         const uint64_t timestampNs,
-        unordered_set<sp<const AnomalyAlarm>, SpHash<AnomalyAlarm>>& anomalySet);
+        unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet);
 
-    void setAnomalyMonitor(const sp<AnomalyMonitor>& anomalyMonitor);
+    void onPeriodicAlarmFired(
+        const uint64_t timestampNs,
+        unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet);
 
     void notifyAppUpgrade(const uint64_t& eventTimeNs, const string& apk, const int uid,
                           const int64_t version) override;
@@ -120,6 +124,9 @@
     // Hold all alert trackers.
     std::vector<sp<AnomalyTracker>> mAllAnomalyTrackers;
 
+    // Hold all periodic alarm trackers.
+    std::vector<sp<AlarmTracker>> mAllPeriodicAlarmTrackers;
+
     // To make the log processing more efficient, we want to do as much filtering as possible
     // before we go into individual trackers and conditions to match.
 
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.cpp b/cmds/statsd/src/metrics/metrics_manager_util.cpp
index 71e5c33..9912afa 100644
--- a/cmds/statsd/src/metrics/metrics_manager_util.cpp
+++ b/cmds/statsd/src/metrics/metrics_manager_util.cpp
@@ -17,16 +17,19 @@
 #define DEBUG false  // STOPSHIP if true
 #include "Log.h"
 
+#include "metrics_manager_util.h"
+
 #include "../condition/CombinationConditionTracker.h"
 #include "../condition/SimpleConditionTracker.h"
 #include "../external/StatsPullerManager.h"
 #include "../matchers/CombinationLogMatchingTracker.h"
 #include "../matchers/SimpleLogMatchingTracker.h"
-#include "CountMetricProducer.h"
-#include "DurationMetricProducer.h"
-#include "EventMetricProducer.h"
-#include "GaugeMetricProducer.h"
-#include "ValueMetricProducer.h"
+#include "../metrics/CountMetricProducer.h"
+#include "../metrics/DurationMetricProducer.h"
+#include "../metrics/EventMetricProducer.h"
+#include "../metrics/GaugeMetricProducer.h"
+#include "../metrics/ValueMetricProducer.h"
+
 #include "stats_util.h"
 
 using std::set;
@@ -494,6 +497,7 @@
 
 bool initAlerts(const StatsdConfig& config,
                 const unordered_map<int64_t, int>& metricProducerMap,
+                const sp<AlarmMonitor>& anomalyAlarmMonitor,
                 vector<sp<MetricProducer>>& allMetricProducers,
                 vector<sp<AnomalyTracker>>& allAnomalyTrackers) {
     unordered_map<int64_t, int> anomalyTrackerMap;
@@ -512,7 +516,7 @@
         }
         const int metricIndex = itr->second;
         sp<MetricProducer> metric = allMetricProducers[metricIndex];
-        sp<AnomalyTracker> anomalyTracker = metric->addAnomalyTracker(alert);
+        sp<AnomalyTracker> anomalyTracker = metric->addAnomalyTracker(alert, anomalyAlarmMonitor);
         if (anomalyTracker == nullptr) {
             // The ALOGW for this invalid alert was already displayed in addAnomalyTracker().
             return false;
@@ -522,6 +526,9 @@
     }
     for (int i = 0; i < config.subscription_size(); ++i) {
         const Subscription& subscription = config.subscription(i);
+        if (subscription.rule_type() != Subscription::ALERT) {
+            continue;
+        }
         if (subscription.subscriber_information_case() ==
             Subscription::SubscriberInformationCase::SUBSCRIBER_INFORMATION_NOT_SET) {
             ALOGW("subscription \"%lld\" has no subscriber info.\"",
@@ -540,13 +547,60 @@
     return true;
 }
 
+bool initAlarms(const StatsdConfig& config, const ConfigKey& key,
+                const sp<AlarmMonitor>& periodicAlarmMonitor,
+                const long timeBaseSec,
+                vector<sp<AlarmTracker>>& allAlarmTrackers) {
+    unordered_map<int64_t, int> alarmTrackerMap;
+    uint64_t startMillis = (uint64_t)timeBaseSec * MS_PER_SEC;
+    for (int i = 0; i < config.alarm_size(); i++) {
+        const Alarm& alarm = config.alarm(i);
+        if (alarm.offset_millis() <= 0) {
+            ALOGW("Alarm offset_millis should be larger than 0.");
+            return false;
+        }
+        if (alarm.period_millis() <= 0) {
+            ALOGW("Alarm period_millis should be larger than 0.");
+            return false;
+        }
+        alarmTrackerMap.insert(std::make_pair(alarm.id(), allAlarmTrackers.size()));
+        allAlarmTrackers.push_back(
+            new AlarmTracker(startMillis, alarm, key, periodicAlarmMonitor));
+    }
+    for (int i = 0; i < config.subscription_size(); ++i) {
+        const Subscription& subscription = config.subscription(i);
+        if (subscription.rule_type() != Subscription::ALARM) {
+            continue;
+        }
+        if (subscription.subscriber_information_case() ==
+            Subscription::SubscriberInformationCase::SUBSCRIBER_INFORMATION_NOT_SET) {
+            ALOGW("subscription \"%lld\" has no subscriber info.\"",
+                (long long)subscription.id());
+            return false;
+        }
+        const auto& itr = alarmTrackerMap.find(subscription.rule_id());
+        if (itr == alarmTrackerMap.end()) {
+            ALOGW("subscription \"%lld\" has unknown rule id: \"%lld\"",
+                (long long)subscription.id(), (long long)subscription.rule_id());
+            return false;
+        }
+        const int trackerIndex = itr->second;
+        allAlarmTrackers[trackerIndex]->addSubscription(subscription);
+    }
+    return true;
+}
+
 bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config,
                       const UidMap& uidMap,
-                      const long timeBaseSec, set<int>& allTagIds,
+                      const sp<AlarmMonitor>& anomalyAlarmMonitor,
+                      const sp<AlarmMonitor>& periodicAlarmMonitor,
+                      const long timeBaseSec,
+                      set<int>& allTagIds,
                       vector<sp<LogMatchingTracker>>& allAtomMatchers,
                       vector<sp<ConditionTracker>>& allConditionTrackers,
                       vector<sp<MetricProducer>>& allMetricProducers,
                       vector<sp<AnomalyTracker>>& allAnomalyTrackers,
+                      vector<sp<AlarmTracker>>& allPeriodicAlarmTrackers,
                       unordered_map<int, std::vector<int>>& conditionToMetricMap,
                       unordered_map<int, std::vector<int>>& trackerToMetricMap,
                       unordered_map<int, std::vector<int>>& trackerToConditionMap,
@@ -573,10 +627,16 @@
         ALOGE("initMetricProducers failed");
         return false;
     }
-    if (!initAlerts(config, metricProducerMap, allMetricProducers, allAnomalyTrackers)) {
+    if (!initAlerts(config, metricProducerMap, anomalyAlarmMonitor, allMetricProducers,
+                    allAnomalyTrackers)) {
         ALOGE("initAlerts failed");
         return false;
     }
+    if (!initAlarms(config, key, periodicAlarmMonitor, timeBaseSec, allPeriodicAlarmTrackers)) {
+        ALOGE("initAlarms failed");
+        return false;
+    }
+
     return true;
 }
 
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.h b/cmds/statsd/src/metrics/metrics_manager_util.h
index 4f19ada..edda53d 100644
--- a/cmds/statsd/src/metrics/metrics_manager_util.h
+++ b/cmds/statsd/src/metrics/metrics_manager_util.h
@@ -13,16 +13,19 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#ifndef METRIC_UTIL_H
-#define METRIC_UTIL_H
+
+#pragma once
+
 #include <memory>
 #include <set>
 #include <unordered_map>
 #include <vector>
 
+#include "../anomaly/AlarmTracker.h"
 #include "../condition/ConditionTracker.h"
 #include "../external/StatsPullerManagerImpl.h"
 #include "../matchers/LogMatchingTracker.h"
+#include "../metrics/MetricProducer.h"
 
 namespace android {
 namespace os {
@@ -93,11 +96,15 @@
 // Parameters are the members of MetricsManager. See MetricsManager for declaration.
 bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config,
                       const UidMap& uidMap,
-                      const long timeBaseSec, std::set<int>& allTagIds,
+                      const sp<AlarmMonitor>& anomalyAlarmMonitor,
+                      const sp<AlarmMonitor>& periodicAlarmMonitor,
+                      const long timeBaseSec,
+                      std::set<int>& allTagIds,
                       std::vector<sp<LogMatchingTracker>>& allAtomMatchers,
                       std::vector<sp<ConditionTracker>>& allConditionTrackers,
                       std::vector<sp<MetricProducer>>& allMetricProducers,
                       vector<sp<AnomalyTracker>>& allAnomalyTrackers,
+                      vector<sp<AlarmTracker>>& allPeriodicAlarmTrackers,
                       std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
                       std::unordered_map<int, std::vector<int>>& trackerToMetricMap,
                       std::unordered_map<int, std::vector<int>>& trackerToConditionMap,
@@ -106,4 +113,3 @@
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
-#endif  // METRIC_UTIL_H