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<AlarmMonitor> anomalyAlarmMonitor =
456 new AlarmMonitor(1, [](const sp<IStatsCompanionService>&, int64_t){},
457 [](const sp<IStatsCompanionService>&){});
458 sp<AlarmMonitor> periodicAlarmMonitor =
459 new AlarmMonitor(1, [](const sp<IStatsCompanionService>&, int64_t){},
460 [](const sp<IStatsCompanionService>&){});
461 sp<StatsLogProcessor> processor = new StatsLogProcessor(
462 uidMap, anomalyAlarmMonitor, periodicAlarmMonitor, timeBaseNs, [](const ConfigKey&){return true;});
463 processor->OnConfigUpdated(currentTimeNs, key, config);
464 return processor;
465 }
466
CreateAttribution(const int & uid,const string & tag)467 AttributionNodeInternal CreateAttribution(const int& uid, const string& tag) {
468 AttributionNodeInternal attribution;
469 attribution.set_uid(uid);
470 attribution.set_tag(tag);
471 return attribution;
472 }
473
sortLogEventsByTimestamp(std::vector<std::unique_ptr<LogEvent>> * events)474 void sortLogEventsByTimestamp(std::vector<std::unique_ptr<LogEvent>> *events) {
475 std::sort(events->begin(), events->end(),
476 [](const std::unique_ptr<LogEvent>& a, const std::unique_ptr<LogEvent>& b) {
477 return a->GetElapsedTimestampNs() < b->GetElapsedTimestampNs();
478 });
479 }
480
StringToId(const string & str)481 int64_t StringToId(const string& str) {
482 return static_cast<int64_t>(std::hash<std::string>()(str));
483 }
484
ValidateAttributionUidDimension(const DimensionsValue & value,int atomId,int uid)485 void ValidateAttributionUidDimension(const DimensionsValue& value, int atomId, int uid) {
486 EXPECT_EQ(value.field(), atomId);
487 // Attribution field.
488 EXPECT_EQ(value.value_tuple().dimensions_value(0).field(), 1);
489 // Uid only.
490 EXPECT_EQ(value.value_tuple().dimensions_value(0)
491 .value_tuple().dimensions_value_size(), 1);
492 EXPECT_EQ(value.value_tuple().dimensions_value(0)
493 .value_tuple().dimensions_value(0).field(), 1);
494 EXPECT_EQ(value.value_tuple().dimensions_value(0)
495 .value_tuple().dimensions_value(0).value_int(), uid);
496 }
497
ValidateUidDimension(const DimensionsValue & value,int atomId,int uid)498 void ValidateUidDimension(const DimensionsValue& value, int atomId, int uid) {
499 EXPECT_EQ(value.field(), atomId);
500 EXPECT_EQ(value.value_tuple().dimensions_value_size(), 1);
501 // Attribution field.
502 EXPECT_EQ(value.value_tuple().dimensions_value(0).field(), 1);
503 // Uid only.
504 EXPECT_EQ(value.value_tuple().dimensions_value(0)
505 .value_tuple().dimensions_value_size(), 1);
506 EXPECT_EQ(value.value_tuple().dimensions_value(0)
507 .value_tuple().dimensions_value(0).field(), 1);
508 EXPECT_EQ(value.value_tuple().dimensions_value(0)
509 .value_tuple().dimensions_value(0).value_int(), uid);
510 }
511
ValidateUidDimension(const DimensionsValue & value,int node_idx,int atomId,int uid)512 void ValidateUidDimension(const DimensionsValue& value, int node_idx, int atomId, int uid) {
513 EXPECT_EQ(value.field(), atomId);
514 EXPECT_GT(value.value_tuple().dimensions_value_size(), node_idx);
515 // Attribution field.
516 EXPECT_EQ(value.value_tuple().dimensions_value(node_idx).field(), 1);
517 EXPECT_EQ(value.value_tuple().dimensions_value(node_idx)
518 .value_tuple().dimensions_value(0).field(), 1);
519 EXPECT_EQ(value.value_tuple().dimensions_value(node_idx)
520 .value_tuple().dimensions_value(0).value_int(), uid);
521 }
522
ValidateAttributionUidAndTagDimension(const DimensionsValue & value,int node_idx,int atomId,int uid,const std::string & tag)523 void ValidateAttributionUidAndTagDimension(
524 const DimensionsValue& value, int node_idx, int atomId, int uid, const std::string& tag) {
525 EXPECT_EQ(value.field(), atomId);
526 EXPECT_GT(value.value_tuple().dimensions_value_size(), node_idx);
527 // Attribution field.
528 EXPECT_EQ(1, value.value_tuple().dimensions_value(node_idx).field());
529 // Uid only.
530 EXPECT_EQ(2, value.value_tuple().dimensions_value(node_idx)
531 .value_tuple().dimensions_value_size());
532 EXPECT_EQ(1, value.value_tuple().dimensions_value(node_idx)
533 .value_tuple().dimensions_value(0).field());
534 EXPECT_EQ(uid, value.value_tuple().dimensions_value(node_idx)
535 .value_tuple().dimensions_value(0).value_int());
536 EXPECT_EQ(2, value.value_tuple().dimensions_value(node_idx)
537 .value_tuple().dimensions_value(1).field());
538 EXPECT_EQ(tag, value.value_tuple().dimensions_value(node_idx)
539 .value_tuple().dimensions_value(1).value_str());
540 }
541
ValidateAttributionUidAndTagDimension(const DimensionsValue & value,int atomId,int uid,const std::string & tag)542 void ValidateAttributionUidAndTagDimension(
543 const DimensionsValue& value, int atomId, int uid, const std::string& tag) {
544 EXPECT_EQ(value.field(), atomId);
545 EXPECT_EQ(1, value.value_tuple().dimensions_value_size());
546 // Attribution field.
547 EXPECT_EQ(1, value.value_tuple().dimensions_value(0).field());
548 // Uid only.
549 EXPECT_EQ(value.value_tuple().dimensions_value(0)
550 .value_tuple().dimensions_value_size(), 2);
551 EXPECT_EQ(value.value_tuple().dimensions_value(0)
552 .value_tuple().dimensions_value(0).field(), 1);
553 EXPECT_EQ(value.value_tuple().dimensions_value(0)
554 .value_tuple().dimensions_value(0).value_int(), uid);
555 EXPECT_EQ(value.value_tuple().dimensions_value(0)
556 .value_tuple().dimensions_value(1).field(), 2);
557 EXPECT_EQ(value.value_tuple().dimensions_value(0)
558 .value_tuple().dimensions_value(1).value_str(), tag);
559 }
560
EqualsTo(const DimensionsValue & s1,const DimensionsValue & s2)561 bool EqualsTo(const DimensionsValue& s1, const DimensionsValue& s2) {
562 if (s1.field() != s2.field()) {
563 return false;
564 }
565 if (s1.value_case() != s2.value_case()) {
566 return false;
567 }
568 switch (s1.value_case()) {
569 case DimensionsValue::ValueCase::kValueStr:
570 return (s1.value_str() == s2.value_str());
571 case DimensionsValue::ValueCase::kValueInt:
572 return s1.value_int() == s2.value_int();
573 case DimensionsValue::ValueCase::kValueLong:
574 return s1.value_long() == s2.value_long();
575 case DimensionsValue::ValueCase::kValueBool:
576 return s1.value_bool() == s2.value_bool();
577 case DimensionsValue::ValueCase::kValueFloat:
578 return s1.value_float() == s2.value_float();
579 case DimensionsValue::ValueCase::kValueTuple: {
580 if (s1.value_tuple().dimensions_value_size() !=
581 s2.value_tuple().dimensions_value_size()) {
582 return false;
583 }
584 bool allMatched = true;
585 for (int i = 0; allMatched && i < s1.value_tuple().dimensions_value_size(); ++i) {
586 allMatched &= EqualsTo(s1.value_tuple().dimensions_value(i),
587 s2.value_tuple().dimensions_value(i));
588 }
589 return allMatched;
590 }
591 case DimensionsValue::ValueCase::VALUE_NOT_SET:
592 default:
593 return true;
594 }
595 }
596
LessThan(const DimensionsValue & s1,const DimensionsValue & s2)597 bool LessThan(const DimensionsValue& s1, const DimensionsValue& s2) {
598 if (s1.field() != s2.field()) {
599 return s1.field() < s2.field();
600 }
601 if (s1.value_case() != s2.value_case()) {
602 return s1.value_case() < s2.value_case();
603 }
604 switch (s1.value_case()) {
605 case DimensionsValue::ValueCase::kValueStr:
606 return s1.value_str() < s2.value_str();
607 case DimensionsValue::ValueCase::kValueInt:
608 return s1.value_int() < s2.value_int();
609 case DimensionsValue::ValueCase::kValueLong:
610 return s1.value_long() < s2.value_long();
611 case DimensionsValue::ValueCase::kValueBool:
612 return (int)s1.value_bool() < (int)s2.value_bool();
613 case DimensionsValue::ValueCase::kValueFloat:
614 return s1.value_float() < s2.value_float();
615 case DimensionsValue::ValueCase::kValueTuple: {
616 if (s1.value_tuple().dimensions_value_size() !=
617 s2.value_tuple().dimensions_value_size()) {
618 return s1.value_tuple().dimensions_value_size() <
619 s2.value_tuple().dimensions_value_size();
620 }
621 for (int i = 0; i < s1.value_tuple().dimensions_value_size(); ++i) {
622 if (EqualsTo(s1.value_tuple().dimensions_value(i),
623 s2.value_tuple().dimensions_value(i))) {
624 continue;
625 } else {
626 return LessThan(s1.value_tuple().dimensions_value(i),
627 s2.value_tuple().dimensions_value(i));
628 }
629 }
630 return false;
631 }
632 case DimensionsValue::ValueCase::VALUE_NOT_SET:
633 default:
634 return false;
635 }
636 }
637
LessThan(const DimensionsPair & s1,const DimensionsPair & s2)638 bool LessThan(const DimensionsPair& s1, const DimensionsPair& s2) {
639 if (LessThan(s1.dimInWhat, s2.dimInWhat)) {
640 return true;
641 } else if (LessThan(s2.dimInWhat, s1.dimInWhat)) {
642 return false;
643 }
644
645 return LessThan(s1.dimInCondition, s2.dimInCondition);
646 }
647
backfillStringInDimension(const std::map<uint64_t,string> & str_map,DimensionsValue * dimension)648 void backfillStringInDimension(const std::map<uint64_t, string>& str_map,
649 DimensionsValue* dimension) {
650 if (dimension->has_value_str_hash()) {
651 auto it = str_map.find((uint64_t)(dimension->value_str_hash()));
652 if (it != str_map.end()) {
653 dimension->clear_value_str_hash();
654 dimension->set_value_str(it->second);
655 } else {
656 ALOGE("Can not find the string hash: %llu",
657 (unsigned long long)dimension->value_str_hash());
658 }
659 } else if (dimension->has_value_tuple()) {
660 auto value_tuple = dimension->mutable_value_tuple();
661 for (int i = 0; i < value_tuple->dimensions_value_size(); ++i) {
662 backfillStringInDimension(str_map, value_tuple->mutable_dimensions_value(i));
663 }
664 }
665 }
666
backfillStringInReport(ConfigMetricsReport * config_report)667 void backfillStringInReport(ConfigMetricsReport *config_report) {
668 std::map<uint64_t, string> str_map;
669 for (const auto& str : config_report->strings()) {
670 uint64_t hash = Hash64(str);
671 if (str_map.find(hash) != str_map.end()) {
672 ALOGE("String hash conflicts: %s %s", str.c_str(), str_map[hash].c_str());
673 }
674 str_map[hash] = str;
675 }
676 for (int i = 0; i < config_report->metrics_size(); ++i) {
677 auto metric_report = config_report->mutable_metrics(i);
678 if (metric_report->has_count_metrics()) {
679 backfillStringInDimension(str_map, metric_report->mutable_count_metrics());
680 } else if (metric_report->has_duration_metrics()) {
681 backfillStringInDimension(str_map, metric_report->mutable_duration_metrics());
682 } else if (metric_report->has_gauge_metrics()) {
683 backfillStringInDimension(str_map, metric_report->mutable_gauge_metrics());
684 } else if (metric_report->has_value_metrics()) {
685 backfillStringInDimension(str_map, metric_report->mutable_value_metrics());
686 }
687 }
688 // Backfill the package names.
689 for (int i = 0 ; i < config_report->uid_map().snapshots_size(); ++i) {
690 auto snapshot = config_report->mutable_uid_map()->mutable_snapshots(i);
691 for (int j = 0 ; j < snapshot->package_info_size(); ++j) {
692 auto package_info = snapshot->mutable_package_info(j);
693 if (package_info->has_name_hash()) {
694 auto it = str_map.find((uint64_t)(package_info->name_hash()));
695 if (it != str_map.end()) {
696 package_info->clear_name_hash();
697 package_info->set_name(it->second);
698 } else {
699 ALOGE("Can not find the string package name hash: %llu",
700 (unsigned long long)package_info->name_hash());
701 }
702
703 }
704 }
705 }
706 // Backfill the app name in app changes.
707 for (int i = 0 ; i < config_report->uid_map().changes_size(); ++i) {
708 auto change = config_report->mutable_uid_map()->mutable_changes(i);
709 if (change->has_app_hash()) {
710 auto it = str_map.find((uint64_t)(change->app_hash()));
711 if (it != str_map.end()) {
712 change->clear_app_hash();
713 change->set_app(it->second);
714 } else {
715 ALOGE("Can not find the string change app name hash: %llu",
716 (unsigned long long)change->app_hash());
717 }
718 }
719 }
720 }
721
backfillStringInReport(ConfigMetricsReportList * config_report_list)722 void backfillStringInReport(ConfigMetricsReportList *config_report_list) {
723 for (int i = 0; i < config_report_list->reports_size(); ++i) {
724 backfillStringInReport(config_report_list->mutable_reports(i));
725 }
726 }
727
backfillDimensionPath(const DimensionsValue & path,const google::protobuf::RepeatedPtrField<DimensionsValue> & leafValues,int * leafIndex,DimensionsValue * dimension)728 bool backfillDimensionPath(const DimensionsValue& path,
729 const google::protobuf::RepeatedPtrField<DimensionsValue>& leafValues,
730 int* leafIndex,
731 DimensionsValue* dimension) {
732 dimension->set_field(path.field());
733 if (path.has_value_tuple()) {
734 for (int i = 0; i < path.value_tuple().dimensions_value_size(); ++i) {
735 if (!backfillDimensionPath(
736 path.value_tuple().dimensions_value(i), leafValues, leafIndex,
737 dimension->mutable_value_tuple()->add_dimensions_value())) {
738 return false;
739 }
740 }
741 } else {
742 if (*leafIndex < 0 || *leafIndex >= leafValues.size()) {
743 return false;
744 }
745 dimension->MergeFrom(leafValues.Get(*leafIndex));
746 (*leafIndex)++;
747 }
748 return true;
749 }
750
backfillDimensionPath(const DimensionsValue & path,const google::protobuf::RepeatedPtrField<DimensionsValue> & leafValues,DimensionsValue * dimension)751 bool backfillDimensionPath(const DimensionsValue& path,
752 const google::protobuf::RepeatedPtrField<DimensionsValue>& leafValues,
753 DimensionsValue* dimension) {
754 int leafIndex = 0;
755 return backfillDimensionPath(path, leafValues, &leafIndex, dimension);
756 }
757
backfillDimensionPath(ConfigMetricsReportList * config_report_list)758 void backfillDimensionPath(ConfigMetricsReportList *config_report_list) {
759 for (int i = 0; i < config_report_list->reports_size(); ++i) {
760 auto report = config_report_list->mutable_reports(i);
761 for (int j = 0; j < report->metrics_size(); ++j) {
762 auto metric_report = report->mutable_metrics(j);
763 if (metric_report->has_dimensions_path_in_what() ||
764 metric_report->has_dimensions_path_in_condition()) {
765 auto whatPath = metric_report->dimensions_path_in_what();
766 auto conditionPath = metric_report->dimensions_path_in_condition();
767 if (metric_report->has_count_metrics()) {
768 backfillDimensionPath(whatPath, conditionPath,
769 metric_report->mutable_count_metrics());
770 } else if (metric_report->has_duration_metrics()) {
771 backfillDimensionPath(whatPath, conditionPath,
772 metric_report->mutable_duration_metrics());
773 } else if (metric_report->has_gauge_metrics()) {
774 backfillDimensionPath(whatPath, conditionPath,
775 metric_report->mutable_gauge_metrics());
776 } else if (metric_report->has_value_metrics()) {
777 backfillDimensionPath(whatPath, conditionPath,
778 metric_report->mutable_value_metrics());
779 }
780 metric_report->clear_dimensions_path_in_what();
781 metric_report->clear_dimensions_path_in_condition();
782 }
783 }
784 }
785 }
786
backfillStartEndTimestamp(StatsLogReport * report)787 void backfillStartEndTimestamp(StatsLogReport *report) {
788 const int64_t timeBaseNs = report->time_base_elapsed_nano_seconds();
789 const int64_t bucketSizeNs = report->bucket_size_nano_seconds();
790 if (report->has_count_metrics()) {
791 backfillStartEndTimestampForMetrics(
792 timeBaseNs, bucketSizeNs, report->mutable_count_metrics());
793 } else if (report->has_duration_metrics()) {
794 backfillStartEndTimestampForMetrics(
795 timeBaseNs, bucketSizeNs, report->mutable_duration_metrics());
796 } else if (report->has_gauge_metrics()) {
797 backfillStartEndTimestampForMetrics(
798 timeBaseNs, bucketSizeNs, report->mutable_gauge_metrics());
799 if (report->gauge_metrics().skipped_size() > 0) {
800 backfillStartEndTimestampForSkippedBuckets(
801 timeBaseNs, report->mutable_gauge_metrics());
802 }
803 } else if (report->has_value_metrics()) {
804 backfillStartEndTimestampForMetrics(
805 timeBaseNs, bucketSizeNs, report->mutable_value_metrics());
806 if (report->value_metrics().skipped_size() > 0) {
807 backfillStartEndTimestampForSkippedBuckets(
808 timeBaseNs, report->mutable_value_metrics());
809 }
810 }
811 }
812
backfillStartEndTimestamp(ConfigMetricsReport * config_report)813 void backfillStartEndTimestamp(ConfigMetricsReport *config_report) {
814 for (int j = 0; j < config_report->metrics_size(); ++j) {
815 backfillStartEndTimestamp(config_report->mutable_metrics(j));
816 }
817 }
818
backfillStartEndTimestamp(ConfigMetricsReportList * config_report_list)819 void backfillStartEndTimestamp(ConfigMetricsReportList *config_report_list) {
820 for (int i = 0; i < config_report_list->reports_size(); ++i) {
821 backfillStartEndTimestamp(config_report_list->mutable_reports(i));
822 }
823 }
824
825 } // namespace statsd
826 } // namespace os
827 } // namespace android