blob: b9732a596b2d1655fac6c9a6261962ee45d6077e [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 Yud7e3a222018-11-28 21:29:44 +000044LogEvent::LogEvent(const StatsLogEventWrapper& statsLogEventWrapper, int workChainIndex) {
Chenjie Yu12e5e672018-09-14 15:54:59 -070045 mTagId = statsLogEventWrapper.getTagId();
46 mLogdTimestampNs = statsLogEventWrapper.getWallClockTimeNs();
47 mElapsedTimestampNs = statsLogEventWrapper.getElapsedRealTimeNs();
48 mLogUid = 0;
Chenjie Yud7e3a222018-11-28 21:29:44 +000049 int workChainPosOffset = 0;
50 if (workChainIndex != -1) {
51 const WorkChain& wc = statsLogEventWrapper.getWorkChains()[workChainIndex];
52 // chains are at field 1, level 2
53 int depth = 2;
54 for (int i = 0; i < (int)wc.uids.size(); i++) {
55 int pos[] = {1, i + 1, 1};
56 mValues.push_back(FieldValue(Field(mTagId, pos, depth), Value(wc.uids[i])));
57 pos[2]++;
58 mValues.push_back(FieldValue(Field(mTagId, pos, depth), Value(wc.tags[i])));
59 mValues.back().mField.decorateLastPos(2);
60 }
61 mValues.back().mField.decorateLastPos(1);
62 workChainPosOffset = 1;
63 }
Chenjie Yu12e5e672018-09-14 15:54:59 -070064 for (int i = 0; i < (int)statsLogEventWrapper.getElements().size(); i++) {
Chenjie Yud7e3a222018-11-28 21:29:44 +000065 Field field(statsLogEventWrapper.getTagId(), getSimpleField(i + 1 + workChainPosOffset));
Chenjie Yu12e5e672018-09-14 15:54:59 -070066 switch (statsLogEventWrapper.getElements()[i].type) {
67 case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::INT:
68 mValues.push_back(
69 FieldValue(field, Value(statsLogEventWrapper.getElements()[i].int_value)));
70 break;
71 case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::LONG:
72 mValues.push_back(
73 FieldValue(field, Value(statsLogEventWrapper.getElements()[i].long_value)));
74 break;
75 case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::FLOAT:
76 mValues.push_back(FieldValue(
77 field, Value(statsLogEventWrapper.getElements()[i].float_value)));
78 break;
79 case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::DOUBLE:
80 mValues.push_back(FieldValue(
81 field, Value(statsLogEventWrapper.getElements()[i].double_value)));
82 break;
83 case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::STRING:
84 mValues.push_back(
85 FieldValue(field, Value(statsLogEventWrapper.getElements()[i].str_value)));
86 break;
87 case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::STORAGE:
88 mValues.push_back(FieldValue(
89 field, Value(statsLogEventWrapper.getElements()[i].storage_value)));
90 break;
91 default:
92 break;
93 }
94 }
95}
96
Chenjie Yud7e3a222018-11-28 21:29:44 +000097void LogEvent::createLogEvents(const StatsLogEventWrapper& statsLogEventWrapper,
98 std::vector<std::shared_ptr<LogEvent>>& logEvents) {
99 if (statsLogEventWrapper.getWorkChains().size() == 0) {
100 logEvents.push_back(std::make_shared<LogEvent>(statsLogEventWrapper, -1));
101 } else {
102 for (size_t i = 0; i < statsLogEventWrapper.getWorkChains().size(); i++) {
103 logEvents.push_back(std::make_shared<LogEvent>(statsLogEventWrapper, i));
104 }
105 }
106}
107
Yangster-mac330af582018-02-08 15:24:38 -0800108LogEvent::LogEvent(int32_t tagId, int64_t wallClockTimestampNs, int64_t elapsedTimestampNs) {
109 mLogdTimestampNs = wallClockTimestampNs;
Yao Chen80235402017-11-13 20:42:25 -0800110 mTagId = tagId;
Yangster-mac20877162017-12-22 17:19:39 -0800111 mLogUid = 0;
Yao Chen80235402017-11-13 20:42:25 -0800112 mContext = create_android_logger(1937006964); // the event tag shared by all stats logs
113 if (mContext) {
Yangster-mac330af582018-02-08 15:24:38 -0800114 android_log_write_int64(mContext, elapsedTimestampNs);
115 android_log_write_int32(mContext, tagId);
116 }
117}
118
Yangster-mac48b3d622018-08-18 12:38:11 -0700119LogEvent::LogEvent(int32_t tagId, int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
120 int32_t uid,
Howard Ro4078dd42018-09-27 17:41:08 -0700121 const std::map<int32_t, int32_t>& int_map,
122 const std::map<int32_t, int64_t>& long_map,
Yangster-mac48b3d622018-08-18 12:38:11 -0700123 const std::map<int32_t, std::string>& string_map,
124 const std::map<int32_t, float>& float_map) {
125 mLogdTimestampNs = wallClockTimestampNs;
126 mElapsedTimestampNs = elapsedTimestampNs;
127 mTagId = android::util::KEY_VALUE_PAIRS_ATOM;
128 mLogUid = uid;
129
130 int pos[] = {1, 1, 1};
131
132 mValues.push_back(FieldValue(Field(mTagId, pos, 0 /* depth */), Value(uid)));
133 pos[0]++;
134 for (const auto&itr : int_map) {
135 pos[2] = 1;
136 mValues.push_back(FieldValue(Field(mTagId, pos, 2 /* depth */), Value(itr.first)));
137 pos[2] = 2;
138 mValues.push_back(FieldValue(Field(mTagId, pos, 2 /* depth */), Value(itr.second)));
139 mValues.back().mField.decorateLastPos(2);
140 pos[1]++;
141 }
142
Howard Ro4078dd42018-09-27 17:41:08 -0700143 for (const auto&itr : long_map) {
Yangster-mac48b3d622018-08-18 12:38:11 -0700144 pos[2] = 1;
145 mValues.push_back(FieldValue(Field(mTagId, pos, 2 /* depth */), Value(itr.first)));
146 pos[2] = 3;
147 mValues.push_back(FieldValue(Field(mTagId, pos, 2 /* depth */), Value(itr.second)));
148 mValues.back().mField.decorateLastPos(2);
149 pos[1]++;
150 }
151
Howard Ro4078dd42018-09-27 17:41:08 -0700152 for (const auto&itr : string_map) {
Yangster-mac48b3d622018-08-18 12:38:11 -0700153 pos[2] = 1;
154 mValues.push_back(FieldValue(Field(mTagId, pos, 2 /* depth */), Value(itr.first)));
155 pos[2] = 4;
156 mValues.push_back(FieldValue(Field(mTagId, pos, 2 /* depth */), Value(itr.second)));
157 mValues.back().mField.decorateLastPos(2);
158 pos[1]++;
159 }
Howard Ro4078dd42018-09-27 17:41:08 -0700160
161 for (const auto&itr : float_map) {
162 pos[2] = 1;
163 mValues.push_back(FieldValue(Field(mTagId, pos, 2 /* depth */), Value(itr.first)));
164 pos[2] = 5;
165 mValues.push_back(FieldValue(Field(mTagId, pos, 2 /* depth */), Value(itr.second)));
166 mValues.back().mField.decorateLastPos(2);
167 pos[1]++;
168 }
Yangster-mac48b3d622018-08-18 12:38:11 -0700169 if (!mValues.empty()) {
170 mValues.back().mField.decorateLastPos(1);
171 mValues.at(mValues.size() - 2).mField.decorateLastPos(1);
172 }
173}
174
Howard Roa46b6582018-09-18 16:45:02 -0700175LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
176 const SpeakerImpedance& speakerImpedance) {
177 mLogdTimestampNs = wallClockTimestampNs;
178 mElapsedTimestampNs = elapsedTimestampNs;
179 mTagId = android::util::SPEAKER_IMPEDANCE_REPORTED;
180
181 mValues.push_back(
182 FieldValue(Field(mTagId, getSimpleField(1)), Value(speakerImpedance.speakerLocation)));
183 mValues.push_back(
184 FieldValue(Field(mTagId, getSimpleField(2)), Value(speakerImpedance.milliOhms)));
Howard Roa46b6582018-09-18 16:45:02 -0700185}
186
187LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
188 const HardwareFailed& hardwareFailed) {
189 mLogdTimestampNs = wallClockTimestampNs;
190 mElapsedTimestampNs = elapsedTimestampNs;
191 mTagId = android::util::HARDWARE_FAILED;
192
193 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(1)),
194 Value(int32_t(hardwareFailed.hardwareType))));
195 mValues.push_back(
196 FieldValue(Field(mTagId, getSimpleField(2)), Value(hardwareFailed.hardwareLocation)));
197 mValues.push_back(
198 FieldValue(Field(mTagId, getSimpleField(3)), Value(int32_t(hardwareFailed.errorCode))));
Howard Roa46b6582018-09-18 16:45:02 -0700199}
200
201LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
202 const PhysicalDropDetected& physicalDropDetected) {
203 mLogdTimestampNs = wallClockTimestampNs;
204 mElapsedTimestampNs = elapsedTimestampNs;
205 mTagId = android::util::PHYSICAL_DROP_DETECTED;
206
207 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(1)),
208 Value(int32_t(physicalDropDetected.confidencePctg))));
209 mValues.push_back(
210 FieldValue(Field(mTagId, getSimpleField(2)), Value(physicalDropDetected.accelPeak)));
211 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(3)),
212 Value(physicalDropDetected.freefallDuration)));
Howard Roa46b6582018-09-18 16:45:02 -0700213}
214
215LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
216 const ChargeCycles& chargeCycles) {
217 mLogdTimestampNs = wallClockTimestampNs;
218 mElapsedTimestampNs = elapsedTimestampNs;
219 mTagId = android::util::CHARGE_CYCLES_REPORTED;
220
221 for (size_t i = 0; i < chargeCycles.cycleBucket.size(); i++) {
222 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(i + 1)),
223 Value(chargeCycles.cycleBucket[i])));
224 }
Howard Roa46b6582018-09-18 16:45:02 -0700225}
226
227LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
228 const BatteryHealthSnapshotArgs& batteryHealthSnapshotArgs) {
229 mLogdTimestampNs = wallClockTimestampNs;
230 mElapsedTimestampNs = elapsedTimestampNs;
231 mTagId = android::util::BATTERY_HEALTH_SNAPSHOT;
232
233 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(1)),
234 Value(int32_t(batteryHealthSnapshotArgs.type))));
235 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(2)),
236 Value(batteryHealthSnapshotArgs.temperatureDeciC)));
237 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(3)),
238 Value(batteryHealthSnapshotArgs.voltageMicroV)));
239 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(4)),
240 Value(batteryHealthSnapshotArgs.currentMicroA)));
241 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(5)),
242 Value(batteryHealthSnapshotArgs.openCircuitVoltageMicroV)));
243 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(6)),
244 Value(batteryHealthSnapshotArgs.resistanceMicroOhm)));
245 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(7)),
246 Value(batteryHealthSnapshotArgs.levelPercent)));
Howard Roa46b6582018-09-18 16:45:02 -0700247}
248
249LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs, const SlowIo& slowIo) {
250 mLogdTimestampNs = wallClockTimestampNs;
251 mElapsedTimestampNs = elapsedTimestampNs;
252 mTagId = android::util::SLOW_IO;
253
254 int pos[] = {1};
255 mValues.push_back(
256 FieldValue(Field(mTagId, getSimpleField(1)), Value(int32_t(slowIo.operation))));
257 pos[0]++;
258 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(2)), Value(slowIo.count)));
Howard Roa46b6582018-09-18 16:45:02 -0700259}
260
261LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
262 const BatteryCausedShutdown& batteryCausedShutdown) {
263 mLogdTimestampNs = wallClockTimestampNs;
264 mElapsedTimestampNs = elapsedTimestampNs;
265 mTagId = android::util::BATTERY_CAUSED_SHUTDOWN;
266
267 mValues.push_back(FieldValue(Field(mTagId, getSimpleField(1)),
268 Value(batteryCausedShutdown.voltageMicroV)));
Howard Roa46b6582018-09-18 16:45:02 -0700269}
270
Howard Ro1a2a3992018-10-22 22:51:57 -0700271LogEvent::LogEvent(int32_t tagId, int64_t timestampNs) : LogEvent(tagId, timestampNs, 0) {}
272
273LogEvent::LogEvent(int32_t tagId, int64_t timestampNs, int32_t uid) {
Yangster-mac330af582018-02-08 15:24:38 -0800274 mLogdTimestampNs = timestampNs;
275 mTagId = tagId;
Howard Ro1a2a3992018-10-22 22:51:57 -0700276 mLogUid = uid;
Yangster-mac330af582018-02-08 15:24:38 -0800277 mContext = create_android_logger(1937006964); // the event tag shared by all stats logs
278 if (mContext) {
279 android_log_write_int64(mContext, timestampNs);
Yao Chen80235402017-11-13 20:42:25 -0800280 android_log_write_int32(mContext, tagId);
281 }
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700282}
283
David Chen1481fe12017-10-16 13:16:34 -0700284void LogEvent::init() {
Yao Chen80235402017-11-13 20:42:25 -0800285 if (mContext) {
286 const char* buffer;
287 size_t len = android_log_write_list_buffer(mContext, &buffer);
288 // turns to reader mode
Chenjie Yuc1fe6f42018-02-01 23:14:18 -0800289 android_log_context contextForRead = create_android_log_parser(buffer, len);
290 if (contextForRead) {
291 init(contextForRead);
292 // destroy the context to save memory.
Yao Chen48d75182018-01-23 09:40:48 -0800293 // android_log_destroy will set mContext to NULL
Chenjie Yuc1fe6f42018-02-01 23:14:18 -0800294 android_log_destroy(&contextForRead);
Yao Chen48d75182018-01-23 09:40:48 -0800295 }
Chenjie Yuc1fe6f42018-02-01 23:14:18 -0800296 android_log_destroy(&mContext);
Yangster-mac20877162017-12-22 17:19:39 -0800297 }
298}
299
300LogEvent::~LogEvent() {
301 if (mContext) {
Yao Chen48d75182018-01-23 09:40:48 -0800302 // This is for the case when LogEvent is created using the test interface
303 // but init() isn't called.
Yangster-mac20877162017-12-22 17:19:39 -0800304 android_log_destroy(&mContext);
Yao Chen80235402017-11-13 20:42:25 -0800305 }
306}
307
308bool LogEvent::write(int32_t value) {
309 if (mContext) {
310 return android_log_write_int32(mContext, value) >= 0;
311 }
312 return false;
313}
314
315bool LogEvent::write(uint32_t value) {
316 if (mContext) {
317 return android_log_write_int32(mContext, value) >= 0;
318 }
319 return false;
320}
321
Chenjie Yud9dfda72017-12-11 17:41:20 -0800322bool LogEvent::write(int64_t value) {
323 if (mContext) {
324 return android_log_write_int64(mContext, value) >= 0;
325 }
326 return false;
327}
328
Yao Chen80235402017-11-13 20:42:25 -0800329bool LogEvent::write(uint64_t value) {
330 if (mContext) {
331 return android_log_write_int64(mContext, value) >= 0;
332 }
333 return false;
334}
335
336bool LogEvent::write(const string& value) {
337 if (mContext) {
338 return android_log_write_string8_len(mContext, value.c_str(), value.length()) >= 0;
339 }
340 return false;
341}
342
343bool LogEvent::write(float value) {
344 if (mContext) {
345 return android_log_write_float32(mContext, value) >= 0;
346 }
347 return false;
348}
349
Howard Ro1a2a3992018-10-22 22:51:57 -0700350bool LogEvent::writeKeyValuePairs(int32_t uid,
351 const std::map<int32_t, int32_t>& int_map,
Howard Ro4078dd42018-09-27 17:41:08 -0700352 const std::map<int32_t, int64_t>& long_map,
Yangster-mace124e422018-08-16 10:30:28 -0700353 const std::map<int32_t, std::string>& string_map,
354 const std::map<int32_t, float>& float_map) {
355 if (mContext) {
356 if (android_log_write_list_begin(mContext) < 0) {
357 return false;
358 }
Howard Ro1a2a3992018-10-22 22:51:57 -0700359 write(uid);
Yangster-mace124e422018-08-16 10:30:28 -0700360 for (const auto& itr : int_map) {
361 if (android_log_write_list_begin(mContext) < 0) {
362 return false;
363 }
364 write(itr.first);
365 write(itr.second);
366 if (android_log_write_list_end(mContext) < 0) {
367 return false;
368 }
369 }
370
Howard Ro4078dd42018-09-27 17:41:08 -0700371 for (const auto& itr : long_map) {
372 if (android_log_write_list_begin(mContext) < 0) {
373 return false;
374 }
375 write(itr.first);
376 write(itr.second);
377 if (android_log_write_list_end(mContext) < 0) {
378 return false;
379 }
380 }
381
Yangster-mace124e422018-08-16 10:30:28 -0700382 for (const auto& itr : string_map) {
383 if (android_log_write_list_begin(mContext) < 0) {
384 return false;
385 }
386 write(itr.first);
387 write(itr.second.c_str());
388 if (android_log_write_list_end(mContext) < 0) {
389 return false;
390 }
391 }
392
393 for (const auto& itr : float_map) {
394 if (android_log_write_list_begin(mContext) < 0) {
395 return false;
396 }
397 write(itr.first);
398 write(itr.second);
399 if (android_log_write_list_end(mContext) < 0) {
400 return false;
401 }
402 }
403
404 if (android_log_write_list_end(mContext) < 0) {
405 return false;
406 }
407 return true;
408 }
409 return false;
410}
411
Yao Chen9c1debe2018-02-19 14:39:19 -0800412bool LogEvent::write(const std::vector<AttributionNodeInternal>& nodes) {
Yao Chen80235402017-11-13 20:42:25 -0800413 if (mContext) {
Yangster-mac20877162017-12-22 17:19:39 -0800414 if (android_log_write_list_begin(mContext) < 0) {
415 return false;
416 }
417 for (size_t i = 0; i < nodes.size(); ++i) {
418 if (!write(nodes[i])) {
419 return false;
420 }
421 }
422 if (android_log_write_list_end(mContext) < 0) {
423 return false;
424 }
425 return true;
426 }
427 return false;
428}
429
Yao Chen9c1debe2018-02-19 14:39:19 -0800430bool LogEvent::write(const AttributionNodeInternal& node) {
Yangster-mac20877162017-12-22 17:19:39 -0800431 if (mContext) {
432 if (android_log_write_list_begin(mContext) < 0) {
433 return false;
434 }
435 if (android_log_write_int32(mContext, node.uid()) < 0) {
436 return false;
437 }
438 if (android_log_write_string8(mContext, node.tag().c_str()) < 0) {
439 return false;
440 }
Yangster-mac20877162017-12-22 17:19:39 -0800441 if (android_log_write_list_end(mContext) < 0) {
442 return false;
443 }
444 return true;
445 }
446 return false;
447}
448
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700449/**
450 * The elements of each log event are stored as a vector of android_log_list_elements.
451 * The goal is to do as little preprocessing as possible, because we read a tiny fraction
452 * of the elements that are written to the log.
Yao Chen8a8d16c2018-02-08 14:50:40 -0800453 *
454 * The idea here is to read through the log items once, we get as much information we need for
455 * matching as possible. Because this log will be matched against lots of matchers.
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700456 */
Yao Chen80235402017-11-13 20:42:25 -0800457void LogEvent::init(android_log_context context) {
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700458 android_log_list_element elem;
Yao Chen80235402017-11-13 20:42:25 -0800459 int i = 0;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800460 int depth = -1;
461 int pos[] = {1, 1, 1};
Yangster-mace124e422018-08-16 10:30:28 -0700462 bool isKeyValuePairAtom = false;
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700463 do {
Yao Chen80235402017-11-13 20:42:25 -0800464 elem = android_log_read_next(context);
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700465 switch ((int)elem.type) {
466 case EVENT_TYPE_INT:
Yangster-mac330af582018-02-08 15:24:38 -0800467 // elem at [0] is EVENT_TYPE_LIST, [1] is the timestamp, [2] is tag id.
468 if (i == 2) {
Yao Chen80235402017-11-13 20:42:25 -0800469 mTagId = elem.data.int32;
Yangster-mace124e422018-08-16 10:30:28 -0700470 isKeyValuePairAtom = (mTagId == android::util::KEY_VALUE_PAIRS_ATOM);
Yangster-mac20877162017-12-22 17:19:39 -0800471 } else {
Yao Chen8a8d16c2018-02-08 14:50:40 -0800472 if (depth < 0 || depth > 2) {
Yangster-mac20877162017-12-22 17:19:39 -0800473 return;
474 }
Yao Chen8a8d16c2018-02-08 14:50:40 -0800475
476 mValues.push_back(
477 FieldValue(Field(mTagId, pos, depth), Value((int32_t)elem.data.int32)));
478
479 pos[depth]++;
Yangster-mac20877162017-12-22 17:19:39 -0800480 }
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700481 break;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800482 case EVENT_TYPE_FLOAT: {
483 if (depth < 0 || depth > 2) {
484 ALOGE("Depth > 2. Not supported!");
485 return;
486 }
487
Yangster-mace124e422018-08-16 10:30:28 -0700488 // Handles the oneof field in KeyValuePair atom.
489 if (isKeyValuePairAtom && depth == 2) {
490 pos[depth] = 4;
491 }
492
Yao Chen8a8d16c2018-02-08 14:50:40 -0800493 mValues.push_back(FieldValue(Field(mTagId, pos, depth), Value(elem.data.float32)));
494
495 pos[depth]++;
496
497 } break;
498 case EVENT_TYPE_STRING: {
499 if (depth < 0 || depth > 2) {
500 ALOGE("Depth > 2. Not supported!");
501 return;
502 }
503
Yangster-mace124e422018-08-16 10:30:28 -0700504 // Handles the oneof field in KeyValuePair atom.
505 if (isKeyValuePairAtom && depth == 2) {
506 pos[depth] = 3;
507 }
Yao Chen8a8d16c2018-02-08 14:50:40 -0800508 mValues.push_back(FieldValue(Field(mTagId, pos, depth),
509 Value(string(elem.data.string, elem.len))));
510
511 pos[depth]++;
512
513 } break;
514 case EVENT_TYPE_LONG: {
Yangster-mac330af582018-02-08 15:24:38 -0800515 if (i == 1) {
516 mElapsedTimestampNs = elem.data.int64;
517 } else {
518 if (depth < 0 || depth > 2) {
519 ALOGE("Depth > 2. Not supported!");
520 return;
521 }
Yangster-mace124e422018-08-16 10:30:28 -0700522 // Handles the oneof field in KeyValuePair atom.
523 if (isKeyValuePairAtom && depth == 2) {
524 pos[depth] = 2;
525 }
Yangster-mac330af582018-02-08 15:24:38 -0800526 mValues.push_back(
527 FieldValue(Field(mTagId, pos, depth), Value((int64_t)elem.data.int64)));
528
529 pos[depth]++;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800530 }
Yao Chen8a8d16c2018-02-08 14:50:40 -0800531 } break;
532 case EVENT_TYPE_LIST:
533 depth++;
534 if (depth > 2) {
535 ALOGE("Depth > 2. Not supported!");
536 return;
537 }
538 pos[depth] = 1;
539
540 break;
541 case EVENT_TYPE_LIST_STOP: {
542 int prevDepth = depth;
543 depth--;
544 if (depth >= 0 && depth < 2) {
545 // Now go back to decorate the previous items that are last at prevDepth.
546 // So that we can later easily match them with Position=Last matchers.
547 pos[prevDepth]--;
548 int path = getEncodedField(pos, prevDepth, false);
Yao Chendb43afc2018-02-13 09:37:27 -0800549 for (auto it = mValues.rbegin(); it != mValues.rend(); ++it) {
550 if (it->mField.getDepth() >= prevDepth &&
551 it->mField.getPath(prevDepth) == path) {
552 it->mField.decorateLastPos(prevDepth);
Yao Chen8a8d16c2018-02-08 14:50:40 -0800553 } else {
554 // Safe to break, because the items are in DFS order.
555 break;
556 }
Yangster-mac20877162017-12-22 17:19:39 -0800557 }
Yao Chen8a8d16c2018-02-08 14:50:40 -0800558 pos[depth]++;
Yangster-mac20877162017-12-22 17:19:39 -0800559 }
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700560 break;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800561 }
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700562 case EVENT_TYPE_UNKNOWN:
563 break;
564 default:
565 break;
566 }
Yao Chen80235402017-11-13 20:42:25 -0800567 i++;
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700568 } while ((elem.type != EVENT_TYPE_UNKNOWN) && !elem.complete);
Howard Ro1a2a3992018-10-22 22:51:57 -0700569 if (isKeyValuePairAtom && mValues.size() > 0) {
570 mValues[0] = FieldValue(Field(android::util::KEY_VALUE_PAIRS_ATOM, getSimpleField(1)),
571 Value((int32_t)mLogUid));
572 }
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700573}
574
575int64_t LogEvent::GetLong(size_t key, status_t* err) const {
Yao Chen5bfffb52018-06-21 16:58:51 -0700576 // TODO(b/110561208): encapsulate the magical operations in Field struct as static functions
Yao Chen8a8d16c2018-02-08 14:50:40 -0800577 int field = getSimpleField(key);
578 for (const auto& value : mValues) {
579 if (value.mField.getField() == field) {
Yao Chenab92a1f2018-02-13 15:17:55 -0800580 if (value.mValue.getType() == LONG) {
581 return value.mValue.long_value;
582 } else if (value.mValue.getType() == INT) {
Yao Chen8a8d16c2018-02-08 14:50:40 -0800583 return value.mValue.int_value;
584 } else {
585 *err = BAD_TYPE;
586 return 0;
587 }
588 }
589 if ((size_t)value.mField.getPosAtDepth(0) > key) {
590 break;
Yangster-mac20877162017-12-22 17:19:39 -0800591 }
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700592 }
Yao Chen8a8d16c2018-02-08 14:50:40 -0800593
594 *err = BAD_INDEX;
595 return 0;
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700596}
597
Chenjie Yu80f91122018-01-31 20:24:50 -0800598int LogEvent::GetInt(size_t key, status_t* err) const {
Yao Chen8a8d16c2018-02-08 14:50:40 -0800599 int field = getSimpleField(key);
600 for (const auto& value : mValues) {
601 if (value.mField.getField() == field) {
602 if (value.mValue.getType() == INT) {
603 return value.mValue.int_value;
604 } else {
605 *err = BAD_TYPE;
606 return 0;
607 }
608 }
609 if ((size_t)value.mField.getPosAtDepth(0) > key) {
610 break;
611 }
612 }
613
Chenjie Yu80f91122018-01-31 20:24:50 -0800614 *err = BAD_INDEX;
615 return 0;
Chenjie Yu80f91122018-01-31 20:24:50 -0800616}
617
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700618const char* LogEvent::GetString(size_t key, status_t* err) const {
Yao Chen8a8d16c2018-02-08 14:50:40 -0800619 int field = getSimpleField(key);
620 for (const auto& value : mValues) {
621 if (value.mField.getField() == field) {
622 if (value.mValue.getType() == STRING) {
623 return value.mValue.str_value.c_str();
624 } else {
625 *err = BAD_TYPE;
626 return 0;
627 }
628 }
629 if ((size_t)value.mField.getPosAtDepth(0) > key) {
630 break;
Yangster-mac20877162017-12-22 17:19:39 -0800631 }
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700632 }
Yao Chen8a8d16c2018-02-08 14:50:40 -0800633
634 *err = BAD_INDEX;
635 return NULL;
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700636}
637
638bool LogEvent::GetBool(size_t key, status_t* err) const {
Yao Chen8a8d16c2018-02-08 14:50:40 -0800639 int field = getSimpleField(key);
640 for (const auto& value : mValues) {
641 if (value.mField.getField() == field) {
642 if (value.mValue.getType() == INT) {
643 return value.mValue.int_value != 0;
644 } else if (value.mValue.getType() == LONG) {
645 return value.mValue.long_value != 0;
646 } else {
647 *err = BAD_TYPE;
648 return false;
649 }
650 }
651 if ((size_t)value.mField.getPosAtDepth(0) > key) {
652 break;
Yangster-mac20877162017-12-22 17:19:39 -0800653 }
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700654 }
Yao Chen8a8d16c2018-02-08 14:50:40 -0800655
656 *err = BAD_INDEX;
657 return false;
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700658}
659
660float LogEvent::GetFloat(size_t key, status_t* err) const {
Yao Chen8a8d16c2018-02-08 14:50:40 -0800661 int field = getSimpleField(key);
662 for (const auto& value : mValues) {
663 if (value.mField.getField() == field) {
664 if (value.mValue.getType() == FLOAT) {
665 return value.mValue.float_value;
666 } else {
667 *err = BAD_TYPE;
668 return 0.0;
669 }
670 }
671 if ((size_t)value.mField.getPosAtDepth(0) > key) {
672 break;
Yangster-mac20877162017-12-22 17:19:39 -0800673 }
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700674 }
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700675
Yao Chen8a8d16c2018-02-08 14:50:40 -0800676 *err = BAD_INDEX;
677 return 0.0;
Yangster-macd40053e2018-01-09 16:29:22 -0800678}
679
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700680string LogEvent::ToString() const {
Yao Chen20e9e622018-02-28 11:18:51 -0800681 string result;
682 result += StringPrintf("{ %lld %lld (%d)", (long long)mLogdTimestampNs,
683 (long long)mElapsedTimestampNs, mTagId);
Yao Chen8a8d16c2018-02-08 14:50:40 -0800684 for (const auto& value : mValues) {
Yao Chen20e9e622018-02-28 11:18:51 -0800685 result +=
686 StringPrintf("%#x", value.mField.getField()) + "->" + value.mValue.toString() + " ";
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700687 }
Yao Chen20e9e622018-02-28 11:18:51 -0800688 result += " }";
689 return result;
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700690}
691
Yangster-mac20877162017-12-22 17:19:39 -0800692void LogEvent::ToProto(ProtoOutputStream& protoOutput) const {
Yao Chen8a8d16c2018-02-08 14:50:40 -0800693 writeFieldValueTreeToStream(mTagId, getValues(), &protoOutput);
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700694}
695
696} // namespace statsd
697} // namespace os
698} // namespace android