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