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 "metric_util.h"
16
17 #include "stats_event.h"
18
19 namespace android {
20 namespace os {
21 namespace statsd {
22
CreateSimpleAtomMatcher(const string & name,int atomId)23 AtomMatcher CreateSimpleAtomMatcher(const string& name, int atomId) {
24 AtomMatcher atom_matcher;
25 atom_matcher.set_id(StringToId(name));
26 auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
27 simple_atom_matcher->set_atom_id(atomId);
28 return atom_matcher;
29 }
30
CreateScheduledJobStateChangedAtomMatcher(const string & name,ScheduledJobStateChanged::State state)31 AtomMatcher CreateScheduledJobStateChangedAtomMatcher(const string& name,
32 ScheduledJobStateChanged::State state) {
33 AtomMatcher atom_matcher;
34 atom_matcher.set_id(StringToId(name));
35 auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
36 simple_atom_matcher->set_atom_id(android::util::SCHEDULED_JOB_STATE_CHANGED);
37 auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
38 field_value_matcher->set_field(3); // State field.
39 field_value_matcher->set_eq_int(state);
40 return atom_matcher;
41 }
42
CreateStartScheduledJobAtomMatcher()43 AtomMatcher CreateStartScheduledJobAtomMatcher() {
44 return CreateScheduledJobStateChangedAtomMatcher("ScheduledJobStart",
45 ScheduledJobStateChanged::STARTED);
46 }
47
CreateFinishScheduledJobAtomMatcher()48 AtomMatcher CreateFinishScheduledJobAtomMatcher() {
49 return CreateScheduledJobStateChangedAtomMatcher("ScheduledJobFinish",
50 ScheduledJobStateChanged::FINISHED);
51 }
52
CreateScreenBrightnessChangedAtomMatcher()53 AtomMatcher CreateScreenBrightnessChangedAtomMatcher() {
54 AtomMatcher atom_matcher;
55 atom_matcher.set_id(StringToId("ScreenBrightnessChanged"));
56 auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
57 simple_atom_matcher->set_atom_id(android::util::SCREEN_BRIGHTNESS_CHANGED);
58 return atom_matcher;
59 }
60
CreateUidProcessStateChangedAtomMatcher()61 AtomMatcher CreateUidProcessStateChangedAtomMatcher() {
62 AtomMatcher atom_matcher;
63 atom_matcher.set_id(StringToId("UidProcessStateChanged"));
64 auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
65 simple_atom_matcher->set_atom_id(android::util::UID_PROCESS_STATE_CHANGED);
66 return atom_matcher;
67 }
68
CreateWakelockStateChangedAtomMatcher(const string & name,WakelockStateChanged::State state)69 AtomMatcher CreateWakelockStateChangedAtomMatcher(const string& name,
70 WakelockStateChanged::State state) {
71 AtomMatcher atom_matcher;
72 atom_matcher.set_id(StringToId(name));
73 auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
74 simple_atom_matcher->set_atom_id(android::util::WAKELOCK_STATE_CHANGED);
75 auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
76 field_value_matcher->set_field(4); // State field.
77 field_value_matcher->set_eq_int(state);
78 return atom_matcher;
79 }
80
CreateAcquireWakelockAtomMatcher()81 AtomMatcher CreateAcquireWakelockAtomMatcher() {
82 return CreateWakelockStateChangedAtomMatcher("AcquireWakelock", WakelockStateChanged::ACQUIRE);
83 }
84
CreateReleaseWakelockAtomMatcher()85 AtomMatcher CreateReleaseWakelockAtomMatcher() {
86 return CreateWakelockStateChangedAtomMatcher("ReleaseWakelock", WakelockStateChanged::RELEASE);
87 }
88
CreateScreenStateChangedAtomMatcher(const string & name,android::view::DisplayStateEnum state)89 AtomMatcher CreateScreenStateChangedAtomMatcher(
90 const string& name, android::view::DisplayStateEnum state) {
91 AtomMatcher atom_matcher;
92 atom_matcher.set_id(StringToId(name));
93 auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
94 simple_atom_matcher->set_atom_id(android::util::SCREEN_STATE_CHANGED);
95 auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
96 field_value_matcher->set_field(1); // State field.
97 field_value_matcher->set_eq_int(state);
98 return atom_matcher;
99 }
100
CreateScreenTurnedOnAtomMatcher()101 AtomMatcher CreateScreenTurnedOnAtomMatcher() {
102 return CreateScreenStateChangedAtomMatcher("ScreenTurnedOn",
103 android::view::DisplayStateEnum::DISPLAY_STATE_ON);
104 }
105
CreateScreenTurnedOffAtomMatcher()106 AtomMatcher CreateScreenTurnedOffAtomMatcher() {
107 return CreateScreenStateChangedAtomMatcher("ScreenTurnedOff",
108 ::android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
109 }
110
CreateSyncStateChangedAtomMatcher(const string & name,SyncStateChanged::State state)111 AtomMatcher CreateSyncStateChangedAtomMatcher(
112 const string& name, SyncStateChanged::State state) {
113 AtomMatcher atom_matcher;
114 atom_matcher.set_id(StringToId(name));
115 auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
116 simple_atom_matcher->set_atom_id(android::util::SYNC_STATE_CHANGED);
117 auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
118 field_value_matcher->set_field(3); // State field.
119 field_value_matcher->set_eq_int(state);
120 return atom_matcher;
121 }
122
CreateSyncStartAtomMatcher()123 AtomMatcher CreateSyncStartAtomMatcher() {
124 return CreateSyncStateChangedAtomMatcher("SyncStart", SyncStateChanged::ON);
125 }
126
CreateSyncEndAtomMatcher()127 AtomMatcher CreateSyncEndAtomMatcher() {
128 return CreateSyncStateChangedAtomMatcher("SyncEnd", SyncStateChanged::OFF);
129 }
130
CreateActivityForegroundStateChangedAtomMatcher(const string & name,ActivityForegroundStateChanged::State state)131 AtomMatcher CreateActivityForegroundStateChangedAtomMatcher(
132 const string& name, ActivityForegroundStateChanged::State state) {
133 AtomMatcher atom_matcher;
134 atom_matcher.set_id(StringToId(name));
135 auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
136 simple_atom_matcher->set_atom_id(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED);
137 auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
138 field_value_matcher->set_field(4); // Activity field.
139 field_value_matcher->set_eq_int(state);
140 return atom_matcher;
141 }
142
CreateMoveToBackgroundAtomMatcher()143 AtomMatcher CreateMoveToBackgroundAtomMatcher() {
144 return CreateActivityForegroundStateChangedAtomMatcher(
145 "MoveToBackground", ActivityForegroundStateChanged::BACKGROUND);
146 }
147
CreateMoveToForegroundAtomMatcher()148 AtomMatcher CreateMoveToForegroundAtomMatcher() {
149 return CreateActivityForegroundStateChangedAtomMatcher(
150 "MoveToForeground", ActivityForegroundStateChanged::FOREGROUND);
151 }
152
CreateScheduledJobPredicate()153 Predicate CreateScheduledJobPredicate() {
154 Predicate predicate;
155 predicate.set_id(StringToId("ScheduledJobRunningPredicate"));
156 predicate.mutable_simple_predicate()->set_start(StringToId("ScheduledJobStart"));
157 predicate.mutable_simple_predicate()->set_stop(StringToId("ScheduledJobFinish"));
158 return predicate;
159 }
160
CreateBatterySaverModePredicate()161 Predicate CreateBatterySaverModePredicate() {
162 Predicate predicate;
163 predicate.set_id(StringToId("BatterySaverIsOn"));
164 predicate.mutable_simple_predicate()->set_start(StringToId("BatterySaverModeStart"));
165 predicate.mutable_simple_predicate()->set_stop(StringToId("BatterySaverModeStop"));
166 return predicate;
167 }
168
CreateScreenIsOnPredicate()169 Predicate CreateScreenIsOnPredicate() {
170 Predicate predicate;
171 predicate.set_id(StringToId("ScreenIsOn"));
172 predicate.mutable_simple_predicate()->set_start(StringToId("ScreenTurnedOn"));
173 predicate.mutable_simple_predicate()->set_stop(StringToId("ScreenTurnedOff"));
174 return predicate;
175 }
176
CreateScreenIsOffPredicate()177 Predicate CreateScreenIsOffPredicate() {
178 Predicate predicate;
179 predicate.set_id(1111123);
180 predicate.mutable_simple_predicate()->set_start(StringToId("ScreenTurnedOff"));
181 predicate.mutable_simple_predicate()->set_stop(StringToId("ScreenTurnedOn"));
182 return predicate;
183 }
184
CreateHoldingWakelockPredicate()185 Predicate CreateHoldingWakelockPredicate() {
186 Predicate predicate;
187 predicate.set_id(StringToId("HoldingWakelock"));
188 predicate.mutable_simple_predicate()->set_start(StringToId("AcquireWakelock"));
189 predicate.mutable_simple_predicate()->set_stop(StringToId("ReleaseWakelock"));
190 return predicate;
191 }
192
CreateIsSyncingPredicate()193 Predicate CreateIsSyncingPredicate() {
194 Predicate predicate;
195 predicate.set_id(33333333333333);
196 predicate.mutable_simple_predicate()->set_start(StringToId("SyncStart"));
197 predicate.mutable_simple_predicate()->set_stop(StringToId("SyncEnd"));
198 return predicate;
199 }
200
CreateIsInBackgroundPredicate()201 Predicate CreateIsInBackgroundPredicate() {
202 Predicate predicate;
203 predicate.set_id(StringToId("IsInBackground"));
204 predicate.mutable_simple_predicate()->set_start(StringToId("MoveToBackground"));
205 predicate.mutable_simple_predicate()->set_stop(StringToId("MoveToForeground"));
206 return predicate;
207 }
208
addPredicateToPredicateCombination(const Predicate & predicate,Predicate * combinationPredicate)209 void addPredicateToPredicateCombination(const Predicate& predicate,
210 Predicate* combinationPredicate) {
211 combinationPredicate->mutable_combination()->add_predicate(predicate.id());
212 }
213
CreateAttributionUidDimensions(const int atomId,const std::vector<Position> & positions)214 FieldMatcher CreateAttributionUidDimensions(const int atomId,
215 const std::vector<Position>& positions) {
216 FieldMatcher dimensions;
217 dimensions.set_field(atomId);
218 for (const auto position : positions) {
219 auto child = dimensions.add_child();
220 child->set_field(1);
221 child->set_position(position);
222 child->add_child()->set_field(1);
223 }
224 return dimensions;
225 }
226
CreateAttributionUidAndTagDimensions(const int atomId,const std::vector<Position> & positions)227 FieldMatcher CreateAttributionUidAndTagDimensions(const int atomId,
228 const std::vector<Position>& positions) {
229 FieldMatcher dimensions;
230 dimensions.set_field(atomId);
231 for (const auto position : positions) {
232 auto child = dimensions.add_child();
233 child->set_field(1);
234 child->set_position(position);
235 child->add_child()->set_field(1);
236 child->add_child()->set_field(2);
237 }
238 return dimensions;
239 }
240
CreateDimensions(const int atomId,const std::vector<int> & fields)241 FieldMatcher CreateDimensions(const int atomId, const std::vector<int>& fields) {
242 FieldMatcher dimensions;
243 dimensions.set_field(atomId);
244 for (const int field : fields) {
245 dimensions.add_child()->set_field(field);
246 }
247 return dimensions;
248 }
249
writeAttribution(AStatsEvent * statsEvent,const vector<int> & attributionUids,const vector<string> & attributionTags)250 void writeAttribution(AStatsEvent* statsEvent, const vector<int>& attributionUids,
251 const vector<string>& attributionTags) {
252 vector<const char*> cTags(attributionTags.size());
253 for (int i = 0; i < cTags.size(); i++) {
254 cTags[i] = attributionTags[i].c_str();
255 }
256
257 AStatsEvent_writeAttributionChain(statsEvent,
258 reinterpret_cast<const uint32_t*>(attributionUids.data()),
259 cTags.data(), attributionUids.size());
260 }
261
parseStatsEventToLogEvent(AStatsEvent * statsEvent,LogEvent * logEvent)262 void parseStatsEventToLogEvent(AStatsEvent* statsEvent, LogEvent* logEvent) {
263 AStatsEvent_build(statsEvent);
264
265 size_t size;
266 uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
267 logEvent->parseBuffer(buf, size);
268
269 AStatsEvent_release(statsEvent);
270 }
271
CreateScreenStateChangedEvent(uint64_t timestampNs,const android::view::DisplayStateEnum state)272 std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(
273 uint64_t timestampNs, const android::view::DisplayStateEnum state) {
274 AStatsEvent* statsEvent = AStatsEvent_obtain();
275 AStatsEvent_setAtomId(statsEvent, util::SCREEN_STATE_CHANGED);
276 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
277 AStatsEvent_writeInt32(statsEvent, state);
278
279 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
280 parseStatsEventToLogEvent(statsEvent, logEvent.get());
281 return logEvent;
282 }
283
CreateScheduledJobStateChangedEvent(const vector<int> & attributionUids,const vector<string> & attributionTags,const string & jobName,const ScheduledJobStateChanged::State state,uint64_t timestampNs)284 std::unique_ptr<LogEvent> CreateScheduledJobStateChangedEvent(
285 const vector<int>& attributionUids, const vector<string>& attributionTags,
286 const string& jobName, const ScheduledJobStateChanged::State state, uint64_t timestampNs) {
287 AStatsEvent* statsEvent = AStatsEvent_obtain();
288 AStatsEvent_setAtomId(statsEvent, util::SCHEDULED_JOB_STATE_CHANGED);
289 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
290
291 writeAttribution(statsEvent, attributionUids, attributionTags);
292 AStatsEvent_writeString(statsEvent, jobName.c_str());
293 AStatsEvent_writeInt32(statsEvent, state);
294
295 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
296 parseStatsEventToLogEvent(statsEvent, logEvent.get());
297 return logEvent;
298 }
299
CreateStartScheduledJobEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & jobName)300 std::unique_ptr<LogEvent> CreateStartScheduledJobEvent(uint64_t timestampNs,
301 const vector<int>& attributionUids,
302 const vector<string>& attributionTags,
303 const string& jobName) {
304 return CreateScheduledJobStateChangedEvent(attributionUids, attributionTags, jobName,
305 ScheduledJobStateChanged::STARTED, timestampNs);
306 }
307
308 // Create log event when scheduled job finishes.
CreateFinishScheduledJobEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & jobName)309 std::unique_ptr<LogEvent> CreateFinishScheduledJobEvent(uint64_t timestampNs,
310 const vector<int>& attributionUids,
311 const vector<string>& attributionTags,
312 const string& jobName) {
313 return CreateScheduledJobStateChangedEvent(attributionUids, attributionTags, jobName,
314 ScheduledJobStateChanged::FINISHED, timestampNs);
315 }
316
CreateSyncStateChangedEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & name,const SyncStateChanged::State state)317 std::unique_ptr<LogEvent> CreateSyncStateChangedEvent(uint64_t timestampNs,
318 const vector<int>& attributionUids,
319 const vector<string>& attributionTags,
320 const string& name,
321 const SyncStateChanged::State state) {
322 AStatsEvent* statsEvent = AStatsEvent_obtain();
323 AStatsEvent_setAtomId(statsEvent, util::SYNC_STATE_CHANGED);
324 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
325
326 writeAttribution(statsEvent, attributionUids, attributionTags);
327 AStatsEvent_writeString(statsEvent, name.c_str());
328 AStatsEvent_writeInt32(statsEvent, state);
329
330 std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
331 parseStatsEventToLogEvent(statsEvent, logEvent.get());
332 return logEvent;
333 }
334
CreateSyncStartEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & name)335 std::unique_ptr<LogEvent> CreateSyncStartEvent(uint64_t timestampNs,
336 const vector<int>& attributionUids,
337 const vector<string>& attributionTags,
338 const string& name) {
339 return CreateSyncStateChangedEvent(timestampNs, attributionUids, attributionTags, name,
340 SyncStateChanged::ON);
341 }
342
CreateSyncEndEvent(uint64_t timestampNs,const vector<int> & attributionUids,const vector<string> & attributionTags,const string & name)343 std::unique_ptr<LogEvent> CreateSyncEndEvent(uint64_t timestampNs,
344 const vector<int>& attributionUids,
345 const vector<string>& attributionTags,
346 const string& name) {
347 return CreateSyncStateChangedEvent(timestampNs, attributionUids, attributionTags, name,
348 SyncStateChanged::OFF);
349 }
350
CreateStatsLogProcessor(const long timeBaseSec,const StatsdConfig & config,const ConfigKey & key)351 sp<StatsLogProcessor> CreateStatsLogProcessor(const long timeBaseSec, const StatsdConfig& config,
352 const ConfigKey& key) {
353 sp<UidMap> uidMap = new UidMap();
354 sp<StatsPullerManager> pullerManager = new StatsPullerManager();
355 sp<AlarmMonitor> anomalyAlarmMonitor;
356 sp<AlarmMonitor> periodicAlarmMonitor;
357 sp<StatsLogProcessor> processor =
358 new StatsLogProcessor(uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
359 timeBaseSec * NS_PER_SEC, [](const ConfigKey&) { return true; },
360 [](const int&, const vector<int64_t>&) { return true; });
361 processor->OnConfigUpdated(timeBaseSec * NS_PER_SEC, key, config);
362 return processor;
363 }
364
sortLogEventsByTimestamp(std::vector<std::unique_ptr<LogEvent>> * events)365 void sortLogEventsByTimestamp(std::vector<std::unique_ptr<LogEvent>> *events) {
366 std::sort(events->begin(), events->end(),
367 [](const std::unique_ptr<LogEvent>& a, const std::unique_ptr<LogEvent>& b) {
368 return a->GetElapsedTimestampNs() < b->GetElapsedTimestampNs();
369 });
370 }
371
StringToId(const string & str)372 int64_t StringToId(const string& str) {
373 return static_cast<int64_t>(std::hash<std::string>()(str));
374 }
375
376
377 } // namespace statsd
378 } // namespace os
379 } // namespace android
380