diff options
author | Chenjie Yu <cjyu@google.com> | 2018-09-14 15:54:59 -0700 |
---|---|---|
committer | Chenjie Yu <cjyu@google.com> | 2018-09-18 16:29:52 -0700 |
commit | 12e5e6755f0aca0fbd03419f6b11987c2d8be3c8 (patch) | |
tree | 3d5449ee015d4ba8bdf0cf3fe4110b95df66cb66 /libs/services | |
parent | cbf34a2318cf633c1b47601edd9f888d1d36eacb (diff) |
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
Diffstat (limited to 'libs/services')
-rw-r--r-- | libs/services/include/android/os/StatsLogEventWrapper.h | 70 | ||||
-rw-r--r-- | libs/services/src/os/StatsLogEventWrapper.cpp | 65 |
2 files changed, 129 insertions, 6 deletions
diff --git a/libs/services/include/android/os/StatsLogEventWrapper.h b/libs/services/include/android/os/StatsLogEventWrapper.h index 255619c6226c..52cb75e8e639 100644 --- a/libs/services/include/android/os/StatsLogEventWrapper.h +++ b/libs/services/include/android/os/StatsLogEventWrapper.h @@ -25,6 +25,58 @@ namespace android { namespace os { +/** + * A wrapper for a union type to contain multiple types of values. + * + */ +struct StatsLogValue { + // Keep in sync with FieldValue.h + enum STATS_LOG_VALUE_TYPE { + UNKNOWN = 0, + INT = 1, + LONG = 2, + FLOAT = 3, + DOUBLE = 4, + STRING = 5, + STORAGE = 6 + }; + + StatsLogValue() : type(UNKNOWN) {} + + StatsLogValue(int32_t v) { + int_value = v; + type = INT; + } + + StatsLogValue(int64_t v) { + long_value = v; + type = LONG; + } + + StatsLogValue(float v) { + float_value = v; + type = FLOAT; + } + + StatsLogValue(const std::string& v) { + str_value = v; + type = STRING; + } + + void setType(STATS_LOG_VALUE_TYPE t) { type = t; } + + union { + int32_t int_value; + int64_t long_value; + float float_value; + double double_value; + }; + std::string str_value; + std::vector<uint8_t> storage_value; + + STATS_LOG_VALUE_TYPE type; +}; + // Represents a parcelable object. Only used to send data from Android OS to statsd. class StatsLogEventWrapper : public android::Parcelable { public: @@ -36,8 +88,22 @@ class StatsLogEventWrapper : public android::Parcelable { android::status_t readFromParcel(const android::Parcel* in); - // These are public for ease of conversion. - std::vector<uint8_t> bytes; + int getTagId() const { return mTagId; } + + int64_t getElapsedRealTimeNs() const { return mElapsedRealTimeNs; } + + int64_t getWallClockTimeNs() const { return mWallClockTimeNs; } + + std::vector<StatsLogValue> getElements() const { return mElements; } + + private: + int mTagId; + + int64_t mElapsedRealTimeNs; + + int64_t mWallClockTimeNs; + + std::vector<StatsLogValue> mElements; }; } // Namespace os } // Namespace android diff --git a/libs/services/src/os/StatsLogEventWrapper.cpp b/libs/services/src/os/StatsLogEventWrapper.cpp index 8b3aa9ab4257..04c4629b5432 100644 --- a/libs/services/src/os/StatsLogEventWrapper.cpp +++ b/libs/services/src/os/StatsLogEventWrapper.cpp @@ -32,13 +32,70 @@ namespace os { StatsLogEventWrapper::StatsLogEventWrapper(){}; status_t StatsLogEventWrapper::writeToParcel(Parcel* out) const { - out->writeByteVector(bytes); - return ::android::NO_ERROR; + // Implement me if desired. We don't currently use this. + ALOGE( + "Cannot do c++ StatsLogEventWrapper.writeToParcel(); it is not " + "implemented."); + (void)out; // To prevent compile error of unused parameter 'in' + return UNKNOWN_ERROR; }; status_t StatsLogEventWrapper::readFromParcel(const Parcel* in) { - in->readByteVector(&bytes); - return ::android::NO_ERROR; + status_t res = OK; + if (in == NULL) { + ALOGE("statsd received parcel argument was NULL."); + return BAD_VALUE; + } + if ((res = in->readInt32(&mTagId)) != OK) { + ALOGE("statsd could not read tagId from parcel"); + return res; + } + if ((res = in->readInt64(&mElapsedRealTimeNs)) != OK) { + ALOGE("statsd could not read elapsed real time from parcel"); + return res; + } + if ((res = in->readInt64(&mWallClockTimeNs)) != OK) { + ALOGE("statsd could not read wall clock time from parcel"); + return res; + } + int dataSize = 0; + if ((res = in->readInt32(&dataSize)) != OK) { + ALOGE("statsd could not read data size from parcel"); + return res; + } + if (mTagId <= 0 || mElapsedRealTimeNs <= 0 || mWallClockTimeNs <= 0 || + dataSize <= 0) { + ALOGE("statsd received invalid parcel"); + return BAD_VALUE; + } + + for (int i = 0; i < dataSize; i++) { + int type = in->readInt32(); + switch (type) { + case StatsLogValue::INT: + mElements.push_back(StatsLogValue(in->readInt32())); + break; + case StatsLogValue::LONG: + mElements.push_back(StatsLogValue(in->readInt64())); + break; + case StatsLogValue::STRING: + mElements.push_back( + StatsLogValue(std::string(String8(in->readString16()).string()))); + break; + case StatsLogValue::FLOAT: + mElements.push_back(StatsLogValue(in->readFloat())); + break; + case StatsLogValue::STORAGE: + mElements.push_back(StatsLogValue()); + mElements.back().setType(StatsLogValue::STORAGE); + in->readByteVector(&(mElements.back().storage_value)); + break; + default: + ALOGE("unrecognized data type: %d", type); + return BAD_TYPE; + } + } + return NO_ERROR; }; } // Namespace os |