• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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