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 namespace android {
18 namespace os {
19 namespace statsd {
20 
21 
CreateSimpleAtomMatcher(const string & name,int atomId)22 AtomMatcher CreateSimpleAtomMatcher(const string& name, int atomId) {
23     AtomMatcher atom_matcher;
24     atom_matcher.set_id(StringToId(name));
25     auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
26     simple_atom_matcher->set_atom_id(atomId);
27     return atom_matcher;
28 }
29 
CreateTemperatureAtomMatcher()30 AtomMatcher CreateTemperatureAtomMatcher() {
31     return CreateSimpleAtomMatcher("TemperatureMatcher", android::util::TEMPERATURE);
32 }
33 
CreateScheduledJobStateChangedAtomMatcher(const string & name,ScheduledJobStateChanged::State state)34 AtomMatcher CreateScheduledJobStateChangedAtomMatcher(const string& name,
35                                                       ScheduledJobStateChanged::State state) {
36     AtomMatcher atom_matcher;
37     atom_matcher.set_id(StringToId(name));
38     auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
39     simple_atom_matcher->set_atom_id(android::util::SCHEDULED_JOB_STATE_CHANGED);
40     auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
41     field_value_matcher->set_field(3);  // State field.
42     field_value_matcher->set_eq_int(state);
43     return atom_matcher;
44 }
45 
CreateStartScheduledJobAtomMatcher()46 AtomMatcher CreateStartScheduledJobAtomMatcher() {
47     return CreateScheduledJobStateChangedAtomMatcher("ScheduledJobStart",
48                                                      ScheduledJobStateChanged::STARTED);
49 }
50 
CreateFinishScheduledJobAtomMatcher()51 AtomMatcher CreateFinishScheduledJobAtomMatcher() {
52     return CreateScheduledJobStateChangedAtomMatcher("ScheduledJobFinish",
53                                                      ScheduledJobStateChanged::FINISHED);
54 }
55 
CreateScreenBrightnessChangedAtomMatcher()56 AtomMatcher CreateScreenBrightnessChangedAtomMatcher() {
57     AtomMatcher atom_matcher;
58     atom_matcher.set_id(StringToId("ScreenBrightnessChanged"));
59     auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
60     simple_atom_matcher->set_atom_id(android::util::SCREEN_BRIGHTNESS_CHANGED);
61     return atom_matcher;
62 }
63 
CreateUidProcessStateChangedAtomMatcher()64 AtomMatcher CreateUidProcessStateChangedAtomMatcher() {
65     AtomMatcher atom_matcher;
66     atom_matcher.set_id(StringToId("UidProcessStateChanged"));
67     auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
68     simple_atom_matcher->set_atom_id(android::util::UID_PROCESS_STATE_CHANGED);
69     return atom_matcher;
70 }
71 
CreateWakelockStateChangedAtomMatcher(const string & name,WakelockStateChanged::State state)72 AtomMatcher CreateWakelockStateChangedAtomMatcher(const string& name,
73                                                   WakelockStateChanged::State state) {
74     AtomMatcher atom_matcher;
75     atom_matcher.set_id(StringToId(name));
76     auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
77     simple_atom_matcher->set_atom_id(android::util::WAKELOCK_STATE_CHANGED);
78     auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
79     field_value_matcher->set_field(4);  // State field.
80     field_value_matcher->set_eq_int(state);
81     return atom_matcher;
82 }
83 
CreateAcquireWakelockAtomMatcher()84 AtomMatcher CreateAcquireWakelockAtomMatcher() {
85     return CreateWakelockStateChangedAtomMatcher("AcquireWakelock", WakelockStateChanged::ACQUIRE);
86 }
87 
CreateReleaseWakelockAtomMatcher()88 AtomMatcher CreateReleaseWakelockAtomMatcher() {
89     return CreateWakelockStateChangedAtomMatcher("ReleaseWakelock", WakelockStateChanged::RELEASE);
90 }
91 
CreateBatterySaverModeStateChangedAtomMatcher(const string & name,BatterySaverModeStateChanged::State state)92 AtomMatcher CreateBatterySaverModeStateChangedAtomMatcher(
93     const string& name, BatterySaverModeStateChanged::State state) {
94     AtomMatcher atom_matcher;
95     atom_matcher.set_id(StringToId(name));
96     auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
97     simple_atom_matcher->set_atom_id(android::util::BATTERY_SAVER_MODE_STATE_CHANGED);
98     auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
99     field_value_matcher->set_field(1);  // State field.
100     field_value_matcher->set_eq_int(state);
101     return atom_matcher;
102 }
103 
CreateBatterySaverModeStartAtomMatcher()104 AtomMatcher CreateBatterySaverModeStartAtomMatcher() {
105     return CreateBatterySaverModeStateChangedAtomMatcher(
106         "BatterySaverModeStart", BatterySaverModeStateChanged::ON);
107 }
108 
109 
CreateBatterySaverModeStopAtomMatcher()110 AtomMatcher CreateBatterySaverModeStopAtomMatcher() {
111     return CreateBatterySaverModeStateChangedAtomMatcher(
112         "BatterySaverModeStop", BatterySaverModeStateChanged::OFF);
113 }
114 
115 
CreateScreenStateChangedAtomMatcher(const string & name,android::view::DisplayStateEnum state)116 AtomMatcher CreateScreenStateChangedAtomMatcher(
117     const string& name, android::view::DisplayStateEnum state) {
118     AtomMatcher atom_matcher;
119     atom_matcher.set_id(StringToId(name));
120     auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
121     simple_atom_matcher->set_atom_id(android::util::SCREEN_STATE_CHANGED);
122     auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
123     field_value_matcher->set_field(1);  // State field.
124     field_value_matcher->set_eq_int(state);
125     return atom_matcher;
126 }
127 
128 
CreateScreenTurnedOnAtomMatcher()129 AtomMatcher CreateScreenTurnedOnAtomMatcher() {
130     return CreateScreenStateChangedAtomMatcher("ScreenTurnedOn",
131             android::view::DisplayStateEnum::DISPLAY_STATE_ON);
132 }
133 
CreateScreenTurnedOffAtomMatcher()134 AtomMatcher CreateScreenTurnedOffAtomMatcher() {
135     return CreateScreenStateChangedAtomMatcher("ScreenTurnedOff",
136             ::android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
137 }
138 
CreateSyncStateChangedAtomMatcher(const string & name,SyncStateChanged::State state)139 AtomMatcher CreateSyncStateChangedAtomMatcher(
140     const string& name, SyncStateChanged::State state) {
141     AtomMatcher atom_matcher;
142     atom_matcher.set_id(StringToId(name));
143     auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
144     simple_atom_matcher->set_atom_id(android::util::SYNC_STATE_CHANGED);
145     auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
146     field_value_matcher->set_field(3);  // State field.
147     field_value_matcher->set_eq_int(state);
148     return atom_matcher;
149 }
150 
CreateSyncStartAtomMatcher()151 AtomMatcher CreateSyncStartAtomMatcher() {
152     return CreateSyncStateChangedAtomMatcher("SyncStart", SyncStateChanged::ON);
153 }
154 
CreateSyncEndAtomMatcher()155 AtomMatcher CreateSyncEndAtomMatcher() {
156     return CreateSyncStateChangedAtomMatcher("SyncEnd", SyncStateChanged::OFF);
157 }
158 
CreateActivityForegroundStateChangedAtomMatcher(const string & name,ActivityForegroundStateChanged::State state)159 AtomMatcher CreateActivityForegroundStateChangedAtomMatcher(
160     const string& name, ActivityForegroundStateChanged::State state) {
161     AtomMatcher atom_matcher;
162     atom_matcher.set_id(StringToId(name));
163     auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
164     simple_atom_matcher->set_atom_id(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED);
165     auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
166     field_value_matcher->set_field(4);  // Activity field.
167     field_value_matcher->set_eq_int(state);
168     return atom_matcher;
169 }
170 
CreateMoveToBackgroundAtomMatcher()171 AtomMatcher CreateMoveToBackgroundAtomMatcher() {
172     return CreateActivityForegroundStateChangedAtomMatcher(
173         "Background", ActivityForegroundStateChanged::BACKGROUND);
174 }
175 
CreateMoveToForegroundAtomMatcher()176 AtomMatcher CreateMoveToForegroundAtomMatcher() {
177     return CreateActivityForegroundStateChangedAtomMatcher(
178         "Foreground", ActivityForegroundStateChanged::FOREGROUND);
179 }
180 
CreateProcessLifeCycleStateChangedAtomMatcher(const string & name,ProcessLifeCycleStateChanged::State state)181 AtomMatcher CreateProcessLifeCycleStateChangedAtomMatcher(
182     const string& name, ProcessLifeCycleStateChanged::State state) {
183     AtomMatcher atom_matcher;
184     atom_matcher.set_id(StringToId(name));
185     auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
186     simple_atom_matcher->set_atom_id(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
187     auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
188     field_value_matcher->set_field(3);  // Process state field.
189     field_value_matcher->set_eq_int(state);
190     return atom_matcher;
191 }
192 
CreateProcessCrashAtomMatcher()193 AtomMatcher CreateProcessCrashAtomMatcher() {
194     return CreateProcessLifeCycleStateChangedAtomMatcher(
195         "Crashed", ProcessLifeCycleStateChanged::CRASHED);
196 }
197 
CreateScheduledJobPredicate()198 Predicate CreateScheduledJobPredicate() {
199     Predicate predicate;
200     predicate.set_id(StringToId("ScheduledJobRunningPredicate"));
201     predicate.mutable_simple_predicate()->set_start(StringToId("ScheduledJobStart"));
202     predicate.mutable_simple_predicate()->set_stop(StringToId("ScheduledJobFinish"));
203     return predicate;
204 }
205 
CreateBatterySaverModePredicate()206 Predicate CreateBatterySaverModePredicate() {
207     Predicate predicate;
208     predicate.set_id(StringToId("BatterySaverIsOn"));
209     predicate.mutable_simple_predicate()->set_start(StringToId("BatterySaverModeStart"));
210     predicate.mutable_simple_predicate()->set_stop(StringToId("BatterySaverModeStop"));
211     return predicate;
212 }
213 
CreateScreenIsOnPredicate()214 Predicate CreateScreenIsOnPredicate() {
215     Predicate predicate;
216     predicate.set_id(StringToId("ScreenIsOn"));
217     predicate.mutable_simple_predicate()->set_start(StringToId("ScreenTurnedOn"));
218     predicate.mutable_simple_predicate()->set_stop(StringToId("ScreenTurnedOff"));
219     return predicate;
220 }
221 
CreateScreenIsOffPredicate()222 Predicate CreateScreenIsOffPredicate() {
223     Predicate predicate;
224     predicate.set_id(1111123);
225     predicate.mutable_simple_predicate()->set_start(StringToId("ScreenTurnedOff"));
226     predicate.mutable_simple_predicate()->set_stop(StringToId("ScreenTurnedOn"));
227     return predicate;
228 }
229 
CreateHoldingWakelockPredicate()230 Predicate CreateHoldingWakelockPredicate() {
231     Predicate predicate;
232     predicate.set_id(StringToId("HoldingWakelock"));
233     predicate.mutable_simple_predicate()->set_start(StringToId("AcquireWakelock"));
234     predicate.mutable_simple_predicate()->set_stop(StringToId("ReleaseWakelock"));
235     return predicate;
236 }
237 
CreateIsSyncingPredicate()238 Predicate CreateIsSyncingPredicate() {
239     Predicate predicate;
240     predicate.set_id(33333333333333);
241     predicate.mutable_simple_predicate()->set_start(StringToId("SyncStart"));
242     predicate.mutable_simple_predicate()->set_stop(StringToId("SyncEnd"));
243     return predicate;
244 }
245 
CreateIsInBackgroundPredicate()246 Predicate CreateIsInBackgroundPredicate() {
247     Predicate predicate;
248     predicate.set_id(StringToId("IsInBackground"));
249     predicate.mutable_simple_predicate()->set_start(StringToId("Background"));
250     predicate.mutable_simple_predicate()->set_stop(StringToId("Foreground"));
251     return predicate;
252 }
253 
addPredicateToPredicateCombination(const Predicate & predicate,Predicate * combinationPredicate)254 void addPredicateToPredicateCombination(const Predicate& predicate,
255                                         Predicate* combinationPredicate) {
256     combinationPredicate->mutable_combination()->add_predicate(predicate.id());
257 }
258 
CreateAttributionUidDimensions(const int atomId,const std::vector<Position> & positions)259 FieldMatcher CreateAttributionUidDimensions(const int atomId,
260                                             const std::vector<Position>& positions) {
261     FieldMatcher dimensions;
262     dimensions.set_field(atomId);
263     for (const auto position : positions) {
264         auto child = dimensions.add_child();
265         child->set_field(1);
266         child->set_position(position);
267         child->add_child()->set_field(1);
268     }
269     return dimensions;
270 }
271 
CreateAttributionUidAndTagDimensions(const int atomId,const std::vector<Position> & positions)272 FieldMatcher CreateAttributionUidAndTagDimensions(const int atomId,
273                                                  const std::vector<Position>& positions) {
274     FieldMatcher dimensions;
275     dimensions.set_field(atomId);
276     for (const auto position : positions) {
277         auto child = dimensions.add_child();
278         child->set_field(1);
279         child->set_position(position);
280         child->add_child()->set_field(1);
281         child->add_child()->set_field(2);
282     }
283     return dimensions;
284 }
285 
CreateDimensions(const int atomId,const std::vector<int> & fields)286 FieldMatcher CreateDimensions(const int atomId, const std::vector<int>& fields) {
287     FieldMatcher dimensions;
288     dimensions.set_field(atomId);
289     for (const int field : fields) {
290         dimensions.add_child()->set_field(field);
291     }
292     return dimensions;
293 }
294 
CreateScreenStateChangedEvent(const android::view::DisplayStateEnum state,uint64_t timestampNs)295 std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(
296     const android::view::DisplayStateEnum state, uint64_t timestampNs) {
297     auto event = std::make_unique<LogEvent>(android::util::SCREEN_STATE_CHANGED, timestampNs);
298     EXPECT_TRUE(event->write(state));
299     event->init();
300     return event;
301 }
302 
CreateBatterySaverOnEvent(uint64_t timestampNs)303 std::unique_ptr<LogEvent> CreateBatterySaverOnEvent(uint64_t timestampNs) {
304     auto event = std::make_unique<LogEvent>(
305         android::util::BATTERY_SAVER_MODE_STATE_CHANGED, timestampNs);
306     EXPECT_TRUE(event->write(BatterySaverModeStateChanged::ON));
307     event->init();
308     return event;
309 }
310 
CreateBatterySaverOffEvent(uint64_t timestampNs)311 std::unique_ptr<LogEvent> CreateBatterySaverOffEvent(uint64_t timestampNs) {
312     auto event = std::make_unique<LogEvent>(
313         android::util::BATTERY_SAVER_MODE_STATE_CHANGED, timestampNs);
314     EXPECT_TRUE(event->write(BatterySaverModeStateChanged::OFF));
315     event->init();
316     return event;
317 }
318 
CreateScreenBrightnessChangedEvent(int level,uint64_t timestampNs)319 std::unique_ptr<LogEvent> CreateScreenBrightnessChangedEvent(
320     int level, uint64_t timestampNs) {
321     auto event = std::make_unique<LogEvent>(android::util::SCREEN_BRIGHTNESS_CHANGED, timestampNs);
322     EXPECT_TRUE(event->write(level));
323     event->init();
324     return event;
325 
326 }
327 
CreateScheduledJobStateChangedEvent(const std::vector<AttributionNodeInternal> & attributions,const string & jobName,const ScheduledJobStateChanged::State state,uint64_t timestampNs)328 std::unique_ptr<LogEvent> CreateScheduledJobStateChangedEvent(
329         const std::vector<AttributionNodeInternal>& attributions, const string& jobName,
330         const ScheduledJobStateChanged::State state, uint64_t timestampNs) {
331     auto event = std::make_unique<LogEvent>(android::util::SCHEDULED_JOB_STATE_CHANGED, timestampNs);
332     event->write(attributions);
333     event->write(jobName);
334     event->write(state);
335     event->init();
336     return event;
337 }
338 
CreateStartScheduledJobEvent(const std::vector<AttributionNodeInternal> & attributions,const string & name,uint64_t timestampNs)339 std::unique_ptr<LogEvent> CreateStartScheduledJobEvent(
340     const std::vector<AttributionNodeInternal>& attributions,
341     const string& name, uint64_t timestampNs) {
342     return CreateScheduledJobStateChangedEvent(
343             attributions, name, ScheduledJobStateChanged::STARTED, timestampNs);
344 }
345 
346 // Create log event when scheduled job finishes.
CreateFinishScheduledJobEvent(const std::vector<AttributionNodeInternal> & attributions,const string & name,uint64_t timestampNs)347 std::unique_ptr<LogEvent> CreateFinishScheduledJobEvent(
348     const std::vector<AttributionNodeInternal>& attributions,
349     const string& name, uint64_t timestampNs) {
350     return CreateScheduledJobStateChangedEvent(
351             attributions, name, ScheduledJobStateChanged::FINISHED, timestampNs);
352 }
353 
CreateWakelockStateChangedEvent(const std::vector<AttributionNodeInternal> & attributions,const string & wakelockName,const WakelockStateChanged::State state,uint64_t timestampNs)354 std::unique_ptr<LogEvent> CreateWakelockStateChangedEvent(
355         const std::vector<AttributionNodeInternal>& attributions, const string& wakelockName,
356         const WakelockStateChanged::State state, uint64_t timestampNs) {
357     auto event = std::make_unique<LogEvent>(android::util::WAKELOCK_STATE_CHANGED, timestampNs);
358     event->write(attributions);
359     event->write(android::os::WakeLockLevelEnum::PARTIAL_WAKE_LOCK);
360     event->write(wakelockName);
361     event->write(state);
362     event->init();
363     return event;
364 }
365 
CreateAcquireWakelockEvent(const std::vector<AttributionNodeInternal> & attributions,const string & wakelockName,uint64_t timestampNs)366 std::unique_ptr<LogEvent> CreateAcquireWakelockEvent(
367         const std::vector<AttributionNodeInternal>& attributions, const string& wakelockName,
368         uint64_t timestampNs) {
369     return CreateWakelockStateChangedEvent(
370         attributions, wakelockName, WakelockStateChanged::ACQUIRE, timestampNs);
371 }
372 
CreateReleaseWakelockEvent(const std::vector<AttributionNodeInternal> & attributions,const string & wakelockName,uint64_t timestampNs)373 std::unique_ptr<LogEvent> CreateReleaseWakelockEvent(
374         const std::vector<AttributionNodeInternal>& attributions, const string& wakelockName,
375         uint64_t timestampNs) {
376     return CreateWakelockStateChangedEvent(
377         attributions, wakelockName, WakelockStateChanged::RELEASE, timestampNs);
378 }
379 
CreateActivityForegroundStateChangedEvent(const int uid,const ActivityForegroundStateChanged::State state,uint64_t timestampNs)380 std::unique_ptr<LogEvent> CreateActivityForegroundStateChangedEvent(
381     const int uid, const ActivityForegroundStateChanged::State state, uint64_t timestampNs) {
382     auto event = std::make_unique<LogEvent>(
383         android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, timestampNs);
384     event->write(uid);
385     event->write("pkg_name");
386     event->write("class_name");
387     event->write(state);
388     event->init();
389     return event;
390 }
391 
CreateMoveToBackgroundEvent(const int uid,uint64_t timestampNs)392 std::unique_ptr<LogEvent> CreateMoveToBackgroundEvent(const int uid, uint64_t timestampNs) {
393     return CreateActivityForegroundStateChangedEvent(
394         uid, ActivityForegroundStateChanged::BACKGROUND, timestampNs);
395 }
396 
CreateMoveToForegroundEvent(const int uid,uint64_t timestampNs)397 std::unique_ptr<LogEvent> CreateMoveToForegroundEvent(const int uid, uint64_t timestampNs) {
398     return CreateActivityForegroundStateChangedEvent(
399         uid, ActivityForegroundStateChanged::FOREGROUND, timestampNs);
400 }
401 
CreateSyncStateChangedEvent(const std::vector<AttributionNodeInternal> & attributions,const string & name,const SyncStateChanged::State state,uint64_t timestampNs)402 std::unique_ptr<LogEvent> CreateSyncStateChangedEvent(
403         const std::vector<AttributionNodeInternal>& attributions, const string& name,
404         const SyncStateChanged::State state, uint64_t timestampNs) {
405     auto event = std::make_unique<LogEvent>(android::util::SYNC_STATE_CHANGED, timestampNs);
406     event->write(attributions);
407     event->write(name);
408     event->write(state);
409     event->init();
410     return event;
411 }
412 
CreateSyncStartEvent(const std::vector<AttributionNodeInternal> & attributions,const string & name,uint64_t timestampNs)413 std::unique_ptr<LogEvent> CreateSyncStartEvent(
414         const std::vector<AttributionNodeInternal>& attributions, const string& name,
415         uint64_t timestampNs) {
416     return CreateSyncStateChangedEvent(attributions, name, SyncStateChanged::ON, timestampNs);
417 }
418 
CreateSyncEndEvent(const std::vector<AttributionNodeInternal> & attributions,const string & name,uint64_t timestampNs)419 std::unique_ptr<LogEvent> CreateSyncEndEvent(
420         const std::vector<AttributionNodeInternal>& attributions, const string& name,
421         uint64_t timestampNs) {
422     return CreateSyncStateChangedEvent(attributions, name, SyncStateChanged::OFF, timestampNs);
423 }
424 
CreateProcessLifeCycleStateChangedEvent(const int uid,const ProcessLifeCycleStateChanged::State state,uint64_t timestampNs)425 std::unique_ptr<LogEvent> CreateProcessLifeCycleStateChangedEvent(
426     const int uid, const ProcessLifeCycleStateChanged::State state, uint64_t timestampNs) {
427     auto logEvent = std::make_unique<LogEvent>(
428         android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, timestampNs);
429     logEvent->write(uid);
430     logEvent->write("");
431     logEvent->write(state);
432     logEvent->init();
433     return logEvent;
434 }
435 
CreateAppCrashEvent(const int uid,uint64_t timestampNs)436 std::unique_ptr<LogEvent> CreateAppCrashEvent(const int uid, uint64_t timestampNs) {
437     return CreateProcessLifeCycleStateChangedEvent(
438         uid, ProcessLifeCycleStateChanged::CRASHED, timestampNs);
439 }
440 
CreateIsolatedUidChangedEvent(int isolatedUid,int hostUid,bool is_create,uint64_t timestampNs)441 std::unique_ptr<LogEvent> CreateIsolatedUidChangedEvent(
442     int isolatedUid, int hostUid, bool is_create, uint64_t timestampNs) {
443     auto logEvent = std::make_unique<LogEvent>(
444         android::util::ISOLATED_UID_CHANGED, timestampNs);
445     logEvent->write(hostUid);
446     logEvent->write(isolatedUid);
447     logEvent->write(is_create);
448     logEvent->init();
449     return logEvent;
450 }
451 
CreateStatsLogProcessor(const int64_t timeBaseNs,const int64_t currentTimeNs,const StatsdConfig & config,const ConfigKey & key)452 sp<StatsLogProcessor> CreateStatsLogProcessor(const int64_t timeBaseNs, const int64_t currentTimeNs,
453                                               const StatsdConfig& config, const ConfigKey& key) {
454     sp<UidMap> uidMap = new UidMap();
455     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
456     sp<AlarmMonitor> anomalyAlarmMonitor =
457         new AlarmMonitor(1,  [](const sp<IStatsCompanionService>&, int64_t){},
458                 [](const sp<IStatsCompanionService>&){});
459     sp<AlarmMonitor> periodicAlarmMonitor =
460         new AlarmMonitor(1,  [](const sp<IStatsCompanionService>&, int64_t){},
461                 [](const sp<IStatsCompanionService>&){});
462     sp<StatsLogProcessor> processor =
463             new StatsLogProcessor(uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
464                                   timeBaseNs, [](const ConfigKey&) { return true; },
465                                   [](const int&, const vector<int64_t>&) {return true;});
466     processor->OnConfigUpdated(currentTimeNs, key, config);
467     return processor;
468 }
469 
CreateAttribution(const int & uid,const string & tag)470 AttributionNodeInternal CreateAttribution(const int& uid, const string& tag) {
471     AttributionNodeInternal attribution;
472     attribution.set_uid(uid);
473     attribution.set_tag(tag);
474     return attribution;
475 }
476 
sortLogEventsByTimestamp(std::vector<std::unique_ptr<LogEvent>> * events)477 void sortLogEventsByTimestamp(std::vector<std::unique_ptr<LogEvent>> *events) {
478   std::sort(events->begin(), events->end(),
479             [](const std::unique_ptr<LogEvent>& a, const std::unique_ptr<LogEvent>& b) {
480               return a->GetElapsedTimestampNs() < b->GetElapsedTimestampNs();
481             });
482 }
483 
StringToId(const string & str)484 int64_t StringToId(const string& str) {
485     return static_cast<int64_t>(std::hash<std::string>()(str));
486 }
487 
ValidateAttributionUidDimension(const DimensionsValue & value,int atomId,int uid)488 void ValidateAttributionUidDimension(const DimensionsValue& value, int atomId, int uid) {
489     EXPECT_EQ(value.field(), atomId);
490     // Attribution field.
491     EXPECT_EQ(value.value_tuple().dimensions_value(0).field(), 1);
492     // Uid only.
493     EXPECT_EQ(value.value_tuple().dimensions_value(0)
494         .value_tuple().dimensions_value_size(), 1);
495     EXPECT_EQ(value.value_tuple().dimensions_value(0)
496         .value_tuple().dimensions_value(0).field(), 1);
497     EXPECT_EQ(value.value_tuple().dimensions_value(0)
498         .value_tuple().dimensions_value(0).value_int(), uid);
499 }
500 
ValidateUidDimension(const DimensionsValue & value,int atomId,int uid)501 void ValidateUidDimension(const DimensionsValue& value, int atomId, int uid) {
502     EXPECT_EQ(value.field(), atomId);
503     EXPECT_EQ(value.value_tuple().dimensions_value_size(), 1);
504     // Attribution field.
505     EXPECT_EQ(value.value_tuple().dimensions_value(0).field(), 1);
506     // Uid only.
507     EXPECT_EQ(value.value_tuple().dimensions_value(0)
508         .value_tuple().dimensions_value_size(), 1);
509     EXPECT_EQ(value.value_tuple().dimensions_value(0)
510         .value_tuple().dimensions_value(0).field(), 1);
511     EXPECT_EQ(value.value_tuple().dimensions_value(0)
512         .value_tuple().dimensions_value(0).value_int(), uid);
513 }
514 
ValidateUidDimension(const DimensionsValue & value,int node_idx,int atomId,int uid)515 void ValidateUidDimension(const DimensionsValue& value, int node_idx, int atomId, int uid) {
516     EXPECT_EQ(value.field(), atomId);
517     EXPECT_GT(value.value_tuple().dimensions_value_size(), node_idx);
518     // Attribution field.
519     EXPECT_EQ(value.value_tuple().dimensions_value(node_idx).field(), 1);
520     EXPECT_EQ(value.value_tuple().dimensions_value(node_idx)
521         .value_tuple().dimensions_value(0).field(), 1);
522     EXPECT_EQ(value.value_tuple().dimensions_value(node_idx)
523         .value_tuple().dimensions_value(0).value_int(), uid);
524 }
525 
ValidateAttributionUidAndTagDimension(const DimensionsValue & value,int node_idx,int atomId,int uid,const std::string & tag)526 void ValidateAttributionUidAndTagDimension(
527     const DimensionsValue& value, int node_idx, int atomId, int uid, const std::string& tag) {
528     EXPECT_EQ(value.field(), atomId);
529     EXPECT_GT(value.value_tuple().dimensions_value_size(), node_idx);
530     // Attribution field.
531     EXPECT_EQ(1, value.value_tuple().dimensions_value(node_idx).field());
532     // Uid only.
533     EXPECT_EQ(2, value.value_tuple().dimensions_value(node_idx)
534         .value_tuple().dimensions_value_size());
535     EXPECT_EQ(1, value.value_tuple().dimensions_value(node_idx)
536         .value_tuple().dimensions_value(0).field());
537     EXPECT_EQ(uid, value.value_tuple().dimensions_value(node_idx)
538         .value_tuple().dimensions_value(0).value_int());
539     EXPECT_EQ(2, value.value_tuple().dimensions_value(node_idx)
540         .value_tuple().dimensions_value(1).field());
541     EXPECT_EQ(tag, value.value_tuple().dimensions_value(node_idx)
542         .value_tuple().dimensions_value(1).value_str());
543 }
544 
ValidateAttributionUidAndTagDimension(const DimensionsValue & value,int atomId,int uid,const std::string & tag)545 void ValidateAttributionUidAndTagDimension(
546     const DimensionsValue& value, int atomId, int uid, const std::string& tag) {
547     EXPECT_EQ(value.field(), atomId);
548     EXPECT_EQ(1, value.value_tuple().dimensions_value_size());
549     // Attribution field.
550     EXPECT_EQ(1, value.value_tuple().dimensions_value(0).field());
551     // Uid only.
552     EXPECT_EQ(value.value_tuple().dimensions_value(0)
553         .value_tuple().dimensions_value_size(), 2);
554     EXPECT_EQ(value.value_tuple().dimensions_value(0)
555         .value_tuple().dimensions_value(0).field(), 1);
556     EXPECT_EQ(value.value_tuple().dimensions_value(0)
557         .value_tuple().dimensions_value(0).value_int(), uid);
558     EXPECT_EQ(value.value_tuple().dimensions_value(0)
559         .value_tuple().dimensions_value(1).field(), 2);
560     EXPECT_EQ(value.value_tuple().dimensions_value(0)
561         .value_tuple().dimensions_value(1).value_str(), tag);
562 }
563 
EqualsTo(const DimensionsValue & s1,const DimensionsValue & s2)564 bool EqualsTo(const DimensionsValue& s1, const DimensionsValue& s2) {
565     if (s1.field() != s2.field()) {
566         return false;
567     }
568     if (s1.value_case() != s2.value_case()) {
569         return false;
570     }
571     switch (s1.value_case()) {
572         case DimensionsValue::ValueCase::kValueStr:
573             return (s1.value_str() == s2.value_str());
574         case DimensionsValue::ValueCase::kValueInt:
575             return s1.value_int() == s2.value_int();
576         case DimensionsValue::ValueCase::kValueLong:
577             return s1.value_long() == s2.value_long();
578         case DimensionsValue::ValueCase::kValueBool:
579             return s1.value_bool() == s2.value_bool();
580         case DimensionsValue::ValueCase::kValueFloat:
581             return s1.value_float() == s2.value_float();
582         case DimensionsValue::ValueCase::kValueTuple: {
583             if (s1.value_tuple().dimensions_value_size() !=
584                 s2.value_tuple().dimensions_value_size()) {
585                 return false;
586             }
587             bool allMatched = true;
588             for (int i = 0; allMatched && i < s1.value_tuple().dimensions_value_size(); ++i) {
589                 allMatched &= EqualsTo(s1.value_tuple().dimensions_value(i),
590                                        s2.value_tuple().dimensions_value(i));
591             }
592             return allMatched;
593         }
594         case DimensionsValue::ValueCase::VALUE_NOT_SET:
595         default:
596             return true;
597     }
598 }
599 
LessThan(const DimensionsValue & s1,const DimensionsValue & s2)600 bool LessThan(const DimensionsValue& s1, const DimensionsValue& s2) {
601     if (s1.field() != s2.field()) {
602         return s1.field() < s2.field();
603     }
604     if (s1.value_case() != s2.value_case()) {
605         return s1.value_case() < s2.value_case();
606     }
607     switch (s1.value_case()) {
608         case DimensionsValue::ValueCase::kValueStr:
609             return s1.value_str() < s2.value_str();
610         case DimensionsValue::ValueCase::kValueInt:
611             return s1.value_int() < s2.value_int();
612         case DimensionsValue::ValueCase::kValueLong:
613             return s1.value_long() < s2.value_long();
614         case DimensionsValue::ValueCase::kValueBool:
615             return (int)s1.value_bool() < (int)s2.value_bool();
616         case DimensionsValue::ValueCase::kValueFloat:
617             return s1.value_float() < s2.value_float();
618         case DimensionsValue::ValueCase::kValueTuple: {
619             if (s1.value_tuple().dimensions_value_size() !=
620                 s2.value_tuple().dimensions_value_size()) {
621                 return s1.value_tuple().dimensions_value_size() <
622                        s2.value_tuple().dimensions_value_size();
623             }
624             for (int i = 0; i < s1.value_tuple().dimensions_value_size(); ++i) {
625                 if (EqualsTo(s1.value_tuple().dimensions_value(i),
626                              s2.value_tuple().dimensions_value(i))) {
627                     continue;
628                 } else {
629                     return LessThan(s1.value_tuple().dimensions_value(i),
630                                     s2.value_tuple().dimensions_value(i));
631                 }
632             }
633             return false;
634         }
635         case DimensionsValue::ValueCase::VALUE_NOT_SET:
636         default:
637             return false;
638     }
639 }
640 
LessThan(const DimensionsPair & s1,const DimensionsPair & s2)641 bool LessThan(const DimensionsPair& s1, const DimensionsPair& s2) {
642     if (LessThan(s1.dimInWhat, s2.dimInWhat)) {
643         return true;
644     } else if (LessThan(s2.dimInWhat, s1.dimInWhat)) {
645         return false;
646     }
647 
648     return LessThan(s1.dimInCondition, s2.dimInCondition);
649 }
650 
backfillStringInDimension(const std::map<uint64_t,string> & str_map,DimensionsValue * dimension)651 void backfillStringInDimension(const std::map<uint64_t, string>& str_map,
652                                DimensionsValue* dimension) {
653     if (dimension->has_value_str_hash()) {
654         auto it = str_map.find((uint64_t)(dimension->value_str_hash()));
655         if (it != str_map.end()) {
656             dimension->clear_value_str_hash();
657             dimension->set_value_str(it->second);
658         } else {
659             ALOGE("Can not find the string hash: %llu",
660                 (unsigned long long)dimension->value_str_hash());
661         }
662     } else if (dimension->has_value_tuple()) {
663         auto value_tuple = dimension->mutable_value_tuple();
664         for (int i = 0; i < value_tuple->dimensions_value_size(); ++i) {
665             backfillStringInDimension(str_map, value_tuple->mutable_dimensions_value(i));
666         }
667     }
668 }
669 
backfillStringInReport(ConfigMetricsReport * config_report)670 void backfillStringInReport(ConfigMetricsReport *config_report) {
671     std::map<uint64_t, string> str_map;
672     for (const auto& str : config_report->strings()) {
673         uint64_t hash = Hash64(str);
674         if (str_map.find(hash) != str_map.end()) {
675             ALOGE("String hash conflicts: %s %s", str.c_str(), str_map[hash].c_str());
676         }
677         str_map[hash] = str;
678     }
679     for (int i = 0; i < config_report->metrics_size(); ++i) {
680         auto metric_report = config_report->mutable_metrics(i);
681         if (metric_report->has_count_metrics()) {
682             backfillStringInDimension(str_map, metric_report->mutable_count_metrics());
683         } else if (metric_report->has_duration_metrics()) {
684             backfillStringInDimension(str_map, metric_report->mutable_duration_metrics());
685         } else if (metric_report->has_gauge_metrics()) {
686             backfillStringInDimension(str_map, metric_report->mutable_gauge_metrics());
687         } else if (metric_report->has_value_metrics()) {
688             backfillStringInDimension(str_map, metric_report->mutable_value_metrics());
689         }
690     }
691     // Backfill the package names.
692     for (int i = 0 ; i < config_report->uid_map().snapshots_size(); ++i) {
693         auto snapshot = config_report->mutable_uid_map()->mutable_snapshots(i);
694         for (int j = 0 ; j < snapshot->package_info_size(); ++j) {
695             auto package_info = snapshot->mutable_package_info(j);
696             if (package_info->has_name_hash()) {
697                 auto it = str_map.find((uint64_t)(package_info->name_hash()));
698                 if (it != str_map.end()) {
699                     package_info->clear_name_hash();
700                     package_info->set_name(it->second);
701                 } else {
702                     ALOGE("Can not find the string package name hash: %llu",
703                         (unsigned long long)package_info->name_hash());
704                 }
705 
706             }
707         }
708     }
709     // Backfill the app name in app changes.
710     for (int i = 0 ; i < config_report->uid_map().changes_size(); ++i) {
711         auto change = config_report->mutable_uid_map()->mutable_changes(i);
712         if (change->has_app_hash()) {
713             auto it = str_map.find((uint64_t)(change->app_hash()));
714             if (it != str_map.end()) {
715                 change->clear_app_hash();
716                 change->set_app(it->second);
717             } else {
718                 ALOGE("Can not find the string change app name hash: %llu",
719                     (unsigned long long)change->app_hash());
720             }
721         }
722     }
723 }
724 
backfillStringInReport(ConfigMetricsReportList * config_report_list)725 void backfillStringInReport(ConfigMetricsReportList *config_report_list) {
726     for (int i = 0; i < config_report_list->reports_size(); ++i) {
727         backfillStringInReport(config_report_list->mutable_reports(i));
728     }
729 }
730 
backfillDimensionPath(const DimensionsValue & path,const google::protobuf::RepeatedPtrField<DimensionsValue> & leafValues,int * leafIndex,DimensionsValue * dimension)731 bool backfillDimensionPath(const DimensionsValue& path,
732                            const google::protobuf::RepeatedPtrField<DimensionsValue>& leafValues,
733                            int* leafIndex,
734                            DimensionsValue* dimension) {
735     dimension->set_field(path.field());
736     if (path.has_value_tuple()) {
737         for (int i = 0; i < path.value_tuple().dimensions_value_size(); ++i) {
738             if (!backfillDimensionPath(
739                 path.value_tuple().dimensions_value(i), leafValues, leafIndex,
740                 dimension->mutable_value_tuple()->add_dimensions_value())) {
741                 return false;
742             }
743         }
744     } else {
745         if (*leafIndex < 0 || *leafIndex >= leafValues.size()) {
746             return false;
747         }
748         dimension->MergeFrom(leafValues.Get(*leafIndex));
749         (*leafIndex)++;
750     }
751     return true;
752 }
753 
backfillDimensionPath(const DimensionsValue & path,const google::protobuf::RepeatedPtrField<DimensionsValue> & leafValues,DimensionsValue * dimension)754 bool backfillDimensionPath(const DimensionsValue& path,
755                            const google::protobuf::RepeatedPtrField<DimensionsValue>& leafValues,
756                            DimensionsValue* dimension) {
757     int leafIndex = 0;
758     return backfillDimensionPath(path, leafValues, &leafIndex, dimension);
759 }
760 
backfillDimensionPath(ConfigMetricsReportList * config_report_list)761 void backfillDimensionPath(ConfigMetricsReportList *config_report_list) {
762     for (int i = 0; i < config_report_list->reports_size(); ++i) {
763         auto report = config_report_list->mutable_reports(i);
764         for (int j = 0; j < report->metrics_size(); ++j) {
765             auto metric_report = report->mutable_metrics(j);
766             if (metric_report->has_dimensions_path_in_what() ||
767                 metric_report->has_dimensions_path_in_condition()) {
768                 auto whatPath = metric_report->dimensions_path_in_what();
769                 auto conditionPath = metric_report->dimensions_path_in_condition();
770                 if (metric_report->has_count_metrics()) {
771                     backfillDimensionPath(whatPath, conditionPath,
772                                           metric_report->mutable_count_metrics());
773                 } else if (metric_report->has_duration_metrics()) {
774                     backfillDimensionPath(whatPath, conditionPath,
775                                           metric_report->mutable_duration_metrics());
776                 } else if (metric_report->has_gauge_metrics()) {
777                     backfillDimensionPath(whatPath, conditionPath,
778                                           metric_report->mutable_gauge_metrics());
779                 } else if (metric_report->has_value_metrics()) {
780                     backfillDimensionPath(whatPath, conditionPath,
781                                           metric_report->mutable_value_metrics());
782                 }
783                 metric_report->clear_dimensions_path_in_what();
784                 metric_report->clear_dimensions_path_in_condition();
785             }
786         }
787     }
788 }
789 
backfillStartEndTimestamp(StatsLogReport * report)790 void backfillStartEndTimestamp(StatsLogReport *report) {
791     const int64_t timeBaseNs = report->time_base_elapsed_nano_seconds();
792     const int64_t bucketSizeNs = report->bucket_size_nano_seconds();
793     if (report->has_count_metrics()) {
794         backfillStartEndTimestampForMetrics(
795             timeBaseNs, bucketSizeNs, report->mutable_count_metrics());
796     } else if (report->has_duration_metrics()) {
797         backfillStartEndTimestampForMetrics(
798             timeBaseNs, bucketSizeNs, report->mutable_duration_metrics());
799     } else if (report->has_gauge_metrics()) {
800         backfillStartEndTimestampForMetrics(
801             timeBaseNs, bucketSizeNs, report->mutable_gauge_metrics());
802         if (report->gauge_metrics().skipped_size() > 0) {
803             backfillStartEndTimestampForSkippedBuckets(
804                 timeBaseNs, report->mutable_gauge_metrics());
805         }
806     } else if (report->has_value_metrics()) {
807         backfillStartEndTimestampForMetrics(
808             timeBaseNs, bucketSizeNs, report->mutable_value_metrics());
809         if (report->value_metrics().skipped_size() > 0) {
810             backfillStartEndTimestampForSkippedBuckets(
811                 timeBaseNs, report->mutable_value_metrics());
812         }
813     }
814 }
815 
backfillStartEndTimestamp(ConfigMetricsReport * config_report)816 void backfillStartEndTimestamp(ConfigMetricsReport *config_report) {
817     for (int j = 0; j < config_report->metrics_size(); ++j) {
818         backfillStartEndTimestamp(config_report->mutable_metrics(j));
819     }
820 }
821 
backfillStartEndTimestamp(ConfigMetricsReportList * config_report_list)822 void backfillStartEndTimestamp(ConfigMetricsReportList *config_report_list) {
823     for (int i = 0; i < config_report_list->reports_size(); ++i) {
824         backfillStartEndTimestamp(config_report_list->mutable_reports(i));
825     }
826 }
827 
828 }  // namespace statsd
829 }  // namespace os
830 }  // namespace android
831