Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8056dd12 authored by Ruchir Rastogi's avatar Ruchir Rastogi
Browse files

Support ERROR_ATOM_ID_INVALID_POSITION

Originally, the native implementation would discard everything clients
wrote to the buffer before the setAtomId call. Thus, the atom id was
always placed in the "correct position." However, for consistency with
the Java implementation, we now allow write calls before setAtomId to
occur and log an error in that case.

Test: bit libstatssocket_test:*
Bug: 152119205
Change-Id: Ib109c7a939a5ae92c1d5fc70aa647ac7390fadad
parent baaf2a44
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -89,7 +89,8 @@ void AStatsEvent_release(AStatsEvent* event);
/**
/**
 * Sets the atom id for this StatsEvent.
 * Sets the atom id for this StatsEvent.
 *
 *
 * This function should be called immediately after AStatsEvent_obtain.
 * This function should be called immediately after AStatsEvent_obtain. It may
 * be called additional times as well, but subsequent calls will have no effect.
 **/
 **/
void AStatsEvent_setAtomId(AStatsEvent* event, uint32_t atomId);
void AStatsEvent_setAtomId(AStatsEvent* event, uint32_t atomId);


+24 −28
Original line number Original line Diff line number Diff line
@@ -47,6 +47,7 @@
#define ERROR_TOO_MANY_FIELDS 0x200
#define ERROR_TOO_MANY_FIELDS 0x200
#define ERROR_INVALID_VALUE_TYPE 0x400
#define ERROR_INVALID_VALUE_TYPE 0x400
#define ERROR_STRING_NOT_NULL_TERMINATED 0x800
#define ERROR_STRING_NOT_NULL_TERMINATED 0x800
#define ERROR_ATOM_ID_INVALID_POSITION 0x2000


/* TYPE IDS */
/* TYPE IDS */
#define INT32_TYPE 0x00
#define INT32_TYPE 0x00
@@ -98,11 +99,6 @@ AStatsEvent* AStatsEvent_obtain() {
    event->buf[0] = OBJECT_TYPE;
    event->buf[0] = OBJECT_TYPE;
    AStatsEvent_writeInt64(event, get_elapsed_realtime_ns());  // write the timestamp
    AStatsEvent_writeInt64(event, get_elapsed_realtime_ns());  // write the timestamp


    // Force client to set atom id immediately (this is required for atom-level
    // annotations to be written correctly). All atom field and annotation
    // writes will fail until the atom id is set because event->errors != 0.
    event->errors |= ERROR_NO_ATOM_ID;

    return event;
    return event;
}
}


@@ -112,10 +108,12 @@ void AStatsEvent_release(AStatsEvent* event) {
}
}


void AStatsEvent_setAtomId(AStatsEvent* event, uint32_t atomId) {
void AStatsEvent_setAtomId(AStatsEvent* event, uint32_t atomId) {
    if ((event->errors & ERROR_NO_ATOM_ID) == 0) return;
    if (event->atomId != 0) return;
    if (event->numElements != 1) {
        event->errors |= ERROR_ATOM_ID_INVALID_POSITION;
        return;
    }


    // Clear the ERROR_NO_ATOM_ID bit.
    event->errors &= ~ERROR_NO_ATOM_ID;
    event->atomId = atomId;
    event->atomId = atomId;
    AStatsEvent_writeInt32(event, atomId);
    AStatsEvent_writeInt32(event, atomId);
}
}
@@ -197,36 +195,26 @@ static void start_field(AStatsEvent* event, uint8_t typeId) {
}
}


void AStatsEvent_writeInt32(AStatsEvent* event, int32_t value) {
void AStatsEvent_writeInt32(AStatsEvent* event, int32_t value) {
    if (event->errors) return;

    start_field(event, INT32_TYPE);
    start_field(event, INT32_TYPE);
    append_int32(event, value);
    append_int32(event, value);
}
}


void AStatsEvent_writeInt64(AStatsEvent* event, int64_t value) {
void AStatsEvent_writeInt64(AStatsEvent* event, int64_t value) {
    if (event->errors) return;

    start_field(event, INT64_TYPE);
    start_field(event, INT64_TYPE);
    append_int64(event, value);
    append_int64(event, value);
}
}


void AStatsEvent_writeFloat(AStatsEvent* event, float value) {
void AStatsEvent_writeFloat(AStatsEvent* event, float value) {
    if (event->errors) return;

    start_field(event, FLOAT_TYPE);
    start_field(event, FLOAT_TYPE);
    append_float(event, value);
    append_float(event, value);
}
}


void AStatsEvent_writeBool(AStatsEvent* event, bool value) {
void AStatsEvent_writeBool(AStatsEvent* event, bool value) {
    if (event->errors) return;

    start_field(event, BOOL_TYPE);
    start_field(event, BOOL_TYPE);
    append_bool(event, value);
    append_bool(event, value);
}
}


