diff --git a/cmds/statsd/src/annotations.h b/cmds/statsd/src/annotations.h index 1e9390e49ae19..cf7f5433663f5 100644 --- a/cmds/statsd/src/annotations.h +++ b/cmds/statsd/src/annotations.h @@ -22,13 +22,11 @@ namespace statsd { const uint8_t ANNOTATION_ID_IS_UID = 1; const uint8_t ANNOTATION_ID_TRUNCATE_TIMESTAMP = 2; -const uint8_t ANNOTATION_ID_STATE_OPTION = 3; -const uint8_t ANNOTATION_ID_RESET_STATE = 5; -const uint8_t ANNOTATION_ID_STATE_NESTED = 6; - -const int32_t STATE_OPTION_PRIMARY_FIELD = 1; -const int32_t STATE_OPTION_EXCLUSIVE_STATE = 2; -const int32_t STATE_OPTION_PRIMARY_FIELD_FIRST_UID = 3; +const uint8_t ANNOTATION_ID_PRIMARY_FIELD = 3; +const uint8_t ANNOTATION_ID_EXCLUSIVE_STATE = 4; +const uint8_t ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID = 5; +const uint8_t ANNOTATION_ID_TRIGGER_STATE_RESET = 7; +const uint8_t ANNOTATION_ID_STATE_NESTED = 8; } // namespace statsd } // namespace os diff --git a/cmds/statsd/src/atom_field_options.proto b/cmds/statsd/src/atom_field_options.proto index afee79d7506bf..8527185d38910 100644 --- a/cmds/statsd/src/atom_field_options.proto +++ b/cmds/statsd/src/atom_field_options.proto @@ -23,25 +23,12 @@ option java_outer_classname = "AtomFieldOptions"; import "google/protobuf/descriptor.proto"; -enum StateField { - // Default value for fields that are not a primary or exclusive state field. - STATE_FIELD_UNSET = 0; - // Fields that represent the key that the state belongs to. - // Used on simple proto fields. Do not use on attribution chains. - PRIMARY_FIELD = 1; - // The field that represents the state. It's an exclusive state. - EXCLUSIVE_STATE = 2; - // Used on an attribution chain field to indicate that the first uid is the - // primary field. - PRIMARY_FIELD_FIRST_UID = 3; -} - // Used to annotate an atom that represents a state change. A state change atom must have exactly // ONE exclusive state field, and any number of primary key fields. For example, message // UidProcessStateChanged { -// optional int32 uid = 1 [(state_field_option).option = PRIMARY_FIELD]; -// optional android.app.ProcessStateEnum state = 2 [(state_field_option).option = -// EXCLUSIVE_STATE]; +// optional int32 uid = 1 [(state_field_option).primary_field = true]; +// optional android.app.ProcessStateEnum state = +// 2 [(state_field_option).exclusive_state = true]; // } // Each UidProcessStateChanged atom event represents a state change for a specific uid. // A new state automatically overrides the previous state. @@ -50,23 +37,23 @@ enum StateField { // primary fields are the primary key. // For example: // message ThreadStateChanged { -// optional int32 pid = 1 [(state_field_option).option = PRIMARY_FIELD]; -// optional int32 tid = 2 [(state_field_option).option = PRIMARY_FIELD]; -// optional int32 state = 3 [(state_field_option).option = EXCLUSIVE_STATE]; +// optional int32 pid = 1 [(state_field_option).primary_field = true]; +// optional int32 tid = 2 [(state_field_option).primary_field = true]; +// optional int32 state = 3 [(state_field_option).exclusive_state = true]; // } // // Sometimes, there is no primary key field, when the state is GLOBAL. // For example, // message ScreenStateChanged { -// optional android.view.DisplayStateEnum state = 1 [(state_field_option).option = -// EXCLUSIVE_STATE]; +// optional android.view.DisplayStateEnum state = +// 1 [(state_field_option).exclusive_state = true]; // } // // For state atoms with attribution chain, sometimes the primary key is the first uid in the chain. // For example: // message AudioStateChanged { // repeated AttributionNode attribution_node = 1 -// [(stateFieldOption).option = PRIMARY_KEY_FIRST_UID]; +// [(stateFieldOption).primary_field_first_uid = true]; // // enum State { // OFF = 0; @@ -74,10 +61,19 @@ enum StateField { // // RESET indicates all audio stopped. Used when it (re)starts (e.g. after it crashes). // RESET = 2; // } -// optional State state = 2 [(stateFieldOption).option = EXCLUSIVE_STATE]; +// optional State state = 2 [(stateFieldOption).exclusive_state = true]; // } message StateAtomFieldOption { - optional StateField option = 1 [default = STATE_FIELD_UNSET]; + // Fields that represent the key that the state belongs to. + // Used on simple proto fields. Do not use on attribution chains. + optional bool primary_field = 1 [default = false]; + + // The field that represents the state. It's an exclusive state. + optional bool exclusive_state = 2 [default = false]; + + // Used on an attribution chain field to indicate that the first uid is the + // primary field. + optional bool primary_field_first_uid = 3 [default = false]; // Note: We cannot annotate directly on the enums because many enums are imported from other // proto files in the platform. proto-lite cc library does not support annotations unfortunately @@ -85,14 +81,14 @@ message StateAtomFieldOption { // Knowing the default state value allows state trackers to remove entries that become the // default state. If there is no default value specified, the default value is unknown, and all // states will be tracked in memory. - optional int32 default_state_value = 2; + optional int32 default_state_value = 4; // A reset state signals all states go to default value. For example, BLE reset means all active // BLE scans are to be turned off. - optional int32 reset_state_value = 3; + optional int32 trigger_state_reset_value = 5; // If the state change needs to count nesting. - optional bool nested = 4 [default = true]; + optional bool nested = 6 [default = true]; } // Used to generate StatsLog.write APIs. diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index 5cd00c35b05c1..c7dbf77652866 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -610,7 +610,7 @@ message ThermalThrottlingStateChanged { message ScreenStateChanged { // New screen state, from frameworks/base/core/proto/android/view/enums.proto. optional android.view.DisplayStateEnum state = 1 - [(state_field_option).option = EXCLUSIVE_STATE, (state_field_option).nested = false]; + [(state_field_option).exclusive_state = true, (state_field_option).nested = false]; } /** @@ -621,11 +621,11 @@ message ScreenStateChanged { * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java */ message UidProcessStateChanged { - optional int32 uid = 1 [(state_field_option).option = PRIMARY_FIELD, (is_uid) = true]; + optional int32 uid = 1 [(state_field_option).primary_field = true, (is_uid) = true]; // The state, from frameworks/base/core/proto/android/app/enums.proto. optional android.app.ProcessStateEnum state = 2 - [(state_field_option).option = EXCLUSIVE_STATE, (state_field_option).nested = false]; + [(state_field_option).exclusive_state = true, (state_field_option).nested = false]; } /** @@ -657,7 +657,7 @@ message ActivityManagerSleepStateChanged { ASLEEP = 1; AWAKE = 2; } - optional State state = 1 [(state_field_option).option = EXCLUSIVE_STATE]; + optional State state = 1 [(state_field_option).exclusive_state = true]; } /** @@ -676,7 +676,7 @@ message MemoryFactorStateChanged { CRITICAL = 4; // critical memory. } - optional State factor = 1 [(state_field_option).option = EXCLUSIVE_STATE]; + optional State factor = 1 [(state_field_option).exclusive_state = true]; } /** @@ -854,7 +854,7 @@ message ProcessLifeCycleStateChanged { */ message BleScanStateChanged { repeated AttributionNode attribution_node = 1 - [(state_field_option).option = PRIMARY_FIELD_FIRST_UID]; + [(state_field_option).primary_field_first_uid = true]; enum State { OFF = 0; @@ -863,18 +863,18 @@ message BleScanStateChanged { RESET = 2; } optional State state = 2 [ - (state_field_option).option = EXCLUSIVE_STATE, + (state_field_option).exclusive_state = true, (state_field_option).default_state_value = 0 /* State.OFF */, - (state_field_option).reset_state_value = 2 /* State.RESET */, + (state_field_option).trigger_state_reset_value = 2 /* State.RESET */, (state_field_option).nested = true ]; // Does the scan have a filter. - optional bool is_filtered = 3 [(state_field_option).option = PRIMARY_FIELD]; + optional bool is_filtered = 3 [(state_field_option).primary_field = true]; // Whether the scan is a CALLBACK_TYPE_FIRST_MATCH scan. Called 'background' scan internally. - optional bool is_first_match = 4 [(state_field_option).option = PRIMARY_FIELD]; + optional bool is_first_match = 4 [(state_field_option).primary_field = true]; // Whether the scan set to piggy-back off the results of other scans (SCAN_MODE_OPPORTUNISTIC). - optional bool is_opportunistic = 5 [(state_field_option).option = PRIMARY_FIELD]; + optional bool is_opportunistic = 5 [(state_field_option).primary_field = true]; } /** @@ -1105,15 +1105,14 @@ message CameraStateChanged { */ message WakelockStateChanged { repeated AttributionNode attribution_node = 1 - [(state_field_option).option = PRIMARY_FIELD_FIRST_UID]; + [(state_field_option).primary_field_first_uid = true]; // The type (level) of the wakelock; e.g. a partial wakelock or a full wakelock. // From frameworks/base/core/proto/android/os/enums.proto. - optional android.os.WakeLockLevelEnum type = 2 [(state_field_option).option = PRIMARY_FIELD]; - ; + optional android.os.WakeLockLevelEnum type = 2 [(state_field_option).primary_field = true]; // The wakelock tag (Called tag in the Java API, sometimes name elsewhere). - optional string tag = 3 [(state_field_option).option = PRIMARY_FIELD]; + optional string tag = 3 [(state_field_option).primary_field = true]; enum State { RELEASE = 0; @@ -1122,7 +1121,7 @@ message WakelockStateChanged { CHANGE_ACQUIRE = 3; } optional State state = 4 [ - (state_field_option).option = EXCLUSIVE_STATE, + (state_field_option).exclusive_state = true, (state_field_option).default_state_value = 0, (state_field_option).nested = true ]; @@ -3494,9 +3493,9 @@ message PictureInPictureStateChanged { * services/core/java/com/android/server/wm/Session.java */ message OverlayStateChanged { - optional int32 uid = 1 [(state_field_option).option = PRIMARY_FIELD, (is_uid) = true]; + optional int32 uid = 1 [(state_field_option).primary_field = true, (is_uid) = true]; - optional string package_name = 2 [(state_field_option).option = PRIMARY_FIELD]; + optional string package_name = 2 [(state_field_option).primary_field = true]; optional bool using_alert_window = 3; @@ -3505,7 +3504,7 @@ message OverlayStateChanged { EXITED = 2; } optional State state = 4 [ - (state_field_option).option = EXCLUSIVE_STATE, + (state_field_option).exclusive_state = true, (state_field_option).nested = false, (state_field_option).default_state_value = 2 ]; @@ -3713,7 +3712,7 @@ message LmkKillOccurred { */ message AppDied { // timestamp(elapsedRealtime) of record creation - optional uint64 timestamp_millis = 1 [(state_field_option).option = EXCLUSIVE_STATE]; + optional uint64 timestamp_millis = 1 [(state_field_option).exclusive_state = true]; } /** @@ -4235,7 +4234,7 @@ message PrivacyIndicatorsInteracted { DIALOG_LINE_ITEM = 5; } - optional Type type = 1 [(state_field_option).option = EXCLUSIVE_STATE]; + optional Type type = 1 [(state_field_option).exclusive_state = true]; // Used if the type is LINE_ITEM optional string package_name = 2; diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp index 0ec11f9268157..96bf04f4f6d61 100644 --- a/cmds/statsd/src/logd/LogEvent.cpp +++ b/cmds/statsd/src/logd/LogEvent.cpp @@ -17,14 +17,14 @@ #define DEBUG false // STOPSHIP if true #include "logd/LogEvent.h" +#include +#include +#include + #include "annotations.h" #include "stats_log_util.h" #include "statslog_statsd.h" -#include -#include -#include - namespace android { namespace os { namespace statsd { @@ -76,9 +76,7 @@ LogEvent::LogEvent(const LogEvent& event) { } LogEvent::LogEvent(int32_t uid, int32_t pid) - : mLogdTimestampNs(time(nullptr)), - mLogUid(uid), - mLogPid(pid) { + : mLogdTimestampNs(time(nullptr)), mLogUid(uid), mLogPid(pid) { } LogEvent::LogEvent(const string& trainName, int64_t trainVersionCode, bool requiresStaging, @@ -193,7 +191,7 @@ void LogEvent::parseKeyValuePairs(int32_t* pos, int32_t depth, bool* last, uint8 uint8_t typeInfo = readNextValue(); switch (getTypeId(typeInfo)) { case INT32_TYPE: - pos[2] = 2; // pos[2] determined by index of type in KeyValuePair in atoms.proto + 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: @@ -261,33 +259,38 @@ void LogEvent::parseTruncateTimestampAnnotation(uint8_t annotationType) { mTruncateTimestamp = readNextValue(); } -void LogEvent::parseStateOptionAnnotation(uint8_t annotationType, int firstUidInChainIndex) { - if (mValues.empty() || annotationType != INT32_TYPE) { +void LogEvent::parsePrimaryFieldAnnotation(uint8_t annotationType) { + if (mValues.empty() || annotationType != BOOL_TYPE) { mValid = false; return; } - int32_t stateOption = readNextValue(); - switch (stateOption) { - case STATE_OPTION_EXCLUSIVE_STATE: - mValues[mValues.size() - 1].mAnnotations.setExclusiveState(true); - break; - case STATE_OPTION_PRIMARY_FIELD: - mValues[mValues.size() - 1].mAnnotations.setPrimaryField(true); - break; - case STATE_OPTION_PRIMARY_FIELD_FIRST_UID: - if (firstUidInChainIndex == -1) { - mValid = false; - } else { - mValues[firstUidInChainIndex].mAnnotations.setPrimaryField(true); - } - break; - default: - mValid = false; - } + const bool primaryField = readNextValue(); + mValues[mValues.size() - 1].mAnnotations.setPrimaryField(primaryField); } -void LogEvent::parseResetStateAnnotation(uint8_t annotationType) { +void LogEvent::parsePrimaryFieldFirstUidAnnotation(uint8_t annotationType, + int firstUidInChainIndex) { + if (mValues.empty() || annotationType != BOOL_TYPE || -1 == firstUidInChainIndex) { + mValid = false; + return; + } + + const bool primaryField = readNextValue(); + mValues[firstUidInChainIndex].mAnnotations.setPrimaryField(primaryField); +} + +void LogEvent::parseExclusiveStateAnnotation(uint8_t annotationType) { + if (mValues.empty() || annotationType != BOOL_TYPE) { + mValid = false; + return; + } + + const bool exclusiveState = readNextValue(); + mValues[mValues.size() - 1].mAnnotations.setExclusiveState(exclusiveState); +} + +void LogEvent::parseTriggerStateResetAnnotation(uint8_t annotationType) { if (mValues.empty() || annotationType != INT32_TYPE) { mValid = false; return; @@ -321,11 +324,17 @@ void LogEvent::parseAnnotations(uint8_t numAnnotations, int firstUidInChainIndex case ANNOTATION_ID_TRUNCATE_TIMESTAMP: parseTruncateTimestampAnnotation(annotationType); break; - case ANNOTATION_ID_STATE_OPTION: - parseStateOptionAnnotation(annotationType, firstUidInChainIndex); + case ANNOTATION_ID_PRIMARY_FIELD: + parsePrimaryFieldAnnotation(annotationType); break; - case ANNOTATION_ID_RESET_STATE: - parseResetStateAnnotation(annotationType); + 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); @@ -362,8 +371,7 @@ bool LogEvent::parseBuffer(uint8_t* buf, size_t len) { if (getTypeId(typeInfo) != INT32_TYPE) mValid = false; mTagId = readNextValue(); numElements--; - parseAnnotations(getNumAnnotations(typeInfo)); // atom-level annotations - + parseAnnotations(getNumAnnotations(typeInfo)); // atom-level annotations for (pos[0] = 1; pos[0] <= numElements && mValid; pos[0]++) { last[0] = (pos[0] == numElements); @@ -372,7 +380,7 @@ bool LogEvent::parseBuffer(uint8_t* buf, size_t len) { uint8_t typeId = getTypeId(typeInfo); // TODO(b/144373276): handle errors passed to the socket - switch(typeId) { + switch (typeId) { case BOOL_TYPE: parseBool(pos, /*depth=*/0, last, getNumAnnotations(typeInfo)); break; @@ -409,11 +417,11 @@ bool LogEvent::parseBuffer(uint8_t* buf, size_t len) { } uint8_t LogEvent::getTypeId(uint8_t typeInfo) { - return typeInfo & 0x0F; // type id in lower 4 bytes + 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 + return (typeInfo >> 4) & 0x0F; // num annotations in upper 4 bytes } int64_t LogEvent::GetLong(size_t key, status_t* err) const { @@ -524,17 +532,17 @@ float LogEvent::GetFloat(size_t key, status_t* err) const { std::vector 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(); + if (value.mField.getField() == field) { + if (value.mValue.getType() == STORAGE) { + return value.mValue.storage_value; + } else { + *err = BAD_TYPE; + return vector(); + } + } + if ((size_t)value.mField.getPosAtDepth(0) > key) { + break; } - } - if ((size_t)value.mField.getPosAtDepth(0) > key) { - break; - } } *err = BAD_INDEX; diff --git a/cmds/statsd/src/logd/LogEvent.h b/cmds/statsd/src/logd/LogEvent.h index 6c6aab1c5ada3..850e2b010f8c0 100644 --- a/cmds/statsd/src/logd/LogEvent.h +++ b/cmds/statsd/src/logd/LogEvent.h @@ -208,8 +208,10 @@ private: void parseAnnotations(uint8_t numAnnotations, int firstUidInChainIndex = -1); void parseIsUidAnnotation(uint8_t annotationType); void parseTruncateTimestampAnnotation(uint8_t annotationType); - void parseStateOptionAnnotation(uint8_t annotationType, int firstUidInChainIndex); - void parseResetStateAnnotation(uint8_t annotationType); + void parsePrimaryFieldAnnotation(uint8_t annotationType); + void parsePrimaryFieldFirstUidAnnotation(uint8_t annotationType, int firstUidInChainIndex); + void parseExclusiveStateAnnotation(uint8_t annotationType); + void parseTriggerStateResetAnnotation(uint8_t annotationType); void parseStateNestedAnnotation(uint8_t annotationType); /** diff --git a/cmds/statsd/tests/LogEvent_test.cpp b/cmds/statsd/tests/LogEvent_test.cpp index 41e21e4afb374..bb4578d9b701e 100644 --- a/cmds/statsd/tests/LogEvent_test.cpp +++ b/cmds/statsd/tests/LogEvent_test.cpp @@ -12,15 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "src/logd/LogEvent.h" + #include #include "frameworks/base/cmds/statsd/src/atoms.pb.h" #include "frameworks/base/core/proto/android/stats/launcher/launcher.pb.h" #include "log/log_event_list.h" -#include "src/logd/LogEvent.h" #include "stats_event.h" - #ifdef __ANDROID__ namespace android { @@ -32,6 +32,8 @@ using std::vector; using util::ProtoOutputStream; using util::ProtoReader; +namespace { + Field getField(int32_t tag, const vector& pos, int32_t depth, const vector& last) { Field f(tag, (int32_t*)pos.data(), depth); @@ -43,6 +45,38 @@ Field getField(int32_t tag, const vector& pos, int32_t depth, const vec return f; } +void createIntWithBoolAnnotationLogEvent(LogEvent* logEvent, uint8_t annotationId, + bool annotationValue) { + AStatsEvent* statsEvent = AStatsEvent_obtain(); + AStatsEvent_setAtomId(statsEvent, /*atomId=*/100); + AStatsEvent_writeInt32(statsEvent, 10); + AStatsEvent_addBoolAnnotation(statsEvent, annotationId, annotationValue); + AStatsEvent_build(statsEvent); + + size_t size; + uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); + EXPECT_TRUE(logEvent->parseBuffer(buf, size)); + + AStatsEvent_release(statsEvent); +} + +void createIntWithIntAnnotationLogEvent(LogEvent* logEvent, uint8_t annotationId, + int annotationValue) { + AStatsEvent* statsEvent = AStatsEvent_obtain(); + AStatsEvent_setAtomId(statsEvent, /*atomId=*/100); + AStatsEvent_writeInt32(statsEvent, 10); + AStatsEvent_addInt32Annotation(statsEvent, annotationId, annotationValue); + AStatsEvent_build(statsEvent); + + size_t size; + uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); + EXPECT_TRUE(logEvent->parseBuffer(buf, size)); + + AStatsEvent_release(statsEvent); +} + +} // anonymous namespace + TEST(LogEventTest, TestPrimitiveParsing) { AStatsEvent* event = AStatsEvent_obtain(); AStatsEvent_setAtomId(event, 100); @@ -86,13 +120,12 @@ TEST(LogEventTest, TestPrimitiveParsing) { const FieldValue& boolItem = values[3]; expectedField = getField(100, {4, 1, 1}, 0, {true, false, false}); EXPECT_EQ(expectedField, boolItem.mField); - EXPECT_EQ(Type::INT, boolItem.mValue.getType()); // FieldValue does not support boolean type + EXPECT_EQ(Type::INT, boolItem.mValue.getType()); // FieldValue does not support boolean type EXPECT_EQ(1, boolItem.mValue.int_value); AStatsEvent_release(event); } - TEST(LogEventTest, TestStringAndByteArrayParsing) { AStatsEvent* event = AStatsEvent_obtain(); AStatsEvent_setAtomId(event, 100); @@ -104,7 +137,7 @@ TEST(LogEventTest, TestStringAndByteArrayParsing) { size_t size; uint8_t* buf = AStatsEvent_getBuffer(event, &size); - LogEvent logEvent(/*uid=*/ 1000, /*pid=*/ 1001); + LogEvent logEvent(/*uid=*/1000, /*pid=*/1001); EXPECT_TRUE(logEvent.parseBuffer(buf, size)); EXPECT_EQ(100, logEvent.GetTagId()); @@ -140,7 +173,7 @@ TEST(LogEventTest, TestEmptyString) { size_t size; uint8_t* buf = AStatsEvent_getBuffer(event, &size); - LogEvent logEvent(/*uid=*/ 1000, /*pid=*/ 1001); + LogEvent logEvent(/*uid=*/1000, /*pid=*/1001); EXPECT_TRUE(logEvent.parseBuffer(buf, size)); EXPECT_EQ(100, logEvent.GetTagId()); @@ -169,7 +202,7 @@ TEST(LogEventTest, TestByteArrayWithNullCharacter) { size_t size; uint8_t* buf = AStatsEvent_getBuffer(event, &size); - LogEvent logEvent(/*uid=*/ 1000, /*pid=*/ 1001); + LogEvent logEvent(/*uid=*/1000, /*pid=*/1001); EXPECT_TRUE(logEvent.parseBuffer(buf, size)); EXPECT_EQ(100, logEvent.GetTagId()); @@ -205,7 +238,7 @@ TEST(LogEventTest, TestAttributionChain) { size_t size; uint8_t* buf = AStatsEvent_getBuffer(event, &size); - LogEvent logEvent(/*uid=*/ 1000, /*pid=*/ 1001); + LogEvent logEvent(/*uid=*/1000, /*pid=*/1001); EXPECT_TRUE(logEvent.parseBuffer(buf, size)); EXPECT_EQ(100, logEvent.GetTagId()); @@ -213,7 +246,7 @@ TEST(LogEventTest, TestAttributionChain) { EXPECT_EQ(1001, logEvent.GetPid()); const vector& values = logEvent.getValues(); - EXPECT_EQ(4, values.size()); // 2 per attribution node + EXPECT_EQ(4, values.size()); // 2 per attribution node // Check first attribution node const FieldValue& uid1Item = values[0]; @@ -244,21 +277,6 @@ TEST(LogEventTest, TestAttributionChain) { AStatsEvent_release(event); } -void createIntWithBoolAnnotationLogEvent(LogEvent* logEvent, uint8_t annotationId, - bool annotationValue) { - AStatsEvent* statsEvent = AStatsEvent_obtain(); - AStatsEvent_setAtomId(statsEvent, /*atomId=*/100); - AStatsEvent_writeInt32(statsEvent, 10); - AStatsEvent_addBoolAnnotation(statsEvent, annotationId, annotationValue); - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); - EXPECT_TRUE(logEvent->parseBuffer(buf, size)); - - AStatsEvent_release(statsEvent); -} - TEST(LogEventTest, TestAnnotationIdIsUid) { LogEvent event(/*uid=*/0, /*pid=*/0); createIntWithBoolAnnotationLogEvent(&event, ANNOTATION_ID_IS_UID, true); @@ -277,25 +295,9 @@ TEST(LogEventTest, TestAnnotationIdStateNested) { EXPECT_TRUE(values[0].mAnnotations.isNested()); } -void createIntWithIntAnnotationLogEvent(LogEvent* logEvent, uint8_t annotationId, - int annotationValue) { - AStatsEvent* statsEvent = AStatsEvent_obtain(); - AStatsEvent_setAtomId(statsEvent, /*atomId=*/100); - AStatsEvent_writeInt32(statsEvent, 10); - AStatsEvent_addInt32Annotation(statsEvent, annotationId, annotationValue); - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); - EXPECT_TRUE(logEvent->parseBuffer(buf, size)); - - AStatsEvent_release(statsEvent); -} - TEST(LogEventTest, TestPrimaryFieldAnnotation) { LogEvent event(/*uid=*/0, /*pid=*/0); - createIntWithIntAnnotationLogEvent(&event, ANNOTATION_ID_STATE_OPTION, - STATE_OPTION_PRIMARY_FIELD); + createIntWithBoolAnnotationLogEvent(&event, ANNOTATION_ID_PRIMARY_FIELD, true); const vector& values = event.getValues(); EXPECT_EQ(values.size(), 1); @@ -304,8 +306,7 @@ TEST(LogEventTest, TestPrimaryFieldAnnotation) { TEST(LogEventTest, TestExclusiveStateAnnotation) { LogEvent event(/*uid=*/0, /*pid=*/0); - createIntWithIntAnnotationLogEvent(&event, ANNOTATION_ID_STATE_OPTION, - STATE_OPTION_EXCLUSIVE_STATE); + createIntWithBoolAnnotationLogEvent(&event, ANNOTATION_ID_EXCLUSIVE_STATE, true); const vector& values = event.getValues(); EXPECT_EQ(values.size(), 1); @@ -328,8 +329,7 @@ TEST(LogEventTest, TestPrimaryFieldFirstUidAnnotation) { AStatsEvent_writeInt32(statsEvent, 10); } AStatsEvent_writeAttributionChain(statsEvent, uids, tags, 2); - AStatsEvent_addInt32Annotation(statsEvent, ANNOTATION_ID_STATE_OPTION, - STATE_OPTION_PRIMARY_FIELD_FIRST_UID); + AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID, true); AStatsEvent_build(statsEvent); // Construct LogEvent @@ -348,7 +348,7 @@ TEST(LogEventTest, TestPrimaryFieldFirstUidAnnotation) { TEST(LogEventTest, TestResetStateAnnotation) { int32_t resetState = 10; LogEvent event(/*uid=*/0, /*pid=*/0); - createIntWithIntAnnotationLogEvent(&event, ANNOTATION_ID_RESET_STATE, resetState); + createIntWithIntAnnotationLogEvent(&event, ANNOTATION_ID_TRIGGER_STATE_RESET, resetState); const vector& values = event.getValues(); EXPECT_EQ(values.size(), 1); diff --git a/tools/stats_log_api_gen/Collation.cpp b/tools/stats_log_api_gen/Collation.cpp index 1387bb5f7bc69..526876f5ec261 100644 --- a/tools/stats_log_api_gen/Collation.cpp +++ b/tools/stats_log_api_gen/Collation.cpp @@ -50,7 +50,7 @@ AtomDecl::AtomDecl(const AtomDecl& that) primaryFields(that.primaryFields), exclusiveField(that.exclusiveField), defaultState(that.defaultState), - resetState(that.resetState), + triggerStateReset(that.triggerStateReset), nested(that.nested), uidField(that.uidField), whitelisted(that.whitelisted), @@ -153,7 +153,8 @@ void collate_enums(const EnumDescriptor& enumDescriptor, AtomField* atomField) { } static void addAnnotationToAtomDecl(AtomDecl* atomDecl, const int fieldNumber, - const int annotationId, const AnnotationType annotationType, + const AnnotationId annotationId, + const AnnotationType annotationType, const AnnotationValue annotationValue) { if (dbg) { printf(" Adding annotation to %s: [%d] = {id: %d, type: %d}\n", atomDecl->name.c_str(), @@ -168,23 +169,35 @@ static int collate_field_annotations(AtomDecl* atomDecl, const FieldDescriptor* int errorCount = 0; if (field->options().HasExtension(os::statsd::state_field_option)) { - const int option = field->options().GetExtension(os::statsd::state_field_option).option(); - if (option != STATE_OPTION_UNSET) { - addAnnotationToAtomDecl(atomDecl, fieldNumber, ANNOTATION_ID_STATE_OPTION, - ANNOTATION_TYPE_INT, AnnotationValue(option)); + const os::statsd::StateAtomFieldOption& stateFieldOption = + field->options().GetExtension(os::statsd::state_field_option); + const bool primaryField = stateFieldOption.primary_field(); + const bool exclusiveState = stateFieldOption.exclusive_state(); + const bool primaryFieldFirstUid = stateFieldOption.primary_field_first_uid(); + + // Check the field is only one of primaryField, exclusiveState, or primaryFieldFirstUid. + if (primaryField + primaryFieldFirstUid + exclusiveState > 1) { + print_error(field, + "Field can be max 1 of primary_field, exclusive_state, " + "or primary_field_first_uid: '%s'\n", + atomDecl->message.c_str()); + errorCount++; } - if (option == STATE_OPTION_PRIMARY) { + if (primaryField) { if (javaType == JAVA_TYPE_UNKNOWN || javaType == JAVA_TYPE_ATTRIBUTION_CHAIN || javaType == JAVA_TYPE_OBJECT || javaType == JAVA_TYPE_BYTE_ARRAY) { print_error(field, "Invalid primary state field: '%s'\n", atomDecl->message.c_str()); errorCount++; + } else { + atomDecl->primaryFields.push_back(fieldNumber); + addAnnotationToAtomDecl(atomDecl, fieldNumber, ANNOTATION_ID_PRIMARY_FIELD, + ANNOTATION_TYPE_BOOL, AnnotationValue(true)); } - atomDecl->primaryFields.push_back(fieldNumber); } - if (option == STATE_OPTION_PRIMARY_FIELD_FIRST_UID) { + if (primaryFieldFirstUid) { if (javaType != JAVA_TYPE_ATTRIBUTION_CHAIN) { print_error(field, "PRIMARY_FIELD_FIRST_UID annotation is only for AttributionChains: " @@ -193,10 +206,13 @@ static int collate_field_annotations(AtomDecl* atomDecl, const FieldDescriptor* errorCount++; } else { atomDecl->primaryFields.push_back(FIRST_UID_IN_CHAIN_ID); + addAnnotationToAtomDecl(atomDecl, fieldNumber, + ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID, ANNOTATION_TYPE_BOOL, + AnnotationValue(true)); } } - if (option == STATE_OPTION_EXCLUSIVE) { + if (exclusiveState) { if (javaType == JAVA_TYPE_UNKNOWN || javaType == JAVA_TYPE_ATTRIBUTION_CHAIN || javaType == JAVA_TYPE_OBJECT || javaType == JAVA_TYPE_BYTE_ARRAY) { print_error(field, "Invalid exclusive state field: '%s'\n", @@ -204,43 +220,36 @@ static int collate_field_annotations(AtomDecl* atomDecl, const FieldDescriptor* errorCount++; } - if (atomDecl->exclusiveField == 0) { - atomDecl->exclusiveField = fieldNumber; - } else { + if (atomDecl->exclusiveField != 0) { print_error(field, "Cannot have more than one exclusive state field in an " "atom: '%s'\n", atomDecl->message.c_str()); errorCount++; + } else { + atomDecl->exclusiveField = fieldNumber; + addAnnotationToAtomDecl(atomDecl, fieldNumber, ANNOTATION_ID_EXCLUSIVE_STATE, + ANNOTATION_TYPE_BOOL, AnnotationValue(true)); } - if (field->options() - .GetExtension(os::statsd::state_field_option) - .has_default_state_value()) { - const int defaultState = field->options() - .GetExtension(os::statsd::state_field_option) - .default_state_value(); + if (stateFieldOption.has_default_state_value()) { + const int defaultState = stateFieldOption.default_state_value(); atomDecl->defaultState = defaultState; addAnnotationToAtomDecl(atomDecl, fieldNumber, ANNOTATION_ID_DEFAULT_STATE, ANNOTATION_TYPE_INT, AnnotationValue(defaultState)); } - if (field->options() - .GetExtension(os::statsd::state_field_option) - .has_reset_state_value()) { - const int resetState = field->options() - .GetExtension(os::statsd::state_field_option) - .reset_state_value(); + if (stateFieldOption.has_trigger_state_reset_value()) { + const int triggerStateReset = stateFieldOption.trigger_state_reset_value(); - atomDecl->resetState = resetState; - addAnnotationToAtomDecl(atomDecl, fieldNumber, ANNOTATION_ID_RESET_STATE, - ANNOTATION_TYPE_INT, AnnotationValue(resetState)); + atomDecl->triggerStateReset = triggerStateReset; + addAnnotationToAtomDecl(atomDecl, fieldNumber, ANNOTATION_ID_TRIGGER_STATE_RESET, + ANNOTATION_TYPE_INT, AnnotationValue(triggerStateReset)); } - if (field->options().GetExtension(os::statsd::state_field_option).has_nested()) { - const bool nested = - field->options().GetExtension(os::statsd::state_field_option).nested(); + if (stateFieldOption.has_nested()) { + const bool nested = stateFieldOption.nested(); atomDecl->nested = nested; addAnnotationToAtomDecl(atomDecl, fieldNumber, ANNOTATION_ID_STATE_NESTED, diff --git a/tools/stats_log_api_gen/Collation.h b/tools/stats_log_api_gen/Collation.h index b1cf1347a98de..d56f2be7ecb3d 100644 --- a/tools/stats_log_api_gen/Collation.h +++ b/tools/stats_log_api_gen/Collation.h @@ -18,6 +18,7 @@ #define ANDROID_STATS_LOG_API_GEN_COLLATION_H #include +#include #include #include @@ -40,17 +41,16 @@ const int PULL_ATOM_START_ID = 10000; const int FIRST_UID_IN_CHAIN_ID = 0; -const unsigned char ANNOTATION_ID_IS_UID = 1; -const unsigned char ANNOTATION_ID_TRUNCATE_TIMESTAMP = 2; -const unsigned char ANNOTATION_ID_STATE_OPTION = 3; -const unsigned char ANNOTATION_ID_DEFAULT_STATE = 4; -const unsigned char ANNOTATION_ID_RESET_STATE = 5; -const unsigned char ANNOTATION_ID_STATE_NESTED = 6; - -const int STATE_OPTION_UNSET = os::statsd::StateField::STATE_FIELD_UNSET; -const int STATE_OPTION_EXCLUSIVE = os::statsd::StateField::EXCLUSIVE_STATE; -const int STATE_OPTION_PRIMARY_FIELD_FIRST_UID = os::statsd::StateField::PRIMARY_FIELD_FIRST_UID; -const int STATE_OPTION_PRIMARY = os::statsd::StateField::PRIMARY_FIELD; +enum AnnotationId : uint8_t { + ANNOTATION_ID_IS_UID = 1, + ANNOTATION_ID_TRUNCATE_TIMESTAMP = 2, + ANNOTATION_ID_PRIMARY_FIELD = 3, + ANNOTATION_ID_EXCLUSIVE_STATE = 4, + ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID = 5, + ANNOTATION_ID_DEFAULT_STATE = 6, + ANNOTATION_ID_TRIGGER_STATE_RESET = 7, + ANNOTATION_ID_STATE_NESTED = 8, +}; const int ATOM_ID_FIELD_NUMBER = -1; @@ -93,12 +93,12 @@ union AnnotationValue { }; struct Annotation { - const unsigned char annotationId; + const AnnotationId annotationId; const int atomId; AnnotationType type; AnnotationValue value; - inline Annotation(unsigned char annotationId, int atomId, AnnotationType type, + inline Annotation(AnnotationId annotationId, int atomId, AnnotationType type, AnnotationValue value) : annotationId(annotationId), atomId(atomId), type(type), value(value) { } @@ -159,7 +159,7 @@ struct AtomDecl { vector primaryFields; int exclusiveField = 0; int defaultState = INT_MAX; - int resetState = INT_MAX; + int triggerStateReset = INT_MAX; bool nested; int uidField = 0; diff --git a/tools/stats_log_api_gen/atoms_info_writer.cpp b/tools/stats_log_api_gen/atoms_info_writer.cpp index 862fed4656b4d..23a0f72782710 100644 --- a/tools/stats_log_api_gen/atoms_info_writer.cpp +++ b/tools/stats_log_api_gen/atoms_info_writer.cpp @@ -151,8 +151,8 @@ static void write_atoms_info_cpp_body(FILE* out, const Atoms& atoms) { fprintf(out, " opt->defaultState = UNSET_VALUE;\n"); } - if ((*atomIt)->resetState != INT_MAX) { - fprintf(out, " opt->resetState = %d;\n", (*atomIt)->resetState); + if ((*atomIt)->triggerStateReset != INT_MAX) { + fprintf(out, " opt->resetState = %d;\n", (*atomIt)->triggerStateReset); } else { fprintf(out, " opt->resetState = UNSET_VALUE;\n"); } diff --git a/tools/stats_log_api_gen/java_writer.cpp b/tools/stats_log_api_gen/java_writer.cpp index 54c5b9059fb0e..556cf5e12d011 100644 --- a/tools/stats_log_api_gen/java_writer.cpp +++ b/tools/stats_log_api_gen/java_writer.cpp @@ -63,11 +63,10 @@ static void write_annotations(FILE* out, int argIndex, int resetState = -1; int defaultState = -1; for (const shared_ptr& annotation : annotations) { - const string& annotationConstant = - ANNOTATION_ID_CONSTANTS.at(annotation->annotationId); + const string& annotationConstant = ANNOTATION_ID_CONSTANTS.at(annotation->annotationId); switch (annotation->type) { case ANNOTATION_TYPE_INT: - if (ANNOTATION_ID_RESET_STATE == annotation->annotationId) { + if (ANNOTATION_ID_TRIGGER_STATE_RESET == annotation->annotationId) { resetState = annotation->value.intValue; } else if (ANNOTATION_ID_DEFAULT_STATE == annotation->annotationId) { defaultState = annotation->value.intValue; @@ -87,7 +86,7 @@ static void write_annotations(FILE* out, int argIndex, } if (defaultState != -1 && resetState != -1) { const string& annotationConstant = - ANNOTATION_ID_CONSTANTS.at(ANNOTATION_ID_RESET_STATE); + ANNOTATION_ID_CONSTANTS.at(ANNOTATION_ID_TRIGGER_STATE_RESET); fprintf(out, " if (arg%d == %d) {\n", argIndex, resetState); fprintf(out, " builder.addIntAnnotation(%s, %d);\n", annotationConstant.c_str(), defaultState); diff --git a/tools/stats_log_api_gen/native_writer.cpp b/tools/stats_log_api_gen/native_writer.cpp index d8db62087f8fd..0c6c0099e459a 100644 --- a/tools/stats_log_api_gen/native_writer.cpp +++ b/tools/stats_log_api_gen/native_writer.cpp @@ -30,7 +30,6 @@ static void write_native_annotation_constants(FILE* out) { fprintf(out, "\n"); } - static void write_annotations(FILE* out, int argIndex, const FieldNumberToAtomDeclSet& fieldNumberToAtomDeclSet, const string& methodPrefix, const string& methodSuffix) { @@ -47,11 +46,10 @@ static void write_annotations(FILE* out, int argIndex, int resetState = -1; int defaultState = -1; for (const shared_ptr& annotation : annotations) { - const string& annotationConstant = - ANNOTATION_ID_CONSTANTS.at(annotation->annotationId); + const string& annotationConstant = ANNOTATION_ID_CONSTANTS.at(annotation->annotationId); switch (annotation->type) { case ANNOTATION_TYPE_INT: - if (ANNOTATION_ID_RESET_STATE == annotation->annotationId) { + if (ANNOTATION_ID_TRIGGER_STATE_RESET == annotation->annotationId) { resetState = annotation->value.intValue; } else if (ANNOTATION_ID_DEFAULT_STATE == annotation->annotationId) { defaultState = annotation->value.intValue; @@ -74,7 +72,7 @@ static void write_annotations(FILE* out, int argIndex, } if (defaultState != -1 && resetState != -1) { const string& annotationConstant = - ANNOTATION_ID_CONSTANTS.at(ANNOTATION_ID_RESET_STATE); + ANNOTATION_ID_CONSTANTS.at(ANNOTATION_ID_TRIGGER_STATE_RESET); fprintf(out, " if (arg%d == %d) {\n", argIndex, resetState); fprintf(out, " %saddInt32Annotation(%s%s, %d);\n", methodPrefix.c_str(), methodSuffix.c_str(), annotationConstant.c_str(), defaultState); diff --git a/tools/stats_log_api_gen/test.proto b/tools/stats_log_api_gen/test.proto index 480442fe9d3dd..d22acc6e6598e 100644 --- a/tools/stats_log_api_gen/test.proto +++ b/tools/stats_log_api_gen/test.proto @@ -149,42 +149,42 @@ message GoodStateAtoms { // The atom has only primary field but no exclusive state field. message BadStateAtom1 { - optional int32 uid = 1 [(android.os.statsd.state_field_option).option = PRIMARY_FIELD]; + optional int32 uid = 1 [(android.os.statsd.state_field_option).primary_field = true]; } // Only primative types can be annotated. message BadStateAtom2 { repeated android.os.statsd.AttributionNode attribution = 1 - [(android.os.statsd.state_field_option).option = PRIMARY_FIELD]; - optional int32 state = 2 [(android.os.statsd.state_field_option).option = EXCLUSIVE_STATE]; + [(android.os.statsd.state_field_option).primary_field = true]; + optional int32 state = 2 [(android.os.statsd.state_field_option).exclusive_state = true]; } // Having 2 exclusive state field in the atom means the atom is badly designed. // E.g., putting bluetooth state and wifi state in the same atom. message BadStateAtom3 { - optional int32 uid = 1 [(android.os.statsd.state_field_option).option = PRIMARY_FIELD]; - optional int32 state = 2 [(android.os.statsd.state_field_option).option = EXCLUSIVE_STATE]; - optional int32 state2 = 3 [(android.os.statsd.state_field_option).option = EXCLUSIVE_STATE]; + optional int32 uid = 1 [(android.os.statsd.state_field_option).primary_field = true]; + optional int32 state = 2 [(android.os.statsd.state_field_option).exclusive_state = true]; + optional int32 state2 = 3 [(android.os.statsd.state_field_option).exclusive_state = true]; } message GoodStateAtom1 { - optional int32 uid = 1 [(android.os.statsd.state_field_option).option = PRIMARY_FIELD]; - optional int32 state = 2 [(android.os.statsd.state_field_option).option = EXCLUSIVE_STATE]; + optional int32 uid = 1 [(android.os.statsd.state_field_option).primary_field = true]; + optional int32 state = 2 [(android.os.statsd.state_field_option).exclusive_state = true]; } // Atoms can have exclusive state field, but no primary field. That means // the state is globally exclusive (e.g., DisplayState). message GoodStateAtom2 { optional int32 uid = 1; - optional int32 state = 2 [(android.os.statsd.state_field_option).option = EXCLUSIVE_STATE]; + optional int32 state = 2 [(android.os.statsd.state_field_option).exclusive_state = true]; } // We can have more than one primary fields. That means their combination is a // primary key. message GoodStateAtom3 { - optional int32 uid = 1 [(android.os.statsd.state_field_option).option = PRIMARY_FIELD]; - optional int32 tid = 2 [(android.os.statsd.state_field_option).option = PRIMARY_FIELD]; - optional int32 state = 3 [(android.os.statsd.state_field_option).option = EXCLUSIVE_STATE]; + optional int32 uid = 1 [(android.os.statsd.state_field_option).primary_field = true]; + optional int32 tid = 2 [(android.os.statsd.state_field_option).primary_field = true]; + optional int32 state = 3 [(android.os.statsd.state_field_option).exclusive_state = true]; } message WhitelistedAtom { @@ -214,7 +214,7 @@ message ModuleTwoAtom { } message ModuleOneAndTwoAtom { - optional int32 field = 1 [(android.os.statsd.state_field_option).option = EXCLUSIVE_STATE]; + optional int32 field = 1 [(android.os.statsd.state_field_option).exclusive_state = true]; } message NoModuleAtom { diff --git a/tools/stats_log_api_gen/test_collation.cpp b/tools/stats_log_api_gen/test_collation.cpp index c654a1b030513..150475223bfac 100644 --- a/tools/stats_log_api_gen/test_collation.cpp +++ b/tools/stats_log_api_gen/test_collation.cpp @@ -308,10 +308,10 @@ TEST(CollationTest, RecognizeModuleAtom) { EXPECT_EQ(1ul, annotationSet->size()); annotationSetIt = annotationSet->begin(); annotation = annotationSetIt->get(); - EXPECT_EQ(ANNOTATION_ID_STATE_OPTION, annotation->annotationId); + EXPECT_EQ(ANNOTATION_ID_EXCLUSIVE_STATE, annotation->annotationId); EXPECT_EQ(3, annotation->atomId); - EXPECT_EQ(ANNOTATION_TYPE_INT, annotation->type); - EXPECT_EQ(os::statsd::StateField::EXCLUSIVE_STATE, annotation->value.intValue); + EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type); + EXPECT_TRUE(annotation->value.boolValue); signatureInfoMapIt++; signature = &signatureInfoMapIt->first; @@ -378,10 +378,10 @@ TEST(CollationTest, RecognizeModule1Atom) { EXPECT_EQ(1ul, annotationSet->size()); annotationSetIt = annotationSet->begin(); annotation = annotationSetIt->get(); - EXPECT_EQ(ANNOTATION_ID_STATE_OPTION, annotation->annotationId); + EXPECT_EQ(ANNOTATION_ID_EXCLUSIVE_STATE, annotation->annotationId); EXPECT_EQ(3, annotation->atomId); - EXPECT_EQ(ANNOTATION_TYPE_INT, annotation->type); - EXPECT_EQ(os::statsd::StateField::EXCLUSIVE_STATE, annotation->value.intValue); + EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type); + EXPECT_TRUE(annotation->value.boolValue); } } // namespace stats_log_api_gen diff --git a/tools/stats_log_api_gen/utils.h b/tools/stats_log_api_gen/utils.h index 1f644426ffa96..7d6d08ebbcbe2 100644 --- a/tools/stats_log_api_gen/utils.h +++ b/tools/stats_log_api_gen/utils.h @@ -38,13 +38,14 @@ const int JAVA_MODULE_REQUIRES_FLOAT = 0x01; const int JAVA_MODULE_REQUIRES_ATTRIBUTION = 0x02; const int JAVA_MODULE_REQUIRES_KEY_VALUE_PAIRS = 0x04; -const map ANNOTATION_ID_CONSTANTS = { - { ANNOTATION_ID_IS_UID, "ANNOTATION_ID_IS_UID" }, - { ANNOTATION_ID_TRUNCATE_TIMESTAMP, "ANNOTATION_ID_TRUNCATE_TIMESTAMP" }, - { ANNOTATION_ID_STATE_OPTION, "ANNOTATION_ID_STATE_OPTION" }, - { ANNOTATION_ID_RESET_STATE, "ANNOTATION_ID_RESET_STATE" }, - { ANNOTATION_ID_STATE_NESTED, "ANNOTATION_ID_STATE_NESTED" } -}; +const map ANNOTATION_ID_CONSTANTS = { + {ANNOTATION_ID_IS_UID, "ANNOTATION_ID_IS_UID"}, + {ANNOTATION_ID_TRUNCATE_TIMESTAMP, "ANNOTATION_ID_TRUNCATE_TIMESTAMP"}, + {ANNOTATION_ID_PRIMARY_FIELD, "ANNOTATION_ID_PRIMARY_FIELD"}, + {ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID, "ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID"}, + {ANNOTATION_ID_EXCLUSIVE_STATE, "ANNOTATION_ID_EXCLUSIVE_STATE"}, + {ANNOTATION_ID_TRIGGER_STATE_RESET, "ANNOTATION_ID_TRIGGER_STATE_RESET"}, + {ANNOTATION_ID_STATE_NESTED, "ANNOTATION_ID_STATE_NESTED"}}; string make_constant_name(const string& str);