Use TimeUnit enum to specify the bucket size.

Test: all statsd unit test passed

Change-Id: I4f6b80ba2f8c984b06e46e6de6df3e546e99a968
diff --git a/cmds/statsd/src/config/ConfigManager.cpp b/cmds/statsd/src/config/ConfigManager.cpp
index de75c71..427fda9 100644
--- a/cmds/statsd/src/config/ConfigManager.cpp
+++ b/cmds/statsd/src/config/ConfigManager.cpp
@@ -234,7 +234,7 @@
     CountMetric* metric = config.add_count_metric();
     metric->set_id(1);  // METRIC_1
     metric->set_what(102);  //  "SCREEN_TURNED_ON"
-    metric->mutable_bucket()->set_bucket_size_millis(30 * 1000L);
+    metric->set_bucket(ONE_MINUTE);
 
     // Anomaly threshold for screen-on count.
     // TODO(b/70627390): Uncomment once the bug is fixed.
@@ -258,7 +258,7 @@
     metric = config.add_count_metric();
     metric->set_id(2);  // "METRIC_2"
     metric->set_what(104);
-    metric->mutable_bucket()->set_bucket_size_millis(30 * 1000L);
+    metric->set_bucket(ONE_MINUTE);
     FieldMatcher* dimensions = metric->mutable_dimensions();
     dimensions->set_field(UID_PROCESS_STATE_TAG_ID);
     dimensions->add_child()->set_field(UID_PROCESS_STATE_UID_KEY);
@@ -280,7 +280,7 @@
     metric = config.add_count_metric();
     metric->set_id(3);
     metric->set_what(104);
-    metric->mutable_bucket()->set_bucket_size_millis(30 * 1000L);
+    metric->set_bucket(ONE_MINUTE);
 
     dimensions = metric->mutable_dimensions();
     dimensions->set_field(UID_PROCESS_STATE_TAG_ID);
@@ -291,7 +291,7 @@
     metric = config.add_count_metric();
     metric->set_id(4);
     metric->set_what(107);
-    metric->mutable_bucket()->set_bucket_size_millis(30 * 1000L);
+    metric->set_bucket(ONE_MINUTE);
     dimensions = metric->mutable_dimensions();
     dimensions->set_field(WAKE_LOCK_TAG_ID);
     dimensions->add_child()->set_field(WAKE_LOCK_UID_KEY_ID);
@@ -308,7 +308,7 @@
     // Duration of an app holding any wl, while screen on and app in background, slice by uid
     DurationMetric* durationMetric = config.add_duration_metric();
     durationMetric->set_id(5);
-    durationMetric->mutable_bucket()->set_bucket_size_millis(30 * 1000L);
+    durationMetric->set_bucket(ONE_MINUTE);
     durationMetric->set_aggregation_type(DurationMetric_AggregationType_SUM);
     dimensions = durationMetric->mutable_dimensions();
     dimensions->set_field(WAKE_LOCK_TAG_ID);
@@ -325,7 +325,7 @@
     // max Duration of an app holding any wl, while screen on and app in background, slice by uid
     durationMetric = config.add_duration_metric();
     durationMetric->set_id(6);
-    durationMetric->mutable_bucket()->set_bucket_size_millis(30 * 1000L);
+    durationMetric->set_bucket(ONE_MINUTE);
     durationMetric->set_aggregation_type(DurationMetric_AggregationType_MAX_SPARSE);
     dimensions = durationMetric->mutable_dimensions();
     dimensions->set_field(WAKE_LOCK_TAG_ID);
@@ -342,7 +342,7 @@
     // Duration of an app holding any wl, while screen on and app in background
     durationMetric = config.add_duration_metric();
     durationMetric->set_id(7);
-    durationMetric->mutable_bucket()->set_bucket_size_millis(30 * 1000L);
+    durationMetric->set_bucket(ONE_MINUTE);
     durationMetric->set_aggregation_type(DurationMetric_AggregationType_MAX_SPARSE);
     durationMetric->set_what(205);
     durationMetric->set_condition(204);
@@ -357,7 +357,7 @@
     // Duration of screen on time.
     durationMetric = config.add_duration_metric();
     durationMetric->set_id(8);
-    durationMetric->mutable_bucket()->set_bucket_size_millis(10 * 1000L);
+    durationMetric->set_bucket(ONE_MINUTE);
     durationMetric->set_aggregation_type(DurationMetric_AggregationType_SUM);
     durationMetric->set_what(201);
 
@@ -384,7 +384,7 @@
     dimensions->set_field(KERNEL_WAKELOCK_TAG_ID);
     dimensions->add_child()->set_field(KERNEL_WAKELOCK_NAME_KEY);
     // This is for testing easier. We should never set bucket size this small.
-    valueMetric->mutable_bucket()->set_bucket_size_millis(60 * 1000L);
+    durationMetric->set_bucket(ONE_MINUTE);
 
     // Add an EventMetric to log process state change events.
     EventMetric* eventMetric = config.add_event_metric();