void AStatsEvent_writeByteArray(AStatsEvent* event, const uint8_t* buf, size_t numBytes) {
void AStatsEvent_writeByteArray(AStatsEvent* event, const uint8_t* buf, size_t numBytes) {
    if (event->errors) return;

    start_field(event, BYTE_ARRAY_TYPE);
    start_field(event, BYTE_ARRAY_TYPE);
    append_int32(event, numBytes);
    append_int32(event, numBytes);
    append_byte_array(event, buf, numBytes);
    append_byte_array(event, buf, numBytes);
@@ -234,8 +222,6 @@ void AStatsEvent_writeByteArray(AStatsEvent* event, const uint8_t* buf, size_t n


// Value is assumed to be encoded using UTF8
// Value is assumed to be encoded using UTF8
void AStatsEvent_writeString(AStatsEvent* event, const char* value) {
void AStatsEvent_writeString(AStatsEvent* event, const char* value) {
    if (event->errors) return;

    start_field(event, STRING_TYPE);
    start_field(event, STRING_TYPE);
    append_string(event, value);
    append_string(event, value);
}
}
@@ -243,8 +229,10 @@ void AStatsEvent_writeString(AStatsEvent* event, const char* value) {
// Tags are assumed to be encoded using UTF8
// Tags are assumed to be encoded using UTF8
void AStatsEvent_writeAttributionChain(AStatsEvent* event, const uint32_t* uids,
void AStatsEvent_writeAttributionChain(AStatsEvent* event, const uint32_t* uids,
                                       const char* const* tags, uint8_t numNodes) {
                                       const char* const* tags, uint8_t numNodes) {
    if (numNodes > MAX_BYTE_VALUE) event->errors |= ERROR_ATTRIBUTION_CHAIN_TOO_LONG;
    if (numNodes > MAX_BYTE_VALUE) {
    if (event->errors) return;
        event->errors |= ERROR_ATTRIBUTION_CHAIN_TOO_LONG;
        return;
    }


    start_field(event, ATTRIBUTION_CHAIN_TYPE);
    start_field(event, ATTRIBUTION_CHAIN_TYPE);
    append_byte(event, numNodes);
    append_byte(event, numNodes);
@@ -270,9 +258,13 @@ static void increment_annotation_count(AStatsEvent* event) {
}
}


void AStatsEvent_addBoolAnnotation(AStatsEvent* event, uint8_t annotationId, bool value) {
void AStatsEvent_addBoolAnnotation(AStatsEvent* event, uint8_t annotationId, bool value) {
    if (event->lastFieldPos == 0) event->errors |= ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD;
    if (event->numElements < 2) {
    if (annotationId > MAX_BYTE_VALUE) event->errors |= ERROR_ANNOTATION_ID_TOO_LARGE;
        event->errors |= ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD;
    if (event->errors) return;
        return;
    } else if (annotationId > MAX_BYTE_VALUE) {
        event->errors |= ERROR_ANNOTATION_ID_TOO_LARGE;
        return;
    }


    append_byte(event, annotationId);
    append_byte(event, annotationId);
    append_byte(event, BOOL_TYPE);
    append_byte(event, BOOL_TYPE);
@@ -281,9 +273,13 @@ void AStatsEvent_addBoolAnnotation(AStatsEvent* event, uint8_t annotationId, boo
}
}


void AStatsEvent_addInt32Annotation(AStatsEvent* event, uint8_t annotationId, int32_t value) {
void AStatsEvent_addInt32Annotation(AStatsEvent* event, uint8_t annotationId, int32_t value) {
    if (event->lastFieldPos == 0) event->errors |= ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD;
    if (event->numElements < 2) {
    if (annotationId > MAX_BYTE_VALUE) event->errors |= ERROR_ANNOTATION_ID_TOO_LARGE;
        event->errors |= ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD;
    if (event->errors) return;
        return;
    } else if (annotationId > MAX_BYTE_VALUE) {
        event->errors |= ERROR_ANNOTATION_ID_TOO_LARGE;
        return;
    }


    append_byte(event, annotationId);
    append_byte(event, annotationId);
    append_byte(event, INT32_TYPE);
    append_byte(event, INT32_TYPE);
+14 −0
Original line number Original line Diff line number Diff line
@@ -32,6 +32,7 @@
#define ERROR_TOO_MANY_FIELDS 0x200
#define ERROR_TOO_MANY_FIELDS 0x200
#define ERROR_INVALID_VALUE_TYPE 0x400
#define ERROR_INVALID_VALUE_TYPE 0x400
#define ERROR_STRING_NOT_NULL_TERMINATED 0x800
#define ERROR_STRING_NOT_NULL_TERMINATED 0x800
#define ERROR_ATOM_ID_INVALID_POSITION 0x2000


/* TYPE IDS */
/* TYPE IDS */
#define INT32_TYPE 0x00
#define INT32_TYPE 0x00
@@ -358,6 +359,19 @@ TEST(StatsEventTest, TestOverflowError) {
    AStatsEvent_release(event);
    AStatsEvent_release(event);
}
}


TEST(StatsEventTest, TestAtomIdInvalidPositionError) {
    AStatsEvent* event = AStatsEvent_obtain();
    AStatsEvent_writeInt32(event, 0);
    AStatsEvent_setAtomId(event, 100);
    AStatsEvent_writeBool(event, true);
    AStatsEvent_build(event);

    uint32_t errors = AStatsEvent_getErrors(event);
    EXPECT_NE(errors | ERROR_ATOM_ID_INVALID_POSITION, 0);

    AStatsEvent_release(event);
}

TEST(StatsEventTest, TestOverwriteTimestamp) {
TEST(StatsEventTest, TestOverwriteTimestamp) {
    uint32_t atomId = 100;
    uint32_t atomId = 100;
    int64_t expectedTimestamp = 0x123456789;
    int64_t expectedTimestamp = 0x123456789;