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