@@ -398,7 +398,7 @@
     auto gaugeFieldMatcher = gaugeMetric->mutable_gauge_fields_filter()->mutable_fields();
     gaugeFieldMatcher->set_field(DEVICE_TEMPERATURE_TAG_ID);
     gaugeFieldMatcher->add_child()->set_field(DEVICE_TEMPERATURE_KEY);
-    gaugeMetric->mutable_bucket()->set_bucket_size_millis(60 * 1000L);
+    durationMetric->set_bucket(ONE_MINUTE);
 
     // Event matchers.
     AtomMatcher* temperatureAtomMatcher = config.add_atom_matcher();
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.cpp b/cmds/statsd/src/metrics/CountMetricProducer.cpp
index a24364d..3e98098 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/CountMetricProducer.cpp
@@ -63,8 +63,8 @@
                                          const uint64_t startTimeNs)
     : MetricProducer(metric.id(), key, startTimeNs, conditionIndex, wizard) {
     // TODO: evaluate initial conditions. and set mConditionMet.
-    if (metric.has_bucket() && metric.bucket().has_bucket_size_millis()) {
-        mBucketSizeNs = metric.bucket().bucket_size_millis() * 1000 * 1000;
+    if (metric.has_bucket()) {
+        mBucketSizeNs = TimeUnitToBucketSizeInMillis(metric.bucket()) * 1000000;
     } else {
         mBucketSizeNs = LLONG_MAX;
     }
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
index 0117b6d..3f8a8ff 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
@@ -73,8 +73,8 @@
     // TODO: The following boiler plate code appears in all MetricProducers, but we can't abstract
     // them in the base class, because the proto generated CountMetric, and DurationMetric are
     // not related. Maybe we should add a template in the future??
-    if (metric.has_bucket() && metric.bucket().has_bucket_size_millis()) {
-        mBucketSizeNs = metric.bucket().bucket_size_millis() * 1000000;
+    if (metric.has_bucket()) {
+        mBucketSizeNs = TimeUnitToBucketSizeInMillis(metric.bucket()) * 1000000;
     } else {
         mBucketSizeNs = LLONG_MAX;
     }
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
index eaf1de2..64ac6fa 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
@@ -69,11 +69,13 @@
       mAtomTagId(atomTagId) {
     mCurrentSlicedBucket = std::make_shared<DimToGaugeFieldsMap>();
     mCurrentSlicedBucketForAnomaly = std::make_shared<DimToValMap>();
-    if (metric.has_bucket() && metric.bucket().has_bucket_size_millis()) {
-        mBucketSizeNs = metric.bucket().bucket_size_millis() * 1000 * 1000;
+    int64_t bucketSizeMills = 0;
+    if (metric.has_bucket()) {
+        bucketSizeMills = TimeUnitToBucketSizeInMillis(metric.bucket());
     } else {
-        mBucketSizeNs = kDefaultGaugemBucketSizeNs;
+        bucketSizeMills = TimeUnitToBucketSizeInMillis(ONE_HOUR);
     }
+    mBucketSizeNs = bucketSizeMills * 1000000;
 
     mFieldFilter = metric.gauge_fields_filter();
 
@@ -88,8 +90,7 @@
 
     // Kicks off the puller immediately.
     if (mPullTagId != -1) {
-        mStatsPullerManager->RegisterReceiver(mPullTagId, this,
-                                              metric.bucket().bucket_size_millis());
+        mStatsPullerManager->RegisterReceiver(mPullTagId, this, bucketSizeMills);
     }
 
     VLOG("metric %lld created. bucket size %lld start_time: %lld", (long long)metric.id(),
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.h b/cmds/statsd/src/metrics/GaugeMetricProducer.h
index 2a6401d..fdf8e61 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.h
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.h
@@ -86,9 +86,6 @@
     // Util function to flush the old packet.
     void flushIfNeededLocked(const uint64_t& eventTime);
 
-    // The default bucket size for gauge metric is 1 hr.
-    static const uint64_t kDefaultGaugemBucketSizeNs = 60ULL * 60 * 1000 * 1000 * 1000;
-
     std::shared_ptr<StatsPullerManager> mStatsPullerManager;
     // tagId for pulled data. -1 if this is not pulled
     const int mPullTagId;
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
index 5f7d761..74bd6f9 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
@@ -61,8 +61,6 @@
 const int FIELD_ID_END_BUCKET_NANOS = 2;
 const int FIELD_ID_VALUE = 3;
 
-static const uint64_t kDefaultBucketSizeMillis = 60 * 60 * 1000L;
-
 // ValueMetric has a minimum bucket size of 10min so that we don't pull too frequently
 ValueMetricProducer::ValueMetricProducer(const ConfigKey& key, const ValueMetric& metric,
                                          const int conditionIndex,
@@ -74,12 +72,14 @@
       mStatsPullerManager(statsPullerManager),
       mPullTagId(pullTagId) {
     // TODO: valuemetric for pushed events may need unlimited bucket length
-    if (metric.has_bucket() && metric.bucket().has_bucket_size_millis()) {
-        mBucketSizeNs = metric.bucket().bucket_size_millis() * 1000 * 1000;
+    int64_t bucketSizeMills = 0;
+    if (metric.has_bucket()) {
+        bucketSizeMills = TimeUnitToBucketSizeInMillis(metric.bucket());
     } else {
-        mBucketSizeNs = kDefaultBucketSizeMillis * 1000 * 1000;
+        bucketSizeMills = TimeUnitToBucketSizeInMillis(ONE_HOUR);
     }
 
+    mBucketSizeNs = bucketSizeMills * 1000000;
     mDimensions = metric.dimensions();
 
     if (metric.links().size() > 0) {
@@ -90,8 +90,7 @@
 
     if (!metric.has_condition() && mPullTagId != -1) {
         VLOG("Setting up periodic pulling for %d", mPullTagId);
-        mStatsPullerManager->RegisterReceiver(mPullTagId, this,
-                                              metric.bucket().bucket_size_millis());
+        mStatsPullerManager->RegisterReceiver(mPullTagId, this, bucketSizeMills);
     }
     VLOG("value metric %lld created. bucket size %lld start_time: %lld",
         (long long)metric.id(), (long long)mBucketSizeNs, (long long)mStartTimeNs);
diff --git a/cmds/statsd/src/stats_log_util.cpp b/cmds/statsd/src/stats_log_util.cpp
index 476e117..b335b58 100644
--- a/cmds/statsd/src/stats_log_util.cpp
+++ b/cmds/statsd/src/stats_log_util.cpp
@@ -218,8 +218,34 @@
         protoOutput->end(tokenStack.top().first);
         tokenStack.pop();
     }
+}
 
-
+int64_t TimeUnitToBucketSizeInMillis(TimeUnit unit) {
+    switch (unit) {
+        case ONE_MINUTE:
+            return 60 * 1000LL;
+        case FIVE_MINUTES:
+            return 5 * 60 * 1000LL;
+        case TEN_MINUTES:
+            return 10 * 60 * 1000LL;
+        case THIRTY_MINUTES:
+            return 30 * 60 * 1000LL;
+        case ONE_HOUR:
+            return 60 * 60 * 1000LL;
+        case THREE_HOURS:
+            return 3 * 60 * 60 * 1000LL;
+        case SIX_HOURS:
+            return 6 * 60 * 60 * 1000LL;
+        case TWELVE_HOURS:
+            return 12 * 60 * 60 * 1000LL;
+        case ONE_DAY:
+            return 24 * 60 * 60 * 1000LL;
+        case CTS:
+            return 1000;
+        case TIME_UNIT_UNSPECIFIED:
+        default:
+            return -1;
+    }
 }
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/stats_log_util.h b/cmds/statsd/src/stats_log_util.h
index 1f81860..33303dc 100644
--- a/cmds/statsd/src/stats_log_util.h
+++ b/cmds/statsd/src/stats_log_util.h
@@ -17,6 +17,7 @@
 #pragma once
 
 #include <android/util/ProtoOutputStream.h>
+#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
 #include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
 #include "field_util.h"
 
@@ -36,6 +37,9 @@
 void writeFieldValueTreeToStream(const FieldValueMap &fieldValueMap,
     util::ProtoOutputStream* protoOutput);
 
+// Convert the TimeUnit enum to the bucket size in millis.
+int64_t TimeUnitToBucketSizeInMillis(TimeUnit unit);
+
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
\ No newline at end of file
diff --git a/cmds/statsd/src/statsd_config.proto b/cmds/statsd/src/statsd_config.proto
index a5057da..31beef4 100644
--- a/cmds/statsd/src/statsd_config.proto
+++ b/cmds/statsd/src/statsd_config.proto
@@ -29,6 +29,20 @@
     ANY = 3;
 }
 
+enum TimeUnit {
+    TIME_UNIT_UNSPECIFIED = 0;
+    ONE_MINUTE = 1;
+    FIVE_MINUTES = 2;
+    TEN_MINUTES = 3;
+    THIRTY_MINUTES = 4;
+    ONE_HOUR = 5;
+    THREE_HOURS = 6;
+    SIX_HOURS = 7;
+    TWELVE_HOURS = 8;
+    ONE_DAY = 9;
+    CTS = 1000;
+}
+
 message FieldMatcher {
     optional int32 field = 1;
 
@@ -166,7 +180,7 @@
 
     optional FieldMatcher dimensions = 4;
 
-    optional Bucket bucket = 5;
+    optional TimeUnit bucket = 5;
 
     repeated MetricConditionLink links = 6;
 }
@@ -189,7 +203,7 @@
 
     optional FieldMatcher dimensions = 6;
 
-    optional Bucket bucket = 7;
+    optional TimeUnit bucket = 7;
 }
 
 message GaugeMetric {
@@ -203,7 +217,7 @@
 
     optional FieldMatcher dimensions = 5;
 
-    optional Bucket bucket = 6;
+    optional TimeUnit bucket = 6;
 
     repeated MetricConditionLink links = 7;
 }
@@ -219,7 +233,7 @@
 
     optional FieldMatcher dimensions = 5;
 
-    optional Bucket bucket = 6;
+    optional TimeUnit bucket = 6;
 
     repeated MetricConditionLink links = 7;