Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2018 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #define DEBUG false
     18 #include "Log.h"
     19 #include "FieldValue.h"
     20 #include "HashableDimensionKey.h"
     21 #include "math.h"
     22 #include "statslog.h"
     23 
     24 namespace android {
     25 namespace os {
     26 namespace statsd {
     27 
     28 int32_t getEncodedField(int32_t pos[], int32_t depth, bool includeDepth) {
     29     int32_t field = 0;
     30     for (int32_t i = 0; i <= depth; i++) {
     31         int32_t shiftBits = 8 * (kMaxLogDepth - i);
     32         field |= (pos[i] << shiftBits);
     33     }
     34 
     35     if (includeDepth) {
     36         field |= (depth << 24);
     37     }
     38     return field;
     39 }
     40 
     41 int32_t encodeMatcherMask(int32_t mask[], int32_t depth) {
     42     return getEncodedField(mask, depth, false) | 0xff000000;
     43 }
     44 
     45 bool Field::matches(const Matcher& matcher) const {
     46     if (mTag != matcher.mMatcher.getTag()) {
     47         return false;
     48     }
     49     if ((mField & matcher.mMask) == matcher.mMatcher.getField()) {
     50         return true;
     51     }
     52 
     53     if (matcher.hasAllPositionMatcher() &&
     54         (mField & (matcher.mMask & kClearAllPositionMatcherMask)) == matcher.mMatcher.getField()) {
     55         return true;
     56     }
     57 
     58     return false;
     59 }
     60 
     61 void translateFieldMatcher(int tag, const FieldMatcher& matcher, int depth, int* pos, int* mask,
     62                            std::vector<Matcher>* output) {
     63     if (depth > kMaxLogDepth) {
     64         ALOGE("depth > 2");
     65         return;
     66     }
     67 
     68     pos[depth] = matcher.field();
     69     mask[depth] = 0x7f;
     70 
     71     if (matcher.has_position()) {
     72         depth++;
     73         if (depth > 2) {
     74             return;
     75         }
     76         switch (matcher.position()) {
     77             case Position::ALL:
     78                 pos[depth] = 0x00;
     79                 mask[depth] = 0x7f;
     80                 break;
     81             case Position::ANY:
     82                 pos[depth] = 0;
     83                 mask[depth] = 0;
     84                 break;
     85             case Position::FIRST:
     86                 pos[depth] = 1;
     87                 mask[depth] = 0x7f;
     88                 break;
     89             case Position::LAST:
     90                 pos[depth] = 0x80;
     91                 mask[depth] = 0x80;
     92                 break;
     93             case Position::POSITION_UNKNOWN:
     94                 pos[depth] = 0;
     95                 mask[depth] = 0;
     96                 break;
     97         }
     98     }
     99 
    100     if (matcher.child_size() == 0) {
    101         output->push_back(Matcher(Field(tag, pos, depth), encodeMatcherMask(mask, depth)));
    102     } else {
    103         for (const auto& child : matcher.child()) {
    104             translateFieldMatcher(tag, child, depth + 1, pos, mask, output);
    105         }
    106     }
    107 }
    108 
    109 void translateFieldMatcher(const FieldMatcher& matcher, std::vector<Matcher>* output) {
    110     int pos[] = {1, 1, 1};
    111     int mask[] = {0x7f, 0x7f, 0x7f};
    112     int tag = matcher.field();
    113     for (const auto& child : matcher.child()) {
    114         translateFieldMatcher(tag, child, 0, pos, mask, output);
    115     }
    116 }
    117 
    118 bool isAttributionUidField(const FieldValue& value) {
    119     int field = value.mField.getField() & 0xff007f;
    120     if (field == 0x10001 && value.mValue.getType() == INT) {
    121         return true;
    122     }
    123     return false;
    124 }
    125 
    126 int32_t getUidIfExists(const FieldValue& value) {
    127     bool isUid = false;
    128     // the field is uid field if the field is the uid field in attribution node or marked as
    129     // is_uid in atoms.proto
    130     if (isAttributionUidField(value)) {
    131         isUid = true;
    132     } else {
    133         auto it = android::util::AtomsInfo::kAtomsWithUidField.find(value.mField.getTag());
    134         if (it != android::util::AtomsInfo::kAtomsWithUidField.end()) {
    135             int uidField = it->second;  // uidField is the field number in proto
    136             isUid = value.mField.getDepth() == 0 && value.mField.getPosAtDepth(0) == uidField &&
    137                     value.mValue.getType() == INT;
    138         }
    139     }
    140 
    141     return isUid ? value.mValue.int_value : -1;
    142 }
    143 
    144 bool isAttributionUidField(const Field& field, const Value& value) {
    145     int f = field.getField() & 0xff007f;
    146     if (f == 0x10001 && value.getType() == INT) {
    147         return true;
    148     }
    149     return false;
    150 }
    151 
    152 Value::Value(const Value& from) {
    153     type = from.getType();
    154     switch (type) {
    155         case INT:
    156             int_value = from.int_value;
    157             break;
    158         case LONG:
    159             long_value = from.long_value;
    160             break;
    161         case FLOAT:
    162             float_value = from.float_value;
    163             break;
    164         case DOUBLE:
    165             double_value = from.double_value;
    166             break;
    167         case STRING:
    168             str_value = from.str_value;
    169             break;
    170         case STORAGE:
    171             storage_value = from.storage_value;
    172             break;
    173         default:
    174             break;
    175     }
    176 }
    177 
    178 std::string Value::toString() const {
    179     switch (type) {
    180         case INT:
    181             return std::to_string(int_value) + "[I]";
    182         case LONG:
    183             return std::to_string(long_value) + "[L]";
    184         case FLOAT:
    185             return std::to_string(float_value) + "[F]";
    186         case DOUBLE:
    187             return std::to_string(double_value) + "[D]";
    188         case STRING:
    189             return str_value + "[S]";
    190         case STORAGE:
    191             return "bytes of size " + std::to_string(storage_value.size()) + "[ST]";
    192         default:
    193             return "[UNKNOWN]";
    194     }
    195 }
    196 
    197 bool Value::isZero() const {
    198     switch (type) {
    199         case INT:
    200             return int_value == 0;
    201         case LONG:
    202             return long_value == 0;
    203         case FLOAT:
    204             return fabs(float_value) <= std::numeric_limits<float>::epsilon();
    205         case DOUBLE:
    206             return fabs(double_value) <= std::numeric_limits<double>::epsilon();
    207         case STRING:
    208             return str_value.size() == 0;
    209         case STORAGE:
    210             return storage_value.size() == 0;
    211         default:
    212             return false;
    213     }
    214 }
    215 
    216 bool Value::operator==(const Value& that) const {
    217     if (type != that.getType()) return false;
    218 
    219     switch (type) {
    220         case INT:
    221             return int_value == that.int_value;
    222         case LONG:
    223             return long_value == that.long_value;
    224         case FLOAT:
    225             return float_value == that.float_value;
    226         case DOUBLE:
    227             return double_value == that.double_value;
    228         case STRING:
    229             return str_value == that.str_value;
    230         case STORAGE:
    231             return storage_value == that.storage_value;
    232         default:
    233             return false;
    234     }
    235 }
    236 
    237 bool Value::operator!=(const Value& that) const {
    238     if (type != that.getType()) return true;
    239     switch (type) {
    240         case INT:
    241             return int_value != that.int_value;
    242         case LONG:
    243             return long_value != that.long_value;
    244         case FLOAT:
    245             return float_value != that.float_value;
    246         case DOUBLE:
    247             return double_value != that.double_value;
    248         case STRING:
    249             return str_value != that.str_value;
    250         case STORAGE:
    251             return storage_value != that.storage_value;
    252         default:
    253             return false;
    254     }
    255 }
    256 
    257 bool Value::operator<(const Value& that) const {
    258     if (type != that.getType()) return type < that.getType();
    259 
    260     switch (type) {
    261         case INT:
    262             return int_value < that.int_value;
    263         case LONG:
    264             return long_value < that.long_value;
    265         case FLOAT:
    266             return float_value < that.float_value;
    267         case DOUBLE:
    268             return double_value < that.double_value;
    269         case STRING:
    270             return str_value < that.str_value;
    271         case STORAGE:
    272             return storage_value < that.storage_value;
    273         default:
    274             return false;
    275     }
    276 }
    277 
    278 bool Value::operator>(const Value& that) const {
    279     if (type != that.getType()) return type > that.getType();
    280 
    281     switch (type) {
    282         case INT:
    283             return int_value > that.int_value;
    284         case LONG:
    285             return long_value > that.long_value;
    286         case FLOAT:
    287             return float_value > that.float_value;
    288         case DOUBLE:
    289             return double_value > that.double_value;
    290         case STRING:
    291             return str_value > that.str_value;
    292         case STORAGE:
    293             return storage_value > that.storage_value;
    294         default:
    295             return false;
    296     }
    297 }
    298 
    299 bool Value::operator>=(const Value& that) const {
    300     if (type != that.getType()) return type >= that.getType();
    301 
    302     switch (type) {
    303         case INT:
    304             return int_value >= that.int_value;
    305         case LONG:
    306             return long_value >= that.long_value;
    307         case FLOAT:
    308             return float_value >= that.float_value;
    309         case DOUBLE:
    310             return double_value >= that.double_value;
    311         case STRING:
    312             return str_value >= that.str_value;
    313         case STORAGE:
    314             return storage_value >= that.storage_value;
    315         default:
    316             return false;
    317     }
    318 }
    319 
    320 Value Value::operator-(const Value& that) const {
    321     Value v;
    322     if (type != that.type) {
    323         ALOGE("Can't operate on different value types, %d, %d", type, that.type);
    324         return v;
    325     }
    326     if (type == STRING) {
    327         ALOGE("Can't operate on string value type");
    328         return v;
    329     }
    330 
    331     if (type == STORAGE) {
    332         ALOGE("Can't operate on storage value type");
    333         return v;
    334     }
    335 
    336     switch (type) {
    337         case INT:
    338             v.setInt(int_value - that.int_value);
    339             break;
    340         case LONG:
    341             v.setLong(long_value - that.long_value);
    342             break;
    343         case FLOAT:
    344             v.setFloat(float_value - that.float_value);
    345             break;
    346         case DOUBLE:
    347             v.setDouble(double_value - that.double_value);
    348             break;
    349         default:
    350             break;
    351     }
    352     return v;
    353 }
    354 
    355 Value& Value::operator=(const Value& that) {
    356     type = that.type;
    357     switch (type) {
    358         case INT:
    359             int_value = that.int_value;
    360             break;
    361         case LONG:
    362             long_value = that.long_value;
    363             break;
    364         case FLOAT:
    365             float_value = that.float_value;
    366             break;
    367         case DOUBLE:
    368             double_value = that.double_value;
    369             break;
    370         case STRING:
    371             str_value = that.str_value;
    372             break;
    373         case STORAGE:
    374             storage_value = that.storage_value;
    375             break;
    376         default:
    377             break;
    378     }
    379     return *this;
    380 }
    381 
    382 Value& Value::operator+=(const Value& that) {
    383     if (type != that.type) {
    384         ALOGE("Can't operate on different value types, %d, %d", type, that.type);
    385         return *this;
    386     }
    387     if (type == STRING) {
    388         ALOGE("Can't operate on string value type");
    389         return *this;
    390     }
    391     if (type == STORAGE) {
    392         ALOGE("Can't operate on storage value type");
    393         return *this;
    394     }
    395 
    396     switch (type) {
    397         case INT:
    398             int_value += that.int_value;
    399             break;
    400         case LONG:
    401             long_value += that.long_value;
    402             break;
    403         case FLOAT:
    404             float_value += that.float_value;
    405             break;
    406         case DOUBLE:
    407             double_value += that.double_value;
    408             break;
    409         default:
    410             break;
    411     }
    412     return *this;
    413 }
    414 
    415 double Value::getDouble() const {
    416     switch (type) {
    417         case INT:
    418             return int_value;
    419         case LONG:
    420             return long_value;
    421         case FLOAT:
    422             return float_value;
    423         case DOUBLE:
    424             return double_value;
    425         default:
    426             return 0;
    427     }
    428 }
    429 
    430 bool equalDimensions(const std::vector<Matcher>& dimension_a,
    431                      const std::vector<Matcher>& dimension_b) {
    432     bool eq = dimension_a.size() == dimension_b.size();
    433     for (size_t i = 0; eq && i < dimension_a.size(); ++i) {
    434         if (dimension_b[i] != dimension_a[i]) {
    435             eq = false;
    436         }
    437     }
    438     return eq;
    439 }
    440 
    441 bool HasPositionANY(const FieldMatcher& matcher) {
    442     if (matcher.has_position() && matcher.position() == Position::ANY) {
    443         return true;
    444     }
    445     for (const auto& child : matcher.child()) {
    446         if (HasPositionANY(child)) {
    447             return true;
    448         }
    449     }
    450     return false;
    451 }
    452 
    453 bool HasPositionALL(const FieldMatcher& matcher) {
    454     if (matcher.has_position() && matcher.position() == Position::ALL) {
    455         return true;
    456     }
    457     for (const auto& child : matcher.child()) {
    458         if (HasPositionALL(child)) {
    459             return true;
    460         }
    461     }
    462     return false;
    463 }
    464 
    465 }  // namespace statsd
    466 }  // namespace os
    467 }  // namespace android