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 
     22 namespace android {
     23 namespace os {
     24 namespace statsd {
     25 
     26 int32_t getEncodedField(int32_t pos[], int32_t depth, bool includeDepth) {
     27     int32_t field = 0;
     28     for (int32_t i = 0; i <= depth; i++) {
     29         int32_t shiftBits = 8 * (kMaxLogDepth - i);
     30         field |= (pos[i] << shiftBits);
     31     }
     32 
     33     if (includeDepth) {
     34         field |= (depth << 24);
     35     }
     36     return field;
     37 }
     38 
     39 int32_t encodeMatcherMask(int32_t mask[], int32_t depth) {
     40     return getEncodedField(mask, depth, false) | 0xff000000;
     41 }
     42 
     43 bool Field::matches(const Matcher& matcher) const {
     44     if (mTag != matcher.mMatcher.getTag()) {
     45         return false;
     46     }
     47     if ((mField & matcher.mMask) == matcher.mMatcher.getField()) {
     48         return true;
     49     }
     50 
     51     if (matcher.hasAllPositionMatcher() &&
     52         (mField & (matcher.mMask & kClearAllPositionMatcherMask)) == matcher.mMatcher.getField()) {
     53         return true;
     54     }
     55 
     56     return false;
     57 }
     58 
     59 void translateFieldMatcher(int tag, const FieldMatcher& matcher, int depth, int* pos, int* mask,
     60                            std::vector<Matcher>* output) {
     61     if (depth > kMaxLogDepth) {
     62         ALOGE("depth > 2");
     63         return;
     64     }
     65 
     66     pos[depth] = matcher.field();
     67     mask[depth] = 0x7f;
     68 
     69     if (matcher.has_position()) {
     70         depth++;
     71         if (depth > 2) {
     72             return;
     73         }
     74         switch (matcher.position()) {
     75             case Position::ALL:
     76                 pos[depth] = 0x00;
     77                 mask[depth] = 0x7f;
     78                 break;
     79             case Position::ANY:
     80                 pos[depth] = 0;
     81                 mask[depth] = 0;
     82                 break;
     83             case Position::FIRST:
     84                 pos[depth] = 1;
     85                 mask[depth] = 0x7f;
     86                 break;
     87             case Position::LAST:
     88                 pos[depth] = 0x80;
     89                 mask[depth] = 0x80;
     90                 break;
     91             case Position::POSITION_UNKNOWN:
     92                 pos[depth] = 0;
     93                 mask[depth] = 0;
     94                 break;
     95         }
     96     }
     97 
     98     if (matcher.child_size() == 0) {
     99         output->push_back(Matcher(Field(tag, pos, depth), encodeMatcherMask(mask, depth)));
    100     } else {
    101         for (const auto& child : matcher.child()) {
    102             translateFieldMatcher(tag, child, depth + 1, pos, mask, output);
    103         }
    104     }
    105 }
    106 
    107 void translateFieldMatcher(const FieldMatcher& matcher, std::vector<Matcher>* output) {
    108     int pos[] = {1, 1, 1};
    109     int mask[] = {0x7f, 0x7f, 0x7f};
    110     int tag = matcher.field();
    111     for (const auto& child : matcher.child()) {
    112         translateFieldMatcher(tag, child, 0, pos, mask, output);
    113     }
    114 }
    115 
    116 bool isAttributionUidField(const FieldValue& value) {
    117     int field = value.mField.getField() & 0xff007f;
    118     if (field == 0x10001 && value.mValue.getType() == INT) {
    119         return true;
    120     }
    121     return false;
    122 }
    123 
    124 bool isAttributionUidField(const Field& field, const Value& value) {
    125     int f = field.getField() & 0xff007f;
    126     if (f == 0x10001 && value.getType() == INT) {
    127         return true;
    128     }
    129     return false;
    130 }
    131 
    132 Value::Value(const Value& from) {
    133     type = from.getType();
    134     switch (type) {
    135         case INT:
    136             int_value = from.int_value;
    137             break;
    138         case LONG:
    139             long_value = from.long_value;
    140             break;
    141         case FLOAT:
    142             float_value = from.float_value;
    143             break;
    144         case STRING:
    145             str_value = from.str_value;
    146             break;
    147         default:
    148             break;
    149     }
    150 }
    151 
    152 std::string Value::toString() const {
    153     switch (type) {
    154         case INT:
    155             return std::to_string(int_value) + "[I]";
    156         case LONG:
    157             return std::to_string(long_value) + "[L]";
    158         case FLOAT:
    159             return std::to_string(float_value) + "[F]";
    160         case STRING:
    161             return str_value + "[S]";
    162         default:
    163             return "[UNKNOWN]";
    164     }
    165 }
    166 
    167 bool Value::operator==(const Value& that) const {
    168     if (type != that.getType()) return false;
    169 
    170     switch (type) {
    171         case INT:
    172             return int_value == that.int_value;
    173         case LONG:
    174             return long_value == that.long_value;
    175         case FLOAT:
    176             return float_value == that.float_value;
    177         case STRING:
    178             return str_value == that.str_value;
    179         default:
    180             return false;
    181     }
    182 }
    183 
    184 bool Value::operator!=(const Value& that) const {
    185     if (type != that.getType()) return true;
    186     switch (type) {
    187         case INT:
    188             return int_value != that.int_value;
    189         case LONG:
    190             return long_value != that.long_value;
    191         case FLOAT:
    192             return float_value != that.float_value;
    193         case STRING:
    194             return str_value != that.str_value;
    195         default:
    196             return false;
    197     }
    198 }
    199 
    200 bool Value::operator<(const Value& that) const {
    201     if (type != that.getType()) return type < that.getType();
    202 
    203     switch (type) {
    204         case INT:
    205             return int_value < that.int_value;
    206         case LONG:
    207             return long_value < that.long_value;
    208         case FLOAT:
    209             return float_value < that.float_value;
    210         case STRING:
    211             return str_value < that.str_value;
    212         default:
    213             return false;
    214     }
    215 }
    216 
    217 bool equalDimensions(const std::vector<Matcher>& dimension_a,
    218                      const std::vector<Matcher>& dimension_b) {
    219     bool eq = dimension_a.size() == dimension_b.size();
    220     for (size_t i = 0; eq && i < dimension_a.size(); ++i) {
    221         if (dimension_b[i] != dimension_a[i]) {
    222             eq = false;
    223         }
    224     }
    225     return eq;
    226 }
    227 
    228 bool HasPositionANY(const FieldMatcher& matcher) {
    229     if (matcher.has_position() && matcher.position() == Position::ANY) {
    230         return true;
    231     }
    232     for (const auto& child : matcher.child()) {
    233         if (HasPositionANY(child)) {
    234             return true;
    235         }
    236     }
    237     return false;
    238 }
    239 
    240 bool HasPositionALL(const FieldMatcher& matcher) {
    241     if (matcher.has_position() && matcher.position() == Position::ALL) {
    242         return true;
    243     }
    244     for (const auto& child : matcher.child()) {
    245         if (HasPositionALL(child)) {
    246             return true;
    247         }
    248     }
    249     return false;
    250 }
    251 
    252 }  // namespace statsd
    253 }  // namespace os
    254 }  // namespace android