blob: 0430e4ec9a2d0b9db227e42a8410c78ac416d141 [file] [log] [blame]
Joe Onoratoc4dfae52017-10-17 23:38:21 -07001/*
2 * Copyright (C) 2017 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
Tej Singh484524a2018-02-01 15:10:05 -080017#define DEBUG false // STOPSHIP if true
Joe Onoratoc4dfae52017-10-17 23:38:21 -070018#include "logd/LogEvent.h"
19
Yangster-mac20877162017-12-22 17:19:39 -080020#include "stats_log_util.h"
Yangster-mac48b3d622018-08-18 12:38:11 -070021#include "statslog.h"
Joe Onoratoc4dfae52017-10-17 23:38:21 -070022
Chenjie Yu6b1667c2019-01-18 10:09:33 -080023#include <binder/IPCThreadState.h>
Tej Singh8928ed72019-02-22 19:06:22 -080024#include <private/android_filesystem_config.h>
Chenjie Yu6b1667c2019-01-18 10:09:33 -080025
Joe Onoratoc4dfae52017-10-17 23:38:21 -070026namespace android {
27namespace os {
28namespace statsd {
29
yro24809bd2017-10-31 23:06:53 -070030using namespace android::util;
Yao Chen9c1debe2018-02-19 14:39:19 -080031using android::util::ProtoOutputStream;
David Chen1481fe12017-10-16 13:16:34 -070032using std::string;
Yao Chen9c1debe2018-02-19 14:39:19 -080033using std::vector;
Joe Onoratoc4dfae52017-10-17 23:38:21 -070034
Yao Chen80235402017-11-13 20:42:25 -080035LogEvent::LogEvent(log_msg& msg) {
Chenjie Yu3ca36832018-01-22 15:10:54 -080036 mContext =
Yao Chen80235402017-11-13 20:42:25 -080037 create_android_log_parser(msg.msg() + sizeof(uint32_t), msg.len() - sizeof(uint32_t));
Yangster-mac330af582018-02-08 15:24:38 -080038 mLogdTimestampNs = msg.entry_v1.sec * NS_PER_SEC + msg.entry_v1.nsec;
Yao Chend10f7b12017-12-18 12:53:50 -080039 mLogUid = msg.entry_v4.uid;
Chenjie Yu3ca36832018-01-22 15:10:54 -080040 init(mContext);
41 if (mContext) {
Yao Chen48d75182018-01-23 09:40:48 -080042 // android_log_destroy will set mContext to NULL
Chenjie Yu3ca36832018-01-22 15:10:54 -080043 android_log_destroy(&mContext);
Yangster-mac20877162017-12-22 17:19:39 -080044 }
Joe Onoratoc4dfae52017-10-17 23:38:21 -070045}
46
Chenjie Yu0bd73db2018-12-16 07:37:04 -080047LogEvent::LogEvent(const LogEvent& event) {
48 mTagId = event.mTagId;
49 mLogUid = event.mLogUid;
50 mElapsedTimestampNs = event.mElapsedTimestampNs;
51 mLogdTimestampNs = event.mLogdTimestampNs;
52 mValues = event.mValues;
53}
54
Chenjie Yud7e3a222018-11-28 21:29:44 +000055LogEvent::LogEvent(const StatsLogEventWrapper& statsLogEventWrapper, int workChainIndex) {
Chenjie Yu12e5e672018-09-14 15:54:59 -070056 mTagId = statsLogEventWrapper.getTagId();
57 mLogdTimestampNs = statsLogEventWrapper.getWallClockTimeNs();
58 mElapsedTimestampNs = statsLogEventWrapper.getElapsedRealTimeNs();
59 mLogUid = 0;
Chenjie Yud7e3a222018-11-28 21:29:44 +000060 int workChainPosOffset = 0;
61 if (workChainIndex != -1) {
62 const WorkChain& wc = statsLogEventWrapper.getWorkChains()[workChainIndex];
63 // chains are at field 1, level 2
64 int depth = 2;
65 for (int i = 0; i < (int)wc.uids.size(); i++) {
66 int pos[] = {1, i + 1, 1};
67 mValues.push_back(FieldValue(Field(mTagId, pos, depth), Value(wc.uids[i])));
68 pos[2]++;
69 mValues.push_back(FieldValue(Field(mTagId, pos, depth), Value(wc.tags[i])));
70 mValues.back().mField.decorateLastPos(2);
71 }
72 mValues.back().mField.decorateLastPos(1);
73 workChainPosOffset = 1;
74 }
Chenjie Yu12e5e672018-09-14 15:54:59 -070075 for (int i = 0; i < (int)statsLogEventWrapper.getElements().size(); i++) {
Chenjie Yud7e3a222018-11-28 21:29:44 +000076 Field field(statsLogEventWrapper.getTagId(), getSimpleField(i + 1 + workChainPosOffset));
Chenjie Yu12e5e672018-09-14 15:54:59 -070077 switch (statsLogEventWrapper.getElements()[i].type) {
78 case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::INT:
79 mValues.push_back(
80 FieldValue(field, Value(statsLogEventWrapper.getElements()[i].int_value)));
81 break;
82 case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::LONG:
83 mValues.push_back(
84 FieldValue(field, Value(statsLogEventWrapper.getElements()[i].long_value)));
85 break;
86 case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::FLOAT:
87 mValues.push_back(FieldValue(
88 field, Value(statsLogEventWrapper.getElements()[i].float_value)));
89 break;
90 case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::DOUBLE:
91 mValues.push_back(FieldValue(
92 field, Value(statsLogEventWrapper.getElements()[i].double_value)));
93 break;
94 case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::STRING:
95 mValues.push_back(
96 FieldValue(field, Value(statsLogEventWrapper.getElements()[i].str_value)));
97 break;
98 case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::STORAGE:
99 mValues.push_back(FieldValue(
100 field, Value(statsLogEventWrapper.getElements()[i].storage_value)));
101 break;
102 default:
103 break;
104 }
105 }
106}
107
Chenjie Yud7e3a222018-11-28 21:29:44 +0000108void LogEvent::createLogEvents(const StatsLogEventWrapper& statsLogEventWrapper,
109 std::vector<std::shared_ptr<LogEvent>>& logEvents) {
110 if (statsLogEventWrapper.getWorkChains().size() == 0) {
111 logEvents.push_back(std::make_shared<LogEvent>(statsLogEventWrapper, -1));
112 } else {
113 for (size_t i = 0; i < statsLogEventWrapper.getWorkChains().size(); i++) {
114 logEvents.push_back(std::make_shared<LogEvent>(statsLogEventWrapper, i));
115 }
116 }
117}
118
Yangster-mac330af582018-02-08 15:24:38 -0800119LogEvent::LogEvent(int32_t tagId, int64_t wallClockTimestampNs, int64_t elapsedTimestampNs) {
120 mLogdTimestampNs = wallClockTimestampNs;
Yao Chen80235402017-11-13 20:42:25 -0800121 mTagId = tagId;
Yangster-mac20877162017-12-22 17:19:39 -0800122 mLogUid = 0;
Yao Chen80235402017-11-13 20:42:25 -0800123 mContext = create_android_logger(1937006964); // the event tag shared by all stats logs
124 if (mContext) {
Yangster-mac330af582018-02-08 15:24:38 -0800125 android_log_write_int64(mContext, elapsedTimestampNs);
126 android_log_write_int32(mContext, tagId);
127 }
128}
129
Yangster-mac48b3d622018-08-18 12:38:11 -0700130LogEvent::LogEvent(int32_t tagId, int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
131 int32_t uid,
Howard Ro4078dd42018-09-27 17:41:08 -0700132 const std::map<int32_t, int32_t>& int_map,
133 const std::map<int32_t, int64_t>& long_map,
Yangster-mac48b3d622018-08-18 12:38:11 -0700134 const std::map<int32_t, std::string>& string_map,
135 const std::map<int32_t, float>& float_map) {
136 mLogdTimestampNs = wallClockTimestampNs;
137 mElapsedTimestampNs = elapsedTimestampNs;
138 mTagId = android::util::KEY_VALUE_PAIRS_ATOM;
139 mLogUid = uid;
140
141 int pos[] = {1, 1, 1};
142
143 mValues.push_back(FieldValue(Field(mTagId, pos, 0 /* depth */), Value(uid)));
144 pos[0]++;
145 for (const auto&itr : int_map) {
146 pos[2] = 1;
147 mValues.push_back(FieldValue(Field(mTagId, pos, 2 /* depth */), Value(itr.first)));
148 pos[2] = 2;
149 mValues.push_back(FieldValue(Field(mTagId, pos, 2 /* depth */), Value(itr.second)));
150 mValues.back().mField.decorateLastPos(2);
151 pos[1]++;
152 }
153
Howard Ro4078dd42018-09-27 17:41:08 -0700154 for (const auto&itr : long_map) {
Yangster-mac48b3d622018-08-18 12:38:11 -0700155 pos[2] = 1;
156 mValues.push_back(FieldValue(Field(mTagId, pos, 2 /* depth */), Value(itr.first)));
157 pos[2] = 3;
158 mValues.push_back(FieldValue(Field(mTagId, pos, 2 /* depth */), Value(itr.second)));
159 mValues.back().mField.decorateLastPos(2);
160 pos[1]++;
161 }
162
Howard Ro4078dd42018-09-27 17:41:08 -0700163 for (const auto&itr : string_map) {
Yangster-mac48b3d622018-08-18 12:38:11 -0700164 pos[2] = 1;
165 mValues.push_back(FieldValue(Field(mTagId, pos, 2 /* depth */), Value(itr.first)));
166 pos[2] = 4;
167 mValues.push_back(FieldValue(Field(mTagId, pos, 2 /* depth */), Value(itr.second)));
168 mValues.back().mField.decorateLastPos(2);
169 pos[1]++;
170 }
Howard Ro4078dd42018-09-27 17:41:08 -0700171
172 for (const auto&itr : float_map) {
173 pos[2] = 1;
174 mValues.push_back(FieldValue(Field(mTagId, pos, 2 /* depth */), Value(itr.first)));
175 pos[2] = 5;
176 mValues.push_back(FieldValue(Field(mTagId, pos, 2 /* depth */), Value(itr.second)));
177 mValues.back().mField.decorateLastPos(2);
178 pos[1]++;
179 }
Yangster-mac48b3d622018-08-18 12:38:11 -0700180 if (!mValues.empty()) {
181 mValues.back().mField.decorateLastPos(1);
182 mValues.at(mValues.size() - 2).mField.decorateLastPos(1);
183 }
184}
185
Chenjie Yu6b1667c2019-01-18 10:09:33 -0800186LogEvent::LogEvent(const string& trainName, int64_t trainVersionCode, bool requiresStaging,
187 bool rollbackEnabled, bool requiresLowLatencyMonitor, int32_t state,
188 const std::vector<uint8_t>& experimentIds, int32_t userId) {
189 mLogdTimestampNs = getWallClockNs();
190 mElapsedTimestampNs = getElapsedRealtimeNs();
191 mTagId = android::util::BINARY_PUSH_STATE_CHANGED;
192 mLogUid = android::IPCThreadState::self()->getCallingUid();
193
194 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(1)), Value(trainName)));
195 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(2)), Value(trainVersionCode)));
196 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(3)), Value((int)requiresStaging)));
197 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(4)), Value((int)rollbackEnabled)));
198 mValues.push_back(
199 FieldValue(Field(mTagId, getSimpleField(5)), Value((int)requiresLowLatencyMonitor)));
200 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(6)), Value(state)));
201 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(7)), Value(experimentIds)));
202 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(8)), Value(userId)));
203}
204
Howard Roa46b6582018-09-18 16:45:02 -0700205LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
Maggie White58174da2019-01-18 15:23:35 -0800206 const VendorAtom& vendorAtom) {
207 mLogdTimestampNs = wallClockTimestampNs;
208 mElapsedTimestampNs = elapsedTimestampNs;
209 mTagId = vendorAtom.atomId;
Tej Singh8928ed72019-02-22 19:06:22 -0800210 mLogUid = AID_STATSD;
Maggie White58174da2019-01-18 15:23:35 -0800211
212 mValues.push_back(
213 FieldValue(Field(mTagId, getSimpleField(1)), Value(vendorAtom.reverseDomainName)));
214 for (int i = 0; i < (int)vendorAtom.values.size(); i++) {
215 switch (vendorAtom.values[i].getDiscriminator()) {
216 case VendorAtom::Value::hidl_discriminator::intValue:
217 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(i + 2)),
218 Value(vendorAtom.values[i].intValue())));
219 break;
220 case VendorAtom::Value::hidl_discriminator::longValue:
221 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(i + 2)),
222 Value(vendorAtom.values[i].longValue())));
223 break;
224 case VendorAtom::Value::hidl_discriminator::floatValue:
225 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(i + 2)),
226 Value(vendorAtom.values[i].floatValue())));
227 break;
228 case VendorAtom::Value::hidl_discriminator::stringValue:
229 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(i + 2)),
230 Value(vendorAtom.values[i].stringValue())));
231 break;
232 }
233 }
234}
235
Chenjie Yu97dbb202019-02-13 16:42:04 -0800236LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
237 const InstallTrainInfo& trainInfo) {
238 mLogdTimestampNs = wallClockTimestampNs;
239 mElapsedTimestampNs = elapsedTimestampNs;
240 mTagId = android::util::TRAIN_INFO;
241 mValues.push_back(
242 FieldValue(Field(mTagId, getSimpleField(1)), Value(trainInfo.trainVersionCode)));
243 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(2)), Value(trainInfo.experimentIds)));
244}
245
Howard Ro1a2a3992018-10-22 22:51:57 -0700246LogEvent::LogEvent(int32_t tagId, int64_t timestampNs) : LogEvent(tagId, timestampNs, 0) {}
247
248LogEvent::LogEvent(int32_t tagId, int64_t timestampNs, int32_t uid) {
Yangster-mac330af582018-02-08 15:24:38 -0800249 mLogdTimestampNs = timestampNs;
250 mTagId = tagId;
Howard Ro1a2a3992018-10-22 22:51:57 -0700251 mLogUid = uid;
Yangster-mac330af582018-02-08 15:24:38 -0800252 mContext = create_android_logger(1937006964); // the event tag shared by all stats logs
253 if (mContext) {
254 android_log_write_int64(mContext, timestampNs);
Yao Chen80235402017-11-13 20:42:25 -0800255 android_log_write_int32(mContext, tagId);
256 }
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700257}
258
David Chen1481fe12017-10-16 13:16:34 -0700259void LogEvent::init() {
Yao Chen80235402017-11-13 20:42:25 -0800260 if (mContext) {
261 const char* buffer;
262 size_t len = android_log_write_list_buffer(mContext, &buffer);
263 // turns to reader mode
Chenjie Yuc1fe6f42018-02-01 23:14:18 -0800264 android_log_context contextForRead = create_android_log_parser(buffer, len);
265 if (contextForRead) {
266 init(contextForRead);
267 // destroy the context to save memory.
Yao Chen48d75182018-01-23 09:40:48 -0800268 // android_log_destroy will set mContext to NULL
Chenjie Yuc1fe6f42018-02-01 23:14:18 -0800269 android_log_destroy(&contextForRead);
Yao Chen48d75182018-01-23 09:40:48 -0800270 }
Chenjie Yuc1fe6f42018-02-01 23:14:18 -0800271 android_log_destroy(&mContext);
Yangster-mac20877162017-12-22 17:19:39 -0800272 }
273}
274
275LogEvent::~LogEvent() {
276 if (mContext) {
Yao Chen48d75182018-01-23 09:40:48 -0800277 // This is for the case when LogEvent is created using the test interface
278 // but init() isn't called.
Yangster-mac20877162017-12-22 17:19:39 -0800279 android_log_destroy(&mContext);
Yao Chen80235402017-11-13 20:42:25 -0800280 }
281}
282
283bool LogEvent::write(int32_t value) {
284 if (mContext) {
285 return android_log_write_int32(mContext, value) >= 0;
286 }
287 return false;
288}
289
290bool LogEvent::write(uint32_t value) {
291 if (mContext) {
292 return android_log_write_int32(mContext, value) >= 0;
293 }
294 return false;
295}
296
Chenjie Yud9dfda72017-12-11 17:41:20 -0800297bool LogEvent::write(int64_t value) {
298 if (mContext) {
299 return android_log_write_int64(mContext, value) >= 0;
300 }
301 return false;
302}
303
Yao Chen80235402017-11-13 20:42:25 -0800304bool LogEvent::write(uint64_t value) {
305 if (mContext) {
306 return android_log_write_int64(mContext, value) >= 0;
307 }
308 return false;
309}
310
311bool LogEvent::write(const string& value) {
312 if (mContext) {
313 return android_log_write_string8_len(mContext, value.c_str(), value.length()) >= 0;
314 }
315 return false;
316}
317
318bool LogEvent::write(float value) {
319 if (mContext) {
320 return android_log_write_float32(mContext, value) >= 0;
321 }
322 return false;
323}
324
Howard Ro1a2a3992018-10-22 22:51:57 -0700325bool LogEvent::writeKeyValuePairs(int32_t uid,
326 const std::map<int32_t, int32_t>& int_map,
Howard Ro4078dd42018-09-27 17:41:08 -0700327 const std::map<int32_t, int64_t>& long_map,
Yangster-mace124e422018-08-16 10:30:28 -0700328 const std::map<int32_t, std::string>& string_map,
329 const std::map<int32_t, float>& float_map) {
330 if (mContext) {
331 if (android_log_write_list_begin(mContext) < 0) {
332 return false;
333 }
Howard Ro1a2a3992018-10-22 22:51:57 -0700334 write(uid);
Yangster-mace124e422018-08-16 10:30:28 -0700335 for (const auto& itr : int_map) {
336 if (android_log_write_list_begin(mContext) < 0) {
337 return false;
338 }
339 write(itr.first);
340 write(itr.second);
341 if (android_log_write_list_end(mContext) < 0) {
342 return false;
343 }
344 }
345
Howard Ro4078dd42018-09-27 17:41:08 -0700346 for (const auto& itr : long_map) {
347 if (android_log_write_list_begin(mContext) < 0) {
348 return false;
349 }
350 write(itr.first);
351 write(itr.second);
352 if (android_log_write_list_end(mContext) < 0) {
353 return false;
354 }
355 }
356
Yangster-mace124e422018-08-16 10:30:28 -0700357 for (const auto& itr : string_map) {
358 if (android_log_write_list_begin(mContext) < 0) {
359 return false;
360 }
361 write(itr.first);
362 write(itr.second.c_str());
363 if (android_log_write_list_end(mContext) < 0) {
364 return false;
365 }
366 }
367
368 for (const auto& itr : float_map) {
369 if (android_log_write_list_begin(mContext) < 0) {
370 return false;
371 }
372 write(itr.first);
373 write(itr.second);
374 if (android_log_write_list_end(mContext) < 0) {
375 return false;
376 }
377 }
378
379 if (android_log_write_list_end(mContext) < 0) {
380 return false;
381 }
382 return true;
383 }
384 return false;
385}
386
Yao Chen9c1debe2018-02-19 14:39:19 -0800387bool LogEvent::write(const std::vector<AttributionNodeInternal>& nodes) {
Yao Chen80235402017-11-13 20:42:25 -0800388 if (mContext) {
Yangster-mac20877162017-12-22 17:19:39 -0800389 if (android_log_write_list_begin(mContext) < 0) {
390 return false;
391 }
392 for (size_t i = 0; i < nodes.size(); ++i) {
393 if (!write(nodes[i])) {
394 return false;
395 }
396 }
397 if (android_log_write_list_end(mContext) < 0) {
398 return false;
399 }
400 return true;
401 }
402 return false;
403}
404
Yao Chen9c1debe2018-02-19 14:39:19 -0800405bool LogEvent::write(const AttributionNodeInternal& node) {
Yangster-mac20877162017-12-22 17:19:39 -0800406 if (mContext) {
407 if (android_log_write_list_begin(mContext) < 0) {
408 return false;
409 }
410 if (android_log_write_int32(mContext, node.uid()) < 0) {
411 return false;
412 }
413 if (android_log_write_string8(mContext, node.tag().c_str()) < 0) {
414 return false;
415 }
Yangster-mac20877162017-12-22 17:19:39 -0800416 if (android_log_write_list_end(mContext) < 0) {
417 return false;
418 }
419 return true;
420 }
421 return false;
422}
423
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700424/**
425 * The elements of each log event are stored as a vector of android_log_list_elements.
426 * The goal is to do as little preprocessing as possible, because we read a tiny fraction
427 * of the elements that are written to the log.
Yao Chen8a8d16c2018-02-08 14:50:40 -0800428 *
429 * The idea here is to read through the log items once, we get as much information we need for
430 * matching as possible. Because this log will be matched against lots of matchers.
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700431 */
Yao Chen80235402017-11-13 20:42:25 -0800432void LogEvent::init(android_log_context context) {
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700433 android_log_list_element elem;
Yao Chen80235402017-11-13 20:42:25 -0800434 int i = 0;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800435 int depth = -1;
436 int pos[] = {1, 1, 1};
Yangster-mace124e422018-08-16 10:30:28 -0700437 bool isKeyValuePairAtom = false;
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700438 do {
Yao Chen80235402017-11-13 20:42:25 -0800439 elem = android_log_read_next(context);
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700440 switch ((int)elem.type) {
441 case EVENT_TYPE_INT:
Yangster-mac330af582018-02-08 15:24:38 -0800442 // elem at [0] is EVENT_TYPE_LIST, [1] is the timestamp, [2] is tag id.
443 if (i == 2) {
Yao Chen80235402017-11-13 20:42:25 -0800444 mTagId = elem.data.int32;
Yangster-mace124e422018-08-16 10:30:28 -0700445 isKeyValuePairAtom = (mTagId == android::util::KEY_VALUE_PAIRS_ATOM);
Yangster-mac20877162017-12-22 17:19:39 -0800446 } else {
Yao Chen8a8d16c2018-02-08 14:50:40 -0800447 if (depth < 0 || depth > 2) {
Yangster-mac20877162017-12-22 17:19:39 -0800448 return;
449 }
Yao Chen8a8d16c2018-02-08 14:50:40 -0800450
451 mValues.push_back(
452 FieldValue(Field(mTagId, pos, depth), Value((int32_t)elem.data.int32)));
453
454 pos[depth]++;
Yangster-mac20877162017-12-22 17:19:39 -0800455 }
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700456 break;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800457 case EVENT_TYPE_FLOAT: {
458 if (depth < 0 || depth > 2) {
459 ALOGE("Depth > 2. Not supported!");
460 return;
461 }
462
Yangster-mace124e422018-08-16 10:30:28 -0700463 // Handles the oneof field in KeyValuePair atom.
464 if (isKeyValuePairAtom && depth == 2) {
Tej Singh2c96b5a2019-02-04 21:28:49 -0800465 pos[depth] = 5;
Yangster-mace124e422018-08-16 10:30:28 -0700466 }
467
Yao Chen8a8d16c2018-02-08 14:50:40 -0800468 mValues.push_back(FieldValue(Field(mTagId, pos, depth), Value(elem.data.float32)));
469
470 pos[depth]++;
471
472 } break;
473 case EVENT_TYPE_STRING: {
474 if (depth < 0 || depth > 2) {
475 ALOGE("Depth > 2. Not supported!");
476 return;
477 }
478
Yangster-mace124e422018-08-16 10:30:28 -0700479 // Handles the oneof field in KeyValuePair atom.
480 if (isKeyValuePairAtom && depth == 2) {
Tej Singh2c96b5a2019-02-04 21:28:49 -0800481 pos[depth] = 4;
Yangster-mace124e422018-08-16 10:30:28 -0700482 }
Yao Chen8a8d16c2018-02-08 14:50:40 -0800483 mValues.push_back(FieldValue(Field(mTagId, pos, depth),
484 Value(string(elem.data.string, elem.len))));
485
486 pos[depth]++;
487
488 } break;
489 case EVENT_TYPE_LONG: {
Yangster-mac330af582018-02-08 15:24:38 -0800490 if (i == 1) {
491 mElapsedTimestampNs = elem.data.int64;
492 } else {
493 if (depth < 0 || depth > 2) {
494 ALOGE("Depth > 2. Not supported!");
495 return;
496 }
Yangster-mace124e422018-08-16 10:30:28 -0700497 // Handles the oneof field in KeyValuePair atom.
498 if (isKeyValuePairAtom && depth == 2) {
Tej Singh2c96b5a2019-02-04 21:28:49 -0800499 pos[depth] = 3;
Yangster-mace124e422018-08-16 10:30:28 -0700500 }
Yangster-mac330af582018-02-08 15:24:38 -0800501 mValues.push_back(
502 FieldValue(Field(mTagId, pos, depth), Value((int64_t)elem.data.int64)));
503
504 pos[depth]++;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800505 }
Yao Chen8a8d16c2018-02-08 14:50:40 -0800506 } break;
507 case EVENT_TYPE_LIST:
508 depth++;
509 if (depth > 2) {
510 ALOGE("Depth > 2. Not supported!");
511 return;
512 }
513 pos[depth] = 1;
514
515 break;
516 case EVENT_TYPE_LIST_STOP: {
517 int prevDepth = depth;
518 depth--;
519 if (depth >= 0 && depth < 2) {
520 // Now go back to decorate the previous items that are last at prevDepth.
521 // So that we can later easily match them with Position=Last matchers.
522 pos[prevDepth]--;
523 int path = getEncodedField(pos, prevDepth, false);
Yao Chendb43afc2018-02-13 09:37:27 -0800524 for (auto it = mValues.rbegin(); it != mValues.rend(); ++it) {
525 if (it->mField.getDepth() >= prevDepth &&
526 it->mField.getPath(prevDepth) == path) {
527 it->mField.decorateLastPos(prevDepth);
Yao Chen8a8d16c2018-02-08 14:50:40 -0800528 } else {
529 // Safe to break, because the items are in DFS order.
530 break;
531 }
Yangster-mac20877162017-12-22 17:19:39 -0800532 }
Yao Chen8a8d16c2018-02-08 14:50:40 -0800533 pos[depth]++;
Yangster-mac20877162017-12-22 17:19:39 -0800534 }
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700535 break;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800536 }
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700537 case EVENT_TYPE_UNKNOWN:
538 break;
539 default:
540 break;
541 }
Yao Chen80235402017-11-13 20:42:25 -0800542 i++;
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700543 } while ((elem.type != EVENT_TYPE_UNKNOWN) && !elem.complete);
Howard Ro1a2a3992018-10-22 22:51:57 -0700544 if (isKeyValuePairAtom && mValues.size() > 0) {
545 mValues[0] = FieldValue(Field(android::util::KEY_VALUE_PAIRS_ATOM, getSimpleField(1)),
546 Value((int32_t)mLogUid));
547 }
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700548}
549
550int64_t LogEvent::GetLong(size_t key, status_t* err) const {
Yao Chen5bfffb52018-06-21 16:58:51 -0700551 // TODO(b/110561208): encapsulate the magical operations in Field struct as static functions
Yao Chen8a8d16c2018-02-08 14:50:40 -0800552 int field = getSimpleField(key);
553 for (const auto& value : mValues) {
554 if (value.mField.getField() == field) {
Yao Chenab92a1f2018-02-13 15:17:55 -0800555 if (value.mValue.getType() == LONG) {
556 return value.mValue.long_value;
557 } else if (value.mValue.getType() == INT) {
Yao Chen8a8d16c2018-02-08 14:50:40 -0800558 return value.mValue.int_value;
559 } else {
560 *err = BAD_TYPE;
561 return 0;
562 }
563 }
564 if ((size_t)value.mField.getPosAtDepth(0) > key) {
565 break;
Yangster-mac20877162017-12-22 17:19:39 -0800566 }
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700567 }
Yao Chen8a8d16c2018-02-08 14:50:40 -0800568
569 *err = BAD_INDEX;
570 return 0;
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700571}
572
Chenjie Yu80f91122018-01-31 20:24:50 -0800573int LogEvent::GetInt(size_t key, status_t* err) const {
Yao Chen8a8d16c2018-02-08 14:50:40 -0800574 int field = getSimpleField(key);
575 for (const auto& value : mValues) {
576 if (value.mField.getField() == field) {
577 if (value.mValue.getType() == INT) {
578 return value.mValue.int_value;
579 } else {
580 *err = BAD_TYPE;
581 return 0;
582 }
583 }
584 if ((size_t)value.mField.getPosAtDepth(0) > key) {
585 break;
586 }
587 }
588
Chenjie Yu80f91122018-01-31 20:24:50 -0800589 *err = BAD_INDEX;
590 return 0;
Chenjie Yu80f91122018-01-31 20:24:50 -0800591}
592
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700593const char* LogEvent::GetString(size_t key, status_t* err) const {
Yao Chen8a8d16c2018-02-08 14:50:40 -0800594 int field = getSimpleField(key);
595 for (const auto& value : mValues) {
596 if (value.mField.getField() == field) {
597 if (value.mValue.getType() == STRING) {
598 return value.mValue.str_value.c_str();
599 } else {
600 *err = BAD_TYPE;
601 return 0;
602 }
603 }
604 if ((size_t)value.mField.getPosAtDepth(0) > key) {
605 break;
Yangster-mac20877162017-12-22 17:19:39 -0800606 }
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700607 }
Yao Chen8a8d16c2018-02-08 14:50:40 -0800608
609 *err = BAD_INDEX;
610 return NULL;
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700611}
612
613bool LogEvent::GetBool(size_t key, status_t* err) const {
Yao Chen8a8d16c2018-02-08 14:50:40 -0800614 int field = getSimpleField(key);
615 for (const auto& value : mValues) {
616 if (value.mField.getField() == field) {
617 if (value.mValue.getType() == INT) {
618 return value.mValue.int_value != 0;
619 } else if (value.mValue.getType() == LONG) {
620 return value.mValue.long_value != 0;
621 } else {
622 *err = BAD_TYPE;
623 return false;
624 }
625 }
626 if ((size_t)value.mField.getPosAtDepth(0) > key) {
627 break;
Yangster-mac20877162017-12-22 17:19:39 -0800628 }
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700629 }
Yao Chen8a8d16c2018-02-08 14:50:40 -0800630
631 *err = BAD_INDEX;
632 return false;
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700633}
634
635float LogEvent::GetFloat(size_t key, status_t* err) const {
Yao Chen8a8d16c2018-02-08 14:50:40 -0800636 int field = getSimpleField(key);
637 for (const auto& value : mValues) {
638 if (value.mField.getField() == field) {
639 if (value.mValue.getType() == FLOAT) {
640 return value.mValue.float_value;
641 } else {
642 *err = BAD_TYPE;
643 return 0.0;
644 }
645 }
646 if ((size_t)value.mField.getPosAtDepth(0) > key) {
647 break;
Yangster-mac20877162017-12-22 17:19:39 -0800648 }
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700649 }
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700650
Yao Chen8a8d16c2018-02-08 14:50:40 -0800651 *err = BAD_INDEX;
652 return 0.0;
Yangster-macd40053e2018-01-09 16:29:22 -0800653}
654
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700655string LogEvent::ToString() const {
Yao Chen20e9e622018-02-28 11:18:51 -0800656 string result;
Yao Chen8e6f9982018-11-29 09:39:45 -0800657 result += StringPrintf("{ uid(%d) %lld %lld (%d)", mLogUid, (long long)mLogdTimestampNs,
Yao Chen20e9e622018-02-28 11:18:51 -0800658 (long long)mElapsedTimestampNs, mTagId);
Yao Chen8a8d16c2018-02-08 14:50:40 -0800659 for (const auto& value : mValues) {
Yao Chen20e9e622018-02-28 11:18:51 -0800660 result +=
661 StringPrintf("%#x", value.mField.getField()) + "->" + value.mValue.toString() + " ";
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700662 }
Yao Chen20e9e622018-02-28 11:18:51 -0800663 result += " }";
664 return result;
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700665}
666
Yangster-mac20877162017-12-22 17:19:39 -0800667void LogEvent::ToProto(ProtoOutputStream& protoOutput) const {
Yao Chen8a8d16c2018-02-08 14:50:40 -0800668 writeFieldValueTreeToStream(mTagId, getValues(), &protoOutput);
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700669}
670
671} // namespace statsd
672} // namespace os
673} // namespace android