use custom Parcel format to pull data

When statsd pulls data from StatsCompanionService, the data is put into
log_msg format on java side and expanded into LogEvent on cpp side.
There is a lot of dependency on log_msg and liblog to add new types.
There is pending bug to rewrite thta part of the code in statsd to
completely rid the legacy of logd and liblog. But that may not happen
soon.

Now we can support new storage type.
Also no need to specify number of fields in StatsLogEventWrapper cstr,
which is a source of bug in P.

Bug: 115775035
Test: manual test and cts test
Change-Id: Id1f0b033885da6f3bcebe043968061821db48f35
diff --git a/cmds/statsd/src/FieldValue.cpp b/cmds/statsd/src/FieldValue.cpp
index 7b6d29b..fc1a61c 100644
--- a/cmds/statsd/src/FieldValue.cpp
+++ b/cmds/statsd/src/FieldValue.cpp
@@ -147,6 +147,9 @@
         case STRING:
             str_value = from.str_value;
             break;
+        case STORAGE:
+            storage_value = from.storage_value;
+            break;
         default:
             break;
     }
@@ -164,6 +167,8 @@
             return std::to_string(double_value) + "[D]";
         case STRING:
             return str_value + "[S]";
+        case STORAGE:
+            return "bytes of size " + std::to_string(storage_value.size()) + "[ST]";
         default:
             return "[UNKNOWN]";
     }
@@ -183,6 +188,8 @@
             return double_value == that.double_value;
         case STRING:
             return str_value == that.str_value;
+        case STORAGE:
+            return storage_value == that.storage_value;
         default:
             return false;
     }
@@ -201,6 +208,8 @@
             return double_value != that.double_value;
         case STRING:
             return str_value != that.str_value;
+        case STORAGE:
+            return storage_value != that.storage_value;
         default:
             return false;
     }
@@ -220,6 +229,8 @@
             return double_value < that.double_value;
         case STRING:
             return str_value < that.str_value;
+        case STORAGE:
+            return storage_value < that.storage_value;
         default:
             return false;
     }
@@ -239,6 +250,8 @@
             return double_value > that.double_value;
         case STRING:
             return str_value > that.str_value;
+        case STORAGE:
+            return storage_value > that.storage_value;
         default:
             return false;
     }
@@ -258,6 +271,8 @@
             return double_value >= that.double_value;
         case STRING:
             return str_value >= that.str_value;
+        case STORAGE:
+            return storage_value >= that.storage_value;
         default:
             return false;
     }
@@ -274,6 +289,11 @@
         return v;
     }
 
+    if (type == STORAGE) {
+        ALOGE("Can't operate on storage value type");
+        return v;
+    }
+
     switch (type) {
         case INT:
             v.setInt(int_value - that.int_value);
@@ -311,6 +331,9 @@
         case STRING:
             str_value = that.str_value;
             break;
+        case STORAGE:
+            storage_value = that.storage_value;
+            break;
         default:
             break;
     }
@@ -326,6 +349,10 @@
         ALOGE("Can't operate on string value type");
         return *this;
     }
+    if (type == STORAGE) {
+        ALOGE("Can't operate on storage value type");
+        return *this;
+    }
 
     switch (type) {
         case INT:
diff --git a/cmds/statsd/src/FieldValue.h b/cmds/statsd/src/FieldValue.h
index b1b885e..77163f9 100644
--- a/cmds/statsd/src/FieldValue.h
+++ b/cmds/statsd/src/FieldValue.h
@@ -32,7 +32,7 @@
 const int32_t kClearLastBitDeco = 0x7f;
 const int32_t kClearAllPositionMatcherMask = 0xffff00ff;
 
-enum Type { UNKNOWN, INT, LONG, FLOAT, DOUBLE, STRING };
+enum Type { UNKNOWN, INT, LONG, FLOAT, DOUBLE, STRING, STORAGE };
 
 int32_t getEncodedField(int32_t pos[], int32_t depth, bool includeDepth);
 
@@ -293,6 +293,11 @@
         type = STRING;
     }
 
