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