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