summaryrefslogtreecommitdiff
path: root/cmds/statsd/src/logd/LogEvent.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cmds/statsd/src/logd/LogEvent.cpp')
-rw-r--r--cmds/statsd/src/logd/LogEvent.cpp599
1 files changed, 0 insertions, 599 deletions
diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp
deleted file mode 100644
index f56fa6221bc9..000000000000
--- a/cmds/statsd/src/logd/LogEvent.cpp
+++ /dev/null
@@ -1,599 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "logd/LogEvent.h"
-
-#include <android-base/stringprintf.h>
-#include <android/binder_ibinder.h>
-#include <private/android_filesystem_config.h>
-
-#include "annotations.h"
-#include "stats_log_util.h"
-#include "statslog_statsd.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// for TrainInfo experiment id serialization
-const int FIELD_ID_EXPERIMENT_ID = 1;
-
-using namespace android::util;
-using android::base::StringPrintf;
-using android::util::ProtoOutputStream;
-using std::string;
-using std::vector;
-
-// stats_event.h socket types. Keep in sync.
-/* ERRORS */
-#define ERROR_NO_TIMESTAMP 0x1
-#define ERROR_NO_ATOM_ID 0x2
-#define ERROR_OVERFLOW 0x4
-#define ERROR_ATTRIBUTION_CHAIN_TOO_LONG 0x8
-#define ERROR_TOO_MANY_KEY_VALUE_PAIRS 0x10
-#define ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD 0x20
-#define ERROR_INVALID_ANNOTATION_ID 0x40
-#define ERROR_ANNOTATION_ID_TOO_LARGE 0x80
-#define ERROR_TOO_MANY_ANNOTATIONS 0x100
-#define ERROR_TOO_MANY_FIELDS 0x200
-#define ERROR_INVALID_VALUE_TYPE 0x400
-#define ERROR_STRING_NOT_NULL_TERMINATED 0x800
-
-/* TYPE IDS */
-#define INT32_TYPE 0x00
-#define INT64_TYPE 0x01
-#define STRING_TYPE 0x02
-#define LIST_TYPE 0x03
-#define FLOAT_TYPE 0x04
-#define BOOL_TYPE 0x05
-#define BYTE_ARRAY_TYPE 0x06
-#define OBJECT_TYPE 0x07
-#define KEY_VALUE_PAIRS_TYPE 0x08
-#define ATTRIBUTION_CHAIN_TYPE 0x09
-#define ERROR_TYPE 0x0F
-
-LogEvent::LogEvent(int32_t uid, int32_t pid)
- : mLogdTimestampNs(time(nullptr)), mLogUid(uid), mLogPid(pid) {
-}
-
-LogEvent::LogEvent(const string& trainName, int64_t trainVersionCode, bool requiresStaging,
- bool rollbackEnabled, bool requiresLowLatencyMonitor, int32_t state,
- const std::vector<uint8_t>& experimentIds, int32_t userId) {
- mLogdTimestampNs = getWallClockNs();
- mElapsedTimestampNs = getElapsedRealtimeNs();
- mTagId = util::BINARY_PUSH_STATE_CHANGED;
- mLogUid = AIBinder_getCallingUid();
- mLogPid = AIBinder_getCallingPid();
-
- mValues.push_back(FieldValue(Field(mTagId, getSimpleField(1)), Value(trainName)));
- mValues.push_back(FieldValue(Field(mTagId, getSimpleField(2)), Value(trainVersionCode)));
- mValues.push_back(FieldValue(Field(mTagId, getSimpleField(3)), Value((int)requiresStaging)));
- mValues.push_back(FieldValue(Field(mTagId, getSimpleField(4)), Value((int)rollbackEnabled)));
- mValues.push_back(
- FieldValue(Field(mTagId, getSimpleField(5)), Value((int)requiresLowLatencyMonitor)));
- mValues.push_back(FieldValue(Field(mTagId, getSimpleField(6)), Value(state)));
- mValues.push_back(FieldValue(Field(mTagId, getSimpleField(7)), Value(experimentIds)));
- mValues.push_back(FieldValue(Field(mTagId, getSimpleField(8)), Value(userId)));
-}
-
-LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
- const InstallTrainInfo& trainInfo) {
- mLogdTimestampNs = wallClockTimestampNs;
- mElapsedTimestampNs = elapsedTimestampNs;
- mTagId = util::TRAIN_INFO;
-
- mValues.push_back(
- FieldValue(Field(mTagId, getSimpleField(1)), Value(trainInfo.trainVersionCode)));
- std::vector<uint8_t> experimentIdsProto;
- writeExperimentIdsToProto(trainInfo.experimentIds, &experimentIdsProto);
- mValues.push_back(FieldValue(Field(mTagId, getSimpleField(2)), Value(experimentIdsProto)));
- mValues.push_back(FieldValue(Field(mTagId, getSimpleField(3)), Value(trainInfo.trainName)));
- mValues.push_back(FieldValue(Field(mTagId, getSimpleField(4)), Value(trainInfo.status)));
-}
-
-void LogEvent::parseInt32(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) {
- int32_t value = readNextValue<int32_t>();
- addToValues(pos, depth, value, last);
- parseAnnotations(numAnnotations);
-}
-
-void LogEvent::parseInt64(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) {
- int64_t value = readNextValue<int64_t>();
- addToValues(pos, depth, value, last);
- parseAnnotations(numAnnotations);
-}
-
-void LogEvent::parseString(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) {
- int32_t numBytes = readNextValue<int32_t>();
- if ((uint32_t)numBytes > mRemainingLen) {
- mValid = false;
- return;
- }
-
- string value = string((char*)mBuf, numBytes);
- mBuf += numBytes;
- mRemainingLen -= numBytes;
- addToValues(pos, depth, value, last);
- parseAnnotations(numAnnotations);
-}
-
-void LogEvent::parseFloat(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) {
- float value = readNextValue<float>();
- addToValues(pos, depth, value, last);
- parseAnnotations(numAnnotations);
-}
-
-void LogEvent::parseBool(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) {
- // cast to int32_t because FieldValue does not support bools
- int32_t value = (int32_t)readNextValue<uint8_t>();
- addToValues(pos, depth, value, last);
- parseAnnotations(numAnnotations);
-}
-
-void LogEvent::parseByteArray(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) {
- int32_t numBytes = readNextValue<int32_t>();
- if ((uint32_t)numBytes > mRemainingLen) {
- mValid = false;
- return;
- }
-
- vector<uint8_t> value(mBuf, mBuf + numBytes);
- mBuf += numBytes;
- mRemainingLen -= numBytes;
- addToValues(pos, depth, value, last);
- parseAnnotations(numAnnotations);
-}
-
-void LogEvent::parseKeyValuePairs(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) {
- int32_t numPairs = readNextValue<uint8_t>();
-
- for (pos[1] = 1; pos[1] <= numPairs; pos[1]++) {
- last[1] = (pos[1] == numPairs);
-
- // parse key
- pos[2] = 1;
- parseInt32(pos, /*depth=*/2, last, /*numAnnotations=*/0);
-
- // parse value
- last[2] = true;
-
- uint8_t typeInfo = readNextValue<uint8_t>();
- switch (getTypeId(typeInfo)) {
- case INT32_TYPE:
- pos[2] = 2; // pos[2] determined by index of type in KeyValuePair in atoms.proto
- parseInt32(pos, /*depth=*/2, last, /*numAnnotations=*/0);
- break;
- case INT64_TYPE:
- pos[2] = 3;
- parseInt64(pos, /*depth=*/2, last, /*numAnnotations=*/0);
- break;
- case STRING_TYPE:
- pos[2] = 4;
- parseString(pos, /*depth=*/2, last, /*numAnnotations=*/0);
- break;
- case FLOAT_TYPE:
- pos[2] = 5;
- parseFloat(pos, /*depth=*/2, last, /*numAnnotations=*/0);
- break;
- default:
- mValid = false;
- }
- }
-
- parseAnnotations(numAnnotations);
-
- pos[1] = pos[2] = 1;
- last[1] = last[2] = false;
-}
-
-void LogEvent::parseAttributionChain(int32_t* pos, int32_t depth, bool* last,
- uint8_t numAnnotations) {
- const unsigned int firstUidInChainIndex = mValues.size();
- const int32_t numNodes = readNextValue<uint8_t>();
- for (pos[1] = 1; pos[1] <= numNodes; pos[1]++) {
- last[1] = (pos[1] == numNodes);
-
- // parse uid
- pos[2] = 1;
- parseInt32(pos, /*depth=*/2, last, /*numAnnotations=*/0);
-
- // parse tag
- pos[2] = 2;
- last[2] = true;
- parseString(pos, /*depth=*/2, last, /*numAnnotations=*/0);
- }
- // Check if at least one node was successfully parsed.
- if (mValues.size() - 1 > firstUidInChainIndex) {
- mAttributionChainStartIndex = static_cast<int8_t>(firstUidInChainIndex);
- mAttributionChainEndIndex = static_cast<int8_t>(mValues.size() - 1);
- }
-
- parseAnnotations(numAnnotations, firstUidInChainIndex);
-
- pos[1] = pos[2] = 1;
- last[1] = last[2] = false;
-}
-
-// Assumes that mValues is not empty
-bool LogEvent::checkPreviousValueType(Type expected) {
- return mValues[mValues.size() - 1].mValue.getType() == expected;
-}
-
-void LogEvent::parseIsUidAnnotation(uint8_t annotationType) {
- if (mValues.empty() || !checkPreviousValueType(INT) || annotationType != BOOL_TYPE) {
- mValid = false;
- return;
- }
-
- bool isUid = readNextValue<uint8_t>();
- if (isUid) mUidFieldIndex = static_cast<int8_t>(mValues.size() - 1);
- mValues[mValues.size() - 1].mAnnotations.setUidField(isUid);
-}
-
-void LogEvent::parseTruncateTimestampAnnotation(uint8_t annotationType) {
- if (!mValues.empty() || annotationType != BOOL_TYPE) {
- mValid = false;
- return;
- }
-
- mTruncateTimestamp = readNextValue<uint8_t>();
-}
-
-void LogEvent::parsePrimaryFieldAnnotation(uint8_t annotationType) {
- if (mValues.empty() || annotationType != BOOL_TYPE) {
- mValid = false;
- return;
- }
-
- const bool primaryField = readNextValue<uint8_t>();
- mValues[mValues.size() - 1].mAnnotations.setPrimaryField(primaryField);
-}
-
-void LogEvent::parsePrimaryFieldFirstUidAnnotation(uint8_t annotationType,
- int firstUidInChainIndex) {
- if (mValues.empty() || annotationType != BOOL_TYPE || -1 == firstUidInChainIndex) {
- mValid = false;
- return;
- }
-
- const bool primaryField = readNextValue<uint8_t>();
- mValues[firstUidInChainIndex].mAnnotations.setPrimaryField(primaryField);
-}
-
-void LogEvent::parseExclusiveStateAnnotation(uint8_t annotationType) {
- if (mValues.empty() || annotationType != BOOL_TYPE) {
- mValid = false;
- return;
- }
-
- const bool exclusiveState = readNextValue<uint8_t>();
- mExclusiveStateFieldIndex = static_cast<int8_t>(mValues.size() - 1);
- mValues[getExclusiveStateFieldIndex()].mAnnotations.setExclusiveState(exclusiveState);
-}
-
-void LogEvent::parseTriggerStateResetAnnotation(uint8_t annotationType) {
- if (mValues.empty() || annotationType != INT32_TYPE) {
- mValid = false;
- return;
- }
-
- mResetState = readNextValue<int32_t>();
-}
-
-void LogEvent::parseStateNestedAnnotation(uint8_t annotationType) {
- if (mValues.empty() || annotationType != BOOL_TYPE) {
- mValid = false;
- return;
- }
-
- bool nested = readNextValue<uint8_t>();
- mValues[mValues.size() - 1].mAnnotations.setNested(nested);
-}
-
-// firstUidInChainIndex is a default parameter that is only needed when parsing
-// annotations for attribution chains.
-void LogEvent::parseAnnotations(uint8_t numAnnotations, int firstUidInChainIndex) {
- for (uint8_t i = 0; i < numAnnotations; i++) {
- uint8_t annotationId = readNextValue<uint8_t>();
- uint8_t annotationType = readNextValue<uint8_t>();
-
- switch (annotationId) {
- case ANNOTATION_ID_IS_UID:
- parseIsUidAnnotation(annotationType);
- break;
- case ANNOTATION_ID_TRUNCATE_TIMESTAMP:
- parseTruncateTimestampAnnotation(annotationType);
- break;
- case ANNOTATION_ID_PRIMARY_FIELD:
- parsePrimaryFieldAnnotation(annotationType);
- break;
- case ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID:
- parsePrimaryFieldFirstUidAnnotation(annotationType, firstUidInChainIndex);
- break;
- case ANNOTATION_ID_EXCLUSIVE_STATE:
- parseExclusiveStateAnnotation(annotationType);
- break;
- case ANNOTATION_ID_TRIGGER_STATE_RESET:
- parseTriggerStateResetAnnotation(annotationType);
- break;
- case ANNOTATION_ID_STATE_NESTED:
- parseStateNestedAnnotation(annotationType);
- break;
- default:
- mValid = false;
- return;
- }
- }
-}
-
-// This parsing logic is tied to the encoding scheme used in StatsEvent.java and
-// stats_event.c
-bool LogEvent::parseBuffer(uint8_t* buf, size_t len) {
- mBuf = buf;
- mRemainingLen = (uint32_t)len;
-
- int32_t pos[] = {1, 1, 1};
- bool last[] = {false, false, false};
-
- // Beginning of buffer is OBJECT_TYPE | NUM_FIELDS | TIMESTAMP | ATOM_ID
- uint8_t typeInfo = readNextValue<uint8_t>();
- if (getTypeId(typeInfo) != OBJECT_TYPE) mValid = false;
-
- uint8_t numElements = readNextValue<uint8_t>();
- if (numElements < 2 || numElements > 127) mValid = false;
-
- typeInfo = readNextValue<uint8_t>();
- if (getTypeId(typeInfo) != INT64_TYPE) mValid = false;
- mElapsedTimestampNs = readNextValue<int64_t>();
- numElements--;
-
- typeInfo = readNextValue<uint8_t>();
- if (getTypeId(typeInfo) != INT32_TYPE) mValid = false;
- mTagId = readNextValue<int32_t>();
- numElements--;
- parseAnnotations(getNumAnnotations(typeInfo)); // atom-level annotations
-
- for (pos[0] = 1; pos[0] <= numElements && mValid; pos[0]++) {
- last[0] = (pos[0] == numElements);
-
- typeInfo = readNextValue<uint8_t>();
- uint8_t typeId = getTypeId(typeInfo);
-
- switch (typeId) {
- case BOOL_TYPE:
- parseBool(pos, /*depth=*/0, last, getNumAnnotations(typeInfo));
- break;
- case INT32_TYPE:
- parseInt32(pos, /*depth=*/0, last, getNumAnnotations(typeInfo));
- break;
- case INT64_TYPE:
- parseInt64(pos, /*depth=*/0, last, getNumAnnotations(typeInfo));
- break;
- case FLOAT_TYPE:
- parseFloat(pos, /*depth=*/0, last, getNumAnnotations(typeInfo));
- break;
- case BYTE_ARRAY_TYPE:
- parseByteArray(pos, /*depth=*/0, last, getNumAnnotations(typeInfo));
- break;
- case STRING_TYPE:
- parseString(pos, /*depth=*/0, last, getNumAnnotations(typeInfo));
- break;
- case KEY_VALUE_PAIRS_TYPE:
- parseKeyValuePairs(pos, /*depth=*/0, last, getNumAnnotations(typeInfo));
- break;
- case ATTRIBUTION_CHAIN_TYPE:
- parseAttributionChain(pos, /*depth=*/0, last, getNumAnnotations(typeInfo));
- break;
- case ERROR_TYPE:
- /* mErrorBitmask =*/ readNextValue<int32_t>();
- mValid = false;
- break;
- default:
- mValid = false;
- break;
- }
- }
-
- if (mRemainingLen != 0) mValid = false;
- mBuf = nullptr;
- return mValid;
-}
-
-uint8_t LogEvent::getTypeId(uint8_t typeInfo) {
- return typeInfo & 0x0F; // type id in lower 4 bytes
-}
-
-uint8_t LogEvent::getNumAnnotations(uint8_t typeInfo) {
- return (typeInfo >> 4) & 0x0F; // num annotations in upper 4 bytes
-}
-
-int64_t LogEvent::GetLong(size_t key, status_t* err) const {
- // TODO(b/110561208): encapsulate the magical operations in Field struct as static functions
- int field = getSimpleField(key);
- for (const auto& value : mValues) {
- if (value.mField.getField() == field) {
- if (value.mValue.getType() == LONG) {
- return value.mValue.long_value;
- } else if (value.mValue.getType() == INT) {
- return value.mValue.int_value;
- } else {
- *err = BAD_TYPE;
- return 0;
- }
- }
- if ((size_t)value.mField.getPosAtDepth(0) > key) {
- break;
- }
- }
-
- *err = BAD_INDEX;
- return 0;
-}
-
-int LogEvent::GetInt(size_t key, status_t* err) const {
- int field = getSimpleField(key);
- for (const auto& value : mValues) {
- if (value.mField.getField() == field) {
- if (value.mValue.getType() == INT) {
- return value.mValue.int_value;
- } else {
- *err = BAD_TYPE;
- return 0;
- }
- }
- if ((size_t)value.mField.getPosAtDepth(0) > key) {
- break;
- }
- }
-
- *err = BAD_INDEX;
- return 0;
-}
-
-const char* LogEvent::GetString(size_t key, status_t* err) const {
- int field = getSimpleField(key);
- for (const auto& value : mValues) {
- if (value.mField.getField() == field) {
- if (value.mValue.getType() == STRING) {
- return value.mValue.str_value.c_str();
- } else {
- *err = BAD_TYPE;
- return 0;
- }
- }
- if ((size_t)value.mField.getPosAtDepth(0) > key) {
- break;
- }
- }
-
- *err = BAD_INDEX;
- return NULL;
-}
-
-bool LogEvent::GetBool(size_t key, status_t* err) const {
- int field = getSimpleField(key);
- for (const auto& value : mValues) {
- if (value.mField.getField() == field) {
- if (value.mValue.getType() == INT) {
- return value.mValue.int_value != 0;
- } else if (value.mValue.getType() == LONG) {
- return value.mValue.long_value != 0;
- } else {
- *err = BAD_TYPE;
- return false;
- }
- }
- if ((size_t)value.mField.getPosAtDepth(0) > key) {
- break;
- }
- }
-
- *err = BAD_INDEX;
- return false;
-}
-
-float LogEvent::GetFloat(size_t key, status_t* err) const {
- int field = getSimpleField(key);
- for (const auto& value : mValues) {
- if (value.mField.getField() == field) {
- if (value.mValue.getType() == FLOAT) {
- return value.mValue.float_value;
- } else {
- *err = BAD_TYPE;
- return 0.0;
- }
- }
- if ((size_t)value.mField.getPosAtDepth(0) > key) {
- break;
- }
- }
-
- *err = BAD_INDEX;
- return 0.0;
-}
-
-std::vector<uint8_t> LogEvent::GetStorage(size_t key, status_t* err) const {
- int field = getSimpleField(key);
- for (const auto& value : mValues) {
- if (value.mField.getField() == field) {
- if (value.mValue.getType() == STORAGE) {
- return value.mValue.storage_value;
- } else {
- *err = BAD_TYPE;
- return vector<uint8_t>();
- }
- }
- if ((size_t)value.mField.getPosAtDepth(0) > key) {
- break;
- }
- }
-
- *err = BAD_INDEX;
- return vector<uint8_t>();
-}
-
-string LogEvent::ToString() const {
- string result;
- result += StringPrintf("{ uid(%d) %lld %lld (%d)", mLogUid, (long long)mLogdTimestampNs,
- (long long)mElapsedTimestampNs, mTagId);
- for (const auto& value : mValues) {
- result +=
- StringPrintf("%#x", value.mField.getField()) + "->" + value.mValue.toString() + " ";
- }
- result += " }";
- return result;
-}
-
-void LogEvent::ToProto(ProtoOutputStream& protoOutput) const {
- writeFieldValueTreeToStream(mTagId, getValues(), &protoOutput);
-}
-
-bool LogEvent::hasAttributionChain(std::pair<int, int>* indexRange) const {
- if (mAttributionChainStartIndex == -1 || mAttributionChainEndIndex == -1) {
- return false;
- }
-
- if (nullptr != indexRange) {
- indexRange->first = static_cast<int>(mAttributionChainStartIndex);
- indexRange->second = static_cast<int>(mAttributionChainEndIndex);
- }
-
- return true;
-}
-
-void writeExperimentIdsToProto(const std::vector<int64_t>& experimentIds,
- std::vector<uint8_t>* protoOut) {
- ProtoOutputStream proto;
- for (const auto& expId : experimentIds) {
- proto.write(FIELD_TYPE_INT64 | FIELD_COUNT_REPEATED | FIELD_ID_EXPERIMENT_ID,
- (long long)expId);
- }
-
- protoOut->resize(proto.size());
- size_t pos = 0;
- sp<ProtoReader> reader = proto.data();
- while (reader->readBuffer() != NULL) {
- size_t toRead = reader->currentToRead();
- std::memcpy(protoOut->data() + pos, reader->readBuffer(), toRead);
- pos += toRead;
- reader->move(toRead);
- }
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android