+    Value(const std::vector<uint8_t>& v) {
+        storage_value = v;
+        type = STORAGE;
+    }
+
     void setInt(int32_t v) {
         int_value = v;
         type = INT;
@@ -320,6 +325,7 @@
         double double_value;
     };
     std::string str_value;
+    std::vector<uint8_t> storage_value;
 
     Type type;
 
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 13ae41d..b8f19ee 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -170,9 +170,9 @@
         DirectoryUsage directory_usage = 10026;
         AppSize app_size = 10027;
         CategorySize category_size = 10028;
-        android.service.procstats.ProcessStatsSectionProto proc_stats = 10029;
         BatteryVoltage battery_voltage = 10030;
         NumFingerprints num_fingerprints = 10031;
+        ProcStats proc_stats = 10029;
     }
 
     // DO NOT USE field numbers above 100,000 in AOSP. Field numbers above
@@ -2479,3 +2479,10 @@
     // Number of fingerprints registered to that user.
     optional int32 num_fingerprints = 2;
 }
+
+/**
+ * Pulled from ProcessStatsService.java
+ */
+message ProcStats {
+    optional android.service.procstats.ProcessStatsSectionProto proc_stats_section = 1;
+}
diff --git a/cmds/statsd/src/external/StatsCompanionServicePuller.cpp b/cmds/statsd/src/external/StatsCompanionServicePuller.cpp
index d953f50..6d7bba0 100644
--- a/cmds/statsd/src/external/StatsCompanionServicePuller.cpp
+++ b/cmds/statsd/src/external/StatsCompanionServicePuller.cpp
@@ -36,8 +36,6 @@
 namespace os {
 namespace statsd {
 
-const int kLogMsgHeaderSize = 28;
-
 // The reading and parsing are implemented in Java. It is not difficult to port over. But for now
 // let StatsCompanionService handle that and send the data back.
 StatsCompanionServicePuller::StatsCompanionServicePuller(int tagId) : StatsPuller(tagId) {
@@ -56,20 +54,12 @@
         vector<StatsLogEventWrapper> returned_value;
         Status status = statsCompanionServiceCopy->pullData(mTagId, &returned_value);
         if (!status.isOk()) {
-            ALOGW("error pulling for %d", mTagId);
+            ALOGW("StatsCompanionServicePuller::pull failed to pull for %d", mTagId);
             return false;
         }
         data->clear();
-        int32_t timestampSec = getWallClockSec();
         for (const StatsLogEventWrapper& it : returned_value) {
-            log_msg tmp;
-            tmp.entry_v1.len = it.bytes.size();
-            // Manually set the header size to 28 bytes to match the pushed log events.
-            tmp.entry.hdr_size = kLogMsgHeaderSize;
-            tmp.entry_v1.sec = timestampSec;
-            // And set the received bytes starting after the 28 bytes reserved for header.
-            std::copy(it.bytes.begin(), it.bytes.end(), tmp.buf + kLogMsgHeaderSize);
-            data->push_back(make_shared<LogEvent>(tmp));
+            data->push_back(make_shared<LogEvent>(it));
         }
         VLOG("StatsCompanionServicePuller::pull succeeded for %d", mTagId);
         return true;
diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp
index c23d65e..5a0172b 100644
--- a/cmds/statsd/src/external/StatsPullerManager.cpp
+++ b/cmds/statsd/src/external/StatsPullerManager.cpp
@@ -195,22 +195,13 @@
           new StatsCompanionServicePuller(android::util::LOOPER_STATS)}},
         // Disk Stats
         {android::util::DISK_STATS,
-         {{},
-          {},
-          1 * NS_PER_SEC,
-          new StatsCompanionServicePuller(android::util::DISK_STATS)}},
+         {{}, {}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::DISK_STATS)}},
         // Directory usage
         {android::util::DIRECTORY_USAGE,
-         {{},
-          {},
-          1 * NS_PER_SEC,
-          new StatsCompanionServicePuller(android::util::DIRECTORY_USAGE)}},
+         {{}, {}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::DIRECTORY_USAGE)}},
         // Size of app's code, data, and cache
         {android::util::APP_SIZE,
-         {{},
-          {},
-          1 * NS_PER_SEC,
-          new StatsCompanionServicePuller(android::util::APP_SIZE)}},
+         {{}, {}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::APP_SIZE)}},
         // Size of specific categories of files. Eg. Music.
         {android::util::CATEGORY_SIZE,
          {{},
diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp
index cf04ee3..f9f1b38 100644
--- a/cmds/statsd/src/logd/LogEvent.cpp
+++ b/cmds/statsd/src/logd/LogEvent.cpp
@@ -41,6 +41,44 @@
     }
 }
 
