• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2017 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "statsd_test_util.h"
16 
17 #include <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,const vector<int64_t> & states)539 EventMetric createEventMetric(const string& name, const int64_t what,
540                               const optional<int64_t>& condition, const vector<int64_t>& states) {
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     for (const int64_t state : states) {
548         metric.add_slice_by_state(state);
549     }
550     return metric;
551 }
552 
createCountMetric(const string & name,const int64_t what,const optional<int64_t> & condition,const vector<int64_t> & states)553 CountMetric createCountMetric(const string& name, const int64_t what,
554                               const optional<int64_t>& condition, const vector<int64_t>& states) {
555     CountMetric metric;
556     metric.set_id(StringToId(name));
557     metric.set_what(what);
558     metric.set_bucket(TEN_MINUTES);
559     if (condition) {
560         metric.set_condition(condition.value());
561     }
562     for (const int64_t state : states) {
563         metric.add_slice_by_state(state);
564     }
565     return metric;
566 }
567 
createDurationMetric(const string & name,const int64_t what,const optional<int64_t> & condition,const vector<int64_t> & states)568 DurationMetric createDurationMetric(const string& name, const int64_t what,
569                                     const optional<int64_t>& condition,
570                                     const vector<int64_t>& states) {
571     DurationMetric metric;
572     metric.set_id(StringToId(name));
573     metric.set_what(what);
574     metric.set_bucket(TEN_MINUTES);
575     if (condition) {
576         metric.set_condition(condition.value());
577     }
578     for (const int64_t state : states) {
579         metric.add_slice_by_state(state);
580     }
581     return metric;
582 }
583 
createGaugeMetric(const string & name,const int64_t what,const GaugeMetric::SamplingType samplingType,const optional<int64_t> & condition,const optional<int64_t> & triggerEvent,const vector<int64_t> & states)584 GaugeMetric createGaugeMetric(const string& name, const int64_t what,
585                               const GaugeMetric::SamplingType samplingType,
586                               const optional<int64_t>& condition,
587                               const optional<int64_t>& triggerEvent,
588                               const vector<int64_t>& states) {
589     GaugeMetric metric;
590     metric.set_id(StringToId(name));
591     metric.set_what(what);
592     metric.set_bucket(TEN_MINUTES);
593     metric.set_sampling_type(samplingType);
594     if (condition) {
595         metric.set_condition(condition.value());
596     }
597     if (triggerEvent) {
598         metric.set_trigger_event(triggerEvent.value());
599     }
600     for (const int64_t state : states) {
601         metric.add_slice_by_state(state);
602     }
603     return metric;
604 }
605 
createValueMetric(const string & name,const AtomMatcher & what,const int valueField,const optional<int64_t> & condition,const vector<int64_t> & states)606 ValueMetric createValueMetric(const string& name, const AtomMatcher& what, const int valueField,
607                               const optional<int64_t>& condition, const vector<int64_t>& states) {
608     return createValueMetric(name, what, {valueField}, /* aggregationTypes */ {}, condition,
609                              states);
610 }
611 
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)612 ValueMetric createValueMetric(const string& name, const AtomMatcher& what,
613                               const vector<int>& valueFields,
614                               const vector<ValueMetric::AggregationType>& aggregationTypes,
615                               const optional<int64_t>& condition, const vector<int64_t>& states) {
616     ValueMetric metric;
617     metric.set_id(StringToId(name));
618     metric.set_what(what.id());
619     metric.set_bucket(TEN_MINUTES);
620     metric.mutable_value_field()->set_field(what.simple_atom_matcher().atom_id());
621     for (int valueField : valueFields) {
622         metric.mutable_value_field()->add_child()->set_field(valueField);
623     }
624     for (const ValueMetric::AggregationType aggType : aggregationTypes) {
625         metric.add_aggregation_types(aggType);
626     }
627     if (condition) {
628         metric.set_condition(condition.value());
629     }
630     for (const int64_t state : states) {
631         metric.add_slice_by_state(state);
632     }
633     return metric;
634 }
635 
createGeneratedBinConfig(int id,float min,float max,int count,HistogramBinConfig::GeneratedBins::Strategy strategy)636 HistogramBinConfig createGeneratedBinConfig(int id, float min, float max, int count,
637                                             HistogramBinConfig::GeneratedBins::Strategy strategy) {
638     HistogramBinConfig binConfig;
639     binConfig.set_id(id);
640     binConfig.mutable_generated_bins()->set_min(min);
641     binConfig.mutable_generated_bins()->set_max(max);
642     binConfig.mutable_generated_bins()->set_count(count);
643     binConfig.mutable_generated_bins()->set_strategy(strategy);
644     return binConfig;
645 }
646 
createExplicitBinConfig(int id,const vector<float> & bins)647 HistogramBinConfig createExplicitBinConfig(int id, const vector<float>& bins) {
648     HistogramBinConfig binConfig;
649     binConfig.set_id(id);
650     *binConfig.mutable_explicit_bins()->mutable_bin() = {bins.begin(), bins.end()};
651     return binConfig;
652 }
653 
createKllMetric(const string & name,const AtomMatcher & what,const int kllField,const optional<int64_t> & condition)654 KllMetric createKllMetric(const string& name, const AtomMatcher& what, const int kllField,
655                           const optional<int64_t>& condition) {
656     KllMetric metric;
657     metric.set_id(StringToId(name));
658     metric.set_what(what.id());
659     metric.set_bucket(TEN_MINUTES);
660     metric.mutable_kll_field()->set_field(what.simple_atom_matcher().atom_id());
661     metric.mutable_kll_field()->add_child()->set_field(kllField);
662     if (condition) {
663         metric.set_condition(condition.value());
664     }
665     return metric;
666 }
667 
createAlert(const string & name,const int64_t metricId,const int buckets,const int64_t triggerSum)668 Alert createAlert(const string& name, const int64_t metricId, const int buckets,
669                   const int64_t triggerSum) {
670     Alert alert;
671     alert.set_id(StringToId(name));
672     alert.set_metric_id(metricId);
673     alert.set_num_buckets(buckets);
674     alert.set_trigger_if_sum_gt(triggerSum);
675     return alert;
676 }
677 
createAlarm(const string & name,const int64_t offsetMillis,const int64_t periodMillis)678 Alarm createAlarm(const string& name, const int64_t offsetMillis, const int64_t periodMillis) {
679     Alarm alarm;
680     alarm.set_id(StringToId(name));
681     alarm.set_offset_millis(offsetMillis);
682     alarm.set_period_millis(periodMillis);
683     return alarm;
684 }
685 
createSubscription(const string & name,const Subscription_RuleType type,const int64_t ruleId)686 Subscription createSubscription(const string& name, const Subscription_RuleType type,
687                                 const int64_t ruleId) {
688     Subscription subscription;
689     subscription.set_id(StringToId(name));
690     subscription.set_rule_type(type);
691     subscription.set_rule_id(ruleId);
692     subscription.mutable_broadcast_subscriber_details();
693     return subscription;
694 }
695 
696 // START: get primary key functions
getUidProcessKey(int uid,HashableDimensionKey * key)697 void getUidProcessKey(int uid, HashableDimensionKey* key) {
698     int pos1[] = {1, 0, 0};
699     Field field1(27 /* atom id */, pos1, 0 /* depth */);
700     Value value1((int32_t)uid);
701 
702     key->addValue(FieldValue(field1, value1));
703 }
704 
getOverlayKey(int uid,string packageName,HashableDimensionKey * key)705 void getOverlayKey(int uid, string packageName, HashableDimensionKey* key) {
706     int pos1[] = {1, 0, 0};
707     int pos2[] = {2, 0, 0};
708 
709     Field field1(59 /* atom id */, pos1, 0 /* depth */);
710     Field field2(59 /* atom id */, pos2, 0 /* depth */);
711 
712     Value value1((int32_t)uid);
713     Value value2(packageName);
714 
715     key->addValue(FieldValue(field1, value1));
716     key->addValue(FieldValue(field2, value2));
717 }
718 
getPartialWakelockKey(int uid,const std::string & tag,HashableDimensionKey * key)719 void getPartialWakelockKey(int uid, const std::string& tag, HashableDimensionKey* key) {
720     int pos1[] = {1, 1, 1};
721     int pos3[] = {2, 0, 0};
722     int pos4[] = {3, 0, 0};
723 
724     Field field1(10 /* atom id */, pos1, 2 /* depth */);
725 
726     Field field3(10 /* atom id */, pos3, 0 /* depth */);
727     Field field4(10 /* atom id */, pos4, 0 /* depth */);
728 
729     Value value1((int32_t)uid);
730     Value value3((int32_t)1 /*partial*/);
731     Value value4(tag);
732 
733     key->addValue(FieldValue(field1, value1));
734     key->addValue(FieldValue(field3, value3));
735     key->addValue(FieldValue(field4, value4));
736 }
737 
getPartialWakelockKey(int uid,HashableDimensionKey * key)738 void getPartialWakelockKey(int uid, HashableDimensionKey* key) {
739     int pos1[] = {1, 1, 1};
740     int pos3[] = {2, 0, 0};
741 
742     Field field1(10 /* atom id */, pos1, 2 /* depth */);
743     Field field3(10 /* atom id */, pos3, 0 /* depth */);
744 
745     Value value1((int32_t)uid);
746     Value value3((int32_t)1 /*partial*/);
747 
748     key->addValue(FieldValue(field1, value1));
749     key->addValue(FieldValue(field3, value3));
750 }
751 // END: get primary key functions
752 
writeAttribution(AStatsEvent * statsEvent,const vector<int> & attributionUids,const vector<string> & attributionTags)753 void writeAttribution(AStatsEvent* statsEvent, const vector<int>& attributionUids,
754                       const vector<string>& attributionTags) {
755     vector<const char*> cTags(attributionTags.size());
756     for (int i = 0; i < cTags.size(); i++) {
757         cTags[i] = attributionTags[i].c_str();
758     }
759 
760     AStatsEvent_writeAttributionChain(statsEvent,
761                                       reinterpret_cast<const uint32_t*>(attributionUids.data()),
762                                       cTags.data(), attributionUids.size());
763 }
764 
parseStatsEventToLogEvent(AStatsEvent * statsEvent,LogEvent * logEvent)765 bool parseStatsEventToLogEvent(AStatsEvent* statsEvent, LogEvent* logEvent) {
766     AStatsEvent_build(statsEvent);
767 
768     size_t size;
769     uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
770     const bool result = logEvent->parseBuffer(buf, size);
771 
772     AStatsEvent_release(statsEvent);
773 
774     return result;
775 }
776 
makeTwoValueStatsEvent(int atomId,int64_t eventTimeNs,int32_t value1,int32_t value2)777 AStatsEvent* makeTwoValueStatsEvent(int atomId, int64_t eventTimeNs, int32_t value1,
778                                     int32_t value2) {
779     AStatsEvent* statsEvent = AStatsEvent_obtain();
780     AStatsEvent_setAtomId(statsEvent, atomId);
781     AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
782 
783     AStatsEvent_writeInt32(statsEvent, value1);
784     AStatsEvent_writeInt32(statsEvent, value2);
785 
786     return statsEvent;
787 }
788 
CreateTwoValueLogEvent(LogEvent * logEvent,int atomId,int64_t eventTimeNs,int32_t value1,int32_t value2)789 void CreateTwoValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs, int32_t value1,
790                             int32_t value2) {
791     AStatsEvent* statsEvent = makeTwoValueStatsEvent(atomId, eventTimeNs, value1, value2);
792     parseStatsEventToLogEvent(statsEvent, logEvent);
793 }
794 
CreateTwoValueLogEvent(int atomId,int64_t eventTimeNs,int32_t value1,int32_t value2)795 shared_ptr<LogEvent> CreateTwoValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1,
796                                             int32_t value2) {
797     shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
798     CreateTwoValueLogEvent(logEvent.get(), atomId, eventTimeNs, value1, value2);
799     return logEvent;
800 }
801 
CreateThreeValueLogEvent(LogEvent * logEvent,int atomId,int64_t eventTimeNs,int32_t value1,int32_t value2,int32_t value3)802 void CreateThreeValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs, int32_t value1,
803                               int32_t value2, int32_t value3) {
804     AStatsEvent* statsEvent = AStatsEvent_obtain();
805     AStatsEvent_setAtomId(statsEvent, atomId);
806     AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
807 
808     AStatsEvent_writeInt32(statsEvent, value1);
809     AStatsEvent_writeInt32(statsEvent, value2);
810     AStatsEvent_writeInt32(statsEvent, value3);
811 
812     parseStatsEventToLogEvent(statsEvent, logEvent);
813 }
814 
CreateThreeValueLogEvent(int atomId,int64_t eventTimeNs,int32_t value1,int32_t value2,int32_t value3)815 shared_ptr<LogEvent> CreateThreeValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1,
816                                               int32_t value2, int32_t value3) {
817     shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
818     CreateThreeValueLogEvent(logEvent.get(), atomId, eventTimeNs, value1, value2, value3);
819     return logEvent;
820 }
821 
CreateRepeatedValueLogEvent(LogEvent * logEvent,int atomId,int64_t eventTimeNs,int32_t value)822 void CreateRepeatedValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs,
823                                  int32_t value) {
824     AStatsEvent* statsEvent = AStatsEvent_obtain();
825     AStatsEvent_setAtomId(statsEvent, atomId);
826     AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
827 
828     AStatsEvent_writeInt32(statsEvent, value);
829     AStatsEvent_writeInt32(statsEvent, value);
830 
831     parseStatsEventToLogEvent(statsEvent, logEvent);
832 }
833 
CreateRepeatedValueLogEvent(int atomId,int64_t eventTimeNs,int32_t value)834 shared_ptr<LogEvent> CreateRepeatedValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value) {
835     shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
836     CreateRepeatedValueLogEvent(logEvent.get(), atomId, eventTimeNs, value);
837     return logEvent;
838 }
839 
CreateNoValuesLogEvent(LogEvent * logEvent,int atomId,int64_t eventTimeNs)840 void CreateNoValuesLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs) {
841     AStatsEvent* statsEvent = AStatsEvent_obtain();
842     AStatsEvent_setAtomId(statsEvent, atomId);
843     AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
844 
845     parseStatsEventToLogEvent(statsEvent, logEvent);
846 }
847 
CreateNoValuesLogEvent(int atomId,int64_t eventTimeNs)848 shared_ptr<LogEvent> CreateNoValuesLogEvent(int atomId, int64_t eventTimeNs) {
849     shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
850     CreateNoValuesLogEvent(logEvent.get(), atomId, eventTimeNs);
851     return logEvent;
852 }
853 
makeUidStatsEvent(int atomId,int64_t eventTimeNs,int uid,int data1,int data2)854 AStatsEvent* makeUidStatsEvent(int atomId, int64_t eventTimeNs, int uid, int data1, int data2) {
855     AStatsEvent* statsEvent = AStatsEvent_obtain();
856     AStatsEvent_setAtomId(statsEvent, atomId);
857     AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
858 
859     AStatsEvent_writeInt32(statsEvent, uid);
860     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
861     AStatsEvent_writeInt32(statsEvent, data1);
862     AStatsEvent_writeInt32(statsEvent, data2);
863 
864     return statsEvent;
865 }
866 
makeUidStatsEvent(int atomId,int64_t eventTimeNs,int uid,int data1,const vector<int> & data2)867 AStatsEvent* makeUidStatsEvent(int atomId, int64_t eventTimeNs, int uid, int data1,
868                                const vector<int>& data2) {
869     AStatsEvent* statsEvent = AStatsEvent_obtain();
870     AStatsEvent_setAtomId(statsEvent, atomId);
871     AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
872     AStatsEvent_writeInt32(statsEvent, uid);
873     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
874     AStatsEvent_writeInt32(statsEvent, data1);
875     AStatsEvent_writeInt32Array(statsEvent, data2.data(), data2.size());
876 
877     return statsEvent;
878 }
879 
makeAttributionStatsEvent(int atomId,int64_t eventTimeNs,const vector<int> & uids,const vector<string> & tags,int data1,int data2)880 AStatsEvent* makeAttributionStatsEvent(int atomId, int64_t eventTimeNs, const vector<int>& uids,
881                                        const vector<string>& tags, int data1, int data2) {
882     AStatsEvent* statsEvent = AStatsEvent_obtain();
883     AStatsEvent_setAtomId(statsEvent, atomId);
884     AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
885 
886     writeAttribution(statsEvent, uids, tags);
887     AStatsEvent_writeInt32(statsEvent, data1);
888     AStatsEvent_writeInt32(statsEvent, data2);
889 
890     return statsEvent;
891 }
892 
makeUidLogEvent(int atomId,int64_t eventTimeNs,int uid,int data1,int data2)893 shared_ptr<LogEvent> makeUidLogEvent(int atomId, int64_t eventTimeNs, int uid, int data1,
894                                      int data2) {
895     AStatsEvent* statsEvent = makeUidStatsEvent(atomId, eventTimeNs, uid, data1, data2);
896 
897     shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
898     parseStatsEventToLogEvent(statsEvent, logEvent.get());
899     return logEvent;
900 }
901 
makeUidLogEvent(int atomId,int64_t eventTimeNs,int uid,int data1,const vector<int> & data2)902 shared_ptr<LogEvent> makeUidLogEvent(int atomId, int64_t eventTimeNs, int uid, int data1,
903                                      const vector<int>& data2) {
904     AStatsEvent* statsEvent = makeUidStatsEvent(atomId, eventTimeNs, uid, data1, data2);
905 
906     shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
907     parseStatsEventToLogEvent(statsEvent, logEvent.get());
908     return logEvent;
909 }
910 
makeExtraUidsLogEvent(int atomId,int64_t eventTimeNs,int uid1,int data1,int data2,const vector<int> & extraUids)911 shared_ptr<LogEvent> makeExtraUidsLogEvent(int atomId, int64_t eventTimeNs, int uid1, int data1,
912                                            int data2, const vector<int>& extraUids) {
913     AStatsEvent* statsEvent = makeUidStatsEvent(atomId, eventTimeNs, uid1, data1, data2);
914     for (const int extraUid : extraUids) {
915         AStatsEvent_writeInt32(statsEvent, extraUid);
916         AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
917     }
918 
919     shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
920     parseStatsEventToLogEvent(statsEvent, logEvent.get());
921     return logEvent;
922 }
923 
makeRepeatedUidLogEvent(int atomId,int64_t eventTimeNs,const vector<int> & uids)924 shared_ptr<LogEvent> makeRepeatedUidLogEvent(int atomId, int64_t eventTimeNs,
925                                              const vector<int>& uids) {
926     AStatsEvent* statsEvent = AStatsEvent_obtain();
927     AStatsEvent_setAtomId(statsEvent, atomId);
928     AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
929     AStatsEvent_writeInt32Array(statsEvent, uids.data(), uids.size());
930     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
931 
932     shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
933     parseStatsEventToLogEvent(statsEvent, logEvent.get());
934 
935     return logEvent;
936 }
937 
makeRepeatedUidLogEvent(int atomId,int64_t eventTimeNs,const vector<int> & uids,int data1,int data2)938 shared_ptr<LogEvent> makeRepeatedUidLogEvent(int atomId, int64_t eventTimeNs,
939                                              const vector<int>& uids, int data1, int data2) {
940     AStatsEvent* statsEvent = AStatsEvent_obtain();
941     AStatsEvent_setAtomId(statsEvent, atomId);
942     AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
943     AStatsEvent_writeInt32Array(statsEvent, uids.data(), uids.size());
944     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
945     AStatsEvent_writeInt32(statsEvent, data1);
946     AStatsEvent_writeInt32(statsEvent, data2);
947 
948     shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
949     parseStatsEventToLogEvent(statsEvent, logEvent.get());
950 
951     return logEvent;
952 }
953 
makeRepeatedUidLogEvent(int atomId,int64_t eventTimeNs,const vector<int> & uids,int data1,const vector<int> & data2)954 shared_ptr<LogEvent> makeRepeatedUidLogEvent(int atomId, int64_t eventTimeNs,
955                                              const vector<int>& uids, int data1,
956                                              const vector<int>& data2) {
957     AStatsEvent* statsEvent = AStatsEvent_obtain();
958     AStatsEvent_setAtomId(statsEvent, atomId);
959     AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
960     AStatsEvent_writeInt32Array(statsEvent, uids.data(), uids.size());
961     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
962     AStatsEvent_writeInt32(statsEvent, data1);
963     AStatsEvent_writeInt32Array(statsEvent, data2.data(), data2.size());
964 
965     shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
966     parseStatsEventToLogEvent(statsEvent, logEvent.get());
967 
968     return logEvent;
969 }
970 
makeAttributionLogEvent(int atomId,int64_t eventTimeNs,const vector<int> & uids,const vector<string> & tags,int data1,int data2)971 shared_ptr<LogEvent> makeAttributionLogEvent(int atomId, int64_t eventTimeNs,
972                                              const vector<int>& uids, const vector<string>& tags,
973                                              int data1, int data2) {
974     AStatsEvent* statsEvent =
975             makeAttributionStatsEvent(atomId, eventTimeNs, uids, tags, data1, data2);
976 
977     shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
978     parseStatsEventToLogEvent(statsEvent, logEvent.get());
979     return logEvent;
980 }
981 
makeMockUidMapForHosts(const map<int,vector<int>> & hostUidToIsolatedUidsMap)982 sp<MockUidMap> makeMockUidMapForHosts(const map<int, vector<int>>& hostUidToIsolatedUidsMap) {
983     sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
984     EXPECT_CALL(*uidMap, getHostUidOrSelf(_)).WillRepeatedly(ReturnArg<0>());
985     for (const auto& [hostUid, isolatedUids] : hostUidToIsolatedUidsMap) {
986         for (const int isolatedUid : isolatedUids) {
987             EXPECT_CALL(*uidMap, getHostUidOrSelf(isolatedUid)).WillRepeatedly(Return(hostUid));
988         }
989     }
990 
991     return uidMap;
992 }
993 
makeMockUidMapForPackage(const string & pkg,const set<int32_t> & uids)994 sp<MockUidMap> makeMockUidMapForPackage(const string& pkg, const set<int32_t>& uids) {
995     sp<MockUidMap> uidMap = new StrictMock<MockUidMap>();
996     EXPECT_CALL(*uidMap, getAppUid(_)).Times(AnyNumber());
997     EXPECT_CALL(*uidMap, getAppUid(pkg)).WillRepeatedly(Return(uids));
998 
999     return uidMap;
1000 }
1001 
CreateScreenStateChangedEvent(uint64_t timestampNs,const android::view::DisplayStateEnum state,int loggerUid)1002 std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(uint64_t timestampNs,
1003                                                         const android::view::DisplayStateEnum state,
1004                                                         int loggerUid) {
1005     AStatsEvent* statsEvent = AStatsEvent_obtain();
1006     AStatsEvent_setAtomId(statsEvent, util::SCREEN_STATE_CHANGED);
1007     AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1008     AStatsEvent_writeInt32(statsEvent, state);
1009     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_EXCLUSIVE_STATE, true);
1010     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_STATE_NESTED, false);
1011 
1012     std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(loggerUid, /*pid=*/0);
1013     parseStatsEventToLogEvent(statsEvent, logEvent.get());
1014     return logEvent;
1015 }
1016 
CreateBatterySaverOnEvent(uint64_t timestampNs)1017 std::unique_ptr<LogEvent> CreateBatterySaverOnEvent(uint64_t timestampNs) {
1018     AStatsEvent* statsEvent = AStatsEvent_obtain();
1019     AStatsEvent_setAtomId(statsEvent, util::BATTERY_SAVER_MODE_STATE_CHANGED);
1020     AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1021     AStatsEvent_writeInt32(statsEvent, BatterySaverModeStateChanged::ON);
1022     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_EXCLUSIVE_STATE, true);
1023     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_STATE_NESTED, false);
1024 
1025     std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1026     parseStatsEventToLogEvent(statsEvent, logEvent.get());
1027     return logEvent;
1028 }
1029 
CreateBatterySaverOffEvent(uint64_t timestampNs)1030 std::unique_ptr<LogEvent> CreateBatterySaverOffEvent(uint64_t timestampNs) {
1031     AStatsEvent* statsEvent = AStatsEvent_obtain();
1032     AStatsEvent_setAtomId(statsEvent, util::BATTERY_SAVER_MODE_STATE_CHANGED);
1033     AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1034     AStatsEvent_writeInt32(statsEvent, BatterySaverModeStateChanged::OFF);
1035     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_EXCLUSIVE_STATE, true);
1036     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_STATE_NESTED, false);
1037 
1038     std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1039     parseStatsEventToLogEvent(statsEvent, logEvent.get());
1040     return logEvent;
1041 }
1042 
CreateBatteryStateChangedEvent(const uint64_t timestampNs,const BatteryPluggedStateEnum state,int32_t uid)1043 std::unique_ptr<LogEvent> CreateBatteryStateChangedEvent(const uint64_t timestampNs,
1044                                                          const BatteryPluggedStateEnum state,
1045                                                          int32_t uid) {
1046     AStatsEvent* statsEvent = AStatsEvent_obtain();
1047     AStatsEvent_setAtomId(statsEvent, util::PLUGGED_STATE_CHANGED);
1048     AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1049     AStatsEvent_writeInt32(statsEvent, state);
1050     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_EXCLUSIVE_STATE, true);
1051     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_STATE_NESTED, false);
1052 
1053     std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/uid, /*pid=*/0);
1054     parseStatsEventToLogEvent(statsEvent, logEvent.get());
1055     return logEvent;
1056 }
1057 
CreateMalformedBatteryStateChangedEvent(const uint64_t timestampNs)1058 std::unique_ptr<LogEvent> CreateMalformedBatteryStateChangedEvent(const uint64_t timestampNs) {
1059     AStatsEvent* statsEvent = AStatsEvent_obtain();
1060     AStatsEvent_setAtomId(statsEvent, util::PLUGGED_STATE_CHANGED);
1061     AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1062     AStatsEvent_writeString(statsEvent, "bad_state");
1063     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_EXCLUSIVE_STATE, true);
1064     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_STATE_NESTED, false);
1065 
1066     std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1067     parseStatsEventToLogEvent(statsEvent, logEvent.get());
1068     return logEvent;
1069 }
1070 
CreateScreenBrightnessChangedEvent(uint64_t timestampNs,int level)1071 std::unique_ptr<LogEvent> CreateScreenBrightnessChangedEvent(uint64_t timestampNs, int level) {
1072     AStatsEvent* statsEvent = AStatsEvent_obtain();
1073     AStatsEvent_setAtomId(statsEvent, util::SCREEN_BRIGHTNESS_CHANGED);
1074     AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1075     AStatsEvent_writeInt32(statsEvent, level);
1076 
1077     std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1078     parseStatsEventToLogEvent(statsEvent, logEvent.get());
1079     return logEvent;
1080 }
1081 
CreateScheduledJobStateChangedEvent(const vector<int> & attributionUids,const vector<string> & attributionTags,const string & jobName,const ScheduledJobStateChanged::State state,uint64_t timestampNs)1082 std::unique_ptr<LogEvent> CreateScheduledJobStateChangedEvent(
1083         const vector<int>& attributionUids, const vector<string>& attributionTags,
1084         const string& jobName, const ScheduledJobStateChanged::State state, uint64_t timestampNs) {
1085     AStatsEvent* statsEvent = AStatsEvent_obtain();
1086     AStatsEvent_setAtomId(statsEvent, util::SCHEDULED_JOB_STATE_CHANGED);
1087     AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1088 
1089     writeAttribution(statsEvent, attributionUids, attributionTags);
1090     AStatsEvent_writeString(statsEvent, jobName.c_str());
1091     AStatsEvent_writeInt32(statsEvent, state);
1092 
1093     std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1094     parseStatsEventToLogEvent(statsEvent, logEvent.get());
1095     return logEvent;
1096 }
1097 
CreateStartScheduledJobEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & jobName)1098 std::unique_ptr<LogEvent> CreateStartScheduledJobEvent(uint64_t timestampNs,
1099                                                        const vector<int>& attributionUids,
1100                                                        const vector<string>& attributionTags,
1101                                                        const string& jobName) {
1102     return CreateScheduledJobStateChangedEvent(attributionUids, attributionTags, jobName,
1103                                                ScheduledJobStateChanged::STARTED, timestampNs);
1104 }
1105 
1106 // Create log event when scheduled job finishes.
CreateFinishScheduledJobEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & jobName)1107 std::unique_ptr<LogEvent> CreateFinishScheduledJobEvent(uint64_t timestampNs,
1108                                                         const vector<int>& attributionUids,
1109                                                         const vector<string>& attributionTags,
1110                                                         const string& jobName) {
1111     return CreateScheduledJobStateChangedEvent(attributionUids, attributionTags, jobName,
1112                                                ScheduledJobStateChanged::FINISHED, timestampNs);
1113 }
1114 
1115 // Create log event when scheduled job is scheduled.
CreateScheduleScheduledJobEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & jobName)1116 std::unique_ptr<LogEvent> CreateScheduleScheduledJobEvent(uint64_t timestampNs,
1117                                                           const vector<int>& attributionUids,
1118                                                           const vector<string>& attributionTags,
1119                                                           const string& jobName) {
1120     return CreateScheduledJobStateChangedEvent(attributionUids, attributionTags, jobName,
1121                                                ScheduledJobStateChanged::SCHEDULED, timestampNs);
1122 }
1123 
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)1124 std::unique_ptr<LogEvent> CreateTestAtomReportedEventVariableRepeatedFields(
1125         uint64_t timestampNs, const vector<int>& repeatedIntField,
1126         const vector<int64_t>& repeatedLongField, const vector<float>& repeatedFloatField,
1127         const vector<string>& repeatedStringField, const bool* repeatedBoolField,
1128         const size_t repeatedBoolFieldLength, const vector<int>& repeatedEnumField) {
1129     return CreateTestAtomReportedEvent(timestampNs, {1001, 1002}, {"app1", "app2"}, 5, 1000l, 21.9f,
1130                                        "string", 1, TestAtomReported::ON, {8, 1, 8, 2, 8, 3},
1131                                        repeatedIntField, repeatedLongField, repeatedFloatField,
1132                                        repeatedStringField, repeatedBoolField,
1133                                        repeatedBoolFieldLength, repeatedEnumField);
1134 }
1135 
CreateTestAtomReportedEventWithPrimitives(uint64_t timestampNs,int intField,long longField,float floatField,const string & stringField,bool boolField,TestAtomReported::State enumField)1136 std::unique_ptr<LogEvent> CreateTestAtomReportedEventWithPrimitives(
1137         uint64_t timestampNs, int intField, long longField, float floatField,
1138         const string& stringField, bool boolField, TestAtomReported::State enumField) {
1139     return CreateTestAtomReportedEvent(
1140             timestampNs, /* attributionUids */ {1001},
1141             /* attributionTags */ {"app1"}, intField, longField, floatField, stringField, boolField,
1142             enumField, /* bytesField */ {},
1143             /* repeatedIntField */ {}, /* repeatedLongField */ {}, /* repeatedFloatField */ {},
1144             /* repeatedStringField */ {}, /* repeatedBoolField */ {},
1145             /* repeatedBoolFieldLength */ 0, /* repeatedEnumField */ {});
1146 }
1147 
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)1148 std::unique_ptr<LogEvent> CreateTestAtomReportedEvent(
1149         uint64_t timestampNs, const vector<int>& attributionUids,
1150         const vector<string>& attributionTags, const int intField, const long longField,
1151         const float floatField, const string& stringField, const bool boolField,
1152         const TestAtomReported::State enumField, const vector<uint8_t>& bytesField,
1153         const vector<int>& repeatedIntField, const vector<int64_t>& repeatedLongField,
1154         const vector<float>& repeatedFloatField, const vector<string>& repeatedStringField,
1155         const bool* repeatedBoolField, const size_t repeatedBoolFieldLength,
1156         const vector<int>& repeatedEnumField) {
1157     vector<const char*> cRepeatedStringField(repeatedStringField.size());
1158     for (int i = 0; i < cRepeatedStringField.size(); i++) {
1159         cRepeatedStringField[i] = repeatedStringField[i].c_str();
1160     }
1161 
1162     AStatsEvent* statsEvent = AStatsEvent_obtain();
1163     AStatsEvent_setAtomId(statsEvent, util::TEST_ATOM_REPORTED);
1164     AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1165 
1166     writeAttribution(statsEvent, attributionUids, attributionTags);
1167     AStatsEvent_writeInt32(statsEvent, intField);
1168     AStatsEvent_writeInt64(statsEvent, longField);
1169     AStatsEvent_writeFloat(statsEvent, floatField);
1170     AStatsEvent_writeString(statsEvent, stringField.c_str());
1171     AStatsEvent_writeBool(statsEvent, boolField);
1172     AStatsEvent_writeInt32(statsEvent, enumField);
1173     AStatsEvent_writeByteArray(statsEvent, bytesField.data(), bytesField.size());
1174     if (__builtin_available(android __ANDROID_API_T__, *)) {
1175         /* CreateTestAtomReportedEvent is used in CreateTestAtomReportedEventVariableRepeatedFields
1176            and CreateTestAtomReportedEventWithPrimitives. Only
1177            CreateTestAtomReportedEventVariableRepeatedFields writes repeated fields, so wrapping
1178            this portion in a __builtin_available and
1179            CreateTestAtomReportedEventVariableRepeatedFields is annotated with __INTRODUCED_IN.
1180         */
1181         AStatsEvent_writeInt32Array(statsEvent, repeatedIntField.data(), repeatedIntField.size());
1182         AStatsEvent_writeInt64Array(statsEvent, repeatedLongField.data(), repeatedLongField.size());
1183         AStatsEvent_writeFloatArray(statsEvent, repeatedFloatField.data(),
1184                                     repeatedFloatField.size());
1185         AStatsEvent_writeStringArray(statsEvent, cRepeatedStringField.data(),
1186                                      repeatedStringField.size());
1187         AStatsEvent_writeBoolArray(statsEvent, repeatedBoolField, repeatedBoolFieldLength);
1188         AStatsEvent_writeInt32Array(statsEvent, repeatedEnumField.data(), repeatedEnumField.size());
1189     } else if (!repeatedIntField.empty() || !repeatedLongField.empty() ||
1190                !repeatedFloatField.empty() || !cRepeatedStringField.empty() ||
1191                repeatedBoolFieldLength != 0 || !repeatedEnumField.empty()) {
1192         ADD_FAILURE() << "CreateTestAtomReportedEvent w/ repeated fields is only available in "
1193                          "Android T and above.";
1194     }
1195 
1196     std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1197     parseStatsEventToLogEvent(statsEvent, logEvent.get());
1198     return logEvent;
1199 }
1200 
CreateWakelockStateChangedEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & wakelockName,const WakelockStateChanged::State state)1201 std::unique_ptr<LogEvent> CreateWakelockStateChangedEvent(uint64_t timestampNs,
1202                                                           const vector<int>& attributionUids,
1203                                                           const vector<string>& attributionTags,
1204                                                           const string& wakelockName,
1205                                                           const WakelockStateChanged::State state) {
1206     AStatsEvent* statsEvent = AStatsEvent_obtain();
1207     AStatsEvent_setAtomId(statsEvent, util::WAKELOCK_STATE_CHANGED);
1208     AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1209 
1210     writeAttribution(statsEvent, attributionUids, attributionTags);
1211     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID,
1212                                   true);
1213     AStatsEvent_writeInt32(statsEvent, android::os::WakeLockLevelEnum::PARTIAL_WAKE_LOCK);
1214     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD, true);
1215     AStatsEvent_writeString(statsEvent, wakelockName.c_str());
1216     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD, true);
1217     AStatsEvent_writeInt32(statsEvent, state);
1218     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_EXCLUSIVE_STATE, true);
1219     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_STATE_NESTED, true);
1220 
1221     std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1222     parseStatsEventToLogEvent(statsEvent, logEvent.get());
1223     return logEvent;
1224 }
1225 
CreateAcquireWakelockEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & wakelockName)1226 std::unique_ptr<LogEvent> CreateAcquireWakelockEvent(uint64_t timestampNs,
1227                                                      const vector<int>& attributionUids,
1228                                                      const vector<string>& attributionTags,
1229                                                      const string& wakelockName) {
1230     return CreateWakelockStateChangedEvent(timestampNs, attributionUids, attributionTags,
1231                                            wakelockName, WakelockStateChanged::ACQUIRE);
1232 }
1233 
CreateReleaseWakelockEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & wakelockName)1234 std::unique_ptr<LogEvent> CreateReleaseWakelockEvent(uint64_t timestampNs,
1235                                                      const vector<int>& attributionUids,
1236                                                      const vector<string>& attributionTags,
1237                                                      const string& wakelockName) {
1238     return CreateWakelockStateChangedEvent(timestampNs, attributionUids, attributionTags,
1239                                            wakelockName, WakelockStateChanged::RELEASE);
1240 }
1241 
CreateActivityForegroundStateChangedEvent(uint64_t timestampNs,const int uid,const string & pkgName,const string & className,const ActivityForegroundStateChanged::State state)1242 std::unique_ptr<LogEvent> CreateActivityForegroundStateChangedEvent(
1243         uint64_t timestampNs, const int uid, const string& pkgName, const string& className,
1244         const ActivityForegroundStateChanged::State state) {
1245     AStatsEvent* statsEvent = AStatsEvent_obtain();
1246     AStatsEvent_setAtomId(statsEvent, util::ACTIVITY_FOREGROUND_STATE_CHANGED);
1247     AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1248 
1249     AStatsEvent_writeInt32(statsEvent, uid);
1250     AStatsEvent_writeString(statsEvent, pkgName.c_str());
1251     AStatsEvent_writeString(statsEvent, className.c_str());
1252     AStatsEvent_writeInt32(statsEvent, state);
1253 
1254     std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1255     parseStatsEventToLogEvent(statsEvent, logEvent.get());
1256     return logEvent;
1257 }
1258 
CreateMoveToBackgroundEvent(uint64_t timestampNs,const int uid)1259 std::unique_ptr<LogEvent> CreateMoveToBackgroundEvent(uint64_t timestampNs, const int uid) {
1260     return CreateActivityForegroundStateChangedEvent(timestampNs, uid, "pkg_name", "class_name",
1261                                                      ActivityForegroundStateChanged::BACKGROUND);
1262 }
1263 
CreateMoveToForegroundEvent(uint64_t timestampNs,const int uid)1264 std::unique_ptr<LogEvent> CreateMoveToForegroundEvent(uint64_t timestampNs, const int uid) {
1265     return CreateActivityForegroundStateChangedEvent(timestampNs, uid, "pkg_name", "class_name",
1266                                                      ActivityForegroundStateChanged::FOREGROUND);
1267 }
1268 
CreateSyncStateChangedEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & name,const SyncStateChanged::State state)1269 std::unique_ptr<LogEvent> CreateSyncStateChangedEvent(uint64_t timestampNs,
1270                                                       const vector<int>& attributionUids,
1271                                                       const vector<string>& attributionTags,
1272                                                       const string& name,
1273                                                       const SyncStateChanged::State state) {
1274     AStatsEvent* statsEvent = AStatsEvent_obtain();
1275     AStatsEvent_setAtomId(statsEvent, util::SYNC_STATE_CHANGED);
1276     AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1277 
1278     writeAttribution(statsEvent, attributionUids, attributionTags);
1279     AStatsEvent_writeString(statsEvent, name.c_str());
1280     AStatsEvent_writeInt32(statsEvent, state);
1281 
1282     std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1283     parseStatsEventToLogEvent(statsEvent, logEvent.get());
1284     return logEvent;
1285 }
1286 
CreateSyncStartEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & name)1287 std::unique_ptr<LogEvent> CreateSyncStartEvent(uint64_t timestampNs,
1288                                                const vector<int>& attributionUids,
1289                                                const vector<string>& attributionTags,
1290                                                const string& name) {
1291     return CreateSyncStateChangedEvent(timestampNs, attributionUids, attributionTags, name,
1292                                        SyncStateChanged::ON);
1293 }
1294 
CreateSyncEndEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & name)1295 std::unique_ptr<LogEvent> CreateSyncEndEvent(uint64_t timestampNs,
1296                                              const vector<int>& attributionUids,
1297                                              const vector<string>& attributionTags,
1298                                              const string& name) {
1299     return CreateSyncStateChangedEvent(timestampNs, attributionUids, attributionTags, name,
1300                                        SyncStateChanged::OFF);
1301 }
1302 
CreateProcessLifeCycleStateChangedEvent(uint64_t timestampNs,const int uid,const ProcessLifeCycleStateChanged::State state)1303 std::unique_ptr<LogEvent> CreateProcessLifeCycleStateChangedEvent(
1304         uint64_t timestampNs, const int uid, const ProcessLifeCycleStateChanged::State state) {
1305     AStatsEvent* statsEvent = AStatsEvent_obtain();
1306     AStatsEvent_setAtomId(statsEvent, util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
1307     AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1308 
1309     AStatsEvent_writeInt32(statsEvent, uid);
1310     AStatsEvent_writeString(statsEvent, "");
1311     AStatsEvent_writeInt32(statsEvent, state);
1312 
1313     std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1314     parseStatsEventToLogEvent(statsEvent, logEvent.get());
1315     return logEvent;
1316 }
1317 
CreateAppCrashEvent(uint64_t timestampNs,const int uid)1318 std::unique_ptr<LogEvent> CreateAppCrashEvent(uint64_t timestampNs, const int uid) {
1319     return CreateProcessLifeCycleStateChangedEvent(timestampNs, uid,
1320                                                    ProcessLifeCycleStateChanged::CRASHED);
1321 }
1322 
CreateAppCrashOccurredEvent(uint64_t timestampNs,const int uid)1323 std::unique_ptr<LogEvent> CreateAppCrashOccurredEvent(uint64_t timestampNs, const int uid) {
1324     AStatsEvent* statsEvent = AStatsEvent_obtain();
1325     AStatsEvent_setAtomId(statsEvent, util::APP_CRASH_OCCURRED);
1326     AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1327 
1328     AStatsEvent_writeInt32(statsEvent, uid);
1329     AStatsEvent_writeString(statsEvent, "eventType");
1330     AStatsEvent_writeString(statsEvent, "processName");
1331 
1332     std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1333     parseStatsEventToLogEvent(statsEvent, logEvent.get());
1334     return logEvent;
1335 }
1336 
CreateIsolatedUidChangedEvent(uint64_t timestampNs,int hostUid,int isolatedUid,bool is_create)1337 std::unique_ptr<LogEvent> CreateIsolatedUidChangedEvent(uint64_t timestampNs, int hostUid,
1338                                                         int isolatedUid, bool is_create) {
1339     AStatsEvent* statsEvent = AStatsEvent_obtain();
1340     AStatsEvent_setAtomId(statsEvent, util::ISOLATED_UID_CHANGED);
1341     AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1342 
1343     AStatsEvent_writeInt32(statsEvent, hostUid);
1344     AStatsEvent_writeInt32(statsEvent, isolatedUid);
1345     AStatsEvent_writeInt32(statsEvent, is_create);
1346 
1347     std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1348     parseStatsEventToLogEvent(statsEvent, logEvent.get());
1349     return logEvent;
1350 }
1351 
CreateUidProcessStateChangedEvent(uint64_t timestampNs,int uid,const android::app::ProcessStateEnum state)1352 std::unique_ptr<LogEvent> CreateUidProcessStateChangedEvent(
1353         uint64_t timestampNs, int uid, const android::app::ProcessStateEnum state) {
1354     AStatsEvent* statsEvent = AStatsEvent_obtain();
1355     AStatsEvent_setAtomId(statsEvent, util::UID_PROCESS_STATE_CHANGED);
1356     AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1357 
1358     AStatsEvent_writeInt32(statsEvent, uid);
1359     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
1360     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD, true);
1361     AStatsEvent_writeInt32(statsEvent, state);
1362     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_EXCLUSIVE_STATE, true);
1363     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_STATE_NESTED, false);
1364 
1365     std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1366     parseStatsEventToLogEvent(statsEvent, logEvent.get());
1367     return logEvent;
1368 }
1369 
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)1370 std::unique_ptr<LogEvent> CreateBleScanStateChangedEvent(uint64_t timestampNs,
1371                                                          const vector<int>& attributionUids,
1372                                                          const vector<string>& attributionTags,
1373                                                          const BleScanStateChanged::State state,
1374                                                          const bool filtered, const bool firstMatch,
1375                                                          const bool opportunistic) {
1376     AStatsEvent* statsEvent = AStatsEvent_obtain();
1377     AStatsEvent_setAtomId(statsEvent, util::BLE_SCAN_STATE_CHANGED);
1378     AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1379 
1380     writeAttribution(statsEvent, attributionUids, attributionTags);
1381     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID,
1382                                   true);
1383     AStatsEvent_writeInt32(statsEvent, state);
1384     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_EXCLUSIVE_STATE, true);
1385     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_STATE_NESTED, true);
1386     if (state == util::BLE_SCAN_STATE_CHANGED__STATE__RESET) {
1387         AStatsEvent_addInt32Annotation(statsEvent, ASTATSLOG_ANNOTATION_ID_TRIGGER_STATE_RESET,
1388                                        util::BLE_SCAN_STATE_CHANGED__STATE__OFF);
1389     }
1390     AStatsEvent_writeBool(statsEvent, filtered);  // filtered
1391     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD, true);
1392     AStatsEvent_writeBool(statsEvent, firstMatch);  // first match
1393     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD, true);
1394     AStatsEvent_writeBool(statsEvent, opportunistic);  // opportunistic
1395     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD, true);
1396 
1397     std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1398     parseStatsEventToLogEvent(statsEvent, logEvent.get());
1399     return logEvent;
1400 }
1401 
CreateOverlayStateChangedEvent(int64_t timestampNs,const int32_t uid,const string & packageName,const bool usingAlertWindow,const OverlayStateChanged::State state)1402 std::unique_ptr<LogEvent> CreateOverlayStateChangedEvent(int64_t timestampNs, const int32_t uid,
1403                                                          const string& packageName,
1404                                                          const bool usingAlertWindow,
1405                                                          const OverlayStateChanged::State state) {
1406     AStatsEvent* statsEvent = AStatsEvent_obtain();
1407     AStatsEvent_setAtomId(statsEvent, util::OVERLAY_STATE_CHANGED);
1408     AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1409 
1410     AStatsEvent_writeInt32(statsEvent, uid);
1411     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
1412     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD, true);
1413     AStatsEvent_writeString(statsEvent, packageName.c_str());
1414     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_PRIMARY_FIELD, true);
1415     AStatsEvent_writeBool(statsEvent, usingAlertWindow);
1416     AStatsEvent_writeInt32(statsEvent, state);
1417     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_EXCLUSIVE_STATE, true);
1418     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_STATE_NESTED, false);
1419 
1420     std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1421     parseStatsEventToLogEvent(statsEvent, logEvent.get());
1422     return logEvent;
1423 }
1424 
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)1425 std::unique_ptr<LogEvent> CreateAppStartOccurredEvent(
1426         uint64_t timestampNs, const int uid, const string& pkgName,
1427         AppStartOccurred::TransitionType type, const string& activityName,
1428         const string& callingPkgName, const bool isInstantApp, int64_t activityStartMs) {
1429     AStatsEvent* statsEvent = AStatsEvent_obtain();
1430     AStatsEvent_setAtomId(statsEvent, util::APP_START_OCCURRED);
1431     AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1432 
1433     AStatsEvent_writeInt32(statsEvent, uid);
1434     AStatsEvent_writeString(statsEvent, pkgName.c_str());
1435     AStatsEvent_writeInt32(statsEvent, type);
1436     AStatsEvent_writeString(statsEvent, activityName.c_str());
1437     AStatsEvent_writeString(statsEvent, callingPkgName.c_str());
1438     AStatsEvent_writeInt32(statsEvent, isInstantApp);
1439     AStatsEvent_writeInt32(statsEvent, activityStartMs);
1440 
1441     std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1442     parseStatsEventToLogEvent(statsEvent, logEvent.get());
1443     return logEvent;
1444 }
1445 
CreateBleScanResultReceivedEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const int numResults)1446 std::unique_ptr<LogEvent> CreateBleScanResultReceivedEvent(uint64_t timestampNs,
1447                                                            const vector<int>& attributionUids,
1448                                                            const vector<string>& attributionTags,
1449                                                            const int numResults) {
1450     AStatsEvent* statsEvent = AStatsEvent_obtain();
1451     AStatsEvent_setAtomId(statsEvent, util::BLE_SCAN_RESULT_RECEIVED);
1452     AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1453 
1454     writeAttribution(statsEvent, attributionUids, attributionTags);
1455     AStatsEvent_writeInt32(statsEvent, numResults);
1456 
1457     std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1458     parseStatsEventToLogEvent(statsEvent, logEvent.get());
1459     return logEvent;
1460 }
1461 
CreateRestrictedLogEvent(int atomTag,int64_t timestampNs)1462 std::unique_ptr<LogEvent> CreateRestrictedLogEvent(int atomTag, int64_t timestampNs) {
1463     AStatsEvent* statsEvent = AStatsEvent_obtain();
1464     AStatsEvent_setAtomId(statsEvent, atomTag);
1465     AStatsEvent_addInt32Annotation(statsEvent, ASTATSLOG_ANNOTATION_ID_RESTRICTION_CATEGORY,
1466                                    ASTATSLOG_RESTRICTION_CATEGORY_DIAGNOSTIC);
1467     AStatsEvent_writeInt32(statsEvent, 10);
1468     AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1469     std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1470     parseStatsEventToLogEvent(statsEvent, logEvent.get());
1471     return logEvent;
1472 }
1473 
CreateNonRestrictedLogEvent(int atomTag,int64_t timestampNs)1474 std::unique_ptr<LogEvent> CreateNonRestrictedLogEvent(int atomTag, int64_t timestampNs) {
1475     AStatsEvent* statsEvent = AStatsEvent_obtain();
1476     AStatsEvent_setAtomId(statsEvent, atomTag);
1477     AStatsEvent_writeInt32(statsEvent, 10);
1478     AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1479     std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1480     parseStatsEventToLogEvent(statsEvent, logEvent.get());
1481     return logEvent;
1482 }
1483 
CreatePhoneSignalStrengthChangedEvent(int64_t timestampNs,::telephony::SignalStrengthEnum state)1484 std::unique_ptr<LogEvent> CreatePhoneSignalStrengthChangedEvent(
1485         int64_t timestampNs, ::telephony::SignalStrengthEnum state) {
1486     AStatsEvent* statsEvent = AStatsEvent_obtain();
1487     AStatsEvent_setAtomId(statsEvent, util::PHONE_SIGNAL_STRENGTH_CHANGED);
1488     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_TRUNCATE_TIMESTAMP, true);
1489     AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
1490     AStatsEvent_writeInt32(statsEvent, state);
1491 
1492     std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
1493     parseStatsEventToLogEvent(statsEvent, logEvent.get());
1494     return logEvent;
1495 }
1496 
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)1497 sp<StatsLogProcessor> CreateStatsLogProcessor(const int64_t timeBaseNs, const int64_t currentTimeNs,
1498                                               const StatsdConfig& config, const ConfigKey& key,
1499                                               const shared_ptr<IPullAtomCallback>& puller,
1500                                               const int32_t atomTag, const sp<UidMap> uidMap,
1501                                               const shared_ptr<LogEventFilter>& logEventFilter) {
1502     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
1503     StatsPuller::SetUidMap(uidMap);
1504     if (puller != nullptr) {
1505         pullerManager->RegisterPullAtomCallback(/*uid=*/0, atomTag, NS_PER_SEC, NS_PER_SEC * 10, {},
1506                                                 puller);
1507     }
1508     sp<AlarmMonitor> anomalyAlarmMonitor =
1509         new AlarmMonitor(1,
1510                          [](const shared_ptr<IStatsCompanionService>&, int64_t){},
1511                          [](const shared_ptr<IStatsCompanionService>&){});
1512     sp<AlarmMonitor> periodicAlarmMonitor =
1513         new AlarmMonitor(1,
1514                          [](const shared_ptr<IStatsCompanionService>&, int64_t){},
1515                          [](const shared_ptr<IStatsCompanionService>&){});
1516     sp<StatsLogProcessor> processor = new StatsLogProcessor(
1517             uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor, timeBaseNs,
1518             [](const ConfigKey&) { return true; },
1519             [](const int&, const vector<int64_t>&) { return true; },
1520             [](const ConfigKey&, const string&, const vector<int64_t>&) {}, logEventFilter);
1521 
1522     processor->OnConfigUpdated(currentTimeNs, key, config);
1523     return processor;
1524 }
1525 
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)1526 sp<NumericValueMetricProducer> createNumericValueMetricProducer(
1527         sp<MockStatsPullerManager>& pullerManager, const ValueMetric& metric, const int atomId,
1528         bool isPulled, const ConfigKey& configKey, const uint64_t protoHash,
1529         const int64_t timeBaseNs, const int64_t startTimeNs, const int logEventMatcherIndex,
1530         optional<ConditionState> conditionAfterFirstBucketPrepared,
1531         vector<int32_t> slicedStateAtoms,
1532         unordered_map<int, unordered_map<int, int64_t>> stateGroupMap,
1533         sp<EventMatcherWizard> eventMatcherWizard) {
1534     if (eventMatcherWizard == nullptr) {
1535         eventMatcherWizard = createEventMatcherWizard(atomId, logEventMatcherIndex);
1536     }
1537     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
1538     if (isPulled) {
1539         EXPECT_CALL(*pullerManager, RegisterReceiver(atomId, configKey, _, _, _))
1540                 .WillOnce(Return());
1541         EXPECT_CALL(*pullerManager, UnRegisterReceiver(atomId, configKey, _))
1542                 .WillRepeatedly(Return());
1543     }
1544     const int64_t bucketSizeNs = MillisToNano(
1545             TimeUnitToBucketSizeInMillisGuardrailed(configKey.GetUid(), metric.bucket()));
1546     const bool containsAnyPositionInDimensionsInWhat = HasPositionANY(metric.dimensions_in_what());
1547     const bool shouldUseNestedDimensions = ShouldUseNestedDimensions(metric.dimensions_in_what());
1548 
1549     vector<Matcher> fieldMatchers;
1550     translateFieldMatcher(metric.value_field(), &fieldMatchers);
1551 
1552     const auto [dimensionSoftLimit, dimensionHardLimit] =
1553             StatsdStats::getAtomDimensionKeySizeLimits(atomId,
1554                                                        StatsdStats::kDimensionKeySizeHardLimitMin);
1555 
1556     int conditionIndex = conditionAfterFirstBucketPrepared ? 0 : -1;
1557     vector<ConditionState> initialConditionCache;
1558     if (conditionAfterFirstBucketPrepared) {
1559         initialConditionCache.push_back(ConditionState::kUnknown);
1560     }
1561 
1562     // get the condition_correction_threshold_nanos value
1563     const optional<int64_t> conditionCorrectionThresholdNs =
1564             metric.has_condition_correction_threshold_nanos()
1565                     ? optional<int64_t>(metric.condition_correction_threshold_nanos())
1566                     : nullopt;
1567 
1568     std::vector<ValueMetric::AggregationType> aggregationTypes;
1569     if (metric.aggregation_types_size() != 0) {
1570         for (int i = 0; i < metric.aggregation_types_size(); i++) {
1571             aggregationTypes.push_back(metric.aggregation_types(i));
1572         }
1573     } else {  // aggregation_type() is set or default is used.
1574         aggregationTypes.push_back(metric.aggregation_type());
1575     }
1576 
1577     ParseHistogramBinConfigsResult parseBinConfigsResult =
1578             parseHistogramBinConfigs(metric, aggregationTypes);
1579     const vector<optional<const BinStarts>>& binStartsList =
1580             std::get<vector<optional<const BinStarts>>>(parseBinConfigsResult);
1581 
1582     sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
1583     const int pullAtomId = isPulled ? atomId : -1;
1584     return new NumericValueMetricProducer(
1585             configKey, metric, protoHash, {pullAtomId, pullerManager},
1586             {timeBaseNs, startTimeNs, bucketSizeNs, metric.min_bucket_size_nanos(),
1587              conditionCorrectionThresholdNs, metric.split_bucket_for_app_upgrade()},
1588             {containsAnyPositionInDimensionsInWhat, shouldUseNestedDimensions, logEventMatcherIndex,
1589              eventMatcherWizard, metric.dimensions_in_what(), fieldMatchers, aggregationTypes,
1590              binStartsList},
1591             {conditionIndex, metric.links(), initialConditionCache, wizard},
1592             {metric.state_link(), slicedStateAtoms, stateGroupMap},
1593             {/*eventActivationMap=*/{}, /*eventDeactivationMap=*/{}},
1594             {dimensionSoftLimit, dimensionHardLimit}, provider);
1595 }
1596 
CreateAtomIdSetDefault()1597 LogEventFilter::AtomIdSet CreateAtomIdSetDefault() {
1598     LogEventFilter::AtomIdSet resultList(StatsLogProcessor::getDefaultAtomIdSet());
1599     StateManager::getInstance().addAllAtomIds(resultList);
1600     return resultList;
1601 }
1602 
CreateAtomIdSetFromConfig(const StatsdConfig & config)1603 LogEventFilter::AtomIdSet CreateAtomIdSetFromConfig(const StatsdConfig& config) {
1604     LogEventFilter::AtomIdSet resultList(StatsLogProcessor::getDefaultAtomIdSet());
1605 
1606     // Parse the config for atom ids. A combination atom matcher is a combination of (in the end)
1607     // simple atom matchers. So by adding all the atoms from the simple atom matchers
1608     // function adds all of the atoms.
1609     for (int i = 0; i < config.atom_matcher_size(); i++) {
1610         const AtomMatcher& matcher = config.atom_matcher(i);
1611         if (matcher.has_simple_atom_matcher()) {
1612             EXPECT_TRUE(matcher.simple_atom_matcher().has_atom_id());
1613             resultList.insert(matcher.simple_atom_matcher().atom_id());
1614         }
1615     }
1616 
1617     for (int i = 0; i < config.state_size(); i++) {
1618         const State& state = config.state(i);
1619         EXPECT_TRUE(state.has_atom_id());
1620         resultList.insert(state.atom_id());
1621     }
1622 
1623     return resultList;
1624 }
1625 
sortLogEventsByTimestamp(std::vector<std::unique_ptr<LogEvent>> * events)1626 void sortLogEventsByTimestamp(std::vector<std::unique_ptr<LogEvent>> *events) {
1627   std::sort(events->begin(), events->end(),
1628             [](const std::unique_ptr<LogEvent>& a, const std::unique_ptr<LogEvent>& b) {
1629               return a->GetElapsedTimestampNs() < b->GetElapsedTimestampNs();
1630             });
1631 }
1632 
StringToId(const string & str)1633 int64_t StringToId(const string& str) {
1634     return static_cast<int64_t>(std::hash<std::string>()(str));
1635 }
1636 
createEventMatcherWizard(int tagId,int matcherIndex,const vector<FieldValueMatcher> & fieldValueMatchers)1637 sp<EventMatcherWizard> createEventMatcherWizard(
1638         int tagId, int matcherIndex, const vector<FieldValueMatcher>& fieldValueMatchers) {
1639     sp<UidMap> uidMap = new UidMap();
1640     SimpleAtomMatcher atomMatcher;
1641     atomMatcher.set_atom_id(tagId);
1642     for (const FieldValueMatcher& fvm : fieldValueMatchers) {
1643         *atomMatcher.add_field_value_matcher() = fvm;
1644     }
1645     uint64_t matcherHash = 0x12345678;
1646     int64_t matcherId = 678;
1647     return new EventMatcherWizard(
1648             {new SimpleAtomMatchingTracker(matcherId, matcherHash, atomMatcher, uidMap)});
1649 }
1650 
CreateAttributionUidDimensionsValueParcel(const int atomId,const int uid)1651 StatsDimensionsValueParcel CreateAttributionUidDimensionsValueParcel(const int atomId,
1652                                                                      const int uid) {
1653     StatsDimensionsValueParcel root;
1654     root.field = atomId;
1655     root.valueType = STATS_DIMENSIONS_VALUE_TUPLE_TYPE;
1656     StatsDimensionsValueParcel attrNode;
1657     attrNode.field = 1;
1658     attrNode.valueType = STATS_DIMENSIONS_VALUE_TUPLE_TYPE;
1659     StatsDimensionsValueParcel posInAttrChain;
1660     posInAttrChain.field = 1;
1661     posInAttrChain.valueType = STATS_DIMENSIONS_VALUE_TUPLE_TYPE;
1662     StatsDimensionsValueParcel uidNode;
1663     uidNode.field = 1;
1664     uidNode.valueType = STATS_DIMENSIONS_VALUE_INT_TYPE;
1665     uidNode.intValue = uid;
1666     posInAttrChain.tupleValue.push_back(uidNode);
1667     attrNode.tupleValue.push_back(posInAttrChain);
1668     root.tupleValue.push_back(attrNode);
1669     return root;
1670 }
1671 
ValidateUidDimension(const DimensionsValue & value,int atomId,int uid)1672 void ValidateUidDimension(const DimensionsValue& value, int atomId, int uid) {
1673     EXPECT_EQ(value.field(), atomId);
1674     ASSERT_EQ(value.value_tuple().dimensions_value_size(), 1);
1675     EXPECT_EQ(value.value_tuple().dimensions_value(0).field(), 1);
1676     EXPECT_EQ(value.value_tuple().dimensions_value(0).value_int(), uid);
1677 }
1678 
ValidateWakelockAttributionUidAndTagDimension(const DimensionsValue & value,const int atomId,const int uid,const string & tag)1679 void ValidateWakelockAttributionUidAndTagDimension(const DimensionsValue& value, const int atomId,
1680                                                    const int uid, const string& tag) {
1681     EXPECT_EQ(value.field(), atomId);
1682     ASSERT_EQ(value.value_tuple().dimensions_value_size(), 2);
1683     // Attribution field.
1684     EXPECT_EQ(value.value_tuple().dimensions_value(0).field(), 1);
1685     // Uid field.
1686     ASSERT_EQ(value.value_tuple().dimensions_value(0).value_tuple().dimensions_value_size(), 1);
1687     EXPECT_EQ(value.value_tuple().dimensions_value(0).value_tuple().dimensions_value(0).field(), 1);
1688     EXPECT_EQ(value.value_tuple().dimensions_value(0).value_tuple().dimensions_value(0).value_int(),
1689               uid);
1690     // Tag field.
1691     EXPECT_EQ(value.value_tuple().dimensions_value(1).field(), 3);
1692     EXPECT_EQ(value.value_tuple().dimensions_value(1).value_str(), tag);
1693 }
1694 
ValidateAttributionUidDimension(const DimensionsValue & value,int atomId,int uid)1695 void ValidateAttributionUidDimension(const DimensionsValue& value, int atomId, int uid) {
1696     EXPECT_EQ(value.field(), atomId);
1697     ASSERT_EQ(value.value_tuple().dimensions_value_size(), 1);
1698     // Attribution field.
1699     EXPECT_EQ(value.value_tuple().dimensions_value(0).field(), 1);
1700     // Uid only.
1701     EXPECT_EQ(value.value_tuple().dimensions_value(0)
1702         .value_tuple().dimensions_value_size(), 1);
1703     EXPECT_EQ(value.value_tuple().dimensions_value(0)
1704         .value_tuple().dimensions_value(0).field(), 1);
1705     EXPECT_EQ(value.value_tuple().dimensions_value(0)
1706         .value_tuple().dimensions_value(0).value_int(), uid);
1707 }
1708 
ValidateUidDimension(const DimensionsValue & value,int node_idx,int atomId,int uid)1709 void ValidateUidDimension(const DimensionsValue& value, int node_idx, int atomId, int uid) {
1710     EXPECT_EQ(value.field(), atomId);
1711     ASSERT_GT(value.value_tuple().dimensions_value_size(), node_idx);
1712     // Attribution field.
1713     EXPECT_EQ(value.value_tuple().dimensions_value(node_idx).field(), 1);
1714     EXPECT_EQ(value.value_tuple().dimensions_value(node_idx)
1715         .value_tuple().dimensions_value(0).field(), 1);
1716     EXPECT_EQ(value.value_tuple().dimensions_value(node_idx)
1717         .value_tuple().dimensions_value(0).value_int(), uid);
1718 }
1719 
ValidateAttributionUidAndTagDimension(const DimensionsValue & value,int node_idx,int atomId,int uid,const std::string & tag)1720 void ValidateAttributionUidAndTagDimension(
1721     const DimensionsValue& value, int node_idx, int atomId, int uid, const std::string& tag) {
1722     EXPECT_EQ(value.field(), atomId);
1723     ASSERT_GT(value.value_tuple().dimensions_value_size(), node_idx);
1724     // Attribution field.
1725     EXPECT_EQ(1, value.value_tuple().dimensions_value(node_idx).field());
1726     // Uid only.
1727     EXPECT_EQ(2, value.value_tuple().dimensions_value(node_idx)
1728         .value_tuple().dimensions_value_size());
1729     EXPECT_EQ(1, value.value_tuple().dimensions_value(node_idx)
1730         .value_tuple().dimensions_value(0).field());
1731     EXPECT_EQ(uid, value.value_tuple().dimensions_value(node_idx)
1732         .value_tuple().dimensions_value(0).value_int());
1733     EXPECT_EQ(2, value.value_tuple().dimensions_value(node_idx)
1734         .value_tuple().dimensions_value(1).field());
1735     EXPECT_EQ(tag, value.value_tuple().dimensions_value(node_idx)
1736         .value_tuple().dimensions_value(1).value_str());
1737 }
1738 
ValidateAttributionUidAndTagDimension(const DimensionsValue & value,int atomId,int uid,const std::string & tag)1739 void ValidateAttributionUidAndTagDimension(
1740     const DimensionsValue& value, int atomId, int uid, const std::string& tag) {
1741     EXPECT_EQ(value.field(), atomId);
1742     ASSERT_EQ(1, value.value_tuple().dimensions_value_size());
1743     // Attribution field.
1744     EXPECT_EQ(1, value.value_tuple().dimensions_value(0).field());
1745     // Uid only.
1746     EXPECT_EQ(value.value_tuple().dimensions_value(0)
1747         .value_tuple().dimensions_value_size(), 2);
1748     EXPECT_EQ(value.value_tuple().dimensions_value(0)
1749         .value_tuple().dimensions_value(0).field(), 1);
1750     EXPECT_EQ(value.value_tuple().dimensions_value(0)
1751         .value_tuple().dimensions_value(0).value_int(), uid);
1752     EXPECT_EQ(value.value_tuple().dimensions_value(0)
1753         .value_tuple().dimensions_value(1).field(), 2);
1754     EXPECT_EQ(value.value_tuple().dimensions_value(0)
1755         .value_tuple().dimensions_value(1).value_str(), tag);
1756 }
1757 
ValidateStateValue(const google::protobuf::RepeatedPtrField<StateValue> & stateValues,int atomId,int64_t value)1758 void ValidateStateValue(const google::protobuf::RepeatedPtrField<StateValue>& stateValues,
1759                         int atomId, int64_t value) {
1760     ASSERT_EQ(stateValues.size(), 1);
1761     ASSERT_EQ(stateValues[0].atom_id(), atomId);
1762     switch (stateValues[0].contents_case()) {
1763         case StateValue::ContentsCase::kValue:
1764             EXPECT_EQ(stateValues[0].value(), (int32_t)value);
1765             break;
1766         case StateValue::ContentsCase::kGroupId:
1767             EXPECT_EQ(stateValues[0].group_id(), value);
1768             break;
1769         default:
1770             FAIL() << "State value should have either a value or a group id";
1771     }
1772 }
1773 
ValidateCountBucket(const CountBucketInfo & countBucket,int64_t startTimeNs,int64_t endTimeNs,int64_t count,int64_t conditionTrueNs)1774 void ValidateCountBucket(const CountBucketInfo& countBucket, int64_t startTimeNs, int64_t endTimeNs,
1775                          int64_t count, int64_t conditionTrueNs) {
1776     EXPECT_EQ(countBucket.start_bucket_elapsed_nanos(), startTimeNs);
1777     EXPECT_EQ(countBucket.end_bucket_elapsed_nanos(), endTimeNs);
1778     EXPECT_EQ(countBucket.count(), count);
1779     EXPECT_EQ(countBucket.condition_true_nanos(), conditionTrueNs);
1780 }
1781 
ValidateDurationBucket(const DurationBucketInfo & bucket,int64_t startTimeNs,int64_t endTimeNs,int64_t durationNs,int64_t conditionTrueNs)1782 void ValidateDurationBucket(const DurationBucketInfo& bucket, int64_t startTimeNs,
1783                             int64_t endTimeNs, int64_t durationNs, int64_t conditionTrueNs) {
1784     EXPECT_EQ(bucket.start_bucket_elapsed_nanos(), startTimeNs);
1785     EXPECT_EQ(bucket.end_bucket_elapsed_nanos(), endTimeNs);
1786     EXPECT_EQ(bucket.duration_nanos(), durationNs);
1787     EXPECT_EQ(bucket.condition_true_nanos(), conditionTrueNs);
1788 }
1789 
ValidateGaugeBucketTimes(const GaugeBucketInfo & gaugeBucket,int64_t startTimeNs,int64_t endTimeNs,vector<int64_t> eventTimesNs)1790 void ValidateGaugeBucketTimes(const GaugeBucketInfo& gaugeBucket, int64_t startTimeNs,
1791                               int64_t endTimeNs, vector<int64_t> eventTimesNs) {
1792     EXPECT_EQ(gaugeBucket.start_bucket_elapsed_nanos(), startTimeNs);
1793     EXPECT_EQ(gaugeBucket.end_bucket_elapsed_nanos(), endTimeNs);
1794     EXPECT_EQ(gaugeBucket.elapsed_timestamp_nanos_size(), eventTimesNs.size());
1795     for (int i = 0; i < eventTimesNs.size(); i++) {
1796         EXPECT_EQ(gaugeBucket.elapsed_timestamp_nanos(i), eventTimesNs[i]);
1797     }
1798 }
1799 
ValidateValueBucket(const ValueBucketInfo & bucket,int64_t startTimeNs,int64_t endTimeNs,const vector<int64_t> & values,int64_t conditionTrueNs,int64_t conditionCorrectionNs)1800 void ValidateValueBucket(const ValueBucketInfo& bucket, int64_t startTimeNs, int64_t endTimeNs,
1801                          const vector<int64_t>& values, int64_t conditionTrueNs,
1802                          int64_t conditionCorrectionNs) {
1803     EXPECT_EQ(bucket.start_bucket_elapsed_nanos(), startTimeNs);
1804     EXPECT_EQ(bucket.end_bucket_elapsed_nanos(), endTimeNs);
1805     ASSERT_EQ(bucket.values_size(), values.size());
1806     for (int i = 0; i < values.size(); ++i) {
1807         if (bucket.values(i).has_value_double()) {
1808             EXPECT_EQ((int64_t)bucket.values(i).value_double(), values[i]);
1809         } else {
1810             EXPECT_EQ(bucket.values(i).value_long(), values[i]);
1811         }
1812     }
1813     if (conditionTrueNs > 0) {
1814         EXPECT_EQ(bucket.condition_true_nanos(), conditionTrueNs);
1815         if (conditionCorrectionNs > 0) {
1816             EXPECT_EQ(bucket.condition_correction_nanos(), conditionCorrectionNs);
1817         }
1818     }
1819 }
1820 
ValidateKllBucket(const KllBucketInfo & bucket,int64_t startTimeNs,int64_t endTimeNs,const vector<int64_t> sketchSizes,int64_t conditionTrueNs)1821 void ValidateKllBucket(const KllBucketInfo& bucket, int64_t startTimeNs, int64_t endTimeNs,
1822                        const vector<int64_t> sketchSizes, int64_t conditionTrueNs) {
1823     EXPECT_EQ(bucket.start_bucket_elapsed_nanos(), startTimeNs);
1824     EXPECT_EQ(bucket.end_bucket_elapsed_nanos(), endTimeNs);
1825     ASSERT_EQ(bucket.sketches_size(), sketchSizes.size());
1826     for (int i = 0; i < sketchSizes.size(); ++i) {
1827         AggregatorStateProto aggProto;
1828         EXPECT_TRUE(aggProto.ParseFromString(bucket.sketches(i).kll_sketch()));
1829         EXPECT_EQ(aggProto.num_values(), sketchSizes[i]);
1830     }
1831     if (conditionTrueNs > 0) {
1832         EXPECT_EQ(bucket.condition_true_nanos(), conditionTrueNs);
1833     }
1834 }
1835 
EqualsTo(const DimensionsValue & s1,const DimensionsValue & s2)1836 bool EqualsTo(const DimensionsValue& s1, const DimensionsValue& s2) {
1837     if (s1.field() != s2.field()) {
1838         return false;
1839     }
1840     if (s1.value_case() != s2.value_case()) {
1841         return false;
1842     }
1843     switch (s1.value_case()) {
1844         case DimensionsValue::ValueCase::kValueStr:
1845             return (s1.value_str() == s2.value_str());
1846         case DimensionsValue::ValueCase::kValueInt:
1847             return s1.value_int() == s2.value_int();
1848         case DimensionsValue::ValueCase::kValueLong:
1849             return s1.value_long() == s2.value_long();
1850         case DimensionsValue::ValueCase::kValueBool:
1851             return s1.value_bool() == s2.value_bool();
1852         case DimensionsValue::ValueCase::kValueFloat:
1853             return s1.value_float() == s2.value_float();
1854         case DimensionsValue::ValueCase::kValueTuple: {
1855             if (s1.value_tuple().dimensions_value_size() !=
1856                 s2.value_tuple().dimensions_value_size()) {
1857                 return false;
1858             }
1859             bool allMatched = true;
1860             for (int i = 0; allMatched && i < s1.value_tuple().dimensions_value_size(); ++i) {
1861                 allMatched &= EqualsTo(s1.value_tuple().dimensions_value(i),
1862                                        s2.value_tuple().dimensions_value(i));
1863             }
1864             return allMatched;
1865         }
1866         case DimensionsValue::ValueCase::VALUE_NOT_SET:
1867         default:
1868             return true;
1869     }
1870 }
1871 
LessThan(const google::protobuf::RepeatedPtrField<StateValue> & s1,const google::protobuf::RepeatedPtrField<StateValue> & s2)1872 bool LessThan(const google::protobuf::RepeatedPtrField<StateValue>& s1,
1873               const google::protobuf::RepeatedPtrField<StateValue>& s2) {
1874     if (s1.size() != s2.size()) {
1875         return s1.size() < s2.size();
1876     }
1877     for (int i = 0; i < s1.size(); i++) {
1878         const StateValue& state1 = s1[i];
1879         const StateValue& state2 = s2[i];
1880         if (state1.atom_id() != state2.atom_id()) {
1881             return state1.atom_id() < state2.atom_id();
1882         }
1883         if (state1.value() != state2.value()) {
1884             return state1.value() < state2.value();
1885         }
1886         if (state1.group_id() != state2.group_id()) {
1887             return state1.group_id() < state2.group_id();
1888         }
1889     }
1890     return false;
1891 }
1892 
LessThan(const DimensionsValue & s1,const DimensionsValue & s2)1893 bool LessThan(const DimensionsValue& s1, const DimensionsValue& s2) {
1894     if (s1.field() != s2.field()) {
1895         return s1.field() < s2.field();
1896     }
1897     if (s1.value_case() != s2.value_case()) {
1898         return s1.value_case() < s2.value_case();
1899     }
1900     switch (s1.value_case()) {
1901         case DimensionsValue::ValueCase::kValueStr:
1902             return s1.value_str() < s2.value_str();
1903         case DimensionsValue::ValueCase::kValueInt:
1904             return s1.value_int() < s2.value_int();
1905         case DimensionsValue::ValueCase::kValueLong:
1906             return s1.value_long() < s2.value_long();
1907         case DimensionsValue::ValueCase::kValueBool:
1908             return (int)s1.value_bool() < (int)s2.value_bool();
1909         case DimensionsValue::ValueCase::kValueFloat:
1910             return s1.value_float() < s2.value_float();
1911         case DimensionsValue::ValueCase::kValueTuple: {
1912             if (s1.value_tuple().dimensions_value_size() !=
1913                 s2.value_tuple().dimensions_value_size()) {
1914                 return s1.value_tuple().dimensions_value_size() <
1915                        s2.value_tuple().dimensions_value_size();
1916             }
1917             for (int i = 0; i < s1.value_tuple().dimensions_value_size(); ++i) {
1918                 if (EqualsTo(s1.value_tuple().dimensions_value(i),
1919                              s2.value_tuple().dimensions_value(i))) {
1920                     continue;
1921                 } else {
1922                     return LessThan(s1.value_tuple().dimensions_value(i),
1923                                     s2.value_tuple().dimensions_value(i));
1924                 }
1925             }
1926             return false;
1927         }
1928         case DimensionsValue::ValueCase::VALUE_NOT_SET:
1929         default:
1930             return false;
1931     }
1932 }
1933 
LessThan(const DimensionsPair & s1,const DimensionsPair & s2)1934 bool LessThan(const DimensionsPair& s1, const DimensionsPair& s2) {
1935     if (LessThan(s1.dimInWhat, s2.dimInWhat)) {
1936         return true;
1937     } else if (LessThan(s2.dimInWhat, s1.dimInWhat)) {
1938         return false;
1939     }
1940 
1941     return LessThan(s1.stateValues, s2.stateValues);
1942 }
1943 
backfillStringInDimension(const std::map<uint64_t,string> & str_map,DimensionsValue * dimension)1944 void backfillStringInDimension(const std::map<uint64_t, string>& str_map,
1945                                DimensionsValue* dimension) {
1946     if (dimension->has_value_str_hash()) {
1947         auto it = str_map.find((uint64_t)(dimension->value_str_hash()));
1948         if (it != str_map.end()) {
1949             dimension->clear_value_str_hash();
1950             dimension->set_value_str(it->second);
1951         } else {
1952             ALOGE("Can not find the string hash: %llu",
1953                 (unsigned long long)dimension->value_str_hash());
1954         }
1955     } else if (dimension->has_value_tuple()) {
1956         auto value_tuple = dimension->mutable_value_tuple();
1957         for (int i = 0; i < value_tuple->dimensions_value_size(); ++i) {
1958             backfillStringInDimension(str_map, value_tuple->mutable_dimensions_value(i));
1959         }
1960     }
1961 }
1962 
backfillStringInReport(ConfigMetricsReport * config_report)1963 void backfillStringInReport(ConfigMetricsReport *config_report) {
1964     std::map<uint64_t, string> str_map;
1965     for (const auto& str : config_report->strings()) {
1966         uint64_t hash = Hash64(str);
1967         if (str_map.find(hash) != str_map.end()) {
1968             ALOGE("String hash conflicts: %s %s", str.c_str(), str_map[hash].c_str());
1969         }
1970         str_map[hash] = str;
1971     }
1972     for (int i = 0; i < config_report->metrics_size(); ++i) {
1973         auto metric_report = config_report->mutable_metrics(i);
1974         if (metric_report->has_count_metrics()) {
1975             backfillStringInDimension(str_map, metric_report->mutable_count_metrics());
1976         } else if (metric_report->has_duration_metrics()) {
1977             backfillStringInDimension(str_map, metric_report->mutable_duration_metrics());
1978         } else if (metric_report->has_gauge_metrics()) {
1979             backfillStringInDimension(str_map, metric_report->mutable_gauge_metrics());
1980         } else if (metric_report->has_value_metrics()) {
1981             backfillStringInDimension(str_map, metric_report->mutable_value_metrics());
1982         } else if (metric_report->has_kll_metrics()) {
1983             backfillStringInDimension(str_map, metric_report->mutable_kll_metrics());
1984         }
1985     }
1986     // Backfill the package names.
1987     for (int i = 0 ; i < config_report->uid_map().snapshots_size(); ++i) {
1988         auto snapshot = config_report->mutable_uid_map()->mutable_snapshots(i);
1989         for (int j = 0 ; j < snapshot->package_info_size(); ++j) {
1990             auto package_info = snapshot->mutable_package_info(j);
1991             if (package_info->has_name_hash()) {
1992                 auto it = str_map.find((uint64_t)(package_info->name_hash()));
1993                 if (it != str_map.end()) {
1994                     package_info->clear_name_hash();
1995                     package_info->set_name(it->second);
1996                 } else {
1997                     ALOGE("Can not find the string package name hash: %llu",
1998                         (unsigned long long)package_info->name_hash());
1999                 }
2000 
2001             }
2002         }
2003     }
2004     // Backfill the app name in app changes.
2005     for (int i = 0 ; i < config_report->uid_map().changes_size(); ++i) {
2006         auto change = config_report->mutable_uid_map()->mutable_changes(i);
2007         if (change->has_app_hash()) {
2008             auto it = str_map.find((uint64_t)(change->app_hash()));
2009             if (it != str_map.end()) {
2010                 change->clear_app_hash();
2011                 change->set_app(it->second);
2012             } else {
2013                 ALOGE("Can not find the string change app name hash: %llu",
2014                     (unsigned long long)change->app_hash());
2015             }
2016         }
2017     }
2018 }
2019 
backfillStringInReport(ConfigMetricsReportList * config_report_list)2020 void backfillStringInReport(ConfigMetricsReportList *config_report_list) {
2021     for (int i = 0; i < config_report_list->reports_size(); ++i) {
2022         backfillStringInReport(config_report_list->mutable_reports(i));
2023     }
2024 }
2025 
backfillDimensionPath(const DimensionsValue & path,const google::protobuf::RepeatedPtrField<DimensionsValue> & leafValues,int * leafIndex,DimensionsValue * dimension)2026 bool backfillDimensionPath(const DimensionsValue& path,
2027                            const google::protobuf::RepeatedPtrField<DimensionsValue>& leafValues,
2028                            int* leafIndex, DimensionsValue* dimension) {
2029     dimension->set_field(path.field());
2030     if (path.has_value_tuple()) {
2031         for (int i = 0; i < path.value_tuple().dimensions_value_size(); ++i) {
2032             if (!backfillDimensionPath(path.value_tuple().dimensions_value(i), leafValues,
2033                                        leafIndex,
2034                                        dimension->mutable_value_tuple()->add_dimensions_value())) {
2035                 return false;
2036             }
2037         }
2038     } else {
2039         if (*leafIndex < 0 || *leafIndex >= leafValues.size()) {
2040             return false;
2041         }
2042         dimension->MergeFrom(leafValues.Get(*leafIndex));
2043         (*leafIndex)++;
2044     }
2045     return true;
2046 }
2047 
backfillDimensionPath(const DimensionsValue & path,const google::protobuf::RepeatedPtrField<DimensionsValue> & leafValues,DimensionsValue * dimension)2048 bool backfillDimensionPath(const DimensionsValue& path,
2049                            const google::protobuf::RepeatedPtrField<DimensionsValue>& leafValues,
2050                            DimensionsValue* dimension) {
2051     int leafIndex = 0;
2052     return backfillDimensionPath(path, leafValues, &leafIndex, dimension);
2053 }
2054 
backfillDimensionPath(StatsLogReport * report)2055 void backfillDimensionPath(StatsLogReport* report) {
2056     if (report->has_dimensions_path_in_what()) {
2057         auto whatPath = report->dimensions_path_in_what();
2058         if (report->has_count_metrics()) {
2059             backfillDimensionPath(whatPath, report->mutable_count_metrics());
2060         } else if (report->has_duration_metrics()) {
2061             backfillDimensionPath(whatPath, report->mutable_duration_metrics());
2062         } else if (report->has_gauge_metrics()) {
2063             backfillDimensionPath(whatPath, report->mutable_gauge_metrics());
2064         } else if (report->has_value_metrics()) {
2065             backfillDimensionPath(whatPath, report->mutable_value_metrics());
2066         } else if (report->has_kll_metrics()) {
2067             backfillDimensionPath(whatPath, report->mutable_kll_metrics());
2068         }
2069         report->clear_dimensions_path_in_what();
2070     }
2071 }
2072 
backfillDimensionPath(ConfigMetricsReport * config_report)2073 void backfillDimensionPath(ConfigMetricsReport* config_report) {
2074     for (int i = 0; i < config_report->metrics_size(); ++i) {
2075         backfillDimensionPath(config_report->mutable_metrics(i));
2076     }
2077 }
2078 
backfillDimensionPath(ConfigMetricsReportList * config_report_list)2079 void backfillDimensionPath(ConfigMetricsReportList* config_report_list) {
2080     for (int i = 0; i < config_report_list->reports_size(); ++i) {
2081         backfillDimensionPath(config_report_list->mutable_reports(i));
2082     }
2083 }
2084 
backfillStartEndTimestamp(StatsLogReport * report)2085 void backfillStartEndTimestamp(StatsLogReport *report) {
2086     const int64_t timeBaseNs = report->time_base_elapsed_nano_seconds();
2087     const int64_t bucketSizeNs = report->bucket_size_nano_seconds();
2088     if (report->has_count_metrics()) {
2089         backfillStartEndTimestampForMetrics(
2090             timeBaseNs, bucketSizeNs, report->mutable_count_metrics());
2091     } else if (report->has_duration_metrics()) {
2092         backfillStartEndTimestampForMetrics(
2093             timeBaseNs, bucketSizeNs, report->mutable_duration_metrics());
2094     } else if (report->has_gauge_metrics()) {
2095         backfillStartEndTimestampForMetrics(
2096             timeBaseNs, bucketSizeNs, report->mutable_gauge_metrics());
2097         if (report->gauge_metrics().skipped_size() > 0) {
2098             backfillStartEndTimestampForSkippedBuckets(
2099                 timeBaseNs, report->mutable_gauge_metrics());
2100         }
2101     } else if (report->has_value_metrics()) {
2102         backfillStartEndTimestampForMetrics(
2103             timeBaseNs, bucketSizeNs, report->mutable_value_metrics());
2104         if (report->value_metrics().skipped_size() > 0) {
2105             backfillStartEndTimestampForSkippedBuckets(
2106                 timeBaseNs, report->mutable_value_metrics());
2107         }
2108     } else if (report->has_kll_metrics()) {
2109         backfillStartEndTimestampForMetrics(timeBaseNs, bucketSizeNs,
2110                                             report->mutable_kll_metrics());
2111         if (report->kll_metrics().skipped_size() > 0) {
2112             backfillStartEndTimestampForSkippedBuckets(timeBaseNs, report->mutable_kll_metrics());
2113         }
2114     }
2115 }
2116 
backfillStartEndTimestamp(ConfigMetricsReport * config_report)2117 void backfillStartEndTimestamp(ConfigMetricsReport *config_report) {
2118     for (int j = 0; j < config_report->metrics_size(); ++j) {
2119         backfillStartEndTimestamp(config_report->mutable_metrics(j));
2120     }
2121 }
2122 
backfillStartEndTimestamp(ConfigMetricsReportList * config_report_list)2123 void backfillStartEndTimestamp(ConfigMetricsReportList *config_report_list) {
2124     for (int i = 0; i < config_report_list->reports_size(); ++i) {
2125         backfillStartEndTimestamp(config_report_list->mutable_reports(i));
2126     }
2127 }
2128 
backfillAggregatedAtoms(ConfigMetricsReportList * config_report_list)2129 void backfillAggregatedAtoms(ConfigMetricsReportList* config_report_list) {
2130     for (int i = 0; i < config_report_list->reports_size(); ++i) {
2131         backfillAggregatedAtoms(config_report_list->mutable_reports(i));
2132     }
2133 }
2134 
backfillAggregatedAtoms(ConfigMetricsReport * config_report)2135 void backfillAggregatedAtoms(ConfigMetricsReport* config_report) {
2136     for (int i = 0; i < config_report->metrics_size(); ++i) {
2137         backfillAggregatedAtoms(config_report->mutable_metrics(i));
2138     }
2139 }
2140 
backfillAggregatedAtoms(StatsLogReport * report)2141 void backfillAggregatedAtoms(StatsLogReport* report) {
2142     if (report->has_event_metrics()) {
2143         backfillAggregatedAtomsInEventMetric(report->mutable_event_metrics());
2144     }
2145     if (report->has_gauge_metrics()) {
2146         backfillAggregatedAtomsInGaugeMetric(report->mutable_gauge_metrics());
2147     }
2148 }
2149 
backfillAggregatedAtomsInEventMetric(StatsLogReport::EventMetricDataWrapper * wrapper)2150 void backfillAggregatedAtomsInEventMetric(StatsLogReport::EventMetricDataWrapper* wrapper) {
2151     std::vector<EventMetricData> metricData;
2152     for (int i = 0; i < wrapper->data_size(); ++i) {
2153         AggregatedAtomInfo* atomInfo = wrapper->mutable_data(i)->mutable_aggregated_atom_info();
2154         for (int j = 0; j < atomInfo->elapsed_timestamp_nanos_size(); j++) {
2155             EventMetricData data;
2156             *(data.mutable_atom()) = atomInfo->atom();
2157             data.set_elapsed_timestamp_nanos(atomInfo->elapsed_timestamp_nanos(j));
2158             metricData.push_back(data);
2159         }
2160         for (int j = 0; j < atomInfo->state_info_size(); j++) {
2161             for (auto timestampNs : atomInfo->state_info(j).elapsed_timestamp_nanos()) {
2162                 EventMetricData data;
2163                 *(data.mutable_atom()) = atomInfo->atom();
2164                 for (auto state : atomInfo->state_info(j).slice_by_state()) {
2165                     *(data.add_slice_by_state()) = state;
2166                 }
2167                 data.set_elapsed_timestamp_nanos(timestampNs);
2168                 metricData.push_back(data);
2169             }
2170         }
2171     }
2172 
2173     if (metricData.size() == 0) {
2174         return;
2175     }
2176 
2177     sort(metricData.begin(), metricData.end(),
2178          [](const EventMetricData& lhs, const EventMetricData& rhs) {
2179              return lhs.elapsed_timestamp_nanos() < rhs.elapsed_timestamp_nanos();
2180          });
2181 
2182     wrapper->clear_data();
2183     for (int i = 0; i < metricData.size(); ++i) {
2184         *(wrapper->add_data()) = metricData[i];
2185     }
2186 }
2187 
backfillAggregatedAtomsInGaugeMetric(StatsLogReport::GaugeMetricDataWrapper * wrapper)2188 void backfillAggregatedAtomsInGaugeMetric(StatsLogReport::GaugeMetricDataWrapper* wrapper) {
2189     for (int i = 0; i < wrapper->data_size(); ++i) {
2190         for (int j = 0; j < wrapper->data(i).bucket_info_size(); ++j) {
2191             GaugeBucketInfo* bucketInfo = wrapper->mutable_data(i)->mutable_bucket_info(j);
2192             vector<pair<Atom, int64_t>> atomData = unnestGaugeAtomData(*bucketInfo);
2193 
2194             if (atomData.size() == 0) {
2195                 return;
2196             }
2197 
2198             bucketInfo->clear_aggregated_atom_info();
2199             ASSERT_EQ(bucketInfo->atom_size(), 0);
2200             ASSERT_EQ(bucketInfo->elapsed_timestamp_nanos_size(), 0);
2201 
2202             for (int k = 0; k < atomData.size(); ++k) {
2203                 *(bucketInfo->add_atom()) = atomData[k].first;
2204                 bucketInfo->add_elapsed_timestamp_nanos(atomData[k].second);
2205             }
2206         }
2207     }
2208 }
2209 
unnestGaugeAtomData(const GaugeBucketInfo & bucketInfo)2210 vector<pair<Atom, int64_t>> unnestGaugeAtomData(const GaugeBucketInfo& bucketInfo) {
2211     vector<pair<Atom, int64_t>> atomData;
2212     for (int k = 0; k < bucketInfo.aggregated_atom_info_size(); ++k) {
2213         const AggregatedAtomInfo& atomInfo = bucketInfo.aggregated_atom_info(k);
2214         for (int l = 0; l < atomInfo.elapsed_timestamp_nanos_size(); ++l) {
2215             atomData.push_back(make_pair(atomInfo.atom(), atomInfo.elapsed_timestamp_nanos(l)));
2216         }
2217     }
2218 
2219     sort(atomData.begin(), atomData.end(),
2220          [](const pair<Atom, int64_t>& lhs, const pair<Atom, int64_t>& rhs) {
2221              return lhs.second < rhs.second;
2222          });
2223 
2224     return atomData;
2225 }
2226 
sortReportsByElapsedTime(ConfigMetricsReportList * configReportList)2227 void sortReportsByElapsedTime(ConfigMetricsReportList* configReportList) {
2228     RepeatedPtrField<ConfigMetricsReport>* reports = configReportList->mutable_reports();
2229     sort(reports->pointer_begin(), reports->pointer_end(),
2230          [](const ConfigMetricsReport* lhs, const ConfigMetricsReport* rhs) {
2231              return lhs->current_report_elapsed_nanos() < rhs->current_report_elapsed_nanos();
2232          });
2233 }
2234 
onPullAtom(int atomTag,const shared_ptr<IPullAtomResultReceiver> & resultReceiver)2235 Status FakeSubsystemSleepCallback::onPullAtom(int atomTag,
2236         const shared_ptr<IPullAtomResultReceiver>& resultReceiver) {
2237     // Convert stats_events into StatsEventParcels.
2238     std::vector<StatsEventParcel> parcels;
2239     for (int i = 1; i < 3; i++) {
2240         AStatsEvent* event = AStatsEvent_obtain();
2241         AStatsEvent_setAtomId(event, atomTag);
2242         std::string subsystemName = "subsystem_name_";
2243         subsystemName = subsystemName + std::to_string(i);
2244         AStatsEvent_writeString(event, subsystemName.c_str());
2245         AStatsEvent_writeString(event, "subsystem_subname foo");
2246         AStatsEvent_writeInt64(event, /*count= */ i);
2247         AStatsEvent_writeInt64(event, /*time_millis= */ pullNum * pullNum * 100 + i);
2248         AStatsEvent_build(event);
2249         size_t size;
2250         uint8_t* buffer = AStatsEvent_getBuffer(event, &size);
2251 
2252         StatsEventParcel p;
2253         // vector.assign() creates a copy, but this is inevitable unless
2254         // stats_event.h/c uses a vector as opposed to a buffer.
2255         p.buffer.assign(buffer, buffer + size);
2256         parcels.push_back(std::move(p));
2257         AStatsEvent_release(event);
2258     }
2259     pullNum++;
2260     resultReceiver->pullFinished(atomTag, /*success=*/true, parcels);
2261     return Status::ok();
2262 }
2263 
onPullAtom(int atomTag,const shared_ptr<IPullAtomResultReceiver> & resultReceiver)2264 Status FakeCpuTimeCallback::onPullAtom(int atomTag,
2265                                        const shared_ptr<IPullAtomResultReceiver>& resultReceiver) {
2266     // Convert stats_events into StatsEventParcels.
2267     std::vector<StatsEventParcel> parcels;
2268     for (int i = 1; i < 3; i++) {
2269         AStatsEvent* event = AStatsEvent_obtain();
2270         AStatsEvent_setAtomId(event, atomTag);
2271         AStatsEvent_writeInt32(event, /*uid=*/i);
2272         AStatsEvent_writeInt64(event, /*user_time_micros= */ pullNum * pullNum * 100 + i);
2273         AStatsEvent_writeInt64(event, /*sys_time_micros= */ pullNum * pullNum * 100 * i);
2274         AStatsEvent_build(event);
2275         size_t size;
2276         uint8_t* buffer = AStatsEvent_getBuffer(event, &size);
2277 
2278         StatsEventParcel p;
2279         // vector.assign() creates a copy, but this is inevitable unless
2280         // stats_event.h/c uses a vector as opposed to a buffer.
2281         p.buffer.assign(buffer, buffer + size);
2282         parcels.push_back(std::move(p));
2283         AStatsEvent_release(event);
2284     }
2285     pullNum++;
2286     resultReceiver->pullFinished(atomTag, /*success=*/true, parcels);
2287     return Status::ok();
2288 }
2289 
writeFlag(const string & flagName,const string & flagValue)2290 void writeFlag(const string& flagName, const string& flagValue) {
2291     SetProperty(StringPrintf("persist.device_config.%s.%s", STATSD_NATIVE_NAMESPACE.c_str(),
2292                              flagName.c_str()),
2293                 flagValue);
2294 }
2295 
writeBootFlag(const string & flagName,const string & flagValue)2296 void writeBootFlag(const string& flagName, const string& flagValue) {
2297     SetProperty(StringPrintf("persist.device_config.%s.%s", STATSD_NATIVE_BOOT_NAMESPACE.c_str(),
2298                              flagName.c_str()),
2299                 flagValue);
2300 }
2301 
getPackageInfoSnapshot(const sp<UidMap> uidMap)2302 PackageInfoSnapshot getPackageInfoSnapshot(const sp<UidMap> uidMap) {
2303     ProtoOutputStream protoOutputStream;
2304     uidMap->writeUidMapSnapshot(/* timestamp */ 1,
2305                                 {/* includeVersionStrings */ true,
2306                                  /* includeInstaller */ true, /* certificateHashSize */ UINT8_MAX,
2307                                  /* omitSystemUids */ false},
2308                                 /* interestingUids */ {},
2309                                 /* installerIndices */ nullptr, /* str_set */ nullptr,
2310                                 &protoOutputStream);
2311 
2312     PackageInfoSnapshot packageInfoSnapshot;
2313     outputStreamToProto(&protoOutputStream, &packageInfoSnapshot);
2314     return packageInfoSnapshot;
2315 }
2316 
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)2317 PackageInfo buildPackageInfo(const string& name, const int32_t uid, const int64_t version,
2318                              const string& versionString, const optional<string> installer,
2319                              const vector<uint8_t>& certHash, const bool deleted,
2320                              const bool hashStrings, const optional<uint32_t> installerIndex) {
2321     PackageInfo packageInfo;
2322     packageInfo.set_version(version);
2323     packageInfo.set_uid(uid);
2324     packageInfo.set_deleted(deleted);
2325     if (!certHash.empty()) {
2326         packageInfo.set_truncated_certificate_hash(certHash.data(), certHash.size());
2327     }
2328     if (hashStrings) {
2329         packageInfo.set_name_hash(Hash64(name));
2330         packageInfo.set_version_string_hash(Hash64(versionString));
2331     } else {
2332         packageInfo.set_name(name);
2333         packageInfo.set_version_string(versionString);
2334     }
2335     if (installer) {
2336         if (installerIndex) {
2337             packageInfo.set_installer_index(*installerIndex);
2338         } else if (hashStrings) {
2339             packageInfo.set_installer_hash(Hash64(*installer));
2340         } else {
2341             packageInfo.set_installer(*installer);
2342         }
2343     }
2344     return packageInfo;
2345 }
2346 
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)2347 vector<PackageInfo> buildPackageInfos(
2348         const vector<string>& names, const vector<int32_t>& uids, const vector<int64_t>& versions,
2349         const vector<string>& versionStrings, const vector<string>& installers,
2350         const vector<vector<uint8_t>>& certHashes, const vector<uint8_t>& deleted,
2351         const vector<uint32_t>& installerIndices, const bool hashStrings) {
2352     vector<PackageInfo> packageInfos;
2353     for (int i = 0; i < uids.size(); i++) {
2354         const optional<uint32_t> installerIndex =
2355                 installerIndices.empty() ? nullopt : optional<uint32_t>(installerIndices[i]);
2356         const optional<string> installer =
2357                 installers.empty() ? nullopt : optional<string>(installers[i]);
2358         vector<uint8_t> certHash;
2359         if (!certHashes.empty()) {
2360             certHash = certHashes[i];
2361         }
2362         packageInfos.emplace_back(buildPackageInfo(names[i], uids[i], versions[i],
2363                                                    versionStrings[i], installer, certHash,
2364                                                    deleted[i], hashStrings, installerIndex));
2365     }
2366     return packageInfos;
2367 }
2368 
createApplicationInfo(const int32_t uid,const int64_t version,const string & versionString,const string & package)2369 ApplicationInfo createApplicationInfo(const int32_t uid, const int64_t version,
2370                                       const string& versionString, const string& package) {
2371     ApplicationInfo info;
2372     info.set_uid(uid);
2373     info.set_version(version);
2374     info.set_version_string(versionString);
2375     info.set_package_name(package);
2376     return info;
2377 }
2378 
getPulledAtomStats(int32_t atom_id)2379 StatsdStatsReport_PulledAtomStats getPulledAtomStats(int32_t atom_id) {
2380     StatsdStatsReport statsReport = getStatsdStatsReport();
2381     StatsdStatsReport_PulledAtomStats pulledAtomStats;
2382     for (size_t i = 0; i < statsReport.pulled_atom_stats_size(); i++) {
2383         if (statsReport.pulled_atom_stats(i).atom_id() == atom_id) {
2384             return statsReport.pulled_atom_stats(i);
2385         }
2386     }
2387     return pulledAtomStats;
2388 }
2389 
createStatsEvent(AStatsEvent * statsEvent,uint8_t typeId,uint32_t atomId)2390 void createStatsEvent(AStatsEvent* statsEvent, uint8_t typeId, uint32_t atomId) {
2391     AStatsEvent_setAtomId(statsEvent, atomId);
2392     fillStatsEventWithSampleValue(statsEvent, typeId);
2393 }
2394 
fillStatsEventWithSampleValue(AStatsEvent * statsEvent,uint8_t typeId)2395 void fillStatsEventWithSampleValue(AStatsEvent* statsEvent, uint8_t typeId) {
2396     int int32Array[2] = {3, 6};
2397     uint32_t uids[] = {1001, 1002};
2398     const char* tags[] = {"tag1", "tag2"};
2399 
2400     switch (typeId) {
2401         case INT32_TYPE:
2402             AStatsEvent_writeInt32(statsEvent, 10);
2403             break;
2404         case INT64_TYPE:
2405             AStatsEvent_writeInt64(statsEvent, 1000L);
2406             break;
2407         case STRING_TYPE:
2408             AStatsEvent_writeString(statsEvent, "test");
2409             break;
2410         case LIST_TYPE:
2411             if (__builtin_available(android __ANDROID_API_T__, *)) {
2412                 /* CAUTION: when using this function with LIST_TYPE,
2413                     wrap the code in a __builtin_available or __INTRODUCED_IN w/ T.
2414                  */
2415                 AStatsEvent_writeInt32Array(statsEvent, int32Array, 2);
2416             } else {
2417                 ADD_FAILURE() << "fillStatsEventWithSampleValue() w/ typeId LIST_TYPE should only "
2418                                  "be used on Android T or above.";
2419             }
2420             break;
2421         case FLOAT_TYPE:
2422             AStatsEvent_writeFloat(statsEvent, 1.3f);
2423             break;
2424         case BOOL_TYPE:
2425             AStatsEvent_writeBool(statsEvent, 1);
2426             break;
2427         case BYTE_ARRAY_TYPE:
2428             AStatsEvent_writeByteArray(statsEvent, (uint8_t*)"test", strlen("test"));
2429             break;
2430         case ATTRIBUTION_CHAIN_TYPE:
2431             AStatsEvent_writeAttributionChain(statsEvent, uids, tags, 2);
2432             break;
2433         default:
2434             break;
2435     }
2436 }
2437 
getStatsdStatsReport(bool resetStats)2438 StatsdStatsReport getStatsdStatsReport(bool resetStats) {
2439     StatsdStats& stats = StatsdStats::getInstance();
2440     return getStatsdStatsReport(stats, resetStats);
2441 }
2442 
getStatsdStatsReport(StatsdStats & stats,bool resetStats)2443 StatsdStatsReport getStatsdStatsReport(StatsdStats& stats, bool resetStats) {
2444     vector<uint8_t> statsBuffer;
2445     stats.dumpStats(&statsBuffer, resetStats);
2446     StatsdStatsReport statsReport;
2447     EXPECT_TRUE(statsReport.ParseFromArray(statsBuffer.data(), statsBuffer.size()));
2448     return statsReport;
2449 }
2450 
buildGoodConfig(int configId)2451 StatsdConfig buildGoodConfig(int configId) {
2452     StatsdConfig config;
2453     config.set_id(configId);
2454 
2455     AtomMatcher screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
2456     *config.add_atom_matcher() = screenOnMatcher;
2457     *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
2458 
2459     AtomMatcher* eventMatcher = config.add_atom_matcher();
2460     eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF"));
2461     AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
2462     combination->set_operation(LogicalOperation::OR);
2463     combination->add_matcher(screenOnMatcher.id());
2464     combination->add_matcher(StringToId("ScreenTurnedOff"));
2465 
2466     CountMetric* countMetric = config.add_count_metric();
2467     *countMetric = createCountMetric("Count", screenOnMatcher.id() /* what */,
2468                                      nullopt /* condition */, {} /* states */);
2469     countMetric->mutable_dimensions_in_what()->set_field(SCREEN_STATE_ATOM_ID);
2470     countMetric->mutable_dimensions_in_what()->add_child()->set_field(1);
2471 
2472     config.add_no_report_metric(StringToId("Count"));
2473 
2474     *config.add_predicate() = CreateScreenIsOnPredicate();
2475     *config.add_duration_metric() =
2476             createDurationMetric("Duration", StringToId("ScreenIsOn") /* what */,
2477                                  nullopt /* condition */, {} /* states */);
2478 
2479     *config.add_gauge_metric() = createGaugeMetric(
2480             "Gauge", screenOnMatcher.id() /* what */, GaugeMetric_SamplingType_FIRST_N_SAMPLES,
2481             nullopt /* condition */, nullopt /* triggerEvent */);
2482 
2483     *config.add_value_metric() =
2484             createValueMetric("Value", screenOnMatcher /* what */, 2 /* valueField */,
2485                               nullopt /* condition */, {} /* states */);
2486 
2487     *config.add_kll_metric() = createKllMetric("Kll", screenOnMatcher /* what */, 2 /* kllField */,
2488                                                nullopt /* condition */);
2489 
2490     return config;
2491 }
2492 
buildGoodConfig(int configId,int alertId)2493 StatsdConfig buildGoodConfig(int configId, int alertId) {
2494     StatsdConfig config = buildGoodConfig(configId);
2495     auto alert = config.add_alert();
2496     alert->set_id(alertId);
2497     alert->set_metric_id(StringToId("Count"));
2498     alert->set_num_buckets(10);
2499     alert->set_refractory_period_secs(100);
2500     alert->set_trigger_if_sum_gt(100);
2501 
2502     return config;
2503 }
2504 
makeMockConfigMetadataProvider(bool enabled)2505 sp<MockConfigMetadataProvider> makeMockConfigMetadataProvider(bool enabled) {
2506     sp<MockConfigMetadataProvider> metadataProvider = new StrictMock<MockConfigMetadataProvider>();
2507     EXPECT_CALL(*metadataProvider, useV2SoftMemoryCalculation()).Times(AnyNumber());
2508     EXPECT_CALL(*metadataProvider, useV2SoftMemoryCalculation()).WillRepeatedly(Return(enabled));
2509     return nullptr;
2510 }
2511 
createSocketLossInfo(int32_t uid,int32_t atomId)2512 SocketLossInfo createSocketLossInfo(int32_t uid, int32_t atomId) {
2513     SocketLossInfo lossInfo;
2514     lossInfo.uid = uid;
2515     lossInfo.errors.push_back(-11);
2516     lossInfo.atomIds.push_back(atomId);
2517     lossInfo.counts.push_back(1);
2518     return lossInfo;
2519 }
2520 
createSocketLossInfoLogEvent(int32_t uid,int32_t lossAtomId)2521 std::unique_ptr<LogEvent> createSocketLossInfoLogEvent(int32_t uid, int32_t lossAtomId) {
2522     const SocketLossInfo lossInfo = createSocketLossInfo(uid, lossAtomId);
2523 
2524     AStatsEvent* statsEvent = AStatsEvent_obtain();
2525     AStatsEvent_setAtomId(statsEvent, util::STATS_SOCKET_LOSS_REPORTED);
2526     AStatsEvent_writeInt32(statsEvent, lossInfo.uid);
2527     AStatsEvent_addBoolAnnotation(statsEvent, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
2528     AStatsEvent_writeInt64(statsEvent, lossInfo.firstLossTsNanos);
2529     AStatsEvent_writeInt64(statsEvent, lossInfo.lastLossTsNanos);
2530     AStatsEvent_writeInt32(statsEvent, lossInfo.overflowCounter);
2531     AStatsEvent_writeInt32Array(statsEvent, lossInfo.errors.data(), lossInfo.errors.size());
2532     AStatsEvent_writeInt32Array(statsEvent, lossInfo.atomIds.data(), lossInfo.atomIds.size());
2533     AStatsEvent_writeInt32Array(statsEvent, lossInfo.counts.data(), lossInfo.counts.size());
2534 
2535     std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(uid /* uid */, 0 /* pid */);
2536     parseStatsEventToLogEvent(statsEvent, logEvent.get());
2537     return logEvent;
2538 }
2539 
2540 }  // namespace statsd
2541 }  // namespace os
2542 }  // namespace android
2543