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