Add support for linear/enumeration histograms.

Review URL: http://codereview.chromium.org/1747008
diff --git a/metrics/metrics_client.cc b/metrics/metrics_client.cc
index bb67698..ad137be 100644
--- a/metrics/metrics_client.cc
+++ b/metrics/metrics_client.cc
@@ -10,6 +10,7 @@
 int main(int argc, char** argv) {
   bool send_to_autotest = false;
   bool send_to_chrome = true;
+  bool send_enum = false;
   bool secs_to_msecs = false;
   int name_index = 1;
   bool print_usage = false;
@@ -17,7 +18,7 @@
   if (argc >= 3) {
     // Parse arguments
     int flag;
-    while ((flag = getopt(argc, argv, "abt")) != -1) {
+    while ((flag = getopt(argc, argv, "abet")) != -1) {
       switch (flag) {
         case 'a':
           send_to_autotest = true;
@@ -27,6 +28,9 @@
           send_to_chrome = true;
           send_to_autotest = true;
           break;
+        case 'e':
+          send_enum = true;
+          break;
         case 't':
           secs_to_msecs = true;
           break;
@@ -40,17 +44,22 @@
     print_usage = true;
   }
 
-  if ((name_index + 5) != argc) {
+  int num_args = send_enum ? 3 : 5;
+  if ((name_index + num_args) != argc ||
+      (send_enum && secs_to_msecs)) {
     print_usage = true;
   }
 
   if (print_usage) {
     fprintf(stderr,
-            "Usage:  metrics_client [-abt] name sample min max nbuckets\n"
+            "Usage:  metrics_client [-ab] [-t] name sample min max nbuckets\n"
+            "        metrics_client [-ab] -e   name sample max\n"
             "\n"
             "  default: send metric with integer values to Chrome only\n"
-            "  -a: send metric to autotest only (min/max/nbuckets ignored)\n"
-            "  -b: send metric to both chrome and autotest\n"
+            "           |min| > 0, |min| <= sample < |max|\n"
+            "  -a: send metric (name/sample) to Autotest only\n"
+            "  -b: send metric to both Chrome and Autotest\n"
+            "  -e: send linear/enumeration histogram data\n"
             "  -t: convert sample from double seconds to int milliseconds\n");
     return 1;
   }
@@ -62,16 +71,22 @@
   } else {
     sample = atoi(argv[name_index + 1]);
   }
-  int min = atoi(argv[name_index + 2]);
-  int max = atoi(argv[name_index + 3]);
-  int nbuckets = atoi(argv[name_index + 4]);
 
   // Send metrics
   if (send_to_autotest) {
     MetricsLibrary::SendToAutotest(name, sample);
   }
+
   if (send_to_chrome) {
-    MetricsLibrary::SendToChrome(name, sample, min, max, nbuckets);
+    if (send_enum) {
+      int max = atoi(argv[name_index + 2]);
+      MetricsLibrary::SendEnumToChrome(name, sample, max);
+    } else {
+      int min = atoi(argv[name_index + 2]);
+      int max = atoi(argv[name_index + 3]);
+      int nbuckets = atoi(argv[name_index + 4]);
+      MetricsLibrary::SendToChrome(name, sample, min, max, nbuckets);
+    }
   }
   return 0;
 }
diff --git a/metrics/metrics_library.cc b/metrics/metrics_library.cc
index 681cf96..95e78b2 100644
--- a/metrics/metrics_library.cc
+++ b/metrics/metrics_library.cc
@@ -150,3 +150,20 @@
   // Send the message.
   return SendMessageToChrome(message_length, message);
 }
+
+//static
+bool MetricsLibrary::SendEnumToChrome(const std::string& name, int sample,
+                                      int max) {
+  // Format the message.
+  char message[kBufferSize];
+  int32_t message_length =
+      FormatChromeMessage(kBufferSize, message,
+                          "linearhistogram%c%s %d %d", '\0',
+                          name.c_str(), sample, max);
+
+  if (message_length < 0)
+    return false;
+
+  // Send the message.
+  return SendMessageToChrome(message_length, message);
+}
diff --git a/metrics/metrics_library.h b/metrics/metrics_library.h
index 5977e72..7383960 100644
--- a/metrics/metrics_library.h
+++ b/metrics/metrics_library.h
@@ -33,6 +33,17 @@
   static bool SendToChrome(const std::string& name, int sample,
                            int min, int max, int nbuckets);
 
+  // Sends linear histogram data to Chrome for transport to UMA and
+  // returns true on success. This method results in the equivalent of
+  // an asynchronous non-blocking RPC to UMA_HISTOGRAM_ENUMERATION
+  // inside Chrome (see base/histogram.h).
+  //
+  // |sample| is the sample value to be recorded (1 <= |sample| < |max|).
+  // |max| is the maximum value of the histogram samples.
+  // 0 is the implicit underflow bucket.
+  // [|max|,infinity) is the implicit overflow bucket.
+  static bool SendEnumToChrome(const std::string& name, int sample, int max);
+
   // Sends to Autotest and returns true on success.
   static bool SendToAutotest(const std::string& name, int value);
 };