1 // Copyright (C) 2017 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "statsd_test_util.h"
16
17 #include <aggregator.pb.h>
18 #include <aidl/android/util/StatsEventParcel.h>
19 #include <android-base/properties.h>
20 #include <android-base/stringprintf.h>
21
22 #include "matchers/SimpleAtomMatchingTracker.h"
23 #include "metrics/parsing_utils/histogram_parsing_utils.h"
24 #include "stats_event.h"
25 #include "stats_util.h"
26
27 using aidl::android::util::StatsEventParcel;
28 using android::base::SetProperty;
29 using android::base::StringPrintf;
30 using std::shared_ptr;
31 using zetasketch::android::AggregatorStateProto;
32
33 namespace android {
34 namespace os {
35 namespace statsd {
36
sendConfig(const StatsdConfig & config)37 bool StatsServiceConfigTest::sendConfig(const StatsdConfig& config) {
38 string str;
39 config.SerializeToString(&str);
40 std::vector<uint8_t> configAsVec(str.begin(), str.end());
41 return service->addConfiguration(kConfigKey, configAsVec, kCallingUid).isOk();
42 }
43
getReports(sp<StatsLogProcessor> processor,int64_t timestamp,bool include_current)44 ConfigMetricsReport StatsServiceConfigTest::getReports(sp<StatsLogProcessor> processor,
45 int64_t timestamp, bool include_current) {
46 vector<uint8_t> output;
47 ConfigKey configKey(kCallingUid, kConfigKey);
48 processor->onDumpReport(configKey, timestamp, include_current /* include_current_bucket*/,
49 true /* erase_data */, ADB_DUMP, NO_TIME_CONSTRAINTS, &output);
50 ConfigMetricsReportList reports;
51 reports.ParseFromArray(output.data(), output.size());
52 EXPECT_EQ(1, reports.reports_size());
53 return reports.reports(0);
54 }
55
outputStreamToProto(ProtoOutputStream * proto)56 StatsLogReport outputStreamToProto(ProtoOutputStream* proto) {
57 vector<uint8_t> bytes;
58 bytes.resize(proto->size());
59 size_t pos = 0;
60 sp<ProtoReader> reader = proto->data();
61
62 while (reader->readBuffer() != NULL) {
63 size_t toRead = reader->currentToRead();
64 std::memcpy(&((bytes)[pos]), reader->readBuffer(), toRead);
65 pos += toRead;
66 reader->move(toRead);
67 }
68
69 StatsLogReport report;
70 report.ParseFromArray(bytes.data(), bytes.size());
71 return report;
72 }
73
CreateSimpleAtomMatcher(const string & name,int atomId)74 AtomMatcher CreateSimpleAtomMatcher(const string& name, int atomId) {
75 AtomMatcher atom_matcher;
76 atom_matcher.set_id(StringToId(name));
77 auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
78 simple_atom_matcher->set_atom_id(atomId);
79 return atom_matcher;
80 }
81
CreateTemperatureAtomMatcher()82 AtomMatcher CreateTemperatureAtomMatcher() {
83 return CreateSimpleAtomMatcher("TemperatureMatcher", util::TEMPERATURE);
84 }
85
CreateScheduledJobStateChangedAtomMatcher(const string & name,ScheduledJobStateChanged::State state)86 AtomMatcher CreateScheduledJobStateChangedAtomMatcher(const string& name,
87 ScheduledJobStateChanged::State state) {
88 AtomMatcher atom_matcher;
89 atom_matcher.set_id(StringToId(name));
90 auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
91 simple_atom_matcher->set_atom_id(util::SCHEDULED_JOB_STATE_CHANGED);
92 auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
93 field_value_matcher->set_field(3); // State field.
94 field_value_matcher->set_eq_int(state);
95 return atom_matcher;
96 }
97
CreateStartScheduledJobAtomMatcher()98 AtomMatcher CreateStartScheduledJobAtomMatcher() {
99 return CreateScheduledJobStateChangedAtomMatcher("ScheduledJobStart",
100 ScheduledJobStateChanged::STARTED);
101 }
102
CreateFinishScheduledJobAtomMatcher()103 AtomMatcher CreateFinishScheduledJobAtomMatcher() {
104 return CreateScheduledJobStateChangedAtomMatcher("ScheduledJobFinish",
105 ScheduledJobStateChanged::FINISHED);
106 }
107
CreateScheduleScheduledJobAtomMatcher()108 AtomMatcher CreateScheduleScheduledJobAtomMatcher() {
109 return CreateScheduledJobStateChangedAtomMatcher("ScheduledJobSchedule",
110 ScheduledJobStateChanged::SCHEDULED);
111 }
112
CreateScreenBrightnessChangedAtomMatcher()113 AtomMatcher CreateScreenBrightnessChangedAtomMatcher() {
114 AtomMatcher atom_matcher;
115 atom_matcher.set_id(StringToId("ScreenBrightnessChanged"));
116 auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
117 simple_atom_matcher->set_atom_id(util::SCREEN_BRIGHTNESS_CHANGED);
118 return atom_matcher;
119 }
120
CreateUidProcessStateChangedAtomMatcher()121 AtomMatcher CreateUidProcessStateChangedAtomMatcher() {
122 AtomMatcher atom_matcher;
123 atom_matcher.set_id(StringToId("UidProcessStateChanged"));
124 auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
125 simple_atom_matcher->set_atom_id(util::UID_PROCESS_STATE_CHANGED);
126 return atom_matcher;
127 }
128
CreateWakelockStateChangedAtomMatcher(const string & name,WakelockStateChanged::State state)129 AtomMatcher CreateWakelockStateChangedAtomMatcher(const string& name,
130 WakelockStateChanged::State state) {
131 AtomMatcher atom_matcher;
132 atom_matcher.set_id(StringToId(name));
133 auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
134 simple_atom_matcher->set_atom_id(util::WAKELOCK_STATE_CHANGED);
135 auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
136 field_value_matcher->set_field(4); // State field.
137 field_value_matcher->set_eq_int(state);
138 return atom_matcher;
139 }
140
CreateAcquireWakelockAtomMatcher()141 AtomMatcher CreateAcquireWakelockAtomMatcher() {
142 return CreateWakelockStateChangedAtomMatcher("AcquireWakelock", WakelockStateChanged::ACQUIRE);
143 }
144
CreateReleaseWakelockAtomMatcher()145 AtomMatcher CreateReleaseWakelockAtomMatcher() {
146 return CreateWakelockStateChangedAtomMatcher("ReleaseWakelock", WakelockStateChanged::RELEASE);
147 }
148
CreateBatterySaverModeStateChangedAtomMatcher(const string & name,BatterySaverModeStateChanged::State state)149 AtomMatcher CreateBatterySaverModeStateChangedAtomMatcher(
150 const string& name, BatterySaverModeStateChanged::State state) {
151 AtomMatcher atom_matcher;
152 atom_matcher.set_id(StringToId(name));
153 auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
154 simple_atom_matcher->set_atom_id(util::BATTERY_SAVER_MODE_STATE_CHANGED);
155 auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
156 field_value_matcher->set_field(1); // State field.
157 field_value_matcher->set_eq_int(state);
158 return atom_matcher;
159 }
160
CreateBatterySaverModeStartAtomMatcher()161 AtomMatcher CreateBatterySaverModeStartAtomMatcher() {
162 return CreateBatterySaverModeStateChangedAtomMatcher(
163 "BatterySaverModeStart", BatterySaverModeStateChanged::ON);
164 }
165
166
CreateBatterySaverModeStopAtomMatcher()167 AtomMatcher CreateBatterySaverModeStopAtomMatcher() {
168 return CreateBatterySaverModeStateChangedAtomMatcher(
169 "BatterySaverModeStop", BatterySaverModeStateChanged::OFF);
170 }
171
CreateBatteryStateChangedAtomMatcher(const string & name,BatteryPluggedStateEnum state)172 AtomMatcher CreateBatteryStateChangedAtomMatcher(const string& name,
173 BatteryPluggedStateEnum state) {
174 AtomMatcher atom_matcher;
175 atom_matcher.set_id(StringToId(name));
176 auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
177 simple_atom_matcher->set_atom_id(util::PLUGGED_STATE_CHANGED);
178 auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
179 field_value_matcher->set_field(1); // State field.
180 field_value_matcher->set_eq_int(state);
181 return atom_matcher;
182 }
183
CreateBatteryStateNoneMatcher()184 AtomMatcher CreateBatteryStateNoneMatcher() {
185 return CreateBatteryStateChangedAtomMatcher("BatteryPluggedNone",
186 BatteryPluggedStateEnum::BATTERY_PLUGGED_NONE);
187 }
188
CreateBatteryStateUsbMatcher()189 AtomMatcher CreateBatteryStateUsbMatcher() {
190 return CreateBatteryStateChangedAtomMatcher("BatteryPluggedUsb",
191 BatteryPluggedStateEnum::BATTERY_PLUGGED_USB);
192 }
193
CreateScreenStateChangedAtomMatcher(const string & name,android::view::DisplayStateEnum state)194 AtomMatcher CreateScreenStateChangedAtomMatcher(
195 const string& name, android::view::DisplayStateEnum state) {
196 AtomMatcher atom_matcher;
197 atom_matcher.set_id(StringToId(name));
198 auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
199 simple_atom_matcher->set_atom_id(util::SCREEN_STATE_CHANGED);
200 auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
201 field_value_matcher->set_field(1); // State field.
202 field_value_matcher->set_eq_int(state);
203 return atom_matcher;
204 }
205
CreateScreenTurnedOnAtomMatcher()206 AtomMatcher CreateScreenTurnedOnAtomMatcher() {
207 return CreateScreenStateChangedAtomMatcher("ScreenTurnedOn",
208 android::view::DisplayStateEnum::DISPLAY_STATE_ON);
209 }
210
CreateScreenTurnedOffAtomMatcher()211 AtomMatcher CreateScreenTurnedOffAtomMatcher() {
212 return CreateScreenStateChangedAtomMatcher("ScreenTurnedOff",
213 ::android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
214 }
215
CreateSyncStateChangedAtomMatcher(const string & name,SyncStateChanged::State state)216 AtomMatcher CreateSyncStateChangedAtomMatcher(
217 const string& name, SyncStateChanged::State state) {
218 AtomMatcher atom_matcher;
219 atom_matcher.set_id(StringToId(name));
220 auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
221 simple_atom_matcher->set_atom_id(util::SYNC_STATE_CHANGED);
222 auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
223 field_value_matcher->set_field(3); // State field.
224 field_value_matcher->set_eq_int(state);
225 return atom_matcher;
226 }
227
CreateSyncStartAtomMatcher()228 AtomMatcher CreateSyncStartAtomMatcher() {
229 return CreateSyncStateChangedAtomMatcher("SyncStart", SyncStateChanged::ON);
230 }
231
CreateSyncEndAtomMatcher()232 AtomMatcher CreateSyncEndAtomMatcher() {
233 return CreateSyncStateChangedAtomMatcher("SyncEnd", SyncStateChanged::OFF);
234 }
235
CreateActivityForegroundStateChangedAtomMatcher(const string & name,ActivityForegroundStateChanged::State state)236 AtomMatcher CreateActivityForegroundStateChangedAtomMatcher(
237 const string& name, ActivityForegroundStateChanged::State state) {
238 AtomMatcher atom_matcher;
239 atom_matcher.set_id(StringToId(name));
240 auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
241 simple_atom_matcher->set_atom_id(util::ACTIVITY_FOREGROUND_STATE_CHANGED);
242 auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
243 field_value_matcher->set_field(4); // Activity field.
244 field_value_matcher->set_eq_int(state);
245 return atom_matcher;
246 }
247
CreateMoveToBackgroundAtomMatcher()248 AtomMatcher CreateMoveToBackgroundAtomMatcher() {
249 return CreateActivityForegroundStateChangedAtomMatcher(
250 "Background", ActivityForegroundStateChanged::BACKGROUND);
251 }
252
CreateMoveToForegroundAtomMatcher()253 AtomMatcher CreateMoveToForegroundAtomMatcher() {
254 return CreateActivityForegroundStateChangedAtomMatcher(
255 "Foreground", ActivityForegroundStateChanged::FOREGROUND);
256 }
257
CreateProcessLifeCycleStateChangedAtomMatcher(const string & name,ProcessLifeCycleStateChanged::State state)258 AtomMatcher CreateProcessLifeCycleStateChangedAtomMatcher(
259 const string& name, ProcessLifeCycleStateChanged::State state) {
260 AtomMatcher atom_matcher;
261 atom_matcher.set_id(StringToId(name));
262 auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
263 simple_atom_matcher->set_atom_id(util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
264 auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
265 field_value_matcher->set_field(3); // Process state field.
266 field_value_matcher->set_eq_int(state);
267 return atom_matcher;
268 }
269
CreateProcessCrashAtomMatcher()270 AtomMatcher CreateProcessCrashAtomMatcher() {
271 return CreateProcessLifeCycleStateChangedAtomMatcher(
272 "Crashed", ProcessLifeCycleStateChanged::CRASHED);
273 }
274
CreateAppStartOccurredAtomMatcher()275 AtomMatcher CreateAppStartOccurredAtomMatcher() {
276 return CreateSimpleAtomMatcher("AppStartOccurredMatcher", util::APP_START_OCCURRED);
277 }
278
CreateTestAtomRepeatedStateAtomMatcher(const string & name,TestAtomReported::State state,Position position)279 AtomMatcher CreateTestAtomRepeatedStateAtomMatcher(const string& name,
280 TestAtomReported::State state,
281 Position position) {
282 AtomMatcher atom_matcher = CreateSimpleAtomMatcher(name, util::TEST_ATOM_REPORTED);
283 auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
284 auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
285 field_value_matcher->set_field(14); // Repeated enum field.
286 field_value_matcher->set_eq_int(state);
287 field_value_matcher->set_position(position);
288 return atom_matcher;
289 }
290
CreateTestAtomRepeatedStateFirstOffAtomMatcher()291 AtomMatcher CreateTestAtomRepeatedStateFirstOffAtomMatcher() {
292 return CreateTestAtomRepeatedStateAtomMatcher("TestFirstStateOff", TestAtomReported::OFF,
293 Position::FIRST);
294 }
295
CreateTestAtomRepeatedStateFirstOnAtomMatcher()296 AtomMatcher CreateTestAtomRepeatedStateFirstOnAtomMatcher() {
297 return CreateTestAtomRepeatedStateAtomMatcher("TestFirstStateOn", TestAtomReported::ON,
298 Position::FIRST);
299 }
300
CreateTestAtomRepeatedStateAnyOnAtomMatcher()301 AtomMatcher CreateTestAtomRepeatedStateAnyOnAtomMatcher() {
302 return CreateTestAtomRepeatedStateAtomMatcher("TestAnyStateOn", TestAtomReported::ON,
303 Position::ANY);
304 }
305
addMatcherToMatcherCombination(const AtomMatcher & matcher,AtomMatcher * combinationMatcher)306 void addMatcherToMatcherCombination(const AtomMatcher& matcher, AtomMatcher* combinationMatcher) {
307 combinationMatcher->mutable_combination()->add_matcher(matcher.id());
308 }
309
CreateScheduledJobPredicate()310 Predicate CreateScheduledJobPredicate() {
311 Predicate predicate;
312 predicate.set_id(StringToId("ScheduledJobRunningPredicate"));
313 predicate.mutable_simple_predicate()->set_start(StringToId("ScheduledJobStart"));
314 predicate.mutable_simple_predicate()->set_stop(StringToId("ScheduledJobFinish"));
315 return predicate;
316 }
317
CreateBatterySaverModePredicate()318 Predicate CreateBatterySaverModePredicate() {
319 Predicate predicate;
320 predicate.set_id(StringToId("BatterySaverIsOn"));
321 predicate.mutable_simple_predicate()->set_start(StringToId("BatterySaverModeStart"));
322 predicate.mutable_simple_predicate()->set_stop(StringToId("BatterySaverModeStop"));
323 return predicate;
324 }
325
CreateDeviceUnpluggedPredicate()326 Predicate CreateDeviceUnpluggedPredicate() {
327 Predicate predicate;
328 predicate.set_id(StringToId("DeviceUnplugged"));
329 predicate.mutable_simple_predicate()->set_start(StringToId("BatteryPluggedNone"));
330 predicate.mutable_simple_predicate()->set_stop(StringToId("BatteryPluggedUsb"));
331 return predicate;
332 }
333
CreateScreenIsOnPredicate()334 Predicate CreateScreenIsOnPredicate() {
335 Predicate predicate;
336 predicate.set_id(StringToId("ScreenIsOn"));
337 predicate.mutable_simple_predicate()->set_start(StringToId("ScreenTurnedOn"));
338 predicate.mutable_simple_predicate()->set_stop(StringToId("ScreenTurnedOff"));
339 return predicate;
340 }
341
CreateScreenIsOffPredicate()342 Predicate CreateScreenIsOffPredicate() {
343 Predicate predicate;
344 predicate.set_id(StringToId("ScreenIsOff"));
345 predicate.mutable_simple_predicate()->set_start(StringToId("ScreenTurnedOff"));
346 predicate.mutable_simple_predicate()->set_stop(StringToId("ScreenTurnedOn"));
347 return predicate;
348 }
349
CreateHoldingWakelockPredicate()350 Predicate CreateHoldingWakelockPredicate() {
351 Predicate predicate;
352 predicate.set_id(StringToId("HoldingWakelock"));
353 predicate.mutable_simple_predicate()->set_start(StringToId("AcquireWakelock"));
354 predicate.mutable_simple_predicate()->set_stop(StringToId("ReleaseWakelock"));
355 return predicate;
356 }
357
CreateIsSyncingPredicate()358 Predicate CreateIsSyncingPredicate() {
359 Predicate predicate;
360 predicate.set_id(StringToId("IsSyncing"));
361 predicate.mutable_simple_predicate()->set_start(StringToId("SyncStart"));
362 predicate.mutable_simple_predicate()->set_stop(StringToId("SyncEnd"));
363 return predicate;
364 }
365
CreateIsInBackgroundPredicate()366 Predicate CreateIsInBackgroundPredicate() {
367 Predicate predicate;
368 predicate.set_id(StringToId("IsInBackground"));
369 predicate.mutable_simple_predicate()->set_start(StringToId("Background"));
370 predicate.mutable_simple_predicate()->set_stop(StringToId("Foreground"));
371 return predicate;
372 }
373
CreateTestAtomRepeatedStateFirstOffPredicate()374 Predicate CreateTestAtomRepeatedStateFirstOffPredicate() {
375 Predicate predicate;
376 predicate.set_id(StringToId("TestFirstStateIsOff"));
377 predicate.mutable_simple_predicate()->set_start(StringToId("TestFirstStateOff"));
378 predicate.mutable_simple_predicate()->set_stop(StringToId("TestFirstStateOn"));
379 return predicate;
380 }
381
CreateScreenState()382 State CreateScreenState() {
383 State state;
384 state.set_id(StringToId("ScreenState"));
385 state.set_atom_id(util::SCREEN_STATE_CHANGED);
386 return state;
387 }
388
CreateUidProcessState()389 State CreateUidProcessState() {
390 State state;
391 state.set_id(StringToId("UidProcessState"));
392 state.set_atom_id(util::UID_PROCESS_STATE_CHANGED);
393 return state;
394 }
395
CreateOverlayState()396 State CreateOverlayState() {
397 State state;
398 state.set_id(StringToId("OverlayState"));
399 state.set_atom_id(util::OVERLAY_STATE_CHANGED);
400 return state;
401 }
402
CreateScreenStateWithOnOffMap(int64_t screenOnId,int64_t screenOffId)403 State CreateScreenStateWithOnOffMap(int64_t screenOnId, int64_t screenOffId) {
404 State state;
405 state.set_id(StringToId("ScreenStateOnOff"));
406 state.set_atom_id(util::SCREEN_STATE_CHANGED);
407
408 auto map = CreateScreenStateOnOffMap(screenOnId, screenOffId);
409 *state.mutable_map() = map;
410
411 return state;
412 }
413
CreateScreenStateWithSimpleOnOffMap(int64_t screenOnId,int64_t screenOffId)414 State CreateScreenStateWithSimpleOnOffMap(int64_t screenOnId, int64_t screenOffId) {
415 State state;
416 state.set_id(StringToId("ScreenStateSimpleOnOff"));
417 state.set_atom_id(util::SCREEN_STATE_CHANGED);
418
419 auto map = CreateScreenStateSimpleOnOffMap(screenOnId, screenOffId);
420 *state.mutable_map() = map;
421
422 return state;
423 }
424
CreateScreenStateOnGroup(int64_t screenOnId)425 StateMap_StateGroup CreateScreenStateOnGroup(int64_t screenOnId) {
426 StateMap_StateGroup group;
427 group.set_group_id(screenOnId);
428 group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_ON);
429 group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_VR);
430 group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_ON_SUSPEND);
431 return group;
432 }
433
CreateScreenStateOffGroup(int64_t screenOffId)434 StateMap_StateGroup CreateScreenStateOffGroup(int64_t screenOffId) {
435 StateMap_StateGroup group;
436 group.set_group_id(screenOffId);
437 group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
438 group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_DOZE);
439 group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_DOZE_SUSPEND);
440 return group;
441 }
442
CreateScreenStateSimpleOnGroup(int64_t screenOnId)443 StateMap_StateGroup CreateScreenStateSimpleOnGroup(int64_t screenOnId) {
444 StateMap_StateGroup group;
445 group.set_group_id(screenOnId);
446 group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_ON);
447 return group;
448 }
449
CreateScreenStateSimpleOffGroup(int64_t screenOffId)450 StateMap_StateGroup CreateScreenStateSimpleOffGroup(int64_t screenOffId) {
451 StateMap_StateGroup group;
452 group.set_group_id(screenOffId);
453 group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
454 return group;
455 }
456
CreateScreenStateOnOffMap(int64_t screenOnId,int64_t screenOffId)457 StateMap CreateScreenStateOnOffMap(int64_t screenOnId, int64_t screenOffId) {
458 StateMap map;
459 *map.add_group() = CreateScreenStateOnGroup(screenOnId);
460 *map.add_group() = CreateScreenStateOffGroup(screenOffId);
461 return map;
462 }
463
CreateScreenStateSimpleOnOffMap(int64_t screenOnId,int64_t screenOffId)464 StateMap CreateScreenStateSimpleOnOffMap(int64_t screenOnId, int64_t screenOffId) {
465 StateMap map;
466 *map.add_group() = CreateScreenStateSimpleOnGroup(screenOnId);
467 *map.add_group() = CreateScreenStateSimpleOffGroup(screenOffId);
468 return map;
469 }
470
addPredicateToPredicateCombination(const Predicate & predicate,Predicate * combinationPredicate)471 void addPredicateToPredicateCombination(const Predicate& predicate,
472 Predicate* combinationPredicate) {
473 combinationPredicate->mutable_combination()->add_predicate(predicate.id());
474 }
475
CreateAttributionUidDimensions(const int atomId,const std::vector<Position> & positions)476 FieldMatcher CreateAttributionUidDimensions(const int atomId,
477 const std::vector<Position>& positions) {
478 FieldMatcher dimensions;
479 dimensions.set_field(atomId);
480 for (const auto position : positions) {
481 auto child = dimensions.add_child();
482 child->set_field(1);
483 child->set_position(position);
484 child->add_child()->set_field(1);
485 }
486 return dimensions;
487 }
488
CreateAttributionUidAndTagDimensions(const int atomId,const std::vector<Position> & positions)489 FieldMatcher CreateAttributionUidAndTagDimensions(const int atomId,
490 const std::vector<Position>& positions) {
491 FieldMatcher dimensions;
492 dimensions.set_field(atomId);
493 for (const auto position : positions) {
494 auto child = dimensions.add_child();
495 child->set_field(1);
496 child->set_position(position);
497 child->add_child()->set_field(1);
498 child->add_child()->set_field(2);
499 }
500 return dimensions;
501 }
502
CreateDimensions(const int atomId,const std::vector<int> & fields)503 FieldMatcher CreateDimensions(const int atomId, const std::vector<int>& fields) {
504 FieldMatcher dimensions;
505 dimensions.set_field(atomId);
506 for (const int field : fields) {
507 dimensions.add_child()->set_field(field);
508 }
509 return dimensions;
510 }
511
CreateRepeatedDimensions(const int atomId,const std::vector<int> & fields,const std::vector<Position> & positions)512 FieldMatcher CreateRepeatedDimensions(const int atomId, const std::vector<int>& fields,
513 const std::vector<Position>& positions) {
514 FieldMatcher dimensions;
515 if (fields.size() != positions.size()) {
516 return dimensions;
517 }
518
519 dimensions.set_field(atomId);
520 for (size_t i = 0; i < fields.size(); i++) {
521 auto child = dimensions.add_child();
522 child->set_field(fields[i]);
523 child->set_position(positions[i]);
524 }
525 return dimensions;
526 }
527
CreateAttributionUidAndOtherDimensions(const int atomId,const std::vector<Position> & positions,const std::vector<int> & fields)528 FieldMatcher CreateAttributionUidAndOtherDimensions(const int atomId,
529 const std::vector<Position>& positions,
530 const std::vector<int>& fields) {
531 FieldMatcher dimensions = CreateAttributionUidDimensions(atomId, positions);
532
533 for (const int field : fields) {
534 dimensions.add_child()->set_field(field);
535 }
536 return dimensions;
537 }
538
createEventMetric(const string & name,const int64_t what,const optional<int64_t> & condition)539 EventMetric createEventMetric(const string& name, const int64_t what,
540 const optional<int64_t>& condition) {
541 EventMetric metric;
542 metric.set_id(StringToId(name));
543 metric.set_what(what);
544 if (condition) {
545 metric.set_condition(condition.value());
546 }
547 return metric;
548 }
549
createCountMetric(const string & name,const int64_t what,const optional<int64_t> & condition,const vector<int64_t> & states)550 CountMetric createCountMetric(const string& name, const int64_t what,
551 const optional<int64_t>& condition, const vector<int64_t>& states) {
552 CountMetric metric;
553 metric.set_id(StringToId(name));
554 metric.set_what(what);
555 metric.set_bucket(TEN_MINUTES);
556 if (condition) {
557 metric.set_condition(condition.value());
558 }
559 for (const int64_t state : states) {
560 metric.add_slice_by_state(state);
561 }
562 return metric;
563 }
564
createDurationMetric(const string & name,const int64_t what,const optional<int64_t> & condition,const vector<int64_t> & states)565 DurationMetric createDurationMetric(const string& name, const int64_t what,
566 const optional<int64_t>& condition,
567 const vector<int64_t>& states) {
568 DurationMetric metric;
569 metric.set_id(StringToId(name));
570 metric.set_what(what);
571 metric.set_bucket(TEN_MINUTES);
572 if (condition) {
573 metric.set_condition(condition.value());
574 }
575 for (const int64_t state : states) {
576 metric.add_slice_by_state(state);
577 }
578 return metric;
579 }
580
createGaugeMetric(const string & name,const int64_t what,const GaugeMetric::SamplingType samplingType,const optional<int64_t> & condition,const optional<int64_t> & triggerEvent)581 GaugeMetric createGaugeMetric(const string& name, const int64_t what,
582 const GaugeMetric::SamplingType samplingType,
583 const optional<int64_t>& condition,
584 const optional<int64_t>& triggerEvent) {
585 GaugeMetric metric;
586 metric.set_id(StringToId(name));
587 metric.set_what(what);
588 metric.set_bucket(TEN_MINUTES);
589 metric.set_sampling_type(samplingType);
590 if (condition) {
591 metric.set_condition(condition.value());
592 }
593 if (triggerEvent) {
594 metric.set_trigger_event(triggerEvent.value());
595 }
596 metric.mutable_gauge_fields_filter()->set_include_all(true);
597 return metric;
598 }
599
createValueMetric(const string & name,const AtomMatcher & what,const int valueField,const optional<int64_t> & condition,const vector<int64_t> & states)600 ValueMetric createValueMetric(const string& name, const AtomMatcher& what, const int valueField,
601 const optional<int64_t>& condition, const vector<int64_t>& states) {
602 return createValueMetric(name, what, {valueField}, /* aggregationTypes */ {}, condition,
603 states);
604 }
605
createValueMetric(const string & name,const AtomMatcher & what,const vector<int> & valueFields,const vector<ValueMetric::AggregationType> & aggregationTypes,const optional<int64_t> & condition,const vector<int64_t> & states)606 ValueMetric createValueMetric(const string& name, const AtomMatcher& what,
607 const vector<int>& valueFields,
608 const vector<ValueMetric::AggregationType>& aggregationTypes,
609 const optional<int64_t>& condition, const vector<int64_t>& states) {
610 ValueMetric metric;
611 metric.set_id(StringToId(name));
612 metric.set_what(what.id());
613 metric.set_bucket(TEN_MINUTES);
614 metric.mutable_value_field()->set_field(what.simple_atom_matcher().atom_id());
615 for (int valueField : valueFields) {
616 metric.mutable_value_field()->add_child()->set_field(valueField);
617 }
618 for (const ValueMetric::AggregationType aggType : aggregationTypes) {
619 metric.add_aggregation_types(aggType);
620 }
621 if (condition) {
622 metric.set_condition(condition.value());
623 }
624 for (const int64_t state : states) {
625 metric.add_slice_by_state(state);
626 }
627 return metric;
628 }
629
createGeneratedBinConfig(int id,float min,float max,int count,HistogramBinConfig::GeneratedBins::Strategy strategy)630 HistogramBinConfig createGeneratedBinConfig(int id, float min, float max, int count,
631 HistogramBinConfig::GeneratedBins::Strategy strategy) {
632 HistogramBinConfig binConfig;
633 binConfig.set_id(id);
634 binConfig.mutable_generated_bins()->set_min(min);
635 binConfig.mutable_generated_bins()->set_max(max);
636 binConfig.mutable_generated_bins()->set_count(count);
637 binConfig.mutable_generated_bins()->set_strategy(strategy);
638 return binConfig;
639 }
640
createExplicitBinConfig(int id,const vector<float> & bins)641 HistogramBinConfig createExplicitBinConfig(int id, const vector<float>& bins) {
642 HistogramBinConfig binConfig;
643 binConfig.set_id(id);
644 *binConfig.mutable_explicit_bins()->mutable_bin() = {bins.begin(), bins.end()};
645 return binConfig;
646 }
647
createKllMetric(const string & name,const AtomMatcher & what,const int kllField,const optional<int64_t> & condition)648 KllMetric createKllMetric(const string& name, const AtomMatcher& what, const int kllField,
649 const optional<int64_t>& condition) {
650 KllMetric metric;
651 metric.set_id(StringToId(name));
652 metric.set_what(what.id());
653 metric.set_bucket(TEN_MINUTES);
654 metric.mutable_kll_field()->set_field(what.simple_atom_matcher().atom_id());
655 metric.mutable_kll_field()->add_child()->set_field(kllField);
656 if (condition) {
657 metric.set_condition(condition.value());
658 }
659 return metric;
660 }
661
createAlert(const string & name,const int64_t metricId,const int buckets,const int64_t triggerSum)662 Alert createAlert(const string& name, const int64_t metricId, const int buckets,
663 const int64_t triggerSum) {
664 Alert alert;
665 alert.set_id(StringToId(name));
666 alert.set_metric_id(metricId);
667 alert.set_num_buckets(buckets);
668 alert.set_trigger_if_sum_gt(triggerSum);
669 return alert;
670 }
671
createAlarm(const string & name,const int64_t offsetMillis,const int64_t periodMillis)672 Alarm createAlarm(const string& name, const int64_t offsetMillis, const int64_t periodMillis) {
673 Alarm alarm;
674 alarm.set_id(StringToId(name));
675 alarm.set_offset_millis(offsetMillis);
676 alarm.set_period_millis(periodMillis);
677 return alarm;
678 }
679
createSubscription(const string & name,const Subscription_RuleType type,const int64_t ruleId)680 Subscription createSubscription(const string& name, const Subscription_RuleType type,
681 const int64_t ruleId) {
682 Subscription subscription;
683 subscription.set_id(StringToId(name));
684 subscription.set_rule_type(type);
685 subscription.set_rule_id(ruleId);
686 subscription.mutable_broadcast_subscriber_details();
687 return subscription;
688 }
689
690 // START: get primary key functions
getUidProcessKey(int uid,HashableDimensionKey * key)691 void getUidProcessKey(int uid, HashableDimensionKey* key) {
692 int pos1[] = {1, 0, 0};
693 Field field1(27 /* atom id */, pos1, 0 /* depth */);
694 Value value1((int32_t)uid);
695
696 key->addValue(FieldValue(field1, value1));
697 }
698
getOverlayKey(int uid,string packageName,HashableDimensionKey * key)699 void getOverlayKey(int uid, string packageName, HashableDimensionKey* key) {
700 int pos1[] = {1, 0, 0};
701 int pos2[] = {2, 0, 0};
702
703 Field field1(59 /* atom id */, pos1, 0 /* depth */);
704 Field field2(59 /* atom id */, pos2, 0 /* depth */);
705
706 Value value1((int32_t)uid);
707 Value value2(packageName);
708
709 key->addValue(FieldValue(field1, value1));
710 key->addValue(FieldValue(field2, value2));
711 }
712
getPartialWakelockKey(int uid,const std::string & tag,HashableDimensionKey * key)713 void getPartialWakelockKey(int uid, const std::string& tag, HashableDimensionKey* key) {
714 int pos1[] = {1, 1, 1};
715 int pos3[] = {2, 0, 0};
716 int pos4[] = {3, 0, 0};
717
718 Field field1(10 /* atom id */, pos1, 2 /* depth */);
719
720 Field field3(10 /* atom id */, pos3, 0 /* depth */);
721 Field field4(10 /* atom id */, pos4, 0 /* depth */);
722
723 Value value1((int32_t)uid);
724 Value value3((int32_t)1 /*partial*/);
725 Value value4(tag);
726
727 key->addValue(FieldValue(field1, value1));
728 key->addValue(FieldValue(field3, value3));
729 key->addValue(FieldValue(field4, value4));
730 }
731
getPartialWakelockKey(int uid,HashableDimensionKey * key)732 void getPartialWakelockKey(int uid, HashableDimensionKey* key) {
733 int pos1[] = {1, 1, 1};
734 int pos3[] = {2, 0, 0};
735
736 Field field1(10 /* atom id */, pos1, 2 /* depth */);
737 Field field3(10 /* atom id */, pos3, 0 /* depth */);
738
739 Value value1((int32_t)uid);
740 Value value3((int32_t)1 /*partial*/);
741
742 key->addValue(FieldValue(field1, value1));
743 key->addValue(FieldValue(field3, value3));
744 }
745 // END: get primary key functions
746
writeAttribution(AStatsEvent * statsEvent,const vector<int> & attributionUids,const vector<string> & attributionTags)747 void writeAttribution(AStatsEvent* statsEvent, const vector<int>& attributionUids,
748 const vector<string>& attributionTags) {
749 vector<const char*> cTags(attributionTags.size());
750 for (int i = 0; i < cTags.size(); i++) {
751 cTags[i] = attributionTags[i].c_str();
752 }
753
754 AStatsEvent_writeAttributionChain(statsEvent,
755 reinterpret_cast<const uint32_t*>(attributionUids.data()),
756 cTags.data(), attributionUids.size());
757 }
758
parseStatsEventToLogEvent(AStatsEvent * statsEvent,LogEvent * logEvent)759 bool parseStatsEventToLogEvent(AStatsEvent* statsEvent, LogEvent* logEvent) {
760 AStatsEvent_build(statsEvent);
761
762 size_t size;
763 uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
764 const bool result = logEvent->parseBuffer(buf, size);
765
766 AStatsEvent_release(statsEvent);
767
768 return result;
769 }
770
makeTwoValueStatsEvent(int atomId,int64_t eventTimeNs,int32_t value1,int32_t value2)771 AStatsEvent* makeTwoValueStatsEvent(int atomId, int64_t eventTimeNs, int32_t value1,
772 int32_t value2) {
773 AStatsEvent* statsEvent = AStatsEvent_obtain();
774 AStatsEvent_setAtomId(statsEvent, atomId);
775 AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
776
777 AStatsEvent_writeInt32(statsEvent, value1);
778 AStatsEvent_writeInt32(statsEvent, value2);
779
780 return statsEvent;
781 }
782
CreateTwoValueLogEvent(LogEvent * logEvent,int atomId,int64_t eventTimeNs,int32_t value1,int32_t value2)783 void CreateTwoValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs, int32_t value1,
784 int32_t value2) {
785 AStatsEvent* statsEvent = makeTwoValueStatsEvent(atomId, eventTimeNs, value1, value2);
786 parseStatsEventToLogEvent(statsEvent, logEvent);
787 }
788
CreateTwoValueLogEvent(int atomId,int64_t eventTimeNs,int32_t value1,int32_t value2)789 shared_ptr<LogEvent> CreateTwoValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1,
790 int32_t value2) {
791 shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
792 CreateTwoValueLogEvent(logEvent.get(), atomId, eventTimeNs, value1, value2);
793 return logEvent;
794 }
795
CreateThreeValueLogEvent(LogEvent * logEvent,int atomId,int64_t eventTimeNs,int32_t value1,int32_t value2,int32_t value3)796 void CreateThreeValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs, int32_t value1,
797 int32_t value2, int32_t value3) {
798 AStatsEvent* statsEvent = AStatsEvent_obtain();
799 AStatsEvent_setAtomId(statsEvent, atomId);
800 AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
801
802 AStatsEvent_writeInt32(statsEvent, value1);
803 AStatsEvent_writeInt32(statsEvent, value2);
804 AStatsEvent_writeInt32(statsEvent, value3);
805
806 parseStatsEventToLogEvent(statsEvent, logEvent);
807 }
808
CreateThreeValueLogEvent(int atomId,int64_t eventTimeNs,int32_t value1,int32_t value2,int32_t value3)809 shared_ptr<LogEvent> CreateThreeValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1,
810 int32_t value2, int32_t value3) {
811 shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
812 CreateThreeValueLogEvent(logEvent.get(), atomId, eventTimeNs, value1, value2, value3);
813 return logEvent;
814 }
815
CreateRepeatedValueLogEvent(LogEvent * logEvent,int atomId,int64_t eventTimeNs,int32_t value)816 void CreateRepeatedValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs,
817 int32_t value) {
818 AStatsEvent* statsEvent = AStatsEvent_obtain();
819 AStatsEvent_setAtomId(statsEvent, atomId);
820 AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
821
822 AStatsEvent_writeInt32(statsEvent, value);
823 AStatsEvent_writeInt32(statsEvent, value);
824
825 parseStatsEventToLogEvent(statsEvent, logEvent);
826 }
827
CreateRepeatedValueLogEvent(int atomId,int64_t eventTimeNs,int32_t value)828 shared_ptr<LogEvent> CreateRepeatedValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value) {
829 shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
830 CreateRepeatedValueLogEvent(logEvent.get(), atomId, eventTimeNs, value);
831 return logEvent;
832 }
833
CreateNoValuesLogEvent(LogEvent * logEvent,int atomId,int64_t eventTimeNs)834 void CreateNoValuesLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs) {
835 AStatsEvent* statsEvent = AStatsEvent_obtain();
836 AStatsEvent_setAtomId(statsEvent, atomId);
837 AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
838
839 parseStatsEventToLogEvent(statsEvent, logEvent);
840 }
841
CreateNoValuesLogEvent(int atomId,int64_t eventTimeNs)842 shared_ptr<LogEvent> CreateNoValuesLogEvent(int atomId, int64_t eventTimeNs) {
843 shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
844 CreateNoValuesLogEvent(logEvent.get(), atomId, eventTimeNs);
845 return logEvent;
846 }
847
makeUidStatsEvent(int atomId,int64_t eventTimeNs,int uid,int data1,int data2)848 AStatsEvent* makeUidStatsEvent(int atomId, int64_t eventTimeNs, int uid, int data1, int data2) {
849 AStatsEvent* statsEvent = AStatsEvent_obtain();
850 AStatsEvent_setAtomId(statsEvent, atomId);
851 AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
852
853 AStatsEvent_writeInt32(statsEvent, uid);
854 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
855 AStatsEvent_writeInt32(statsEvent, data1);
856 AStatsEvent_writeInt32(statsEvent, data2);
857
858 return statsEvent;
859 }
860
makeUidStatsEvent(int atomId,int64_t eventTimeNs,int uid,int data1,const vector<int> & data2)861 AStatsEvent* makeUidStatsEvent(int atomId, int64_t eventTimeNs, int uid, int data1,
862 const vector<int>& data2) {
863 AStatsEvent* statsEvent = AStatsEvent_obtain();
864 AStatsEvent_setAtomId(statsEvent, atomId);
865 AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
866 AStatsEvent_writeInt32(statsEvent, uid);
867 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
868 AStatsEvent_writeInt32(statsEvent, data1);
869 AStatsEvent_writeInt32Array(statsEvent, data2.data(), data2.size());
870
871 return statsEvent;
872 }
873
makeAttributionStatsEvent(int atomId,int64_t eventTimeNs,const vector<int> & uids,const vector<string> & tags,int data1,int data2)874 AStatsEvent* makeAttributionStatsEvent(int atomId, int64_t eventTimeNs, const vector<int>& uids,
875 const vector<string>& tags, int data1, int data2) {
876 AStatsEvent* statsEvent = AStatsEvent_obtain();
877 AStatsEvent_setAtomId(statsEvent, atomId);
878 AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
879
880 writeAttribution(statsEvent, uids, tags);
881 AStatsEvent_writeInt32(statsEvent, data1);
882 AStatsEvent_writeInt32(statsEvent, data2);
883
884 return statsEvent;
885 }
886
makeUidLogEvent(int atomId,int64_t eventTimeNs,int uid,int data1,int data2)887 shared_ptr<LogEvent> makeUidLogEvent(int atomId, int64_t eventTimeNs, int uid, int data1,
888 int data2) {
889 AStatsEvent* statsEvent = makeUidStatsEvent(atomId, eventTimeNs, uid, data1, data2);
890
891 shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
892 parseStatsEventToLogEvent(statsEvent, logEvent.get());
893 return logEvent;
894 }
895
makeUidLogEvent(int atomId,int64_t eventTimeNs,int uid,int data1,const vector<int> & data2)896 shared_ptr<LogEvent> makeUidLogEvent(int atomId, int64_t eventTimeNs, int uid, int data1,
897 const vector<int>& data2) {
898 AStatsEvent* statsEvent = makeUidStatsEvent(atomId, eventTimeNs, uid, data1, data2);
899
900 shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
901 parseStatsEventToLogEvent(statsEvent, logEvent.get());
902 return logEvent;
903 }
904
makeExtraUidsLogEvent(int atomId,int64_t eventTimeNs,int uid1,int data1,int data2,const vector<int> & extraUids)905 shared_ptr<LogEvent> makeExtraUidsLogEvent(int atomId, int64_t eventTimeNs, int uid1, int data1,
906 int data2, const vector<int>& extraUids) {
907 AStatsEvent* statsEvent = makeUidStatsEvent(atomId, eventTimeNs, uid1, data1, data2);
908 for (const int extraUid : extraUids) {
909 AStatsEvent_writeInt32(statsEvent, extraUid);
910 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
911 }
912
913 shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
914 parseStatsEventToLogEvent(statsEvent, logEvent.get());
915 return logEvent;
916 }
917
makeRepeatedUidLogEvent(int atomId,int64_t eventTimeNs,const vector<int> & uids)918 shared_ptr<LogEvent> makeRepeatedUidLogEvent(int atomId, int64_t eventTimeNs,
919 const vector<int>& uids) {
920 AStatsEvent* statsEvent = AStatsEvent_obtain();
921 AStatsEvent_setAtomId(statsEvent, atomId);
922 AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
923 AStatsEvent_writeInt32Array(statsEvent, uids.data(), uids.size());
924 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
925
926 shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
927 parseStatsEventToLogEvent(statsEvent, logEvent.get());
928
929 return logEvent;
930 }
931
makeRepeatedUidLogEvent(int atomId,int64_t eventTimeNs,const vector<int> & uids,int data1,int data2)932 shared_ptr<LogEvent> makeRepeatedUidLogEvent(int atomId, int64_t eventTimeNs,
933 const vector<int>& uids, int data1, int data2) {
934 AStatsEvent* statsEvent = AStatsEvent_obtain();
935 AStatsEvent_setAtomId(statsEvent, atomId);
936 AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
937 AStatsEvent_writeInt32Array(statsEvent, uids.data(), uids.size());
938 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
939 AStatsEvent_writeInt32(statsEvent, data1);
940 AStatsEvent_writeInt32(statsEvent, data2);
941
942 shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
943 parseStatsEventToLogEvent(statsEvent, logEvent.get());
944
945 return logEvent;
946 }
947
makeRepeatedUidLogEvent(int atomId,int64_t eventTimeNs,const vector<int> & uids,int data1,const vector<int> & data2)948 shared_ptr<LogEvent> makeRepeatedUidLogEvent(int atomId, int64_t eventTimeNs,
949 const vector<int>& uids, int data1,
950 const vector<int>& data2) {
951 AStatsEvent* statsEvent = AStatsEvent_obtain();
952 AStatsEvent_setAtomId(statsEvent, atomId);
953 AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
954 AStatsEvent_writeInt32Array(statsEvent, uids.data(), uids.size());
955 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
956 AStatsEvent_writeInt32(statsEvent, data1);
957 AStatsEvent_writeInt32Array(statsEvent, data2.data(), data2.size());
958
959 shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
960 parseStatsEventToLogEvent(statsEvent, logEvent.get());
961
962 return logEvent;
963 }
964
makeAttributionLogEvent(int atomId,int64_t eventTimeNs,const vector<int> & uids,const vector<string> & tags,int data1,int data2)965 shared_ptr<LogEvent> makeAttributionLogEvent(int atomId, int64_t eventTimeNs,
966 const vector<int>& uids, const vector<string>& tags,
967 int data1, int data2) {
968 AStatsEvent* statsEvent =
969 makeAttributionStatsEvent(atomId, eventTimeNs, uids, tags, data1, data2);
970
971 shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
972 parseStatsEventToLogEvent(statsEvent, logEvent.get());
973 return logEvent;
974 }
975
makeMockUidMapForHosts(const map<int,vector<int>> & hostUidToIsolatedUidsMap)976 sp<MockUidMap> makeMockUidMapForHosts(const map<int, vector<int>>& hostUidToIsolatedUidsMap) {
977 sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
978 EXPECT_CALL(*uidMap, getHostUidOrSelf(_)).WillRepeatedly(ReturnArg<0>());
979 for (const auto& [hostUid, isolatedUids] : hostUidToIsolatedUidsMap) {
980 for (const int isolatedUid : isolatedUids) {
981 EXPECT_CALL(*uidMap, getHostUidOrSelf(isolatedUid)).WillRepeatedly(Return(hostUid));
982 }
983 }
984
985 return uidMap;
986 }
987
makeMockUidMapForPackage(const string & pkg,const set<int32_t> & uids)988 sp<MockUidMap> makeMockUidMapForPackage(const string& pkg, const set<int32_t>& uids) {
989 sp<MockUidMap> uidMap = new StrictMock<MockUidMap>();
990 EXPECT_CALL(*uidMap, getAppUid(_)).Times(AnyNumber());
991 EXPECT_CALL(*uidMap, getAppUid(pkg)).WillRepeatedly(Return(uids));
992
993 return uidMap;
994 }
995
CreateScreenStateChangedEvent(uint64_t timestampNs,const android::view::DisplayStateEnum state,int loggerUid)996 std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(uint64_t timestampNs,
997 const android::view::DisplayStateEnum state,
998 int loggerUid) {
999 AStatsEvent* statsEvent = AStatsEvent_obtain();
1000 AStatsEvent_setAtomId(statsEvent, util::SCREEN_STATE_CHANGED);
1001 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1002 AStatsEvent_writeInt32(statsEvent, state);
1003 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_EXCLUSIVE_STATE, true);
1004 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_STATE_NESTED, false);
1005
1006 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(loggerUid, /*pid=*/0);
1007 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1008 return logEvent;
1009 }
1010
CreateBatterySaverOnEvent(uint64_t timestampNs)1011 std::unique_ptr<LogEvent> CreateBatterySaverOnEvent(uint64_t timestampNs) {
1012 AStatsEvent* statsEvent = AStatsEvent_obtain();
1013 AStatsEvent_setAtomId(statsEvent, util::BATTERY_SAVER_MODE_STATE_CHANGED);
1014 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1015 AStatsEvent_writeInt32(statsEvent, BatterySaverModeStateChanged::ON);
1016 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_EXCLUSIVE_STATE, true);
1017 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_STATE_NESTED, false);
1018
1019 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1020 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1021 return logEvent;
1022 }
1023
CreateBatterySaverOffEvent(uint64_t timestampNs)1024 std::unique_ptr<LogEvent> CreateBatterySaverOffEvent(uint64_t timestampNs) {
1025 AStatsEvent* statsEvent = AStatsEvent_obtain();
1026 AStatsEvent_setAtomId(statsEvent, util::BATTERY_SAVER_MODE_STATE_CHANGED);
1027 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1028 AStatsEvent_writeInt32(statsEvent, BatterySaverModeStateChanged::OFF);
1029 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_EXCLUSIVE_STATE, true);
1030 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_STATE_NESTED, false);
1031
1032 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1033 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1034 return logEvent;
1035 }
1036
CreateBatteryStateChangedEvent(const uint64_t timestampNs,const BatteryPluggedStateEnum state,int32_t uid)1037 std::unique_ptr<LogEvent> CreateBatteryStateChangedEvent(const uint64_t timestampNs,
1038 const BatteryPluggedStateEnum state,
1039 int32_t uid) {
1040 AStatsEvent* statsEvent = AStatsEvent_obtain();
1041 AStatsEvent_setAtomId(statsEvent, util::PLUGGED_STATE_CHANGED);
1042 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1043 AStatsEvent_writeInt32(statsEvent, state);
1044 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_EXCLUSIVE_STATE, true);
1045 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_STATE_NESTED, false);
1046
1047 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/uid, /*pid=*/0);
1048 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1049 return logEvent;
1050 }
1051
CreateMalformedBatteryStateChangedEvent(const uint64_t timestampNs)1052 std::unique_ptr<LogEvent> CreateMalformedBatteryStateChangedEvent(const uint64_t timestampNs) {
1053 AStatsEvent* statsEvent = AStatsEvent_obtain();
1054 AStatsEvent_setAtomId(statsEvent, util::PLUGGED_STATE_CHANGED);
1055 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1056 AStatsEvent_writeString(statsEvent, "bad_state");
1057 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_EXCLUSIVE_STATE, true);
1058 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_STATE_NESTED, false);
1059
1060 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1061 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1062 return logEvent;
1063 }
1064
CreateScreenBrightnessChangedEvent(uint64_t timestampNs,int level)1065 std::unique_ptr<LogEvent> CreateScreenBrightnessChangedEvent(uint64_t timestampNs, int level) {
1066 AStatsEvent* statsEvent = AStatsEvent_obtain();
1067 AStatsEvent_setAtomId(statsEvent, util::SCREEN_BRIGHTNESS_CHANGED);
1068 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1069 AStatsEvent_writeInt32(statsEvent, level);
1070
1071 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1072 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1073 return logEvent;
1074 }
1075
CreateScheduledJobStateChangedEvent(const vector<int> & attributionUids,const vector<string> & attributionTags,const string & jobName,const ScheduledJobStateChanged::State state,uint64_t timestampNs)1076 std::unique_ptr<LogEvent> CreateScheduledJobStateChangedEvent(
1077 const vector<int>& attributionUids, const vector<string>& attributionTags,
1078 const string& jobName, const ScheduledJobStateChanged::State state, uint64_t timestampNs) {
1079 AStatsEvent* statsEvent = AStatsEvent_obtain();
1080 AStatsEvent_setAtomId(statsEvent, util::SCHEDULED_JOB_STATE_CHANGED);
1081 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1082
1083 writeAttribution(statsEvent, attributionUids, attributionTags);
1084 AStatsEvent_writeString(statsEvent, jobName.c_str());
1085 AStatsEvent_writeInt32(statsEvent, state);
1086
1087 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1088 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1089 return logEvent;
1090 }
1091
CreateStartScheduledJobEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & jobName)1092 std::unique_ptr<LogEvent> CreateStartScheduledJobEvent(uint64_t timestampNs,
1093 const vector<int>& attributionUids,
1094 const vector<string>& attributionTags,
1095 const string& jobName) {
1096 return CreateScheduledJobStateChangedEvent(attributionUids, attributionTags, jobName,
1097 ScheduledJobStateChanged::STARTED, timestampNs);
1098 }
1099
1100 // Create log event when scheduled job finishes.
CreateFinishScheduledJobEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & jobName)1101 std::unique_ptr<LogEvent> CreateFinishScheduledJobEvent(uint64_t timestampNs,
1102 const vector<int>& attributionUids,
1103 const vector<string>& attributionTags,
1104 const string& jobName) {
1105 return CreateScheduledJobStateChangedEvent(attributionUids, attributionTags, jobName,
1106 ScheduledJobStateChanged::FINISHED, timestampNs);
1107 }
1108
1109 // Create log event when scheduled job is scheduled.
CreateScheduleScheduledJobEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & jobName)1110 std::unique_ptr<LogEvent> CreateScheduleScheduledJobEvent(uint64_t timestampNs,
1111 const vector<int>& attributionUids,
1112 const vector<string>& attributionTags,
1113 const string& jobName) {
1114 return CreateScheduledJobStateChangedEvent(attributionUids, attributionTags, jobName,
1115 ScheduledJobStateChanged::SCHEDULED, timestampNs);
1116 }
1117
CreateTestAtomReportedEventVariableRepeatedFields(uint64_t timestampNs,const vector<int> & repeatedIntField,const vector<int64_t> & repeatedLongField,const vector<float> & repeatedFloatField,const vector<string> & repeatedStringField,const bool * repeatedBoolField,const size_t repeatedBoolFieldLength,const vector<int> & repeatedEnumField)1118 std::unique_ptr<LogEvent> CreateTestAtomReportedEventVariableRepeatedFields(
1119 uint64_t timestampNs, const vector<int>& repeatedIntField,
1120 const vector<int64_t>& repeatedLongField, const vector<float>& repeatedFloatField,
1121 const vector<string>& repeatedStringField, const bool* repeatedBoolField,
1122 const size_t repeatedBoolFieldLength, const vector<int>& repeatedEnumField) {
1123 return CreateTestAtomReportedEvent(timestampNs, {1001, 1002}, {"app1", "app2"}, 5, 1000l, 21.9f,
1124 "string", 1, TestAtomReported::ON, {8, 1, 8, 2, 8, 3},
1125 repeatedIntField, repeatedLongField, repeatedFloatField,
1126 repeatedStringField, repeatedBoolField,
1127 repeatedBoolFieldLength, repeatedEnumField);
1128 }
1129
CreateTestAtomReportedEventWithPrimitives(uint64_t timestampNs,int intField,long longField,float floatField,const string & stringField,bool boolField,TestAtomReported::State enumField)1130 std::unique_ptr<LogEvent> CreateTestAtomReportedEventWithPrimitives(
1131 uint64_t timestampNs, int intField, long longField, float floatField,
1132 const string& stringField, bool boolField, TestAtomReported::State enumField) {
1133 return CreateTestAtomReportedEvent(
1134 timestampNs, /* attributionUids */ {1001},
1135 /* attributionTags */ {"app1"}, intField, longField, floatField, stringField, boolField,
1136 enumField, /* bytesField */ {},
1137 /* repeatedIntField */ {}, /* repeatedLongField */ {}, /* repeatedFloatField */ {},
1138 /* repeatedStringField */ {}, /* repeatedBoolField */ {},
1139 /* repeatedBoolFieldLength */ 0, /* repeatedEnumField */ {});
1140 }
1141
CreateTestAtomReportedEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const int intField,const long longField,const float floatField,const string & stringField,const bool boolField,const TestAtomReported::State enumField,const vector<uint8_t> & bytesField,const vector<int> & repeatedIntField,const vector<int64_t> & repeatedLongField,const vector<float> & repeatedFloatField,const vector<string> & repeatedStringField,const bool * repeatedBoolField,const size_t repeatedBoolFieldLength,const vector<int> & repeatedEnumField)1142 std::unique_ptr<LogEvent> CreateTestAtomReportedEvent(
1143 uint64_t timestampNs, const vector<int>& attributionUids,
1144 const vector<string>& attributionTags, const int intField, const long longField,
1145 const float floatField, const string& stringField, const bool boolField,
1146 const TestAtomReported::State enumField, const vector<uint8_t>& bytesField,
1147 const vector<int>& repeatedIntField, const vector<int64_t>& repeatedLongField,
1148 const vector<float>& repeatedFloatField, const vector<string>& repeatedStringField,
1149 const bool* repeatedBoolField, const size_t repeatedBoolFieldLength,
1150 const vector<int>& repeatedEnumField) {
1151 vector<const char*> cRepeatedStringField(repeatedStringField.size());
1152 for (int i = 0; i < cRepeatedStringField.size(); i++) {
1153 cRepeatedStringField[i] = repeatedStringField[i].c_str();
1154 }
1155
1156 AStatsEvent* statsEvent = AStatsEvent_obtain();
1157 AStatsEvent_setAtomId(statsEvent, util::TEST_ATOM_REPORTED);
1158 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1159
1160 writeAttribution(statsEvent, attributionUids, attributionTags);
1161 AStatsEvent_writeInt32(statsEvent, intField);
1162 AStatsEvent_writeInt64(statsEvent, longField);
1163 AStatsEvent_writeFloat(statsEvent, floatField);
1164 AStatsEvent_writeString(statsEvent, stringField.c_str());
1165 AStatsEvent_writeBool(statsEvent, boolField);
1166 AStatsEvent_writeInt32(statsEvent, enumField);
1167 AStatsEvent_writeByteArray(statsEvent, bytesField.data(), bytesField.size());
1168 if (__builtin_available(android __ANDROID_API_T__, *)) {
1169 /* CreateTestAtomReportedEvent is used in CreateTestAtomReportedEventVariableRepeatedFields
1170 and CreateTestAtomReportedEventWithPrimitives. Only
1171 CreateTestAtomReportedEventVariableRepeatedFields writes repeated fields, so wrapping
1172 this portion in a __builtin_available and
1173 CreateTestAtomReportedEventVariableRepeatedFields is annotated with __INTRODUCED_IN.
1174 */
1175 AStatsEvent_writeInt32Array(statsEvent, repeatedIntField.data(), repeatedIntField.size());
1176 AStatsEvent_writeInt64Array(statsEvent, repeatedLongField.data(), repeatedLongField.size());
1177 AStatsEvent_writeFloatArray(statsEvent, repeatedFloatField.data(),
1178 repeatedFloatField.size());
1179 AStatsEvent_writeStringArray(statsEvent, cRepeatedStringField.data(),
1180 repeatedStringField.size());
1181 AStatsEvent_writeBoolArray(statsEvent, repeatedBoolField, repeatedBoolFieldLength);
1182 AStatsEvent_writeInt32Array(statsEvent, repeatedEnumField.data(), repeatedEnumField.size());
1183 } else if (!repeatedIntField.empty() || !repeatedLongField.empty() ||
1184 !repeatedFloatField.empty() || !cRepeatedStringField.empty() ||
1185 repeatedBoolFieldLength != 0 || !repeatedEnumField.empty()) {
1186 ADD_FAILURE() << "CreateTestAtomReportedEvent w/ repeated fields is only available in "
1187 "Android T and above.";
1188 }
1189
1190 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1191 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1192 return logEvent;
1193 }
1194
CreateWakelockStateChangedEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & wakelockName,const WakelockStateChanged::State state)1195 std::unique_ptr<LogEvent> CreateWakelockStateChangedEvent(uint64_t timestampNs,
1196 const vector<int>& attributionUids,
1197 const vector<string>& attributionTags,
1198 const string& wakelockName,
1199 const WakelockStateChanged::State state) {
1200 AStatsEvent* statsEvent = AStatsEvent_obtain();
1201 AStatsEvent_setAtomId(statsEvent, util::WAKELOCK_STATE_CHANGED);
1202 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1203
1204 writeAttribution(statsEvent, attributionUids, attributionTags);
1205 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID,
1206 true);
1207 AStatsEvent_writeInt32(statsEvent, android::os::WakeLockLevelEnum::PARTIAL_WAKE_LOCK);
1208 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD, true);
1209 AStatsEvent_writeString(statsEvent, wakelockName.c_str());
1210 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD, true);
1211 AStatsEvent_writeInt32(statsEvent, state);
1212 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_EXCLUSIVE_STATE, true);
1213 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_STATE_NESTED, true);
1214
1215 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1216 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1217 return logEvent;
1218 }
1219
CreateAcquireWakelockEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & wakelockName)1220 std::unique_ptr<LogEvent> CreateAcquireWakelockEvent(uint64_t timestampNs,
1221 const vector<int>& attributionUids,
1222 const vector<string>& attributionTags,
1223 const string& wakelockName) {
1224 return CreateWakelockStateChangedEvent(timestampNs, attributionUids, attributionTags,
1225 wakelockName, WakelockStateChanged::ACQUIRE);
1226 }
1227
CreateReleaseWakelockEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & wakelockName)1228 std::unique_ptr<LogEvent> CreateReleaseWakelockEvent(uint64_t timestampNs,
1229 const vector<int>& attributionUids,
1230 const vector<string>& attributionTags,
1231 const string& wakelockName) {
1232 return CreateWakelockStateChangedEvent(timestampNs, attributionUids, attributionTags,
1233 wakelockName, WakelockStateChanged::RELEASE);
1234 }
1235
CreateActivityForegroundStateChangedEvent(uint64_t timestampNs,const int uid,const string & pkgName,const string & className,const ActivityForegroundStateChanged::State state)1236 std::unique_ptr<LogEvent> CreateActivityForegroundStateChangedEvent(
1237 uint64_t timestampNs, const int uid, const string& pkgName, const string& className,
1238 const ActivityForegroundStateChanged::State state) {
1239 AStatsEvent* statsEvent = AStatsEvent_obtain();
1240 AStatsEvent_setAtomId(statsEvent, util::ACTIVITY_FOREGROUND_STATE_CHANGED);
1241 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1242
1243 AStatsEvent_writeInt32(statsEvent, uid);
1244 AStatsEvent_writeString(statsEvent, pkgName.c_str());
1245 AStatsEvent_writeString(statsEvent, className.c_str());
1246 AStatsEvent_writeInt32(statsEvent, state);
1247
1248 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1249 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1250 return logEvent;
1251 }
1252
CreateMoveToBackgroundEvent(uint64_t timestampNs,const int uid)1253 std::unique_ptr<LogEvent> CreateMoveToBackgroundEvent(uint64_t timestampNs, const int uid) {
1254 return CreateActivityForegroundStateChangedEvent(timestampNs, uid, "pkg_name", "class_name",
1255 ActivityForegroundStateChanged::BACKGROUND);
1256 }
1257
CreateMoveToForegroundEvent(uint64_t timestampNs,const int uid)1258 std::unique_ptr<LogEvent> CreateMoveToForegroundEvent(uint64_t timestampNs, const int uid) {
1259 return CreateActivityForegroundStateChangedEvent(timestampNs, uid, "pkg_name", "class_name",
1260 ActivityForegroundStateChanged::FOREGROUND);
1261 }
1262
CreateSyncStateChangedEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & name,const SyncStateChanged::State state)1263 std::unique_ptr<LogEvent> CreateSyncStateChangedEvent(uint64_t timestampNs,
1264 const vector<int>& attributionUids,
1265 const vector<string>& attributionTags,
1266 const string& name,
1267 const SyncStateChanged::State state) {
1268 AStatsEvent* statsEvent = AStatsEvent_obtain();
1269 AStatsEvent_setAtomId(statsEvent, util::SYNC_STATE_CHANGED);
1270 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1271
1272 writeAttribution(statsEvent, attributionUids, attributionTags);
1273 AStatsEvent_writeString(statsEvent, name.c_str());
1274 AStatsEvent_writeInt32(statsEvent, state);
1275
1276 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1277 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1278 return logEvent;
1279 }
1280
CreateSyncStartEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & name)1281 std::unique_ptr<LogEvent> CreateSyncStartEvent(uint64_t timestampNs,
1282 const vector<int>& attributionUids,
1283 const vector<string>& attributionTags,
1284 const string& name) {
1285 return CreateSyncStateChangedEvent(timestampNs, attributionUids, attributionTags, name,
1286 SyncStateChanged::ON);
1287 }
1288
CreateSyncEndEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & name)1289 std::unique_ptr<LogEvent> CreateSyncEndEvent(uint64_t timestampNs,
1290 const vector<int>& attributionUids,
1291 const vector<string>& attributionTags,
1292 const string& name) {
1293 return CreateSyncStateChangedEvent(timestampNs, attributionUids, attributionTags, name,
1294 SyncStateChanged::OFF);
1295 }
1296
CreateProcessLifeCycleStateChangedEvent(uint64_t timestampNs,const int uid,const ProcessLifeCycleStateChanged::State state)1297 std::unique_ptr<LogEvent> CreateProcessLifeCycleStateChangedEvent(
1298 uint64_t timestampNs, const int uid, const ProcessLifeCycleStateChanged::State state) {
1299 AStatsEvent* statsEvent = AStatsEvent_obtain();
1300 AStatsEvent_setAtomId(statsEvent, util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
1301 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1302
1303 AStatsEvent_writeInt32(statsEvent, uid);
1304 AStatsEvent_writeString(statsEvent, "");
1305 AStatsEvent_writeInt32(statsEvent, state);
1306
1307 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1308 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1309 return logEvent;
1310 }
1311
CreateAppCrashEvent(uint64_t timestampNs,const int uid)1312 std::unique_ptr<LogEvent> CreateAppCrashEvent(uint64_t timestampNs, const int uid) {
1313 return CreateProcessLifeCycleStateChangedEvent(timestampNs, uid,
1314 ProcessLifeCycleStateChanged::CRASHED);
1315 }
1316
CreateAppCrashOccurredEvent(uint64_t timestampNs,const int uid)1317 std::unique_ptr<LogEvent> CreateAppCrashOccurredEvent(uint64_t timestampNs, const int uid) {
1318 AStatsEvent* statsEvent = AStatsEvent_obtain();
1319 AStatsEvent_setAtomId(statsEvent, util::APP_CRASH_OCCURRED);
1320 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1321
1322 AStatsEvent_writeInt32(statsEvent, uid);
1323 AStatsEvent_writeString(statsEvent, "eventType");
1324 AStatsEvent_writeString(statsEvent, "processName");
1325
1326 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1327 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1328 return logEvent;
1329 }
1330
CreateIsolatedUidChangedEvent(uint64_t timestampNs,int hostUid,int isolatedUid,bool is_create)1331 std::unique_ptr<LogEvent> CreateIsolatedUidChangedEvent(uint64_t timestampNs, int hostUid,
1332 int isolatedUid, bool is_create) {
1333 AStatsEvent* statsEvent = AStatsEvent_obtain();
1334 AStatsEvent_setAtomId(statsEvent, util::ISOLATED_UID_CHANGED);
1335 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1336
1337 AStatsEvent_writeInt32(statsEvent, hostUid);
1338 AStatsEvent_writeInt32(statsEvent, isolatedUid);
1339 AStatsEvent_writeInt32(statsEvent, is_create);
1340
1341 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1342 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1343 return logEvent;
1344 }
1345
CreateUidProcessStateChangedEvent(uint64_t timestampNs,int uid,const android::app::ProcessStateEnum state)1346 std::unique_ptr<LogEvent> CreateUidProcessStateChangedEvent(
1347 uint64_t timestampNs, int uid, const android::app::ProcessStateEnum state) {
1348 AStatsEvent* statsEvent = AStatsEvent_obtain();
1349 AStatsEvent_setAtomId(statsEvent, util::UID_PROCESS_STATE_CHANGED);
1350 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1351
1352 AStatsEvent_writeInt32(statsEvent, uid);
1353 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
1354 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD, true);
1355 AStatsEvent_writeInt32(statsEvent, state);
1356 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_EXCLUSIVE_STATE, true);
1357 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_STATE_NESTED, false);
1358
1359 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1360 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1361 return logEvent;
1362 }
1363
CreateBleScanStateChangedEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const BleScanStateChanged::State state,const bool filtered,const bool firstMatch,const bool opportunistic)1364 std::unique_ptr<LogEvent> CreateBleScanStateChangedEvent(uint64_t timestampNs,
1365 const vector<int>& attributionUids,
1366 const vector<string>& attributionTags,
1367 const BleScanStateChanged::State state,
1368 const bool filtered, const bool firstMatch,
1369 const bool opportunistic) {
1370 AStatsEvent* statsEvent = AStatsEvent_obtain();
1371 AStatsEvent_setAtomId(statsEvent, util::BLE_SCAN_STATE_CHANGED);
1372 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1373
1374 writeAttribution(statsEvent, attributionUids, attributionTags);
1375 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID,
1376 true);
1377 AStatsEvent_writeInt32(statsEvent, state);
1378 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_EXCLUSIVE_STATE, true);
1379 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_STATE_NESTED, true);
1380 if (state == util::BLE_SCAN_STATE_CHANGED__STATE__RESET) {
1381 AStatsEvent_addInt32Annotation(statsEvent, ASTATSLOG_ANNOTATION_ID_TRIGGER_STATE_RESET,
1382 util::BLE_SCAN_STATE_CHANGED__STATE__OFF);
1383 }
1384 AStatsEvent_writeBool(statsEvent, filtered); // filtered
1385 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD, true);
1386 AStatsEvent_writeBool(statsEvent, firstMatch); // first match
1387 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD, true);
1388 AStatsEvent_writeBool(statsEvent, opportunistic); // opportunistic
1389 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD, true);
1390
1391 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1392 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1393 return logEvent;
1394 }
1395
CreateOverlayStateChangedEvent(int64_t timestampNs,const int32_t uid,const string & packageName,const bool usingAlertWindow,const OverlayStateChanged::State state)1396 std::unique_ptr<LogEvent> CreateOverlayStateChangedEvent(int64_t timestampNs, const int32_t uid,
1397 const string& packageName,
1398 const bool usingAlertWindow,
1399 const OverlayStateChanged::State state) {
1400 AStatsEvent* statsEvent = AStatsEvent_obtain();
1401 AStatsEvent_setAtomId(statsEvent, util::OVERLAY_STATE_CHANGED);
1402 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1403
1404 AStatsEvent_writeInt32(statsEvent, uid);
1405 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
1406 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD, true);
1407 AStatsEvent_writeString(statsEvent, packageName.c_str());
1408 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD, true);
1409 AStatsEvent_writeBool(statsEvent, usingAlertWindow);
1410 AStatsEvent_writeInt32(statsEvent, state);
1411 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_EXCLUSIVE_STATE, true);
1412 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_STATE_NESTED, false);
1413
1414 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1415 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1416 return logEvent;
1417 }
1418
CreateAppStartOccurredEvent(uint64_t timestampNs,const int uid,const string & pkgName,AppStartOccurred::TransitionType type,const string & activityName,const string & callingPkgName,const bool isInstantApp,int64_t activityStartMs)1419 std::unique_ptr<LogEvent> CreateAppStartOccurredEvent(
1420 uint64_t timestampNs, const int uid, const string& pkgName,
1421 AppStartOccurred::TransitionType type, const string& activityName,
1422 const string& callingPkgName, const bool isInstantApp, int64_t activityStartMs) {
1423 AStatsEvent* statsEvent = AStatsEvent_obtain();
1424 AStatsEvent_setAtomId(statsEvent, util::APP_START_OCCURRED);
1425 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1426
1427 AStatsEvent_writeInt32(statsEvent, uid);
1428 AStatsEvent_writeString(statsEvent, pkgName.c_str());
1429 AStatsEvent_writeInt32(statsEvent, type);
1430 AStatsEvent_writeString(statsEvent, activityName.c_str());
1431 AStatsEvent_writeString(statsEvent, callingPkgName.c_str());
1432 AStatsEvent_writeInt32(statsEvent, isInstantApp);
1433 AStatsEvent_writeInt32(statsEvent, activityStartMs);
1434
1435 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1436 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1437 return logEvent;
1438 }
1439
CreateBleScanResultReceivedEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const int numResults)1440 std::unique_ptr<LogEvent> CreateBleScanResultReceivedEvent(uint64_t timestampNs,
1441 const vector<int>& attributionUids,
1442 const vector<string>& attributionTags,
1443 const int numResults) {
1444 AStatsEvent* statsEvent = AStatsEvent_obtain();
1445 AStatsEvent_setAtomId(statsEvent, util::BLE_SCAN_RESULT_RECEIVED);
1446 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1447
1448 writeAttribution(statsEvent, attributionUids, attributionTags);
1449 AStatsEvent_writeInt32(statsEvent, numResults);
1450
1451 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1452 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1453 return logEvent;
1454 }
1455
CreateRestrictedLogEvent(int atomTag,int64_t timestampNs)1456 std::unique_ptr<LogEvent> CreateRestrictedLogEvent(int atomTag, int64_t timestampNs) {
1457 AStatsEvent* statsEvent = AStatsEvent_obtain();
1458 AStatsEvent_setAtomId(statsEvent, atomTag);
1459 AStatsEvent_addInt32Annotation(statsEvent, ASTATSLOG_ANNOTATION_ID_RESTRICTION_CATEGORY,
1460 ASTATSLOG_RESTRICTION_CATEGORY_DIAGNOSTIC);
1461 AStatsEvent_writeInt32(statsEvent, 10);
1462 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1463 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1464 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1465 return logEvent;
1466 }
1467
CreateNonRestrictedLogEvent(int atomTag,int64_t timestampNs)1468 std::unique_ptr<LogEvent> CreateNonRestrictedLogEvent(int atomTag, int64_t timestampNs) {
1469 AStatsEvent* statsEvent = AStatsEvent_obtain();
1470 AStatsEvent_setAtomId(statsEvent, atomTag);
1471 AStatsEvent_writeInt32(statsEvent, 10);
1472 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1473 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1474 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1475 return logEvent;
1476 }
1477
CreatePhoneSignalStrengthChangedEvent(int64_t timestampNs,::telephony::SignalStrengthEnum state)1478 std::unique_ptr<LogEvent> CreatePhoneSignalStrengthChangedEvent(
1479 int64_t timestampNs, ::telephony::SignalStrengthEnum state) {
1480 AStatsEvent* statsEvent = AStatsEvent_obtain();
1481 AStatsEvent_setAtomId(statsEvent, util::PHONE_SIGNAL_STRENGTH_CHANGED);
1482 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_TRUNCATE_TIMESTAMP, true);
1483 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1484 AStatsEvent_writeInt32(statsEvent, state);
1485
1486 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1487 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1488 return logEvent;
1489 }
1490
CreateStatsLogProcessor(const int64_t timeBaseNs,const int64_t currentTimeNs,const StatsdConfig & config,const ConfigKey & key,const shared_ptr<IPullAtomCallback> & puller,const int32_t atomTag,const sp<UidMap> uidMap,const shared_ptr<LogEventFilter> & logEventFilter)1491 sp<StatsLogProcessor> CreateStatsLogProcessor(const int64_t timeBaseNs, const int64_t currentTimeNs,
1492 const StatsdConfig& config, const ConfigKey& key,
1493 const shared_ptr<IPullAtomCallback>& puller,
1494 const int32_t atomTag, const sp<UidMap> uidMap,
1495 const shared_ptr<LogEventFilter>& logEventFilter) {
1496 sp<StatsPullerManager> pullerManager = new StatsPullerManager();
1497 StatsPuller::SetUidMap(uidMap);
1498 if (puller != nullptr) {
1499 pullerManager->RegisterPullAtomCallback(/*uid=*/0, atomTag, NS_PER_SEC, NS_PER_SEC * 10, {},
1500 puller);
1501 }
1502 sp<AlarmMonitor> anomalyAlarmMonitor =
1503 new AlarmMonitor(1,
1504 [](const shared_ptr<IStatsCompanionService>&, int64_t){},
1505 [](const shared_ptr<IStatsCompanionService>&){});
1506 sp<AlarmMonitor> periodicAlarmMonitor =
1507 new AlarmMonitor(1,
1508 [](const shared_ptr<IStatsCompanionService>&, int64_t){},
1509 [](const shared_ptr<IStatsCompanionService>&){});
1510 sp<StatsLogProcessor> processor = new StatsLogProcessor(
1511 uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor, timeBaseNs,
1512 [](const ConfigKey&) { return true; },
1513 [](const int&, const vector<int64_t>&) { return true; },
1514 [](const ConfigKey&, const string&, const vector<int64_t>&) {}, logEventFilter);
1515
1516 processor->OnConfigUpdated(currentTimeNs, key, config);
1517 return processor;
1518 }
1519
createNumericValueMetricProducer(sp<MockStatsPullerManager> & pullerManager,const ValueMetric & metric,const int atomId,bool isPulled,const ConfigKey & configKey,const uint64_t protoHash,const int64_t timeBaseNs,const int64_t startTimeNs,const int logEventMatcherIndex,optional<ConditionState> conditionAfterFirstBucketPrepared,vector<int32_t> slicedStateAtoms,unordered_map<int,unordered_map<int,int64_t>> stateGroupMap,sp<EventMatcherWizard> eventMatcherWizard)1520 sp<NumericValueMetricProducer> createNumericValueMetricProducer(
1521 sp<MockStatsPullerManager>& pullerManager, const ValueMetric& metric, const int atomId,
1522 bool isPulled, const ConfigKey& configKey, const uint64_t protoHash,
1523 const int64_t timeBaseNs, const int64_t startTimeNs, const int logEventMatcherIndex,
1524 optional<ConditionState> conditionAfterFirstBucketPrepared,
1525 vector<int32_t> slicedStateAtoms,
1526 unordered_map<int, unordered_map<int, int64_t>> stateGroupMap,
1527 sp<EventMatcherWizard> eventMatcherWizard) {
1528 if (eventMatcherWizard == nullptr) {
1529 eventMatcherWizard = createEventMatcherWizard(atomId, logEventMatcherIndex);
1530 }
1531 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
1532 if (isPulled) {
1533 EXPECT_CALL(*pullerManager, RegisterReceiver(atomId, configKey, _, _, _))
1534 .WillOnce(Return());
1535 EXPECT_CALL(*pullerManager, UnRegisterReceiver(atomId, configKey, _))
1536 .WillRepeatedly(Return());
1537 }
1538 const int64_t bucketSizeNs = MillisToNano(
1539 TimeUnitToBucketSizeInMillisGuardrailed(configKey.GetUid(), metric.bucket()));
1540 const bool containsAnyPositionInDimensionsInWhat = HasPositionANY(metric.dimensions_in_what());
1541 const bool shouldUseNestedDimensions = ShouldUseNestedDimensions(metric.dimensions_in_what());
1542
1543 vector<Matcher> fieldMatchers;
1544 translateFieldMatcher(metric.value_field(), &fieldMatchers);
1545
1546 const auto [dimensionSoftLimit, dimensionHardLimit] =
1547 StatsdStats::getAtomDimensionKeySizeLimits(atomId,
1548 StatsdStats::kDimensionKeySizeHardLimitMin);
1549
1550 int conditionIndex = conditionAfterFirstBucketPrepared ? 0 : -1;
1551 vector<ConditionState> initialConditionCache;
1552 if (conditionAfterFirstBucketPrepared) {
1553 initialConditionCache.push_back(ConditionState::kUnknown);
1554 }
1555
1556 // get the condition_correction_threshold_nanos value
1557 const optional<int64_t> conditionCorrectionThresholdNs =
1558 metric.has_condition_correction_threshold_nanos()
1559 ? optional<int64_t>(metric.condition_correction_threshold_nanos())
1560 : nullopt;
1561
1562 std::vector<ValueMetric::AggregationType> aggregationTypes;
1563 if (metric.aggregation_types_size() != 0) {
1564 for (int i = 0; i < metric.aggregation_types_size(); i++) {
1565 aggregationTypes.push_back(metric.aggregation_types(i));
1566 }
1567 } else { // aggregation_type() is set or default is used.
1568 aggregationTypes.push_back(metric.aggregation_type());
1569 }
1570
1571 ParseHistogramBinConfigsResult parseBinConfigsResult =
1572 parseHistogramBinConfigs(metric, aggregationTypes);
1573 const vector<optional<const BinStarts>>& binStartsList =
1574 std::get<vector<optional<const BinStarts>>>(parseBinConfigsResult);
1575
1576 sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
1577 const int pullAtomId = isPulled ? atomId : -1;
1578 return new NumericValueMetricProducer(
1579 configKey, metric, protoHash, {pullAtomId, pullerManager},
1580 {timeBaseNs, startTimeNs, bucketSizeNs, metric.min_bucket_size_nanos(),
1581 conditionCorrectionThresholdNs, metric.split_bucket_for_app_upgrade()},
1582 {containsAnyPositionInDimensionsInWhat, shouldUseNestedDimensions, logEventMatcherIndex,
1583 eventMatcherWizard, metric.dimensions_in_what(), fieldMatchers, aggregationTypes,
1584 binStartsList},
1585 {conditionIndex, metric.links(), initialConditionCache, wizard},
1586 {metric.state_link(), slicedStateAtoms, stateGroupMap},
1587 {/*eventActivationMap=*/{}, /*eventDeactivationMap=*/{}},
1588 {dimensionSoftLimit, dimensionHardLimit}, provider);
1589 }
1590
CreateAtomIdSetDefault()1591 LogEventFilter::AtomIdSet CreateAtomIdSetDefault() {
1592 LogEventFilter::AtomIdSet resultList(StatsLogProcessor::getDefaultAtomIdSet());
1593 StateManager::getInstance().addAllAtomIds(resultList);
1594 return resultList;
1595 }
1596
CreateAtomIdSetFromConfig(const StatsdConfig & config)1597 LogEventFilter::AtomIdSet CreateAtomIdSetFromConfig(const StatsdConfig& config) {
1598 LogEventFilter::AtomIdSet resultList(StatsLogProcessor::getDefaultAtomIdSet());
1599
1600 // Parse the config for atom ids. A combination atom matcher is a combination of (in the end)
1601 // simple atom matchers. So by adding all the atoms from the simple atom matchers
1602 // function adds all of the atoms.
1603 for (int i = 0; i < config.atom_matcher_size(); i++) {
1604 const AtomMatcher& matcher = config.atom_matcher(i);
1605 if (matcher.has_simple_atom_matcher()) {
1606 EXPECT_TRUE(matcher.simple_atom_matcher().has_atom_id());
1607 resultList.insert(matcher.simple_atom_matcher().atom_id());
1608 }
1609 }
1610
1611 for (int i = 0; i < config.state_size(); i++) {
1612 const State& state = config.state(i);
1613 EXPECT_TRUE(state.has_atom_id());
1614 resultList.insert(state.atom_id());
1615 }
1616
1617 return resultList;
1618 }
1619
sortLogEventsByTimestamp(std::vector<std::unique_ptr<LogEvent>> * events)1620 void sortLogEventsByTimestamp(std::vector<std::unique_ptr<LogEvent>> *events) {
1621 std::sort(events->begin(), events->end(),
1622 [](const std::unique_ptr<LogEvent>& a, const std::unique_ptr<LogEvent>& b) {
1623 return a->GetElapsedTimestampNs() < b->GetElapsedTimestampNs();
1624 });
1625 }
1626
StringToId(const string & str)1627 int64_t StringToId(const string& str) {
1628 return static_cast<int64_t>(std::hash<std::string>()(str));
1629 }
1630
createEventMatcherWizard(int tagId,int matcherIndex,const vector<FieldValueMatcher> & fieldValueMatchers)1631 sp<EventMatcherWizard> createEventMatcherWizard(
1632 int tagId, int matcherIndex, const vector<FieldValueMatcher>& fieldValueMatchers) {
1633 sp<UidMap> uidMap = new UidMap();
1634 SimpleAtomMatcher atomMatcher;
1635 atomMatcher.set_atom_id(tagId);
1636 for (const FieldValueMatcher& fvm : fieldValueMatchers) {
1637 *atomMatcher.add_field_value_matcher() = fvm;
1638 }
1639 uint64_t matcherHash = 0x12345678;
1640 int64_t matcherId = 678;
1641 return new EventMatcherWizard(
1642 {new SimpleAtomMatchingTracker(matcherId, matcherHash, atomMatcher, uidMap)});
1643 }
1644
CreateAttributionUidDimensionsValueParcel(const int atomId,const int uid)1645 StatsDimensionsValueParcel CreateAttributionUidDimensionsValueParcel(const int atomId,
1646 const int uid) {
1647 StatsDimensionsValueParcel root;
1648 root.field = atomId;
1649 root.valueType = STATS_DIMENSIONS_VALUE_TUPLE_TYPE;
1650 StatsDimensionsValueParcel attrNode;
1651 attrNode.field = 1;
1652 attrNode.valueType = STATS_DIMENSIONS_VALUE_TUPLE_TYPE;
1653 StatsDimensionsValueParcel posInAttrChain;
1654 posInAttrChain.field = 1;
1655 posInAttrChain.valueType = STATS_DIMENSIONS_VALUE_TUPLE_TYPE;
1656 StatsDimensionsValueParcel uidNode;
1657 uidNode.field = 1;
1658 uidNode.valueType = STATS_DIMENSIONS_VALUE_INT_TYPE;
1659 uidNode.intValue = uid;
1660 posInAttrChain.tupleValue.push_back(uidNode);
1661 attrNode.tupleValue.push_back(posInAttrChain);
1662 root.tupleValue.push_back(attrNode);
1663 return root;
1664 }
1665
ValidateUidDimension(const DimensionsValue & value,int atomId,int uid)1666 void ValidateUidDimension(const DimensionsValue& value, int atomId, int uid) {
1667 EXPECT_EQ(value.field(), atomId);
1668 ASSERT_EQ(value.value_tuple().dimensions_value_size(), 1);
1669 EXPECT_EQ(value.value_tuple().dimensions_value(0).field(), 1);
1670 EXPECT_EQ(value.value_tuple().dimensions_value(0).value_int(), uid);
1671 }
1672
ValidateWakelockAttributionUidAndTagDimension(const DimensionsValue & value,const int atomId,const int uid,const string & tag)1673 void ValidateWakelockAttributionUidAndTagDimension(const DimensionsValue& value, const int atomId,
1674 const int uid, const string& tag) {
1675 EXPECT_EQ(value.field(), atomId);
1676 ASSERT_EQ(value.value_tuple().dimensions_value_size(), 2);
1677 // Attribution field.
1678 EXPECT_EQ(value.value_tuple().dimensions_value(0).field(), 1);
1679 // Uid field.
1680 ASSERT_EQ(value.value_tuple().dimensions_value(0).value_tuple().dimensions_value_size(), 1);
1681 EXPECT_EQ(value.value_tuple().dimensions_value(0).value_tuple().dimensions_value(0).field(), 1);
1682 EXPECT_EQ(value.value_tuple().dimensions_value(0).value_tuple().dimensions_value(0).value_int(),
1683 uid);
1684 // Tag field.
1685 EXPECT_EQ(value.value_tuple().dimensions_value(1).field(), 3);
1686 EXPECT_EQ(value.value_tuple().dimensions_value(1).value_str(), tag);
1687 }
1688
ValidateAttributionUidDimension(const DimensionsValue & value,int atomId,int uid)1689 void ValidateAttributionUidDimension(const DimensionsValue& value, int atomId, int uid) {
1690 EXPECT_EQ(value.field(), atomId);
1691 ASSERT_EQ(value.value_tuple().dimensions_value_size(), 1);
1692 // Attribution field.
1693 EXPECT_EQ(value.value_tuple().dimensions_value(0).field(), 1);
1694 // Uid only.
1695 EXPECT_EQ(value.value_tuple().dimensions_value(0)
1696 .value_tuple().dimensions_value_size(), 1);
1697 EXPECT_EQ(value.value_tuple().dimensions_value(0)
1698 .value_tuple().dimensions_value(0).field(), 1);
1699 EXPECT_EQ(value.value_tuple().dimensions_value(0)
1700 .value_tuple().dimensions_value(0).value_int(), uid);
1701 }
1702
ValidateUidDimension(const DimensionsValue & value,int node_idx,int atomId,int uid)1703 void ValidateUidDimension(const DimensionsValue& value, int node_idx, int atomId, int uid) {
1704 EXPECT_EQ(value.field(), atomId);
1705 ASSERT_GT(value.value_tuple().dimensions_value_size(), node_idx);
1706 // Attribution field.
1707 EXPECT_EQ(value.value_tuple().dimensions_value(node_idx).field(), 1);
1708 EXPECT_EQ(value.value_tuple().dimensions_value(node_idx)
1709 .value_tuple().dimensions_value(0).field(), 1);
1710 EXPECT_EQ(value.value_tuple().dimensions_value(node_idx)
1711 .value_tuple().dimensions_value(0).value_int(), uid);
1712 }
1713
ValidateAttributionUidAndTagDimension(const DimensionsValue & value,int node_idx,int atomId,int uid,const std::string & tag)1714 void ValidateAttributionUidAndTagDimension(
1715 const DimensionsValue& value, int node_idx, int atomId, int uid, const std::string& tag) {
1716 EXPECT_EQ(value.field(), atomId);
1717 ASSERT_GT(value.value_tuple().dimensions_value_size(), node_idx);
1718 // Attribution field.
1719 EXPECT_EQ(1, value.value_tuple().dimensions_value(node_idx).field());
1720 // Uid only.
1721 EXPECT_EQ(2, value.value_tuple().dimensions_value(node_idx)
1722 .value_tuple().dimensions_value_size());
1723 EXPECT_EQ(1, value.value_tuple().dimensions_value(node_idx)
1724 .value_tuple().dimensions_value(0).field());
1725 EXPECT_EQ(uid, value.value_tuple().dimensions_value(node_idx)
1726 .value_tuple().dimensions_value(0).value_int());
1727 EXPECT_EQ(2, value.value_tuple().dimensions_value(node_idx)
1728 .value_tuple().dimensions_value(1).field());
1729 EXPECT_EQ(tag, value.value_tuple().dimensions_value(node_idx)
1730 .value_tuple().dimensions_value(1).value_str());
1731 }
1732
ValidateAttributionUidAndTagDimension(const DimensionsValue & value,int atomId,int uid,const std::string & tag)1733 void ValidateAttributionUidAndTagDimension(
1734 const DimensionsValue& value, int atomId, int uid, const std::string& tag) {
1735 EXPECT_EQ(value.field(), atomId);
1736 ASSERT_EQ(1, value.value_tuple().dimensions_value_size());
1737 // Attribution field.
1738 EXPECT_EQ(1, value.value_tuple().dimensions_value(0).field());
1739 // Uid only.
1740 EXPECT_EQ(value.value_tuple().dimensions_value(0)
1741 .value_tuple().dimensions_value_size(), 2);
1742 EXPECT_EQ(value.value_tuple().dimensions_value(0)
1743 .value_tuple().dimensions_value(0).field(), 1);
1744 EXPECT_EQ(value.value_tuple().dimensions_value(0)
1745 .value_tuple().dimensions_value(0).value_int(), uid);
1746 EXPECT_EQ(value.value_tuple().dimensions_value(0)
1747 .value_tuple().dimensions_value(1).field(), 2);
1748 EXPECT_EQ(value.value_tuple().dimensions_value(0)
1749 .value_tuple().dimensions_value(1).value_str(), tag);
1750 }
1751
ValidateStateValue(const google::protobuf::RepeatedPtrField<StateValue> & stateValues,int atomId,int64_t value)1752 void ValidateStateValue(const google::protobuf::RepeatedPtrField<StateValue>& stateValues,
1753 int atomId, int64_t value) {
1754 ASSERT_EQ(stateValues.size(), 1);
1755 ASSERT_EQ(stateValues[0].atom_id(), atomId);
1756 switch (stateValues[0].contents_case()) {
1757 case StateValue::ContentsCase::kValue:
1758 EXPECT_EQ(stateValues[0].value(), (int32_t)value);
1759 break;
1760 case StateValue::ContentsCase::kGroupId:
1761 EXPECT_EQ(stateValues[0].group_id(), value);
1762 break;
1763 default:
1764 FAIL() << "State value should have either a value or a group id";
1765 }
1766 }
1767
ValidateCountBucket(const CountBucketInfo & countBucket,int64_t startTimeNs,int64_t endTimeNs,int64_t count,int64_t conditionTrueNs)1768 void ValidateCountBucket(const CountBucketInfo& countBucket, int64_t startTimeNs, int64_t endTimeNs,
1769 int64_t count, int64_t conditionTrueNs) {
1770 EXPECT_EQ(countBucket.start_bucket_elapsed_nanos(), startTimeNs);
1771 EXPECT_EQ(countBucket.end_bucket_elapsed_nanos(), endTimeNs);
1772 EXPECT_EQ(countBucket.count(), count);
1773 EXPECT_EQ(countBucket.condition_true_nanos(), conditionTrueNs);
1774 }
1775
ValidateDurationBucket(const DurationBucketInfo & bucket,int64_t startTimeNs,int64_t endTimeNs,int64_t durationNs,int64_t conditionTrueNs)1776 void ValidateDurationBucket(const DurationBucketInfo& bucket, int64_t startTimeNs,
1777 int64_t endTimeNs, int64_t durationNs, int64_t conditionTrueNs) {
1778 EXPECT_EQ(bucket.start_bucket_elapsed_nanos(), startTimeNs);
1779 EXPECT_EQ(bucket.end_bucket_elapsed_nanos(), endTimeNs);
1780 EXPECT_EQ(bucket.duration_nanos(), durationNs);
1781 EXPECT_EQ(bucket.condition_true_nanos(), conditionTrueNs);
1782 }
1783
ValidateGaugeBucketTimes(const GaugeBucketInfo & gaugeBucket,int64_t startTimeNs,int64_t endTimeNs,vector<int64_t> eventTimesNs)1784 void ValidateGaugeBucketTimes(const GaugeBucketInfo& gaugeBucket, int64_t startTimeNs,
1785 int64_t endTimeNs, vector<int64_t> eventTimesNs) {
1786 EXPECT_EQ(gaugeBucket.start_bucket_elapsed_nanos(), startTimeNs);
1787 EXPECT_EQ(gaugeBucket.end_bucket_elapsed_nanos(), endTimeNs);
1788 EXPECT_EQ(gaugeBucket.elapsed_timestamp_nanos_size(), eventTimesNs.size());
1789 for (int i = 0; i < eventTimesNs.size(); i++) {
1790 EXPECT_EQ(gaugeBucket.elapsed_timestamp_nanos(i), eventTimesNs[i]);
1791 }
1792 }
1793
ValidateValueBucket(const ValueBucketInfo & bucket,int64_t startTimeNs,int64_t endTimeNs,const vector<int64_t> & values,int64_t conditionTrueNs,int64_t conditionCorrectionNs)1794 void ValidateValueBucket(const ValueBucketInfo& bucket, int64_t startTimeNs, int64_t endTimeNs,
1795 const vector<int64_t>& values, int64_t conditionTrueNs,
1796 int64_t conditionCorrectionNs) {
1797 EXPECT_EQ(bucket.start_bucket_elapsed_nanos(), startTimeNs);
1798 EXPECT_EQ(bucket.end_bucket_elapsed_nanos(), endTimeNs);
1799 ASSERT_EQ(bucket.values_size(), values.size());
1800 for (int i = 0; i < values.size(); ++i) {
1801 if (bucket.values(i).has_value_double()) {
1802 EXPECT_EQ((int64_t)bucket.values(i).value_double(), values[i]);
1803 } else {
1804 EXPECT_EQ(bucket.values(i).value_long(), values[i]);
1805 }
1806 }
1807 if (conditionTrueNs > 0) {
1808 EXPECT_EQ(bucket.condition_true_nanos(), conditionTrueNs);
1809 if (conditionCorrectionNs > 0) {
1810 EXPECT_EQ(bucket.condition_correction_nanos(), conditionCorrectionNs);
1811 }
1812 }
1813 }
1814
ValidateKllBucket(const KllBucketInfo & bucket,int64_t startTimeNs,int64_t endTimeNs,const vector<int64_t> sketchSizes,int64_t conditionTrueNs)1815 void ValidateKllBucket(const KllBucketInfo& bucket, int64_t startTimeNs, int64_t endTimeNs,
1816 const vector<int64_t> sketchSizes, int64_t conditionTrueNs) {
1817 EXPECT_EQ(bucket.start_bucket_elapsed_nanos(), startTimeNs);
1818 EXPECT_EQ(bucket.end_bucket_elapsed_nanos(), endTimeNs);
1819 ASSERT_EQ(bucket.sketches_size(), sketchSizes.size());
1820 for (int i = 0; i < sketchSizes.size(); ++i) {
1821 AggregatorStateProto aggProto;
1822 EXPECT_TRUE(aggProto.ParseFromString(bucket.sketches(i).kll_sketch()));
1823 EXPECT_EQ(aggProto.num_values(), sketchSizes[i]);
1824 }
1825 if (conditionTrueNs > 0) {
1826 EXPECT_EQ(bucket.condition_true_nanos(), conditionTrueNs);
1827 }
1828 }
1829
EqualsTo(const DimensionsValue & s1,const DimensionsValue & s2)1830 bool EqualsTo(const DimensionsValue& s1, const DimensionsValue& s2) {
1831 if (s1.field() != s2.field()) {
1832 return false;
1833 }
1834 if (s1.value_case() != s2.value_case()) {
1835 return false;
1836 }
1837 switch (s1.value_case()) {
1838 case DimensionsValue::ValueCase::kValueStr:
1839 return (s1.value_str() == s2.value_str());
1840 case DimensionsValue::ValueCase::kValueInt:
1841 return s1.value_int() == s2.value_int();
1842 case DimensionsValue::ValueCase::kValueLong:
1843 return s1.value_long() == s2.value_long();
1844 case DimensionsValue::ValueCase::kValueBool:
1845 return s1.value_bool() == s2.value_bool();
1846 case DimensionsValue::ValueCase::kValueFloat:
1847 return s1.value_float() == s2.value_float();
1848 case DimensionsValue::ValueCase::kValueTuple: {
1849 if (s1.value_tuple().dimensions_value_size() !=
1850 s2.value_tuple().dimensions_value_size()) {
1851 return false;
1852 }
1853 bool allMatched = true;
1854 for (int i = 0; allMatched && i < s1.value_tuple().dimensions_value_size(); ++i) {
1855 allMatched &= EqualsTo(s1.value_tuple().dimensions_value(i),
1856 s2.value_tuple().dimensions_value(i));
1857 }
1858 return allMatched;
1859 }
1860 case DimensionsValue::ValueCase::VALUE_NOT_SET:
1861 default:
1862 return true;
1863 }
1864 }
1865
LessThan(const google::protobuf::RepeatedPtrField<StateValue> & s1,const google::protobuf::RepeatedPtrField<StateValue> & s2)1866 bool LessThan(const google::protobuf::RepeatedPtrField<StateValue>& s1,
1867 const google::protobuf::RepeatedPtrField<StateValue>& s2) {
1868 if (s1.size() != s2.size()) {
1869 return s1.size() < s2.size();
1870 }
1871 for (int i = 0; i < s1.size(); i++) {
1872 const StateValue& state1 = s1[i];
1873 const StateValue& state2 = s2[i];
1874 if (state1.atom_id() != state2.atom_id()) {
1875 return state1.atom_id() < state2.atom_id();
1876 }
1877 if (state1.value() != state2.value()) {
1878 return state1.value() < state2.value();
1879 }
1880 if (state1.group_id() != state2.group_id()) {
1881 return state1.group_id() < state2.group_id();
1882 }
1883 }
1884 return false;
1885 }
1886
LessThan(const DimensionsValue & s1,const DimensionsValue & s2)1887 bool LessThan(const DimensionsValue& s1, const DimensionsValue& s2) {
1888 if (s1.field() != s2.field()) {
1889 return s1.field() < s2.field();
1890 }
1891 if (s1.value_case() != s2.value_case()) {
1892 return s1.value_case() < s2.value_case();
1893 }
1894 switch (s1.value_case()) {
1895 case DimensionsValue::ValueCase::kValueStr:
1896 return s1.value_str() < s2.value_str();
1897 case DimensionsValue::ValueCase::kValueInt:
1898 return s1.value_int() < s2.value_int();
1899 case DimensionsValue::ValueCase::kValueLong:
1900 return s1.value_long() < s2.value_long();
1901 case DimensionsValue::ValueCase::kValueBool:
1902 return (int)s1.value_bool() < (int)s2.value_bool();
1903 case DimensionsValue::ValueCase::kValueFloat:
1904 return s1.value_float() < s2.value_float();
1905 case DimensionsValue::ValueCase::kValueTuple: {
1906 if (s1.value_tuple().dimensions_value_size() !=
1907 s2.value_tuple().dimensions_value_size()) {
1908 return s1.value_tuple().dimensions_value_size() <
1909 s2.value_tuple().dimensions_value_size();
1910 }
1911 for (int i = 0; i < s1.value_tuple().dimensions_value_size(); ++i) {
1912 if (EqualsTo(s1.value_tuple().dimensions_value(i),
1913 s2.value_tuple().dimensions_value(i))) {
1914 continue;
1915 } else {
1916 return LessThan(s1.value_tuple().dimensions_value(i),
1917 s2.value_tuple().dimensions_value(i));
1918 }
1919 }
1920 return false;
1921 }
1922 case DimensionsValue::ValueCase::VALUE_NOT_SET:
1923 default:
1924 return false;
1925 }
1926 }
1927
LessThan(const DimensionsPair & s1,const DimensionsPair & s2)1928 bool LessThan(const DimensionsPair& s1, const DimensionsPair& s2) {
1929 if (LessThan(s1.dimInWhat, s2.dimInWhat)) {
1930 return true;
1931 } else if (LessThan(s2.dimInWhat, s1.dimInWhat)) {
1932 return false;
1933 }
1934
1935 return LessThan(s1.stateValues, s2.stateValues);
1936 }
1937
backfillStringInDimension(const std::map<uint64_t,string> & str_map,DimensionsValue * dimension)1938 void backfillStringInDimension(const std::map<uint64_t, string>& str_map,
1939 DimensionsValue* dimension) {
1940 if (dimension->has_value_str_hash()) {
1941 auto it = str_map.find((uint64_t)(dimension->value_str_hash()));
1942 if (it != str_map.end()) {
1943 dimension->clear_value_str_hash();
1944 dimension->set_value_str(it->second);
1945 } else {
1946 ALOGE("Can not find the string hash: %llu",
1947 (unsigned long long)dimension->value_str_hash());
1948 }
1949 } else if (dimension->has_value_tuple()) {
1950 auto value_tuple = dimension->mutable_value_tuple();
1951 for (int i = 0; i < value_tuple->dimensions_value_size(); ++i) {
1952 backfillStringInDimension(str_map, value_tuple->mutable_dimensions_value(i));
1953 }
1954 }
1955 }
1956
backfillStringInReport(ConfigMetricsReport * config_report)1957 void backfillStringInReport(ConfigMetricsReport *config_report) {
1958 std::map<uint64_t, string> str_map;
1959 for (const auto& str : config_report->strings()) {
1960 uint64_t hash = Hash64(str);
1961 if (str_map.find(hash) != str_map.end()) {
1962 ALOGE("String hash conflicts: %s %s", str.c_str(), str_map[hash].c_str());
1963 }
1964 str_map[hash] = str;
1965 }
1966 for (int i = 0; i < config_report->metrics_size(); ++i) {
1967 auto metric_report = config_report->mutable_metrics(i);
1968 if (metric_report->has_count_metrics()) {
1969 backfillStringInDimension(str_map, metric_report->mutable_count_metrics());
1970 } else if (metric_report->has_duration_metrics()) {
1971 backfillStringInDimension(str_map, metric_report->mutable_duration_metrics());
1972 } else if (metric_report->has_gauge_metrics()) {
1973 backfillStringInDimension(str_map, metric_report->mutable_gauge_metrics());
1974 } else if (metric_report->has_value_metrics()) {
1975 backfillStringInDimension(str_map, metric_report->mutable_value_metrics());
1976 } else if (metric_report->has_kll_metrics()) {
1977 backfillStringInDimension(str_map, metric_report->mutable_kll_metrics());
1978 }
1979 }
1980 // Backfill the package names.
1981 for (int i = 0 ; i < config_report->uid_map().snapshots_size(); ++i) {
1982 auto snapshot = config_report->mutable_uid_map()->mutable_snapshots(i);
1983 for (int j = 0 ; j < snapshot->package_info_size(); ++j) {
1984 auto package_info = snapshot->mutable_package_info(j);
1985 if (package_info->has_name_hash()) {
1986 auto it = str_map.find((uint64_t)(package_info->name_hash()));
1987 if (it != str_map.end()) {
1988 package_info->clear_name_hash();
1989 package_info->set_name(it->second);
1990 } else {
1991 ALOGE("Can not find the string package name hash: %llu",
1992 (unsigned long long)package_info->name_hash());
1993 }
1994
1995 }
1996 }
1997 }
1998 // Backfill the app name in app changes.
1999 for (int i = 0 ; i < config_report->uid_map().changes_size(); ++i) {
2000 auto change = config_report->mutable_uid_map()->mutable_changes(i);
2001 if (change->has_app_hash()) {
2002 auto it = str_map.find((uint64_t)(change->app_hash()));
2003 if (it != str_map.end()) {
2004 change->clear_app_hash();
2005 change->set_app(it->second);
2006 } else {
2007 ALOGE("Can not find the string change app name hash: %llu",
2008 (unsigned long long)change->app_hash());
2009 }
2010 }
2011 }
2012 }
2013
backfillStringInReport(ConfigMetricsReportList * config_report_list)2014 void backfillStringInReport(ConfigMetricsReportList *config_report_list) {
2015 for (int i = 0; i < config_report_list->reports_size(); ++i) {
2016 backfillStringInReport(config_report_list->mutable_reports(i));
2017 }
2018 }
2019
backfillDimensionPath(const DimensionsValue & path,const google::protobuf::RepeatedPtrField<DimensionsValue> & leafValues,int * leafIndex,DimensionsValue * dimension)2020 bool backfillDimensionPath(const DimensionsValue& path,
2021 const google::protobuf::RepeatedPtrField<DimensionsValue>& leafValues,
2022 int* leafIndex, DimensionsValue* dimension) {
2023 dimension->set_field(path.field());
2024 if (path.has_value_tuple()) {
2025 for (int i = 0; i < path.value_tuple().dimensions_value_size(); ++i) {
2026 if (!backfillDimensionPath(path.value_tuple().dimensions_value(i), leafValues,
2027 leafIndex,
2028 dimension->mutable_value_tuple()->add_dimensions_value())) {
2029 return false;
2030 }
2031 }
2032 } else {
2033 if (*leafIndex < 0 || *leafIndex >= leafValues.size()) {
2034 return false;
2035 }
2036 dimension->MergeFrom(leafValues.Get(*leafIndex));
2037 (*leafIndex)++;
2038 }
2039 return true;
2040 }
2041
backfillDimensionPath(const DimensionsValue & path,const google::protobuf::RepeatedPtrField<DimensionsValue> & leafValues,DimensionsValue * dimension)2042 bool backfillDimensionPath(const DimensionsValue& path,
2043 const google::protobuf::RepeatedPtrField<DimensionsValue>& leafValues,
2044 DimensionsValue* dimension) {
2045 int leafIndex = 0;
2046 return backfillDimensionPath(path, leafValues, &leafIndex, dimension);
2047 }
2048
backfillDimensionPath(StatsLogReport * report)2049 void backfillDimensionPath(StatsLogReport* report) {
2050 if (report->has_dimensions_path_in_what()) {
2051 auto whatPath = report->dimensions_path_in_what();
2052 if (report->has_count_metrics()) {
2053 backfillDimensionPath(whatPath, report->mutable_count_metrics());
2054 } else if (report->has_duration_metrics()) {
2055 backfillDimensionPath(whatPath, report->mutable_duration_metrics());
2056 } else if (report->has_gauge_metrics()) {
2057 backfillDimensionPath(whatPath, report->mutable_gauge_metrics());
2058 } else if (report->has_value_metrics()) {
2059 backfillDimensionPath(whatPath, report->mutable_value_metrics());
2060 } else if (report->has_kll_metrics()) {
2061 backfillDimensionPath(whatPath, report->mutable_kll_metrics());
2062 }
2063 report->clear_dimensions_path_in_what();
2064 }
2065 }
2066
backfillDimensionPath(ConfigMetricsReport * config_report)2067 void backfillDimensionPath(ConfigMetricsReport* config_report) {
2068 for (int i = 0; i < config_report->metrics_size(); ++i) {
2069 backfillDimensionPath(config_report->mutable_metrics(i));
2070 }
2071 }
2072
backfillDimensionPath(ConfigMetricsReportList * config_report_list)2073 void backfillDimensionPath(ConfigMetricsReportList* config_report_list) {
2074 for (int i = 0; i < config_report_list->reports_size(); ++i) {
2075 backfillDimensionPath(config_report_list->mutable_reports(i));
2076 }
2077 }
2078
backfillStartEndTimestamp(StatsLogReport * report)2079 void backfillStartEndTimestamp(StatsLogReport *report) {
2080 const int64_t timeBaseNs = report->time_base_elapsed_nano_seconds();
2081 const int64_t bucketSizeNs = report->bucket_size_nano_seconds();
2082 if (report->has_count_metrics()) {
2083 backfillStartEndTimestampForMetrics(
2084 timeBaseNs, bucketSizeNs, report->mutable_count_metrics());
2085 } else if (report->has_duration_metrics()) {
2086 backfillStartEndTimestampForMetrics(
2087 timeBaseNs, bucketSizeNs, report->mutable_duration_metrics());
2088 } else if (report->has_gauge_metrics()) {
2089 backfillStartEndTimestampForMetrics(
2090 timeBaseNs, bucketSizeNs, report->mutable_gauge_metrics());
2091 if (report->gauge_metrics().skipped_size() > 0) {
2092 backfillStartEndTimestampForSkippedBuckets(
2093 timeBaseNs, report->mutable_gauge_metrics());
2094 }
2095 } else if (report->has_value_metrics()) {
2096 backfillStartEndTimestampForMetrics(
2097 timeBaseNs, bucketSizeNs, report->mutable_value_metrics());
2098 if (report->value_metrics().skipped_size() > 0) {
2099 backfillStartEndTimestampForSkippedBuckets(
2100 timeBaseNs, report->mutable_value_metrics());
2101 }
2102 } else if (report->has_kll_metrics()) {
2103 backfillStartEndTimestampForMetrics(timeBaseNs, bucketSizeNs,
2104 report->mutable_kll_metrics());
2105 if (report->kll_metrics().skipped_size() > 0) {
2106 backfillStartEndTimestampForSkippedBuckets(timeBaseNs, report->mutable_kll_metrics());
2107 }
2108 }
2109 }
2110
backfillStartEndTimestamp(ConfigMetricsReport * config_report)2111 void backfillStartEndTimestamp(ConfigMetricsReport *config_report) {
2112 for (int j = 0; j < config_report->metrics_size(); ++j) {
2113 backfillStartEndTimestamp(config_report->mutable_metrics(j));
2114 }
2115 }
2116
backfillStartEndTimestamp(ConfigMetricsReportList * config_report_list)2117 void backfillStartEndTimestamp(ConfigMetricsReportList *config_report_list) {
2118 for (int i = 0; i < config_report_list->reports_size(); ++i) {
2119 backfillStartEndTimestamp(config_report_list->mutable_reports(i));
2120 }
2121 }
2122
backfillAggregatedAtoms(ConfigMetricsReportList * config_report_list)2123 void backfillAggregatedAtoms(ConfigMetricsReportList* config_report_list) {
2124 for (int i = 0; i < config_report_list->reports_size(); ++i) {
2125 backfillAggregatedAtoms(config_report_list->mutable_reports(i));
2126 }
2127 }
2128
backfillAggregatedAtoms(ConfigMetricsReport * config_report)2129 void backfillAggregatedAtoms(ConfigMetricsReport* config_report) {
2130 for (int i = 0; i < config_report->metrics_size(); ++i) {
2131 backfillAggregatedAtoms(config_report->mutable_metrics(i));
2132 }
2133 }
2134
backfillAggregatedAtoms(StatsLogReport * report)2135 void backfillAggregatedAtoms(StatsLogReport* report) {
2136 if (report->has_event_metrics()) {
2137 backfillAggregatedAtomsInEventMetric(report->mutable_event_metrics());
2138 }
2139 if (report->has_gauge_metrics()) {
2140 backfillAggregatedAtomsInGaugeMetric(report->mutable_gauge_metrics());
2141 }
2142 }
2143
backfillAggregatedAtomsInEventMetric(StatsLogReport::EventMetricDataWrapper * wrapper)2144 void backfillAggregatedAtomsInEventMetric(StatsLogReport::EventMetricDataWrapper* wrapper) {
2145 std::vector<EventMetricData> metricData;
2146 for (int i = 0; i < wrapper->data_size(); ++i) {
2147 AggregatedAtomInfo* atomInfo = wrapper->mutable_data(i)->mutable_aggregated_atom_info();
2148 for (int j = 0; j < atomInfo->elapsed_timestamp_nanos_size(); j++) {
2149 EventMetricData data;
2150 *(data.mutable_atom()) = atomInfo->atom();
2151 data.set_elapsed_timestamp_nanos(atomInfo->elapsed_timestamp_nanos(j));
2152 metricData.push_back(data);
2153 }
2154 }
2155
2156 if (metricData.size() == 0) {
2157 return;
2158 }
2159
2160 sort(metricData.begin(), metricData.end(),
2161 [](const EventMetricData& lhs, const EventMetricData& rhs) {
2162 return lhs.elapsed_timestamp_nanos() < rhs.elapsed_timestamp_nanos();
2163 });
2164
2165 wrapper->clear_data();
2166 for (int i = 0; i < metricData.size(); ++i) {
2167 *(wrapper->add_data()) = metricData[i];
2168 }
2169 }
2170
backfillAggregatedAtomsInGaugeMetric(StatsLogReport::GaugeMetricDataWrapper * wrapper)2171 void backfillAggregatedAtomsInGaugeMetric(StatsLogReport::GaugeMetricDataWrapper* wrapper) {
2172 for (int i = 0; i < wrapper->data_size(); ++i) {
2173 for (int j = 0; j < wrapper->data(i).bucket_info_size(); ++j) {
2174 GaugeBucketInfo* bucketInfo = wrapper->mutable_data(i)->mutable_bucket_info(j);
2175 vector<pair<Atom, int64_t>> atomData = unnestGaugeAtomData(*bucketInfo);
2176
2177 if (atomData.size() == 0) {
2178 return;
2179 }
2180
2181 bucketInfo->clear_aggregated_atom_info();
2182 ASSERT_EQ(bucketInfo->atom_size(), 0);
2183 ASSERT_EQ(bucketInfo->elapsed_timestamp_nanos_size(), 0);
2184
2185 for (int k = 0; k < atomData.size(); ++k) {
2186 *(bucketInfo->add_atom()) = atomData[k].first;
2187 bucketInfo->add_elapsed_timestamp_nanos(atomData[k].second);
2188 }
2189 }
2190 }
2191 }
2192
unnestGaugeAtomData(const GaugeBucketInfo & bucketInfo)2193 vector<pair<Atom, int64_t>> unnestGaugeAtomData(const GaugeBucketInfo& bucketInfo) {
2194 vector<pair<Atom, int64_t>> atomData;
2195 for (int k = 0; k < bucketInfo.aggregated_atom_info_size(); ++k) {
2196 const AggregatedAtomInfo& atomInfo = bucketInfo.aggregated_atom_info(k);
2197 for (int l = 0; l < atomInfo.elapsed_timestamp_nanos_size(); ++l) {
2198 atomData.push_back(make_pair(atomInfo.atom(), atomInfo.elapsed_timestamp_nanos(l)));
2199 }
2200 }
2201
2202 sort(atomData.begin(), atomData.end(),
2203 [](const pair<Atom, int64_t>& lhs, const pair<Atom, int64_t>& rhs) {
2204 return lhs.second < rhs.second;
2205 });
2206
2207 return atomData;
2208 }
2209
sortReportsByElapsedTime(ConfigMetricsReportList * configReportList)2210 void sortReportsByElapsedTime(ConfigMetricsReportList* configReportList) {
2211 RepeatedPtrField<ConfigMetricsReport>* reports = configReportList->mutable_reports();
2212 sort(reports->pointer_begin(), reports->pointer_end(),
2213 [](const ConfigMetricsReport* lhs, const ConfigMetricsReport* rhs) {
2214 return lhs->current_report_elapsed_nanos() < rhs->current_report_elapsed_nanos();
2215 });
2216 }
2217
onPullAtom(int atomTag,const shared_ptr<IPullAtomResultReceiver> & resultReceiver)2218 Status FakeSubsystemSleepCallback::onPullAtom(int atomTag,
2219 const shared_ptr<IPullAtomResultReceiver>& resultReceiver) {
2220 // Convert stats_events into StatsEventParcels.
2221 std::vector<StatsEventParcel> parcels;
2222 for (int i = 1; i < 3; i++) {
2223 AStatsEvent* event = AStatsEvent_obtain();
2224 AStatsEvent_setAtomId(event, atomTag);
2225 std::string subsystemName = "subsystem_name_";
2226 subsystemName = subsystemName + std::to_string(i);
2227 AStatsEvent_writeString(event, subsystemName.c_str());
2228 AStatsEvent_writeString(event, "subsystem_subname foo");
2229 AStatsEvent_writeInt64(event, /*count= */ i);
2230 AStatsEvent_writeInt64(event, /*time_millis= */ pullNum * pullNum * 100 + i);
2231 AStatsEvent_build(event);
2232 size_t size;
2233 uint8_t* buffer = AStatsEvent_getBuffer(event, &size);
2234
2235 StatsEventParcel p;
2236 // vector.assign() creates a copy, but this is inevitable unless
2237 // stats_event.h/c uses a vector as opposed to a buffer.
2238 p.buffer.assign(buffer, buffer + size);
2239 parcels.push_back(std::move(p));
2240 AStatsEvent_release(event);
2241 }
2242 pullNum++;
2243 resultReceiver->pullFinished(atomTag, /*success=*/true, parcels);
2244 return Status::ok();
2245 }
2246
writeFlag(const string & flagName,const string & flagValue)2247 void writeFlag(const string& flagName, const string& flagValue) {
2248 SetProperty(StringPrintf("persist.device_config.%s.%s", STATSD_NATIVE_NAMESPACE.c_str(),
2249 flagName.c_str()),
2250 flagValue);
2251 }
2252
writeBootFlag(const string & flagName,const string & flagValue)2253 void writeBootFlag(const string& flagName, const string& flagValue) {
2254 SetProperty(StringPrintf("persist.device_config.%s.%s", STATSD_NATIVE_BOOT_NAMESPACE.c_str(),
2255 flagName.c_str()),
2256 flagValue);
2257 }
2258
getPackageInfoSnapshot(const sp<UidMap> uidMap)2259 PackageInfoSnapshot getPackageInfoSnapshot(const sp<UidMap> uidMap) {
2260 ProtoOutputStream protoOutputStream;
2261 uidMap->writeUidMapSnapshot(/* timestamp */ 1,
2262 {/* includeVersionStrings */ true,
2263 /* includeInstaller */ true, /* certificateHashSize */ UINT8_MAX,
2264 /* omitSystemUids */ false},
2265 /* interestingUids */ {},
2266 /* installerIndices */ nullptr, /* str_set */ nullptr,
2267 &protoOutputStream);
2268
2269 PackageInfoSnapshot packageInfoSnapshot;
2270 outputStreamToProto(&protoOutputStream, &packageInfoSnapshot);
2271 return packageInfoSnapshot;
2272 }
2273
buildPackageInfo(const string & name,const int32_t uid,const int64_t version,const string & versionString,const optional<string> installer,const vector<uint8_t> & certHash,const bool deleted,const bool hashStrings,const optional<uint32_t> installerIndex)2274 PackageInfo buildPackageInfo(const string& name, const int32_t uid, const int64_t version,
2275 const string& versionString, const optional<string> installer,
2276 const vector<uint8_t>& certHash, const bool deleted,
2277 const bool hashStrings, const optional<uint32_t> installerIndex) {
2278 PackageInfo packageInfo;
2279 packageInfo.set_version(version);
2280 packageInfo.set_uid(uid);
2281 packageInfo.set_deleted(deleted);
2282 if (!certHash.empty()) {
2283 packageInfo.set_truncated_certificate_hash(certHash.data(), certHash.size());
2284 }
2285 if (hashStrings) {
2286 packageInfo.set_name_hash(Hash64(name));
2287 packageInfo.set_version_string_hash(Hash64(versionString));
2288 } else {
2289 packageInfo.set_name(name);
2290 packageInfo.set_version_string(versionString);
2291 }
2292 if (installer) {
2293 if (installerIndex) {
2294 packageInfo.set_installer_index(*installerIndex);
2295 } else if (hashStrings) {
2296 packageInfo.set_installer_hash(Hash64(*installer));
2297 } else {
2298 packageInfo.set_installer(*installer);
2299 }
2300 }
2301 return packageInfo;
2302 }
2303
buildPackageInfos(const vector<string> & names,const vector<int32_t> & uids,const vector<int64_t> & versions,const vector<string> & versionStrings,const vector<string> & installers,const vector<vector<uint8_t>> & certHashes,const vector<uint8_t> & deleted,const vector<uint32_t> & installerIndices,const bool hashStrings)2304 vector<PackageInfo> buildPackageInfos(
2305 const vector<string>& names, const vector<int32_t>& uids, const vector<int64_t>& versions,
2306 const vector<string>& versionStrings, const vector<string>& installers,
2307 const vector<vector<uint8_t>>& certHashes, const vector<uint8_t>& deleted,
2308 const vector<uint32_t>& installerIndices, const bool hashStrings) {
2309 vector<PackageInfo> packageInfos;
2310 for (int i = 0; i < uids.size(); i++) {
2311 const optional<uint32_t> installerIndex =
2312 installerIndices.empty() ? nullopt : optional<uint32_t>(installerIndices[i]);
2313 const optional<string> installer =
2314 installers.empty() ? nullopt : optional<string>(installers[i]);
2315 vector<uint8_t> certHash;
2316 if (!certHashes.empty()) {
2317 certHash = certHashes[i];
2318 }
2319 packageInfos.emplace_back(buildPackageInfo(names[i], uids[i], versions[i],
2320 versionStrings[i], installer, certHash,
2321 deleted[i], hashStrings, installerIndex));
2322 }
2323 return packageInfos;
2324 }
2325
createApplicationInfo(const int32_t uid,const int64_t version,const string & versionString,const string & package)2326 ApplicationInfo createApplicationInfo(const int32_t uid, const int64_t version,
2327 const string& versionString, const string& package) {
2328 ApplicationInfo info;
2329 info.set_uid(uid);
2330 info.set_version(version);
2331 info.set_version_string(versionString);
2332 info.set_package_name(package);
2333 return info;
2334 }
2335
getPulledAtomStats(int32_t atom_id)2336 StatsdStatsReport_PulledAtomStats getPulledAtomStats(int32_t atom_id) {
2337 StatsdStatsReport statsReport = getStatsdStatsReport();
2338 StatsdStatsReport_PulledAtomStats pulledAtomStats;
2339 for (size_t i = 0; i < statsReport.pulled_atom_stats_size(); i++) {
2340 if (statsReport.pulled_atom_stats(i).atom_id() == atom_id) {
2341 return statsReport.pulled_atom_stats(i);
2342 }
2343 }
2344 return pulledAtomStats;
2345 }
2346
createStatsEvent(AStatsEvent * statsEvent,uint8_t typeId,uint32_t atomId)2347 void createStatsEvent(AStatsEvent* statsEvent, uint8_t typeId, uint32_t atomId) {
2348 AStatsEvent_setAtomId(statsEvent, atomId);
2349 fillStatsEventWithSampleValue(statsEvent, typeId);
2350 }
2351
fillStatsEventWithSampleValue(AStatsEvent * statsEvent,uint8_t typeId)2352 void fillStatsEventWithSampleValue(AStatsEvent* statsEvent, uint8_t typeId) {
2353 int int32Array[2] = {3, 6};
2354 uint32_t uids[] = {1001, 1002};
2355 const char* tags[] = {"tag1", "tag2"};
2356
2357 switch (typeId) {
2358 case INT32_TYPE:
2359 AStatsEvent_writeInt32(statsEvent, 10);
2360 break;
2361 case INT64_TYPE:
2362 AStatsEvent_writeInt64(statsEvent, 1000L);
2363 break;
2364 case STRING_TYPE:
2365 AStatsEvent_writeString(statsEvent, "test");
2366 break;
2367 case LIST_TYPE:
2368 if (__builtin_available(android __ANDROID_API_T__, *)) {
2369 /* CAUTION: when using this function with LIST_TYPE,
2370 wrap the code in a __builtin_available or __INTRODUCED_IN w/ T.
2371 */
2372 AStatsEvent_writeInt32Array(statsEvent, int32Array, 2);
2373 } else {
2374 ADD_FAILURE() << "fillStatsEventWithSampleValue() w/ typeId LIST_TYPE should only "
2375 "be used on Android T or above.";
2376 }
2377 break;
2378 case FLOAT_TYPE:
2379 AStatsEvent_writeFloat(statsEvent, 1.3f);
2380 break;
2381 case BOOL_TYPE:
2382 AStatsEvent_writeBool(statsEvent, 1);
2383 break;
2384 case BYTE_ARRAY_TYPE:
2385 AStatsEvent_writeByteArray(statsEvent, (uint8_t*)"test", strlen("test"));
2386 break;
2387 case ATTRIBUTION_CHAIN_TYPE:
2388 AStatsEvent_writeAttributionChain(statsEvent, uids, tags, 2);
2389 break;
2390 default:
2391 break;
2392 }
2393 }
2394
getStatsdStatsReport(bool resetStats)2395 StatsdStatsReport getStatsdStatsReport(bool resetStats) {
2396 StatsdStats& stats = StatsdStats::getInstance();
2397 return getStatsdStatsReport(stats, resetStats);
2398 }
2399
getStatsdStatsReport(StatsdStats & stats,bool resetStats)2400 StatsdStatsReport getStatsdStatsReport(StatsdStats& stats, bool resetStats) {
2401 vector<uint8_t> statsBuffer;
2402 stats.dumpStats(&statsBuffer, resetStats);
2403 StatsdStatsReport statsReport;
2404 EXPECT_TRUE(statsReport.ParseFromArray(statsBuffer.data(), statsBuffer.size()));
2405 return statsReport;
2406 }
2407
buildGoodConfig(int configId)2408 StatsdConfig buildGoodConfig(int configId) {
2409 StatsdConfig config;
2410 config.set_id(configId);
2411
2412 AtomMatcher screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
2413 *config.add_atom_matcher() = screenOnMatcher;
2414 *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
2415
2416 AtomMatcher* eventMatcher = config.add_atom_matcher();
2417 eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF"));
2418 AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
2419 combination->set_operation(LogicalOperation::OR);
2420 combination->add_matcher(screenOnMatcher.id());
2421 combination->add_matcher(StringToId("ScreenTurnedOff"));
2422
2423 CountMetric* countMetric = config.add_count_metric();
2424 *countMetric = createCountMetric("Count", screenOnMatcher.id() /* what */,
2425 nullopt /* condition */, {} /* states */);
2426 countMetric->mutable_dimensions_in_what()->set_field(SCREEN_STATE_ATOM_ID);
2427 countMetric->mutable_dimensions_in_what()->add_child()->set_field(1);
2428
2429 config.add_no_report_metric(StringToId("Count"));
2430
2431 *config.add_predicate() = CreateScreenIsOnPredicate();
2432 *config.add_duration_metric() =
2433 createDurationMetric("Duration", StringToId("ScreenIsOn") /* what */,
2434 nullopt /* condition */, {} /* states */);
2435
2436 *config.add_gauge_metric() = createGaugeMetric(
2437 "Gauge", screenOnMatcher.id() /* what */, GaugeMetric_SamplingType_FIRST_N_SAMPLES,
2438 nullopt /* condition */, nullopt /* triggerEvent */);
2439
2440 *config.add_value_metric() =
2441 createValueMetric("Value", screenOnMatcher /* what */, 2 /* valueField */,
2442 nullopt /* condition */, {} /* states */);
2443
2444 *config.add_kll_metric() = createKllMetric("Kll", screenOnMatcher /* what */, 2 /* kllField */,
2445 nullopt /* condition */);
2446
2447 return config;
2448 }
2449
buildGoodConfig(int configId,int alertId)2450 StatsdConfig buildGoodConfig(int configId, int alertId) {
2451 StatsdConfig config = buildGoodConfig(configId);
2452 auto alert = config.add_alert();
2453 alert->set_id(alertId);
2454 alert->set_metric_id(StringToId("Count"));
2455 alert->set_num_buckets(10);
2456 alert->set_refractory_period_secs(100);
2457 alert->set_trigger_if_sum_gt(100);
2458
2459 return config;
2460 }
2461
makeMockConfigMetadataProvider(bool enabled)2462 sp<MockConfigMetadataProvider> makeMockConfigMetadataProvider(bool enabled) {
2463 sp<MockConfigMetadataProvider> metadataProvider = new StrictMock<MockConfigMetadataProvider>();
2464 EXPECT_CALL(*metadataProvider, useV2SoftMemoryCalculation()).Times(AnyNumber());
2465 EXPECT_CALL(*metadataProvider, useV2SoftMemoryCalculation()).WillRepeatedly(Return(enabled));
2466 return nullptr;
2467 }
2468
createSocketLossInfo(int32_t uid,int32_t atomId)2469 SocketLossInfo createSocketLossInfo(int32_t uid, int32_t atomId) {
2470 SocketLossInfo lossInfo;
2471 lossInfo.uid = uid;
2472 lossInfo.errors.push_back(-11);
2473 lossInfo.atomIds.push_back(atomId);
2474 lossInfo.counts.push_back(1);
2475 return lossInfo;
2476 }
2477
createSocketLossInfoLogEvent(int32_t uid,int32_t lossAtomId)2478 std::unique_ptr<LogEvent> createSocketLossInfoLogEvent(int32_t uid, int32_t lossAtomId) {
2479 const SocketLossInfo lossInfo = createSocketLossInfo(uid, lossAtomId);
2480
2481 AStatsEvent* statsEvent = AStatsEvent_obtain();
2482 AStatsEvent_setAtomId(statsEvent, util::STATS_SOCKET_LOSS_REPORTED);
2483 AStatsEvent_writeInt32(statsEvent, lossInfo.uid);
2484 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
2485 AStatsEvent_writeInt64(statsEvent, lossInfo.firstLossTsNanos);
2486 AStatsEvent_writeInt64(statsEvent, lossInfo.lastLossTsNanos);
2487 AStatsEvent_writeInt32(statsEvent, lossInfo.overflowCounter);
2488 AStatsEvent_writeInt32Array(statsEvent, lossInfo.errors.data(), lossInfo.errors.size());
2489 AStatsEvent_writeInt32Array(statsEvent, lossInfo.atomIds.data(), lossInfo.atomIds.size());
2490 AStatsEvent_writeInt32Array(statsEvent, lossInfo.counts.data(), lossInfo.counts.size());
2491
2492 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(uid /* uid */, 0 /* pid */);
2493 parseStatsEventToLogEvent(statsEvent, logEvent.get());
2494 return logEvent;
2495 }
2496
2497 } // namespace statsd
2498 } // namespace os
2499 } // namespace android
2500