+LogEvent::LogEvent(const StatsLogEventWrapper& statsLogEventWrapper) {
+    mTagId = statsLogEventWrapper.getTagId();
+    mLogdTimestampNs = statsLogEventWrapper.getWallClockTimeNs();
+    mElapsedTimestampNs = statsLogEventWrapper.getElapsedRealTimeNs();
+    mLogUid = 0;
+    for (int i = 0; i < (int)statsLogEventWrapper.getElements().size(); i++) {
+        Field field(statsLogEventWrapper.getTagId(), getSimpleField(i + 1));
+        switch (statsLogEventWrapper.getElements()[i].type) {
+            case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::INT:
+                mValues.push_back(
+                        FieldValue(field, Value(statsLogEventWrapper.getElements()[i].int_value)));
+                break;
+            case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::LONG:
+                mValues.push_back(
+                        FieldValue(field, Value(statsLogEventWrapper.getElements()[i].long_value)));
+                break;
+            case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::FLOAT:
+                mValues.push_back(FieldValue(
+                        field, Value(statsLogEventWrapper.getElements()[i].float_value)));
+                break;
+            case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::DOUBLE:
+                mValues.push_back(FieldValue(
+                        field, Value(statsLogEventWrapper.getElements()[i].double_value)));
+                break;
+            case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::STRING:
+                mValues.push_back(
+                        FieldValue(field, Value(statsLogEventWrapper.getElements()[i].str_value)));
+                break;
+            case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::STORAGE:
+                mValues.push_back(FieldValue(
+                        field, Value(statsLogEventWrapper.getElements()[i].storage_value)));
+                break;
+            default:
+                break;
+        }
+    }
+}
+
 LogEvent::LogEvent(int32_t tagId, int64_t wallClockTimestampNs, int64_t elapsedTimestampNs) {
     mLogdTimestampNs = wallClockTimestampNs;
     mTagId = tagId;
diff --git a/cmds/statsd/src/logd/LogEvent.h b/cmds/statsd/src/logd/LogEvent.h
index 2ee6bdf..9ef0bf4 100644
--- a/cmds/statsd/src/logd/LogEvent.h
+++ b/cmds/statsd/src/logd/LogEvent.h
@@ -18,6 +18,7 @@
 
 #include "FieldValue.h"
 
+#include <android/os/StatsLogEventWrapper.h>
 #include <android/util/ProtoOutputStream.h>
 #include <log/log_event_list.h>
 #include <log/log_read.h>
@@ -61,6 +62,8 @@
      */
     explicit LogEvent(log_msg& msg);
 
+    explicit LogEvent(const StatsLogEventWrapper& statsLogEventWrapper);
+
     /**
      * Constructs a LogEvent with synthetic data for testing. Must call init() before reading.
      */
diff --git a/cmds/statsd/src/stats_log_util.cpp b/cmds/statsd/src/stats_log_util.cpp
index a0ab3e4..805e583 100644
--- a/cmds/statsd/src/stats_log_util.cpp
+++ b/cmds/statsd/src/stats_log_util.cpp
@@ -322,6 +322,11 @@
                 case STRING:
                     protoOutput->write(FIELD_TYPE_STRING | fieldNum, dim.mValue.str_value);
                     break;
+                case STORAGE:
+                    protoOutput->write(FIELD_TYPE_MESSAGE | fieldNum,
+                                       (const char*)dim.mValue.storage_value.data(),
+                                       dim.mValue.storage_value.size());
+                    break;
                 default:
                     break;
             }