1 // Copyright (C) 2017 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "src/logd/LogEvent.h"
16 
17 #include <gtest/gtest.h>
18 
19 #include "flags/FlagProvider.h"
20 #include "frameworks/proto_logging/stats/atoms.pb.h"
21 #include "frameworks/proto_logging/stats/enums/stats/launcher/launcher.pb.h"
22 #include "log/log_event_list.h"
23 #include "stats_annotations.h"
24 #include "stats_event.h"
25 #include "statsd_test_util.h"
26 
27 #ifdef __ANDROID__
28 
29 namespace android {
30 namespace os {
31 namespace statsd {
32 
33 using std::string;
34 using std::vector;
35 using ::util::ProtoOutputStream;
36 using ::util::ProtoReader;
37 
38 namespace {
39 
getField(int32_t tag,const vector<int32_t> & pos,int32_t depth,const vector<uint8_t> & last)40 Field getField(int32_t tag, const vector<int32_t>& pos, int32_t depth,
41                const vector<uint8_t>& last) {
42     Field f(tag, (int32_t*)pos.data(), depth);
43 
44     // only decorate last position for depths with repeated fields (depth 1)
45     if (depth > 0 && last[1]) f.decorateLastPos(1);
46 
47     return f;
48 }
49 
createFieldWithBoolAnnotationLogEvent(LogEvent * logEvent,uint8_t typeId,uint8_t annotationId,bool annotationValue,bool doHeaderPrefetch)50 bool createFieldWithBoolAnnotationLogEvent(LogEvent* logEvent, uint8_t typeId, uint8_t annotationId,
51                                            bool annotationValue, bool doHeaderPrefetch) {
52     AStatsEvent* statsEvent = AStatsEvent_obtain();
53     createStatsEvent(statsEvent, typeId, /*atomId=*/100);
54     AStatsEvent_addBoolAnnotation(statsEvent, annotationId, annotationValue);
55     AStatsEvent_build(statsEvent);
56 
57     size_t size;
58     const uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
59     if (doHeaderPrefetch) {
60         // Testing LogEvent header prefetch logic
61         const LogEvent::BodyBufferInfo bodyInfo = logEvent->parseHeader(buf, size);
62         logEvent->parseBody(bodyInfo);
63     } else {
64         logEvent->parseBuffer(buf, size);
65     }
66     AStatsEvent_release(statsEvent);
67 
68     return logEvent->isValid();
69 }
70 
createFieldWithIntAnnotationLogEvent(LogEvent * logEvent,uint8_t typeId,uint8_t annotationId,int annotationValue,bool doHeaderPrefetch)71 bool createFieldWithIntAnnotationLogEvent(LogEvent* logEvent, uint8_t typeId, uint8_t annotationId,
72                                           int annotationValue, bool doHeaderPrefetch) {
73     AStatsEvent* statsEvent = AStatsEvent_obtain();
74     createStatsEvent(statsEvent, typeId, /*atomId=*/100);
75     AStatsEvent_addInt32Annotation(statsEvent, annotationId, annotationValue);
76     AStatsEvent_build(statsEvent);
77 
78     size_t size;
79     const uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
80     if (doHeaderPrefetch) {
81         // Testing LogEvent header prefetch logic
82         const LogEvent::BodyBufferInfo bodyInfo = logEvent->parseHeader(buf, size);
83         logEvent->parseBody(bodyInfo);
84     } else {
85         logEvent->parseBuffer(buf, size);
86     }
87     AStatsEvent_release(statsEvent);
88 
89     return logEvent->isValid();
90 }
91 
createAtomLevelIntAnnotationLogEvent(LogEvent * logEvent,uint8_t typeId,uint8_t annotationId,int annotationValue,bool doHeaderPrefetch)92 bool createAtomLevelIntAnnotationLogEvent(LogEvent* logEvent, uint8_t typeId, uint8_t annotationId,
93                                           int annotationValue, bool doHeaderPrefetch) {
94     AStatsEvent* statsEvent = AStatsEvent_obtain();
95     AStatsEvent_setAtomId(statsEvent, /*atomId=*/100);
96     AStatsEvent_addInt32Annotation(statsEvent, annotationId, annotationValue);
97     fillStatsEventWithSampleValue(statsEvent, typeId);
98     AStatsEvent_build(statsEvent);
99 
100     size_t size;
101     const uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
102     if (doHeaderPrefetch) {
103         // Testing LogEvent header prefetch logic
104         const LogEvent::BodyBufferInfo bodyInfo = logEvent->parseHeader(buf, size);
105         logEvent->parseBody(bodyInfo);
106     } else {
107         logEvent->parseBuffer(buf, size);
108     }
109     AStatsEvent_release(statsEvent);
110 
111     return logEvent->isValid();
112 }
113 
createAtomLevelBoolAnnotationLogEvent(LogEvent * logEvent,uint8_t typeId,uint8_t annotationId,bool annotationValue,bool doHeaderPrefetch)114 bool createAtomLevelBoolAnnotationLogEvent(LogEvent* logEvent, uint8_t typeId, uint8_t annotationId,
115                                            bool annotationValue, bool doHeaderPrefetch) {
116     AStatsEvent* statsEvent = AStatsEvent_obtain();
117     AStatsEvent_setAtomId(statsEvent, /*atomId=*/100);
118     AStatsEvent_addBoolAnnotation(statsEvent, annotationId, annotationValue);
119     fillStatsEventWithSampleValue(statsEvent, typeId);
120     AStatsEvent_build(statsEvent);
121 
122     size_t size;
123     const uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
124     if (doHeaderPrefetch) {
125         // Testing LogEvent header prefetch logic
126         const LogEvent::BodyBufferInfo bodyInfo = logEvent->parseHeader(buf, size);
127         logEvent->parseBody(bodyInfo);
128     } else {
129         logEvent->parseBuffer(buf, size);
130     }
131     AStatsEvent_release(statsEvent);
132 
133     return logEvent->isValid();
134 }
135 
136 }  // anonymous namespace
137 
138 // Setup for parameterized tests.
139 class LogEventTestBadAnnotationFieldTypes : public testing::TestWithParam<std::tuple<int, bool>> {
140 public:
ToString(testing::TestParamInfo<std::tuple<int,bool>> info)141     static std::string ToString(testing::TestParamInfo<std::tuple<int, bool>> info) {
142         const std::string boolName = std::get<1>(info.param) ? "_prefetchTrue" : "_prefetchFalse";
143 
144         switch (std::get<0>(info.param)) {
145             case INT32_TYPE:
146                 return "Int32" + boolName;
147             case INT64_TYPE:
148                 return "Int64" + boolName;
149             case STRING_TYPE:
150                 return "String" + boolName;
151             case LIST_TYPE:
152                 return "List" + boolName;
153             case FLOAT_TYPE:
154                 return "Float" + boolName;
155             case BYTE_ARRAY_TYPE:
156                 return "ByteArray" + boolName;
157             case ATTRIBUTION_CHAIN_TYPE:
158                 return "AttributionChain" + boolName;
159             default:
160                 return "Unknown" + boolName;
161         }
162     }
163 };
164 
165 // TODO(b/222539899): Add BOOL_TYPE value once parseAnnotations is updated to check specific
166 // typeIds. BOOL_TYPE should be a bad field type for is_uid, nested, and reset state annotations.
167 INSTANTIATE_TEST_SUITE_P(BadAnnotationFieldTypes, LogEventTestBadAnnotationFieldTypes,
168                          testing::Combine(testing::Values(INT32_TYPE, INT64_TYPE, STRING_TYPE,
169                                                           LIST_TYPE, FLOAT_TYPE, BYTE_ARRAY_TYPE,
170                                                           ATTRIBUTION_CHAIN_TYPE),
171                                           testing::Bool()),
172                          LogEventTestBadAnnotationFieldTypes::ToString);
173 
174 class LogEventTest : public testing::TestWithParam<bool> {
175 public:
ParseBuffer(LogEvent & logEvent,const uint8_t * buf,size_t size)176     bool ParseBuffer(LogEvent& logEvent, const uint8_t* buf, size_t size) {
177         size_t bufferOffset = 0;
178         if (GetParam()) {
179             // Testing LogEvent header prefetch logic
180             const LogEvent::BodyBufferInfo bodyInfo = logEvent.parseHeader(buf, size);
181             EXPECT_TRUE(logEvent.isParsedHeaderOnly());
182             const bool parseResult = logEvent.parseBody(bodyInfo);
183             EXPECT_EQ(parseResult, logEvent.isValid());
184             EXPECT_FALSE(logEvent.isParsedHeaderOnly());
185         } else {
186             const bool parseResult = logEvent.parseBuffer(buf, size);
187             EXPECT_EQ(parseResult, logEvent.isValid());
188             EXPECT_FALSE(logEvent.isParsedHeaderOnly());
189         }
190         return logEvent.isValid();
191     }
192 
ToString(testing::TestParamInfo<bool> info)193     static std::string ToString(testing::TestParamInfo<bool> info) {
194         return info.param ? "PrefetchTrue" : "PrefetchFalse";
195     }
196 };
197 
198 INSTANTIATE_TEST_SUITE_P(LogEventTestBufferParsing, LogEventTest, testing::Bool(),
199                          LogEventTest::ToString);
200 
TEST_P(LogEventTest,TestPrimitiveParsing)201 TEST_P(LogEventTest, TestPrimitiveParsing) {
202     AStatsEvent* event = AStatsEvent_obtain();
203     AStatsEvent_setAtomId(event, 100);
204     AStatsEvent_writeInt32(event, 10);
205     AStatsEvent_writeInt64(event, 0x123456789);
206     AStatsEvent_writeFloat(event, 2.0);
207     AStatsEvent_writeBool(event, true);
208     AStatsEvent_build(event);
209 
210     size_t size;
211     const uint8_t* buf = AStatsEvent_getBuffer(event, &size);
212 
213     LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
214     EXPECT_TRUE(ParseBuffer(logEvent, buf, size));
215 
216     EXPECT_EQ(100, logEvent.GetTagId());
217     EXPECT_EQ(1000, logEvent.GetUid());
218     EXPECT_EQ(1001, logEvent.GetPid());
219     EXPECT_FALSE(logEvent.hasAttributionChain());
220 
221     const vector<FieldValue>& values = logEvent.getValues();
222     ASSERT_EQ(4, values.size());
223 
224     const FieldValue& int32Item = values[0];
225     Field expectedField = getField(100, {1, 1, 1}, 0, {false, false, false});
226     EXPECT_EQ(expectedField, int32Item.mField);
227     EXPECT_EQ(Type::INT, int32Item.mValue.getType());
228     EXPECT_EQ(10, int32Item.mValue.int_value);
229 
230     const FieldValue& int64Item = values[1];
231     expectedField = getField(100, {2, 1, 1}, 0, {false, false, false});
232     EXPECT_EQ(expectedField, int64Item.mField);
233     EXPECT_EQ(Type::LONG, int64Item.mValue.getType());
234     EXPECT_EQ(0x123456789, int64Item.mValue.long_value);
235 
236     const FieldValue& floatItem = values[2];
237     expectedField = getField(100, {3, 1, 1}, 0, {false, false, false});
238     EXPECT_EQ(expectedField, floatItem.mField);
239     EXPECT_EQ(Type::FLOAT, floatItem.mValue.getType());
240     EXPECT_EQ(2.0, floatItem.mValue.float_value);
241 
242     const FieldValue& boolItem = values[3];
243     expectedField = getField(100, {4, 1, 1}, 0, {true, false, false});
244     EXPECT_EQ(expectedField, boolItem.mField);
245     EXPECT_EQ(Type::INT, boolItem.mValue.getType());  // FieldValue does not support boolean type
246     EXPECT_EQ(1, boolItem.mValue.int_value);
247 
248     AStatsEvent_release(event);
249 }
250 
TEST_P(LogEventTest,TestEventWithInvalidHeaderParsing)251 TEST_P(LogEventTest, TestEventWithInvalidHeaderParsing) {
252     AStatsEvent* event = AStatsEvent_obtain();
253     AStatsEvent_setAtomId(event, 100);
254     AStatsEvent_writeInt32(event, 10);
255     AStatsEvent_writeInt64(event, 0x123456789);
256     AStatsEvent_writeFloat(event, 2.0);
257     AStatsEvent_writeBool(event, true);
258     AStatsEvent_build(event);
259 
260     size_t size;
261     const uint8_t* buf = AStatsEvent_getBuffer(event, &size);
262 
263     // Corrupt LogEvent header info
264     // OBJECT_TYPE | NUM_FIELDS | TIMESTAMP | ATOM_ID
265     // Corrupting first 4 bytes will be sufficient
266     uint8_t* bufMod = const_cast<uint8_t*>(buf);
267     memset(static_cast<void*>(bufMod), 4, ERROR_TYPE);
268 
269     LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
270     EXPECT_FALSE(ParseBuffer(logEvent, buf, size));
271     EXPECT_FALSE(logEvent.isValid());
272     EXPECT_FALSE(logEvent.isParsedHeaderOnly());
273 
274     AStatsEvent_release(event);
275 }
276 
TEST(LogEventTestParsing,TestFetchHeaderOnly)277 TEST(LogEventTestParsing, TestFetchHeaderOnly) {
278     AStatsEvent* event = AStatsEvent_obtain();
279     AStatsEvent_setAtomId(event, 100);
280     AStatsEvent_writeInt32(event, 10);
281     AStatsEvent_writeInt64(event, 0x123456789);
282     AStatsEvent_writeFloat(event, 2.0);
283     AStatsEvent_writeBool(event, true);
284     AStatsEvent_build(event);
285 
286     size_t size;
287     const uint8_t* buf = AStatsEvent_getBuffer(event, &size);
288 
289     LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
290     const LogEvent::BodyBufferInfo bodyInfo = logEvent.parseHeader(buf, size);
291     EXPECT_TRUE(logEvent.isValid());
292     EXPECT_TRUE(logEvent.isParsedHeaderOnly());
293 
294     AStatsEvent_release(event);
295 
296     EXPECT_EQ(100, logEvent.GetTagId());
297     EXPECT_EQ(1000, logEvent.GetUid());
298     EXPECT_EQ(1001, logEvent.GetPid());
299     EXPECT_FALSE(logEvent.hasAttributionChain());
300     ASSERT_EQ(0, logEvent.getValues().size());
301 }
302 
TEST_P(LogEventTest,TestStringAndByteArrayParsing)303 TEST_P(LogEventTest, TestStringAndByteArrayParsing) {
304     AStatsEvent* event = AStatsEvent_obtain();
305     AStatsEvent_setAtomId(event, 100);
306     string str = "test";
307     AStatsEvent_writeString(event, str.c_str());
308     AStatsEvent_writeByteArray(event, (uint8_t*)str.c_str(), str.length());
309     AStatsEvent_build(event);
310 
311     size_t size;
312     const uint8_t* buf = AStatsEvent_getBuffer(event, &size);
313 
314     LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
315     EXPECT_TRUE(ParseBuffer(logEvent, buf, size));
316 
317     EXPECT_EQ(100, logEvent.GetTagId());
318     EXPECT_EQ(1000, logEvent.GetUid());
319     EXPECT_EQ(1001, logEvent.GetPid());
320     EXPECT_FALSE(logEvent.hasAttributionChain());
321 
322     const vector<FieldValue>& values = logEvent.getValues();
323     ASSERT_EQ(2, values.size());
324 
325     const FieldValue& stringItem = values[0];
326     Field expectedField = getField(100, {1, 1, 1}, 0, {false, false, false});
327     EXPECT_EQ(expectedField, stringItem.mField);
328     EXPECT_EQ(Type::STRING, stringItem.mValue.getType());
329     EXPECT_EQ(str, stringItem.mValue.str_value);
330 
331     const FieldValue& storageItem = values[1];
332     expectedField = getField(100, {2, 1, 1}, 0, {true, false, false});
333     EXPECT_EQ(expectedField, storageItem.mField);
334     EXPECT_EQ(Type::STORAGE, storageItem.mValue.getType());
335     vector<uint8_t> expectedValue = {'t', 'e', 's', 't'};
336     EXPECT_EQ(expectedValue, storageItem.mValue.storage_value);
337 
338     AStatsEvent_release(event);
339 }
340 
TEST_P(LogEventTest,TestEmptyString)341 TEST_P(LogEventTest, TestEmptyString) {
342     AStatsEvent* event = AStatsEvent_obtain();
343     AStatsEvent_setAtomId(event, 100);
344     string empty = "";
345     AStatsEvent_writeString(event, empty.c_str());
346     AStatsEvent_build(event);
347 
348     size_t size;
349     const uint8_t* buf = AStatsEvent_getBuffer(event, &size);
350 
351     LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
352     EXPECT_TRUE(ParseBuffer(logEvent, buf, size));
353 
354     EXPECT_EQ(100, logEvent.GetTagId());
355     EXPECT_EQ(1000, logEvent.GetUid());
356     EXPECT_EQ(1001, logEvent.GetPid());
357     EXPECT_FALSE(logEvent.hasAttributionChain());
358 
359     const vector<FieldValue>& values = logEvent.getValues();
360     ASSERT_EQ(1, values.size());
361 
362     const FieldValue& item = values[0];
363     Field expectedField = getField(100, {1, 1, 1}, 0, {true, false, false});
364     EXPECT_EQ(expectedField, item.mField);
365     EXPECT_EQ(Type::STRING, item.mValue.getType());
366     EXPECT_EQ(empty, item.mValue.str_value);
367 
368     AStatsEvent_release(event);
369 }
370 
TEST_P(LogEventTest,TestByteArrayWithNullCharacter)371 TEST_P(LogEventTest, TestByteArrayWithNullCharacter) {
372     AStatsEvent* event = AStatsEvent_obtain();
373     AStatsEvent_setAtomId(event, 100);
374     uint8_t message[] = {'\t', 'e', '\0', 's', 't'};
375     AStatsEvent_writeByteArray(event, message, 5);
376     AStatsEvent_build(event);
377 
378     size_t size;
379     const uint8_t* buf = AStatsEvent_getBuffer(event, &size);
380 
381     LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
382     EXPECT_TRUE(ParseBuffer(logEvent, buf, size));
383 
384     EXPECT_EQ(100, logEvent.GetTagId());
385     EXPECT_EQ(1000, logEvent.GetUid());
386     EXPECT_EQ(1001, logEvent.GetPid());
387 
388     const vector<FieldValue>& values = logEvent.getValues();
389     ASSERT_EQ(1, values.size());
390 
391     const FieldValue& item = values[0];
392     Field expectedField = getField(100, {1, 1, 1}, 0, {true, false, false});
393     EXPECT_EQ(expectedField, item.mField);
394     EXPECT_EQ(Type::STORAGE, item.mValue.getType());
395     vector<uint8_t> expectedValue(message, message + 5);
396     EXPECT_EQ(expectedValue, item.mValue.storage_value);
397 
398     AStatsEvent_release(event);
399 }
400 
TEST_P(LogEventTest,TestTooManyTopLevelElements)401 TEST_P(LogEventTest, TestTooManyTopLevelElements) {
402     int32_t numElements = 128;
403     AStatsEvent* event = AStatsEvent_obtain();
404     AStatsEvent_setAtomId(event, 100);
405 
406     for (int i = 0; i < numElements; i++) {
407         AStatsEvent_writeInt32(event, i);
408     }
409 
410     AStatsEvent_build(event);
411 
412     size_t size;
413     const uint8_t* buf = AStatsEvent_getBuffer(event, &size);
414     LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
415     EXPECT_FALSE(ParseBuffer(logEvent, buf, size));
416 
417     AStatsEvent_release(event);
418 }
419 
TEST_P(LogEventTest,TestAttributionChain)420 TEST_P(LogEventTest, TestAttributionChain) {
421     AStatsEvent* event = AStatsEvent_obtain();
422     AStatsEvent_setAtomId(event, 100);
423 
424     string tag1 = "tag1";
425     string tag2 = "tag2";
426 
427     uint32_t uids[] = {1001, 1002};
428     const char* tags[] = {tag1.c_str(), tag2.c_str()};
429 
430     AStatsEvent_writeAttributionChain(event, uids, tags, 2);
431     AStatsEvent_build(event);
432 
433     size_t size;
434     const uint8_t* buf = AStatsEvent_getBuffer(event, &size);
435 
436     LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
437     EXPECT_TRUE(ParseBuffer(logEvent, buf, size));
438 
439     EXPECT_EQ(100, logEvent.GetTagId());
440     EXPECT_EQ(1000, logEvent.GetUid());
441     EXPECT_EQ(1001, logEvent.GetPid());
442 
443     const vector<FieldValue>& values = logEvent.getValues();
444     ASSERT_EQ(4, values.size());  // 2 per attribution node
445 
446     std::pair<size_t, size_t> attrIndexRange;
447     EXPECT_TRUE(logEvent.hasAttributionChain(&attrIndexRange));
448     EXPECT_EQ(0, attrIndexRange.first);
449     EXPECT_EQ(3, attrIndexRange.second);
450 
451     // Check first attribution node
452     const FieldValue& uid1Item = values[0];
453     Field expectedField = getField(100, {1, 1, 1}, 2, {true, false, false});
454     EXPECT_EQ(expectedField, uid1Item.mField);
455     EXPECT_EQ(Type::INT, uid1Item.mValue.getType());
456     EXPECT_EQ(1001, uid1Item.mValue.int_value);
457 
458     const FieldValue& tag1Item = values[1];
459     expectedField = getField(100, {1, 1, 2}, 2, {true, false, true});
460     EXPECT_EQ(expectedField, tag1Item.mField);
461     EXPECT_EQ(Type::STRING, tag1Item.mValue.getType());
462     EXPECT_EQ(tag1, tag1Item.mValue.str_value);
463 
464     // Check second attribution nodes
465     const FieldValue& uid2Item = values[2];
466     expectedField = getField(100, {1, 2, 1}, 2, {true, true, false});
467     EXPECT_EQ(expectedField, uid2Item.mField);
468     EXPECT_EQ(Type::INT, uid2Item.mValue.getType());
469     EXPECT_EQ(1002, uid2Item.mValue.int_value);
470 
471     const FieldValue& tag2Item = values[3];
472     expectedField = getField(100, {1, 2, 2}, 2, {true, true, true});
473     EXPECT_EQ(expectedField, tag2Item.mField);
474     EXPECT_EQ(Type::STRING, tag2Item.mValue.getType());
475     EXPECT_EQ(tag2, tag2Item.mValue.str_value);
476 
477     AStatsEvent_release(event);
478 }
479 
TEST_P(LogEventTest,TestEmptyAttributionChain)480 TEST_P(LogEventTest, TestEmptyAttributionChain) {
481     AStatsEvent* event = AStatsEvent_obtain();
482     AStatsEvent_setAtomId(event, 100);
483 
484     AStatsEvent_writeAttributionChain(event, {}, {}, 0);
485     AStatsEvent_writeInt32(event, 10);
486     AStatsEvent_build(event);
487 
488     size_t size;
489     const uint8_t* buf = AStatsEvent_getBuffer(event, &size);
490 
491     LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
492     EXPECT_FALSE(ParseBuffer(logEvent, buf, size));
493 
494     AStatsEvent_release(event);
495 }
496 
TEST_P(LogEventTest,TestAttributionChainTooManyElements)497 TEST_P(LogEventTest, TestAttributionChainTooManyElements) {
498     int32_t numNodes = 128;
499     uint32_t uids[numNodes];
500     vector<string> tags(numNodes);  // storage that cTag elements point to
501     const char* cTags[numNodes];
502 
503     for (int i = 0; i < numNodes; i++) {
504         uids[i] = i;
505         tags.push_back("test");
506         cTags[i] = tags[i].c_str();
507     }
508 
509     AStatsEvent* event = AStatsEvent_obtain();
510     AStatsEvent_setAtomId(event, 100);
511     AStatsEvent_writeAttributionChain(event, uids, cTags, numNodes);
512     AStatsEvent_build(event);
513 
514     size_t size;
515     const uint8_t* buf = AStatsEvent_getBuffer(event, &size);
516     LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
517     EXPECT_FALSE(ParseBuffer(logEvent, buf, size));
518 
519     AStatsEvent_release(event);
520 }
521 
TEST_P(LogEventTest,TestArrayParsing)522 TEST_P(LogEventTest, TestArrayParsing) {
523     size_t numElements = 2;
524     int32_t int32Array[2] = {3, 6};
525     int64_t int64Array[2] = {1000L, 1002L};
526     float floatArray[2] = {0.3f, 0.09f};
527     bool boolArray[2] = {0, 1};
528 
529     vector<string> stringArray = {"str1", "str2"};
530     const char* cStringArray[2];
531     for (int i = 0; i < numElements; i++) {
532         cStringArray[i] = stringArray[i].c_str();
533     }
534 
535     AStatsEvent* event = AStatsEvent_obtain();
536     AStatsEvent_setAtomId(event, 100);
537     AStatsEvent_writeInt32Array(event, int32Array, numElements);
538     AStatsEvent_writeInt64Array(event, int64Array, numElements);
539     AStatsEvent_writeFloatArray(event, floatArray, numElements);
540     AStatsEvent_writeBoolArray(event, boolArray, numElements);
541     AStatsEvent_writeStringArray(event, cStringArray, numElements);
542     AStatsEvent_build(event);
543 
544     size_t size;
545     const uint8_t* buf = AStatsEvent_getBuffer(event, &size);
546 
547     LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
548     EXPECT_TRUE(ParseBuffer(logEvent, buf, size));
549 
550     EXPECT_EQ(100, logEvent.GetTagId());
551     EXPECT_EQ(1000, logEvent.GetUid());
552     EXPECT_EQ(1001, logEvent.GetPid());
553     EXPECT_FALSE(logEvent.hasAttributionChain());
554 
555     const vector<FieldValue>& values = logEvent.getValues();
556     ASSERT_EQ(10, values.size());  // 2 for each array type
557 
558     const FieldValue& int32ArrayItem1 = values[0];
559     Field expectedField = getField(100, {1, 1, 1}, 1, {false, false, false});
560     EXPECT_EQ(expectedField, int32ArrayItem1.mField);
561     EXPECT_EQ(Type::INT, int32ArrayItem1.mValue.getType());
562     EXPECT_EQ(3, int32ArrayItem1.mValue.int_value);
563 
564     const FieldValue& int32ArrayItem2 = values[1];
565     expectedField = getField(100, {1, 2, 1}, 1, {false, true, false});
566     EXPECT_EQ(expectedField, int32ArrayItem2.mField);
567     EXPECT_EQ(Type::INT, int32ArrayItem2.mValue.getType());
568     EXPECT_EQ(6, int32ArrayItem2.mValue.int_value);
569 
570     const FieldValue& int64ArrayItem1 = values[2];
571     expectedField = getField(100, {2, 1, 1}, 1, {false, false, false});
572     EXPECT_EQ(expectedField, int64ArrayItem1.mField);
573     EXPECT_EQ(Type::LONG, int64ArrayItem1.mValue.getType());
574     EXPECT_EQ(1000L, int64ArrayItem1.mValue.long_value);
575 
576     const FieldValue& int64ArrayItem2 = values[3];
577     expectedField = getField(100, {2, 2, 1}, 1, {false, true, false});
578     EXPECT_EQ(expectedField, int64ArrayItem2.mField);
579     EXPECT_EQ(Type::LONG, int64ArrayItem2.mValue.getType());
580     EXPECT_EQ(1002L, int64ArrayItem2.mValue.long_value);
581 
582     const FieldValue& floatArrayItem1 = values[4];
583     expectedField = getField(100, {3, 1, 1}, 1, {false, false, false});
584     EXPECT_EQ(expectedField, floatArrayItem1.mField);
585     EXPECT_EQ(Type::FLOAT, floatArrayItem1.mValue.getType());
586     EXPECT_EQ(0.3f, floatArrayItem1.mValue.float_value);
587 
588     const FieldValue& floatArrayItem2 = values[5];
589     expectedField = getField(100, {3, 2, 1}, 1, {false, true, false});
590     EXPECT_EQ(expectedField, floatArrayItem2.mField);
591     EXPECT_EQ(Type::FLOAT, floatArrayItem2.mValue.getType());
592     EXPECT_EQ(0.09f, floatArrayItem2.mValue.float_value);
593 
594     const FieldValue& boolArrayItem1 = values[6];
595     expectedField = getField(100, {4, 1, 1}, 1, {false, false, false});
596     EXPECT_EQ(expectedField, boolArrayItem1.mField);
597     EXPECT_EQ(Type::INT,
598               boolArrayItem1.mValue.getType());  // FieldValue does not support boolean type
599     EXPECT_EQ(false, boolArrayItem1.mValue.int_value);
600 
601     const FieldValue& boolArrayItem2 = values[7];
602     expectedField = getField(100, {4, 2, 1}, 1, {false, true, false});
603     EXPECT_EQ(expectedField, boolArrayItem2.mField);
604     EXPECT_EQ(Type::INT,
605               boolArrayItem2.mValue.getType());  // FieldValue does not support boolean type
606     EXPECT_EQ(true, boolArrayItem2.mValue.int_value);
607 
608     const FieldValue& stringArrayItem1 = values[8];
609     expectedField = getField(100, {5, 1, 1}, 1, {true, false, false});
610     EXPECT_EQ(expectedField, stringArrayItem1.mField);
611     EXPECT_EQ(Type::STRING, stringArrayItem1.mValue.getType());
612     EXPECT_EQ("str1", stringArrayItem1.mValue.str_value);
613 
614     const FieldValue& stringArrayItem2 = values[9];
615     expectedField = getField(100, {5, 2, 1}, 1, {true, true, false});
616     EXPECT_EQ(expectedField, stringArrayItem2.mField);
617     EXPECT_EQ(Type::STRING, stringArrayItem2.mValue.getType());
618     EXPECT_EQ("str2", stringArrayItem2.mValue.str_value);
619 }
620 
TEST_P(LogEventTest,TestEmptyStringArray)621 TEST_P(LogEventTest, TestEmptyStringArray) {
622     const char* cStringArray[2];
623     string empty = "";
624     cStringArray[0] = empty.c_str();
625     cStringArray[1] = empty.c_str();
626 
627     AStatsEvent* event = AStatsEvent_obtain();
628     AStatsEvent_setAtomId(event, 100);
629     AStatsEvent_writeStringArray(event, cStringArray, 2);
630     AStatsEvent_build(event);
631 
632     size_t size;
633     const uint8_t* buf = AStatsEvent_getBuffer(event, &size);
634 
635     LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
636     EXPECT_TRUE(ParseBuffer(logEvent, buf, size));
637 
638     EXPECT_EQ(100, logEvent.GetTagId());
639     EXPECT_EQ(1000, logEvent.GetUid());
640     EXPECT_EQ(1001, logEvent.GetPid());
641 
642     const vector<FieldValue>& values = logEvent.getValues();
643     ASSERT_EQ(2, values.size());
644 
645     const FieldValue& stringArrayItem1 = values[0];
646     Field expectedField = getField(100, {1, 1, 1}, 1, {true, false, false});
647     EXPECT_EQ(expectedField, stringArrayItem1.mField);
648     EXPECT_EQ(Type::STRING, stringArrayItem1.mValue.getType());
649     EXPECT_EQ(empty, stringArrayItem1.mValue.str_value);
650 
651     const FieldValue& stringArrayItem2 = values[1];
652     expectedField = getField(100, {1, 2, 1}, 1, {true, true, false});
653     EXPECT_EQ(expectedField, stringArrayItem2.mField);
654     EXPECT_EQ(Type::STRING, stringArrayItem2.mValue.getType());
655     EXPECT_EQ(empty, stringArrayItem2.mValue.str_value);
656 
657     AStatsEvent_release(event);
658 }
659 
TEST_P(LogEventTest,TestArrayTooManyElements)660 TEST_P(LogEventTest, TestArrayTooManyElements) {
661     int32_t numElements = 128;
662     int32_t int32Array[numElements];
663 
664     for (int i = 0; i < numElements; i++) {
665         int32Array[i] = 1;
666     }
667 
668     AStatsEvent* event = AStatsEvent_obtain();
669     AStatsEvent_setAtomId(event, 100);
670     AStatsEvent_writeInt32Array(event, int32Array, numElements);
671     AStatsEvent_build(event);
672 
673     size_t size;
674     const uint8_t* buf = AStatsEvent_getBuffer(event, &size);
675 
676     LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
677     EXPECT_FALSE(ParseBuffer(logEvent, buf, size));
678 
679     AStatsEvent_release(event);
680 }
681 
TEST_P(LogEventTest,TestEmptyArray)682 TEST_P(LogEventTest, TestEmptyArray) {
683     int32_t int32Array[0] = {};
684 
685     AStatsEvent* event = AStatsEvent_obtain();
686     AStatsEvent_setAtomId(event, 100);
687     AStatsEvent_writeInt32Array(event, int32Array, 0);
688     AStatsEvent_build(event);
689 
690     size_t size;
691     const uint8_t* buf = AStatsEvent_getBuffer(event, &size);
692 
693     LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
694     EXPECT_TRUE(ParseBuffer(logEvent, buf, size));
695 
696     EXPECT_EQ(100, logEvent.GetTagId());
697     EXPECT_EQ(1000, logEvent.GetUid());
698     EXPECT_EQ(1001, logEvent.GetPid());
699 
700     ASSERT_EQ(logEvent.getValues().size(), 0);
701 
702     AStatsEvent_release(event);
703 }
704 
TEST_P(LogEventTest,TestEmptyArrayWithAnnotations)705 TEST_P(LogEventTest, TestEmptyArrayWithAnnotations) {
706     int32_t int32Array[0] = {};
707 
708     AStatsEvent* event = AStatsEvent_obtain();
709     AStatsEvent_setAtomId(event, 100);
710     AStatsEvent_writeInt32Array(event, int32Array, 0);
711     AStatsEvent_addBoolAnnotation(event, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
712     AStatsEvent_build(event);
713 
714     size_t size;
715     const uint8_t* buf = AStatsEvent_getBuffer(event, &size);
716 
717     LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
718     EXPECT_TRUE(ParseBuffer(logEvent, buf, size));
719 
720     EXPECT_EQ(100, logEvent.GetTagId());
721     EXPECT_EQ(1000, logEvent.GetUid());
722     EXPECT_EQ(1001, logEvent.GetPid());
723 
724     ASSERT_EQ(logEvent.getValues().size(), 0);
725 
726     AStatsEvent_release(event);
727 }
728 
TEST_P(LogEventTest,TestAnnotationIdIsUid)729 TEST_P(LogEventTest, TestAnnotationIdIsUid) {
730     LogEvent event(/*uid=*/0, /*pid=*/0);
731     EXPECT_TRUE(createFieldWithBoolAnnotationLogEvent(&event, INT32_TYPE,
732                                                       ASTATSLOG_ANNOTATION_ID_IS_UID, true,
733                                                       /*doHeaderPrefetch=*/GetParam()));
734 
735     ASSERT_EQ(event.getNumUidFields(), 1);
736 
737     const vector<FieldValue>& values = event.getValues();
738     ASSERT_EQ(values.size(), 1);
739     EXPECT_TRUE(isUidField(values.at(0)));
740 }
741 
TEST_P(LogEventTest,TestAnnotationIdIsUid_RepeatedIntAndOtherFields)742 TEST_P(LogEventTest, TestAnnotationIdIsUid_RepeatedIntAndOtherFields) {
743     size_t numElements = 2;
744     int32_t int32Array[2] = {3, 6};
745 
746     vector<string> stringArray = {"str1", "str2"};
747     const char* cStringArray[2];
748     for (int i = 0; i < numElements; i++) {
749         cStringArray[i] = stringArray[i].c_str();
750     }
751 
752     AStatsEvent* statsEvent = AStatsEvent_obtain();
753     AStatsEvent_setAtomId(statsEvent, 100);
754     AStatsEvent_writeInt32(statsEvent, 5);
755     AStatsEvent_writeInt32Array(statsEvent, int32Array, numElements);
756     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
757     AStatsEvent_writeStringArray(statsEvent, cStringArray, numElements);
758     AStatsEvent_build(statsEvent);
759 
760     size_t size;
761     const uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
762     LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
763     EXPECT_TRUE(ParseBuffer(logEvent, buf, size));
764     EXPECT_EQ(2, logEvent.getNumUidFields());
765 
766     const vector<FieldValue>& values = logEvent.getValues();
767     ASSERT_EQ(values.size(), 5);
768     EXPECT_FALSE(isUidField(values.at(0)));
769     EXPECT_TRUE(isUidField(values.at(1)));
770     EXPECT_TRUE(isUidField(values.at(2)));
771     EXPECT_FALSE(isUidField(values.at(3)));
772     EXPECT_FALSE(isUidField(values.at(4)));
773 }
774 
TEST_P(LogEventTest,TestAnnotationIdIsUid_RepeatedIntOneEntry)775 TEST_P(LogEventTest, TestAnnotationIdIsUid_RepeatedIntOneEntry) {
776     size_t numElements = 1;
777     int32_t int32Array[1] = {3};
778 
779     AStatsEvent* statsEvent = AStatsEvent_obtain();
780     AStatsEvent_setAtomId(statsEvent, 100);
781     AStatsEvent_writeInt32Array(statsEvent, int32Array, numElements);
782     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
783     AStatsEvent_build(statsEvent);
784 
785     size_t size;
786     const uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
787     LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
788     EXPECT_TRUE(ParseBuffer(logEvent, buf, size));
789     EXPECT_EQ(1, logEvent.getNumUidFields());
790 
791     const vector<FieldValue>& values = logEvent.getValues();
792     ASSERT_EQ(values.size(), 1);
793     EXPECT_TRUE(isUidField(values.at(0)));
794 }
795 
TEST_P(LogEventTest,TestAnnotationIdIsUid_EmptyIntArray)796 TEST_P(LogEventTest, TestAnnotationIdIsUid_EmptyIntArray) {
797     int32_t int32Array[0] = {};
798 
799     AStatsEvent* statsEvent = AStatsEvent_obtain();
800     AStatsEvent_setAtomId(statsEvent, 100);
801     AStatsEvent_writeInt32Array(statsEvent, int32Array, /*numElements*/ 0);
802     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
803     AStatsEvent_writeInt32(statsEvent, 5);
804     AStatsEvent_build(statsEvent);
805 
806     size_t size;
807     const uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
808     LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
809     EXPECT_TRUE(ParseBuffer(logEvent, buf, size));
810     EXPECT_EQ(0, logEvent.getNumUidFields());
811 
812     const vector<FieldValue>& values = logEvent.getValues();
813     EXPECT_EQ(values.size(), 1);
814 }
815 
TEST_P(LogEventTest,TestAnnotationIdIsUid_BadRepeatedInt64)816 TEST_P(LogEventTest, TestAnnotationIdIsUid_BadRepeatedInt64) {
817     int64_t int64Array[2] = {1000L, 1002L};
818 
819     AStatsEvent* statsEvent = AStatsEvent_obtain();
820     AStatsEvent_setAtomId(statsEvent, /*atomId=*/100);
821     AStatsEvent_writeInt64Array(statsEvent, int64Array, /*numElements*/ 2);
822     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
823     AStatsEvent_build(statsEvent);
824 
825     size_t size;
826     const uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
827     LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
828 
829     EXPECT_FALSE(ParseBuffer(logEvent, buf, size));
830     EXPECT_EQ(0, logEvent.getNumUidFields());
831 
832     AStatsEvent_release(statsEvent);
833 }
834 
TEST_P(LogEventTest,TestAnnotationIdIsUid_BadRepeatedString)835 TEST_P(LogEventTest, TestAnnotationIdIsUid_BadRepeatedString) {
836     size_t numElements = 2;
837     vector<string> stringArray = {"str1", "str2"};
838     const char* cStringArray[2];
839     for (int i = 0; i < numElements; i++) {
840         cStringArray[i] = stringArray[i].c_str();
841     }
842 
843     AStatsEvent* statsEvent = AStatsEvent_obtain();
844     AStatsEvent_setAtomId(statsEvent, /*atomId=*/100);
845     AStatsEvent_writeStringArray(statsEvent, cStringArray, /*numElements*/ 2);
846     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
847     AStatsEvent_build(statsEvent);
848 
849     size_t size;
850     const uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
851     LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
852 
853     EXPECT_FALSE(ParseBuffer(logEvent, buf, size));
854     EXPECT_EQ(0, logEvent.getNumUidFields());
855 
856     AStatsEvent_release(statsEvent);
857 }
858 
TEST_P(LogEventTestBadAnnotationFieldTypes,TestAnnotationIdIsUid)859 TEST_P(LogEventTestBadAnnotationFieldTypes, TestAnnotationIdIsUid) {
860     LogEvent event(/*uid=*/0, /*pid=*/0);
861 
862     if (std::get<0>(GetParam()) != INT32_TYPE && std::get<0>(GetParam()) != LIST_TYPE) {
863         EXPECT_FALSE(createFieldWithBoolAnnotationLogEvent(
864                 &event, std::get<0>(GetParam()), ASTATSLOG_ANNOTATION_ID_IS_UID, true,
865                 /*doHeaderPrefetch=*/std::get<1>(GetParam())));
866     }
867 }
868 
TEST_P(LogEventTest,TestAnnotationIdIsUid_NotIntAnnotation)869 TEST_P(LogEventTest, TestAnnotationIdIsUid_NotIntAnnotation) {
870     LogEvent event(/*uid=*/0, /*pid=*/0);
871     EXPECT_FALSE(createFieldWithIntAnnotationLogEvent(&event, INT32_TYPE,
872                                                       ASTATSLOG_ANNOTATION_ID_IS_UID, 10,
873                                                       /*doHeaderPrefetch=*/GetParam()));
874 }
875 
TEST_P(LogEventTest,TestAnnotationIdStateNested)876 TEST_P(LogEventTest, TestAnnotationIdStateNested) {
877     LogEvent event(/*uid=*/0, /*pid=*/0);
878     EXPECT_TRUE(createFieldWithBoolAnnotationLogEvent(&event, INT32_TYPE,
879                                                       ASTATSLOG_ANNOTATION_ID_STATE_NESTED, true,
880                                                       /*doHeaderPrefetch=*/GetParam()));
881 
882     const vector<FieldValue>& values = event.getValues();
883     ASSERT_EQ(values.size(), 1);
884     EXPECT_TRUE(values[0].mAnnotations.isNested());
885 }
886 
TEST_P(LogEventTestBadAnnotationFieldTypes,TestAnnotationIdStateNested)887 TEST_P(LogEventTestBadAnnotationFieldTypes, TestAnnotationIdStateNested) {
888     LogEvent event(/*uid=*/0, /*pid=*/0);
889 
890     if (std::get<0>(GetParam()) != INT32_TYPE) {
891         EXPECT_FALSE(createFieldWithBoolAnnotationLogEvent(
892                 &event, std::get<0>(GetParam()), ASTATSLOG_ANNOTATION_ID_STATE_NESTED, true,
893                 /*doHeaderPrefetch=*/std::get<1>(GetParam())));
894     }
895 }
896 
TEST_P(LogEventTest,TestAnnotationIdStateNested_NotIntAnnotation)897 TEST_P(LogEventTest, TestAnnotationIdStateNested_NotIntAnnotation) {
898     LogEvent event(/*uid=*/0, /*pid=*/0);
899     EXPECT_FALSE(createFieldWithIntAnnotationLogEvent(&event, INT32_TYPE,
900                                                       ASTATSLOG_ANNOTATION_ID_STATE_NESTED, 10,
901                                                       /*doHeaderPrefetch=*/GetParam()));
902 }
903 
TEST_P(LogEventTest,TestPrimaryFieldAnnotation)904 TEST_P(LogEventTest, TestPrimaryFieldAnnotation) {
905     LogEvent event(/*uid=*/0, /*pid=*/0);
906     EXPECT_TRUE(createFieldWithBoolAnnotationLogEvent(&event, INT32_TYPE,
907                                                       ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD, true,
908                                                       /*doHeaderPrefetch=*/GetParam()));
909 
910     const vector<FieldValue>& values = event.getValues();
911     ASSERT_EQ(values.size(), 1);
912     EXPECT_TRUE(values[0].mAnnotations.isPrimaryField());
913 }
914 
TEST_P(LogEventTestBadAnnotationFieldTypes,TestPrimaryFieldAnnotation)915 TEST_P(LogEventTestBadAnnotationFieldTypes, TestPrimaryFieldAnnotation) {
916     LogEvent event(/*uid=*/0, /*pid=*/0);
917 
918     if (std::get<0>(GetParam()) == LIST_TYPE || std::get<0>(GetParam()) == ATTRIBUTION_CHAIN_TYPE) {
919         EXPECT_FALSE(createFieldWithBoolAnnotationLogEvent(
920                 &event, std::get<0>(GetParam()), ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD, true,
921                 /*doHeaderPrefetch=*/std::get<1>(GetParam())));
922     }
923 }
924 
TEST_P(LogEventTest,TestPrimaryFieldAnnotation_NotIntAnnotation)925 TEST_P(LogEventTest, TestPrimaryFieldAnnotation_NotIntAnnotation) {
926     LogEvent event(/*uid=*/0, /*pid=*/0);
927     EXPECT_FALSE(createFieldWithIntAnnotationLogEvent(&event, INT32_TYPE,
928                                                       ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD, 10,
929                                                       /*doHeaderPrefetch=*/GetParam()));
930 }
931 
TEST_P(LogEventTest,TestExclusiveStateAnnotation)932 TEST_P(LogEventTest, TestExclusiveStateAnnotation) {
933     LogEvent event(/*uid=*/0, /*pid=*/0);
934     EXPECT_TRUE(createFieldWithBoolAnnotationLogEvent(&event, INT32_TYPE,
935                                                       ASTATSLOG_ANNOTATION_ID_EXCLUSIVE_STATE, true,
936                                                       /*doHeaderPrefetch=*/GetParam()));
937 
938     const vector<FieldValue>& values = event.getValues();
939     ASSERT_EQ(values.size(), 1);
940     EXPECT_TRUE(values[0].mAnnotations.isExclusiveState());
941 }
942 
TEST_P(LogEventTestBadAnnotationFieldTypes,TestExclusiveStateAnnotation)943 TEST_P(LogEventTestBadAnnotationFieldTypes, TestExclusiveStateAnnotation) {
944     LogEvent event(/*uid=*/0, /*pid=*/0);
945 
946     if (std::get<0>(GetParam()) != INT32_TYPE) {
947         EXPECT_FALSE(createFieldWithBoolAnnotationLogEvent(
948                 &event, std::get<0>(GetParam()), ASTATSLOG_ANNOTATION_ID_EXCLUSIVE_STATE, true,
949                 /*doHeaderPrefetch=*/std::get<1>(GetParam())));
950     }
951 }
952 
TEST_P(LogEventTest,TestExclusiveStateAnnotation_NotIntAnnotation)953 TEST_P(LogEventTest, TestExclusiveStateAnnotation_NotIntAnnotation) {
954     LogEvent event(/*uid=*/0, /*pid=*/0);
955     EXPECT_FALSE(createFieldWithIntAnnotationLogEvent(&event, INT32_TYPE,
956                                                       ASTATSLOG_ANNOTATION_ID_EXCLUSIVE_STATE, 10,
957                                                       /*doHeaderPrefetch=*/GetParam()));
958 }
959 
TEST_P(LogEventTest,TestPrimaryFieldFirstUidAnnotation)960 TEST_P(LogEventTest, TestPrimaryFieldFirstUidAnnotation) {
961     // Event has 10 ints and then an attribution chain
962     int numInts = 10;
963     int firstUidInChainIndex = numInts;
964     string tag1 = "tag1";
965     string tag2 = "tag2";
966     uint32_t uids[] = {1001, 1002};
967     const char* tags[] = {tag1.c_str(), tag2.c_str()};
968 
969     // Construct AStatsEvent
970     AStatsEvent* statsEvent = AStatsEvent_obtain();
971     AStatsEvent_setAtomId(statsEvent, 100);
972     for (int i = 0; i < numInts; i++) {
973         AStatsEvent_writeInt32(statsEvent, 10);
974     }
975     AStatsEvent_writeAttributionChain(statsEvent, uids, tags, 2);
976     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID,
977                                   true);
978     AStatsEvent_build(statsEvent);
979 
980     // Construct LogEvent
981     size_t size;
982     const uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
983     LogEvent logEvent(/*uid=*/0, /*pid=*/0);
984     EXPECT_TRUE(ParseBuffer(logEvent, buf, size));
985     AStatsEvent_release(statsEvent);
986 
987     // Check annotation
988     const vector<FieldValue>& values = logEvent.getValues();
989     ASSERT_EQ(values.size(), numInts + 4);
990     EXPECT_TRUE(values[firstUidInChainIndex].mAnnotations.isPrimaryField());
991 }
992 
TEST_P(LogEventTestBadAnnotationFieldTypes,TestPrimaryFieldFirstUidAnnotation)993 TEST_P(LogEventTestBadAnnotationFieldTypes, TestPrimaryFieldFirstUidAnnotation) {
994     LogEvent event(/*uid=*/0, /*pid=*/0);
995 
996     if (std::get<0>(GetParam()) != ATTRIBUTION_CHAIN_TYPE) {
997         EXPECT_FALSE(createFieldWithBoolAnnotationLogEvent(
998                 &event, std::get<0>(GetParam()), ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID,
999                 true,
1000                 /*doHeaderPrefetch=*/std::get<1>(GetParam())));
1001     }
1002 }
1003 
TEST_P(LogEventTest,TestPrimaryFieldFirstUidAnnotation_NotIntAnnotation)1004 TEST_P(LogEventTest, TestPrimaryFieldFirstUidAnnotation_NotIntAnnotation) {
1005     LogEvent event(/*uid=*/0, /*pid=*/0);
1006     EXPECT_FALSE(createFieldWithIntAnnotationLogEvent(
1007             &event, ATTRIBUTION_CHAIN_TYPE, ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID, 10,
1008             /*doHeaderPrefetch=*/GetParam()));
1009 }
1010 
TEST_P(LogEventTest,TestResetStateAnnotation)1011 TEST_P(LogEventTest, TestResetStateAnnotation) {
1012     int32_t resetState = 10;
1013     LogEvent event(/*uid=*/0, /*pid=*/0);
1014     EXPECT_TRUE(createFieldWithIntAnnotationLogEvent(
1015             &event, INT32_TYPE, ASTATSLOG_ANNOTATION_ID_TRIGGER_STATE_RESET, resetState,
1016             /*doHeaderPrefetch=*/GetParam()));
1017 
1018     const vector<FieldValue>& values = event.getValues();
1019     ASSERT_EQ(values.size(), 1);
1020     EXPECT_EQ(event.getResetState(), resetState);
1021 }
1022 
TEST_P(LogEventTest,TestRestrictionCategoryAnnotation)1023 TEST_P(LogEventTest, TestRestrictionCategoryAnnotation) {
1024     if (!isAtLeastU()) {
1025         GTEST_SKIP();
1026     }
1027     int32_t restrictionCategory = ASTATSLOG_RESTRICTION_CATEGORY_DIAGNOSTIC;
1028     LogEvent event(/*uid=*/0, /*pid=*/0);
1029     EXPECT_TRUE(createAtomLevelIntAnnotationLogEvent(
1030             &event, INT32_TYPE, ASTATSLOG_ANNOTATION_ID_RESTRICTION_CATEGORY, restrictionCategory,
1031             /*doHeaderPrefetch=*/GetParam()));
1032 
1033     ASSERT_EQ(event.getRestrictionCategory(), restrictionCategory);
1034 }
1035 
TEST_P(LogEventTest,TestInvalidRestrictionCategoryAnnotation)1036 TEST_P(LogEventTest, TestInvalidRestrictionCategoryAnnotation) {
1037     if (!isAtLeastU()) {
1038         GTEST_SKIP();
1039     }
1040     int32_t restrictionCategory = 619;  // unknown category
1041     LogEvent event(/*uid=*/0, /*pid=*/0);
1042     EXPECT_FALSE(createAtomLevelIntAnnotationLogEvent(
1043             &event, INT32_TYPE, ASTATSLOG_ANNOTATION_ID_RESTRICTION_CATEGORY, restrictionCategory,
1044             /*doHeaderPrefetch=*/GetParam()));
1045 }
1046 
TEST_P(LogEventTest,TestRestrictionCategoryAnnotationBelowUDevice)1047 TEST_P(LogEventTest, TestRestrictionCategoryAnnotationBelowUDevice) {
1048     if (isAtLeastU()) {
1049         GTEST_SKIP();
1050     }
1051     int32_t restrictionCategory = ASTATSLOG_RESTRICTION_CATEGORY_DIAGNOSTIC;
1052     LogEvent event(/*uid=*/0, /*pid=*/0);
1053     EXPECT_FALSE(createAtomLevelIntAnnotationLogEvent(
1054             &event, INT32_TYPE, ASTATSLOG_ANNOTATION_ID_RESTRICTION_CATEGORY, restrictionCategory,
1055             /*doHeaderPrefetch=*/GetParam()));
1056 }
1057 
TEST_P(LogEventTestBadAnnotationFieldTypes,TestResetStateAnnotation)1058 TEST_P(LogEventTestBadAnnotationFieldTypes, TestResetStateAnnotation) {
1059     LogEvent event(/*uid=*/0, /*pid=*/0);
1060     int32_t resetState = 10;
1061 
1062     if (std::get<0>(GetParam()) != INT32_TYPE) {
1063         EXPECT_FALSE(createFieldWithIntAnnotationLogEvent(
1064                 &event, std::get<0>(GetParam()), ASTATSLOG_ANNOTATION_ID_TRIGGER_STATE_RESET,
1065                 resetState,
1066                 /*doHeaderPrefetch=*/std::get<1>(GetParam())));
1067     }
1068 }
1069 
TEST_P(LogEventTest,TestResetStateAnnotation_NotBoolAnnotation)1070 TEST_P(LogEventTest, TestResetStateAnnotation_NotBoolAnnotation) {
1071     LogEvent event(/*uid=*/0, /*pid=*/0);
1072     EXPECT_FALSE(createFieldWithBoolAnnotationLogEvent(
1073             &event, INT32_TYPE, ASTATSLOG_ANNOTATION_ID_TRIGGER_STATE_RESET, true,
1074             /*doHeaderPrefetch=*/GetParam()));
1075 }
1076 
TEST_P(LogEventTest,TestUidAnnotationWithInt8MaxValues)1077 TEST_P(LogEventTest, TestUidAnnotationWithInt8MaxValues) {
1078     int32_t numElements = INT8_MAX;
1079     int32_t int32Array[numElements];
1080 
1081     for (int i = 0; i < numElements; i++) {
1082         int32Array[i] = i;
1083     }
1084 
1085     AStatsEvent* event = AStatsEvent_obtain();
1086     AStatsEvent_setAtomId(event, 100);
1087     AStatsEvent_writeInt32Array(event, int32Array, numElements);
1088     AStatsEvent_writeInt32(event, 10);
1089     AStatsEvent_writeInt32(event, 11);
1090     AStatsEvent_addBoolAnnotation(event, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
1091     AStatsEvent_build(event);
1092 
1093     size_t size;
1094     const uint8_t* buf = AStatsEvent_getBuffer(event, &size);
1095     LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
1096     EXPECT_TRUE(ParseBuffer(logEvent, buf, size));
1097 
1098     AStatsEvent_release(event);
1099 }
1100 
TEST_P(LogEventTest,TestEmptyAttributionChainWithPrimaryFieldFirstUidAnnotation)1101 TEST_P(LogEventTest, TestEmptyAttributionChainWithPrimaryFieldFirstUidAnnotation) {
1102     AStatsEvent* event = AStatsEvent_obtain();
1103     AStatsEvent_setAtomId(event, 100);
1104 
1105     uint32_t uids[] = {};
1106     const char* tags[] = {};
1107 
1108     AStatsEvent_writeInt32(event, 10);
1109     AStatsEvent_writeAttributionChain(event, uids, tags, 0);
1110     AStatsEvent_addBoolAnnotation(event, ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID, true);
1111 
1112     AStatsEvent_build(event);
1113 
1114     size_t size;
1115     const uint8_t* buf = AStatsEvent_getBuffer(event, &size);
1116 
1117     LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
1118     EXPECT_FALSE(ParseBuffer(logEvent, buf, size));
1119 
1120     AStatsEvent_release(event);
1121 }
1122 
TEST_P(LogEventTest,TestInvalidBufferParsing)1123 TEST_P(LogEventTest, TestInvalidBufferParsing) {
1124     size_t emptyAtomBufferSize = 0;
1125     {
1126         // creating valid event to get valid buffer header size when no data fields
1127         AStatsEvent* event = AStatsEvent_obtain();
1128         AStatsEvent_setAtomId(event, 100);
1129         AStatsEvent_build(event);
1130         AStatsEvent_getBuffer(event, &emptyAtomBufferSize);
1131         AStatsEvent_release(event);
1132     }
1133 
1134     uint8_t buffer[4096];
1135     memset(buffer, 0, 4096);
1136     {
1137         // creating valid event to get valid buffer header with 1 array field and 1 annotation
1138         AStatsEvent* event = AStatsEvent_obtain();
1139         AStatsEvent_setAtomId(event, 100);
1140         AStatsEvent_writeInt32Array(event, nullptr, 0);
1141         AStatsEvent_addBoolAnnotation(event, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
1142         EXPECT_EQ(AStatsEvent_getErrors(event), 0);
1143         AStatsEvent_build(event);
1144 
1145         const uint8_t* buf = AStatsEvent_getBuffer(event, nullptr);
1146         memcpy(buffer, buf, emptyAtomBufferSize);
1147         AStatsEvent_release(event);
1148     }
1149 
1150     size_t bufferPosWithAlteredData = emptyAtomBufferSize;
1151 
1152     // adding extra data to test the logEvent parser logic
1153 
1154     buffer[bufferPosWithAlteredData++] = 0x13;  // array with 1 annotation
1155     buffer[bufferPosWithAlteredData++] = 0x00;  // size of array is 0
1156     buffer[bufferPosWithAlteredData++] = 0x00;  // type of array is int32
1157     buffer[bufferPosWithAlteredData++] = 0x01;  // annotation type is isUid
1158     buffer[bufferPosWithAlteredData++] = 0x01;  // annotation value type is not bool
1159 
1160     LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
1161     EXPECT_FALSE(ParseBuffer(logEvent, buffer, bufferPosWithAlteredData));
1162 }
1163 
1164 // Setup for parameterized tests.
1165 class LogEvent_FieldRestrictionTest : public testing::TestWithParam<std::tuple<int, bool>> {
1166 public:
ToString(testing::TestParamInfo<std::tuple<int,bool>> info)1167     static std::string ToString(testing::TestParamInfo<std::tuple<int, bool>> info) {
1168         const std::string boolName = std::get<1>(info.param) ? "_prefetchTrue" : "_prefetchFalse";
1169 
1170         switch (std::get<0>(info.param)) {
1171             case ASTATSLOG_ANNOTATION_ID_FIELD_RESTRICTION_PERIPHERAL_DEVICE_INFO:
1172                 return "PeripheralDeviceInfo" + boolName;
1173             case ASTATSLOG_ANNOTATION_ID_FIELD_RESTRICTION_APP_USAGE:
1174                 return "AppUsage" + boolName;
1175             case ASTATSLOG_ANNOTATION_ID_FIELD_RESTRICTION_APP_ACTIVITY:
1176                 return "AppActivity" + boolName;
1177             case ASTATSLOG_ANNOTATION_ID_FIELD_RESTRICTION_HEALTH_CONNECT:
1178                 return "HealthConnect" + boolName;
1179             case ASTATSLOG_ANNOTATION_ID_FIELD_RESTRICTION_ACCESSIBILITY:
1180                 return "Accessibility" + boolName;
1181             case ASTATSLOG_ANNOTATION_ID_FIELD_RESTRICTION_SYSTEM_SEARCH:
1182                 return "SystemSearch" + boolName;
1183             case ASTATSLOG_ANNOTATION_ID_FIELD_RESTRICTION_USER_ENGAGEMENT:
1184                 return "UserEngagement" + boolName;
1185             case ASTATSLOG_ANNOTATION_ID_FIELD_RESTRICTION_AMBIENT_SENSING:
1186                 return "AmbientSensing" + boolName;
1187             case ASTATSLOG_ANNOTATION_ID_FIELD_RESTRICTION_DEMOGRAPHIC_CLASSIFICATION:
1188                 return "DemographicClassification" + boolName;
1189             default:
1190                 return "Unknown" + boolName;
1191         }
1192     }
TearDown()1193     void TearDown() override {
1194         FlagProvider::getInstance().resetOverrides();
1195     }
1196 };
1197 
1198 // TODO(b/222539899): Add BOOL_TYPE value once parseAnnotations is updated to check specific
1199 // typeIds. BOOL_TYPE should be a bad field type for is_uid, nested, and reset state annotations.
1200 INSTANTIATE_TEST_SUITE_P(
1201         LogEvent_FieldRestrictionTest, LogEvent_FieldRestrictionTest,
1202         testing::Combine(
1203                 testing::Values(
1204                         ASTATSLOG_ANNOTATION_ID_FIELD_RESTRICTION_PERIPHERAL_DEVICE_INFO,
1205                         ASTATSLOG_ANNOTATION_ID_FIELD_RESTRICTION_APP_USAGE,
1206                         ASTATSLOG_ANNOTATION_ID_FIELD_RESTRICTION_APP_ACTIVITY,
1207                         ASTATSLOG_ANNOTATION_ID_FIELD_RESTRICTION_HEALTH_CONNECT,
1208                         ASTATSLOG_ANNOTATION_ID_FIELD_RESTRICTION_ACCESSIBILITY,
1209                         ASTATSLOG_ANNOTATION_ID_FIELD_RESTRICTION_SYSTEM_SEARCH,
1210                         ASTATSLOG_ANNOTATION_ID_FIELD_RESTRICTION_USER_ENGAGEMENT,
1211                         ASTATSLOG_ANNOTATION_ID_FIELD_RESTRICTION_AMBIENT_SENSING,
1212                         ASTATSLOG_ANNOTATION_ID_FIELD_RESTRICTION_DEMOGRAPHIC_CLASSIFICATION),
1213                 testing::Bool()),
1214         LogEvent_FieldRestrictionTest::ToString);
1215 
TEST_P(LogEvent_FieldRestrictionTest,TestFieldRestrictionAnnotation)1216 TEST_P(LogEvent_FieldRestrictionTest, TestFieldRestrictionAnnotation) {
1217     if (!isAtLeastU()) {
1218         GTEST_SKIP();
1219     }
1220     LogEvent event(/*uid=*/0, /*pid=*/0);
1221     EXPECT_TRUE(
1222             createFieldWithBoolAnnotationLogEvent(&event, INT32_TYPE, std::get<0>(GetParam()), true,
1223                                                   /*doHeaderPrefetch=*/std::get<1>(GetParam())));
1224     // Some basic checks to make sure the event is parsed correctly.
1225     EXPECT_EQ(event.GetTagId(), 100);
1226     ASSERT_EQ(event.getValues().size(), 1);
1227     EXPECT_EQ(event.getValues()[0].mValue.getType(), Type::INT);
1228 }
1229 
TEST_P(LogEvent_FieldRestrictionTest,TestInvalidAnnotationIntType)1230 TEST_P(LogEvent_FieldRestrictionTest, TestInvalidAnnotationIntType) {
1231     if (!isAtLeastU()) {
1232         GTEST_SKIP();
1233     }
1234     LogEvent event(/*uid=*/0, /*pid=*/0);
1235     EXPECT_FALSE(createFieldWithIntAnnotationLogEvent(
1236             &event, STRING_TYPE, std::get<0>(GetParam()),
1237             /*random int*/ 15, /*doHeaderPrefetch=*/std::get<1>(GetParam())));
1238 }
1239 
TEST_P(LogEvent_FieldRestrictionTest,TestInvalidAnnotationAtomLevel)1240 TEST_P(LogEvent_FieldRestrictionTest, TestInvalidAnnotationAtomLevel) {
1241     if (!isAtLeastU()) {
1242         GTEST_SKIP();
1243     }
1244     LogEvent event(/*uid=*/0, /*pid=*/0);
1245     EXPECT_FALSE(createAtomLevelBoolAnnotationLogEvent(
1246             &event, STRING_TYPE, std::get<0>(GetParam()), true,
1247             /*doHeaderPrefetch=*/std::get<1>(GetParam())));
1248 }
1249 
TEST_P(LogEvent_FieldRestrictionTest,TestRestrictionCategoryAnnotationBelowUDevice)1250 TEST_P(LogEvent_FieldRestrictionTest, TestRestrictionCategoryAnnotationBelowUDevice) {
1251     if (isAtLeastU()) {
1252         GTEST_SKIP();
1253     }
1254     int32_t restrictionCategory = ASTATSLOG_RESTRICTION_CATEGORY_DIAGNOSTIC;
1255     LogEvent event(/*uid=*/0, /*pid=*/0);
1256     EXPECT_FALSE(
1257             createFieldWithBoolAnnotationLogEvent(&event, INT32_TYPE, std::get<0>(GetParam()), true,
1258                                                   /*doHeaderPrefetch=*/std::get<1>(GetParam())));
1259 }
1260 
1261 }  // namespace statsd
1262 }  // namespace os
1263 }  // namespace android
1264 #else
1265 GTEST_LOG_(INFO) << "This test does nothing.\n";
1266 #endif
1267