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 <aidl/android/os/BnPendingIntentRef.h> 18 #include <aidl/android/os/BnPullAtomCallback.h> 19 #include <aidl/android/os/IPullAtomCallback.h> 20 #include <aidl/android/os/IPullAtomResultReceiver.h> 21 #include <gmock/gmock.h> 22 #include <gtest/gtest.h> 23 24 #include "src/stats_log.pb.h" 25 #include "src/statsd_config.pb.h" 26 #include "src/StatsLogProcessor.h" 27 #include "src/hash.h" 28 #include "src/logd/LogEvent.h" 29 #include "src/matchers/EventMatcherWizard.h" 30 #include "src/packages/UidMap.h" 31 #include "src/stats_log_util.h" 32 #include "stats_event.h" 33 #include "statslog_statsdtest.h" 34 35 namespace android { 36 namespace os { 37 namespace statsd { 38 39 using namespace testing; 40 using ::aidl::android::os::BnPullAtomCallback; 41 using ::aidl::android::os::IPullAtomCallback; 42 using ::aidl::android::os::IPullAtomResultReceiver; 43 using android::util::ProtoReader; 44 using google::protobuf::RepeatedPtrField; 45 using Status = ::ndk::ScopedAStatus; 46 47 const int SCREEN_STATE_ATOM_ID = util::SCREEN_STATE_CHANGED; 48 const int UID_PROCESS_STATE_ATOM_ID = util::UID_PROCESS_STATE_CHANGED; 49 50 enum BucketSplitEvent { APP_UPGRADE, BOOT_COMPLETE }; 51 52 class MockUidMap : public UidMap { 53 public: 54 MOCK_METHOD(int, getHostUidOrSelf, (int uid), (const)); 55 MOCK_METHOD(std::set<int32_t>, getAppUid, (const string& package), (const)); 56 }; 57 58 class MockPendingIntentRef : public aidl::android::os::BnPendingIntentRef { 59 public: 60 MOCK_METHOD1(sendDataBroadcast, Status(int64_t lastReportTimeNs)); 61 MOCK_METHOD1(sendActiveConfigsChangedBroadcast, Status(const vector<int64_t>& configIds)); 62 MOCK_METHOD6(sendSubscriberBroadcast, 63 Status(int64_t configUid, int64_t configId, int64_t subscriptionId, 64 int64_t subscriptionRuleId, const vector<string>& cookies, 65 const StatsDimensionsValueParcel& dimensionsValueParcel)); 66 }; 67 68 // Converts a ProtoOutputStream to a StatsLogReport proto. 69 StatsLogReport outputStreamToProto(ProtoOutputStream* proto); 70 71 // Create AtomMatcher proto to simply match a specific atom type. 72 AtomMatcher CreateSimpleAtomMatcher(const string& name, int atomId); 73 74 // Create AtomMatcher proto for temperature atom. 75 AtomMatcher CreateTemperatureAtomMatcher(); 76 77 // Create AtomMatcher proto for scheduled job state changed. 78 AtomMatcher CreateScheduledJobStateChangedAtomMatcher(); 79 80 // Create AtomMatcher proto for starting a scheduled job. 81 AtomMatcher CreateStartScheduledJobAtomMatcher(); 82 83 // Create AtomMatcher proto for a scheduled job is done. 84 AtomMatcher CreateFinishScheduledJobAtomMatcher(); 85 86 // Create AtomMatcher proto for screen brightness state changed. 87 AtomMatcher CreateScreenBrightnessChangedAtomMatcher(); 88 89 // Create AtomMatcher proto for starting battery save mode. 90 AtomMatcher CreateBatterySaverModeStartAtomMatcher(); 91 92 // Create AtomMatcher proto for stopping battery save mode. 93 AtomMatcher CreateBatterySaverModeStopAtomMatcher(); 94 95 // Create AtomMatcher proto for battery state none mode. 96 AtomMatcher CreateBatteryStateNoneMatcher(); 97 98 // Create AtomMatcher proto for battery state usb mode. 99 AtomMatcher CreateBatteryStateUsbMatcher(); 100 101 // Create AtomMatcher proto for process state changed. 102 AtomMatcher CreateUidProcessStateChangedAtomMatcher(); 103 104 // Create AtomMatcher proto for acquiring wakelock. 105 AtomMatcher CreateAcquireWakelockAtomMatcher(); 106 107 // Create AtomMatcher proto for releasing wakelock. 108 AtomMatcher CreateReleaseWakelockAtomMatcher() ; 109 110 // Create AtomMatcher proto for screen turned on. 111 AtomMatcher CreateScreenTurnedOnAtomMatcher(); 112 113 // Create AtomMatcher proto for screen turned off. 114 AtomMatcher CreateScreenTurnedOffAtomMatcher(); 115 116 // Create AtomMatcher proto for app sync turned on. 117 AtomMatcher CreateSyncStartAtomMatcher(); 118 119 // Create AtomMatcher proto for app sync turned off. 120 AtomMatcher CreateSyncEndAtomMatcher(); 121 122 // Create AtomMatcher proto for app sync moves to background. 123 AtomMatcher CreateMoveToBackgroundAtomMatcher(); 124 125 // Create AtomMatcher proto for app sync moves to foreground. 126 AtomMatcher CreateMoveToForegroundAtomMatcher(); 127 128 // Create AtomMatcher proto for process crashes 129 AtomMatcher CreateProcessCrashAtomMatcher() ; 130 131 // Add an AtomMatcher to a combination AtomMatcher. 132 void addMatcherToMatcherCombination(const AtomMatcher& matcher, AtomMatcher* combinationMatcher); 133 134 // Create Predicate proto for screen is on. 135 Predicate CreateScreenIsOnPredicate(); 136 137 // Create Predicate proto for screen is off. 138 Predicate CreateScreenIsOffPredicate(); 139 140 // Create Predicate proto for a running scheduled job. 141 Predicate CreateScheduledJobPredicate(); 142 143 // Create Predicate proto for battery saver mode. 144 Predicate CreateBatterySaverModePredicate(); 145 146 // Create Predicate proto for device unplogged mode. 147 Predicate CreateDeviceUnpluggedPredicate(); 148 149 // Create Predicate proto for holding wakelock. 150 Predicate CreateHoldingWakelockPredicate(); 151 152 // Create a Predicate proto for app syncing. 153 Predicate CreateIsSyncingPredicate(); 154 155 // Create a Predicate proto for app is in background. 156 Predicate CreateIsInBackgroundPredicate(); 157 158 // Create State proto for screen state atom. 159 State CreateScreenState(); 160 161 // Create State proto for uid process state atom. 162 State CreateUidProcessState(); 163 164 // Create State proto for overlay state atom. 165 State CreateOverlayState(); 166 167 // Create State proto for screen state atom with on/off map. 168 State CreateScreenStateWithOnOffMap(int64_t screenOnId, int64_t screenOffId); 169 170 // Create State proto for screen state atom with simple on/off map. 171 State CreateScreenStateWithSimpleOnOffMap(int64_t screenOnId, int64_t screenOffId); 172 173 // Create StateGroup proto for ScreenState ON group 174 StateMap_StateGroup CreateScreenStateOnGroup(int64_t screenOnId); 175 176 // Create StateGroup proto for ScreenState OFF group 177 StateMap_StateGroup CreateScreenStateOffGroup(int64_t screenOffId); 178 179 // Create StateGroup proto for simple ScreenState ON group 180 StateMap_StateGroup CreateScreenStateSimpleOnGroup(int64_t screenOnId); 181 182 // Create StateGroup proto for simple ScreenState OFF group 183 StateMap_StateGroup CreateScreenStateSimpleOffGroup(int64_t screenOffId); 184 185 // Create StateMap proto for ScreenState ON/OFF map 186 StateMap CreateScreenStateOnOffMap(int64_t screenOnId, int64_t screenOffId); 187 188 // Create StateMap proto for simple ScreenState ON/OFF map 189 StateMap CreateScreenStateSimpleOnOffMap(int64_t screenOnId, int64_t screenOffId); 190 191 // Add a predicate to the predicate combination. 192 void addPredicateToPredicateCombination(const Predicate& predicate, Predicate* combination); 193 194 // Create dimensions from primitive fields. 195 FieldMatcher CreateDimensions(const int atomId, const std::vector<int>& fields); 196 197 // Create dimensions by attribution uid and tag. 198 FieldMatcher CreateAttributionUidAndTagDimensions(const int atomId, 199 const std::vector<Position>& positions); 200 201 // Create dimensions by attribution uid only. 202 FieldMatcher CreateAttributionUidDimensions(const int atomId, 203 const std::vector<Position>& positions); 204 205 FieldMatcher CreateAttributionUidAndOtherDimensions(const int atomId, 206 const std::vector<Position>& positions, 207 const std::vector<int>& fields); 208 209 EventMetric createEventMetric(const string& name, const int64_t what, 210 const optional<int64_t>& condition); 211 212 CountMetric createCountMetric(const string& name, const int64_t what, 213 const optional<int64_t>& condition, const vector<int64_t>& states); 214 215 DurationMetric createDurationMetric(const string& name, const int64_t what, 216 const optional<int64_t>& condition, 217 const vector<int64_t>& states); 218 219 GaugeMetric createGaugeMetric(const string& name, const int64_t what, 220 const GaugeMetric::SamplingType samplingType, 221 const optional<int64_t>& condition, 222 const optional<int64_t>& triggerEvent); 223 224 ValueMetric createValueMetric(const string& name, const AtomMatcher& what, const int valueField, 225 const optional<int64_t>& condition, const vector<int64_t>& states); 226 227 Alert createAlert(const string& name, const int64_t metricId, const int buckets, 228 const int64_t triggerSum); 229 230 Alarm createAlarm(const string& name, const int64_t offsetMillis, const int64_t periodMillis); 231 232 Subscription createSubscription(const string& name, const Subscription_RuleType type, 233 const int64_t ruleId); 234 235 // START: get primary key functions 236 // These functions take in atom field information and create FieldValues which are stored in the 237 // given HashableDimensionKey. 238 void getUidProcessKey(int uid, HashableDimensionKey* key); 239 240 void getOverlayKey(int uid, string packageName, HashableDimensionKey* key); 241 242 void getPartialWakelockKey(int uid, const std::string& tag, HashableDimensionKey* key); 243 244 void getPartialWakelockKey(int uid, HashableDimensionKey* key); 245 // END: get primary key functions 246 247 void writeAttribution(AStatsEvent* statsEvent, const vector<int>& attributionUids, 248 const vector<string>& attributionTags); 249 250 // Builds statsEvent to get buffer that is parsed into logEvent then releases statsEvent. 251 void parseStatsEventToLogEvent(AStatsEvent* statsEvent, LogEvent* logEvent); 252 253 shared_ptr<LogEvent> CreateTwoValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1, 254 int32_t value2); 255 256 void CreateTwoValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs, int32_t value1, 257 int32_t value2); 258 259 shared_ptr<LogEvent> CreateThreeValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1, 260 int32_t value2, int32_t value3); 261 262 void CreateThreeValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs, int32_t value1, 263 int32_t value2, int32_t value3); 264 265 // The repeated value log event helpers create a log event with two int fields, both 266 // set to the same value. This is useful for testing metrics that are only interested 267 // in the value of the second field but still need the first field to be populated. 268 std::shared_ptr<LogEvent> CreateRepeatedValueLogEvent(int atomId, int64_t eventTimeNs, 269 int32_t value); 270 271 void CreateRepeatedValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs, 272 int32_t value); 273 274 std::shared_ptr<LogEvent> CreateNoValuesLogEvent(int atomId, int64_t eventTimeNs); 275 276 void CreateNoValuesLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs); 277 278 std::shared_ptr<LogEvent> makeUidLogEvent(int atomId, int64_t eventTimeNs, int uid, int data1, 279 int data2); 280 281 std::shared_ptr<LogEvent> makeAttributionLogEvent(int atomId, int64_t eventTimeNs, 282 const vector<int>& uids, 283 const vector<string>& tags, int data1, int data2); 284 285 sp<MockUidMap> makeMockUidMapForOneHost(int hostUid, const vector<int>& isolatedUids); 286 287 sp<MockUidMap> makeMockUidMapForPackage(const string& pkg, const set<int32_t>& uids); 288 289 // Create log event for screen state changed. 290 std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(uint64_t timestampNs, 291 const android::view::DisplayStateEnum state, 292 int loggerUid = 0); 293 294 // Create log event for screen brightness state changed. 295 std::unique_ptr<LogEvent> CreateScreenBrightnessChangedEvent(uint64_t timestampNs, int level); 296 297 // Create log event when scheduled job starts. 298 std::unique_ptr<LogEvent> CreateStartScheduledJobEvent(uint64_t timestampNs, 299 const vector<int>& attributionUids, 300 const vector<string>& attributionTags, 301 const string& jobName); 302 303 // Create log event when scheduled job finishes. 304 std::unique_ptr<LogEvent> CreateFinishScheduledJobEvent(uint64_t timestampNs, 305 const vector<int>& attributionUids, 306 const vector<string>& attributionTags, 307 const string& jobName); 308 309 // Create log event when battery saver starts. 310 std::unique_ptr<LogEvent> CreateBatterySaverOnEvent(uint64_t timestampNs); 311 // Create log event when battery saver stops. 312 std::unique_ptr<LogEvent> CreateBatterySaverOffEvent(uint64_t timestampNs); 313 314 // Create log event when battery state changes. 315 std::unique_ptr<LogEvent> CreateBatteryStateChangedEvent(const uint64_t timestampNs, const BatteryPluggedStateEnum state); 316 317 // Create log event for app moving to background. 318 std::unique_ptr<LogEvent> CreateMoveToBackgroundEvent(uint64_t timestampNs, const int uid); 319 320 // Create log event for app moving to foreground. 321 std::unique_ptr<LogEvent> CreateMoveToForegroundEvent(uint64_t timestampNs, const int uid); 322 323 // Create log event when the app sync starts. 324 std::unique_ptr<LogEvent> CreateSyncStartEvent(uint64_t timestampNs, const vector<int>& uids, 325 const vector<string>& tags, const string& name); 326 327 // Create log event when the app sync ends. 328 std::unique_ptr<LogEvent> CreateSyncEndEvent(uint64_t timestampNs, const vector<int>& uids, 329 const vector<string>& tags, const string& name); 330 331 // Create log event when the app sync ends. 332 std::unique_ptr<LogEvent> CreateAppCrashEvent(uint64_t timestampNs, const int uid); 333 334 // Create log event for an app crash. 335 std::unique_ptr<LogEvent> CreateAppCrashOccurredEvent(uint64_t timestampNs, const int uid); 336 337 // Create log event for acquiring wakelock. 338 std::unique_ptr<LogEvent> CreateAcquireWakelockEvent(uint64_t timestampNs, const vector<int>& uids, 339 const vector<string>& tags, 340 const string& wakelockName); 341 342 // Create log event for releasing wakelock. 343 std::unique_ptr<LogEvent> CreateReleaseWakelockEvent(uint64_t timestampNs, const vector<int>& uids, 344 const vector<string>& tags, 345 const string& wakelockName); 346 347 // Create log event for releasing wakelock. 348 std::unique_ptr<LogEvent> CreateIsolatedUidChangedEvent(uint64_t timestampNs, int hostUid, 349 int isolatedUid, bool is_create); 350 351 // Create log event for uid process state change. 352 std::unique_ptr<LogEvent> CreateUidProcessStateChangedEvent( 353 uint64_t timestampNs, int uid, const android::app::ProcessStateEnum state); 354 355 std::unique_ptr<LogEvent> CreateBleScanStateChangedEvent(uint64_t timestampNs, 356 const vector<int>& attributionUids, 357 const vector<string>& attributionTags, 358 const BleScanStateChanged::State state, 359 const bool filtered, const bool firstMatch, 360 const bool opportunistic); 361 362 std::unique_ptr<LogEvent> CreateOverlayStateChangedEvent(int64_t timestampNs, const int32_t uid, 363 const string& packageName, 364 const bool usingAlertWindow, 365 const OverlayStateChanged::State state); 366 367 std::unique_ptr<LogEvent> CreateAppStartOccurredEvent( 368 uint64_t timestampNs, const int uid, const string& pkg_name, 369 AppStartOccurred::TransitionType type, const string& activity_name, 370 const string& calling_pkg_name, const bool is_instant_app, int64_t activity_start_msec); 371 372 // Create a statsd log event processor upon the start time in seconds, config and key. 373 sp<StatsLogProcessor> CreateStatsLogProcessor(const int64_t timeBaseNs, const int64_t currentTimeNs, 374 const StatsdConfig& config, const ConfigKey& key, 375 const shared_ptr<IPullAtomCallback>& puller = nullptr, 376 const int32_t atomTag = 0 /*for puller only*/, 377 const sp<UidMap> = new UidMap()); 378 379 // Util function to sort the log events by timestamp. 380 void sortLogEventsByTimestamp(std::vector<std::unique_ptr<LogEvent>> *events); 381 382 int64_t StringToId(const string& str); 383 384 sp<EventMatcherWizard> createEventMatcherWizard( 385 int tagId, int matcherIndex, const std::vector<FieldValueMatcher>& fieldValueMatchers = {}); 386 387 StatsDimensionsValueParcel CreateAttributionUidDimensionsValueParcel(const int atomId, 388 const int uid); 389 390 void ValidateUidDimension(const DimensionsValue& value, int atomId, int uid); 391 void ValidateWakelockAttributionUidAndTagDimension(const DimensionsValue& value, const int atomId, 392 const int uid, const string& tag); 393 void ValidateUidDimension(const DimensionsValue& value, int node_idx, int atomId, int uid); 394 void ValidateAttributionUidDimension(const DimensionsValue& value, int atomId, int uid); 395 void ValidateAttributionUidAndTagDimension( 396 const DimensionsValue& value, int atomId, int uid, const std::string& tag); 397 void ValidateAttributionUidAndTagDimension( 398 const DimensionsValue& value, int node_idx, int atomId, int uid, const std::string& tag); 399 void ValidateStateValue(const google::protobuf::RepeatedPtrField<StateValue>& stateValues, 400 int atomId, int64_t value); 401 402 void ValidateCountBucket(const CountBucketInfo& countBucket, int64_t startTimeNs, int64_t endTimeNs, 403 int64_t count); 404 void ValidateDurationBucket(const DurationBucketInfo& bucket, int64_t startTimeNs, 405 int64_t endTimeNs, int64_t durationNs); 406 void ValidateGaugeBucketTimes(const GaugeBucketInfo& gaugeBucket, int64_t startTimeNs, 407 int64_t endTimeNs, vector<int64_t> eventTimesNs); 408 void ValidateValueBucket(const ValueBucketInfo& bucket, int64_t startTimeNs, int64_t endTimeNs, 409 const vector<int64_t>& values, int64_t conditionTrueNs); 410 411 struct DimensionsPair { 412 DimensionsPair(DimensionsValue m1, google::protobuf::RepeatedPtrField<StateValue> m2) 413 : dimInWhat(m1), stateValues(m2){}; 414 415 DimensionsValue dimInWhat; 416 google::protobuf::RepeatedPtrField<StateValue> stateValues; 417 }; 418 419 bool LessThan(const StateValue& s1, const StateValue& s2); 420 bool LessThan(const DimensionsValue& s1, const DimensionsValue& s2); 421 bool LessThan(const DimensionsPair& s1, const DimensionsPair& s2); 422 423 void backfillStartEndTimestamp(StatsLogReport* report); 424 void backfillStartEndTimestamp(ConfigMetricsReport *config_report); 425 void backfillStartEndTimestamp(ConfigMetricsReportList *config_report_list); 426 427 void backfillStringInReport(ConfigMetricsReportList *config_report_list); 428 void backfillStringInDimension(const std::map<uint64_t, string>& str_map, 429 DimensionsValue* dimension); 430 431 template <typename T> 432 void backfillStringInDimension(const std::map<uint64_t, string>& str_map, 433 T* metrics) { 434 for (int i = 0; i < metrics->data_size(); ++i) { 435 auto data = metrics->mutable_data(i); 436 if (data->has_dimensions_in_what()) { 437 backfillStringInDimension(str_map, data->mutable_dimensions_in_what()); 438 } 439 if (data->has_dimensions_in_condition()) { 440 backfillStringInDimension(str_map, data->mutable_dimensions_in_condition()); 441 } 442 } 443 } 444 445 void backfillDimensionPath(StatsLogReport* report); 446 void backfillDimensionPath(ConfigMetricsReport* config_report); 447 void backfillDimensionPath(ConfigMetricsReportList* config_report_list); 448 449 bool backfillDimensionPath(const DimensionsValue& path, 450 const google::protobuf::RepeatedPtrField<DimensionsValue>& leafValues, 451 DimensionsValue* dimension); 452 453 class FakeSubsystemSleepCallback : public BnPullAtomCallback { 454 public: 455 // Track the number of pulls. 456 int pullNum = 1; 457 Status onPullAtom(int atomTag, 458 const shared_ptr<IPullAtomResultReceiver>& resultReceiver) override; 459 }; 460 461 template <typename T> 462 void backfillDimensionPath(const DimensionsValue& whatPath, 463 const DimensionsValue& conditionPath, 464 T* metricData) { 465 for (int i = 0; i < metricData->data_size(); ++i) { 466 auto data = metricData->mutable_data(i); 467 if (data->dimension_leaf_values_in_what_size() > 0) { 468 backfillDimensionPath(whatPath, data->dimension_leaf_values_in_what(), 469 data->mutable_dimensions_in_what()); 470 data->clear_dimension_leaf_values_in_what(); 471 } 472 if (data->dimension_leaf_values_in_condition_size() > 0) { 473 backfillDimensionPath(conditionPath, data->dimension_leaf_values_in_condition(), 474 data->mutable_dimensions_in_condition()); 475 data->clear_dimension_leaf_values_in_condition(); 476 } 477 } 478 } 479 480 struct DimensionCompare { 481 bool operator()(const DimensionsPair& s1, const DimensionsPair& s2) const { 482 return LessThan(s1, s2); 483 } 484 }; 485 486 template <typename T> 487 void sortMetricDataByDimensionsValue(const T& metricData, T* sortedMetricData) { 488 std::map<DimensionsPair, int, DimensionCompare> dimensionIndexMap; 489 for (int i = 0; i < metricData.data_size(); ++i) { 490 dimensionIndexMap.insert( 491 std::make_pair(DimensionsPair(metricData.data(i).dimensions_in_what(), 492 metricData.data(i).slice_by_state()), 493 i)); 494 } 495 for (const auto& itr : dimensionIndexMap) { 496 *sortedMetricData->add_data() = metricData.data(itr.second); 497 } 498 } 499 500 template <typename T> 501 void sortMetricDataByFirstDimensionLeafValue(const T& metricData, T* sortedMetricData) { 502 std::map<DimensionsPair, int, DimensionCompare> dimensionIndexMap; 503 for (int i = 0; i < metricData.data_size(); ++i) { 504 dimensionIndexMap.insert( 505 std::make_pair(DimensionsPair(metricData.data(i).dimension_leaf_values_in_what()[0], 506 metricData.data(i).slice_by_state()), 507 i)); 508 } 509 for (const auto& itr : dimensionIndexMap) { 510 *sortedMetricData->add_data() = metricData.data(itr.second); 511 } 512 } 513 514 template <typename T> 515 void backfillStartEndTimestampForFullBucket( 516 const int64_t timeBaseNs, const int64_t bucketSizeNs, T* bucket) { 517 bucket->set_start_bucket_elapsed_nanos(timeBaseNs + bucketSizeNs * bucket->bucket_num()); 518 bucket->set_end_bucket_elapsed_nanos( 519 timeBaseNs + bucketSizeNs * bucket->bucket_num() + bucketSizeNs); 520 bucket->clear_bucket_num(); 521 } 522 523 template <typename T> 524 void backfillStartEndTimestampForPartialBucket(const int64_t timeBaseNs, T* bucket) { 525 if (bucket->has_start_bucket_elapsed_millis()) { 526 bucket->set_start_bucket_elapsed_nanos( 527 MillisToNano(bucket->start_bucket_elapsed_millis())); 528 bucket->clear_start_bucket_elapsed_millis(); 529 } 530 if (bucket->has_end_bucket_elapsed_millis()) { 531 bucket->set_end_bucket_elapsed_nanos( 532 MillisToNano(bucket->end_bucket_elapsed_millis())); 533 bucket->clear_end_bucket_elapsed_millis(); 534 } 535 } 536 537 template <typename T> 538 void backfillStartEndTimestampForMetrics(const int64_t timeBaseNs, const int64_t bucketSizeNs, 539 T* metrics) { 540 for (int i = 0; i < metrics->data_size(); ++i) { 541 auto data = metrics->mutable_data(i); 542 for (int j = 0; j < data->bucket_info_size(); ++j) { 543 auto bucket = data->mutable_bucket_info(j); 544 if (bucket->has_bucket_num()) { 545 backfillStartEndTimestampForFullBucket(timeBaseNs, bucketSizeNs, bucket); 546 } else { 547 backfillStartEndTimestampForPartialBucket(timeBaseNs, bucket); 548 } 549 } 550 } 551 } 552 553 template <typename T> 554 void backfillStartEndTimestampForSkippedBuckets(const int64_t timeBaseNs, T* metrics) { 555 for (int i = 0; i < metrics->skipped_size(); ++i) { 556 backfillStartEndTimestampForPartialBucket(timeBaseNs, metrics->mutable_skipped(i)); 557 } 558 } 559 } // namespace statsd 560 } // namespace os 561 } // namespace android 562