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 #pragma once
16
17 #include <gtest/gtest.h>
18 #include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
19 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
20 #include "src/StatsLogProcessor.h"
21 #include "src/logd/LogEvent.h"
22 #include "src/hash.h"
23 #include "src/stats_log_util.h"
24 #include "statslog.h"
25
26 namespace android {
27 namespace os {
28 namespace statsd {
29
30 using google::protobuf::RepeatedPtrField;
31
32 // Create AtomMatcher proto to simply match a specific atom type.
33 AtomMatcher CreateSimpleAtomMatcher(const string& name, int atomId);
34
35 // Create AtomMatcher proto for temperature atom.
36 AtomMatcher CreateTemperatureAtomMatcher();
37
38 // Create AtomMatcher proto for scheduled job state changed.
39 AtomMatcher CreateScheduledJobStateChangedAtomMatcher();
40
41 // Create AtomMatcher proto for starting a scheduled job.
42 AtomMatcher CreateStartScheduledJobAtomMatcher();
43
44 // Create AtomMatcher proto for a scheduled job is done.
45 AtomMatcher CreateFinishScheduledJobAtomMatcher();
46
47 // Create AtomMatcher proto for screen brightness state changed.
48 AtomMatcher CreateScreenBrightnessChangedAtomMatcher();
49
50 // Create AtomMatcher proto for starting battery save mode.
51 AtomMatcher CreateBatterySaverModeStartAtomMatcher();
52
53 // Create AtomMatcher proto for stopping battery save mode.
54 AtomMatcher CreateBatterySaverModeStopAtomMatcher();
55
56 // Create AtomMatcher proto for process state changed.
57 AtomMatcher CreateUidProcessStateChangedAtomMatcher();
58
59 // Create AtomMatcher proto for acquiring wakelock.
60 AtomMatcher CreateAcquireWakelockAtomMatcher();
61
62 // Create AtomMatcher proto for releasing wakelock.
63 AtomMatcher CreateReleaseWakelockAtomMatcher() ;
64
65 // Create AtomMatcher proto for screen turned on.
66 AtomMatcher CreateScreenTurnedOnAtomMatcher();
67
68 // Create AtomMatcher proto for screen turned off.
69 AtomMatcher CreateScreenTurnedOffAtomMatcher();
70
71 // Create AtomMatcher proto for app sync turned on.
72 AtomMatcher CreateSyncStartAtomMatcher();
73
74 // Create AtomMatcher proto for app sync turned off.
75 AtomMatcher CreateSyncEndAtomMatcher();
76
77 // Create AtomMatcher proto for app sync moves to background.
78 AtomMatcher CreateMoveToBackgroundAtomMatcher();
79
80 // Create AtomMatcher proto for app sync moves to foreground.
81 AtomMatcher CreateMoveToForegroundAtomMatcher();
82
83 // Create AtomMatcher proto for process crashes
84 AtomMatcher CreateProcessCrashAtomMatcher() ;
85
86 // Create Predicate proto for screen is on.
87 Predicate CreateScreenIsOnPredicate();
88
89 // Create Predicate proto for screen is off.
90 Predicate CreateScreenIsOffPredicate();
91
92 // Create Predicate proto for a running scheduled job.
93 Predicate CreateScheduledJobPredicate();
94
95 // Create Predicate proto for battery saver mode.
96 Predicate CreateBatterySaverModePredicate();
97
98 // Create Predicate proto for holding wakelock.
99 Predicate CreateHoldingWakelockPredicate();
100
101 // Create a Predicate proto for app syncing.
102 Predicate CreateIsSyncingPredicate();
103
104 // Create a Predicate proto for app is in background.
105 Predicate CreateIsInBackgroundPredicate();
106
107 // Add a predicate to the predicate combination.
108 void addPredicateToPredicateCombination(const Predicate& predicate, Predicate* combination);
109
110 // Create dimensions from primitive fields.
111 FieldMatcher CreateDimensions(const int atomId, const std::vector<int>& fields);
112
113 // Create dimensions by attribution uid and tag.
114 FieldMatcher CreateAttributionUidAndTagDimensions(const int atomId,
115 const std::vector<Position>& positions);
116
117 // Create dimensions by attribution uid only.
118 FieldMatcher CreateAttributionUidDimensions(const int atomId,
119 const std::vector<Position>& positions);
120
121 // Create log event for screen state changed.
122 std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(
123 const android::view::DisplayStateEnum state, uint64_t timestampNs);
124
125 // Create log event for screen brightness state changed.
126 std::unique_ptr<LogEvent> CreateScreenBrightnessChangedEvent(
127 int level, uint64_t timestampNs);
128
129 // Create log event when scheduled job starts.
130 std::unique_ptr<LogEvent> CreateStartScheduledJobEvent(
131 const std::vector<AttributionNodeInternal>& attributions,
132 const string& name, uint64_t timestampNs);
133
134 // Create log event when scheduled job finishes.
135 std::unique_ptr<LogEvent> CreateFinishScheduledJobEvent(
136 const std::vector<AttributionNodeInternal>& attributions,
137 const string& name, uint64_t timestampNs);
138
139 // Create log event when battery saver starts.
140 std::unique_ptr<LogEvent> CreateBatterySaverOnEvent(uint64_t timestampNs);
141 // Create log event when battery saver stops.
142 std::unique_ptr<LogEvent> CreateBatterySaverOffEvent(uint64_t timestampNs);
143
144 // Create log event for app moving to background.
145 std::unique_ptr<LogEvent> CreateMoveToBackgroundEvent(const int uid, uint64_t timestampNs);
146
147 // Create log event for app moving to foreground.
148 std::unique_ptr<LogEvent> CreateMoveToForegroundEvent(const int uid, uint64_t timestampNs);
149
150 // Create log event when the app sync starts.
151 std::unique_ptr<LogEvent> CreateSyncStartEvent(
152 const std::vector<AttributionNodeInternal>& attributions, const string& name,
153 uint64_t timestampNs);
154
155 // Create log event when the app sync ends.
156 std::unique_ptr<LogEvent> CreateSyncEndEvent(
157 const std::vector<AttributionNodeInternal>& attributions, const string& name,
158 uint64_t timestampNs);
159
160 // Create log event when the app sync ends.
161 std::unique_ptr<LogEvent> CreateAppCrashEvent(
162 const int uid, uint64_t timestampNs);
163
164 // Create log event for acquiring wakelock.
165 std::unique_ptr<LogEvent> CreateAcquireWakelockEvent(
166 const std::vector<AttributionNodeInternal>& attributions, const string& wakelockName,
167 uint64_t timestampNs);
168
169 // Create log event for releasing wakelock.
170 std::unique_ptr<LogEvent> CreateReleaseWakelockEvent(
171 const std::vector<AttributionNodeInternal>& attributions, const string& wakelockName,
172 uint64_t timestampNs);
173
174 // Create log event for releasing wakelock.
175 std::unique_ptr<LogEvent> CreateIsolatedUidChangedEvent(
176 int isolatedUid, int hostUid, bool is_create, uint64_t timestampNs);
177
178 // Helper function to create an AttributionNodeInternal proto.
179 AttributionNodeInternal CreateAttribution(const int& uid, const string& tag);
180
181 // Create a statsd log event processor upon the start time in seconds, config and key.
182 sp<StatsLogProcessor> CreateStatsLogProcessor(const int64_t timeBaseNs,
183 const int64_t currentTimeNs,
184 const StatsdConfig& config, const ConfigKey& key);
185
186 // Util function to sort the log events by timestamp.
187 void sortLogEventsByTimestamp(std::vector<std::unique_ptr<LogEvent>> *events);
188
189 int64_t StringToId(const string& str);
190
191 void ValidateUidDimension(const DimensionsValue& value, int node_idx, int atomId, int uid);
192 void ValidateAttributionUidDimension(const DimensionsValue& value, int atomId, int uid);
193 void ValidateAttributionUidAndTagDimension(
194 const DimensionsValue& value, int atomId, int uid, const std::string& tag);
195 void ValidateAttributionUidAndTagDimension(
196 const DimensionsValue& value, int node_idx, int atomId, int uid, const std::string& tag);
197
198 struct DimensionsPair {
DimensionsPairDimensionsPair199 DimensionsPair(DimensionsValue m1, DimensionsValue m2) : dimInWhat(m1), dimInCondition(m2){};
200
201 DimensionsValue dimInWhat;
202 DimensionsValue dimInCondition;
203 };
204
205 bool LessThan(const DimensionsValue& s1, const DimensionsValue& s2);
206 bool LessThan(const DimensionsPair& s1, const DimensionsPair& s2);
207
208
209 void backfillStartEndTimestamp(ConfigMetricsReport *config_report);
210 void backfillStartEndTimestamp(ConfigMetricsReportList *config_report_list);
211
212 void backfillStringInReport(ConfigMetricsReportList *config_report_list);
213 void backfillStringInDimension(const std::map<uint64_t, string>& str_map,
214 DimensionsValue* dimension);
215
216 template <typename T>
backfillStringInDimension(const std::map<uint64_t,string> & str_map,T * metrics)217 void backfillStringInDimension(const std::map<uint64_t, string>& str_map,
218 T* metrics) {
219 for (int i = 0; i < metrics->data_size(); ++i) {
220 auto data = metrics->mutable_data(i);
221 if (data->has_dimensions_in_what()) {
222 backfillStringInDimension(str_map, data->mutable_dimensions_in_what());
223 }
224 if (data->has_dimensions_in_condition()) {
225 backfillStringInDimension(str_map, data->mutable_dimensions_in_condition());
226 }
227 }
228 }
229
230 void backfillDimensionPath(ConfigMetricsReportList* config_report_list);
231
232 bool backfillDimensionPath(const DimensionsValue& path,
233 const google::protobuf::RepeatedPtrField<DimensionsValue>& leafValues,
234 DimensionsValue* dimension);
235
236 template <typename T>
backfillDimensionPath(const DimensionsValue & whatPath,const DimensionsValue & conditionPath,T * metricData)237 void backfillDimensionPath(const DimensionsValue& whatPath,
238 const DimensionsValue& conditionPath,
239 T* metricData) {
240 for (int i = 0; i < metricData->data_size(); ++i) {
241 auto data = metricData->mutable_data(i);
242 if (data->dimension_leaf_values_in_what_size() > 0) {
243 backfillDimensionPath(whatPath, data->dimension_leaf_values_in_what(),
244 data->mutable_dimensions_in_what());
245 data->clear_dimension_leaf_values_in_what();
246 }
247 if (data->dimension_leaf_values_in_condition_size() > 0) {
248 backfillDimensionPath(conditionPath, data->dimension_leaf_values_in_condition(),
249 data->mutable_dimensions_in_condition());
250 data->clear_dimension_leaf_values_in_condition();
251 }
252 }
253 }
254
255 struct DimensionCompare {
operatorDimensionCompare256 bool operator()(const DimensionsPair& s1, const DimensionsPair& s2) const {
257 return LessThan(s1, s2);
258 }
259 };
260
261 template <typename T>
sortMetricDataByDimensionsValue(const T & metricData,T * sortedMetricData)262 void sortMetricDataByDimensionsValue(const T& metricData, T* sortedMetricData) {
263 std::map<DimensionsPair, int, DimensionCompare> dimensionIndexMap;
264 for (int i = 0; i < metricData.data_size(); ++i) {
265 dimensionIndexMap.insert(
266 std::make_pair(DimensionsPair(metricData.data(i).dimensions_in_what(),
267 metricData.data(i).dimensions_in_condition()),
268 i));
269 }
270 for (const auto& itr : dimensionIndexMap) {
271 *sortedMetricData->add_data() = metricData.data(itr.second);
272 }
273 }
274
275 template <typename T>
backfillStartEndTimestampForFullBucket(const int64_t timeBaseNs,const int64_t bucketSizeNs,T * bucket)276 void backfillStartEndTimestampForFullBucket(
277 const int64_t timeBaseNs, const int64_t bucketSizeNs, T* bucket) {
278 bucket->set_start_bucket_elapsed_nanos(timeBaseNs + bucketSizeNs * bucket->bucket_num());
279 bucket->set_end_bucket_elapsed_nanos(
280 timeBaseNs + bucketSizeNs * bucket->bucket_num() + bucketSizeNs);
281 bucket->clear_bucket_num();
282 }
283
284 template <typename T>
backfillStartEndTimestampForPartialBucket(const int64_t timeBaseNs,T * bucket)285 void backfillStartEndTimestampForPartialBucket(const int64_t timeBaseNs, T* bucket) {
286 if (bucket->has_start_bucket_elapsed_millis()) {
287 bucket->set_start_bucket_elapsed_nanos(
288 MillisToNano(bucket->start_bucket_elapsed_millis()));
289 bucket->clear_start_bucket_elapsed_millis();
290 }
291 if (bucket->has_end_bucket_elapsed_millis()) {
292 bucket->set_end_bucket_elapsed_nanos(
293 MillisToNano(bucket->end_bucket_elapsed_millis()));
294 bucket->clear_end_bucket_elapsed_millis();
295 }
296 }
297
298 template <typename T>
backfillStartEndTimestampForMetrics(const int64_t timeBaseNs,const int64_t bucketSizeNs,T * metrics)299 void backfillStartEndTimestampForMetrics(const int64_t timeBaseNs, const int64_t bucketSizeNs,
300 T* metrics) {
301 for (int i = 0; i < metrics->data_size(); ++i) {
302 auto data = metrics->mutable_data(i);
303 for (int j = 0; j < data->bucket_info_size(); ++j) {
304 auto bucket = data->mutable_bucket_info(j);
305 if (bucket->has_bucket_num()) {
306 backfillStartEndTimestampForFullBucket(timeBaseNs, bucketSizeNs, bucket);
307 } else {
308 backfillStartEndTimestampForPartialBucket(timeBaseNs, bucket);
309 }
310 }
311 }
312 }
313
314 template <typename T>
backfillStartEndTimestampForSkippedBuckets(const int64_t timeBaseNs,T * metrics)315 void backfillStartEndTimestampForSkippedBuckets(const int64_t timeBaseNs, T* metrics) {
316 for (int i = 0; i < metrics->skipped_size(); ++i) {
317 backfillStartEndTimestampForPartialBucket(timeBaseNs, metrics->mutable_skipped(i));
318 }
319 }
320 } // namespace statsd
321 } // namespace os
322 } // namespace android