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