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,const vector<int64_t> & states)539 EventMetric createEventMetric(const string& name, const int64_t what,
540 const optional<int64_t>& condition, const vector<int64_t>& states) {
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 for (const int64_t state : states) {
548 metric.add_slice_by_state(state);
549 }
550 return metric;
551 }
552
createCountMetric(const string & name,const int64_t what,const optional<int64_t> & condition,const vector<int64_t> & states)553 CountMetric createCountMetric(const string& name, const int64_t what,
554 const optional<int64_t>& condition, const vector<int64_t>& states) {
555 CountMetric metric;
556 metric.set_id(StringToId(name));
557 metric.set_what(what);
558 metric.set_bucket(TEN_MINUTES);
559 if (condition) {
560 metric.set_condition(condition.value());
561 }
562 for (const int64_t state : states) {
563 metric.add_slice_by_state(state);
564 }
565 return metric;
566 }
567
createDurationMetric(const string & name,const int64_t what,const optional<int64_t> & condition,const vector<int64_t> & states)568 DurationMetric createDurationMetric(const string& name, const int64_t what,
569 const optional<int64_t>& condition,
570 const vector<int64_t>& states) {
571 DurationMetric metric;
572 metric.set_id(StringToId(name));
573 metric.set_what(what);
574 metric.set_bucket(TEN_MINUTES);
575 if (condition) {
576 metric.set_condition(condition.value());
577 }
578 for (const int64_t state : states) {
579 metric.add_slice_by_state(state);
580 }
581 return metric;
582 }
583
createGaugeMetric(const string & name,const int64_t what,const GaugeMetric::SamplingType samplingType,const optional<int64_t> & condition,const optional<int64_t> & triggerEvent,const vector<int64_t> & states)584 GaugeMetric createGaugeMetric(const string& name, const int64_t what,
585 const GaugeMetric::SamplingType samplingType,
586 const optional<int64_t>& condition,
587 const optional<int64_t>& triggerEvent,
588 const vector<int64_t>& states) {
589 GaugeMetric metric;
590 metric.set_id(StringToId(name));
591 metric.set_what(what);
592 metric.set_bucket(TEN_MINUTES);
593 metric.set_sampling_type(samplingType);
594 if (condition) {
595 metric.set_condition(condition.value());
596 }
597 if (triggerEvent) {
598 metric.set_trigger_event(triggerEvent.value());
599 }
600 for (const int64_t state : states) {
601 metric.add_slice_by_state(state);
602 }
603 return metric;
604 }
605
createValueMetric(const string & name,const AtomMatcher & what,const int valueField,const optional<int64_t> & condition,const vector<int64_t> & states)606 ValueMetric createValueMetric(const string& name, const AtomMatcher& what, const int valueField,
607 const optional<int64_t>& condition, const vector<int64_t>& states) {
608 return createValueMetric(name, what, {valueField}, /* aggregationTypes */ {}, condition,
609 states);
610 }
611
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)612 ValueMetric createValueMetric(const string& name, const AtomMatcher& what,
613 const vector<int>& valueFields,
614 const vector<ValueMetric::AggregationType>& aggregationTypes,
615 const optional<int64_t>& condition, const vector<int64_t>& states) {
616 ValueMetric metric;
617 metric.set_id(StringToId(name));
618 metric.set_what(what.id());
619 metric.set_bucket(TEN_MINUTES);
620 metric.mutable_value_field()->set_field(what.simple_atom_matcher().atom_id());
621 for (int valueField : valueFields) {
622 metric.mutable_value_field()->add_child()->set_field(valueField);
623 }
624 for (const ValueMetric::AggregationType aggType : aggregationTypes) {
625 metric.add_aggregation_types(aggType);
626 }
627 if (condition) {
628 metric.set_condition(condition.value());
629 }
630 for (const int64_t state : states) {
631 metric.add_slice_by_state(state);
632 }
633 return metric;
634 }
635
createGeneratedBinConfig(int id,float min,float max,int count,HistogramBinConfig::GeneratedBins::Strategy strategy)636 HistogramBinConfig createGeneratedBinConfig(int id, float min, float max, int count,
637 HistogramBinConfig::GeneratedBins::Strategy strategy) {
638 HistogramBinConfig binConfig;
639 binConfig.set_id(id);
640 binConfig.mutable_generated_bins()->set_min(min);
641 binConfig.mutable_generated_bins()->set_max(max);
642 binConfig.mutable_generated_bins()->set_count(count);
643 binConfig.mutable_generated_bins()->set_strategy(strategy);
644 return binConfig;
645 }
646
createExplicitBinConfig(int id,const vector<float> & bins)647 HistogramBinConfig createExplicitBinConfig(int id, const vector<float>& bins) {
648 HistogramBinConfig binConfig;
649 binConfig.set_id(id);
650 *binConfig.mutable_explicit_bins()->mutable_bin() = {bins.begin(), bins.end()};
651 return binConfig;
652 }
653
createKllMetric(const string & name,const AtomMatcher & what,const int kllField,const optional<int64_t> & condition)654 KllMetric createKllMetric(const string& name, const AtomMatcher& what, const int kllField,
655 const optional<int64_t>& condition) {
656 KllMetric metric;
657 metric.set_id(StringToId(name));
658 metric.set_what(what.id());
659 metric.set_bucket(TEN_MINUTES);
660 metric.mutable_kll_field()->set_field(what.simple_atom_matcher().atom_id());
661 metric.mutable_kll_field()->add_child()->set_field(kllField);
662 if (condition) {
663 metric.set_condition(condition.value());
664 }
665 return metric;
666 }
667
createAlert(const string & name,const int64_t metricId,const int buckets,const int64_t triggerSum)668 Alert createAlert(const string& name, const int64_t metricId, const int buckets,
669 const int64_t triggerSum) {
670 Alert alert;
671 alert.set_id(StringToId(name));
672 alert.set_metric_id(metricId);
673 alert.set_num_buckets(buckets);
674 alert.set_trigger_if_sum_gt(triggerSum);
675 return alert;
676 }
677
createAlarm(const string & name,const int64_t offsetMillis,const int64_t periodMillis)678 Alarm createAlarm(const string& name, const int64_t offsetMillis, const int64_t periodMillis) {
679 Alarm alarm;
680 alarm.set_id(StringToId(name));
681 alarm.set_offset_millis(offsetMillis);
682 alarm.set_period_millis(periodMillis);
683 return alarm;
684 }
685
createSubscription(const string & name,const Subscription_RuleType type,const int64_t ruleId)686 Subscription createSubscription(const string& name, const Subscription_RuleType type,
687 const int64_t ruleId) {
688 Subscription subscription;
689 subscription.set_id(StringToId(name));
690 subscription.set_rule_type(type);
691 subscription.set_rule_id(ruleId);
692 subscription.mutable_broadcast_subscriber_details();
693 return subscription;
694 }
695
696 // START: get primary key functions
getUidProcessKey(int uid,HashableDimensionKey * key)697 void getUidProcessKey(int uid, HashableDimensionKey* key) {
698 int pos1[] = {1, 0, 0};
699 Field field1(27 /* atom id */, pos1, 0 /* depth */);
700 Value value1((int32_t)uid);
701
702 key->addValue(FieldValue(field1, value1));
703 }
704
getOverlayKey(int uid,string packageName,HashableDimensionKey * key)705 void getOverlayKey(int uid, string packageName, HashableDimensionKey* key) {
706 int pos1[] = {1, 0, 0};
707 int pos2[] = {2, 0, 0};
708
709 Field field1(59 /* atom id */, pos1, 0 /* depth */);
710 Field field2(59 /* atom id */, pos2, 0 /* depth */);
711
712 Value value1((int32_t)uid);
713 Value value2(packageName);
714
715 key->addValue(FieldValue(field1, value1));
716 key->addValue(FieldValue(field2, value2));
717 }
718
getPartialWakelockKey(int uid,const std::string & tag,HashableDimensionKey * key)719 void getPartialWakelockKey(int uid, const std::string& tag, HashableDimensionKey* key) {
720 int pos1[] = {1, 1, 1};
721 int pos3[] = {2, 0, 0};
722 int pos4[] = {3, 0, 0};
723
724 Field field1(10 /* atom id */, pos1, 2 /* depth */);
725
726 Field field3(10 /* atom id */, pos3, 0 /* depth */);
727 Field field4(10 /* atom id */, pos4, 0 /* depth */);
728
729 Value value1((int32_t)uid);
730 Value value3((int32_t)1 /*partial*/);
731 Value value4(tag);
732
733 key->addValue(FieldValue(field1, value1));
734 key->addValue(FieldValue(field3, value3));
735 key->addValue(FieldValue(field4, value4));
736 }
737
getPartialWakelockKey(int uid,HashableDimensionKey * key)738 void getPartialWakelockKey(int uid, HashableDimensionKey* key) {
739 int pos1[] = {1, 1, 1};
740 int pos3[] = {2, 0, 0};
741
742 Field field1(10 /* atom id */, pos1, 2 /* depth */);
743 Field field3(10 /* atom id */, pos3, 0 /* depth */);
744
745 Value value1((int32_t)uid);
746 Value value3((int32_t)1 /*partial*/);
747
748 key->addValue(FieldValue(field1, value1));
749 key->addValue(FieldValue(field3, value3));
750 }
751 // END: get primary key functions
752
writeAttribution(AStatsEvent * statsEvent,const vector<int> & attributionUids,const vector<string> & attributionTags)753 void writeAttribution(AStatsEvent* statsEvent, const vector<int>& attributionUids,
754 const vector<string>& attributionTags) {
755 vector<const char*> cTags(attributionTags.size());
756 for (int i = 0; i < cTags.size(); i++) {
757 cTags[i] = attributionTags[i].c_str();
758 }
759
760 AStatsEvent_writeAttributionChain(statsEvent,
761 reinterpret_cast<const uint32_t*>(attributionUids.data()),
762 cTags.data(), attributionUids.size());
763 }
764
parseStatsEventToLogEvent(AStatsEvent * statsEvent,LogEvent * logEvent)765 bool parseStatsEventToLogEvent(AStatsEvent* statsEvent, LogEvent* logEvent) {
766 AStatsEvent_build(statsEvent);
767
768 size_t size;
769 uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
770 const bool result = logEvent->parseBuffer(buf, size);
771
772 AStatsEvent_release(statsEvent);
773
774 return result;
775 }
776
makeTwoValueStatsEvent(int atomId,int64_t eventTimeNs,int32_t value1,int32_t value2)777 AStatsEvent* makeTwoValueStatsEvent(int atomId, int64_t eventTimeNs, int32_t value1,
778 int32_t value2) {
779 AStatsEvent* statsEvent = AStatsEvent_obtain();
780 AStatsEvent_setAtomId(statsEvent, atomId);
781 AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
782
783 AStatsEvent_writeInt32(statsEvent, value1);
784 AStatsEvent_writeInt32(statsEvent, value2);
785
786 return statsEvent;
787 }
788
CreateTwoValueLogEvent(LogEvent * logEvent,int atomId,int64_t eventTimeNs,int32_t value1,int32_t value2)789 void CreateTwoValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs, int32_t value1,
790 int32_t value2) {
791 AStatsEvent* statsEvent = makeTwoValueStatsEvent(atomId, eventTimeNs, value1, value2);
792 parseStatsEventToLogEvent(statsEvent, logEvent);
793 }
794
CreateTwoValueLogEvent(int atomId,int64_t eventTimeNs,int32_t value1,int32_t value2)795 shared_ptr<LogEvent> CreateTwoValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1,
796 int32_t value2) {
797 shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
798 CreateTwoValueLogEvent(logEvent.get(), atomId, eventTimeNs, value1, value2);
799 return logEvent;
800 }
801
CreateThreeValueLogEvent(LogEvent * logEvent,int atomId,int64_t eventTimeNs,int32_t value1,int32_t value2,int32_t value3)802 void CreateThreeValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs, int32_t value1,
803 int32_t value2, int32_t value3) {
804 AStatsEvent* statsEvent = AStatsEvent_obtain();
805 AStatsEvent_setAtomId(statsEvent, atomId);
806 AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
807
808 AStatsEvent_writeInt32(statsEvent, value1);
809 AStatsEvent_writeInt32(statsEvent, value2);
810 AStatsEvent_writeInt32(statsEvent, value3);
811
812 parseStatsEventToLogEvent(statsEvent, logEvent);
813 }
814
CreateThreeValueLogEvent(int atomId,int64_t eventTimeNs,int32_t value1,int32_t value2,int32_t value3)815 shared_ptr<LogEvent> CreateThreeValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1,
816 int32_t value2, int32_t value3) {
817 shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
818 CreateThreeValueLogEvent(logEvent.get(), atomId, eventTimeNs, value1, value2, value3);
819 return logEvent;
820 }
821
CreateRepeatedValueLogEvent(LogEvent * logEvent,int atomId,int64_t eventTimeNs,int32_t value)822 void CreateRepeatedValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs,
823 int32_t value) {
824 AStatsEvent* statsEvent = AStatsEvent_obtain();
825 AStatsEvent_setAtomId(statsEvent, atomId);
826 AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
827
828 AStatsEvent_writeInt32(statsEvent, value);
829 AStatsEvent_writeInt32(statsEvent, value);
830
831 parseStatsEventToLogEvent(statsEvent, logEvent);
832 }
833
CreateRepeatedValueLogEvent(int atomId,int64_t eventTimeNs,int32_t value)834 shared_ptr<LogEvent> CreateRepeatedValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value) {
835 shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
836 CreateRepeatedValueLogEvent(logEvent.get(), atomId, eventTimeNs, value);
837 return logEvent;
838 }
839
CreateNoValuesLogEvent(LogEvent * logEvent,int atomId,int64_t eventTimeNs)840 void CreateNoValuesLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs) {
841 AStatsEvent* statsEvent = AStatsEvent_obtain();
842 AStatsEvent_setAtomId(statsEvent, atomId);
843 AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
844
845 parseStatsEventToLogEvent(statsEvent, logEvent);
846 }
847
CreateNoValuesLogEvent(int atomId,int64_t eventTimeNs)848 shared_ptr<LogEvent> CreateNoValuesLogEvent(int atomId, int64_t eventTimeNs) {
849 shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
850 CreateNoValuesLogEvent(logEvent.get(), atomId, eventTimeNs);
851 return logEvent;
852 }
853
makeUidStatsEvent(int atomId,int64_t eventTimeNs,int uid,int data1,int data2)854 AStatsEvent* makeUidStatsEvent(int atomId, int64_t eventTimeNs, int uid, int data1, int data2) {
855 AStatsEvent* statsEvent = AStatsEvent_obtain();
856 AStatsEvent_setAtomId(statsEvent, atomId);
857 AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
858
859 AStatsEvent_writeInt32(statsEvent, uid);
860 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
861 AStatsEvent_writeInt32(statsEvent, data1);
862 AStatsEvent_writeInt32(statsEvent, data2);
863
864 return statsEvent;
865 }
866
makeUidStatsEvent(int atomId,int64_t eventTimeNs,int uid,int data1,const vector<int> & data2)867 AStatsEvent* makeUidStatsEvent(int atomId, int64_t eventTimeNs, int uid, int data1,
868 const vector<int>& data2) {
869 AStatsEvent* statsEvent = AStatsEvent_obtain();
870 AStatsEvent_setAtomId(statsEvent, atomId);
871 AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
872 AStatsEvent_writeInt32(statsEvent, uid);
873 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
874 AStatsEvent_writeInt32(statsEvent, data1);
875 AStatsEvent_writeInt32Array(statsEvent, data2.data(), data2.size());
876
877 return statsEvent;
878 }
879
makeAttributionStatsEvent(int atomId,int64_t eventTimeNs,const vector<int> & uids,const vector<string> & tags,int data1,int data2)880 AStatsEvent* makeAttributionStatsEvent(int atomId, int64_t eventTimeNs, const vector<int>& uids,
881 const vector<string>& tags, int data1, int data2) {
882 AStatsEvent* statsEvent = AStatsEvent_obtain();
883 AStatsEvent_setAtomId(statsEvent, atomId);
884 AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
885
886 writeAttribution(statsEvent, uids, tags);
887 AStatsEvent_writeInt32(statsEvent, data1);
888 AStatsEvent_writeInt32(statsEvent, data2);
889
890 return statsEvent;
891 }
892
makeUidLogEvent(int atomId,int64_t eventTimeNs,int uid,int data1,int data2)893 shared_ptr<LogEvent> makeUidLogEvent(int atomId, int64_t eventTimeNs, int uid, int data1,
894 int data2) {
895 AStatsEvent* statsEvent = makeUidStatsEvent(atomId, eventTimeNs, uid, data1, data2);
896
897 shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
898 parseStatsEventToLogEvent(statsEvent, logEvent.get());
899 return logEvent;
900 }
901
makeUidLogEvent(int atomId,int64_t eventTimeNs,int uid,int data1,const vector<int> & data2)902 shared_ptr<LogEvent> makeUidLogEvent(int atomId, int64_t eventTimeNs, int uid, int data1,
903 const vector<int>& data2) {
904 AStatsEvent* statsEvent = makeUidStatsEvent(atomId, eventTimeNs, uid, data1, data2);
905
906 shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
907 parseStatsEventToLogEvent(statsEvent, logEvent.get());
908 return logEvent;
909 }
910
makeExtraUidsLogEvent(int atomId,int64_t eventTimeNs,int uid1,int data1,int data2,const vector<int> & extraUids)911 shared_ptr<LogEvent> makeExtraUidsLogEvent(int atomId, int64_t eventTimeNs, int uid1, int data1,
912 int data2, const vector<int>& extraUids) {
913 AStatsEvent* statsEvent = makeUidStatsEvent(atomId, eventTimeNs, uid1, data1, data2);
914 for (const int extraUid : extraUids) {
915 AStatsEvent_writeInt32(statsEvent, extraUid);
916 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
917 }
918
919 shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
920 parseStatsEventToLogEvent(statsEvent, logEvent.get());
921 return logEvent;
922 }
923
makeRepeatedUidLogEvent(int atomId,int64_t eventTimeNs,const vector<int> & uids)924 shared_ptr<LogEvent> makeRepeatedUidLogEvent(int atomId, int64_t eventTimeNs,
925 const vector<int>& uids) {
926 AStatsEvent* statsEvent = AStatsEvent_obtain();
927 AStatsEvent_setAtomId(statsEvent, atomId);
928 AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
929 AStatsEvent_writeInt32Array(statsEvent, uids.data(), uids.size());
930 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
931
932 shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
933 parseStatsEventToLogEvent(statsEvent, logEvent.get());
934
935 return logEvent;
936 }
937
makeRepeatedUidLogEvent(int atomId,int64_t eventTimeNs,const vector<int> & uids,int data1,int data2)938 shared_ptr<LogEvent> makeRepeatedUidLogEvent(int atomId, int64_t eventTimeNs,
939 const vector<int>& uids, int data1, int data2) {
940 AStatsEvent* statsEvent = AStatsEvent_obtain();
941 AStatsEvent_setAtomId(statsEvent, atomId);
942 AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
943 AStatsEvent_writeInt32Array(statsEvent, uids.data(), uids.size());
944 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
945 AStatsEvent_writeInt32(statsEvent, data1);
946 AStatsEvent_writeInt32(statsEvent, data2);
947
948 shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
949 parseStatsEventToLogEvent(statsEvent, logEvent.get());
950
951 return logEvent;
952 }
953
makeRepeatedUidLogEvent(int atomId,int64_t eventTimeNs,const vector<int> & uids,int data1,const vector<int> & data2)954 shared_ptr<LogEvent> makeRepeatedUidLogEvent(int atomId, int64_t eventTimeNs,
955 const vector<int>& uids, int data1,
956 const vector<int>& data2) {
957 AStatsEvent* statsEvent = AStatsEvent_obtain();
958 AStatsEvent_setAtomId(statsEvent, atomId);
959 AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
960 AStatsEvent_writeInt32Array(statsEvent, uids.data(), uids.size());
961 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
962 AStatsEvent_writeInt32(statsEvent, data1);
963 AStatsEvent_writeInt32Array(statsEvent, data2.data(), data2.size());
964
965 shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
966 parseStatsEventToLogEvent(statsEvent, logEvent.get());
967
968 return logEvent;
969 }
970
makeAttributionLogEvent(int atomId,int64_t eventTimeNs,const vector<int> & uids,const vector<string> & tags,int data1,int data2)971 shared_ptr<LogEvent> makeAttributionLogEvent(int atomId, int64_t eventTimeNs,
972 const vector<int>& uids, const vector<string>& tags,
973 int data1, int data2) {
974 AStatsEvent* statsEvent =
975 makeAttributionStatsEvent(atomId, eventTimeNs, uids, tags, data1, data2);
976
977 shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
978 parseStatsEventToLogEvent(statsEvent, logEvent.get());
979 return logEvent;
980 }
981
makeMockUidMapForHosts(const map<int,vector<int>> & hostUidToIsolatedUidsMap)982 sp<MockUidMap> makeMockUidMapForHosts(const map<int, vector<int>>& hostUidToIsolatedUidsMap) {
983 sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
984 EXPECT_CALL(*uidMap, getHostUidOrSelf(_)).WillRepeatedly(ReturnArg<0>());
985 for (const auto& [hostUid, isolatedUids] : hostUidToIsolatedUidsMap) {
986 for (const int isolatedUid : isolatedUids) {
987 EXPECT_CALL(*uidMap, getHostUidOrSelf(isolatedUid)).WillRepeatedly(Return(hostUid));
988 }
989 }
990
991 return uidMap;
992 }
993
makeMockUidMapForPackage(const string & pkg,const set<int32_t> & uids)994 sp<MockUidMap> makeMockUidMapForPackage(const string& pkg, const set<int32_t>& uids) {
995 sp<MockUidMap> uidMap = new StrictMock<MockUidMap>();
996 EXPECT_CALL(*uidMap, getAppUid(_)).Times(AnyNumber());
997 EXPECT_CALL(*uidMap, getAppUid(pkg)).WillRepeatedly(Return(uids));
998
999 return uidMap;
1000 }
1001
CreateScreenStateChangedEvent(uint64_t timestampNs,const android::view::DisplayStateEnum state,int loggerUid)1002 std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(uint64_t timestampNs,
1003 const android::view::DisplayStateEnum state,
1004 int loggerUid) {
1005 AStatsEvent* statsEvent = AStatsEvent_obtain();
1006 AStatsEvent_setAtomId(statsEvent, util::SCREEN_STATE_CHANGED);
1007 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1008 AStatsEvent_writeInt32(statsEvent, state);
1009 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_EXCLUSIVE_STATE, true);
1010 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_STATE_NESTED, false);
1011
1012 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(loggerUid, /*pid=*/0);
1013 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1014 return logEvent;
1015 }
1016
CreateBatterySaverOnEvent(uint64_t timestampNs)1017 std::unique_ptr<LogEvent> CreateBatterySaverOnEvent(uint64_t timestampNs) {
1018 AStatsEvent* statsEvent = AStatsEvent_obtain();
1019 AStatsEvent_setAtomId(statsEvent, util::BATTERY_SAVER_MODE_STATE_CHANGED);
1020 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1021 AStatsEvent_writeInt32(statsEvent, BatterySaverModeStateChanged::ON);
1022 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_EXCLUSIVE_STATE, true);
1023 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_STATE_NESTED, false);
1024
1025 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1026 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1027 return logEvent;
1028 }
1029
CreateBatterySaverOffEvent(uint64_t timestampNs)1030 std::unique_ptr<LogEvent> CreateBatterySaverOffEvent(uint64_t timestampNs) {
1031 AStatsEvent* statsEvent = AStatsEvent_obtain();
1032 AStatsEvent_setAtomId(statsEvent, util::BATTERY_SAVER_MODE_STATE_CHANGED);
1033 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1034 AStatsEvent_writeInt32(statsEvent, BatterySaverModeStateChanged::OFF);
1035 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_EXCLUSIVE_STATE, true);
1036 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_STATE_NESTED, false);
1037
1038 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1039 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1040 return logEvent;
1041 }
1042
CreateBatteryStateChangedEvent(const uint64_t timestampNs,const BatteryPluggedStateEnum state,int32_t uid)1043 std::unique_ptr<LogEvent> CreateBatteryStateChangedEvent(const uint64_t timestampNs,
1044 const BatteryPluggedStateEnum state,
1045 int32_t uid) {
1046 AStatsEvent* statsEvent = AStatsEvent_obtain();
1047 AStatsEvent_setAtomId(statsEvent, util::PLUGGED_STATE_CHANGED);
1048 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1049 AStatsEvent_writeInt32(statsEvent, state);
1050 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_EXCLUSIVE_STATE, true);
1051 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_STATE_NESTED, false);
1052
1053 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/uid, /*pid=*/0);
1054 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1055 return logEvent;
1056 }
1057
CreateMalformedBatteryStateChangedEvent(const uint64_t timestampNs)1058 std::unique_ptr<LogEvent> CreateMalformedBatteryStateChangedEvent(const uint64_t timestampNs) {
1059 AStatsEvent* statsEvent = AStatsEvent_obtain();
1060 AStatsEvent_setAtomId(statsEvent, util::PLUGGED_STATE_CHANGED);
1061 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1062 AStatsEvent_writeString(statsEvent, "bad_state");
1063 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_EXCLUSIVE_STATE, true);
1064 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_STATE_NESTED, false);
1065
1066 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1067 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1068 return logEvent;
1069 }
1070
CreateScreenBrightnessChangedEvent(uint64_t timestampNs,int level)1071 std::unique_ptr<LogEvent> CreateScreenBrightnessChangedEvent(uint64_t timestampNs, int level) {
1072 AStatsEvent* statsEvent = AStatsEvent_obtain();
1073 AStatsEvent_setAtomId(statsEvent, util::SCREEN_BRIGHTNESS_CHANGED);
1074 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1075 AStatsEvent_writeInt32(statsEvent, level);
1076
1077 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1078 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1079 return logEvent;
1080 }
1081
CreateScheduledJobStateChangedEvent(const vector<int> & attributionUids,const vector<string> & attributionTags,const string & jobName,const ScheduledJobStateChanged::State state,uint64_t timestampNs)1082 std::unique_ptr<LogEvent> CreateScheduledJobStateChangedEvent(
1083 const vector<int>& attributionUids, const vector<string>& attributionTags,
1084 const string& jobName, const ScheduledJobStateChanged::State state, uint64_t timestampNs) {
1085 AStatsEvent* statsEvent = AStatsEvent_obtain();
1086 AStatsEvent_setAtomId(statsEvent, util::SCHEDULED_JOB_STATE_CHANGED);
1087 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1088
1089 writeAttribution(statsEvent, attributionUids, attributionTags);
1090 AStatsEvent_writeString(statsEvent, jobName.c_str());
1091 AStatsEvent_writeInt32(statsEvent, state);
1092
1093 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1094 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1095 return logEvent;
1096 }
1097
CreateStartScheduledJobEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & jobName)1098 std::unique_ptr<LogEvent> CreateStartScheduledJobEvent(uint64_t timestampNs,
1099 const vector<int>& attributionUids,
1100 const vector<string>& attributionTags,
1101 const string& jobName) {
1102 return CreateScheduledJobStateChangedEvent(attributionUids, attributionTags, jobName,
1103 ScheduledJobStateChanged::STARTED, timestampNs);
1104 }
1105
1106 // Create log event when scheduled job finishes.
CreateFinishScheduledJobEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & jobName)1107 std::unique_ptr<LogEvent> CreateFinishScheduledJobEvent(uint64_t timestampNs,
1108 const vector<int>& attributionUids,
1109 const vector<string>& attributionTags,
1110 const string& jobName) {
1111 return CreateScheduledJobStateChangedEvent(attributionUids, attributionTags, jobName,
1112 ScheduledJobStateChanged::FINISHED, timestampNs);
1113 }
1114
1115 // Create log event when scheduled job is scheduled.
CreateScheduleScheduledJobEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & jobName)1116 std::unique_ptr<LogEvent> CreateScheduleScheduledJobEvent(uint64_t timestampNs,
1117 const vector<int>& attributionUids,
1118 const vector<string>& attributionTags,
1119 const string& jobName) {
1120 return CreateScheduledJobStateChangedEvent(attributionUids, attributionTags, jobName,
1121 ScheduledJobStateChanged::SCHEDULED, timestampNs);
1122 }
1123
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)1124 std::unique_ptr<LogEvent> CreateTestAtomReportedEventVariableRepeatedFields(
1125 uint64_t timestampNs, const vector<int>& repeatedIntField,
1126 const vector<int64_t>& repeatedLongField, const vector<float>& repeatedFloatField,
1127 const vector<string>& repeatedStringField, const bool* repeatedBoolField,
1128 const size_t repeatedBoolFieldLength, const vector<int>& repeatedEnumField) {
1129 return CreateTestAtomReportedEvent(timestampNs, {1001, 1002}, {"app1", "app2"}, 5, 1000l, 21.9f,
1130 "string", 1, TestAtomReported::ON, {8, 1, 8, 2, 8, 3},
1131 repeatedIntField, repeatedLongField, repeatedFloatField,
1132 repeatedStringField, repeatedBoolField,
1133 repeatedBoolFieldLength, repeatedEnumField);
1134 }
1135
CreateTestAtomReportedEventWithPrimitives(uint64_t timestampNs,int intField,long longField,float floatField,const string & stringField,bool boolField,TestAtomReported::State enumField)1136 std::unique_ptr<LogEvent> CreateTestAtomReportedEventWithPrimitives(
1137 uint64_t timestampNs, int intField, long longField, float floatField,
1138 const string& stringField, bool boolField, TestAtomReported::State enumField) {
1139 return CreateTestAtomReportedEvent(
1140 timestampNs, /* attributionUids */ {1001},
1141 /* attributionTags */ {"app1"}, intField, longField, floatField, stringField, boolField,
1142 enumField, /* bytesField */ {},
1143 /* repeatedIntField */ {}, /* repeatedLongField */ {}, /* repeatedFloatField */ {},
1144 /* repeatedStringField */ {}, /* repeatedBoolField */ {},
1145 /* repeatedBoolFieldLength */ 0, /* repeatedEnumField */ {});
1146 }
1147
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)1148 std::unique_ptr<LogEvent> CreateTestAtomReportedEvent(
1149 uint64_t timestampNs, const vector<int>& attributionUids,
1150 const vector<string>& attributionTags, const int intField, const long longField,
1151 const float floatField, const string& stringField, const bool boolField,
1152 const TestAtomReported::State enumField, const vector<uint8_t>& bytesField,
1153 const vector<int>& repeatedIntField, const vector<int64_t>& repeatedLongField,
1154 const vector<float>& repeatedFloatField, const vector<string>& repeatedStringField,
1155 const bool* repeatedBoolField, const size_t repeatedBoolFieldLength,
1156 const vector<int>& repeatedEnumField) {
1157 vector<const char*> cRepeatedStringField(repeatedStringField.size());
1158 for (int i = 0; i < cRepeatedStringField.size(); i++) {
1159 cRepeatedStringField[i] = repeatedStringField[i].c_str();
1160 }
1161
1162 AStatsEvent* statsEvent = AStatsEvent_obtain();
1163 AStatsEvent_setAtomId(statsEvent, util::TEST_ATOM_REPORTED);
1164 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1165
1166 writeAttribution(statsEvent, attributionUids, attributionTags);
1167 AStatsEvent_writeInt32(statsEvent, intField);
1168 AStatsEvent_writeInt64(statsEvent, longField);
1169 AStatsEvent_writeFloat(statsEvent, floatField);
1170 AStatsEvent_writeString(statsEvent, stringField.c_str());
1171 AStatsEvent_writeBool(statsEvent, boolField);
1172 AStatsEvent_writeInt32(statsEvent, enumField);
1173 AStatsEvent_writeByteArray(statsEvent, bytesField.data(), bytesField.size());
1174 if (__builtin_available(android __ANDROID_API_T__, *)) {
1175 /* CreateTestAtomReportedEvent is used in CreateTestAtomReportedEventVariableRepeatedFields
1176 and CreateTestAtomReportedEventWithPrimitives. Only
1177 CreateTestAtomReportedEventVariableRepeatedFields writes repeated fields, so wrapping
1178 this portion in a __builtin_available and
1179 CreateTestAtomReportedEventVariableRepeatedFields is annotated with __INTRODUCED_IN.
1180 */
1181 AStatsEvent_writeInt32Array(statsEvent, repeatedIntField.data(), repeatedIntField.size());
1182 AStatsEvent_writeInt64Array(statsEvent, repeatedLongField.data(), repeatedLongField.size());
1183 AStatsEvent_writeFloatArray(statsEvent, repeatedFloatField.data(),
1184 repeatedFloatField.size());
1185 AStatsEvent_writeStringArray(statsEvent, cRepeatedStringField.data(),
1186 repeatedStringField.size());
1187 AStatsEvent_writeBoolArray(statsEvent, repeatedBoolField, repeatedBoolFieldLength);
1188 AStatsEvent_writeInt32Array(statsEvent, repeatedEnumField.data(), repeatedEnumField.size());
1189 } else if (!repeatedIntField.empty() || !repeatedLongField.empty() ||
1190 !repeatedFloatField.empty() || !cRepeatedStringField.empty() ||
1191 repeatedBoolFieldLength != 0 || !repeatedEnumField.empty()) {
1192 ADD_FAILURE() << "CreateTestAtomReportedEvent w/ repeated fields is only available in "
1193 "Android T and above.";
1194 }
1195
1196 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1197 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1198 return logEvent;
1199 }
1200
CreateWakelockStateChangedEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & wakelockName,const WakelockStateChanged::State state)1201 std::unique_ptr<LogEvent> CreateWakelockStateChangedEvent(uint64_t timestampNs,
1202 const vector<int>& attributionUids,
1203 const vector<string>& attributionTags,
1204 const string& wakelockName,
1205 const WakelockStateChanged::State state) {
1206 AStatsEvent* statsEvent = AStatsEvent_obtain();
1207 AStatsEvent_setAtomId(statsEvent, util::WAKELOCK_STATE_CHANGED);
1208 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1209
1210 writeAttribution(statsEvent, attributionUids, attributionTags);
1211 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID,
1212 true);
1213 AStatsEvent_writeInt32(statsEvent, android::os::WakeLockLevelEnum::PARTIAL_WAKE_LOCK);
1214 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD, true);
1215 AStatsEvent_writeString(statsEvent, wakelockName.c_str());
1216 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD, true);
1217 AStatsEvent_writeInt32(statsEvent, state);
1218 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_EXCLUSIVE_STATE, true);
1219 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_STATE_NESTED, true);
1220
1221 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1222 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1223 return logEvent;
1224 }
1225
CreateAcquireWakelockEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & wakelockName)1226 std::unique_ptr<LogEvent> CreateAcquireWakelockEvent(uint64_t timestampNs,
1227 const vector<int>& attributionUids,
1228 const vector<string>& attributionTags,
1229 const string& wakelockName) {
1230 return CreateWakelockStateChangedEvent(timestampNs, attributionUids, attributionTags,
1231 wakelockName, WakelockStateChanged::ACQUIRE);
1232 }
1233
CreateReleaseWakelockEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & wakelockName)1234 std::unique_ptr<LogEvent> CreateReleaseWakelockEvent(uint64_t timestampNs,
1235 const vector<int>& attributionUids,
1236 const vector<string>& attributionTags,
1237 const string& wakelockName) {
1238 return CreateWakelockStateChangedEvent(timestampNs, attributionUids, attributionTags,
1239 wakelockName, WakelockStateChanged::RELEASE);
1240 }
1241
CreateActivityForegroundStateChangedEvent(uint64_t timestampNs,const int uid,const string & pkgName,const string & className,const ActivityForegroundStateChanged::State state)1242 std::unique_ptr<LogEvent> CreateActivityForegroundStateChangedEvent(
1243 uint64_t timestampNs, const int uid, const string& pkgName, const string& className,
1244 const ActivityForegroundStateChanged::State state) {
1245 AStatsEvent* statsEvent = AStatsEvent_obtain();
1246 AStatsEvent_setAtomId(statsEvent, util::ACTIVITY_FOREGROUND_STATE_CHANGED);
1247 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1248
1249 AStatsEvent_writeInt32(statsEvent, uid);
1250 AStatsEvent_writeString(statsEvent, pkgName.c_str());
1251 AStatsEvent_writeString(statsEvent, className.c_str());
1252 AStatsEvent_writeInt32(statsEvent, state);
1253
1254 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1255 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1256 return logEvent;
1257 }
1258
CreateMoveToBackgroundEvent(uint64_t timestampNs,const int uid)1259 std::unique_ptr<LogEvent> CreateMoveToBackgroundEvent(uint64_t timestampNs, const int uid) {
1260 return CreateActivityForegroundStateChangedEvent(timestampNs, uid, "pkg_name", "class_name",
1261 ActivityForegroundStateChanged::BACKGROUND);
1262 }
1263
CreateMoveToForegroundEvent(uint64_t timestampNs,const int uid)1264 std::unique_ptr<LogEvent> CreateMoveToForegroundEvent(uint64_t timestampNs, const int uid) {
1265 return CreateActivityForegroundStateChangedEvent(timestampNs, uid, "pkg_name", "class_name",
1266 ActivityForegroundStateChanged::FOREGROUND);
1267 }
1268
CreateSyncStateChangedEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & name,const SyncStateChanged::State state)1269 std::unique_ptr<LogEvent> CreateSyncStateChangedEvent(uint64_t timestampNs,
1270 const vector<int>& attributionUids,
1271 const vector<string>& attributionTags,
1272 const string& name,
1273 const SyncStateChanged::State state) {
1274 AStatsEvent* statsEvent = AStatsEvent_obtain();
1275 AStatsEvent_setAtomId(statsEvent, util::SYNC_STATE_CHANGED);
1276 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1277
1278 writeAttribution(statsEvent, attributionUids, attributionTags);
1279 AStatsEvent_writeString(statsEvent, name.c_str());
1280 AStatsEvent_writeInt32(statsEvent, state);
1281
1282 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1283 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1284 return logEvent;
1285 }
1286
CreateSyncStartEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & name)1287 std::unique_ptr<LogEvent> CreateSyncStartEvent(uint64_t timestampNs,
1288 const vector<int>& attributionUids,
1289 const vector<string>& attributionTags,
1290 const string& name) {
1291 return CreateSyncStateChangedEvent(timestampNs, attributionUids, attributionTags, name,
1292 SyncStateChanged::ON);
1293 }
1294
CreateSyncEndEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & name)1295 std::unique_ptr<LogEvent> CreateSyncEndEvent(uint64_t timestampNs,
1296 const vector<int>& attributionUids,
1297 const vector<string>& attributionTags,
1298 const string& name) {
1299 return CreateSyncStateChangedEvent(timestampNs, attributionUids, attributionTags, name,
1300 SyncStateChanged::OFF);
1301 }
1302
CreateProcessLifeCycleStateChangedEvent(uint64_t timestampNs,const int uid,const ProcessLifeCycleStateChanged::State state)1303 std::unique_ptr<LogEvent> CreateProcessLifeCycleStateChangedEvent(
1304 uint64_t timestampNs, const int uid, const ProcessLifeCycleStateChanged::State state) {
1305 AStatsEvent* statsEvent = AStatsEvent_obtain();
1306 AStatsEvent_setAtomId(statsEvent, util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
1307 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1308
1309 AStatsEvent_writeInt32(statsEvent, uid);
1310 AStatsEvent_writeString(statsEvent, "");
1311 AStatsEvent_writeInt32(statsEvent, state);
1312
1313 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1314 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1315 return logEvent;
1316 }
1317
CreateAppCrashEvent(uint64_t timestampNs,const int uid)1318 std::unique_ptr<LogEvent> CreateAppCrashEvent(uint64_t timestampNs, const int uid) {
1319 return CreateProcessLifeCycleStateChangedEvent(timestampNs, uid,
1320 ProcessLifeCycleStateChanged::CRASHED);
1321 }
1322
CreateAppCrashOccurredEvent(uint64_t timestampNs,const int uid)1323 std::unique_ptr<LogEvent> CreateAppCrashOccurredEvent(uint64_t timestampNs, const int uid) {
1324 AStatsEvent* statsEvent = AStatsEvent_obtain();
1325 AStatsEvent_setAtomId(statsEvent, util::APP_CRASH_OCCURRED);
1326 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1327
1328 AStatsEvent_writeInt32(statsEvent, uid);
1329 AStatsEvent_writeString(statsEvent, "eventType");
1330 AStatsEvent_writeString(statsEvent, "processName");
1331
1332 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1333 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1334 return logEvent;
1335 }
1336
CreateIsolatedUidChangedEvent(uint64_t timestampNs,int hostUid,int isolatedUid,bool is_create)1337 std::unique_ptr<LogEvent> CreateIsolatedUidChangedEvent(uint64_t timestampNs, int hostUid,
1338 int isolatedUid, bool is_create) {
1339 AStatsEvent* statsEvent = AStatsEvent_obtain();
1340 AStatsEvent_setAtomId(statsEvent, util::ISOLATED_UID_CHANGED);
1341 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1342
1343 AStatsEvent_writeInt32(statsEvent, hostUid);
1344 AStatsEvent_writeInt32(statsEvent, isolatedUid);
1345 AStatsEvent_writeInt32(statsEvent, is_create);
1346
1347 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1348 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1349 return logEvent;
1350 }
1351
CreateUidProcessStateChangedEvent(uint64_t timestampNs,int uid,const android::app::ProcessStateEnum state)1352 std::unique_ptr<LogEvent> CreateUidProcessStateChangedEvent(
1353 uint64_t timestampNs, int uid, const android::app::ProcessStateEnum state) {
1354 AStatsEvent* statsEvent = AStatsEvent_obtain();
1355 AStatsEvent_setAtomId(statsEvent, util::UID_PROCESS_STATE_CHANGED);
1356 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1357
1358 AStatsEvent_writeInt32(statsEvent, uid);
1359 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
1360 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD, true);
1361 AStatsEvent_writeInt32(statsEvent, state);
1362 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_EXCLUSIVE_STATE, true);
1363 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_STATE_NESTED, false);
1364
1365 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1366 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1367 return logEvent;
1368 }
1369
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)1370 std::unique_ptr<LogEvent> CreateBleScanStateChangedEvent(uint64_t timestampNs,
1371 const vector<int>& attributionUids,
1372 const vector<string>& attributionTags,
1373 const BleScanStateChanged::State state,
1374 const bool filtered, const bool firstMatch,
1375 const bool opportunistic) {
1376 AStatsEvent* statsEvent = AStatsEvent_obtain();
1377 AStatsEvent_setAtomId(statsEvent, util::BLE_SCAN_STATE_CHANGED);
1378 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1379
1380 writeAttribution(statsEvent, attributionUids, attributionTags);
1381 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID,
1382 true);
1383 AStatsEvent_writeInt32(statsEvent, state);
1384 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_EXCLUSIVE_STATE, true);
1385 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_STATE_NESTED, true);
1386 if (state == util::BLE_SCAN_STATE_CHANGED__STATE__RESET) {
1387 AStatsEvent_addInt32Annotation(statsEvent, ASTATSLOG_ANNOTATION_ID_TRIGGER_STATE_RESET,
1388 util::BLE_SCAN_STATE_CHANGED__STATE__OFF);
1389 }
1390 AStatsEvent_writeBool(statsEvent, filtered); // filtered
1391 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD, true);
1392 AStatsEvent_writeBool(statsEvent, firstMatch); // first match
1393 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD, true);
1394 AStatsEvent_writeBool(statsEvent, opportunistic); // opportunistic
1395 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD, true);
1396
1397 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1398 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1399 return logEvent;
1400 }
1401
CreateOverlayStateChangedEvent(int64_t timestampNs,const int32_t uid,const string & packageName,const bool usingAlertWindow,const OverlayStateChanged::State state)1402 std::unique_ptr<LogEvent> CreateOverlayStateChangedEvent(int64_t timestampNs, const int32_t uid,
1403 const string& packageName,
1404 const bool usingAlertWindow,
1405 const OverlayStateChanged::State state) {
1406 AStatsEvent* statsEvent = AStatsEvent_obtain();
1407 AStatsEvent_setAtomId(statsEvent, util::OVERLAY_STATE_CHANGED);
1408 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1409
1410 AStatsEvent_writeInt32(statsEvent, uid);
1411 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
1412 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD, true);
1413 AStatsEvent_writeString(statsEvent, packageName.c_str());
1414 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD, true);
1415 AStatsEvent_writeBool(statsEvent, usingAlertWindow);
1416 AStatsEvent_writeInt32(statsEvent, state);
1417 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_EXCLUSIVE_STATE, true);
1418 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_STATE_NESTED, false);
1419
1420 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1421 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1422 return logEvent;
1423 }
1424
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)1425 std::unique_ptr<LogEvent> CreateAppStartOccurredEvent(
1426 uint64_t timestampNs, const int uid, const string& pkgName,
1427 AppStartOccurred::TransitionType type, const string& activityName,
1428 const string& callingPkgName, const bool isInstantApp, int64_t activityStartMs) {
1429 AStatsEvent* statsEvent = AStatsEvent_obtain();
1430 AStatsEvent_setAtomId(statsEvent, util::APP_START_OCCURRED);
1431 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1432
1433 AStatsEvent_writeInt32(statsEvent, uid);
1434 AStatsEvent_writeString(statsEvent, pkgName.c_str());
1435 AStatsEvent_writeInt32(statsEvent, type);
1436 AStatsEvent_writeString(statsEvent, activityName.c_str());
1437 AStatsEvent_writeString(statsEvent, callingPkgName.c_str());
1438 AStatsEvent_writeInt32(statsEvent, isInstantApp);
1439 AStatsEvent_writeInt32(statsEvent, activityStartMs);
1440
1441 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1442 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1443 return logEvent;
1444 }
1445
CreateBleScanResultReceivedEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const int numResults)1446 std::unique_ptr<LogEvent> CreateBleScanResultReceivedEvent(uint64_t timestampNs,
1447 const vector<int>& attributionUids,
1448 const vector<string>& attributionTags,
1449 const int numResults) {
1450 AStatsEvent* statsEvent = AStatsEvent_obtain();
1451 AStatsEvent_setAtomId(statsEvent, util::BLE_SCAN_RESULT_RECEIVED);
1452 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1453
1454 writeAttribution(statsEvent, attributionUids, attributionTags);
1455 AStatsEvent_writeInt32(statsEvent, numResults);
1456
1457 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1458 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1459 return logEvent;
1460 }
1461
CreateRestrictedLogEvent(int atomTag,int64_t timestampNs)1462 std::unique_ptr<LogEvent> CreateRestrictedLogEvent(int atomTag, int64_t timestampNs) {
1463 AStatsEvent* statsEvent = AStatsEvent_obtain();
1464 AStatsEvent_setAtomId(statsEvent, atomTag);
1465 AStatsEvent_addInt32Annotation(statsEvent, ASTATSLOG_ANNOTATION_ID_RESTRICTION_CATEGORY,
1466 ASTATSLOG_RESTRICTION_CATEGORY_DIAGNOSTIC);
1467 AStatsEvent_writeInt32(statsEvent, 10);
1468 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1469 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1470 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1471 return logEvent;
1472 }
1473
CreateNonRestrictedLogEvent(int atomTag,int64_t timestampNs)1474 std::unique_ptr<LogEvent> CreateNonRestrictedLogEvent(int atomTag, int64_t timestampNs) {
1475 AStatsEvent* statsEvent = AStatsEvent_obtain();
1476 AStatsEvent_setAtomId(statsEvent, atomTag);
1477 AStatsEvent_writeInt32(statsEvent, 10);
1478 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1479 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1480 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1481 return logEvent;
1482 }
1483
CreatePhoneSignalStrengthChangedEvent(int64_t timestampNs,::telephony::SignalStrengthEnum state)1484 std::unique_ptr<LogEvent> CreatePhoneSignalStrengthChangedEvent(
1485 int64_t timestampNs, ::telephony::SignalStrengthEnum state) {
1486 AStatsEvent* statsEvent = AStatsEvent_obtain();
1487 AStatsEvent_setAtomId(statsEvent, util::PHONE_SIGNAL_STRENGTH_CHANGED);
1488 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_TRUNCATE_TIMESTAMP, true);
1489 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1490 AStatsEvent_writeInt32(statsEvent, state);
1491
1492 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1493 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1494 return logEvent;
1495 }
1496
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)1497 sp<StatsLogProcessor> CreateStatsLogProcessor(const int64_t timeBaseNs, const int64_t currentTimeNs,
1498 const StatsdConfig& config, const ConfigKey& key,
1499 const shared_ptr<IPullAtomCallback>& puller,
1500 const int32_t atomTag, const sp<UidMap> uidMap,
1501 const shared_ptr<LogEventFilter>& logEventFilter) {
1502 sp<StatsPullerManager> pullerManager = new StatsPullerManager();
1503 StatsPuller::SetUidMap(uidMap);
1504 if (puller != nullptr) {
1505 pullerManager->RegisterPullAtomCallback(/*uid=*/0, atomTag, NS_PER_SEC, NS_PER_SEC * 10, {},
1506 puller);
1507 }
1508 sp<AlarmMonitor> anomalyAlarmMonitor =
1509 new AlarmMonitor(1,
1510 [](const shared_ptr<IStatsCompanionService>&, int64_t){},
1511 [](const shared_ptr<IStatsCompanionService>&){});
1512 sp<AlarmMonitor> periodicAlarmMonitor =
1513 new AlarmMonitor(1,
1514 [](const shared_ptr<IStatsCompanionService>&, int64_t){},
1515 [](const shared_ptr<IStatsCompanionService>&){});
1516 sp<StatsLogProcessor> processor = new StatsLogProcessor(
1517 uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor, timeBaseNs,
1518 [](const ConfigKey&) { return true; },
1519 [](const int&, const vector<int64_t>&) { return true; },
1520 [](const ConfigKey&, const string&, const vector<int64_t>&) {}, logEventFilter);
1521
1522 processor->OnConfigUpdated(currentTimeNs, key, config);
1523 return processor;
1524 }
1525
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)1526 sp<NumericValueMetricProducer> createNumericValueMetricProducer(
1527 sp<MockStatsPullerManager>& pullerManager, const ValueMetric& metric, const int atomId,
1528 bool isPulled, const ConfigKey& configKey, const uint64_t protoHash,
1529 const int64_t timeBaseNs, const int64_t startTimeNs, const int logEventMatcherIndex,
1530 optional<ConditionState> conditionAfterFirstBucketPrepared,
1531 vector<int32_t> slicedStateAtoms,
1532 unordered_map<int, unordered_map<int, int64_t>> stateGroupMap,
1533 sp<EventMatcherWizard> eventMatcherWizard) {
1534 if (eventMatcherWizard == nullptr) {
1535 eventMatcherWizard = createEventMatcherWizard(atomId, logEventMatcherIndex);
1536 }
1537 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
1538 if (isPulled) {
1539 EXPECT_CALL(*pullerManager, RegisterReceiver(atomId, configKey, _, _, _))
1540 .WillOnce(Return());
1541 EXPECT_CALL(*pullerManager, UnRegisterReceiver(atomId, configKey, _))
1542 .WillRepeatedly(Return());
1543 }
1544 const int64_t bucketSizeNs = MillisToNano(
1545 TimeUnitToBucketSizeInMillisGuardrailed(configKey.GetUid(), metric.bucket()));
1546 const bool containsAnyPositionInDimensionsInWhat = HasPositionANY(metric.dimensions_in_what());
1547 const bool shouldUseNestedDimensions = ShouldUseNestedDimensions(metric.dimensions_in_what());
1548
1549 vector<Matcher> fieldMatchers;
1550 translateFieldMatcher(metric.value_field(), &fieldMatchers);
1551
1552 const auto [dimensionSoftLimit, dimensionHardLimit] =
1553 StatsdStats::getAtomDimensionKeySizeLimits(atomId,
1554 StatsdStats::kDimensionKeySizeHardLimitMin);
1555
1556 int conditionIndex = conditionAfterFirstBucketPrepared ? 0 : -1;
1557 vector<ConditionState> initialConditionCache;
1558 if (conditionAfterFirstBucketPrepared) {
1559 initialConditionCache.push_back(ConditionState::kUnknown);
1560 }
1561
1562 // get the condition_correction_threshold_nanos value
1563 const optional<int64_t> conditionCorrectionThresholdNs =
1564 metric.has_condition_correction_threshold_nanos()
1565 ? optional<int64_t>(metric.condition_correction_threshold_nanos())
1566 : nullopt;
1567
1568 std::vector<ValueMetric::AggregationType> aggregationTypes;
1569 if (metric.aggregation_types_size() != 0) {
1570 for (int i = 0; i < metric.aggregation_types_size(); i++) {
1571 aggregationTypes.push_back(metric.aggregation_types(i));
1572 }
1573 } else { // aggregation_type() is set or default is used.
1574 aggregationTypes.push_back(metric.aggregation_type());
1575 }
1576
1577 ParseHistogramBinConfigsResult parseBinConfigsResult =
1578 parseHistogramBinConfigs(metric, aggregationTypes);
1579 const vector<optional<const BinStarts>>& binStartsList =
1580 std::get<vector<optional<const BinStarts>>>(parseBinConfigsResult);
1581
1582 sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
1583 const int pullAtomId = isPulled ? atomId : -1;
1584 return new NumericValueMetricProducer(
1585 configKey, metric, protoHash, {pullAtomId, pullerManager},
1586 {timeBaseNs, startTimeNs, bucketSizeNs, metric.min_bucket_size_nanos(),
1587 conditionCorrectionThresholdNs, metric.split_bucket_for_app_upgrade()},
1588 {containsAnyPositionInDimensionsInWhat, shouldUseNestedDimensions, logEventMatcherIndex,
1589 eventMatcherWizard, metric.dimensions_in_what(), fieldMatchers, aggregationTypes,
1590 binStartsList},
1591 {conditionIndex, metric.links(), initialConditionCache, wizard},
1592 {metric.state_link(), slicedStateAtoms, stateGroupMap},
1593 {/*eventActivationMap=*/{}, /*eventDeactivationMap=*/{}},
1594 {dimensionSoftLimit, dimensionHardLimit}, provider);
1595 }
1596
CreateAtomIdSetDefault()1597 LogEventFilter::AtomIdSet CreateAtomIdSetDefault() {
1598 LogEventFilter::AtomIdSet resultList(StatsLogProcessor::getDefaultAtomIdSet());
1599 StateManager::getInstance().addAllAtomIds(resultList);
1600 return resultList;
1601 }
1602
CreateAtomIdSetFromConfig(const StatsdConfig & config)1603 LogEventFilter::AtomIdSet CreateAtomIdSetFromConfig(const StatsdConfig& config) {
1604 LogEventFilter::AtomIdSet resultList(StatsLogProcessor::getDefaultAtomIdSet());
1605
1606 // Parse the config for atom ids. A combination atom matcher is a combination of (in the end)
1607 // simple atom matchers. So by adding all the atoms from the simple atom matchers
1608 // function adds all of the atoms.
1609 for (int i = 0; i < config.atom_matcher_size(); i++) {
1610 const AtomMatcher& matcher = config.atom_matcher(i);
1611 if (matcher.has_simple_atom_matcher()) {
1612 EXPECT_TRUE(matcher.simple_atom_matcher().has_atom_id());
1613 resultList.insert(matcher.simple_atom_matcher().atom_id());
1614 }
1615 }
1616
1617 for (int i = 0; i < config.state_size(); i++) {
1618 const State& state = config.state(i);
1619 EXPECT_TRUE(state.has_atom_id());
1620 resultList.insert(state.atom_id());
1621 }
1622
1623 return resultList;
1624 }
1625
sortLogEventsByTimestamp(std::vector<std::unique_ptr<LogEvent>> * events)1626 void sortLogEventsByTimestamp(std::vector<std::unique_ptr<LogEvent>> *events) {
1627 std::sort(events->begin(), events->end(),
1628 [](const std::unique_ptr<LogEvent>& a, const std::unique_ptr<LogEvent>& b) {
1629 return a->GetElapsedTimestampNs() < b->GetElapsedTimestampNs();
1630 });
1631 }
1632
StringToId(const string & str)1633 int64_t StringToId(const string& str) {
1634 return static_cast<int64_t>(std::hash<std::string>()(str));
1635 }
1636
createEventMatcherWizard(int tagId,int matcherIndex,const vector<FieldValueMatcher> & fieldValueMatchers)1637 sp<EventMatcherWizard> createEventMatcherWizard(
1638 int tagId, int matcherIndex, const vector<FieldValueMatcher>& fieldValueMatchers) {
1639 sp<UidMap> uidMap = new UidMap();
1640 SimpleAtomMatcher atomMatcher;
1641 atomMatcher.set_atom_id(tagId);
1642 for (const FieldValueMatcher& fvm : fieldValueMatchers) {
1643 *atomMatcher.add_field_value_matcher() = fvm;
1644 }
1645 uint64_t matcherHash = 0x12345678;
1646 int64_t matcherId = 678;
1647 return new EventMatcherWizard(
1648 {new SimpleAtomMatchingTracker(matcherId, matcherHash, atomMatcher, uidMap)});
1649 }
1650
CreateAttributionUidDimensionsValueParcel(const int atomId,const int uid)1651 StatsDimensionsValueParcel CreateAttributionUidDimensionsValueParcel(const int atomId,
1652 const int uid) {
1653 StatsDimensionsValueParcel root;
1654 root.field = atomId;
1655 root.valueType = STATS_DIMENSIONS_VALUE_TUPLE_TYPE;
1656 StatsDimensionsValueParcel attrNode;
1657 attrNode.field = 1;
1658 attrNode.valueType = STATS_DIMENSIONS_VALUE_TUPLE_TYPE;
1659 StatsDimensionsValueParcel posInAttrChain;
1660 posInAttrChain.field = 1;
1661 posInAttrChain.valueType = STATS_DIMENSIONS_VALUE_TUPLE_TYPE;
1662 StatsDimensionsValueParcel uidNode;
1663 uidNode.field = 1;
1664 uidNode.valueType = STATS_DIMENSIONS_VALUE_INT_TYPE;
1665 uidNode.intValue = uid;
1666 posInAttrChain.tupleValue.push_back(uidNode);
1667 attrNode.tupleValue.push_back(posInAttrChain);
1668 root.tupleValue.push_back(attrNode);
1669 return root;
1670 }
1671
ValidateUidDimension(const DimensionsValue & value,int atomId,int uid)1672 void ValidateUidDimension(const DimensionsValue& value, int atomId, int uid) {
1673 EXPECT_EQ(value.field(), atomId);
1674 ASSERT_EQ(value.value_tuple().dimensions_value_size(), 1);
1675 EXPECT_EQ(value.value_tuple().dimensions_value(0).field(), 1);
1676 EXPECT_EQ(value.value_tuple().dimensions_value(0).value_int(), uid);
1677 }
1678
ValidateWakelockAttributionUidAndTagDimension(const DimensionsValue & value,const int atomId,const int uid,const string & tag)1679 void ValidateWakelockAttributionUidAndTagDimension(const DimensionsValue& value, const int atomId,
1680 const int uid, const string& tag) {
1681 EXPECT_EQ(value.field(), atomId);
1682 ASSERT_EQ(value.value_tuple().dimensions_value_size(), 2);
1683 // Attribution field.
1684 EXPECT_EQ(value.value_tuple().dimensions_value(0).field(), 1);
1685 // Uid field.
1686 ASSERT_EQ(value.value_tuple().dimensions_value(0).value_tuple().dimensions_value_size(), 1);
1687 EXPECT_EQ(value.value_tuple().dimensions_value(0).value_tuple().dimensions_value(0).field(), 1);
1688 EXPECT_EQ(value.value_tuple().dimensions_value(0).value_tuple().dimensions_value(0).value_int(),
1689 uid);
1690 // Tag field.
1691 EXPECT_EQ(value.value_tuple().dimensions_value(1).field(), 3);
1692 EXPECT_EQ(value.value_tuple().dimensions_value(1).value_str(), tag);
1693 }
1694
ValidateAttributionUidDimension(const DimensionsValue & value,int atomId,int uid)1695 void ValidateAttributionUidDimension(const DimensionsValue& value, int atomId, int uid) {
1696 EXPECT_EQ(value.field(), atomId);
1697 ASSERT_EQ(value.value_tuple().dimensions_value_size(), 1);
1698 // Attribution field.
1699 EXPECT_EQ(value.value_tuple().dimensions_value(0).field(), 1);
1700 // Uid only.
1701 EXPECT_EQ(value.value_tuple().dimensions_value(0)
1702 .value_tuple().dimensions_value_size(), 1);
1703 EXPECT_EQ(value.value_tuple().dimensions_value(0)
1704 .value_tuple().dimensions_value(0).field(), 1);
1705 EXPECT_EQ(value.value_tuple().dimensions_value(0)
1706 .value_tuple().dimensions_value(0).value_int(), uid);
1707 }
1708
ValidateUidDimension(const DimensionsValue & value,int node_idx,int atomId,int uid)1709 void ValidateUidDimension(const DimensionsValue& value, int node_idx, int atomId, int uid) {
1710 EXPECT_EQ(value.field(), atomId);
1711 ASSERT_GT(value.value_tuple().dimensions_value_size(), node_idx);
1712 // Attribution field.
1713 EXPECT_EQ(value.value_tuple().dimensions_value(node_idx).field(), 1);
1714 EXPECT_EQ(value.value_tuple().dimensions_value(node_idx)
1715 .value_tuple().dimensions_value(0).field(), 1);
1716 EXPECT_EQ(value.value_tuple().dimensions_value(node_idx)
1717 .value_tuple().dimensions_value(0).value_int(), uid);
1718 }
1719
ValidateAttributionUidAndTagDimension(const DimensionsValue & value,int node_idx,int atomId,int uid,const std::string & tag)1720 void ValidateAttributionUidAndTagDimension(
1721 const DimensionsValue& value, int node_idx, int atomId, int uid, const std::string& tag) {
1722 EXPECT_EQ(value.field(), atomId);
1723 ASSERT_GT(value.value_tuple().dimensions_value_size(), node_idx);
1724 // Attribution field.
1725 EXPECT_EQ(1, value.value_tuple().dimensions_value(node_idx).field());
1726 // Uid only.
1727 EXPECT_EQ(2, value.value_tuple().dimensions_value(node_idx)
1728 .value_tuple().dimensions_value_size());
1729 EXPECT_EQ(1, value.value_tuple().dimensions_value(node_idx)
1730 .value_tuple().dimensions_value(0).field());
1731 EXPECT_EQ(uid, value.value_tuple().dimensions_value(node_idx)
1732 .value_tuple().dimensions_value(0).value_int());
1733 EXPECT_EQ(2, value.value_tuple().dimensions_value(node_idx)
1734 .value_tuple().dimensions_value(1).field());
1735 EXPECT_EQ(tag, value.value_tuple().dimensions_value(node_idx)
1736 .value_tuple().dimensions_value(1).value_str());
1737 }
1738
ValidateAttributionUidAndTagDimension(const DimensionsValue & value,int atomId,int uid,const std::string & tag)1739 void ValidateAttributionUidAndTagDimension(
1740 const DimensionsValue& value, int atomId, int uid, const std::string& tag) {
1741 EXPECT_EQ(value.field(), atomId);
1742 ASSERT_EQ(1, value.value_tuple().dimensions_value_size());
1743 // Attribution field.
1744 EXPECT_EQ(1, value.value_tuple().dimensions_value(0).field());
1745 // Uid only.
1746 EXPECT_EQ(value.value_tuple().dimensions_value(0)
1747 .value_tuple().dimensions_value_size(), 2);
1748 EXPECT_EQ(value.value_tuple().dimensions_value(0)
1749 .value_tuple().dimensions_value(0).field(), 1);
1750 EXPECT_EQ(value.value_tuple().dimensions_value(0)
1751 .value_tuple().dimensions_value(0).value_int(), uid);
1752 EXPECT_EQ(value.value_tuple().dimensions_value(0)
1753 .value_tuple().dimensions_value(1).field(), 2);
1754 EXPECT_EQ(value.value_tuple().dimensions_value(0)
1755 .value_tuple().dimensions_value(1).value_str(), tag);
1756 }
1757
ValidateStateValue(const google::protobuf::RepeatedPtrField<StateValue> & stateValues,int atomId,int64_t value)1758 void ValidateStateValue(const google::protobuf::RepeatedPtrField<StateValue>& stateValues,
1759 int atomId, int64_t value) {
1760 ASSERT_EQ(stateValues.size(), 1);
1761 ASSERT_EQ(stateValues[0].atom_id(), atomId);
1762 switch (stateValues[0].contents_case()) {
1763 case StateValue::ContentsCase::kValue:
1764 EXPECT_EQ(stateValues[0].value(), (int32_t)value);
1765 break;
1766 case StateValue::ContentsCase::kGroupId:
1767 EXPECT_EQ(stateValues[0].group_id(), value);
1768 break;
1769 default:
1770 FAIL() << "State value should have either a value or a group id";
1771 }
1772 }
1773
ValidateCountBucket(const CountBucketInfo & countBucket,int64_t startTimeNs,int64_t endTimeNs,int64_t count,int64_t conditionTrueNs)1774 void ValidateCountBucket(const CountBucketInfo& countBucket, int64_t startTimeNs, int64_t endTimeNs,
1775 int64_t count, int64_t conditionTrueNs) {
1776 EXPECT_EQ(countBucket.start_bucket_elapsed_nanos(), startTimeNs);
1777 EXPECT_EQ(countBucket.end_bucket_elapsed_nanos(), endTimeNs);
1778 EXPECT_EQ(countBucket.count(), count);
1779 EXPECT_EQ(countBucket.condition_true_nanos(), conditionTrueNs);
1780 }
1781
ValidateDurationBucket(const DurationBucketInfo & bucket,int64_t startTimeNs,int64_t endTimeNs,int64_t durationNs,int64_t conditionTrueNs)1782 void ValidateDurationBucket(const DurationBucketInfo& bucket, int64_t startTimeNs,
1783 int64_t endTimeNs, int64_t durationNs, int64_t conditionTrueNs) {
1784 EXPECT_EQ(bucket.start_bucket_elapsed_nanos(), startTimeNs);
1785 EXPECT_EQ(bucket.end_bucket_elapsed_nanos(), endTimeNs);
1786 EXPECT_EQ(bucket.duration_nanos(), durationNs);
1787 EXPECT_EQ(bucket.condition_true_nanos(), conditionTrueNs);
1788 }
1789
ValidateGaugeBucketTimes(const GaugeBucketInfo & gaugeBucket,int64_t startTimeNs,int64_t endTimeNs,vector<int64_t> eventTimesNs)1790 void ValidateGaugeBucketTimes(const GaugeBucketInfo& gaugeBucket, int64_t startTimeNs,
1791 int64_t endTimeNs, vector<int64_t> eventTimesNs) {
1792 EXPECT_EQ(gaugeBucket.start_bucket_elapsed_nanos(), startTimeNs);
1793 EXPECT_EQ(gaugeBucket.end_bucket_elapsed_nanos(), endTimeNs);
1794 EXPECT_EQ(gaugeBucket.elapsed_timestamp_nanos_size(), eventTimesNs.size());
1795 for (int i = 0; i < eventTimesNs.size(); i++) {
1796 EXPECT_EQ(gaugeBucket.elapsed_timestamp_nanos(i), eventTimesNs[i]);
1797 }
1798 }
1799
ValidateValueBucket(const ValueBucketInfo & bucket,int64_t startTimeNs,int64_t endTimeNs,const vector<int64_t> & values,int64_t conditionTrueNs,int64_t conditionCorrectionNs)1800 void ValidateValueBucket(const ValueBucketInfo& bucket, int64_t startTimeNs, int64_t endTimeNs,
1801 const vector<int64_t>& values, int64_t conditionTrueNs,
1802 int64_t conditionCorrectionNs) {
1803 EXPECT_EQ(bucket.start_bucket_elapsed_nanos(), startTimeNs);
1804 EXPECT_EQ(bucket.end_bucket_elapsed_nanos(), endTimeNs);
1805 ASSERT_EQ(bucket.values_size(), values.size());
1806 for (int i = 0; i < values.size(); ++i) {
1807 if (bucket.values(i).has_value_double()) {
1808 EXPECT_EQ((int64_t)bucket.values(i).value_double(), values[i]);
1809 } else {
1810 EXPECT_EQ(bucket.values(i).value_long(), values[i]);
1811 }
1812 }
1813 if (conditionTrueNs > 0) {
1814 EXPECT_EQ(bucket.condition_true_nanos(), conditionTrueNs);
1815 if (conditionCorrectionNs > 0) {
1816 EXPECT_EQ(bucket.condition_correction_nanos(), conditionCorrectionNs);
1817 }
1818 }
1819 }
1820
ValidateKllBucket(const KllBucketInfo & bucket,int64_t startTimeNs,int64_t endTimeNs,const vector<int64_t> sketchSizes,int64_t conditionTrueNs)1821 void ValidateKllBucket(const KllBucketInfo& bucket, int64_t startTimeNs, int64_t endTimeNs,
1822 const vector<int64_t> sketchSizes, int64_t conditionTrueNs) {
1823 EXPECT_EQ(bucket.start_bucket_elapsed_nanos(), startTimeNs);
1824 EXPECT_EQ(bucket.end_bucket_elapsed_nanos(), endTimeNs);
1825 ASSERT_EQ(bucket.sketches_size(), sketchSizes.size());
1826 for (int i = 0; i < sketchSizes.size(); ++i) {
1827 AggregatorStateProto aggProto;
1828 EXPECT_TRUE(aggProto.ParseFromString(bucket.sketches(i).kll_sketch()));
1829 EXPECT_EQ(aggProto.num_values(), sketchSizes[i]);
1830 }
1831 if (conditionTrueNs > 0) {
1832 EXPECT_EQ(bucket.condition_true_nanos(), conditionTrueNs);
1833 }
1834 }
1835
EqualsTo(const DimensionsValue & s1,const DimensionsValue & s2)1836 bool EqualsTo(const DimensionsValue& s1, const DimensionsValue& s2) {
1837 if (s1.field() != s2.field()) {
1838 return false;
1839 }
1840 if (s1.value_case() != s2.value_case()) {
1841 return false;
1842 }
1843 switch (s1.value_case()) {
1844 case DimensionsValue::ValueCase::kValueStr:
1845 return (s1.value_str() == s2.value_str());
1846 case DimensionsValue::ValueCase::kValueInt:
1847 return s1.value_int() == s2.value_int();
1848 case DimensionsValue::ValueCase::kValueLong:
1849 return s1.value_long() == s2.value_long();
1850 case DimensionsValue::ValueCase::kValueBool:
1851 return s1.value_bool() == s2.value_bool();
1852 case DimensionsValue::ValueCase::kValueFloat:
1853 return s1.value_float() == s2.value_float();
1854 case DimensionsValue::ValueCase::kValueTuple: {
1855 if (s1.value_tuple().dimensions_value_size() !=
1856 s2.value_tuple().dimensions_value_size()) {
1857 return false;
1858 }
1859 bool allMatched = true;
1860 for (int i = 0; allMatched && i < s1.value_tuple().dimensions_value_size(); ++i) {
1861 allMatched &= EqualsTo(s1.value_tuple().dimensions_value(i),
1862 s2.value_tuple().dimensions_value(i));
1863 }
1864 return allMatched;
1865 }
1866 case DimensionsValue::ValueCase::VALUE_NOT_SET:
1867 default:
1868 return true;
1869 }
1870 }
1871
LessThan(const google::protobuf::RepeatedPtrField<StateValue> & s1,const google::protobuf::RepeatedPtrField<StateValue> & s2)1872 bool LessThan(const google::protobuf::RepeatedPtrField<StateValue>& s1,
1873 const google::protobuf::RepeatedPtrField<StateValue>& s2) {
1874 if (s1.size() != s2.size()) {
1875 return s1.size() < s2.size();
1876 }
1877 for (int i = 0; i < s1.size(); i++) {
1878 const StateValue& state1 = s1[i];
1879 const StateValue& state2 = s2[i];
1880 if (state1.atom_id() != state2.atom_id()) {
1881 return state1.atom_id() < state2.atom_id();
1882 }
1883 if (state1.value() != state2.value()) {
1884 return state1.value() < state2.value();
1885 }
1886 if (state1.group_id() != state2.group_id()) {
1887 return state1.group_id() < state2.group_id();
1888 }
1889 }
1890 return false;
1891 }
1892
LessThan(const DimensionsValue & s1,const DimensionsValue & s2)1893 bool LessThan(const DimensionsValue& s1, const DimensionsValue& s2) {
1894 if (s1.field() != s2.field()) {
1895 return s1.field() < s2.field();
1896 }
1897 if (s1.value_case() != s2.value_case()) {
1898 return s1.value_case() < s2.value_case();
1899 }
1900 switch (s1.value_case()) {
1901 case DimensionsValue::ValueCase::kValueStr:
1902 return s1.value_str() < s2.value_str();
1903 case DimensionsValue::ValueCase::kValueInt:
1904 return s1.value_int() < s2.value_int();
1905 case DimensionsValue::ValueCase::kValueLong:
1906 return s1.value_long() < s2.value_long();
1907 case DimensionsValue::ValueCase::kValueBool:
1908 return (int)s1.value_bool() < (int)s2.value_bool();
1909 case DimensionsValue::ValueCase::kValueFloat:
1910 return s1.value_float() < s2.value_float();
1911 case DimensionsValue::ValueCase::kValueTuple: {
1912 if (s1.value_tuple().dimensions_value_size() !=
1913 s2.value_tuple().dimensions_value_size()) {
1914 return s1.value_tuple().dimensions_value_size() <
1915 s2.value_tuple().dimensions_value_size();
1916 }
1917 for (int i = 0; i < s1.value_tuple().dimensions_value_size(); ++i) {
1918 if (EqualsTo(s1.value_tuple().dimensions_value(i),
1919 s2.value_tuple().dimensions_value(i))) {
1920 continue;
1921 } else {
1922 return LessThan(s1.value_tuple().dimensions_value(i),
1923 s2.value_tuple().dimensions_value(i));
1924 }
1925 }
1926 return false;
1927 }
1928 case DimensionsValue::ValueCase::VALUE_NOT_SET:
1929 default:
1930 return false;
1931 }
1932 }
1933
LessThan(const DimensionsPair & s1,const DimensionsPair & s2)1934 bool LessThan(const DimensionsPair& s1, const DimensionsPair& s2) {
1935 if (LessThan(s1.dimInWhat, s2.dimInWhat)) {
1936 return true;
1937 } else if (LessThan(s2.dimInWhat, s1.dimInWhat)) {
1938 return false;
1939 }
1940
1941 return LessThan(s1.stateValues, s2.stateValues);
1942 }
1943
backfillStringInDimension(const std::map<uint64_t,string> & str_map,DimensionsValue * dimension)1944 void backfillStringInDimension(const std::map<uint64_t, string>& str_map,
1945 DimensionsValue* dimension) {
1946 if (dimension->has_value_str_hash()) {
1947 auto it = str_map.find((uint64_t)(dimension->value_str_hash()));
1948 if (it != str_map.end()) {
1949 dimension->clear_value_str_hash();
1950 dimension->set_value_str(it->second);
1951 } else {
1952 ALOGE("Can not find the string hash: %llu",
1953 (unsigned long long)dimension->value_str_hash());
1954 }
1955 } else if (dimension->has_value_tuple()) {
1956 auto value_tuple = dimension->mutable_value_tuple();
1957 for (int i = 0; i < value_tuple->dimensions_value_size(); ++i) {
1958 backfillStringInDimension(str_map, value_tuple->mutable_dimensions_value(i));
1959 }
1960 }
1961 }
1962
backfillStringInReport(ConfigMetricsReport * config_report)1963 void backfillStringInReport(ConfigMetricsReport *config_report) {
1964 std::map<uint64_t, string> str_map;
1965 for (const auto& str : config_report->strings()) {
1966 uint64_t hash = Hash64(str);
1967 if (str_map.find(hash) != str_map.end()) {
1968 ALOGE("String hash conflicts: %s %s", str.c_str(), str_map[hash].c_str());
1969 }
1970 str_map[hash] = str;
1971 }
1972 for (int i = 0; i < config_report->metrics_size(); ++i) {
1973 auto metric_report = config_report->mutable_metrics(i);
1974 if (metric_report->has_count_metrics()) {
1975 backfillStringInDimension(str_map, metric_report->mutable_count_metrics());
1976 } else if (metric_report->has_duration_metrics()) {
1977 backfillStringInDimension(str_map, metric_report->mutable_duration_metrics());
1978 } else if (metric_report->has_gauge_metrics()) {
1979 backfillStringInDimension(str_map, metric_report->mutable_gauge_metrics());
1980 } else if (metric_report->has_value_metrics()) {
1981 backfillStringInDimension(str_map, metric_report->mutable_value_metrics());
1982 } else if (metric_report->has_kll_metrics()) {
1983 backfillStringInDimension(str_map, metric_report->mutable_kll_metrics());
1984 }
1985 }
1986 // Backfill the package names.
1987 for (int i = 0 ; i < config_report->uid_map().snapshots_size(); ++i) {
1988 auto snapshot = config_report->mutable_uid_map()->mutable_snapshots(i);
1989 for (int j = 0 ; j < snapshot->package_info_size(); ++j) {
1990 auto package_info = snapshot->mutable_package_info(j);
1991 if (package_info->has_name_hash()) {
1992 auto it = str_map.find((uint64_t)(package_info->name_hash()));
1993 if (it != str_map.end()) {
1994 package_info->clear_name_hash();
1995 package_info->set_name(it->second);
1996 } else {
1997 ALOGE("Can not find the string package name hash: %llu",
1998 (unsigned long long)package_info->name_hash());
1999 }
2000
2001 }
2002 }
2003 }
2004 // Backfill the app name in app changes.
2005 for (int i = 0 ; i < config_report->uid_map().changes_size(); ++i) {
2006 auto change = config_report->mutable_uid_map()->mutable_changes(i);
2007 if (change->has_app_hash()) {
2008 auto it = str_map.find((uint64_t)(change->app_hash()));
2009 if (it != str_map.end()) {
2010 change->clear_app_hash();
2011 change->set_app(it->second);
2012 } else {
2013 ALOGE("Can not find the string change app name hash: %llu",
2014 (unsigned long long)change->app_hash());
2015 }
2016 }
2017 }
2018 }
2019
backfillStringInReport(ConfigMetricsReportList * config_report_list)2020 void backfillStringInReport(ConfigMetricsReportList *config_report_list) {
2021 for (int i = 0; i < config_report_list->reports_size(); ++i) {
2022 backfillStringInReport(config_report_list->mutable_reports(i));
2023 }
2024 }
2025
backfillDimensionPath(const DimensionsValue & path,const google::protobuf::RepeatedPtrField<DimensionsValue> & leafValues,int * leafIndex,DimensionsValue * dimension)2026 bool backfillDimensionPath(const DimensionsValue& path,
2027 const google::protobuf::RepeatedPtrField<DimensionsValue>& leafValues,
2028 int* leafIndex, DimensionsValue* dimension) {
2029 dimension->set_field(path.field());
2030 if (path.has_value_tuple()) {
2031 for (int i = 0; i < path.value_tuple().dimensions_value_size(); ++i) {
2032 if (!backfillDimensionPath(path.value_tuple().dimensions_value(i), leafValues,
2033 leafIndex,
2034 dimension->mutable_value_tuple()->add_dimensions_value())) {
2035 return false;
2036 }
2037 }
2038 } else {
2039 if (*leafIndex < 0 || *leafIndex >= leafValues.size()) {
2040 return false;
2041 }
2042 dimension->MergeFrom(leafValues.Get(*leafIndex));
2043 (*leafIndex)++;
2044 }
2045 return true;
2046 }
2047
backfillDimensionPath(const DimensionsValue & path,const google::protobuf::RepeatedPtrField<DimensionsValue> & leafValues,DimensionsValue * dimension)2048 bool backfillDimensionPath(const DimensionsValue& path,
2049 const google::protobuf::RepeatedPtrField<DimensionsValue>& leafValues,
2050 DimensionsValue* dimension) {
2051 int leafIndex = 0;
2052 return backfillDimensionPath(path, leafValues, &leafIndex, dimension);
2053 }
2054
backfillDimensionPath(StatsLogReport * report)2055 void backfillDimensionPath(StatsLogReport* report) {
2056 if (report->has_dimensions_path_in_what()) {
2057 auto whatPath = report->dimensions_path_in_what();
2058 if (report->has_count_metrics()) {
2059 backfillDimensionPath(whatPath, report->mutable_count_metrics());
2060 } else if (report->has_duration_metrics()) {
2061 backfillDimensionPath(whatPath, report->mutable_duration_metrics());
2062 } else if (report->has_gauge_metrics()) {
2063 backfillDimensionPath(whatPath, report->mutable_gauge_metrics());
2064 } else if (report->has_value_metrics()) {
2065 backfillDimensionPath(whatPath, report->mutable_value_metrics());
2066 } else if (report->has_kll_metrics()) {
2067 backfillDimensionPath(whatPath, report->mutable_kll_metrics());
2068 }
2069 report->clear_dimensions_path_in_what();
2070 }
2071 }
2072
backfillDimensionPath(ConfigMetricsReport * config_report)2073 void backfillDimensionPath(ConfigMetricsReport* config_report) {
2074 for (int i = 0; i < config_report->metrics_size(); ++i) {
2075 backfillDimensionPath(config_report->mutable_metrics(i));
2076 }
2077 }
2078
backfillDimensionPath(ConfigMetricsReportList * config_report_list)2079 void backfillDimensionPath(ConfigMetricsReportList* config_report_list) {
2080 for (int i = 0; i < config_report_list->reports_size(); ++i) {
2081 backfillDimensionPath(config_report_list->mutable_reports(i));
2082 }
2083 }
2084
backfillStartEndTimestamp(StatsLogReport * report)2085 void backfillStartEndTimestamp(StatsLogReport *report) {
2086 const int64_t timeBaseNs = report->time_base_elapsed_nano_seconds();
2087 const int64_t bucketSizeNs = report->bucket_size_nano_seconds();
2088 if (report->has_count_metrics()) {
2089 backfillStartEndTimestampForMetrics(
2090 timeBaseNs, bucketSizeNs, report->mutable_count_metrics());
2091 } else if (report->has_duration_metrics()) {
2092 backfillStartEndTimestampForMetrics(
2093 timeBaseNs, bucketSizeNs, report->mutable_duration_metrics());
2094 } else if (report->has_gauge_metrics()) {
2095 backfillStartEndTimestampForMetrics(
2096 timeBaseNs, bucketSizeNs, report->mutable_gauge_metrics());
2097 if (report->gauge_metrics().skipped_size() > 0) {
2098 backfillStartEndTimestampForSkippedBuckets(
2099 timeBaseNs, report->mutable_gauge_metrics());
2100 }
2101 } else if (report->has_value_metrics()) {
2102 backfillStartEndTimestampForMetrics(
2103 timeBaseNs, bucketSizeNs, report->mutable_value_metrics());
2104 if (report->value_metrics().skipped_size() > 0) {
2105 backfillStartEndTimestampForSkippedBuckets(
2106 timeBaseNs, report->mutable_value_metrics());
2107 }
2108 } else if (report->has_kll_metrics()) {
2109 backfillStartEndTimestampForMetrics(timeBaseNs, bucketSizeNs,
2110 report->mutable_kll_metrics());
2111 if (report->kll_metrics().skipped_size() > 0) {
2112 backfillStartEndTimestampForSkippedBuckets(timeBaseNs, report->mutable_kll_metrics());
2113 }
2114 }
2115 }
2116
backfillStartEndTimestamp(ConfigMetricsReport * config_report)2117 void backfillStartEndTimestamp(ConfigMetricsReport *config_report) {
2118 for (int j = 0; j < config_report->metrics_size(); ++j) {
2119 backfillStartEndTimestamp(config_report->mutable_metrics(j));
2120 }
2121 }
2122
backfillStartEndTimestamp(ConfigMetricsReportList * config_report_list)2123 void backfillStartEndTimestamp(ConfigMetricsReportList *config_report_list) {
2124 for (int i = 0; i < config_report_list->reports_size(); ++i) {
2125 backfillStartEndTimestamp(config_report_list->mutable_reports(i));
2126 }
2127 }
2128
backfillAggregatedAtoms(ConfigMetricsReportList * config_report_list)2129 void backfillAggregatedAtoms(ConfigMetricsReportList* config_report_list) {
2130 for (int i = 0; i < config_report_list->reports_size(); ++i) {
2131 backfillAggregatedAtoms(config_report_list->mutable_reports(i));
2132 }
2133 }
2134
backfillAggregatedAtoms(ConfigMetricsReport * config_report)2135 void backfillAggregatedAtoms(ConfigMetricsReport* config_report) {
2136 for (int i = 0; i < config_report->metrics_size(); ++i) {
2137 backfillAggregatedAtoms(config_report->mutable_metrics(i));
2138 }
2139 }
2140
backfillAggregatedAtoms(StatsLogReport * report)2141 void backfillAggregatedAtoms(StatsLogReport* report) {
2142 if (report->has_event_metrics()) {
2143 backfillAggregatedAtomsInEventMetric(report->mutable_event_metrics());
2144 }
2145 if (report->has_gauge_metrics()) {
2146 backfillAggregatedAtomsInGaugeMetric(report->mutable_gauge_metrics());
2147 }
2148 }
2149
backfillAggregatedAtomsInEventMetric(StatsLogReport::EventMetricDataWrapper * wrapper)2150 void backfillAggregatedAtomsInEventMetric(StatsLogReport::EventMetricDataWrapper* wrapper) {
2151 std::vector<EventMetricData> metricData;
2152 for (int i = 0; i < wrapper->data_size(); ++i) {
2153 AggregatedAtomInfo* atomInfo = wrapper->mutable_data(i)->mutable_aggregated_atom_info();
2154 for (int j = 0; j < atomInfo->elapsed_timestamp_nanos_size(); j++) {
2155 EventMetricData data;
2156 *(data.mutable_atom()) = atomInfo->atom();
2157 data.set_elapsed_timestamp_nanos(atomInfo->elapsed_timestamp_nanos(j));
2158 metricData.push_back(data);
2159 }
2160 for (int j = 0; j < atomInfo->state_info_size(); j++) {
2161 for (auto timestampNs : atomInfo->state_info(j).elapsed_timestamp_nanos()) {
2162 EventMetricData data;
2163 *(data.mutable_atom()) = atomInfo->atom();
2164 for (auto state : atomInfo->state_info(j).slice_by_state()) {
2165 *(data.add_slice_by_state()) = state;
2166 }
2167 data.set_elapsed_timestamp_nanos(timestampNs);
2168 metricData.push_back(data);
2169 }
2170 }
2171 }
2172
2173 if (metricData.size() == 0) {
2174 return;
2175 }
2176
2177 sort(metricData.begin(), metricData.end(),
2178 [](const EventMetricData& lhs, const EventMetricData& rhs) {
2179 return lhs.elapsed_timestamp_nanos() < rhs.elapsed_timestamp_nanos();
2180 });
2181
2182 wrapper->clear_data();
2183 for (int i = 0; i < metricData.size(); ++i) {
2184 *(wrapper->add_data()) = metricData[i];
2185 }
2186 }
2187
backfillAggregatedAtomsInGaugeMetric(StatsLogReport::GaugeMetricDataWrapper * wrapper)2188 void backfillAggregatedAtomsInGaugeMetric(StatsLogReport::GaugeMetricDataWrapper* wrapper) {
2189 for (int i = 0; i < wrapper->data_size(); ++i) {
2190 for (int j = 0; j < wrapper->data(i).bucket_info_size(); ++j) {
2191 GaugeBucketInfo* bucketInfo = wrapper->mutable_data(i)->mutable_bucket_info(j);
2192 vector<pair<Atom, int64_t>> atomData = unnestGaugeAtomData(*bucketInfo);
2193
2194 if (atomData.size() == 0) {
2195 return;
2196 }
2197
2198 bucketInfo->clear_aggregated_atom_info();
2199 ASSERT_EQ(bucketInfo->atom_size(), 0);
2200 ASSERT_EQ(bucketInfo->elapsed_timestamp_nanos_size(), 0);
2201
2202 for (int k = 0; k < atomData.size(); ++k) {
2203 *(bucketInfo->add_atom()) = atomData[k].first;
2204 bucketInfo->add_elapsed_timestamp_nanos(atomData[k].second);
2205 }
2206 }
2207 }
2208 }
2209
unnestGaugeAtomData(const GaugeBucketInfo & bucketInfo)2210 vector<pair<Atom, int64_t>> unnestGaugeAtomData(const GaugeBucketInfo& bucketInfo) {
2211 vector<pair<Atom, int64_t>> atomData;
2212 for (int k = 0; k < bucketInfo.aggregated_atom_info_size(); ++k) {
2213 const AggregatedAtomInfo& atomInfo = bucketInfo.aggregated_atom_info(k);
2214 for (int l = 0; l < atomInfo.elapsed_timestamp_nanos_size(); ++l) {
2215 atomData.push_back(make_pair(atomInfo.atom(), atomInfo.elapsed_timestamp_nanos(l)));
2216 }
2217 }
2218
2219 sort(atomData.begin(), atomData.end(),
2220 [](const pair<Atom, int64_t>& lhs, const pair<Atom, int64_t>& rhs) {
2221 return lhs.second < rhs.second;
2222 });
2223
2224 return atomData;
2225 }
2226
sortReportsByElapsedTime(ConfigMetricsReportList * configReportList)2227 void sortReportsByElapsedTime(ConfigMetricsReportList* configReportList) {
2228 RepeatedPtrField<ConfigMetricsReport>* reports = configReportList->mutable_reports();
2229 sort(reports->pointer_begin(), reports->pointer_end(),
2230 [](const ConfigMetricsReport* lhs, const ConfigMetricsReport* rhs) {
2231 return lhs->current_report_elapsed_nanos() < rhs->current_report_elapsed_nanos();
2232 });
2233 }
2234
onPullAtom(int atomTag,const shared_ptr<IPullAtomResultReceiver> & resultReceiver)2235 Status FakeSubsystemSleepCallback::onPullAtom(int atomTag,
2236 const shared_ptr<IPullAtomResultReceiver>& resultReceiver) {
2237 // Convert stats_events into StatsEventParcels.
2238 std::vector<StatsEventParcel> parcels;
2239 for (int i = 1; i < 3; i++) {
2240 AStatsEvent* event = AStatsEvent_obtain();
2241 AStatsEvent_setAtomId(event, atomTag);
2242 std::string subsystemName = "subsystem_name_";
2243 subsystemName = subsystemName + std::to_string(i);
2244 AStatsEvent_writeString(event, subsystemName.c_str());
2245 AStatsEvent_writeString(event, "subsystem_subname foo");
2246 AStatsEvent_writeInt64(event, /*count= */ i);
2247 AStatsEvent_writeInt64(event, /*time_millis= */ pullNum * pullNum * 100 + i);
2248 AStatsEvent_build(event);
2249 size_t size;
2250 uint8_t* buffer = AStatsEvent_getBuffer(event, &size);
2251
2252 StatsEventParcel p;
2253 // vector.assign() creates a copy, but this is inevitable unless
2254 // stats_event.h/c uses a vector as opposed to a buffer.
2255 p.buffer.assign(buffer, buffer + size);
2256 parcels.push_back(std::move(p));
2257 AStatsEvent_release(event);
2258 }
2259 pullNum++;
2260 resultReceiver->pullFinished(atomTag, /*success=*/true, parcels);
2261 return Status::ok();
2262 }
2263
onPullAtom(int atomTag,const shared_ptr<IPullAtomResultReceiver> & resultReceiver)2264 Status FakeCpuTimeCallback::onPullAtom(int atomTag,
2265 const shared_ptr<IPullAtomResultReceiver>& resultReceiver) {
2266 // Convert stats_events into StatsEventParcels.
2267 std::vector<StatsEventParcel> parcels;
2268 for (int i = 1; i < 3; i++) {
2269 AStatsEvent* event = AStatsEvent_obtain();
2270 AStatsEvent_setAtomId(event, atomTag);
2271 AStatsEvent_writeInt32(event, /*uid=*/i);
2272 AStatsEvent_writeInt64(event, /*user_time_micros= */ pullNum * pullNum * 100 + i);
2273 AStatsEvent_writeInt64(event, /*sys_time_micros= */ pullNum * pullNum * 100 * i);
2274 AStatsEvent_build(event);
2275 size_t size;
2276 uint8_t* buffer = AStatsEvent_getBuffer(event, &size);
2277
2278 StatsEventParcel p;
2279 // vector.assign() creates a copy, but this is inevitable unless
2280 // stats_event.h/c uses a vector as opposed to a buffer.
2281 p.buffer.assign(buffer, buffer + size);
2282 parcels.push_back(std::move(p));
2283 AStatsEvent_release(event);
2284 }
2285 pullNum++;
2286 resultReceiver->pullFinished(atomTag, /*success=*/true, parcels);
2287 return Status::ok();
2288 }
2289
writeFlag(const string & flagName,const string & flagValue)2290 void writeFlag(const string& flagName, const string& flagValue) {
2291 SetProperty(StringPrintf("persist.device_config.%s.%s", STATSD_NATIVE_NAMESPACE.c_str(),
2292 flagName.c_str()),
2293 flagValue);
2294 }
2295
writeBootFlag(const string & flagName,const string & flagValue)2296 void writeBootFlag(const string& flagName, const string& flagValue) {
2297 SetProperty(StringPrintf("persist.device_config.%s.%s", STATSD_NATIVE_BOOT_NAMESPACE.c_str(),
2298 flagName.c_str()),
2299 flagValue);
2300 }
2301
getPackageInfoSnapshot(const sp<UidMap> uidMap)2302 PackageInfoSnapshot getPackageInfoSnapshot(const sp<UidMap> uidMap) {
2303 ProtoOutputStream protoOutputStream;
2304 uidMap->writeUidMapSnapshot(/* timestamp */ 1,
2305 {/* includeVersionStrings */ true,
2306 /* includeInstaller */ true, /* certificateHashSize */ UINT8_MAX,
2307 /* omitSystemUids */ false},
2308 /* interestingUids */ {},
2309 /* installerIndices */ nullptr, /* str_set */ nullptr,
2310 &protoOutputStream);
2311
2312 PackageInfoSnapshot packageInfoSnapshot;
2313 outputStreamToProto(&protoOutputStream, &packageInfoSnapshot);
2314 return packageInfoSnapshot;
2315 }
2316
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)2317 PackageInfo buildPackageInfo(const string& name, const int32_t uid, const int64_t version,
2318 const string& versionString, const optional<string> installer,
2319 const vector<uint8_t>& certHash, const bool deleted,
2320 const bool hashStrings, const optional<uint32_t> installerIndex) {
2321 PackageInfo packageInfo;
2322 packageInfo.set_version(version);
2323 packageInfo.set_uid(uid);
2324 packageInfo.set_deleted(deleted);
2325 if (!certHash.empty()) {
2326 packageInfo.set_truncated_certificate_hash(certHash.data(), certHash.size());
2327 }
2328 if (hashStrings) {
2329 packageInfo.set_name_hash(Hash64(name));
2330 packageInfo.set_version_string_hash(Hash64(versionString));
2331 } else {
2332 packageInfo.set_name(name);
2333 packageInfo.set_version_string(versionString);
2334 }
2335 if (installer) {
2336 if (installerIndex) {
2337 packageInfo.set_installer_index(*installerIndex);
2338 } else if (hashStrings) {
2339 packageInfo.set_installer_hash(Hash64(*installer));
2340 } else {
2341 packageInfo.set_installer(*installer);
2342 }
2343 }
2344 return packageInfo;
2345 }
2346
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)2347 vector<PackageInfo> buildPackageInfos(
2348 const vector<string>& names, const vector<int32_t>& uids, const vector<int64_t>& versions,
2349 const vector<string>& versionStrings, const vector<string>& installers,
2350 const vector<vector<uint8_t>>& certHashes, const vector<uint8_t>& deleted,
2351 const vector<uint32_t>& installerIndices, const bool hashStrings) {
2352 vector<PackageInfo> packageInfos;
2353 for (int i = 0; i < uids.size(); i++) {
2354 const optional<uint32_t> installerIndex =
2355 installerIndices.empty() ? nullopt : optional<uint32_t>(installerIndices[i]);
2356 const optional<string> installer =
2357 installers.empty() ? nullopt : optional<string>(installers[i]);
2358 vector<uint8_t> certHash;
2359 if (!certHashes.empty()) {
2360 certHash = certHashes[i];
2361 }
2362 packageInfos.emplace_back(buildPackageInfo(names[i], uids[i], versions[i],
2363 versionStrings[i], installer, certHash,
2364 deleted[i], hashStrings, installerIndex));
2365 }
2366 return packageInfos;
2367 }
2368
createApplicationInfo(const int32_t uid,const int64_t version,const string & versionString,const string & package)2369 ApplicationInfo createApplicationInfo(const int32_t uid, const int64_t version,
2370 const string& versionString, const string& package) {
2371 ApplicationInfo info;
2372 info.set_uid(uid);
2373 info.set_version(version);
2374 info.set_version_string(versionString);
2375 info.set_package_name(package);
2376 return info;
2377 }
2378
getPulledAtomStats(int32_t atom_id)2379 StatsdStatsReport_PulledAtomStats getPulledAtomStats(int32_t atom_id) {
2380 StatsdStatsReport statsReport = getStatsdStatsReport();
2381 StatsdStatsReport_PulledAtomStats pulledAtomStats;
2382 for (size_t i = 0; i < statsReport.pulled_atom_stats_size(); i++) {
2383 if (statsReport.pulled_atom_stats(i).atom_id() == atom_id) {
2384 return statsReport.pulled_atom_stats(i);
2385 }
2386 }
2387 return pulledAtomStats;
2388 }
2389
createStatsEvent(AStatsEvent * statsEvent,uint8_t typeId,uint32_t atomId)2390 void createStatsEvent(AStatsEvent* statsEvent, uint8_t typeId, uint32_t atomId) {
2391 AStatsEvent_setAtomId(statsEvent, atomId);
2392 fillStatsEventWithSampleValue(statsEvent, typeId);
2393 }
2394
fillStatsEventWithSampleValue(AStatsEvent * statsEvent,uint8_t typeId)2395 void fillStatsEventWithSampleValue(AStatsEvent* statsEvent, uint8_t typeId) {
2396 int int32Array[2] = {3, 6};
2397 uint32_t uids[] = {1001, 1002};
2398 const char* tags[] = {"tag1", "tag2"};
2399
2400 switch (typeId) {
2401 case INT32_TYPE:
2402 AStatsEvent_writeInt32(statsEvent, 10);
2403 break;
2404 case INT64_TYPE:
2405 AStatsEvent_writeInt64(statsEvent, 1000L);
2406 break;
2407 case STRING_TYPE:
2408 AStatsEvent_writeString(statsEvent, "test");
2409 break;
2410 case LIST_TYPE:
2411 if (__builtin_available(android __ANDROID_API_T__, *)) {
2412 /* CAUTION: when using this function with LIST_TYPE,
2413 wrap the code in a __builtin_available or __INTRODUCED_IN w/ T.
2414 */
2415 AStatsEvent_writeInt32Array(statsEvent, int32Array, 2);
2416 } else {
2417 ADD_FAILURE() << "fillStatsEventWithSampleValue() w/ typeId LIST_TYPE should only "
2418 "be used on Android T or above.";
2419 }
2420 break;
2421 case FLOAT_TYPE:
2422 AStatsEvent_writeFloat(statsEvent, 1.3f);
2423 break;
2424 case BOOL_TYPE:
2425 AStatsEvent_writeBool(statsEvent, 1);
2426 break;
2427 case BYTE_ARRAY_TYPE:
2428 AStatsEvent_writeByteArray(statsEvent, (uint8_t*)"test", strlen("test"));
2429 break;
2430 case ATTRIBUTION_CHAIN_TYPE:
2431 AStatsEvent_writeAttributionChain(statsEvent, uids, tags, 2);
2432 break;
2433 default:
2434 break;
2435 }
2436 }
2437
getStatsdStatsReport(bool resetStats)2438 StatsdStatsReport getStatsdStatsReport(bool resetStats) {
2439 StatsdStats& stats = StatsdStats::getInstance();
2440 return getStatsdStatsReport(stats, resetStats);
2441 }
2442
getStatsdStatsReport(StatsdStats & stats,bool resetStats)2443 StatsdStatsReport getStatsdStatsReport(StatsdStats& stats, bool resetStats) {
2444 vector<uint8_t> statsBuffer;
2445 stats.dumpStats(&statsBuffer, resetStats);
2446 StatsdStatsReport statsReport;
2447 EXPECT_TRUE(statsReport.ParseFromArray(statsBuffer.data(), statsBuffer.size()));
2448 return statsReport;
2449 }
2450
buildGoodConfig(int configId)2451 StatsdConfig buildGoodConfig(int configId) {
2452 StatsdConfig config;
2453 config.set_id(configId);
2454
2455 AtomMatcher screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
2456 *config.add_atom_matcher() = screenOnMatcher;
2457 *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
2458
2459 AtomMatcher* eventMatcher = config.add_atom_matcher();
2460 eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF"));
2461 AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
2462 combination->set_operation(LogicalOperation::OR);
2463 combination->add_matcher(screenOnMatcher.id());
2464 combination->add_matcher(StringToId("ScreenTurnedOff"));
2465
2466 CountMetric* countMetric = config.add_count_metric();
2467 *countMetric = createCountMetric("Count", screenOnMatcher.id() /* what */,
2468 nullopt /* condition */, {} /* states */);
2469 countMetric->mutable_dimensions_in_what()->set_field(SCREEN_STATE_ATOM_ID);
2470 countMetric->mutable_dimensions_in_what()->add_child()->set_field(1);
2471
2472 config.add_no_report_metric(StringToId("Count"));
2473
2474 *config.add_predicate() = CreateScreenIsOnPredicate();
2475 *config.add_duration_metric() =
2476 createDurationMetric("Duration", StringToId("ScreenIsOn") /* what */,
2477 nullopt /* condition */, {} /* states */);
2478
2479 *config.add_gauge_metric() = createGaugeMetric(
2480 "Gauge", screenOnMatcher.id() /* what */, GaugeMetric_SamplingType_FIRST_N_SAMPLES,
2481 nullopt /* condition */, nullopt /* triggerEvent */);
2482
2483 *config.add_value_metric() =
2484 createValueMetric("Value", screenOnMatcher /* what */, 2 /* valueField */,
2485 nullopt /* condition */, {} /* states */);
2486
2487 *config.add_kll_metric() = createKllMetric("Kll", screenOnMatcher /* what */, 2 /* kllField */,
2488 nullopt /* condition */);
2489
2490 return config;
2491 }
2492
buildGoodConfig(int configId,int alertId)2493 StatsdConfig buildGoodConfig(int configId, int alertId) {
2494 StatsdConfig config = buildGoodConfig(configId);
2495 auto alert = config.add_alert();
2496 alert->set_id(alertId);
2497 alert->set_metric_id(StringToId("Count"));
2498 alert->set_num_buckets(10);
2499 alert->set_refractory_period_secs(100);
2500 alert->set_trigger_if_sum_gt(100);
2501
2502 return config;
2503 }
2504
makeMockConfigMetadataProvider(bool enabled)2505 sp<MockConfigMetadataProvider> makeMockConfigMetadataProvider(bool enabled) {
2506 sp<MockConfigMetadataProvider> metadataProvider = new StrictMock<MockConfigMetadataProvider>();
2507 EXPECT_CALL(*metadataProvider, useV2SoftMemoryCalculation()).Times(AnyNumber());
2508 EXPECT_CALL(*metadataProvider, useV2SoftMemoryCalculation()).WillRepeatedly(Return(enabled));
2509 return nullptr;
2510 }
2511
createSocketLossInfo(int32_t uid,int32_t atomId)2512 SocketLossInfo createSocketLossInfo(int32_t uid, int32_t atomId) {
2513 SocketLossInfo lossInfo;
2514 lossInfo.uid = uid;
2515 lossInfo.errors.push_back(-11);
2516 lossInfo.atomIds.push_back(atomId);
2517 lossInfo.counts.push_back(1);
2518 return lossInfo;
2519 }
2520
createSocketLossInfoLogEvent(int32_t uid,int32_t lossAtomId)2521 std::unique_ptr<LogEvent> createSocketLossInfoLogEvent(int32_t uid, int32_t lossAtomId) {
2522 const SocketLossInfo lossInfo = createSocketLossInfo(uid, lossAtomId);
2523
2524 AStatsEvent* statsEvent = AStatsEvent_obtain();
2525 AStatsEvent_setAtomId(statsEvent, util::STATS_SOCKET_LOSS_REPORTED);
2526 AStatsEvent_writeInt32(statsEvent, lossInfo.uid);
2527 AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
2528 AStatsEvent_writeInt64(statsEvent, lossInfo.firstLossTsNanos);
2529 AStatsEvent_writeInt64(statsEvent, lossInfo.lastLossTsNanos);
2530 AStatsEvent_writeInt32(statsEvent, lossInfo.overflowCounter);
2531 AStatsEvent_writeInt32Array(statsEvent, lossInfo.errors.data(), lossInfo.errors.size());
2532 AStatsEvent_writeInt32Array(statsEvent, lossInfo.atomIds.data(), lossInfo.atomIds.size());
2533 AStatsEvent_writeInt32Array(statsEvent, lossInfo.counts.data(), lossInfo.counts.size());
2534
2535 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(uid /* uid */, 0 /* pid */);
2536 parseStatsEventToLogEvent(statsEvent, logEvent.get());
2537 return logEvent;
2538 }
2539
2540 } // namespace statsd
2541 } // namespace os
2542 } // namespace android
2543