1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <gtest/gtest_prod.h>
20 #include <map>
21 #include <mutex>
22 #include <vector>
23 #include "stats_event.h"
24 #include "stats_event_list.h"
25 
26 using std::map;
27 using std::vector;
28 
29 struct AStatsEventApi {
30     // Indicates whether the below function pointers have been set using dlsym.
31     bool initialized = false;
32 
33     AStatsEvent* (*obtain)(void);
34     void (*build)(AStatsEvent*);
35     int (*write)(AStatsEvent*);
36     void (*release)(AStatsEvent*);
37     void (*setAtomId)(AStatsEvent*, uint32_t);
38     void (*writeInt32)(AStatsEvent*, int32_t);
39     void (*writeInt64)(AStatsEvent*, int64_t);
40     void (*writeFloat)(AStatsEvent*, float);
41     void (*writeBool)(AStatsEvent*, bool);
42     void (*writeByteArray)(AStatsEvent*, const uint8_t*, size_t);
43     void (*writeString)(AStatsEvent*, const char*);
44     void (*writeAttributionChain)(AStatsEvent*, const uint32_t*, const char* const*, uint8_t);
45     void (*addBoolAnnotation)(AStatsEvent*, uint8_t, bool);
46     void (*addInt32Annotation)(AStatsEvent*, uint8_t, int32_t);
47 };
48 
49 class StatsEventCompat {
50   public:
51     StatsEventCompat();
52     ~StatsEventCompat();
53 
54     void setAtomId(int32_t atomId);
55     void writeInt32(int32_t value);
56     void writeInt64(int64_t value);
57     void writeFloat(float value);
58     void writeBool(bool value);
59     void writeByteArray(const char* buffer, size_t length);
60     void writeString(const char* value);
61 
62     // Pre-condition: numUids == tags.size()
63     void writeAttributionChain(const int32_t* uids, size_t numUids,
64                                const vector<const char*>& tags);
65 
66     void writeKeyValuePairs(const map<int, int32_t>& int32Map, const map<int, int64_t>& int64Map,
67                             const map<int, const char*>& stringMap,
68                             const map<int, float>& floatMap);
69 
70     void addBoolAnnotation(uint8_t annotationId, bool value);
71     void addInt32Annotation(uint8_t annotationId, int32_t value);
72 
73     int writeToSocket();
74 
75   private:
76     // static member variables
77     const static bool mPlatformAtLeastR;
78     static bool mAttemptedLoad;
79     static std::mutex mLoadLock;
80     static AStatsEventApi mAStatsEventApi;
81 
82     // non-static member variables
83     AStatsEvent* mEventR = nullptr;
84     stats_event_list mEventQ;
85 
86     template <class T>
87     void writeKeyValuePairMap(const map<int, T>& keyValuePairMap);
88 
89     void initializeApiTableLocked(void* handle);
90     bool useRSchema();
91     bool useQSchema();
92 
93     FRIEND_TEST(StatsEventCompatTest, TestDynamicLoading);
94 };
95