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