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 { 199 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> 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> 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 { 256 bool operator()(const DimensionsPair& s1, const DimensionsPair& s2) const { 257 return LessThan(s1, s2); 258 } 259 }; 260 261 template <typename T> 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> 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> 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> 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> 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