blob: febb9229bc9508f6b0b0b552af684781b0490cb1 [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
23namespace android {
24namespace os {
25namespace statsd {
26
yro24809bd2017-10-31 23:06:53 -070027using namespace android::util;
Yao Chen9c1debe2018-02-19 14:39:19 -080028using android::util::ProtoOutputStream;
David Chen1481fe12017-10-16 13:16:34 -070029using std::string;
Yao Chen9c1debe2018-02-19 14:39:19 -080030using std::vector;
Joe Onoratoc4dfae52017-10-17 23:38:21 -070031
Yao Chen80235402017-11-13 20:42:25 -080032LogEvent::LogEvent(log_msg& msg) {
Chenjie Yu3ca36832018-01-22 15:10:54 -080033 mContext =
Yao Chen80235402017-11-13 20:42:25 -080034 create_android_log_parser(msg.msg() + sizeof(uint32_t), msg.len() - sizeof(uint32_t));
Yangster-mac330af582018-02-08 15:24:38 -080035 mLogdTimestampNs = msg.entry_v1.sec * NS_PER_SEC + msg.entry_v1.nsec;
Yao Chend10f7b12017-12-18 12:53:50 -080036 mLogUid = msg.entry_v4.uid;
Chenjie Yu3ca36832018-01-22 15:10:54 -080037 init(mContext);
38 if (mContext) {
Yao Chen48d75182018-01-23 09:40:48 -080039 // android_log_destroy will set mContext to NULL
Chenjie Yu3ca36832018-01-22 15:10:54 -080040 android_log_destroy(&mContext);
Yangster-mac20877162017-12-22 17:19:39 -080041 }
Joe Onoratoc4dfae52017-10-17 23:38:21 -070042}
43
Chenjie Yu12e5e672018-09-14 15:54:59 -070044LogEvent::LogEvent(const StatsLogEventWrapper& statsLogEventWrapper) {
45 mTagId = statsLogEventWrapper.getTagId();
46 mLogdTimestampNs = statsLogEventWrapper.getWallClockTimeNs();
47 mElapsedTimestampNs = statsLogEventWrapper.getElapsedRealTimeNs();
48 mLogUid = 0;
49 for (int i = 0; i < (int)statsLogEventWrapper.getElements().size(); i++) {
50 Field field(statsLogEventWrapper.getTagId(), getSimpleField(i + 1));
51 switch (statsLogEventWrapper.getElements()[i].type) {
52 case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::INT:
53 mValues.push_back(
54 FieldValue(field, Value(statsLogEventWrapper.getElements()[i].int_value)));
55 break;
56 case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::LONG:
57 mValues.push_back(
58 FieldValue(field, Value(statsLogEventWrapper.getElements()[i].long_value)));
59 break;
60 case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::FLOAT:
61 mValues.push_back(FieldValue(
62 field, Value(statsLogEventWrapper.getElements()[i].float_value)));
63 break;
64 case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::DOUBLE:
65 mValues.push_back(FieldValue(
66 field, Value(statsLogEventWrapper.getElements()[i].double_value)));
67 break;
68 case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::STRING:
69 mValues.push_back(
70 FieldValue(field, Value(statsLogEventWrapper.getElements()[i].str_value)));
71 break;
72 case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::STORAGE:
73 mValues.push_back(FieldValue(
74 field, Value(statsLogEventWrapper.getElements()[i].storage_value)));
75 break;
76 default:
77 break;
78 }
79 }
80}
81
Yangster-mac330af582018-02-08 15:24:38 -080082LogEvent::LogEvent(int32_t tagId, int64_t wallClockTimestampNs, int64_t elapsedTimestampNs) {
83 mLogdTimestampNs = wallClockTimestampNs;
Yao Chen80235402017-11-13 20:42:25 -080084 mTagId = tagId;
Yangster-mac20877162017-12-22 17:19:39 -080085 mLogUid = 0;
Yao Chen80235402017-11-13 20:42:25 -080086 mContext = create_android_logger(1937006964); // the event tag shared by all stats logs
87 if (mContext) {
Yangster-mac330af582018-02-08 15:24:38 -080088 android_log_write_int64(mContext, elapsedTimestampNs);
89 android_log_write_int32(mContext, tagId);
90 }
91}
92
Yangster-mac48b3d622018-08-18 12:38:11 -070093LogEvent::LogEvent(int32_t tagId, int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
94 int32_t uid,
Howard Ro4078dd42018-09-27 17:41:08 -070095 const std::map<int32_t, int32_t>& int_map,
96 const std::map<int32_t, int64_t>& long_map,
Yangster-mac48b3d622018-08-18 12:38:11 -070097 const std::map<int32_t, std::string>& string_map,
98 const std::map<int32_t, float>& float_map) {
99 mLogdTimestampNs = wallClockTimestampNs;
100 mElapsedTimestampNs = elapsedTimestampNs;
101 mTagId = android::util::KEY_VALUE_PAIRS_ATOM;
102 mLogUid = uid;
103
104 int pos[] = {1, 1, 1};
105
106 mValues.push_back(FieldValue(Field(mTagId, pos, 0 /* depth */), Value(uid)));
107 pos[0]++;
108 for (const auto&itr : int_map) {
109 pos[2] = 1;
110 mValues.push_back(FieldValue(Field(mTagId, pos, 2 /* depth */), Value(itr.first)));
111 pos[2] = 2;
112 mValues.push_back(FieldValue(Field(mTagId, pos, 2 /* depth */), Value(itr.second)));
113 mValues.back().mField.decorateLastPos(2);
114 pos[1]++;
115 }
116
Howard Ro4078dd42018-09-27 17:41:08 -0700117 for (const auto&itr : long_map) {
Yangster-mac48b3d622018-08-18 12:38:11 -0700118 pos[2] = 1;
119 mValues.push_back(FieldValue(Field(mTagId, pos, 2 /* depth */), Value(itr.first)));
120 pos[2] = 3;
121 mValues.push_back(FieldValue(Field(mTagId, pos, 2 /* depth */), Value(itr.second)));
122 mValues.back().mField.decorateLastPos(2);
123 pos[1]++;
124 }
125
Howard Ro4078dd42018-09-27 17:41:08 -0700126 for (const auto&itr : string_map) {
Yangster-mac48b3d622018-08-18 12:38:11 -0700127 pos[2] = 1;
128 mValues.push_back(FieldValue(Field(mTagId, pos, 2 /* depth */), Value(itr.first)));
129 pos[2] = 4;
130 mValues.push_back(FieldValue(Field(mTagId, pos, 2 /* depth */), Value(itr.second)));
131 mValues.back().mField.decorateLastPos(2);
132 pos[1]++;
133 }
Howard Ro4078dd42018-09-27 17:41:08 -0700134
135 for (const auto&itr : float_map) {
136 pos[2] = 1;
137 mValues.push_back(FieldValue(Field(mTagId, pos, 2 /* depth */), Value(itr.first)));
138 pos[2] = 5;
139 mValues.push_back(FieldValue(Field(mTagId, pos, 2 /* depth */), Value(itr.second)));
140 mValues.back().mField.decorateLastPos(2);
141 pos[1]++;
142 }
Yangster-mac48b3d622018-08-18 12:38:11 -0700143 if (!mValues.empty()) {
144 mValues.back().mField.decorateLastPos(1);
145 mValues.at(mValues.size() - 2).mField.decorateLastPos(1);
146 }
147}
148
Howard Roa46b6582018-09-18 16:45:02 -0700149LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
150 const SpeakerImpedance& speakerImpedance) {
151 mLogdTimestampNs = wallClockTimestampNs;
152 mElapsedTimestampNs = elapsedTimestampNs;
153 mTagId = android::util::SPEAKER_IMPEDANCE_REPORTED;
154
155 mValues.push_back(
156 FieldValue(Field(mTagId, getSimpleField(1)), Value(speakerImpedance.speakerLocation)));
157 mValues.push_back(
158 FieldValue(Field(mTagId, getSimpleField(2)), Value(speakerImpedance.milliOhms)));
159 if (!mValues.empty()) {
160 mValues.back().mField.decorateLastPos(1);
161 }
162}
163
164LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
165 const HardwareFailed& hardwareFailed) {
166 mLogdTimestampNs = wallClockTimestampNs;
167 mElapsedTimestampNs = elapsedTimestampNs;
168 mTagId = android::util::HARDWARE_FAILED;
169
170 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(1)),
171 Value(int32_t(hardwareFailed.hardwareType))));
172 mValues.push_back(
173 FieldValue(Field(mTagId, getSimpleField(2)), Value(hardwareFailed.hardwareLocation)));
174 mValues.push_back(
175 FieldValue(Field(mTagId, getSimpleField(3)), Value(int32_t(hardwareFailed.errorCode))));
176 if (!mValues.empty()) {
177 mValues.back().mField.decorateLastPos(1);
178 }
179}
180
181LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
182 const PhysicalDropDetected& physicalDropDetected) {
183 mLogdTimestampNs = wallClockTimestampNs;
184 mElapsedTimestampNs = elapsedTimestampNs;
185 mTagId = android::util::PHYSICAL_DROP_DETECTED;
186
187 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(1)),
188 Value(int32_t(physicalDropDetected.confidencePctg))));
189 mValues.push_back(
190 FieldValue(Field(mTagId, getSimpleField(2)), Value(physicalDropDetected.accelPeak)));
191 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(3)),
192 Value(physicalDropDetected.freefallDuration)));
193 if (!mValues.empty()) {
194 mValues.back().mField.decorateLastPos(1);
195 }
196}
197
198LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
199 const ChargeCycles& chargeCycles) {
200 mLogdTimestampNs = wallClockTimestampNs;
201 mElapsedTimestampNs = elapsedTimestampNs;
202 mTagId = android::util::CHARGE_CYCLES_REPORTED;
203
204 for (size_t i = 0; i < chargeCycles.cycleBucket.size(); i++) {
205 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(i + 1)),
206 Value(chargeCycles.cycleBucket[i])));
207 }
208
209 if (!mValues.empty()) {
210 mValues.back().mField.decorateLastPos(1);
211 }
212}
213
214LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
215 const BatteryHealthSnapshotArgs& batteryHealthSnapshotArgs) {
216 mLogdTimestampNs = wallClockTimestampNs;
217 mElapsedTimestampNs = elapsedTimestampNs;
218 mTagId = android::util::BATTERY_HEALTH_SNAPSHOT;
219
220 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(1)),
221 Value(int32_t(batteryHealthSnapshotArgs.type))));
222 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(2)),
223 Value(batteryHealthSnapshotArgs.temperatureDeciC)));
224 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(3)),
225 Value(batteryHealthSnapshotArgs.voltageMicroV)));
226 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(4)),
227 Value(batteryHealthSnapshotArgs.currentMicroA)));
228 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(5)),
229 Value(batteryHealthSnapshotArgs.openCircuitVoltageMicroV)));
230 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(6)),
231 Value(batteryHealthSnapshotArgs.resistanceMicroOhm)));
232 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(7)),
233 Value(batteryHealthSnapshotArgs.levelPercent)));
234
235 if (!mValues.empty()) {
236 mValues.back().mField.decorateLastPos(1);
237 }
238}
239
240LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs, const SlowIo& slowIo) {
241 mLogdTimestampNs = wallClockTimestampNs;
242 mElapsedTimestampNs = elapsedTimestampNs;
243 mTagId = android::util::SLOW_IO;
244
245 int pos[] = {1};
246 mValues.push_back(
247 FieldValue(Field(mTagId, getSimpleField(1)), Value(int32_t(slowIo.operation))));
248 pos[0]++;
249 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(2)), Value(slowIo.count)));
250
251 if (!mValues.empty()) {
252 mValues.back().mField.decorateLastPos(1);
253 }
254}
255
256LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
257 const BatteryCausedShutdown& batteryCausedShutdown) {
258 mLogdTimestampNs = wallClockTimestampNs;
259 mElapsedTimestampNs = elapsedTimestampNs;
260 mTagId = android::util::BATTERY_CAUSED_SHUTDOWN;
261
262 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(1)),
263 Value(batteryCausedShutdown.voltageMicroV)));
264
265 if (!mValues.empty()) {
266 mValues.back().mField.decorateLastPos(1);
267 }
268}
269
Howard Ro1a2a3992018-10-22 22:51:57 -0700270LogEvent::LogEvent(int32_t tagId, int64_t timestampNs) : LogEvent(tagId, timestampNs, 0) {}
271
272LogEvent::LogEvent(int32_t tagId, int64_t timestampNs, int32_t uid) {
Yangster-mac330af582018-02-08 15:24:38 -0800273 mLogdTimestampNs = timestampNs;
274 mTagId = tagId;
Howard Ro1a2a3992018-10-22 22:51:57 -0700275 mLogUid = uid;
Yangster-mac330af582018-02-08 15:24:38 -0800276 mContext = create_android_logger(1937006964); // the event tag shared by all stats logs
277 if (mContext) {
278 android_log_write_int64(mContext, timestampNs);
Yao Chen80235402017-11-13 20:42:25 -0800279 android_log_write_int32(mContext, tagId);
280 }
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700281}
282
David Chen1481fe12017-10-16 13:16:34 -0700283void LogEvent::init() {
Yao Chen80235402017-11-13 20:42:25 -0800284 if (mContext) {
285 const char* buffer;
286 size_t len = android_log_write_list_buffer(mContext, &buffer);
287 // turns to reader mode
Chenjie Yuc1fe6f42018-02-01 23:14:18 -0800288 android_log_context contextForRead = create_android_log_parser(buffer, len);
289 if (contextForRead) {
290 init(contextForRead);
291 // destroy the context to save memory.
Yao Chen48d75182018-01-23 09:40:48 -0800292 // android_log_destroy will set mContext to NULL
Chenjie Yuc1fe6f42018-02-01 23:14:18 -0800293 android_log_destroy(&contextForRead);
Yao Chen48d75182018-01-23 09:40:48 -0800294 }
Chenjie Yuc1fe6f42018-02-01 23:14:18 -0800295 android_log_destroy(&mContext);
Yangster-mac20877162017-12-22 17:19:39 -0800296 }
297}
298
299LogEvent::~LogEvent() {
300 if (mContext) {
Yao Chen48d75182018-01-23 09:40:48 -0800301 // This is for the case when LogEvent is created using the test interface
302 // but init() isn't called.
Yangster-mac20877162017-12-22 17:19:39 -0800303 android_log_destroy(&mContext);
Yao Chen80235402017-11-13 20:42:25 -0800304 }
305}
306
307bool LogEvent::write(int32_t value) {
308 if (mContext) {
309 return android_log_write_int32(mContext, value) >= 0;
310 }
311 return false;
312}
313
314bool LogEvent::write(uint32_t value) {
315 if (mContext) {
316 return android_log_write_int32(mContext, value) >= 0;
317 }
318 return false;
319}
320
Chenjie Yud9dfda72017-12-11 17:41:20 -0800321bool LogEvent::write(int64_t value) {
322 if (mContext) {
323 return android_log_write_int64(mContext, value) >= 0;
324 }
325 return false;
326}
327
Yao Chen80235402017-11-13 20:42:25 -0800328bool LogEvent::write(uint64_t value) {
329 if (mContext) {
330 return android_log_write_int64(mContext, value) >= 0;
331 }
332 return false;
333}
334
335bool LogEvent::write(const string& value) {
336 if (mContext) {
337 return android_log_write_string8_len(mContext, value.c_str(), value.length()) >= 0;
338 }
339 return false;
340}
341
342bool LogEvent::write(float value) {
343 if (mContext) {
344 return android_log_write_float32(mContext, value) >= 0;
345 }
346 return false;
347}
348
Howard Ro1a2a3992018-10-22 22:51:57 -0700349bool LogEvent::writeKeyValuePairs(int32_t uid,
350 const std::map<int32_t, int32_t>& int_map,
Howard Ro4078dd42018-09-27 17:41:08 -0700351 const std::map<int32_t, int64_t>& long_map,
Yangster-mace124e422018-08-16 10:30:28 -0700352 const std::map<int32_t, std::string>& string_map,
353 const std::map<int32_t, float>& float_map) {
354 if (mContext) {
355 if (android_log_write_list_begin(mContext) < 0) {
356 return false;
357 }
Howard Ro1a2a3992018-10-22 22:51:57 -0700358 write(uid);
Yangster-mace124e422018-08-16 10:30:28 -0700359 for (const auto& itr : int_map) {
360 if (android_log_write_list_begin(mContext) < 0) {
361 return false;
362 }
363 write(itr.first);
364 write(itr.second);
365 if (android_log_write_list_end(mContext) < 0) {
366 return false;
367 }
368 }
369
Howard Ro4078dd42018-09-27 17:41:08 -0700370 for (const auto& itr : long_map) {
371 if (android_log_write_list_begin(mContext) < 0) {
372 return false;
373 }
374 write(itr.first);
375 write(itr.second);
376 if (android_log_write_list_end(mContext) < 0) {
377 return false;
378 }
379 }
380
Yangster-mace124e422018-08-16 10:30:28 -0700381 for (const auto& itr : string_map) {
382 if (android_log_write_list_begin(mContext) < 0) {
383 return false;
384 }
385 write(itr.first);
386 write(itr.second.c_str());
387 if (android_log_write_list_end(mContext) < 0) {
388 return false;
389 }
390 }
391
392 for (const auto& itr : float_map) {
393 if (android_log_write_list_begin(mContext) < 0) {
394 return false;
395 }
396 write(itr.first);
397 write(itr.second);
398 if (android_log_write_list_end(mContext) < 0) {
399 return false;
400 }
401 }
402
403 if (android_log_write_list_end(mContext) < 0) {
404 return false;
405 }
406 return true;
407 }
408 return false;
409}
410
Yao Chen9c1debe2018-02-19 14:39:19 -0800411bool LogEvent::write(const std::vector<AttributionNodeInternal>& nodes) {
Yao Chen80235402017-11-13 20:42:25 -0800412 if (mContext) {
Yangster-mac20877162017-12-22 17:19:39 -0800413 if (android_log_write_list_begin(mContext) < 0) {
414 return false;
415 }
416 for (size_t i = 0; i < nodes.size(); ++i) {
417 if (!write(nodes[i])) {
418 return false;
419 }
420 }
421 if (android_log_write_list_end(mContext) < 0) {
422 return false;
423 }
424 return true;
425 }
426 return false;
427}
428
Yao Chen9c1debe2018-02-19 14:39:19 -0800429bool LogEvent::write(const AttributionNodeInternal& node) {
Yangster-mac20877162017-12-22 17:19:39 -0800430 if (mContext) {
431 if (android_log_write_list_begin(mContext) < 0) {
432 return false;
433 }
434 if (android_log_write_int32(mContext, node.uid()) < 0) {
435 return false;
436 }
437 if (android_log_write_string8(mContext, node.tag().c_str()) < 0) {
438 return false;
439 }
Yangster-mac20877162017-12-22 17:19:39 -0800440 if (android_log_write_list_end(mContext) < 0) {
441 return false;
442 }
443 return true;
444 }
445 return false;
446}
447
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700448/**
449 * The elements of each log event are stored as a vector of android_log_list_elements.
450 * The goal is to do as little preprocessing as possible, because we read a tiny fraction
451 * of the elements that are written to the log.
Yao Chen8a8d16c2018-02-08 14:50:40 -0800452 *
453 * The idea here is to read through the log items once, we get as much information we need for
454 * matching as possible. Because this log will be matched against lots of matchers.
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700455 */
Yao Chen80235402017-11-13 20:42:25 -0800456void LogEvent::init(android_log_context context) {
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700457 android_log_list_element elem;
Yao Chen80235402017-11-13 20:42:25 -0800458 int i = 0;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800459 int depth = -1;
460 int pos[] = {1, 1, 1};
Yangster-mace124e422018-08-16 10:30:28 -0700461 bool isKeyValuePairAtom = false;
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700462 do {
Yao Chen80235402017-11-13 20:42:25 -0800463 elem = android_log_read_next(context);
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700464 switch ((int)elem.type) {
465 case EVENT_TYPE_INT:
Yangster-mac330af582018-02-08 15:24:38 -0800466 // elem at [0] is EVENT_TYPE_LIST, [1] is the timestamp, [2] is tag id.
467 if (i == 2) {
Yao Chen80235402017-11-13 20:42:25 -0800468 mTagId = elem.data.int32;
Yangster-mace124e422018-08-16 10:30:28 -0700469 isKeyValuePairAtom = (mTagId == android::util::KEY_VALUE_PAIRS_ATOM);
Yangster-mac20877162017-12-22 17:19:39 -0800470 } else {
Yao Chen8a8d16c2018-02-08 14:50:40 -0800471 if (depth < 0 || depth > 2) {
Yangster-mac20877162017-12-22 17:19:39 -0800472 return;
473 }
Yao Chen8a8d16c2018-02-08 14:50:40 -0800474
475 mValues.push_back(
476 FieldValue(Field(mTagId, pos, depth), Value((int32_t)elem.data.int32)));
477
478 pos[depth]++;
Yangster-mac20877162017-12-22 17:19:39 -0800479 }
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700480 break;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800481 case EVENT_TYPE_FLOAT: {
482 if (depth < 0 || depth > 2) {
483 ALOGE("Depth > 2. Not supported!");
484 return;
485 }
486
Yangster-mace124e422018-08-16 10:30:28 -0700487 // Handles the oneof field in KeyValuePair atom.
488 if (isKeyValuePairAtom && depth == 2) {
489 pos[depth] = 4;
490 }
491
Yao Chen8a8d16c2018-02-08 14:50:40 -0800492 mValues.push_back(FieldValue(Field(mTagId, pos, depth), Value(elem.data.float32)));
493
494 pos[depth]++;
495
496 } break;
497 case EVENT_TYPE_STRING: {
498 if (depth < 0 || depth > 2) {
499 ALOGE("Depth > 2. Not supported!");
500 return;
501 }
502
Yangster-mace124e422018-08-16 10:30:28 -0700503 // Handles the oneof field in KeyValuePair atom.
504 if (isKeyValuePairAtom && depth == 2) {
505 pos[depth] = 3;
506 }
Yao Chen8a8d16c2018-02-08 14:50:40 -0800507 mValues.push_back(FieldValue(Field(mTagId, pos, depth),
508 Value(string(elem.data.string, elem.len))));
509
510 pos[depth]++;
511
512 } break;
513 case EVENT_TYPE_LONG: {
Yangster-mac330af582018-02-08 15:24:38 -0800514 if (i == 1) {
515 mElapsedTimestampNs = elem.data.int64;
516 } else {
517 if (depth < 0 || depth > 2) {
518 ALOGE("Depth > 2. Not supported!");
519 return;
520 }
Yangster-mace124e422018-08-16 10:30:28 -0700521 // Handles the oneof field in KeyValuePair atom.
522 if (isKeyValuePairAtom && depth == 2) {
523 pos[depth] = 2;
524 }
Yangster-mac330af582018-02-08 15:24:38 -0800525 mValues.push_back(
526 FieldValue(Field(mTagId, pos, depth), Value((int64_t)elem.data.int64)));
527
528 pos[depth]++;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800529 }
Yao Chen8a8d16c2018-02-08 14:50:40 -0800530 } break;
531 case EVENT_TYPE_LIST:
532 depth++;
533 if (depth > 2) {
534 ALOGE("Depth > 2. Not supported!");
535 return;
536 }
537 pos[depth] = 1;
538
539 break;
540 case EVENT_TYPE_LIST_STOP: {
541 int prevDepth = depth;
542 depth--;
543 if (depth >= 0 && depth < 2) {
544 // Now go back to decorate the previous items that are last at prevDepth.
545 // So that we can later easily match them with Position=Last matchers.
546 pos[prevDepth]--;
547 int path = getEncodedField(pos, prevDepth, false);
Yao Chendb43afc2018-02-13 09:37:27 -0800548 for (auto it = mValues.rbegin(); it != mValues.rend(); ++it) {
549 if (it->mField.getDepth() >= prevDepth &&
550 it->mField.getPath(prevDepth) == path) {
551 it->mField.decorateLastPos(prevDepth);
Yao Chen8a8d16c2018-02-08 14:50:40 -0800552 } else {
553 // Safe to break, because the items are in DFS order.
554 break;
555 }
Yangster-mac20877162017-12-22 17:19:39 -0800556 }
Yao Chen8a8d16c2018-02-08 14:50:40 -0800557 pos[depth]++;
Yangster-mac20877162017-12-22 17:19:39 -0800558 }
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700559 break;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800560 }
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700561 case EVENT_TYPE_UNKNOWN:
562 break;
563 default:
564 break;
565 }
Yao Chen80235402017-11-13 20:42:25 -0800566 i++;
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700567 } while ((elem.type != EVENT_TYPE_UNKNOWN) && !elem.complete);
Howard Ro1a2a3992018-10-22 22:51:57 -0700568 if (isKeyValuePairAtom && mValues.size() > 0) {
569 mValues[0] = FieldValue(Field(android::util::KEY_VALUE_PAIRS_ATOM, getSimpleField(1)),
570 Value((int32_t)mLogUid));
571 }
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700572}
573
574int64_t LogEvent::GetLong(size_t key, status_t* err) const {
Yao Chen5bfffb52018-06-21 16:58:51 -0700575 // TODO(b/110561208): encapsulate the magical operations in Field struct as static functions
Yao Chen8a8d16c2018-02-08 14:50:40 -0800576 int field = getSimpleField(key);
577 for (const auto& value : mValues) {
578 if (value.mField.getField() == field) {
Yao Chenab92a1f2018-02-13 15:17:55 -0800579 if (value.mValue.getType() == LONG) {
580 return value.mValue.long_value;
581 } else if (value.mValue.getType() == INT) {
Yao Chen8a8d16c2018-02-08 14:50:40 -0800582 return value.mValue.int_value;
583 } else {
584 *err = BAD_TYPE;
585 return 0;
586 }
587 }
588 if ((size_t)value.mField.getPosAtDepth(0) > key) {
589 break;
Yangster-mac20877162017-12-22 17:19:39 -0800590 }
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700591 }
Yao Chen8a8d16c2018-02-08 14:50:40 -0800592
593 *err = BAD_INDEX;
594 return 0;
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700595}
596
Chenjie Yu80f91122018-01-31 20:24:50 -0800597int LogEvent::GetInt(size_t key, status_t* err) const {
Yao Chen8a8d16c2018-02-08 14:50:40 -0800598 int field = getSimpleField(key);
599 for (const auto& value : mValues) {
600 if (value.mField.getField() == field) {
601 if (value.mValue.getType() == INT) {
602 return value.mValue.int_value;
603 } else {
604 *err = BAD_TYPE;
605 return 0;
606 }
607 }
608 if ((size_t)value.mField.getPosAtDepth(0) > key) {
609 break;
610 }
611 }
612
Chenjie Yu80f91122018-01-31 20:24:50 -0800613 *err = BAD_INDEX;
614 return 0;
Chenjie Yu80f91122018-01-31 20:24:50 -0800615}
616
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700617const char* LogEvent::GetString(size_t key, status_t* err) const {
Yao Chen8a8d16c2018-02-08 14:50:40 -0800618 int field = getSimpleField(key);
619 for (const auto& value : mValues) {
620 if (value.mField.getField() == field) {
621 if (value.mValue.getType() == STRING) {
622 return value.mValue.str_value.c_str();
623 } else {
624 *err = BAD_TYPE;
625 return 0;
626 }
627 }
628 if ((size_t)value.mField.getPosAtDepth(0) > key) {
629 break;
Yangster-mac20877162017-12-22 17:19:39 -0800630 }
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700631 }
Yao Chen8a8d16c2018-02-08 14:50:40 -0800632
633 *err = BAD_INDEX;
634 return NULL;
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700635}
636
637bool LogEvent::GetBool(size_t key, status_t* err) const {
Yao Chen8a8d16c2018-02-08 14:50:40 -0800638 int field = getSimpleField(key);
639 for (const auto& value : mValues) {
640 if (value.mField.getField() == field) {
641 if (value.mValue.getType() == INT) {
642 return value.mValue.int_value != 0;
643 } else if (value.mValue.getType() == LONG) {
644 return value.mValue.long_value != 0;
645 } else {
646 *err = BAD_TYPE;
647 return false;
648 }
649 }
650 if ((size_t)value.mField.getPosAtDepth(0) > key) {
651 break;
Yangster-mac20877162017-12-22 17:19:39 -0800652 }
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700653 }
Yao Chen8a8d16c2018-02-08 14:50:40 -0800654
655 *err = BAD_INDEX;
656 return false;
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700657}
658
659float LogEvent::GetFloat(size_t key, status_t* err) const {
Yao Chen8a8d16c2018-02-08 14:50:40 -0800660 int field = getSimpleField(key);
661 for (const auto& value : mValues) {
662 if (value.mField.getField() == field) {
663 if (value.mValue.getType() == FLOAT) {
664 return value.mValue.float_value;
665 } else {
666 *err = BAD_TYPE;
667 return 0.0;
668 }
669 }
670 if ((size_t)value.mField.getPosAtDepth(0) > key) {
671 break;
Yangster-mac20877162017-12-22 17:19:39 -0800672 }
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700673 }
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700674
Yao Chen8a8d16c2018-02-08 14:50:40 -0800675 *err = BAD_INDEX;
676 return 0.0;
Yangster-macd40053e2018-01-09 16:29:22 -0800677}
678
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700679string LogEvent::ToString() const {
Yao Chen20e9e622018-02-28 11:18:51 -0800680 string result;
681 result += StringPrintf("{ %lld %lld (%d)", (long long)mLogdTimestampNs,
682 (long long)mElapsedTimestampNs, mTagId);
Yao Chen8a8d16c2018-02-08 14:50:40 -0800683 for (const auto& value : mValues) {
Yao Chen20e9e622018-02-28 11:18:51 -0800684 result +=
685 StringPrintf("%#x", value.mField.getField()) + "->" + value.mValue.toString() + " ";
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700686 }
Yao Chen20e9e622018-02-28 11:18:51 -0800687 result += " }";
688 return result;
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700689}
690
Yangster-mac20877162017-12-22 17:19:39 -0800691void LogEvent::ToProto(ProtoOutputStream& protoOutput) const {
Yao Chen8a8d16c2018-02-08 14:50:40 -0800692 writeFieldValueTreeToStream(mTagId, getValues(), &protoOutput);
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700693}
694
695} // namespace statsd
696} // namespace os
697} // namespace android