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 {
DimensionsPairDimensionsPair412 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>
backfillStringInDimension(const std::map<uint64_t,string> & str_map,T * metrics)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>
backfillDimensionPath(const DimensionsValue & whatPath,const DimensionsValue & conditionPath,T * metricData)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 {
operatorDimensionCompare481 bool operator()(const DimensionsPair& s1, const DimensionsPair& s2) const {
482 return LessThan(s1, s2);
483 }
484 };
485
486 template <typename T>
sortMetricDataByDimensionsValue(const T & metricData,T * sortedMetricData)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>
sortMetricDataByFirstDimensionLeafValue(const T & metricData,T * sortedMetricData)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>
backfillStartEndTimestampForFullBucket(const int64_t timeBaseNs,const int64_t bucketSizeNs,T * bucket)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>
backfillStartEndTimestampForPartialBucket(const int64_t timeBaseNs,T * bucket)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>
backfillStartEndTimestampForMetrics(const int64_t timeBaseNs,const int64_t bucketSizeNs,T * metrics)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>
backfillStartEndTimestampForSkippedBuckets(const int64_t timeBaseNs,T * metrics)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