1 /*
2  * Copyright (C) 2018, 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 <log/log_event_list.h>
20 #include <sys/uio.h>
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 void reset_log_context(android_log_context ctx);
26 int write_to_logger(android_log_context context, log_id_t id);
27 void note_log_drop(int error, int atom_tag);
28 void stats_log_close();
29 int android_log_write_char_array(android_log_context ctx, const char* value, size_t len);
30 extern int (*write_to_statsd)(struct iovec* vec, size_t nr);
31 
32 #ifdef __cplusplus
33 }
34 #endif
35 
36 #ifdef __cplusplus
37 /**
38  * A copy of android_log_event_list class.
39  *
40  * android_log_event_list is going to be deprecated soon, so copy it here to
41  * avoid creating dependency on upstream code. TODO(b/78304629): Rewrite this
42  * code.
43  */
44 class stats_event_list {
45   private:
46     android_log_context ctx;
47     int ret;
48 
49     stats_event_list(const stats_event_list&) = delete;
50     void operator=(const stats_event_list&) = delete;
51 
52   public:
stats_event_list(int tag)53     explicit stats_event_list(int tag) : ret(0) {
54         ctx = create_android_logger(static_cast<uint32_t>(tag));
55     }
~stats_event_list()56     ~stats_event_list() { android_log_destroy(&ctx); }
57 
close()58     int close() {
59         int retval = android_log_destroy(&ctx);
60         if (retval < 0) {
61             ret = retval;
62         }
63         return retval;
64     }
65 
66     /* To allow above C calls to use this class as parameter */
android_log_context()67     operator android_log_context() const { return ctx; }
68 
69     /* return errors or transmit status */
status()70     int status() const { return ret; }
71 
begin()72     int begin() {
73         int retval = android_log_write_list_begin(ctx);
74         if (retval < 0) {
75             ret = retval;
76         }
77         return ret;
78     }
end()79     int end() {
80         int retval = android_log_write_list_end(ctx);
81         if (retval < 0) {
82             ret = retval;
83         }
84         return ret;
85     }
86 
87     stats_event_list& operator<<(int32_t value) {
88         int retval = android_log_write_int32(ctx, value);
89         if (retval < 0) {
90             ret = retval;
91         }
92         return *this;
93     }
94 
95     stats_event_list& operator<<(uint32_t value) {
96         int retval = android_log_write_int32(ctx, static_cast<int32_t>(value));
97         if (retval < 0) {
98             ret = retval;
99         }
100         return *this;
101     }
102 
103     stats_event_list& operator<<(bool value) {
104         int retval = android_log_write_int32(ctx, value ? 1 : 0);
105         if (retval < 0) {
106             ret = retval;
107         }
108         return *this;
109     }
110 
111     stats_event_list& operator<<(int64_t value) {
112         int retval = android_log_write_int64(ctx, value);
113         if (retval < 0) {
114             ret = retval;
115         }
116         return *this;
117     }
118 
119     stats_event_list& operator<<(uint64_t value) {
120         int retval = android_log_write_int64(ctx, static_cast<int64_t>(value));
121         if (retval < 0) {
122             ret = retval;
123         }
124         return *this;
125     }
126 
127     stats_event_list& operator<<(const char* value) {
128         int retval = android_log_write_string8(ctx, value);
129         if (retval < 0) {
130             ret = retval;
131         }
132         return *this;
133     }
134 
135     stats_event_list& operator<<(const std::string& value) {
136         int retval = android_log_write_string8_len(ctx, value.data(), value.length());
137         if (retval < 0) {
138             ret = retval;
139         }
140         return *this;
141     }
142 
143     stats_event_list& operator<<(float value) {
144         int retval = android_log_write_float32(ctx, value);
145         if (retval < 0) {
146             ret = retval;
147         }
148         return *this;
149     }
150 
151     int write(log_id_t id = LOG_ID_EVENTS) {
152         /* facilitate -EBUSY retry */
153         if ((ret == -EBUSY) || (ret > 0)) {
154             ret = 0;
155         }
156         int retval = write_to_logger(ctx, id);
157         /* existing errors trump transmission errors */
158         if (!ret) {
159             ret = retval;
160         }
161         return ret;
162     }
163 
164     /*
165      * Append<Type> methods removes any integer promotion
166      * confusion, and adds access to string with length.
167      * Append methods are also added for all types for
168      * convenience.
169      */
170 
AppendInt(int32_t value)171     bool AppendInt(int32_t value) {
172         int retval = android_log_write_int32(ctx, value);
173         if (retval < 0) {
174             ret = retval;
175         }
176         return ret >= 0;
177     }
178 
AppendLong(int64_t value)179     bool AppendLong(int64_t value) {
180         int retval = android_log_write_int64(ctx, value);
181         if (retval < 0) {
182             ret = retval;
183         }
184         return ret >= 0;
185     }
186 
AppendString(const char * value)187     bool AppendString(const char* value) {
188         int retval = android_log_write_string8(ctx, value);
189         if (retval < 0) {
190             ret = retval;
191         }
192         return ret >= 0;
193     }
194 
AppendString(const char * value,size_t len)195     bool AppendString(const char* value, size_t len) {
196         int retval = android_log_write_string8_len(ctx, value, len);
197         if (retval < 0) {
198             ret = retval;
199         }
200         return ret >= 0;
201     }
202 
AppendString(const std::string & value)203     bool AppendString(const std::string& value) {
204         int retval = android_log_write_string8_len(ctx, value.data(), value.length());
205         if (retval < 0) {
206             ret = retval;
207         }
208         return ret;
209     }
210 
Append(const std::string & value)211     bool Append(const std::string& value) {
212         int retval = android_log_write_string8_len(ctx, value.data(), value.length());
213         if (retval < 0) {
214             ret = retval;
215         }
216         return ret;
217     }
218 
AppendFloat(float value)219     bool AppendFloat(float value) {
220         int retval = android_log_write_float32(ctx, value);
221         if (retval < 0) {
222             ret = retval;
223         }
224         return ret >= 0;
225     }
226 
227     template <typename Tvalue>
Append(Tvalue value)228     bool Append(Tvalue value) {
229         *this << value;
230         return ret >= 0;
231     }
232 
Append(const char * value,size_t len)233     bool Append(const char* value, size_t len) {
234         int retval = android_log_write_string8_len(ctx, value, len);
235         if (retval < 0) {
236             ret = retval;
237         }
238         return ret >= 0;
239     }
240 
AppendCharArray(const char * value,size_t len)241     bool AppendCharArray(const char* value, size_t len) {
242         int retval = android_log_write_char_array(ctx, value, len);
243         if (retval < 0) {
244             ret = retval;
245         }
246         return ret >= 0;
247     }
248 };
249 
250 #endif
251