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 <aidl/android/util/StatsEventParcel.h>
18
19 #include "matchers/SimpleAtomMatchingTracker.h"
20 #include "stats_annotations.h"
21 #include "stats_event.h"
22
23 using aidl::android::util::StatsEventParcel;
24 using std::shared_ptr;
25
26 namespace android {
27 namespace os {
28 namespace statsd {
29
outputStreamToProto(ProtoOutputStream * proto)30 StatsLogReport outputStreamToProto(ProtoOutputStream* proto) {
31 vector<uint8_t> bytes;
32 bytes.resize(proto->size());
33 size_t pos = 0;
34 sp<ProtoReader> reader = proto->data();
35
36 while (reader->readBuffer() != NULL) {
37 size_t toRead = reader->currentToRead();
38 std::memcpy(&((bytes)[pos]), reader->readBuffer(), toRead);
39 pos += toRead;
40 reader->move(toRead);
41 }
42
43 StatsLogReport report;
44 report.ParseFromArray(bytes.data(), bytes.size());
45 return report;
46 }
47
CreateSimpleAtomMatcher(const string & name,int atomId)48 AtomMatcher CreateSimpleAtomMatcher(const string& name, int atomId) {
49 AtomMatcher atom_matcher;
50 atom_matcher.set_id(StringToId(name));
51 auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
52 simple_atom_matcher->set_atom_id(atomId);
53 return atom_matcher;
54 }
55
CreateTemperatureAtomMatcher()56 AtomMatcher CreateTemperatureAtomMatcher() {
57 return CreateSimpleAtomMatcher("TemperatureMatcher", util::TEMPERATURE);
58 }
59
CreateScheduledJobStateChangedAtomMatcher(const string & name,ScheduledJobStateChanged::State state)60 AtomMatcher CreateScheduledJobStateChangedAtomMatcher(const string& name,
61 ScheduledJobStateChanged::State state) {
62 AtomMatcher atom_matcher;
63 atom_matcher.set_id(StringToId(name));
64 auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
65 simple_atom_matcher->set_atom_id(util::SCHEDULED_JOB_STATE_CHANGED);
66 auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
67 field_value_matcher->set_field(3); // State field.
68 field_value_matcher->set_eq_int(state);
69 return atom_matcher;
70 }
71
CreateStartScheduledJobAtomMatcher()72 AtomMatcher CreateStartScheduledJobAtomMatcher() {
73 return CreateScheduledJobStateChangedAtomMatcher("ScheduledJobStart",
74 ScheduledJobStateChanged::STARTED);
75 }
76
CreateFinishScheduledJobAtomMatcher()77 AtomMatcher CreateFinishScheduledJobAtomMatcher() {
78 return CreateScheduledJobStateChangedAtomMatcher("ScheduledJobFinish",
79 ScheduledJobStateChanged::FINISHED);
80 }
81
CreateScreenBrightnessChangedAtomMatcher()82 AtomMatcher CreateScreenBrightnessChangedAtomMatcher() {
83 AtomMatcher atom_matcher;
84 atom_matcher.set_id(StringToId("ScreenBrightnessChanged"));
85 auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
86 simple_atom_matcher->set_atom_id(util::SCREEN_BRIGHTNESS_CHANGED);
87 return atom_matcher;
88 }
89
CreateUidProcessStateChangedAtomMatcher()90 AtomMatcher CreateUidProcessStateChangedAtomMatcher() {
91 AtomMatcher atom_matcher;
92 atom_matcher.set_id(StringToId("UidProcessStateChanged"));
93 auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
94 simple_atom_matcher->set_atom_id(util::UID_PROCESS_STATE_CHANGED);
95 return atom_matcher;
96 }
97
CreateWakelockStateChangedAtomMatcher(const string & name,WakelockStateChanged::State state)98 AtomMatcher CreateWakelockStateChangedAtomMatcher(const string& name,
99 WakelockStateChanged::State state) {
100 AtomMatcher atom_matcher;
101 atom_matcher.set_id(StringToId(name));
102 auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
103 simple_atom_matcher->set_atom_id(util::WAKELOCK_STATE_CHANGED);
104 auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
105 field_value_matcher->set_field(4); // State field.
106 field_value_matcher->set_eq_int(state);
107 return atom_matcher;
108 }
109
CreateAcquireWakelockAtomMatcher()110 AtomMatcher CreateAcquireWakelockAtomMatcher() {
111 return CreateWakelockStateChangedAtomMatcher("AcquireWakelock", WakelockStateChanged::ACQUIRE);
112 }
113
CreateReleaseWakelockAtomMatcher()114 AtomMatcher CreateReleaseWakelockAtomMatcher() {
115 return CreateWakelockStateChangedAtomMatcher("ReleaseWakelock", WakelockStateChanged::RELEASE);
116 }
117
CreateBatterySaverModeStateChangedAtomMatcher(const string & name,BatterySaverModeStateChanged::State state)118 AtomMatcher CreateBatterySaverModeStateChangedAtomMatcher(
119 const string& name, BatterySaverModeStateChanged::State state) {
120 AtomMatcher atom_matcher;
121 atom_matcher.set_id(StringToId(name));
122 auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
123 simple_atom_matcher->set_atom_id(util::BATTERY_SAVER_MODE_STATE_CHANGED);
124 auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
125 field_value_matcher->set_field(1); // State field.
126 field_value_matcher->set_eq_int(state);
127 return atom_matcher;
128 }
129
CreateBatterySaverModeStartAtomMatcher()130 AtomMatcher CreateBatterySaverModeStartAtomMatcher() {
131 return CreateBatterySaverModeStateChangedAtomMatcher(
132 "BatterySaverModeStart", BatterySaverModeStateChanged::ON);
133 }
134
135
CreateBatterySaverModeStopAtomMatcher()136 AtomMatcher CreateBatterySaverModeStopAtomMatcher() {
137 return CreateBatterySaverModeStateChangedAtomMatcher(
138 "BatterySaverModeStop", BatterySaverModeStateChanged::OFF);
139 }
140
CreateBatteryStateChangedAtomMatcher(const string & name,BatteryPluggedStateEnum state)141 AtomMatcher CreateBatteryStateChangedAtomMatcher(const string& name,
142 BatteryPluggedStateEnum state) {
143 AtomMatcher atom_matcher;
144 atom_matcher.set_id(StringToId(name));
145 auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
146 simple_atom_matcher->set_atom_id(util::PLUGGED_STATE_CHANGED);
147 auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
148 field_value_matcher->set_field(1); // State field.
149 field_value_matcher->set_eq_int(state);
150 return atom_matcher;
151 }
152
CreateBatteryStateNoneMatcher()153 AtomMatcher CreateBatteryStateNoneMatcher() {
154 return CreateBatteryStateChangedAtomMatcher("BatteryPluggedNone",
155 BatteryPluggedStateEnum::BATTERY_PLUGGED_NONE);
156 }
157
CreateBatteryStateUsbMatcher()158 AtomMatcher CreateBatteryStateUsbMatcher() {
159 return CreateBatteryStateChangedAtomMatcher("BatteryPluggedUsb",
160 BatteryPluggedStateEnum::BATTERY_PLUGGED_USB);
161 }
162
CreateScreenStateChangedAtomMatcher(const string & name,android::view::DisplayStateEnum state)163 AtomMatcher CreateScreenStateChangedAtomMatcher(
164 const string& name, android::view::DisplayStateEnum state) {
165 AtomMatcher atom_matcher;
166 atom_matcher.set_id(StringToId(name));
167 auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
168 simple_atom_matcher->set_atom_id(util::SCREEN_STATE_CHANGED);
169 auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
170 field_value_matcher->set_field(1); // State field.
171 field_value_matcher->set_eq_int(state);
172 return atom_matcher;
173 }
174
CreateScreenTurnedOnAtomMatcher()175 AtomMatcher CreateScreenTurnedOnAtomMatcher() {
176 return CreateScreenStateChangedAtomMatcher("ScreenTurnedOn",
177 android::view::DisplayStateEnum::DISPLAY_STATE_ON);
178 }
179
CreateScreenTurnedOffAtomMatcher()180 AtomMatcher CreateScreenTurnedOffAtomMatcher() {
181 return CreateScreenStateChangedAtomMatcher("ScreenTurnedOff",
182 ::android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
183 }
184
CreateSyncStateChangedAtomMatcher(const string & name,SyncStateChanged::State state)185 AtomMatcher CreateSyncStateChangedAtomMatcher(
186 const string& name, SyncStateChanged::State state) {
187 AtomMatcher atom_matcher;
188 atom_matcher.set_id(StringToId(name));
189 auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
190 simple_atom_matcher->set_atom_id(util::SYNC_STATE_CHANGED);
191 auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
192 field_value_matcher->set_field(3); // State field.
193 field_value_matcher->set_eq_int(state);
194 return atom_matcher;
195 }
196
CreateSyncStartAtomMatcher()197 AtomMatcher CreateSyncStartAtomMatcher() {
198 return CreateSyncStateChangedAtomMatcher("SyncStart", SyncStateChanged::ON);
199 }
200
CreateSyncEndAtomMatcher()201 AtomMatcher CreateSyncEndAtomMatcher() {
202 return CreateSyncStateChangedAtomMatcher("SyncEnd", SyncStateChanged::OFF);
203 }
204
CreateActivityForegroundStateChangedAtomMatcher(const string & name,ActivityForegroundStateChanged::State state)205 AtomMatcher CreateActivityForegroundStateChangedAtomMatcher(
206 const string& name, ActivityForegroundStateChanged::State state) {
207 AtomMatcher atom_matcher;
208 atom_matcher.set_id(StringToId(name));
209 auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
210 simple_atom_matcher->set_atom_id(util::ACTIVITY_FOREGROUND_STATE_CHANGED);
211 auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
212 field_value_matcher->set_field(4); // Activity field.
213 field_value_matcher->set_eq_int(state);
214 return atom_matcher;
215 }
216
CreateMoveToBackgroundAtomMatcher()217 AtomMatcher CreateMoveToBackgroundAtomMatcher() {
218 return CreateActivityForegroundStateChangedAtomMatcher(
219 "Background", ActivityForegroundStateChanged::BACKGROUND);
220 }
221
CreateMoveToForegroundAtomMatcher()222 AtomMatcher CreateMoveToForegroundAtomMatcher() {
223 return CreateActivityForegroundStateChangedAtomMatcher(
224 "Foreground", ActivityForegroundStateChanged::FOREGROUND);
225 }
226
CreateProcessLifeCycleStateChangedAtomMatcher(const string & name,ProcessLifeCycleStateChanged::State state)227 AtomMatcher CreateProcessLifeCycleStateChangedAtomMatcher(
228 const string& name, ProcessLifeCycleStateChanged::State state) {
229 AtomMatcher atom_matcher;
230 atom_matcher.set_id(StringToId(name));
231 auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
232 simple_atom_matcher->set_atom_id(util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
233 auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
234 field_value_matcher->set_field(3); // Process state field.
235 field_value_matcher->set_eq_int(state);
236 return atom_matcher;
237 }
238
CreateProcessCrashAtomMatcher()239 AtomMatcher CreateProcessCrashAtomMatcher() {
240 return CreateProcessLifeCycleStateChangedAtomMatcher(
241 "Crashed", ProcessLifeCycleStateChanged::CRASHED);
242 }
243
addMatcherToMatcherCombination(const AtomMatcher & matcher,AtomMatcher * combinationMatcher)244 void addMatcherToMatcherCombination(const AtomMatcher& matcher, AtomMatcher* combinationMatcher) {
245 combinationMatcher->mutable_combination()->add_matcher(matcher.id());
246 }
247
CreateScheduledJobPredicate()248 Predicate CreateScheduledJobPredicate() {
249 Predicate predicate;
250 predicate.set_id(StringToId("ScheduledJobRunningPredicate"));
251 predicate.mutable_simple_predicate()->set_start(StringToId("ScheduledJobStart"));
252 predicate.mutable_simple_predicate()->set_stop(StringToId("ScheduledJobFinish"));
253 return predicate;
254 }
255
CreateBatterySaverModePredicate()256 Predicate CreateBatterySaverModePredicate() {
257 Predicate predicate;
258 predicate.set_id(StringToId("BatterySaverIsOn"));
259 predicate.mutable_simple_predicate()->set_start(StringToId("BatterySaverModeStart"));
260 predicate.mutable_simple_predicate()->set_stop(StringToId("BatterySaverModeStop"));
261 return predicate;
262 }
263
CreateDeviceUnpluggedPredicate()264 Predicate CreateDeviceUnpluggedPredicate() {
265 Predicate predicate;
266 predicate.set_id(StringToId("DeviceUnplugged"));
267 predicate.mutable_simple_predicate()->set_start(StringToId("BatteryPluggedNone"));
268 predicate.mutable_simple_predicate()->set_stop(StringToId("BatteryPluggedUsb"));
269 return predicate;
270 }
271
CreateScreenIsOnPredicate()272 Predicate CreateScreenIsOnPredicate() {
273 Predicate predicate;
274 predicate.set_id(StringToId("ScreenIsOn"));
275 predicate.mutable_simple_predicate()->set_start(StringToId("ScreenTurnedOn"));
276 predicate.mutable_simple_predicate()->set_stop(StringToId("ScreenTurnedOff"));
277 return predicate;
278 }
279
CreateScreenIsOffPredicate()280 Predicate CreateScreenIsOffPredicate() {
281 Predicate predicate;
282 predicate.set_id(1111123);
283 predicate.mutable_simple_predicate()->set_start(StringToId("ScreenTurnedOff"));
284 predicate.mutable_simple_predicate()->set_stop(StringToId("ScreenTurnedOn"));
285 return predicate;
286 }
287
CreateHoldingWakelockPredicate()288 Predicate CreateHoldingWakelockPredicate() {
289 Predicate predicate;
290 predicate.set_id(StringToId("HoldingWakelock"));
291 predicate.mutable_simple_predicate()->set_start(StringToId("AcquireWakelock"));
292 predicate.mutable_simple_predicate()->set_stop(StringToId("ReleaseWakelock"));
293 return predicate;
294 }
295
CreateIsSyncingPredicate()296 Predicate CreateIsSyncingPredicate() {
297 Predicate predicate;
298 predicate.set_id(33333333333333);
299 predicate.mutable_simple_predicate()->set_start(StringToId("SyncStart"));
300 predicate.mutable_simple_predicate()->set_stop(StringToId("SyncEnd"));
301 return predicate;
302 }
303
CreateIsInBackgroundPredicate()304 Predicate CreateIsInBackgroundPredicate() {
305 Predicate predicate;
306 predicate.set_id(StringToId("IsInBackground"));
307 predicate.mutable_simple_predicate()->set_start(StringToId("Background"));
308 predicate.mutable_simple_predicate()->set_stop(StringToId("Foreground"));
309 return predicate;
310 }
311
CreateScreenState()312 State CreateScreenState() {
313 State state;
314 state.set_id(StringToId("ScreenState"));
315 state.set_atom_id(util::SCREEN_STATE_CHANGED);
316 return state;
317 }
318
CreateUidProcessState()319 State CreateUidProcessState() {
320 State state;
321 state.set_id(StringToId("UidProcessState"));
322 state.set_atom_id(util::UID_PROCESS_STATE_CHANGED);
323 return state;
324 }
325
CreateOverlayState()326 State CreateOverlayState() {
327 State state;
328 state.set_id(StringToId("OverlayState"));
329 state.set_atom_id(util::OVERLAY_STATE_CHANGED);
330 return state;
331 }
332
CreateScreenStateWithOnOffMap(int64_t screenOnId,int64_t screenOffId)333 State CreateScreenStateWithOnOffMap(int64_t screenOnId, int64_t screenOffId) {
334 State state;
335 state.set_id(StringToId("ScreenStateOnOff"));
336 state.set_atom_id(util::SCREEN_STATE_CHANGED);
337
338 auto map = CreateScreenStateOnOffMap(screenOnId, screenOffId);
339 *state.mutable_map() = map;
340
341 return state;
342 }
343
CreateScreenStateWithSimpleOnOffMap(int64_t screenOnId,int64_t screenOffId)344 State CreateScreenStateWithSimpleOnOffMap(int64_t screenOnId, int64_t screenOffId) {
345 State state;
346 state.set_id(StringToId("ScreenStateSimpleOnOff"));
347 state.set_atom_id(util::SCREEN_STATE_CHANGED);
348
349 auto map = CreateScreenStateSimpleOnOffMap(screenOnId, screenOffId);
350 *state.mutable_map() = map;
351
352 return state;
353 }
354
CreateScreenStateOnGroup(int64_t screenOnId)355 StateMap_StateGroup CreateScreenStateOnGroup(int64_t screenOnId) {
356 StateMap_StateGroup group;
357 group.set_group_id(screenOnId);
358 group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_ON);
359 group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_VR);
360 group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_ON_SUSPEND);
361 return group;
362 }
363
CreateScreenStateOffGroup(int64_t screenOffId)364 StateMap_StateGroup CreateScreenStateOffGroup(int64_t screenOffId) {
365 StateMap_StateGroup group;
366 group.set_group_id(screenOffId);
367 group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
368 group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_DOZE);
369 group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_DOZE_SUSPEND);
370 return group;
371 }
372
CreateScreenStateSimpleOnGroup(int64_t screenOnId)373 StateMap_StateGroup CreateScreenStateSimpleOnGroup(int64_t screenOnId) {
374 StateMap_StateGroup group;
375 group.set_group_id(screenOnId);
376 group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_ON);
377 return group;
378 }
379
CreateScreenStateSimpleOffGroup(int64_t screenOffId)380 StateMap_StateGroup CreateScreenStateSimpleOffGroup(int64_t screenOffId) {
381 StateMap_StateGroup group;
382 group.set_group_id(screenOffId);
383 group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
384 return group;
385 }
386
CreateScreenStateOnOffMap(int64_t screenOnId,int64_t screenOffId)387 StateMap CreateScreenStateOnOffMap(int64_t screenOnId, int64_t screenOffId) {
388 StateMap map;
389 *map.add_group() = CreateScreenStateOnGroup(screenOnId);
390 *map.add_group() = CreateScreenStateOffGroup(screenOffId);
391 return map;
392 }
393
CreateScreenStateSimpleOnOffMap(int64_t screenOnId,int64_t screenOffId)394 StateMap CreateScreenStateSimpleOnOffMap(int64_t screenOnId, int64_t screenOffId) {
395 StateMap map;
396 *map.add_group() = CreateScreenStateSimpleOnGroup(screenOnId);
397 *map.add_group() = CreateScreenStateSimpleOffGroup(screenOffId);
398 return map;
399 }
400
addPredicateToPredicateCombination(const Predicate & predicate,Predicate * combinationPredicate)401 void addPredicateToPredicateCombination(const Predicate& predicate,
402 Predicate* combinationPredicate) {
403 combinationPredicate->mutable_combination()->add_predicate(predicate.id());
404 }
405
CreateAttributionUidDimensions(const int atomId,const std::vector<Position> & positions)406 FieldMatcher CreateAttributionUidDimensions(const int atomId,
407 const std::vector<Position>& positions) {
408 FieldMatcher dimensions;
409 dimensions.set_field(atomId);
410 for (const auto position : positions) {
411 auto child = dimensions.add_child();
412 child->set_field(1);
413 child->set_position(position);
414 child->add_child()->set_field(1);
415 }
416 return dimensions;
417 }
418
CreateAttributionUidAndTagDimensions(const int atomId,const std::vector<Position> & positions)419 FieldMatcher CreateAttributionUidAndTagDimensions(const int atomId,
420 const std::vector<Position>& positions) {
421 FieldMatcher dimensions;
422 dimensions.set_field(atomId);
423 for (const auto position : positions) {
424 auto child = dimensions.add_child();
425 child->set_field(1);
426 child->set_position(position);
427 child->add_child()->set_field(1);
428 child->add_child()->set_field(2);
429 }
430 return dimensions;
431 }
432
CreateDimensions(const int atomId,const std::vector<int> & fields)433 FieldMatcher CreateDimensions(const int atomId, const std::vector<int>& fields) {
434 FieldMatcher dimensions;
435 dimensions.set_field(atomId);
436 for (const int field : fields) {
437 dimensions.add_child()->set_field(field);
438 }
439 return dimensions;
440 }
441
CreateAttributionUidAndOtherDimensions(const int atomId,const std::vector<Position> & positions,const std::vector<int> & fields)442 FieldMatcher CreateAttributionUidAndOtherDimensions(const int atomId,
443 const std::vector<Position>& positions,
444 const std::vector<int>& fields) {
445 FieldMatcher dimensions = CreateAttributionUidDimensions(atomId, positions);
446
447 for (const int field : fields) {
448 dimensions.add_child()->set_field(field);
449 }
450 return dimensions;
451 }
452
createEventMetric(const string & name,const int64_t what,const optional<int64_t> & condition)453 EventMetric createEventMetric(const string& name, const int64_t what,
454 const optional<int64_t>& condition) {
455 EventMetric metric;
456 metric.set_id(StringToId(name));
457 metric.set_what(what);
458 if (condition) {
459 metric.set_condition(condition.value());
460 }
461 return metric;
462 }
463
createCountMetric(const string & name,const int64_t what,const optional<int64_t> & condition,const vector<int64_t> & states)464 CountMetric createCountMetric(const string& name, const int64_t what,
465 const optional<int64_t>& condition, const vector<int64_t>& states) {
466 CountMetric metric;
467 metric.set_id(StringToId(name));
468 metric.set_what(what);
469 metric.set_bucket(TEN_MINUTES);
470 if (condition) {
471 metric.set_condition(condition.value());
472 }
473 for (const int64_t state : states) {
474 metric.add_slice_by_state(state);
475 }
476 return metric;
477 }
478
createDurationMetric(const string & name,const int64_t what,const optional<int64_t> & condition,const vector<int64_t> & states)479 DurationMetric createDurationMetric(const string& name, const int64_t what,
480 const optional<int64_t>& condition,
481 const vector<int64_t>& states) {
482 DurationMetric metric;
483 metric.set_id(StringToId(name));
484 metric.set_what(what);
485 metric.set_bucket(TEN_MINUTES);
486 if (condition) {
487 metric.set_condition(condition.value());
488 }
489 for (const int64_t state : states) {
490 metric.add_slice_by_state(state);
491 }
492 return metric;
493 }
494
createGaugeMetric(const string & name,const int64_t what,const GaugeMetric::SamplingType samplingType,const optional<int64_t> & condition,const optional<int64_t> & triggerEvent)495 GaugeMetric createGaugeMetric(const string& name, const int64_t what,
496 const GaugeMetric::SamplingType samplingType,
497 const optional<int64_t>& condition,
498 const optional<int64_t>& triggerEvent) {
499 GaugeMetric metric;
500 metric.set_id(StringToId(name));
501 metric.set_what(what);
502 metric.set_bucket(TEN_MINUTES);
503 metric.set_sampling_type(samplingType);
504 if (condition) {
505 metric.set_condition(condition.value());
506 }
507 if (triggerEvent) {
508 metric.set_trigger_event(triggerEvent.value());
509 }
510 metric.mutable_gauge_fields_filter()->set_include_all(true);
511 return metric;
512 }
513
createValueMetric(const string & name,const AtomMatcher & what,const int valueField,const optional<int64_t> & condition,const vector<int64_t> & states)514 ValueMetric createValueMetric(const string& name, const AtomMatcher& what, const int valueField,
515 const optional<int64_t>& condition, const vector<int64_t>& states) {
516 ValueMetric metric;
517 metric.set_id(StringToId(name));
518 metric.set_what(what.id());
519 metric.set_bucket(TEN_MINUTES);
520 metric.mutable_value_field()->set_field(what.simple_atom_matcher().atom_id());
521 metric.mutable_value_field()->add_child()->set_field(valueField);
522 if (condition) {
523 metric.set_condition(condition.value());
524 }
525 for (const int64_t state : states) {
526 metric.add_slice_by_state(state);
527 }
528 return metric;
529 }
530
createAlert(const string & name,const int64_t metricId,const int buckets,const int64_t triggerSum)531 Alert createAlert(const string& name, const int64_t metricId, const int buckets,
532 const int64_t triggerSum) {
533 Alert alert;
534 alert.set_id(StringToId(name));
535 alert.set_metric_id(metricId);
536 alert.set_num_buckets(buckets);
537 alert.set_trigger_if_sum_gt(triggerSum);
538 return alert;
539 }
540
createAlarm(const string & name,const int64_t offsetMillis,const int64_t periodMillis)541 Alarm createAlarm(const string& name, const int64_t offsetMillis, const int64_t periodMillis) {
542 Alarm alarm;
543 alarm.set_id(StringToId(name));
544 alarm.set_offset_millis(offsetMillis);
545 alarm.set_period_millis(periodMillis);
546 return alarm;
547 }
548
createSubscription(const string & name,const Subscription_RuleType type,const int64_t ruleId)549 Subscription createSubscription(const string& name, const Subscription_RuleType type,
550 const int64_t ruleId) {
551 Subscription subscription;
552 subscription.set_id(StringToId(name));
553 subscription.set_rule_type(type);
554 subscription.set_rule_id(ruleId);
555 subscription.mutable_broadcast_subscriber_details();
556 return subscription;
557 }
558
559 // START: get primary key functions
getUidProcessKey(int uid,HashableDimensionKey * key)560 void getUidProcessKey(int uid, HashableDimensionKey* key) {
561 int pos1[] = {1, 0, 0};
562 Field field1(27 /* atom id */, pos1, 0 /* depth */);
563 Value value1((int32_t)uid);
564
565 key->addValue(FieldValue(field1, value1));
566 }
567
getOverlayKey(int uid,string packageName,HashableDimensionKey * key)568 void getOverlayKey(int uid, string packageName, HashableDimensionKey* key) {
569 int pos1[] = {1, 0, 0};
570 int pos2[] = {2, 0, 0};
571
572 Field field1(59 /* atom id */, pos1, 0 /* depth */);
573 Field field2(59 /* atom id */, pos2, 0 /* depth */);
574
575 Value value1((int32_t)uid);
576 Value value2(packageName);
577
578 key->addValue(FieldValue(field1, value1));
579 key->addValue(FieldValue(field2, value2));
580 }
581
getPartialWakelockKey(int uid,const std::string & tag,HashableDimensionKey * key)582 void getPartialWakelockKey(int uid, const std::string& tag, HashableDimensionKey* key) {
583 int pos1[] = {1, 1, 1};
584 int pos3[] = {2, 0, 0};
585 int pos4[] = {3, 0, 0};
586
587 Field field1(10 /* atom id */, pos1, 2 /* depth */);
588
589 Field field3(10 /* atom id */, pos3, 0 /* depth */);
590 Field field4(10 /* atom id */, pos4, 0 /* depth */);
591
592 Value value1((int32_t)uid);
593 Value value3((int32_t)1 /*partial*/);
594 Value value4(tag);
595
596 key->addValue(FieldValue(field1, value1));
597 key->addValue(FieldValue(field3, value3));
598 key->addValue(FieldValue(field4, value4));
599 }
600
getPartialWakelockKey(int uid,HashableDimensionKey * key)601 void getPartialWakelockKey(int uid, HashableDimensionKey* key) {
602 int pos1[] = {1, 1, 1};
603 int pos3[] = {2, 0, 0};
604
605 Field field1(10 /* atom id */, pos1, 2 /* depth */);
606 Field field3(10 /* atom id */, pos3, 0 /* depth */);
607
608 Value value1((int32_t)uid);
609 Value value3((int32_t)1 /*partial*/);
610
611 key->addValue(FieldValue(field1, value1));
612 key->addValue(FieldValue(field3, value3));
613 }
614 // END: get primary key functions
615
writeAttribution(AStatsEvent * statsEvent,const vector<int> & attributionUids,const vector<string> & attributionTags)616 void writeAttribution(AStatsEvent* statsEvent, const vector<int>& attributionUids,
617 const vector<string>& attributionTags) {
618 vector<const char*> cTags(attributionTags.size());
619 for (int i = 0; i < cTags.size(); i++) {
620 cTags[i] = attributionTags[i].c_str();
621 }
622
623 AStatsEvent_writeAttributionChain(statsEvent,
624 reinterpret_cast<const uint32_t*>(attributionUids.data()),
625 cTags.data(), attributionUids.size());
626 }
627
parseStatsEventToLogEvent(AStatsEvent * statsEvent,LogEvent * logEvent)628 void parseStatsEventToLogEvent(AStatsEvent* statsEvent, LogEvent* logEvent) {
629 AStatsEvent_build(statsEvent);
630
631 size_t size;
632 uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
633 logEvent->parseBuffer(buf, size);
634
635 AStatsEvent_release(statsEvent);
636 }
637
CreateTwoValueLogEvent(LogEvent * logEvent,int atomId,int64_t eventTimeNs,int32_t value1,int32_t value2)638 void CreateTwoValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs, int32_t value1,
639 int32_t value2) {
640 AStatsEvent* statsEvent = AStatsEvent_obtain();
641 AStatsEvent_setAtomId(statsEvent, atomId);
642 AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
643
644 AStatsEvent_writeInt32(statsEvent, value1);
645 AStatsEvent_writeInt32(statsEvent, value2);
646
647 parseStatsEventToLogEvent(statsEvent, logEvent);
648 }
649
CreateTwoValueLogEvent(int atomId,int64_t eventTimeNs,int32_t value1,int32_t value2)650 shared_ptr<LogEvent> CreateTwoValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1,
651 int32_t value2) {
652 shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
653 CreateTwoValueLogEvent(logEvent.get(), atomId, eventTimeNs, value1, value2);
654 return logEvent;
655 }
656
CreateThreeValueLogEvent(LogEvent * logEvent,int atomId,int64_t eventTimeNs,int32_t value1,int32_t value2,int32_t value3)657 void CreateThreeValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs, int32_t value1,
658 int32_t value2, int32_t value3) {
659 AStatsEvent* statsEvent = AStatsEvent_obtain();
660 AStatsEvent_setAtomId(statsEvent, atomId);
661 AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
662
663 AStatsEvent_writeInt32(statsEvent, value1);
664 AStatsEvent_writeInt32(statsEvent, value2);
665 AStatsEvent_writeInt32(statsEvent, value3);
666
667 parseStatsEventToLogEvent(statsEvent, logEvent);
668 }
669
CreateThreeValueLogEvent(int atomId,int64_t eventTimeNs,int32_t value1,int32_t value2,int32_t value3)670 shared_ptr<LogEvent> CreateThreeValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1,
671 int32_t value2, int32_t value3) {
672 shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
673 CreateThreeValueLogEvent(logEvent.get(), atomId, eventTimeNs, value1, value2, value3);
674 return logEvent;
675 }
676
CreateRepeatedValueLogEvent(LogEvent * logEvent,int atomId,int64_t eventTimeNs,int32_t value)677 void CreateRepeatedValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs,
678 int32_t value) {
679 AStatsEvent* statsEvent = AStatsEvent_obtain();
680 AStatsEvent_setAtomId(statsEvent, atomId);
681 AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
682
683 AStatsEvent_writeInt32(statsEvent, value);
684 AStatsEvent_writeInt32(statsEvent, value);
685
686 parseStatsEventToLogEvent(statsEvent, logEvent);
687 }
688
CreateRepeatedValueLogEvent(int atomId,int64_t eventTimeNs,int32_t value)689 shared_ptr<LogEvent> CreateRepeatedValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value) {
690 shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
691 CreateRepeatedValueLogEvent(logEvent.get(), atomId, eventTimeNs, value);
692 return logEvent;
693 }
694
CreateNoValuesLogEvent(LogEvent * logEvent,int atomId,int64_t eventTimeNs)695 void CreateNoValuesLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs) {
696 AStatsEvent* statsEvent = AStatsEvent_obtain();
697 AStatsEvent_setAtomId(statsEvent, atomId);
698 AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
699
700 parseStatsEventToLogEvent(statsEvent, logEvent);
701 }
702
CreateNoValuesLogEvent(int atomId,int64_t eventTimeNs)703 shared_ptr<LogEvent> CreateNoValuesLogEvent(int atomId, int64_t eventTimeNs) {
704 shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
705 CreateNoValuesLogEvent(logEvent.get(), atomId, eventTimeNs);
706 return logEvent;
707 }
708
makeUidLogEvent(int atomId,int64_t eventTimeNs,int uid,int data1,int data2)709 shared_ptr<LogEvent> makeUidLogEvent(int atomId, int64_t eventTimeNs, int uid, int data1,
710 int data2) {
711 AStatsEvent* statsEvent = AStatsEvent_obtain();
712 AStatsEvent_setAtomId(statsEvent, atomId);
713 AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
714
715 AStatsEvent_writeInt32(statsEvent, uid);
716 AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_IS_UID, true);
717 AStatsEvent_writeInt32(statsEvent, data1);
718 AStatsEvent_writeInt32(statsEvent, data2);
719
720 shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
721 parseStatsEventToLogEvent(statsEvent, logEvent.get());
722 return logEvent;
723 }
724
makeAttributionLogEvent(int atomId,int64_t eventTimeNs,const vector<int> & uids,const vector<string> & tags,int data1,int data2)725 shared_ptr<LogEvent> makeAttributionLogEvent(int atomId, int64_t eventTimeNs,
726 const vector<int>& uids, const vector<string>& tags,
727 int data1, int data2) {
728 AStatsEvent* statsEvent = AStatsEvent_obtain();
729 AStatsEvent_setAtomId(statsEvent, atomId);
730 AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
731
732 writeAttribution(statsEvent, uids, tags);
733 AStatsEvent_writeInt32(statsEvent, data1);
734 AStatsEvent_writeInt32(statsEvent, data2);
735
736 shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
737 parseStatsEventToLogEvent(statsEvent, logEvent.get());
738 return logEvent;
739 }
740
makeMockUidMapForOneHost(int hostUid,const vector<int> & isolatedUids)741 sp<MockUidMap> makeMockUidMapForOneHost(int hostUid, const vector<int>& isolatedUids) {
742 sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
743 EXPECT_CALL(*uidMap, getHostUidOrSelf(_)).WillRepeatedly(ReturnArg<0>());
744 for (const int isolatedUid : isolatedUids) {
745 EXPECT_CALL(*uidMap, getHostUidOrSelf(isolatedUid)).WillRepeatedly(Return(hostUid));
746 }
747
748 return uidMap;
749 }
750
makeMockUidMapForPackage(const string & pkg,const set<int32_t> & uids)751 sp<MockUidMap> makeMockUidMapForPackage(const string& pkg, const set<int32_t>& uids) {
752 sp<MockUidMap> uidMap = new StrictMock<MockUidMap>();
753 EXPECT_CALL(*uidMap, getAppUid(_)).Times(AnyNumber());
754 EXPECT_CALL(*uidMap, getAppUid(pkg)).WillRepeatedly(Return(uids));
755
756 return uidMap;
757 }
758
CreateScreenStateChangedEvent(uint64_t timestampNs,const android::view::DisplayStateEnum state,int loggerUid)759 std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(uint64_t timestampNs,
760 const android::view::DisplayStateEnum state,
761 int loggerUid) {
762 AStatsEvent* statsEvent = AStatsEvent_obtain();
763 AStatsEvent_setAtomId(statsEvent, util::SCREEN_STATE_CHANGED);
764 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
765 AStatsEvent_writeInt32(statsEvent, state);
766 AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_EXCLUSIVE_STATE, true);
767 AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_STATE_NESTED, false);
768
769 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(loggerUid, /*pid=*/0);
770 parseStatsEventToLogEvent(statsEvent, logEvent.get());
771 return logEvent;
772 }
773
CreateBatterySaverOnEvent(uint64_t timestampNs)774 std::unique_ptr<LogEvent> CreateBatterySaverOnEvent(uint64_t timestampNs) {
775 AStatsEvent* statsEvent = AStatsEvent_obtain();
776 AStatsEvent_setAtomId(statsEvent, util::BATTERY_SAVER_MODE_STATE_CHANGED);
777 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
778 AStatsEvent_writeInt32(statsEvent, BatterySaverModeStateChanged::ON);
779 AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_EXCLUSIVE_STATE, true);
780 AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_STATE_NESTED, false);
781
782 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
783 parseStatsEventToLogEvent(statsEvent, logEvent.get());
784 return logEvent;
785 }
786
CreateBatterySaverOffEvent(uint64_t timestampNs)787 std::unique_ptr<LogEvent> CreateBatterySaverOffEvent(uint64_t timestampNs) {
788 AStatsEvent* statsEvent = AStatsEvent_obtain();
789 AStatsEvent_setAtomId(statsEvent, util::BATTERY_SAVER_MODE_STATE_CHANGED);
790 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
791 AStatsEvent_writeInt32(statsEvent, BatterySaverModeStateChanged::OFF);
792 AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_EXCLUSIVE_STATE, true);
793 AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_STATE_NESTED, false);
794
795 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
796 parseStatsEventToLogEvent(statsEvent, logEvent.get());
797 return logEvent;
798 }
799
CreateBatteryStateChangedEvent(const uint64_t timestampNs,const BatteryPluggedStateEnum state)800 std::unique_ptr<LogEvent> CreateBatteryStateChangedEvent(const uint64_t timestampNs, const BatteryPluggedStateEnum state) {
801 AStatsEvent* statsEvent = AStatsEvent_obtain();
802 AStatsEvent_setAtomId(statsEvent, util::PLUGGED_STATE_CHANGED);
803 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
804 AStatsEvent_writeInt32(statsEvent, state);
805
806 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
807 parseStatsEventToLogEvent(statsEvent, logEvent.get());
808 return logEvent;
809 }
810
CreateScreenBrightnessChangedEvent(uint64_t timestampNs,int level)811 std::unique_ptr<LogEvent> CreateScreenBrightnessChangedEvent(uint64_t timestampNs, int level) {
812 AStatsEvent* statsEvent = AStatsEvent_obtain();
813 AStatsEvent_setAtomId(statsEvent, util::SCREEN_BRIGHTNESS_CHANGED);
814 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
815 AStatsEvent_writeInt32(statsEvent, level);
816
817 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
818 parseStatsEventToLogEvent(statsEvent, logEvent.get());
819 return logEvent;
820 }
821
CreateScheduledJobStateChangedEvent(const vector<int> & attributionUids,const vector<string> & attributionTags,const string & jobName,const ScheduledJobStateChanged::State state,uint64_t timestampNs)822 std::unique_ptr<LogEvent> CreateScheduledJobStateChangedEvent(
823 const vector<int>& attributionUids, const vector<string>& attributionTags,
824 const string& jobName, const ScheduledJobStateChanged::State state, uint64_t timestampNs) {
825 AStatsEvent* statsEvent = AStatsEvent_obtain();
826 AStatsEvent_setAtomId(statsEvent, util::SCHEDULED_JOB_STATE_CHANGED);
827 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
828
829 writeAttribution(statsEvent, attributionUids, attributionTags);
830 AStatsEvent_writeString(statsEvent, jobName.c_str());
831 AStatsEvent_writeInt32(statsEvent, state);
832
833 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
834 parseStatsEventToLogEvent(statsEvent, logEvent.get());
835 return logEvent;
836 }
837
CreateStartScheduledJobEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & jobName)838 std::unique_ptr<LogEvent> CreateStartScheduledJobEvent(uint64_t timestampNs,
839 const vector<int>& attributionUids,
840 const vector<string>& attributionTags,
841 const string& jobName) {
842 return CreateScheduledJobStateChangedEvent(attributionUids, attributionTags, jobName,
843 ScheduledJobStateChanged::STARTED, timestampNs);
844 }
845
846 // Create log event when scheduled job finishes.
CreateFinishScheduledJobEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & jobName)847 std::unique_ptr<LogEvent> CreateFinishScheduledJobEvent(uint64_t timestampNs,
848 const vector<int>& attributionUids,
849 const vector<string>& attributionTags,
850 const string& jobName) {
851 return CreateScheduledJobStateChangedEvent(attributionUids, attributionTags, jobName,
852 ScheduledJobStateChanged::FINISHED, timestampNs);
853 }
854
CreateWakelockStateChangedEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & wakelockName,const WakelockStateChanged::State state)855 std::unique_ptr<LogEvent> CreateWakelockStateChangedEvent(uint64_t timestampNs,
856 const vector<int>& attributionUids,
857 const vector<string>& attributionTags,
858 const string& wakelockName,
859 const WakelockStateChanged::State state) {
860 AStatsEvent* statsEvent = AStatsEvent_obtain();
861 AStatsEvent_setAtomId(statsEvent, util::WAKELOCK_STATE_CHANGED);
862 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
863
864 writeAttribution(statsEvent, attributionUids, attributionTags);
865 AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID, true);
866 AStatsEvent_writeInt32(statsEvent, android::os::WakeLockLevelEnum::PARTIAL_WAKE_LOCK);
867 AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_PRIMARY_FIELD, true);
868 AStatsEvent_writeString(statsEvent, wakelockName.c_str());
869 AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_PRIMARY_FIELD, true);
870 AStatsEvent_writeInt32(statsEvent, state);
871 AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_EXCLUSIVE_STATE, true);
872 AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_STATE_NESTED, true);
873
874 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
875 parseStatsEventToLogEvent(statsEvent, logEvent.get());
876 return logEvent;
877 }
878
CreateAcquireWakelockEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & wakelockName)879 std::unique_ptr<LogEvent> CreateAcquireWakelockEvent(uint64_t timestampNs,
880 const vector<int>& attributionUids,
881 const vector<string>& attributionTags,
882 const string& wakelockName) {
883 return CreateWakelockStateChangedEvent(timestampNs, attributionUids, attributionTags,
884 wakelockName, WakelockStateChanged::ACQUIRE);
885 }
886
CreateReleaseWakelockEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & wakelockName)887 std::unique_ptr<LogEvent> CreateReleaseWakelockEvent(uint64_t timestampNs,
888 const vector<int>& attributionUids,
889 const vector<string>& attributionTags,
890 const string& wakelockName) {
891 return CreateWakelockStateChangedEvent(timestampNs, attributionUids, attributionTags,
892 wakelockName, WakelockStateChanged::RELEASE);
893 }
894
CreateActivityForegroundStateChangedEvent(uint64_t timestampNs,const int uid,const ActivityForegroundStateChanged::State state)895 std::unique_ptr<LogEvent> CreateActivityForegroundStateChangedEvent(
896 uint64_t timestampNs, const int uid, const ActivityForegroundStateChanged::State state) {
897 AStatsEvent* statsEvent = AStatsEvent_obtain();
898 AStatsEvent_setAtomId(statsEvent, util::ACTIVITY_FOREGROUND_STATE_CHANGED);
899 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
900
901 AStatsEvent_writeInt32(statsEvent, uid);
902 AStatsEvent_writeString(statsEvent, "pkg_name");
903 AStatsEvent_writeString(statsEvent, "class_name");
904 AStatsEvent_writeInt32(statsEvent, state);
905
906 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
907 parseStatsEventToLogEvent(statsEvent, logEvent.get());
908 return logEvent;
909 }
910
CreateMoveToBackgroundEvent(uint64_t timestampNs,const int uid)911 std::unique_ptr<LogEvent> CreateMoveToBackgroundEvent(uint64_t timestampNs, const int uid) {
912 return CreateActivityForegroundStateChangedEvent(timestampNs, uid,
913 ActivityForegroundStateChanged::BACKGROUND);
914 }
915
CreateMoveToForegroundEvent(uint64_t timestampNs,const int uid)916 std::unique_ptr<LogEvent> CreateMoveToForegroundEvent(uint64_t timestampNs, const int uid) {
917 return CreateActivityForegroundStateChangedEvent(timestampNs, uid,
918 ActivityForegroundStateChanged::FOREGROUND);
919 }
920
CreateSyncStateChangedEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & name,const SyncStateChanged::State state)921 std::unique_ptr<LogEvent> CreateSyncStateChangedEvent(uint64_t timestampNs,
922 const vector<int>& attributionUids,
923 const vector<string>& attributionTags,
924 const string& name,
925 const SyncStateChanged::State state) {
926 AStatsEvent* statsEvent = AStatsEvent_obtain();
927 AStatsEvent_setAtomId(statsEvent, util::SYNC_STATE_CHANGED);
928 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
929
930 writeAttribution(statsEvent, attributionUids, attributionTags);
931 AStatsEvent_writeString(statsEvent, name.c_str());
932 AStatsEvent_writeInt32(statsEvent, state);
933
934 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
935 parseStatsEventToLogEvent(statsEvent, logEvent.get());
936 return logEvent;
937 }
938
CreateSyncStartEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & name)939 std::unique_ptr<LogEvent> CreateSyncStartEvent(uint64_t timestampNs,
940 const vector<int>& attributionUids,
941 const vector<string>& attributionTags,
942 const string& name) {
943 return CreateSyncStateChangedEvent(timestampNs, attributionUids, attributionTags, name,
944 SyncStateChanged::ON);
945 }
946
CreateSyncEndEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & name)947 std::unique_ptr<LogEvent> CreateSyncEndEvent(uint64_t timestampNs,
948 const vector<int>& attributionUids,
949 const vector<string>& attributionTags,
950 const string& name) {
951 return CreateSyncStateChangedEvent(timestampNs, attributionUids, attributionTags, name,
952 SyncStateChanged::OFF);
953 }
954
CreateProcessLifeCycleStateChangedEvent(uint64_t timestampNs,const int uid,const ProcessLifeCycleStateChanged::State state)955 std::unique_ptr<LogEvent> CreateProcessLifeCycleStateChangedEvent(
956 uint64_t timestampNs, const int uid, const ProcessLifeCycleStateChanged::State state) {
957 AStatsEvent* statsEvent = AStatsEvent_obtain();
958 AStatsEvent_setAtomId(statsEvent, util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
959 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
960
961 AStatsEvent_writeInt32(statsEvent, uid);
962 AStatsEvent_writeString(statsEvent, "");
963 AStatsEvent_writeInt32(statsEvent, state);
964
965 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
966 parseStatsEventToLogEvent(statsEvent, logEvent.get());
967 return logEvent;
968 }
969
CreateAppCrashEvent(uint64_t timestampNs,const int uid)970 std::unique_ptr<LogEvent> CreateAppCrashEvent(uint64_t timestampNs, const int uid) {
971 return CreateProcessLifeCycleStateChangedEvent(timestampNs, uid,
972 ProcessLifeCycleStateChanged::CRASHED);
973 }
974
CreateAppCrashOccurredEvent(uint64_t timestampNs,const int uid)975 std::unique_ptr<LogEvent> CreateAppCrashOccurredEvent(uint64_t timestampNs, const int uid) {
976 AStatsEvent* statsEvent = AStatsEvent_obtain();
977 AStatsEvent_setAtomId(statsEvent, util::APP_CRASH_OCCURRED);
978 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
979
980 AStatsEvent_writeInt32(statsEvent, uid);
981 AStatsEvent_writeString(statsEvent, "eventType");
982 AStatsEvent_writeString(statsEvent, "processName");
983
984 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
985 parseStatsEventToLogEvent(statsEvent, logEvent.get());
986 return logEvent;
987 }
988
CreateIsolatedUidChangedEvent(uint64_t timestampNs,int hostUid,int isolatedUid,bool is_create)989 std::unique_ptr<LogEvent> CreateIsolatedUidChangedEvent(uint64_t timestampNs, int hostUid,
990 int isolatedUid, bool is_create) {
991 AStatsEvent* statsEvent = AStatsEvent_obtain();
992 AStatsEvent_setAtomId(statsEvent, util::ISOLATED_UID_CHANGED);
993 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
994
995 AStatsEvent_writeInt32(statsEvent, hostUid);
996 AStatsEvent_writeInt32(statsEvent, isolatedUid);
997 AStatsEvent_writeInt32(statsEvent, is_create);
998
999 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1000 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1001 return logEvent;
1002 }
1003
CreateUidProcessStateChangedEvent(uint64_t timestampNs,int uid,const android::app::ProcessStateEnum state)1004 std::unique_ptr<LogEvent> CreateUidProcessStateChangedEvent(
1005 uint64_t timestampNs, int uid, const android::app::ProcessStateEnum state) {
1006 AStatsEvent* statsEvent = AStatsEvent_obtain();
1007 AStatsEvent_setAtomId(statsEvent, util::UID_PROCESS_STATE_CHANGED);
1008 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1009
1010 AStatsEvent_writeInt32(statsEvent, uid);
1011 AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_IS_UID, true);
1012 AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_PRIMARY_FIELD, true);
1013 AStatsEvent_writeInt32(statsEvent, state);
1014 AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_EXCLUSIVE_STATE, true);
1015 AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_STATE_NESTED, false);
1016
1017 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1018 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1019 return logEvent;
1020 }
1021
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)1022 std::unique_ptr<LogEvent> CreateBleScanStateChangedEvent(uint64_t timestampNs,
1023 const vector<int>& attributionUids,
1024 const vector<string>& attributionTags,
1025 const BleScanStateChanged::State state,
1026 const bool filtered, const bool firstMatch,
1027 const bool opportunistic) {
1028 AStatsEvent* statsEvent = AStatsEvent_obtain();
1029 AStatsEvent_setAtomId(statsEvent, util::BLE_SCAN_STATE_CHANGED);
1030 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1031
1032 writeAttribution(statsEvent, attributionUids, attributionTags);
1033 AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID, true);
1034 AStatsEvent_writeInt32(statsEvent, state);
1035 AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_EXCLUSIVE_STATE, true);
1036 AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_STATE_NESTED, true);
1037 if (state == util::BLE_SCAN_STATE_CHANGED__STATE__RESET) {
1038 AStatsEvent_addInt32Annotation(statsEvent, ANNOTATION_ID_TRIGGER_STATE_RESET,
1039 util::BLE_SCAN_STATE_CHANGED__STATE__OFF);
1040 }
1041 AStatsEvent_writeBool(statsEvent, filtered); // filtered
1042 AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_PRIMARY_FIELD, true);
1043 AStatsEvent_writeBool(statsEvent, firstMatch); // first match
1044 AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_PRIMARY_FIELD, true);
1045 AStatsEvent_writeBool(statsEvent, opportunistic); // opportunistic
1046 AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_PRIMARY_FIELD, true);
1047
1048 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1049 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1050 return logEvent;
1051 }
1052
CreateOverlayStateChangedEvent(int64_t timestampNs,const int32_t uid,const string & packageName,const bool usingAlertWindow,const OverlayStateChanged::State state)1053 std::unique_ptr<LogEvent> CreateOverlayStateChangedEvent(int64_t timestampNs, const int32_t uid,
1054 const string& packageName,
1055 const bool usingAlertWindow,
1056 const OverlayStateChanged::State state) {
1057 AStatsEvent* statsEvent = AStatsEvent_obtain();
1058 AStatsEvent_setAtomId(statsEvent, util::OVERLAY_STATE_CHANGED);
1059 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1060
1061 AStatsEvent_writeInt32(statsEvent, uid);
1062 AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_IS_UID, true);
1063 AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_PRIMARY_FIELD, true);
1064 AStatsEvent_writeString(statsEvent, packageName.c_str());
1065 AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_PRIMARY_FIELD, true);
1066 AStatsEvent_writeBool(statsEvent, usingAlertWindow);
1067 AStatsEvent_writeInt32(statsEvent, state);
1068 AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_EXCLUSIVE_STATE, true);
1069 AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_STATE_NESTED, false);
1070
1071 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1072 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1073 return logEvent;
1074 }
1075
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)1076 std::unique_ptr<LogEvent> CreateAppStartOccurredEvent(
1077 uint64_t timestampNs, const int uid, const string& pkgName,
1078 AppStartOccurred::TransitionType type, const string& activityName,
1079 const string& callingPkgName, const bool isInstantApp, int64_t activityStartMs) {
1080 AStatsEvent* statsEvent = AStatsEvent_obtain();
1081 AStatsEvent_setAtomId(statsEvent, util::APP_START_OCCURRED);
1082 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1083
1084 AStatsEvent_writeInt32(statsEvent, uid);
1085 AStatsEvent_writeString(statsEvent, pkgName.c_str());
1086 AStatsEvent_writeInt32(statsEvent, type);
1087 AStatsEvent_writeString(statsEvent, activityName.c_str());
1088 AStatsEvent_writeString(statsEvent, callingPkgName.c_str());
1089 AStatsEvent_writeInt32(statsEvent, isInstantApp);
1090 AStatsEvent_writeInt32(statsEvent, activityStartMs);
1091
1092 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1093 parseStatsEventToLogEvent(statsEvent, logEvent.get());
1094 return logEvent;
1095 }
1096
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)1097 sp<StatsLogProcessor> CreateStatsLogProcessor(const int64_t timeBaseNs, const int64_t currentTimeNs,
1098 const StatsdConfig& config, const ConfigKey& key,
1099 const shared_ptr<IPullAtomCallback>& puller,
1100 const int32_t atomTag, const sp<UidMap> uidMap) {
1101 sp<StatsPullerManager> pullerManager = new StatsPullerManager();
1102 if (puller != nullptr) {
1103 pullerManager->RegisterPullAtomCallback(/*uid=*/0, atomTag, NS_PER_SEC, NS_PER_SEC * 10, {},
1104 puller);
1105 }
1106 sp<AlarmMonitor> anomalyAlarmMonitor =
1107 new AlarmMonitor(1,
1108 [](const shared_ptr<IStatsCompanionService>&, int64_t){},
1109 [](const shared_ptr<IStatsCompanionService>&){});
1110 sp<AlarmMonitor> periodicAlarmMonitor =
1111 new AlarmMonitor(1,
1112 [](const shared_ptr<IStatsCompanionService>&, int64_t){},
1113 [](const shared_ptr<IStatsCompanionService>&){});
1114 sp<StatsLogProcessor> processor =
1115 new StatsLogProcessor(uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
1116 timeBaseNs, [](const ConfigKey&) { return true; },
1117 [](const int&, const vector<int64_t>&) {return true;});
1118 processor->OnConfigUpdated(currentTimeNs, key, config);
1119 return processor;
1120 }
1121
sortLogEventsByTimestamp(std::vector<std::unique_ptr<LogEvent>> * events)1122 void sortLogEventsByTimestamp(std::vector<std::unique_ptr<LogEvent>> *events) {
1123 std::sort(events->begin(), events->end(),
1124 [](const std::unique_ptr<LogEvent>& a, const std::unique_ptr<LogEvent>& b) {
1125 return a->GetElapsedTimestampNs() < b->GetElapsedTimestampNs();
1126 });
1127 }
1128
StringToId(const string & str)1129 int64_t StringToId(const string& str) {
1130 return static_cast<int64_t>(std::hash<std::string>()(str));
1131 }
1132
createEventMatcherWizard(int tagId,int matcherIndex,const vector<FieldValueMatcher> & fieldValueMatchers)1133 sp<EventMatcherWizard> createEventMatcherWizard(
1134 int tagId, int matcherIndex, const vector<FieldValueMatcher>& fieldValueMatchers) {
1135 sp<UidMap> uidMap = new UidMap();
1136 SimpleAtomMatcher atomMatcher;
1137 atomMatcher.set_atom_id(tagId);
1138 for (const FieldValueMatcher& fvm : fieldValueMatchers) {
1139 *atomMatcher.add_field_value_matcher() = fvm;
1140 }
1141 uint64_t matcherHash = 0x12345678;
1142 int64_t matcherId = 678;
1143 return new EventMatcherWizard({new SimpleAtomMatchingTracker(
1144 matcherId, matcherIndex, matcherHash, atomMatcher, uidMap)});
1145 }
1146
CreateAttributionUidDimensionsValueParcel(const int atomId,const int uid)1147 StatsDimensionsValueParcel CreateAttributionUidDimensionsValueParcel(const int atomId,
1148 const int uid) {
1149 StatsDimensionsValueParcel root;
1150 root.field = atomId;
1151 root.valueType = STATS_DIMENSIONS_VALUE_TUPLE_TYPE;
1152 StatsDimensionsValueParcel attrNode;
1153 attrNode.field = 1;
1154 attrNode.valueType = STATS_DIMENSIONS_VALUE_TUPLE_TYPE;
1155 StatsDimensionsValueParcel posInAttrChain;
1156 posInAttrChain.field = 1;
1157 posInAttrChain.valueType = STATS_DIMENSIONS_VALUE_TUPLE_TYPE;
1158 StatsDimensionsValueParcel uidNode;
1159 uidNode.field = 1;
1160 uidNode.valueType = STATS_DIMENSIONS_VALUE_INT_TYPE;
1161 uidNode.intValue = uid;
1162 posInAttrChain.tupleValue.push_back(uidNode);
1163 attrNode.tupleValue.push_back(posInAttrChain);
1164 root.tupleValue.push_back(attrNode);
1165 return root;
1166 }
1167
ValidateUidDimension(const DimensionsValue & value,int atomId,int uid)1168 void ValidateUidDimension(const DimensionsValue& value, int atomId, int uid) {
1169 EXPECT_EQ(value.field(), atomId);
1170 ASSERT_EQ(value.value_tuple().dimensions_value_size(), 1);
1171 EXPECT_EQ(value.value_tuple().dimensions_value(0).field(), 1);
1172 EXPECT_EQ(value.value_tuple().dimensions_value(0).value_int(), uid);
1173 }
1174
ValidateWakelockAttributionUidAndTagDimension(const DimensionsValue & value,const int atomId,const int uid,const string & tag)1175 void ValidateWakelockAttributionUidAndTagDimension(const DimensionsValue& value, const int atomId,
1176 const int uid, const string& tag) {
1177 EXPECT_EQ(value.field(), atomId);
1178 ASSERT_EQ(value.value_tuple().dimensions_value_size(), 2);
1179 // Attribution field.
1180 EXPECT_EQ(value.value_tuple().dimensions_value(0).field(), 1);
1181 // Uid field.
1182 ASSERT_EQ(value.value_tuple().dimensions_value(0).value_tuple().dimensions_value_size(), 1);
1183 EXPECT_EQ(value.value_tuple().dimensions_value(0).value_tuple().dimensions_value(0).field(), 1);
1184 EXPECT_EQ(value.value_tuple().dimensions_value(0).value_tuple().dimensions_value(0).value_int(),
1185 uid);
1186 // Tag field.
1187 EXPECT_EQ(value.value_tuple().dimensions_value(1).field(), 3);
1188 EXPECT_EQ(value.value_tuple().dimensions_value(1).value_str(), tag);
1189 }
1190
ValidateAttributionUidDimension(const DimensionsValue & value,int atomId,int uid)1191 void ValidateAttributionUidDimension(const DimensionsValue& value, int atomId, int uid) {
1192 EXPECT_EQ(value.field(), atomId);
1193 ASSERT_EQ(value.value_tuple().dimensions_value_size(), 1);
1194 // Attribution field.
1195 EXPECT_EQ(value.value_tuple().dimensions_value(0).field(), 1);
1196 // Uid only.
1197 EXPECT_EQ(value.value_tuple().dimensions_value(0)
1198 .value_tuple().dimensions_value_size(), 1);
1199 EXPECT_EQ(value.value_tuple().dimensions_value(0)
1200 .value_tuple().dimensions_value(0).field(), 1);
1201 EXPECT_EQ(value.value_tuple().dimensions_value(0)
1202 .value_tuple().dimensions_value(0).value_int(), uid);
1203 }
1204
ValidateUidDimension(const DimensionsValue & value,int node_idx,int atomId,int uid)1205 void ValidateUidDimension(const DimensionsValue& value, int node_idx, int atomId, int uid) {
1206 EXPECT_EQ(value.field(), atomId);
1207 ASSERT_GT(value.value_tuple().dimensions_value_size(), node_idx);
1208 // Attribution field.
1209 EXPECT_EQ(value.value_tuple().dimensions_value(node_idx).field(), 1);
1210 EXPECT_EQ(value.value_tuple().dimensions_value(node_idx)
1211 .value_tuple().dimensions_value(0).field(), 1);
1212 EXPECT_EQ(value.value_tuple().dimensions_value(node_idx)
1213 .value_tuple().dimensions_value(0).value_int(), uid);
1214 }
1215
ValidateAttributionUidAndTagDimension(const DimensionsValue & value,int node_idx,int atomId,int uid,const std::string & tag)1216 void ValidateAttributionUidAndTagDimension(
1217 const DimensionsValue& value, int node_idx, int atomId, int uid, const std::string& tag) {
1218 EXPECT_EQ(value.field(), atomId);
1219 ASSERT_GT(value.value_tuple().dimensions_value_size(), node_idx);
1220 // Attribution field.
1221 EXPECT_EQ(1, value.value_tuple().dimensions_value(node_idx).field());
1222 // Uid only.
1223 EXPECT_EQ(2, value.value_tuple().dimensions_value(node_idx)
1224 .value_tuple().dimensions_value_size());
1225 EXPECT_EQ(1, value.value_tuple().dimensions_value(node_idx)
1226 .value_tuple().dimensions_value(0).field());
1227 EXPECT_EQ(uid, value.value_tuple().dimensions_value(node_idx)
1228 .value_tuple().dimensions_value(0).value_int());
1229 EXPECT_EQ(2, value.value_tuple().dimensions_value(node_idx)
1230 .value_tuple().dimensions_value(1).field());
1231 EXPECT_EQ(tag, value.value_tuple().dimensions_value(node_idx)
1232 .value_tuple().dimensions_value(1).value_str());
1233 }
1234
ValidateAttributionUidAndTagDimension(const DimensionsValue & value,int atomId,int uid,const std::string & tag)1235 void ValidateAttributionUidAndTagDimension(
1236 const DimensionsValue& value, int atomId, int uid, const std::string& tag) {
1237 EXPECT_EQ(value.field(), atomId);
1238 ASSERT_EQ(1, value.value_tuple().dimensions_value_size());
1239 // Attribution field.
1240 EXPECT_EQ(1, value.value_tuple().dimensions_value(0).field());
1241 // Uid only.
1242 EXPECT_EQ(value.value_tuple().dimensions_value(0)
1243 .value_tuple().dimensions_value_size(), 2);
1244 EXPECT_EQ(value.value_tuple().dimensions_value(0)
1245 .value_tuple().dimensions_value(0).field(), 1);
1246 EXPECT_EQ(value.value_tuple().dimensions_value(0)
1247 .value_tuple().dimensions_value(0).value_int(), uid);
1248 EXPECT_EQ(value.value_tuple().dimensions_value(0)
1249 .value_tuple().dimensions_value(1).field(), 2);
1250 EXPECT_EQ(value.value_tuple().dimensions_value(0)
1251 .value_tuple().dimensions_value(1).value_str(), tag);
1252 }
1253
ValidateStateValue(const google::protobuf::RepeatedPtrField<StateValue> & stateValues,int atomId,int64_t value)1254 void ValidateStateValue(const google::protobuf::RepeatedPtrField<StateValue>& stateValues,
1255 int atomId, int64_t value) {
1256 ASSERT_EQ(stateValues.size(), 1);
1257 ASSERT_EQ(stateValues[0].atom_id(), atomId);
1258 switch (stateValues[0].contents_case()) {
1259 case StateValue::ContentsCase::kValue:
1260 EXPECT_EQ(stateValues[0].value(), (int32_t)value);
1261 break;
1262 case StateValue::ContentsCase::kGroupId:
1263 EXPECT_EQ(stateValues[0].group_id(), value);
1264 break;
1265 default:
1266 FAIL() << "State value should have either a value or a group id";
1267 }
1268 }
1269
ValidateCountBucket(const CountBucketInfo & countBucket,int64_t startTimeNs,int64_t endTimeNs,int64_t count)1270 void ValidateCountBucket(const CountBucketInfo& countBucket, int64_t startTimeNs, int64_t endTimeNs,
1271 int64_t count) {
1272 EXPECT_EQ(countBucket.start_bucket_elapsed_nanos(), startTimeNs);
1273 EXPECT_EQ(countBucket.end_bucket_elapsed_nanos(), endTimeNs);
1274 EXPECT_EQ(countBucket.count(), count);
1275 }
1276
ValidateDurationBucket(const DurationBucketInfo & bucket,int64_t startTimeNs,int64_t endTimeNs,int64_t durationNs)1277 void ValidateDurationBucket(const DurationBucketInfo& bucket, int64_t startTimeNs,
1278 int64_t endTimeNs, int64_t durationNs) {
1279 EXPECT_EQ(bucket.start_bucket_elapsed_nanos(), startTimeNs);
1280 EXPECT_EQ(bucket.end_bucket_elapsed_nanos(), endTimeNs);
1281 EXPECT_EQ(bucket.duration_nanos(), durationNs);
1282 }
1283
ValidateGaugeBucketTimes(const GaugeBucketInfo & gaugeBucket,int64_t startTimeNs,int64_t endTimeNs,vector<int64_t> eventTimesNs)1284 void ValidateGaugeBucketTimes(const GaugeBucketInfo& gaugeBucket, int64_t startTimeNs,
1285 int64_t endTimeNs, vector<int64_t> eventTimesNs) {
1286 EXPECT_EQ(gaugeBucket.start_bucket_elapsed_nanos(), startTimeNs);
1287 EXPECT_EQ(gaugeBucket.end_bucket_elapsed_nanos(), endTimeNs);
1288 EXPECT_EQ(gaugeBucket.elapsed_timestamp_nanos_size(), eventTimesNs.size());
1289 for (int i = 0; i < eventTimesNs.size(); i++) {
1290 EXPECT_EQ(gaugeBucket.elapsed_timestamp_nanos(i), eventTimesNs[i]);
1291 }
1292 }
1293
ValidateValueBucket(const ValueBucketInfo & bucket,int64_t startTimeNs,int64_t endTimeNs,const vector<int64_t> & values,int64_t conditionTrueNs)1294 void ValidateValueBucket(const ValueBucketInfo& bucket, int64_t startTimeNs, int64_t endTimeNs,
1295 const vector<int64_t>& values, int64_t conditionTrueNs) {
1296 EXPECT_EQ(bucket.start_bucket_elapsed_nanos(), startTimeNs);
1297 EXPECT_EQ(bucket.end_bucket_elapsed_nanos(), endTimeNs);
1298 ASSERT_EQ(bucket.values_size(), values.size());
1299 for (int i = 0; i < values.size(); ++i) {
1300 if (bucket.values(i).has_value_double()) {
1301 EXPECT_EQ((int64_t)bucket.values(i).value_double(), values[i]);
1302 } else {
1303 EXPECT_EQ(bucket.values(i).value_long(), values[i]);
1304 }
1305 }
1306 if (conditionTrueNs > 0) {
1307 EXPECT_EQ(bucket.condition_true_nanos(), conditionTrueNs);
1308 }
1309 }
1310
EqualsTo(const DimensionsValue & s1,const DimensionsValue & s2)1311 bool EqualsTo(const DimensionsValue& s1, const DimensionsValue& s2) {
1312 if (s1.field() != s2.field()) {
1313 return false;
1314 }
1315 if (s1.value_case() != s2.value_case()) {
1316 return false;
1317 }
1318 switch (s1.value_case()) {
1319 case DimensionsValue::ValueCase::kValueStr:
1320 return (s1.value_str() == s2.value_str());
1321 case DimensionsValue::ValueCase::kValueInt:
1322 return s1.value_int() == s2.value_int();
1323 case DimensionsValue::ValueCase::kValueLong:
1324 return s1.value_long() == s2.value_long();
1325 case DimensionsValue::ValueCase::kValueBool:
1326 return s1.value_bool() == s2.value_bool();
1327 case DimensionsValue::ValueCase::kValueFloat:
1328 return s1.value_float() == s2.value_float();
1329 case DimensionsValue::ValueCase::kValueTuple: {
1330 if (s1.value_tuple().dimensions_value_size() !=
1331 s2.value_tuple().dimensions_value_size()) {
1332 return false;
1333 }
1334 bool allMatched = true;
1335 for (int i = 0; allMatched && i < s1.value_tuple().dimensions_value_size(); ++i) {
1336 allMatched &= EqualsTo(s1.value_tuple().dimensions_value(i),
1337 s2.value_tuple().dimensions_value(i));
1338 }
1339 return allMatched;
1340 }
1341 case DimensionsValue::ValueCase::VALUE_NOT_SET:
1342 default:
1343 return true;
1344 }
1345 }
1346
LessThan(const google::protobuf::RepeatedPtrField<StateValue> & s1,const google::protobuf::RepeatedPtrField<StateValue> & s2)1347 bool LessThan(const google::protobuf::RepeatedPtrField<StateValue>& s1,
1348 const google::protobuf::RepeatedPtrField<StateValue>& s2) {
1349 if (s1.size() != s2.size()) {
1350 return s1.size() < s2.size();
1351 }
1352 for (int i = 0; i < s1.size(); i++) {
1353 const StateValue& state1 = s1[i];
1354 const StateValue& state2 = s2[i];
1355 if (state1.atom_id() != state2.atom_id()) {
1356 return state1.atom_id() < state2.atom_id();
1357 }
1358 if (state1.value() != state2.value()) {
1359 return state1.value() < state2.value();
1360 }
1361 if (state1.group_id() != state2.group_id()) {
1362 return state1.group_id() < state2.group_id();
1363 }
1364 }
1365 return false;
1366 }
1367
LessThan(const DimensionsValue & s1,const DimensionsValue & s2)1368 bool LessThan(const DimensionsValue& s1, const DimensionsValue& s2) {
1369 if (s1.field() != s2.field()) {
1370 return s1.field() < s2.field();
1371 }
1372 if (s1.value_case() != s2.value_case()) {
1373 return s1.value_case() < s2.value_case();
1374 }
1375 switch (s1.value_case()) {
1376 case DimensionsValue::ValueCase::kValueStr:
1377 return s1.value_str() < s2.value_str();
1378 case DimensionsValue::ValueCase::kValueInt:
1379 return s1.value_int() < s2.value_int();
1380 case DimensionsValue::ValueCase::kValueLong:
1381 return s1.value_long() < s2.value_long();
1382 case DimensionsValue::ValueCase::kValueBool:
1383 return (int)s1.value_bool() < (int)s2.value_bool();
1384 case DimensionsValue::ValueCase::kValueFloat:
1385 return s1.value_float() < s2.value_float();
1386 case DimensionsValue::ValueCase::kValueTuple: {
1387 if (s1.value_tuple().dimensions_value_size() !=
1388 s2.value_tuple().dimensions_value_size()) {
1389 return s1.value_tuple().dimensions_value_size() <
1390 s2.value_tuple().dimensions_value_size();
1391 }
1392 for (int i = 0; i < s1.value_tuple().dimensions_value_size(); ++i) {
1393 if (EqualsTo(s1.value_tuple().dimensions_value(i),
1394 s2.value_tuple().dimensions_value(i))) {
1395 continue;
1396 } else {
1397 return LessThan(s1.value_tuple().dimensions_value(i),
1398 s2.value_tuple().dimensions_value(i));
1399 }
1400 }
1401 return false;
1402 }
1403 case DimensionsValue::ValueCase::VALUE_NOT_SET:
1404 default:
1405 return false;
1406 }
1407 }
1408
LessThan(const DimensionsPair & s1,const DimensionsPair & s2)1409 bool LessThan(const DimensionsPair& s1, const DimensionsPair& s2) {
1410 if (LessThan(s1.dimInWhat, s2.dimInWhat)) {
1411 return true;
1412 } else if (LessThan(s2.dimInWhat, s1.dimInWhat)) {
1413 return false;
1414 }
1415
1416 return LessThan(s1.stateValues, s2.stateValues);
1417 }
1418
backfillStringInDimension(const std::map<uint64_t,string> & str_map,DimensionsValue * dimension)1419 void backfillStringInDimension(const std::map<uint64_t, string>& str_map,
1420 DimensionsValue* dimension) {
1421 if (dimension->has_value_str_hash()) {
1422 auto it = str_map.find((uint64_t)(dimension->value_str_hash()));
1423 if (it != str_map.end()) {
1424 dimension->clear_value_str_hash();
1425 dimension->set_value_str(it->second);
1426 } else {
1427 ALOGE("Can not find the string hash: %llu",
1428 (unsigned long long)dimension->value_str_hash());
1429 }
1430 } else if (dimension->has_value_tuple()) {
1431 auto value_tuple = dimension->mutable_value_tuple();
1432 for (int i = 0; i < value_tuple->dimensions_value_size(); ++i) {
1433 backfillStringInDimension(str_map, value_tuple->mutable_dimensions_value(i));
1434 }
1435 }
1436 }
1437
backfillStringInReport(ConfigMetricsReport * config_report)1438 void backfillStringInReport(ConfigMetricsReport *config_report) {
1439 std::map<uint64_t, string> str_map;
1440 for (const auto& str : config_report->strings()) {
1441 uint64_t hash = Hash64(str);
1442 if (str_map.find(hash) != str_map.end()) {
1443 ALOGE("String hash conflicts: %s %s", str.c_str(), str_map[hash].c_str());
1444 }
1445 str_map[hash] = str;
1446 }
1447 for (int i = 0; i < config_report->metrics_size(); ++i) {
1448 auto metric_report = config_report->mutable_metrics(i);
1449 if (metric_report->has_count_metrics()) {
1450 backfillStringInDimension(str_map, metric_report->mutable_count_metrics());
1451 } else if (metric_report->has_duration_metrics()) {
1452 backfillStringInDimension(str_map, metric_report->mutable_duration_metrics());
1453 } else if (metric_report->has_gauge_metrics()) {
1454 backfillStringInDimension(str_map, metric_report->mutable_gauge_metrics());
1455 } else if (metric_report->has_value_metrics()) {
1456 backfillStringInDimension(str_map, metric_report->mutable_value_metrics());
1457 }
1458 }
1459 // Backfill the package names.
1460 for (int i = 0 ; i < config_report->uid_map().snapshots_size(); ++i) {
1461 auto snapshot = config_report->mutable_uid_map()->mutable_snapshots(i);
1462 for (int j = 0 ; j < snapshot->package_info_size(); ++j) {
1463 auto package_info = snapshot->mutable_package_info(j);
1464 if (package_info->has_name_hash()) {
1465 auto it = str_map.find((uint64_t)(package_info->name_hash()));
1466 if (it != str_map.end()) {
1467 package_info->clear_name_hash();
1468 package_info->set_name(it->second);
1469 } else {
1470 ALOGE("Can not find the string package name hash: %llu",
1471 (unsigned long long)package_info->name_hash());
1472 }
1473
1474 }
1475 }
1476 }
1477 // Backfill the app name in app changes.
1478 for (int i = 0 ; i < config_report->uid_map().changes_size(); ++i) {
1479 auto change = config_report->mutable_uid_map()->mutable_changes(i);
1480 if (change->has_app_hash()) {
1481 auto it = str_map.find((uint64_t)(change->app_hash()));
1482 if (it != str_map.end()) {
1483 change->clear_app_hash();
1484 change->set_app(it->second);
1485 } else {
1486 ALOGE("Can not find the string change app name hash: %llu",
1487 (unsigned long long)change->app_hash());
1488 }
1489 }
1490 }
1491 }
1492
backfillStringInReport(ConfigMetricsReportList * config_report_list)1493 void backfillStringInReport(ConfigMetricsReportList *config_report_list) {
1494 for (int i = 0; i < config_report_list->reports_size(); ++i) {
1495 backfillStringInReport(config_report_list->mutable_reports(i));
1496 }
1497 }
1498
backfillDimensionPath(const DimensionsValue & path,const google::protobuf::RepeatedPtrField<DimensionsValue> & leafValues,int * leafIndex,DimensionsValue * dimension)1499 bool backfillDimensionPath(const DimensionsValue& path,
1500 const google::protobuf::RepeatedPtrField<DimensionsValue>& leafValues,
1501 int* leafIndex,
1502 DimensionsValue* dimension) {
1503 dimension->set_field(path.field());
1504 if (path.has_value_tuple()) {
1505 for (int i = 0; i < path.value_tuple().dimensions_value_size(); ++i) {
1506 if (!backfillDimensionPath(
1507 path.value_tuple().dimensions_value(i), leafValues, leafIndex,
1508 dimension->mutable_value_tuple()->add_dimensions_value())) {
1509 return false;
1510 }
1511 }
1512 } else {
1513 if (*leafIndex < 0 || *leafIndex >= leafValues.size()) {
1514 return false;
1515 }
1516 dimension->MergeFrom(leafValues.Get(*leafIndex));
1517 (*leafIndex)++;
1518 }
1519 return true;
1520 }
1521
backfillDimensionPath(const DimensionsValue & path,const google::protobuf::RepeatedPtrField<DimensionsValue> & leafValues,DimensionsValue * dimension)1522 bool backfillDimensionPath(const DimensionsValue& path,
1523 const google::protobuf::RepeatedPtrField<DimensionsValue>& leafValues,
1524 DimensionsValue* dimension) {
1525 int leafIndex = 0;
1526 return backfillDimensionPath(path, leafValues, &leafIndex, dimension);
1527 }
1528
backfillDimensionPath(StatsLogReport * report)1529 void backfillDimensionPath(StatsLogReport* report) {
1530 if (report->has_dimensions_path_in_what() || report->has_dimensions_path_in_condition()) {
1531 auto whatPath = report->dimensions_path_in_what();
1532 auto conditionPath = report->dimensions_path_in_condition();
1533 if (report->has_count_metrics()) {
1534 backfillDimensionPath(whatPath, conditionPath, report->mutable_count_metrics());
1535 } else if (report->has_duration_metrics()) {
1536 backfillDimensionPath(whatPath, conditionPath, report->mutable_duration_metrics());
1537 } else if (report->has_gauge_metrics()) {
1538 backfillDimensionPath(whatPath, conditionPath, report->mutable_gauge_metrics());
1539 } else if (report->has_value_metrics()) {
1540 backfillDimensionPath(whatPath, conditionPath, report->mutable_value_metrics());
1541 }
1542 report->clear_dimensions_path_in_what();
1543 report->clear_dimensions_path_in_condition();
1544 }
1545 }
1546
backfillDimensionPath(ConfigMetricsReport * config_report)1547 void backfillDimensionPath(ConfigMetricsReport* config_report) {
1548 for (int i = 0; i < config_report->metrics_size(); ++i) {
1549 backfillDimensionPath(config_report->mutable_metrics(i));
1550 }
1551 }
1552
backfillDimensionPath(ConfigMetricsReportList * config_report_list)1553 void backfillDimensionPath(ConfigMetricsReportList* config_report_list) {
1554 for (int i = 0; i < config_report_list->reports_size(); ++i) {
1555 backfillDimensionPath(config_report_list->mutable_reports(i));
1556 }
1557 }
1558
backfillStartEndTimestamp(StatsLogReport * report)1559 void backfillStartEndTimestamp(StatsLogReport *report) {
1560 const int64_t timeBaseNs = report->time_base_elapsed_nano_seconds();
1561 const int64_t bucketSizeNs = report->bucket_size_nano_seconds();
1562 if (report->has_count_metrics()) {
1563 backfillStartEndTimestampForMetrics(
1564 timeBaseNs, bucketSizeNs, report->mutable_count_metrics());
1565 } else if (report->has_duration_metrics()) {
1566 backfillStartEndTimestampForMetrics(
1567 timeBaseNs, bucketSizeNs, report->mutable_duration_metrics());
1568 } else if (report->has_gauge_metrics()) {
1569 backfillStartEndTimestampForMetrics(
1570 timeBaseNs, bucketSizeNs, report->mutable_gauge_metrics());
1571 if (report->gauge_metrics().skipped_size() > 0) {
1572 backfillStartEndTimestampForSkippedBuckets(
1573 timeBaseNs, report->mutable_gauge_metrics());
1574 }
1575 } else if (report->has_value_metrics()) {
1576 backfillStartEndTimestampForMetrics(
1577 timeBaseNs, bucketSizeNs, report->mutable_value_metrics());
1578 if (report->value_metrics().skipped_size() > 0) {
1579 backfillStartEndTimestampForSkippedBuckets(
1580 timeBaseNs, report->mutable_value_metrics());
1581 }
1582 }
1583 }
1584
backfillStartEndTimestamp(ConfigMetricsReport * config_report)1585 void backfillStartEndTimestamp(ConfigMetricsReport *config_report) {
1586 for (int j = 0; j < config_report->metrics_size(); ++j) {
1587 backfillStartEndTimestamp(config_report->mutable_metrics(j));
1588 }
1589 }
1590
backfillStartEndTimestamp(ConfigMetricsReportList * config_report_list)1591 void backfillStartEndTimestamp(ConfigMetricsReportList *config_report_list) {
1592 for (int i = 0; i < config_report_list->reports_size(); ++i) {
1593 backfillStartEndTimestamp(config_report_list->mutable_reports(i));
1594 }
1595 }
1596
onPullAtom(int atomTag,const shared_ptr<IPullAtomResultReceiver> & resultReceiver)1597 Status FakeSubsystemSleepCallback::onPullAtom(int atomTag,
1598 const shared_ptr<IPullAtomResultReceiver>& resultReceiver) {
1599 // Convert stats_events into StatsEventParcels.
1600 std::vector<StatsEventParcel> parcels;
1601 for (int i = 1; i < 3; i++) {
1602 AStatsEvent* event = AStatsEvent_obtain();
1603 AStatsEvent_setAtomId(event, atomTag);
1604 std::string subsystemName = "subsystem_name_";
1605 subsystemName = subsystemName + std::to_string(i);
1606 AStatsEvent_writeString(event, subsystemName.c_str());
1607 AStatsEvent_writeString(event, "subsystem_subname foo");
1608 AStatsEvent_writeInt64(event, /*count= */ i);
1609 AStatsEvent_writeInt64(event, /*time_millis= */ pullNum * pullNum * 100 + i);
1610 AStatsEvent_build(event);
1611 size_t size;
1612 uint8_t* buffer = AStatsEvent_getBuffer(event, &size);
1613
1614 StatsEventParcel p;
1615 // vector.assign() creates a copy, but this is inevitable unless
1616 // stats_event.h/c uses a vector as opposed to a buffer.
1617 p.buffer.assign(buffer, buffer + size);
1618 parcels.push_back(std::move(p));
1619 AStatsEvent_release(event);
1620 }
1621 pullNum++;
1622 resultReceiver->pullFinished(atomTag, /*success=*/true, parcels);
1623 return Status::ok();
1624 }
1625
1626 } // namespace statsd
1627 } // namespace os
1628 } // namespace android
1629