Statsd atom: pull Build information

Pulls Build information, such as Build.ID.

Test: cts-tradefed run cts-dev -m CtsStatsdHostTestCases -t android.cts.statsd.atom.HostAtomTests#testBuildInformation
Bug: 114443697
Change-Id: If1d573dbdc49543d4268f4d62e02b3ea360e75d5
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index ada5d4c..e97d6c3 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -205,6 +205,7 @@
         DeviceCalculatedPowerBlameOther device_calculated_power_blame_other = 10041;
         ProcessMemoryHighWaterMark process_memory_high_water_mark = 10042;
         BatteryLevel battery_level = 10043;
+        BuildInformation build_information = 10044;
     }
 
     // DO NOT USE field numbers above 100,000 in AOSP.
@@ -3331,6 +3332,40 @@
 }
 
 /**
+ * Pulls information about the device's build.
+ */
+message BuildInformation {
+    // Build.FINGERPRINT. A string that uniquely identifies this build. Do not parse.
+    // E.g. may be composed of the brand, product, device, release, id, incremental, type, and tags.
+    optional string fingerprint = 1;
+
+    // Build.BRAND. The consumer-visible brand with which the product/hardware will be associated.
+    optional string brand = 2;
+
+    // Build.PRODUCT. The name of the overall product.
+    optional string product = 3;
+
+    // Build.DEVICE. The name of the industrial design.
+    optional string device = 4;
+
+    // Build.VERSION.RELEASE. The user-visible version string.  E.g., "1.0" or "3.4b5" or "bananas".
+    optional string version_release = 5;
+
+    // Build.ID. E.g. a label like "M4-rc20".
+    optional string id = 6;
+
+    // Build.VERSION.INCREMENTAL. The internal value used by the underlying source control to
+    // represent this build.
+    optional string version_incremental = 7;
+
+    // Build.TYPE. The type of build, like "user" or "eng".
+    optional string type = 8;
+
+    // Build.TAGS. Comma-separated tags describing the build, like "unsigned,debug".
+    optional string tags = 9;
+}
+
+/**
  * Pulls on-device BatteryStats power use calculations for the overall device.
  */
 message DeviceCalculatedPowerUse {
diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp
index ab635a0..87a065b 100644
--- a/cmds/statsd/src/external/StatsPullerManager.cpp
+++ b/cmds/statsd/src/external/StatsPullerManager.cpp
@@ -265,6 +265,11 @@
          {{}, {},
           1 * NS_PER_SEC,
           new StatsCompanionServicePuller(android::util::DEVICE_CALCULATED_POWER_BLAME_OTHER)}},
+        // BuildInformation.
+        {android::util::BUILD_INFORMATION,
+         {{}, {},
+          1 * NS_PER_SEC,
+          new StatsCompanionServicePuller(android::util::BUILD_INFORMATION)}},
 };
 
 StatsPullerManager::StatsPullerManager() : mNextPullTimeNs(NO_ALARM_UPDATE) {
diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java
index 3179ce9..aa11e1e 100644
--- a/services/core/java/com/android/server/stats/StatsCompanionService.java
+++ b/services/core/java/com/android/server/stats/StatsCompanionService.java
@@ -51,6 +51,7 @@
 import android.os.BatteryStats;
 import android.os.BatteryStatsInternal;
 import android.os.Binder;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Environment;
 import android.os.FileUtils;
@@ -1517,6 +1518,21 @@
         pulledData.add(e);
     }
 
+    private void pullBuildInformation(int tagId,
+            long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData) {
+        StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
+        e.writeString(Build.FINGERPRINT);
+        e.writeString(Build.BRAND);
+        e.writeString(Build.PRODUCT);
+        e.writeString(Build.DEVICE);
+        e.writeString(Build.VERSION.RELEASE);
+        e.writeString(Build.ID);
+        e.writeString(Build.VERSION.INCREMENTAL);
+        e.writeString(Build.TYPE);
+        e.writeString(Build.TAGS);
+        pulledData.add(e);
+    }
+
     private BatteryStatsHelper getBatteryStatsHelper() {
         if (mBatteryStatsHelper == null) {
             final long callingToken = Binder.clearCallingIdentity();
@@ -1810,6 +1826,10 @@
                 pullPowerProfile(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
             }
+            case StatsLog.BUILD_INFORMATION: {
+                pullBuildInformation(tagId, elapsedNanos, wallClockNanos, ret);
+                break;
+            }
             case StatsLog.PROCESS_CPU_TIME: {
                 pullProcessCpuTime(tagId, elapsedNanos, wallClockNanos, ret);
                 break;