• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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