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