Home | History | Annotate | Download | only in tests
      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 #include "statsd_test_util.h"
     16 
     17 namespace android {
     18 namespace os {
     19 namespace statsd {
     20 
     21 
     22 AtomMatcher CreateSimpleAtomMatcher(const string& name, int atomId) {
     23     AtomMatcher atom_matcher;
     24     atom_matcher.set_id(StringToId(name));
     25     auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
     26     simple_atom_matcher->set_atom_id(atomId);
     27     return atom_matcher;
     28 }
     29 
     30 AtomMatcher CreateTemperatureAtomMatcher() {
     31     return CreateSimpleAtomMatcher("TemperatureMatcher", android::util::TEMPERATURE);
     32 }
     33 
     34 AtomMatcher CreateScheduledJobStateChangedAtomMatcher(const string& name,
     35                                                       ScheduledJobStateChanged::State state) {
     36     AtomMatcher atom_matcher;
     37     atom_matcher.set_id(StringToId(name));
     38     auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
     39     simple_atom_matcher->set_atom_id(android::util::SCHEDULED_JOB_STATE_CHANGED);
     40     auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
     41     field_value_matcher->set_field(3);  // State field.
     42     field_value_matcher->set_eq_int(state);
     43     return atom_matcher;
     44 }
     45 
     46 AtomMatcher CreateStartScheduledJobAtomMatcher() {
     47     return CreateScheduledJobStateChangedAtomMatcher("ScheduledJobStart",
     48                                                      ScheduledJobStateChanged::STARTED);
     49 }
     50 
     51 AtomMatcher CreateFinishScheduledJobAtomMatcher() {
     52     return CreateScheduledJobStateChangedAtomMatcher("ScheduledJobFinish",
     53                                                      ScheduledJobStateChanged::FINISHED);
     54 }
     55 
     56 AtomMatcher CreateScreenBrightnessChangedAtomMatcher() {
     57     AtomMatcher atom_matcher;
     58     atom_matcher.set_id(StringToId("ScreenBrightnessChanged"));
     59     auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
     60     simple_atom_matcher->set_atom_id(android::util::SCREEN_BRIGHTNESS_CHANGED);
     61     return atom_matcher;
     62 }
     63 
     64 AtomMatcher CreateUidProcessStateChangedAtomMatcher() {
     65     AtomMatcher atom_matcher;
     66     atom_matcher.set_id(StringToId("UidProcessStateChanged"));
     67     auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
     68     simple_atom_matcher->set_atom_id(android::util::UID_PROCESS_STATE_CHANGED);
     69     return atom_matcher;
     70 }
     71 
     72 AtomMatcher CreateWakelockStateChangedAtomMatcher(const string& name,
     73                                                   WakelockStateChanged::State state) {
     74     AtomMatcher atom_matcher;
     75     atom_matcher.set_id(StringToId(name));
     76     auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
     77     simple_atom_matcher->set_atom_id(android::util::WAKELOCK_STATE_CHANGED);
     78     auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
     79     field_value_matcher->set_field(4);  // State field.
     80     field_value_matcher->set_eq_int(state);
     81     return atom_matcher;
     82 }
     83 
     84 AtomMatcher CreateAcquireWakelockAtomMatcher() {
     85     return CreateWakelockStateChangedAtomMatcher("AcquireWakelock", WakelockStateChanged::ACQUIRE);
     86 }
     87 
     88 AtomMatcher CreateReleaseWakelockAtomMatcher() {
     89     return CreateWakelockStateChangedAtomMatcher("ReleaseWakelock", WakelockStateChanged::RELEASE);
     90 }
     91 
     92 AtomMatcher CreateBatterySaverModeStateChangedAtomMatcher(
     93     const string& name, BatterySaverModeStateChanged::State state) {
     94     AtomMatcher atom_matcher;
     95     atom_matcher.set_id(StringToId(name));
     96     auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
     97     simple_atom_matcher->set_atom_id(android::util::BATTERY_SAVER_MODE_STATE_CHANGED);
     98     auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
     99     field_value_matcher->set_field(1);  // State field.
    100     field_value_matcher->set_eq_int(state);
    101     return atom_matcher;
    102 }
    103 
    104 AtomMatcher CreateBatterySaverModeStartAtomMatcher() {
    105     return CreateBatterySaverModeStateChangedAtomMatcher(
    106         "BatterySaverModeStart", BatterySaverModeStateChanged::ON);
    107 }
    108 
    109 
    110 AtomMatcher CreateBatterySaverModeStopAtomMatcher() {
    111     return CreateBatterySaverModeStateChangedAtomMatcher(
    112         "BatterySaverModeStop", BatterySaverModeStateChanged::OFF);
    113 }
    114 
    115 
    116 AtomMatcher CreateScreenStateChangedAtomMatcher(
    117     const string& name, android::view::DisplayStateEnum state) {
    118     AtomMatcher atom_matcher;
    119     atom_matcher.set_id(StringToId(name));
    120     auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
    121     simple_atom_matcher->set_atom_id(android::util::SCREEN_STATE_CHANGED);
    122     auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
    123     field_value_matcher->set_field(1);  // State field.
    124     field_value_matcher->set_eq_int(state);
    125     return atom_matcher;
    126 }
    127 
    128 
    129 AtomMatcher CreateScreenTurnedOnAtomMatcher() {
    130     return CreateScreenStateChangedAtomMatcher("ScreenTurnedOn",
    131             android::view::DisplayStateEnum::DISPLAY_STATE_ON);
    132 }
    133 
    134 AtomMatcher CreateScreenTurnedOffAtomMatcher() {
    135     return CreateScreenStateChangedAtomMatcher("ScreenTurnedOff",
    136             ::android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
    137 }
    138 
    139 AtomMatcher CreateSyncStateChangedAtomMatcher(
    140     const string& name, SyncStateChanged::State state) {
    141     AtomMatcher atom_matcher;
    142     atom_matcher.set_id(StringToId(name));
    143     auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
    144     simple_atom_matcher->set_atom_id(android::util::SYNC_STATE_CHANGED);
    145     auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
    146     field_value_matcher->set_field(3);  // State field.
    147     field_value_matcher->set_eq_int(state);
    148     return atom_matcher;
    149 }
    150 
    151 AtomMatcher CreateSyncStartAtomMatcher() {
    152     return CreateSyncStateChangedAtomMatcher("SyncStart", SyncStateChanged::ON);
    153 }
    154 
    155 AtomMatcher CreateSyncEndAtomMatcher() {
    156     return CreateSyncStateChangedAtomMatcher("SyncEnd", SyncStateChanged::OFF);
    157 }
    158 
    159 AtomMatcher CreateActivityForegroundStateChangedAtomMatcher(
    160     const string& name, ActivityForegroundStateChanged::State state) {
    161     AtomMatcher atom_matcher;
    162     atom_matcher.set_id(StringToId(name));
    163     auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
    164     simple_atom_matcher->set_atom_id(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED);
    165     auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
    166     field_value_matcher->set_field(4);  // Activity field.
    167     field_value_matcher->set_eq_int(state);
    168     return atom_matcher;
    169 }
    170 
    171 AtomMatcher CreateMoveToBackgroundAtomMatcher() {
    172     return CreateActivityForegroundStateChangedAtomMatcher(
    173         "Background", ActivityForegroundStateChanged::BACKGROUND);
    174 }
    175 
    176 AtomMatcher CreateMoveToForegroundAtomMatcher() {
    177     return CreateActivityForegroundStateChangedAtomMatcher(
    178         "Foreground", ActivityForegroundStateChanged::FOREGROUND);
    179 }
    180 
    181 AtomMatcher CreateProcessLifeCycleStateChangedAtomMatcher(
    182     const string& name, ProcessLifeCycleStateChanged::State state) {
    183     AtomMatcher atom_matcher;
    184     atom_matcher.set_id(StringToId(name));
    185     auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
    186     simple_atom_matcher->set_atom_id(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
    187     auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
    188     field_value_matcher->set_field(3);  // Process state field.
    189     field_value_matcher->set_eq_int(state);
    190     return atom_matcher;
    191 }
    192 
    193 AtomMatcher CreateProcessCrashAtomMatcher() {
    194     return CreateProcessLifeCycleStateChangedAtomMatcher(
    195         "Crashed", ProcessLifeCycleStateChanged::CRASHED);
    196 }
    197 
    198 Predicate CreateScheduledJobPredicate() {
    199     Predicate predicate;
    200     predicate.set_id(StringToId("ScheduledJobRunningPredicate"));
    201     predicate.mutable_simple_predicate()->set_start(StringToId("ScheduledJobStart"));
    202     predicate.mutable_simple_predicate()->set_stop(StringToId("ScheduledJobFinish"));
    203     return predicate;
    204 }
    205 
    206 Predicate CreateBatterySaverModePredicate() {
    207     Predicate predicate;
    208     predicate.set_id(StringToId("BatterySaverIsOn"));
    209     predicate.mutable_simple_predicate()->set_start(StringToId("BatterySaverModeStart"));
    210     predicate.mutable_simple_predicate()->set_stop(StringToId("BatterySaverModeStop"));
    211     return predicate;
    212 }
    213 
    214 Predicate CreateScreenIsOnPredicate() {
    215     Predicate predicate;
    216     predicate.set_id(StringToId("ScreenIsOn"));
    217     predicate.mutable_simple_predicate()->set_start(StringToId("ScreenTurnedOn"));
    218     predicate.mutable_simple_predicate()->set_stop(StringToId("ScreenTurnedOff"));
    219     return predicate;
    220 }
    221 
    222 Predicate CreateScreenIsOffPredicate() {
    223     Predicate predicate;
    224     predicate.set_id(1111123);
    225     predicate.mutable_simple_predicate()->set_start(StringToId("ScreenTurnedOff"));
    226     predicate.mutable_simple_predicate()->set_stop(StringToId("ScreenTurnedOn"));
    227     return predicate;
    228 }
    229 
    230 Predicate CreateHoldingWakelockPredicate() {
    231     Predicate predicate;
    232     predicate.set_id(StringToId("HoldingWakelock"));
    233     predicate.mutable_simple_predicate()->set_start(StringToId("AcquireWakelock"));
    234     predicate.mutable_simple_predicate()->set_stop(StringToId("ReleaseWakelock"));
    235     return predicate;
    236 }
    237 
    238 Predicate CreateIsSyncingPredicate() {
    239     Predicate predicate;
    240     predicate.set_id(33333333333333);
    241     predicate.mutable_simple_predicate()->set_start(StringToId("SyncStart"));
    242     predicate.mutable_simple_predicate()->set_stop(StringToId("SyncEnd"));
    243     return predicate;
    244 }
    245 
    246 Predicate CreateIsInBackgroundPredicate() {
    247     Predicate predicate;
    248     predicate.set_id(StringToId("IsInBackground"));
    249     predicate.mutable_simple_predicate()->set_start(StringToId("Background"));
    250     predicate.mutable_simple_predicate()->set_stop(StringToId("Foreground"));
    251     return predicate;
    252 }
    253 
    254 void addPredicateToPredicateCombination(const Predicate& predicate,
    255                                         Predicate* combinationPredicate) {
    256     combinationPredicate->mutable_combination()->add_predicate(predicate.id());
    257 }
    258 
    259 FieldMatcher CreateAttributionUidDimensions(const int atomId,
    260                                             const std::vector<Position>& positions) {
    261     FieldMatcher dimensions;
    262     dimensions.set_field(atomId);
    263     for (const auto position : positions) {
    264         auto child = dimensions.add_child();
    265         child->set_field(1);
    266         child->set_position(position);
    267         child->add_child()->set_field(1);
    268     }
    269     return dimensions;
    270 }
    271 
    272 FieldMatcher CreateAttributionUidAndTagDimensions(const int atomId,
    273                                                  const std::vector<Position>& positions) {
    274     FieldMatcher dimensions;
    275     dimensions.set_field(atomId);
    276     for (const auto position : positions) {
    277         auto child = dimensions.add_child();
    278         child->set_field(1);
    279         child->set_position(position);
    280         child->add_child()->set_field(1);
    281         child->add_child()->set_field(2);
    282     }
    283     return dimensions;
    284 }
    285 
    286 FieldMatcher CreateDimensions(const int atomId, const std::vector<int>& fields) {
    287     FieldMatcher dimensions;
    288     dimensions.set_field(atomId);
    289     for (const int field : fields) {
    290         dimensions.add_child()->set_field(field);
    291     }
    292     return dimensions;
    293 }
    294 
    295 std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(
    296     const android::view::DisplayStateEnum state, uint64_t timestampNs) {
    297     auto event = std::make_unique<LogEvent>(android::util::SCREEN_STATE_CHANGED, timestampNs);
    298     EXPECT_TRUE(event->write(state));
    299     event->init();
    300     return event;
    301 }
    302 
    303 std::unique_ptr<LogEvent> CreateBatterySaverOnEvent(uint64_t timestampNs) {
    304     auto event = std::make_unique<LogEvent>(
    305         android::util::BATTERY_SAVER_MODE_STATE_CHANGED, timestampNs);
    306     EXPECT_TRUE(event->write(BatterySaverModeStateChanged::ON));
    307     event->init();
    308     return event;
    309 }
    310 
    311 std::unique_ptr<LogEvent> CreateBatterySaverOffEvent(uint64_t timestampNs) {
    312     auto event = std::make_unique<LogEvent>(
    313         android::util::BATTERY_SAVER_MODE_STATE_CHANGED, timestampNs);
    314     EXPECT_TRUE(event->write(BatterySaverModeStateChanged::OFF));
    315     event->init();
    316     return event;
    317 }
    318 
    319 std::unique_ptr<LogEvent> CreateScreenBrightnessChangedEvent(
    320     int level, uint64_t timestampNs) {
    321     auto event = std::make_unique<LogEvent>(android::util::SCREEN_BRIGHTNESS_CHANGED, timestampNs);
    322     EXPECT_TRUE(event->write(level));
    323     event->init();
    324     return event;
    325 
    326 }
    327 
    328 std::unique_ptr<LogEvent> CreateScheduledJobStateChangedEvent(
    329         const std::vector<AttributionNodeInternal>& attributions, const string& jobName,
    330         const ScheduledJobStateChanged::State state, uint64_t timestampNs) {
    331     auto event = std::make_unique<LogEvent>(android::util::SCHEDULED_JOB_STATE_CHANGED, timestampNs);
    332     event->write(attributions);
    333     event->write(jobName);
    334     event->write(state);
    335     event->init();
    336     return event;
    337 }
    338 
    339 std::unique_ptr<LogEvent> CreateStartScheduledJobEvent(
    340     const std::vector<AttributionNodeInternal>& attributions,
    341     const string& name, uint64_t timestampNs) {
    342     return CreateScheduledJobStateChangedEvent(
    343             attributions, name, ScheduledJobStateChanged::STARTED, timestampNs);
    344 }
    345 
    346 // Create log event when scheduled job finishes.
    347 std::unique_ptr<LogEvent> CreateFinishScheduledJobEvent(
    348     const std::vector<AttributionNodeInternal>& attributions,
    349     const string& name, uint64_t timestampNs) {
    350     return CreateScheduledJobStateChangedEvent(
    351             attributions, name, ScheduledJobStateChanged::FINISHED, timestampNs);
    352 }
    353 
    354 std::unique_ptr<LogEvent> CreateWakelockStateChangedEvent(
    355         const std::vector<AttributionNodeInternal>& attributions, const string& wakelockName,
    356         const WakelockStateChanged::State state, uint64_t timestampNs) {
    357     auto event = std::make_unique<LogEvent>(android::util::WAKELOCK_STATE_CHANGED, timestampNs);
    358     event->write(attributions);
    359     event->write(android::os::WakeLockLevelEnum::PARTIAL_WAKE_LOCK);
    360     event->write(wakelockName);
    361     event->write(state);
    362     event->init();
    363     return event;
    364 }
    365 
    366 std::unique_ptr<LogEvent> CreateAcquireWakelockEvent(
    367         const std::vector<AttributionNodeInternal>& attributions, const string& wakelockName,
    368         uint64_t timestampNs) {
    369     return CreateWakelockStateChangedEvent(
    370         attributions, wakelockName, WakelockStateChanged::ACQUIRE, timestampNs);
    371 }
    372 
    373 std::unique_ptr<LogEvent> CreateReleaseWakelockEvent(
    374         const std::vector<AttributionNodeInternal>& attributions, const string& wakelockName,
    375         uint64_t timestampNs) {
    376     return CreateWakelockStateChangedEvent(
    377         attributions, wakelockName, WakelockStateChanged::RELEASE, timestampNs);
    378 }
    379 
    380 std::unique_ptr<LogEvent> CreateActivityForegroundStateChangedEvent(
    381     const int uid, const ActivityForegroundStateChanged::State state, uint64_t timestampNs) {
    382     auto event = std::make_unique<LogEvent>(
    383         android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, timestampNs);
    384     event->write(uid);
    385     event->write("pkg_name");
    386     event->write("class_name");
    387     event->write(state);
    388     event->init();
    389     return event;
    390 }
    391 
    392 std::unique_ptr<LogEvent> CreateMoveToBackgroundEvent(const int uid, uint64_t timestampNs) {
    393     return CreateActivityForegroundStateChangedEvent(
    394         uid, ActivityForegroundStateChanged::BACKGROUND, timestampNs);
    395 }
    396 
    397 std::unique_ptr<LogEvent> CreateMoveToForegroundEvent(const int uid, uint64_t timestampNs) {
    398     return CreateActivityForegroundStateChangedEvent(
    399         uid, ActivityForegroundStateChanged::FOREGROUND, timestampNs);
    400 }
    401 
    402 std::unique_ptr<LogEvent> CreateSyncStateChangedEvent(
    403         const std::vector<AttributionNodeInternal>& attributions, const string& name,
    404         const SyncStateChanged::State state, uint64_t timestampNs) {
    405     auto event = std::make_unique<LogEvent>(android::util::SYNC_STATE_CHANGED, timestampNs);
    406     event->write(attributions);
    407     event->write(name);
    408     event->write(state);
    409     event->init();
    410     return event;
    411 }
    412 
    413 std::unique_ptr<LogEvent> CreateSyncStartEvent(
    414         const std::vector<AttributionNodeInternal>& attributions, const string& name,
    415         uint64_t timestampNs) {
    416     return CreateSyncStateChangedEvent(attributions, name, SyncStateChanged::ON, timestampNs);
    417 }
    418 
    419 std::unique_ptr<LogEvent> CreateSyncEndEvent(
    420         const std::vector<AttributionNodeInternal>& attributions, const string& name,
    421         uint64_t timestampNs) {
    422     return CreateSyncStateChangedEvent(attributions, name, SyncStateChanged::OFF, timestampNs);
    423 }
    424 
    425 std::unique_ptr<LogEvent> CreateProcessLifeCycleStateChangedEvent(
    426     const int uid, const ProcessLifeCycleStateChanged::State state, uint64_t timestampNs) {
    427     auto logEvent = std::make_unique<LogEvent>(
    428         android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, timestampNs);
    429     logEvent->write(uid);
    430     logEvent->write("");
    431     logEvent->write(state);
    432     logEvent->init();
    433     return logEvent;
    434 }
    435 
    436 std::unique_ptr<LogEvent> CreateAppCrashEvent(const int uid, uint64_t timestampNs) {
    437     return CreateProcessLifeCycleStateChangedEvent(
    438         uid, ProcessLifeCycleStateChanged::CRASHED, timestampNs);
    439 }
    440 
    441 std::unique_ptr<LogEvent> CreateIsolatedUidChangedEvent(
    442     int isolatedUid, int hostUid, bool is_create, uint64_t timestampNs) {
    443     auto logEvent = std::make_unique<LogEvent>(
    444         android::util::ISOLATED_UID_CHANGED, timestampNs);
    445     logEvent->write(hostUid);
    446     logEvent->write(isolatedUid);
    447     logEvent->write(is_create);
    448     logEvent->init();
    449     return logEvent;
    450 }
    451 
    452 sp<StatsLogProcessor> CreateStatsLogProcessor(const int64_t timeBaseNs, const int64_t currentTimeNs,
    453                                               const StatsdConfig& config, const ConfigKey& key) {
    454     sp<UidMap> uidMap = new UidMap();
    455     sp<AlarmMonitor> anomalyAlarmMonitor =
    456         new AlarmMonitor(1,  [](const sp<IStatsCompanionService>&, int64_t){},
    457                 [](const sp<IStatsCompanionService>&){});
    458     sp<AlarmMonitor> periodicAlarmMonitor =
    459         new AlarmMonitor(1,  [](const sp<IStatsCompanionService>&, int64_t){},
    460                 [](const sp<IStatsCompanionService>&){});
    461     sp<StatsLogProcessor> processor = new StatsLogProcessor(
    462         uidMap, anomalyAlarmMonitor, periodicAlarmMonitor, timeBaseNs, [](const ConfigKey&){return true;});
    463     processor->OnConfigUpdated(currentTimeNs, key, config);
    464     return processor;
    465 }
    466 
    467 AttributionNodeInternal CreateAttribution(const int& uid, const string& tag) {
    468     AttributionNodeInternal attribution;
    469     attribution.set_uid(uid);
    470     attribution.set_tag(tag);
    471     return attribution;
    472 }
    473 
    474 void sortLogEventsByTimestamp(std::vector<std::unique_ptr<LogEvent>> *events) {
    475   std::sort(events->begin(), events->end(),
    476             [](const std::unique_ptr<LogEvent>& a, const std::unique_ptr<LogEvent>& b) {
    477               return a->GetElapsedTimestampNs() < b->GetElapsedTimestampNs();
    478             });
    479 }
    480 
    481 int64_t StringToId(const string& str) {
    482     return static_cast<int64_t>(std::hash<std::string>()(str));
    483 }
    484 
    485 void ValidateAttributionUidDimension(const DimensionsValue& value, int atomId, int uid) {
    486     EXPECT_EQ(value.field(), atomId);
    487     // Attribution field.
    488     EXPECT_EQ(value.value_tuple().dimensions_value(0).field(), 1);
    489     // Uid only.
    490     EXPECT_EQ(value.value_tuple().dimensions_value(0)
    491         .value_tuple().dimensions_value_size(), 1);
    492     EXPECT_EQ(value.value_tuple().dimensions_value(0)
    493         .value_tuple().dimensions_value(0).field(), 1);
    494     EXPECT_EQ(value.value_tuple().dimensions_value(0)
    495         .value_tuple().dimensions_value(0).value_int(), uid);
    496 }
    497 
    498 void ValidateUidDimension(const DimensionsValue& value, int atomId, int uid) {
    499     EXPECT_EQ(value.field(), atomId);
    500     EXPECT_EQ(value.value_tuple().dimensions_value_size(), 1);
    501     // Attribution field.
    502     EXPECT_EQ(value.value_tuple().dimensions_value(0).field(), 1);
    503     // Uid only.
    504     EXPECT_EQ(value.value_tuple().dimensions_value(0)
    505         .value_tuple().dimensions_value_size(), 1);
    506     EXPECT_EQ(value.value_tuple().dimensions_value(0)
    507         .value_tuple().dimensions_value(0).field(), 1);
    508     EXPECT_EQ(value.value_tuple().dimensions_value(0)
    509         .value_tuple().dimensions_value(0).value_int(), uid);
    510 }
    511 
    512 void ValidateUidDimension(const DimensionsValue& value, int node_idx, int atomId, int uid) {
    513     EXPECT_EQ(value.field(), atomId);
    514     EXPECT_GT(value.value_tuple().dimensions_value_size(), node_idx);
    515     // Attribution field.
    516     EXPECT_EQ(value.value_tuple().dimensions_value(node_idx).field(), 1);
    517     EXPECT_EQ(value.value_tuple().dimensions_value(node_idx)
    518         .value_tuple().dimensions_value(0).field(), 1);
    519     EXPECT_EQ(value.value_tuple().dimensions_value(node_idx)
    520         .value_tuple().dimensions_value(0).value_int(), uid);
    521 }
    522 
    523 void ValidateAttributionUidAndTagDimension(
    524     const DimensionsValue& value, int node_idx, int atomId, int uid, const std::string& tag) {
    525     EXPECT_EQ(value.field(), atomId);
    526     EXPECT_GT(value.value_tuple().dimensions_value_size(), node_idx);
    527     // Attribution field.
    528     EXPECT_EQ(1, value.value_tuple().dimensions_value(node_idx).field());
    529     // Uid only.
    530     EXPECT_EQ(2, value.value_tuple().dimensions_value(node_idx)
    531         .value_tuple().dimensions_value_size());
    532     EXPECT_EQ(1, value.value_tuple().dimensions_value(node_idx)
    533         .value_tuple().dimensions_value(0).field());
    534     EXPECT_EQ(uid, value.value_tuple().dimensions_value(node_idx)
    535         .value_tuple().dimensions_value(0).value_int());
    536     EXPECT_EQ(2, value.value_tuple().dimensions_value(node_idx)
    537         .value_tuple().dimensions_value(1).field());
    538     EXPECT_EQ(tag, value.value_tuple().dimensions_value(node_idx)
    539         .value_tuple().dimensions_value(1).value_str());
    540 }
    541 
    542 void ValidateAttributionUidAndTagDimension(
    543     const DimensionsValue& value, int atomId, int uid, const std::string& tag) {
    544     EXPECT_EQ(value.field(), atomId);
    545     EXPECT_EQ(1, value.value_tuple().dimensions_value_size());
    546     // Attribution field.
    547     EXPECT_EQ(1, value.value_tuple().dimensions_value(0).field());
    548     // Uid only.
    549     EXPECT_EQ(value.value_tuple().dimensions_value(0)
    550         .value_tuple().dimensions_value_size(), 2);
    551     EXPECT_EQ(value.value_tuple().dimensions_value(0)
    552         .value_tuple().dimensions_value(0).field(), 1);
    553     EXPECT_EQ(value.value_tuple().dimensions_value(0)
    554         .value_tuple().dimensions_value(0).value_int(), uid);
    555     EXPECT_EQ(value.value_tuple().dimensions_value(0)
    556         .value_tuple().dimensions_value(1).field(), 2);
    557     EXPECT_EQ(value.value_tuple().dimensions_value(0)
    558         .value_tuple().dimensions_value(1).value_str(), tag);
    559 }
    560 
    561 bool EqualsTo(const DimensionsValue& s1, const DimensionsValue& s2) {
    562     if (s1.field() != s2.field()) {
    563         return false;
    564     }
    565     if (s1.value_case() != s2.value_case()) {
    566         return false;
    567     }
    568     switch (s1.value_case()) {
    569         case DimensionsValue::ValueCase::kValueStr:
    570             return (s1.value_str() == s2.value_str());
    571         case DimensionsValue::ValueCase::kValueInt:
    572             return s1.value_int() == s2.value_int();
    573         case DimensionsValue::ValueCase::kValueLong:
    574             return s1.value_long() == s2.value_long();
    575         case DimensionsValue::ValueCase::kValueBool:
    576             return s1.value_bool() == s2.value_bool();
    577         case DimensionsValue::ValueCase::kValueFloat:
    578             return s1.value_float() == s2.value_float();
    579         case DimensionsValue::ValueCase::kValueTuple: {
    580             if (s1.value_tuple().dimensions_value_size() !=
    581                 s2.value_tuple().dimensions_value_size()) {
    582                 return false;
    583             }
    584             bool allMatched = true;
    585             for (int i = 0; allMatched && i < s1.value_tuple().dimensions_value_size(); ++i) {
    586                 allMatched &= EqualsTo(s1.value_tuple().dimensions_value(i),
    587                                        s2.value_tuple().dimensions_value(i));
    588             }
    589             return allMatched;
    590         }
    591         case DimensionsValue::ValueCase::VALUE_NOT_SET:
    592         default:
    593             return true;
    594     }
    595 }
    596 
    597 bool LessThan(const DimensionsValue& s1, const DimensionsValue& s2) {
    598     if (s1.field() != s2.field()) {
    599         return s1.field() < s2.field();
    600     }
    601     if (s1.value_case() != s2.value_case()) {
    602         return s1.value_case() < s2.value_case();
    603     }
    604     switch (s1.value_case()) {
    605         case DimensionsValue::ValueCase::kValueStr:
    606             return s1.value_str() < s2.value_str();
    607         case DimensionsValue::ValueCase::kValueInt:
    608             return s1.value_int() < s2.value_int();
    609         case DimensionsValue::ValueCase::kValueLong:
    610             return s1.value_long() < s2.value_long();
    611         case DimensionsValue::ValueCase::kValueBool:
    612             return (int)s1.value_bool() < (int)s2.value_bool();
    613         case DimensionsValue::ValueCase::kValueFloat:
    614             return s1.value_float() < s2.value_float();
    615         case DimensionsValue::ValueCase::kValueTuple: {
    616             if (s1.value_tuple().dimensions_value_size() !=
    617                 s2.value_tuple().dimensions_value_size()) {
    618                 return s1.value_tuple().dimensions_value_size() <
    619                        s2.value_tuple().dimensions_value_size();
    620             }
    621             for (int i = 0; i < s1.value_tuple().dimensions_value_size(); ++i) {
    622                 if (EqualsTo(s1.value_tuple().dimensions_value(i),
    623                              s2.value_tuple().dimensions_value(i))) {
    624                     continue;
    625                 } else {
    626                     return LessThan(s1.value_tuple().dimensions_value(i),
    627                                     s2.value_tuple().dimensions_value(i));
    628                 }
    629             }
    630             return false;
    631         }
    632         case DimensionsValue::ValueCase::VALUE_NOT_SET:
    633         default:
    634             return false;
    635     }
    636 }
    637 
    638 bool LessThan(const DimensionsPair& s1, const DimensionsPair& s2) {
    639     if (LessThan(s1.dimInWhat, s2.dimInWhat)) {
    640         return true;
    641     } else if (LessThan(s2.dimInWhat, s1.dimInWhat)) {
    642         return false;
    643     }
    644 
    645     return LessThan(s1.dimInCondition, s2.dimInCondition);
    646 }
    647 
    648 void backfillStringInDimension(const std::map<uint64_t, string>& str_map,
    649                                DimensionsValue* dimension) {
    650     if (dimension->has_value_str_hash()) {
    651         auto it = str_map.find((uint64_t)(dimension->value_str_hash()));
    652         if (it != str_map.end()) {
    653             dimension->clear_value_str_hash();
    654             dimension->set_value_str(it->second);
    655         } else {
    656             ALOGE("Can not find the string hash: %llu",
    657                 (unsigned long long)dimension->value_str_hash());
    658         }
    659     } else if (dimension->has_value_tuple()) {
    660         auto value_tuple = dimension->mutable_value_tuple();
    661         for (int i = 0; i < value_tuple->dimensions_value_size(); ++i) {
    662             backfillStringInDimension(str_map, value_tuple->mutable_dimensions_value(i));
    663         }
    664     }
    665 }
    666 
    667 void backfillStringInReport(ConfigMetricsReport *config_report) {
    668     std::map<uint64_t, string> str_map;
    669     for (const auto& str : config_report->strings()) {
    670         uint64_t hash = Hash64(str);
    671         if (str_map.find(hash) != str_map.end()) {
    672             ALOGE("String hash conflicts: %s %s", str.c_str(), str_map[hash].c_str());
    673         }
    674         str_map[hash] = str;
    675     }
    676     for (int i = 0; i < config_report->metrics_size(); ++i) {
    677         auto metric_report = config_report->mutable_metrics(i);
    678         if (metric_report->has_count_metrics()) {
    679             backfillStringInDimension(str_map, metric_report->mutable_count_metrics());
    680         } else if (metric_report->has_duration_metrics()) {
    681             backfillStringInDimension(str_map, metric_report->mutable_duration_metrics());
    682         } else if (metric_report->has_gauge_metrics()) {
    683             backfillStringInDimension(str_map, metric_report->mutable_gauge_metrics());
    684         } else if (metric_report->has_value_metrics()) {
    685             backfillStringInDimension(str_map, metric_report->mutable_value_metrics());
    686         }
    687     }
    688     // Backfill the package names.
    689     for (int i = 0 ; i < config_report->uid_map().snapshots_size(); ++i) {
    690         auto snapshot = config_report->mutable_uid_map()->mutable_snapshots(i);
    691         for (int j = 0 ; j < snapshot->package_info_size(); ++j) {
    692             auto package_info = snapshot->mutable_package_info(j);
    693             if (package_info->has_name_hash()) {
    694                 auto it = str_map.find((uint64_t)(package_info->name_hash()));
    695                 if (it != str_map.end()) {
    696                     package_info->clear_name_hash();
    697                     package_info->set_name(it->second);
    698                 } else {
    699                     ALOGE("Can not find the string package name hash: %llu",
    700                         (unsigned long long)package_info->name_hash());
    701                 }
    702 
    703             }
    704         }
    705     }
    706     // Backfill the app name in app changes.
    707     for (int i = 0 ; i < config_report->uid_map().changes_size(); ++i) {
    708         auto change = config_report->mutable_uid_map()->mutable_changes(i);
    709         if (change->has_app_hash()) {
    710             auto it = str_map.find((uint64_t)(change->app_hash()));
    711             if (it != str_map.end()) {
    712                 change->clear_app_hash();
    713                 change->set_app(it->second);
    714             } else {
    715                 ALOGE("Can not find the string change app name hash: %llu",
    716                     (unsigned long long)change->app_hash());
    717             }
    718         }
    719     }
    720 }
    721 
    722 void backfillStringInReport(ConfigMetricsReportList *config_report_list) {
    723     for (int i = 0; i < config_report_list->reports_size(); ++i) {
    724         backfillStringInReport(config_report_list->mutable_reports(i));
    725     }
    726 }
    727 
    728 bool backfillDimensionPath(const DimensionsValue& path,
    729                            const google::protobuf::RepeatedPtrField<DimensionsValue>& leafValues,
    730                            int* leafIndex,
    731                            DimensionsValue* dimension) {
    732     dimension->set_field(path.field());
    733     if (path.has_value_tuple()) {
    734         for (int i = 0; i < path.value_tuple().dimensions_value_size(); ++i) {
    735             if (!backfillDimensionPath(
    736                 path.value_tuple().dimensions_value(i), leafValues, leafIndex,
    737                 dimension->mutable_value_tuple()->add_dimensions_value())) {
    738                 return false;
    739             }
    740         }
    741     } else {
    742         if (*leafIndex < 0 || *leafIndex >= leafValues.size()) {
    743             return false;
    744         }
    745         dimension->MergeFrom(leafValues.Get(*leafIndex));
    746         (*leafIndex)++;
    747     }
    748     return true;
    749 }
    750 
    751 bool backfillDimensionPath(const DimensionsValue& path,
    752                            const google::protobuf::RepeatedPtrField<DimensionsValue>& leafValues,
    753                            DimensionsValue* dimension) {
    754     int leafIndex = 0;
    755     return backfillDimensionPath(path, leafValues, &leafIndex, dimension);
    756 }
    757 
    758 void backfillDimensionPath(ConfigMetricsReportList *config_report_list) {
    759     for (int i = 0; i < config_report_list->reports_size(); ++i) {
    760         auto report = config_report_list->mutable_reports(i);
    761         for (int j = 0; j < report->metrics_size(); ++j) {
    762             auto metric_report = report->mutable_metrics(j);
    763             if (metric_report->has_dimensions_path_in_what() ||
    764                 metric_report->has_dimensions_path_in_condition()) {
    765                 auto whatPath = metric_report->dimensions_path_in_what();
    766                 auto conditionPath = metric_report->dimensions_path_in_condition();
    767                 if (metric_report->has_count_metrics()) {
    768                     backfillDimensionPath(whatPath, conditionPath,
    769                                           metric_report->mutable_count_metrics());
    770                 } else if (metric_report->has_duration_metrics()) {
    771                     backfillDimensionPath(whatPath, conditionPath,
    772                                           metric_report->mutable_duration_metrics());
    773                 } else if (metric_report->has_gauge_metrics()) {
    774                     backfillDimensionPath(whatPath, conditionPath,
    775                                           metric_report->mutable_gauge_metrics());
    776                 } else if (metric_report->has_value_metrics()) {
    777                     backfillDimensionPath(whatPath, conditionPath,
    778                                           metric_report->mutable_value_metrics());
    779                 }
    780                 metric_report->clear_dimensions_path_in_what();
    781                 metric_report->clear_dimensions_path_in_condition();
    782             }
    783         }
    784     }
    785 }
    786 
    787 void backfillStartEndTimestamp(StatsLogReport *report) {
    788     const int64_t timeBaseNs = report->time_base_elapsed_nano_seconds();
    789     const int64_t bucketSizeNs = report->bucket_size_nano_seconds();
    790     if (report->has_count_metrics()) {
    791         backfillStartEndTimestampForMetrics(
    792             timeBaseNs, bucketSizeNs, report->mutable_count_metrics());
    793     } else if (report->has_duration_metrics()) {
    794         backfillStartEndTimestampForMetrics(
    795             timeBaseNs, bucketSizeNs, report->mutable_duration_metrics());
    796     } else if (report->has_gauge_metrics()) {
    797         backfillStartEndTimestampForMetrics(
    798             timeBaseNs, bucketSizeNs, report->mutable_gauge_metrics());
    799         if (report->gauge_metrics().skipped_size() > 0) {
    800             backfillStartEndTimestampForSkippedBuckets(
    801                 timeBaseNs, report->mutable_gauge_metrics());
    802         }
    803     } else if (report->has_value_metrics()) {
    804         backfillStartEndTimestampForMetrics(
    805             timeBaseNs, bucketSizeNs, report->mutable_value_metrics());
    806         if (report->value_metrics().skipped_size() > 0) {
    807             backfillStartEndTimestampForSkippedBuckets(
    808                 timeBaseNs, report->mutable_value_metrics());
    809         }
    810     }
    811 }
    812 
    813 void backfillStartEndTimestamp(ConfigMetricsReport *config_report) {
    814     for (int j = 0; j < config_report->metrics_size(); ++j) {
    815         backfillStartEndTimestamp(config_report->mutable_metrics(j));
    816     }
    817 }
    818 
    819 void backfillStartEndTimestamp(ConfigMetricsReportList *config_report_list) {
    820     for (int i = 0; i < config_report_list->reports_size(); ++i) {
    821         backfillStartEndTimestamp(config_report_list->mutable_reports(i));
    822     }
    823 }
    824 
    825 }  // namespace statsd
    826 }  // namespace os
    827 }  // namespace android