1 /* 2 * Copyright (C) 2016 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 LOG_NDEBUG 0 18 19 #define LOG_TAG "CamComm1.0-MD" 20 #include <log/log.h> 21 #include <utils/Errors.h> 22 23 #include "CameraMetadata.h" 24 #include "VendorTagDescriptor.h" 25 26 namespace android { 27 namespace hardware { 28 namespace camera { 29 namespace common { 30 namespace V1_0 { 31 namespace helper { 32 33 #define ALIGN_TO(val, alignment) \ 34 (((uintptr_t)(val) + ((alignment) - 1)) & ~((alignment) - 1)) 35 36 CameraMetadata::CameraMetadata() : 37 mBuffer(NULL), mLocked(false) { 38 } 39 40 CameraMetadata::CameraMetadata(size_t entryCapacity, size_t dataCapacity) : 41 mLocked(false) 42 { 43 mBuffer = allocate_camera_metadata(entryCapacity, dataCapacity); 44 } 45 46 CameraMetadata::CameraMetadata(const CameraMetadata &other) : 47 mLocked(false) { 48 mBuffer = clone_camera_metadata(other.mBuffer); 49 } 50 51 CameraMetadata::CameraMetadata(camera_metadata_t *buffer) : 52 mBuffer(NULL), mLocked(false) { 53 acquire(buffer); 54 } 55 56 CameraMetadata &CameraMetadata::operator=(const CameraMetadata &other) { 57 return operator=(other.mBuffer); 58 } 59 60 CameraMetadata &CameraMetadata::operator=(const camera_metadata_t *buffer) { 61 if (mLocked) { 62 ALOGE("%s: Assignment to a locked CameraMetadata!", __FUNCTION__); 63 return *this; 64 } 65 66 if (CC_LIKELY(buffer != mBuffer)) { 67 camera_metadata_t *newBuffer = clone_camera_metadata(buffer); 68 clear(); 69 mBuffer = newBuffer; 70 } 71 return *this; 72 } 73 74 CameraMetadata::~CameraMetadata() { 75 mLocked = false; 76 clear(); 77 } 78 79 const camera_metadata_t* CameraMetadata::getAndLock() const { 80 mLocked = true; 81 return mBuffer; 82 } 83 84 status_t CameraMetadata::unlock(const camera_metadata_t *buffer) const { 85 if (!mLocked) { 86 ALOGE("%s: Can't unlock a non-locked CameraMetadata!", __FUNCTION__); 87 return INVALID_OPERATION; 88 } 89 if (buffer != mBuffer) { 90 ALOGE("%s: Can't unlock CameraMetadata with wrong pointer!", 91 __FUNCTION__); 92 return BAD_VALUE; 93 } 94 mLocked = false; 95 return OK; 96 } 97 98 camera_metadata_t* CameraMetadata::release() { 99 if (mLocked) { 100 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 101 return NULL; 102 } 103 camera_metadata_t *released = mBuffer; 104 mBuffer = NULL; 105 return released; 106 } 107 108 void CameraMetadata::clear() { 109 if (mLocked) { 110 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 111 return; 112 } 113 if (mBuffer) { 114 free_camera_metadata(mBuffer); 115 mBuffer = NULL; 116 } 117 } 118 119 void CameraMetadata::acquire(camera_metadata_t *buffer) { 120 if (mLocked) { 121 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 122 return; 123 } 124 clear(); 125 mBuffer = buffer; 126 127 ALOGE_IF(validate_camera_metadata_structure(mBuffer, /*size*/NULL) != OK, 128 "%s: Failed to validate metadata structure %p", 129 __FUNCTION__, buffer); 130 } 131 132 void CameraMetadata::acquire(CameraMetadata &other) { 133 if (mLocked) { 134 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 135 return; 136 } 137 acquire(other.release()); 138 } 139 140 status_t CameraMetadata::append(const CameraMetadata &other) { 141 return append(other.mBuffer); 142 } 143 144 status_t CameraMetadata::append(const camera_metadata_t* other) { 145 if (mLocked) { 146 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 147 return INVALID_OPERATION; 148 } 149 size_t extraEntries = get_camera_metadata_entry_count(other); 150 size_t extraData = get_camera_metadata_data_count(other); 151 resizeIfNeeded(extraEntries, extraData); 152 153 return append_camera_metadata(mBuffer, other); 154 } 155 156 size_t CameraMetadata::entryCount() const { 157 return (mBuffer == NULL) ? 0 : 158 get_camera_metadata_entry_count(mBuffer); 159 } 160 161 bool CameraMetadata::isEmpty() const { 162 return entryCount() == 0; 163 } 164 165 status_t CameraMetadata::sort() { 166 if (mLocked) { 167 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 168 return INVALID_OPERATION; 169 } 170 return sort_camera_metadata(mBuffer); 171 } 172 173 status_t CameraMetadata::checkType(uint32_t tag, uint8_t expectedType) { 174 int tagType = get_camera_metadata_tag_type(tag); 175 if ( CC_UNLIKELY(tagType == -1)) { 176 ALOGE("Update metadata entry: Unknown tag %d", tag); 177 return INVALID_OPERATION; 178 } 179 if ( CC_UNLIKELY(tagType != expectedType) ) { 180 ALOGE("Mismatched tag type when updating entry %s (%d) of type %s; " 181 "got type %s data instead ", 182 get_camera_metadata_tag_name(tag), tag, 183 camera_metadata_type_names[tagType], 184 camera_metadata_type_names[expectedType]); 185 return INVALID_OPERATION; 186 } 187 return OK; 188 } 189 190 status_t CameraMetadata::update(uint32_t tag, 191 const int32_t *data, size_t data_count) { 192 status_t res; 193 if (mLocked) { 194 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 195 return INVALID_OPERATION; 196 } 197 if ( (res = checkType(tag, TYPE_INT32)) != OK) { 198 return res; 199 } 200 return updateImpl(tag, (const void*)data, data_count); 201 } 202 203 status_t CameraMetadata::update(uint32_t tag, 204 const uint8_t *data, size_t data_count) { 205 status_t res; 206 if (mLocked) { 207 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 208 return INVALID_OPERATION; 209 } 210 if ( (res = checkType(tag, TYPE_BYTE)) != OK) { 211 return res; 212 } 213 return updateImpl(tag, (const void*)data, data_count); 214 } 215 216 status_t CameraMetadata::update(uint32_t tag, 217 const float *data, size_t data_count) { 218 status_t res; 219 if (mLocked) { 220 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 221 return INVALID_OPERATION; 222 } 223 if ( (res = checkType(tag, TYPE_FLOAT)) != OK) { 224 return res; 225 } 226 return updateImpl(tag, (const void*)data, data_count); 227 } 228 229 status_t CameraMetadata::update(uint32_t tag, 230 const int64_t *data, size_t data_count) { 231 status_t res; 232 if (mLocked) { 233 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 234 return INVALID_OPERATION; 235 } 236 if ( (res = checkType(tag, TYPE_INT64)) != OK) { 237 return res; 238 } 239 return updateImpl(tag, (const void*)data, data_count); 240 } 241 242 status_t CameraMetadata::update(uint32_t tag, 243 const double *data, size_t data_count) { 244 status_t res; 245 if (mLocked) { 246 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 247 return INVALID_OPERATION; 248 } 249 if ( (res = checkType(tag, TYPE_DOUBLE)) != OK) { 250 return res; 251 } 252 return updateImpl(tag, (const void*)data, data_count); 253 } 254 255 status_t CameraMetadata::update(uint32_t tag, 256 const camera_metadata_rational_t *data, size_t data_count) { 257 status_t res; 258 if (mLocked) { 259 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 260 return INVALID_OPERATION; 261 } 262 if ( (res = checkType(tag, TYPE_RATIONAL)) != OK) { 263 return res; 264 } 265 return updateImpl(tag, (const void*)data, data_count); 266 } 267 268 status_t CameraMetadata::update(uint32_t tag, 269 const String8 &string) { 270 status_t res; 271 if (mLocked) { 272 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 273 return INVALID_OPERATION; 274 } 275 if ( (res = checkType(tag, TYPE_BYTE)) != OK) { 276 return res; 277 } 278 // string.size() doesn't count the null termination character. 279 return updateImpl(tag, (const void*)string.string(), string.size() + 1); 280 } 281 282 status_t CameraMetadata::update(const camera_metadata_ro_entry &entry) { 283 status_t res; 284 if (mLocked) { 285 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 286 return INVALID_OPERATION; 287 } 288 if ( (res = checkType(entry.tag, entry.type)) != OK) { 289 return res; 290 } 291 return updateImpl(entry.tag, (const void*)entry.data.u8, entry.count); 292 } 293 294 status_t CameraMetadata::updateImpl(uint32_t tag, const void *data, 295 size_t data_count) { 296 status_t res; 297 if (mLocked) { 298 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 299 return INVALID_OPERATION; 300 } 301 int type = get_camera_metadata_tag_type(tag); 302 if (type == -1) { 303 ALOGE("%s: Tag %d not found", __FUNCTION__, tag); 304 return BAD_VALUE; 305 } 306 // Safety check - ensure that data isn't pointing to this metadata, since 307 // that would get invalidated if a resize is needed 308 size_t bufferSize = get_camera_metadata_size(mBuffer); 309 uintptr_t bufAddr = reinterpret_cast<uintptr_t>(mBuffer); 310 uintptr_t dataAddr = reinterpret_cast<uintptr_t>(data); 311 if (dataAddr > bufAddr && dataAddr < (bufAddr + bufferSize)) { 312 ALOGE("%s: Update attempted with data from the same metadata buffer!", 313 __FUNCTION__); 314 return INVALID_OPERATION; 315 } 316 317 size_t data_size = calculate_camera_metadata_entry_data_size(type, 318 data_count); 319 320 res = resizeIfNeeded(1, data_size); 321 322 if (res == OK) { 323 camera_metadata_entry_t entry; 324 res = find_camera_metadata_entry(mBuffer, tag, &entry); 325 if (res == NAME_NOT_FOUND) { 326 res = add_camera_metadata_entry(mBuffer, 327 tag, data, data_count); 328 } else if (res == OK) { 329 res = update_camera_metadata_entry(mBuffer, 330 entry.index, data, data_count, NULL); 331 } 332 } 333 334 if (res != OK) { 335 ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)", 336 __FUNCTION__, get_camera_metadata_section_name(tag), 337 get_camera_metadata_tag_name(tag), tag, strerror(-res), res); 338 } 339 340 IF_ALOGV() { 341 ALOGE_IF(validate_camera_metadata_structure(mBuffer, /*size*/NULL) != 342 OK, 343 344 "%s: Failed to validate metadata structure after update %p", 345 __FUNCTION__, mBuffer); 346 } 347 348 return res; 349 } 350 351 bool CameraMetadata::exists(uint32_t tag) const { 352 camera_metadata_ro_entry entry; 353 return find_camera_metadata_ro_entry(mBuffer, tag, &entry) == 0; 354 } 355 356 camera_metadata_entry_t CameraMetadata::find(uint32_t tag) { 357 status_t res; 358 camera_metadata_entry entry; 359 if (mLocked) { 360 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 361 entry.count = 0; 362 return entry; 363 } 364 res = find_camera_metadata_entry(mBuffer, tag, &entry); 365 if (CC_UNLIKELY( res != OK )) { 366 entry.count = 0; 367 entry.data.u8 = NULL; 368 } 369 return entry; 370 } 371 372 camera_metadata_ro_entry_t CameraMetadata::find(uint32_t tag) const { 373 status_t res; 374 camera_metadata_ro_entry entry; 375 res = find_camera_metadata_ro_entry(mBuffer, tag, &entry); 376 if (CC_UNLIKELY( res != OK )) { 377 entry.count = 0; 378 entry.data.u8 = NULL; 379 } 380 return entry; 381 } 382 383 status_t CameraMetadata::erase(uint32_t tag) { 384 camera_metadata_entry_t entry; 385 status_t res; 386 if (mLocked) { 387 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 388 return INVALID_OPERATION; 389 } 390 res = find_camera_metadata_entry(mBuffer, tag, &entry); 391 if (res == NAME_NOT_FOUND) { 392 return OK; 393 } else if (res != OK) { 394 ALOGE("%s: Error looking for entry %s.%s (%x): %s %d", 395 __FUNCTION__, 396 get_camera_metadata_section_name(tag), 397 get_camera_metadata_tag_name(tag), tag, strerror(-res), res); 398 return res; 399 } 400 res = delete_camera_metadata_entry(mBuffer, entry.index); 401 if (res != OK) { 402 ALOGE("%s: Error deleting entry %s.%s (%x): %s %d", 403 __FUNCTION__, 404 get_camera_metadata_section_name(tag), 405 get_camera_metadata_tag_name(tag), tag, strerror(-res), res); 406 } 407 return res; 408 } 409 410 void CameraMetadata::dump(int fd, int verbosity, int indentation) const { 411 dump_indented_camera_metadata(mBuffer, fd, verbosity, indentation); 412 } 413 414 status_t CameraMetadata::resizeIfNeeded(size_t extraEntries, size_t extraData) { 415 if (mBuffer == NULL) { 416 mBuffer = allocate_camera_metadata(extraEntries * 2, extraData * 2); 417 if (mBuffer == NULL) { 418 ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__); 419 return NO_MEMORY; 420 } 421 } else { 422 size_t currentEntryCount = get_camera_metadata_entry_count(mBuffer); 423 size_t currentEntryCap = get_camera_metadata_entry_capacity(mBuffer); 424 size_t newEntryCount = currentEntryCount + 425 extraEntries; 426 newEntryCount = (newEntryCount > currentEntryCap) ? 427 newEntryCount * 2 : currentEntryCap; 428 429 size_t currentDataCount = get_camera_metadata_data_count(mBuffer); 430 size_t currentDataCap = get_camera_metadata_data_capacity(mBuffer); 431 size_t newDataCount = currentDataCount + 432 extraData; 433 newDataCount = (newDataCount > currentDataCap) ? 434 newDataCount * 2 : currentDataCap; 435 436 if (newEntryCount > currentEntryCap || 437 newDataCount > currentDataCap) { 438 camera_metadata_t *oldBuffer = mBuffer; 439 mBuffer = allocate_camera_metadata(newEntryCount, 440 newDataCount); 441 if (mBuffer == NULL) { 442 ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__); 443 return NO_MEMORY; 444 } 445 append_camera_metadata(mBuffer, oldBuffer); 446 free_camera_metadata(oldBuffer); 447 } 448 } 449 return OK; 450 } 451 452 void CameraMetadata::swap(CameraMetadata& other) { 453 if (mLocked) { 454 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 455 return; 456 } else if (other.mLocked) { 457 ALOGE("%s: Other CameraMetadata is locked", __FUNCTION__); 458 return; 459 } 460 461 camera_metadata* thisBuf = mBuffer; 462 camera_metadata* otherBuf = other.mBuffer; 463 464 other.mBuffer = thisBuf; 465 mBuffer = otherBuf; 466 } 467 468 status_t CameraMetadata::getTagFromName(const char *name, 469 const VendorTagDescriptor* vTags, uint32_t *tag) { 470 471 if (name == nullptr || tag == nullptr) return BAD_VALUE; 472 473 size_t nameLength = strlen(name); 474 475 const SortedVector<String8> *vendorSections; 476 size_t vendorSectionCount = 0; 477 478 if (vTags != NULL) { 479 vendorSections = vTags->getAllSectionNames(); 480 vendorSectionCount = vendorSections->size(); 481 } 482 483 // First, find the section by the longest string match 484 const char *section = NULL; 485 size_t sectionIndex = 0; 486 size_t sectionLength = 0; 487 size_t totalSectionCount = ANDROID_SECTION_COUNT + vendorSectionCount; 488 for (size_t i = 0; i < totalSectionCount; ++i) { 489 490 const char *str = (i < ANDROID_SECTION_COUNT) ? camera_metadata_section_names[i] : 491 (*vendorSections)[i - ANDROID_SECTION_COUNT].string(); 492 493 ALOGV("%s: Trying to match against section '%s'", __FUNCTION__, str); 494 495 if (strstr(name, str) == name) { // name begins with the section name 496 size_t strLength = strlen(str); 497 498 ALOGV("%s: Name begins with section name", __FUNCTION__); 499 500 // section name is the longest we've found so far 501 if (section == NULL || sectionLength < strLength) { 502 section = str; 503 sectionIndex = i; 504 sectionLength = strLength; 505 506 ALOGV("%s: Found new best section (%s)", __FUNCTION__, section); 507 } 508 } 509 } 510 511 if (section == NULL) { 512 return NAME_NOT_FOUND; 513 } else { 514 ALOGV("%s: Found matched section '%s' (%zu)", 515 __FUNCTION__, section, sectionIndex); 516 } 517 518 // Get the tag name component of the name 519 const char *nameTagName = name + sectionLength + 1; // x.y.z -> z 520 if (sectionLength + 1 >= nameLength) { 521 return BAD_VALUE; 522 } 523 524 // Match rest of name against the tag names in that section only 525 uint32_t candidateTag = 0; 526 if (sectionIndex < ANDROID_SECTION_COUNT) { 527 // Match built-in tags (typically android.*) 528 uint32_t tagBegin, tagEnd; // [tagBegin, tagEnd) 529 tagBegin = camera_metadata_section_bounds[sectionIndex][0]; 530 tagEnd = camera_metadata_section_bounds[sectionIndex][1]; 531 532 for (candidateTag = tagBegin; candidateTag < tagEnd; ++candidateTag) { 533 const char *tagName = get_camera_metadata_tag_name(candidateTag); 534 535 if (strcmp(nameTagName, tagName) == 0) { 536 ALOGV("%s: Found matched tag '%s' (%d)", 537 __FUNCTION__, tagName, candidateTag); 538 break; 539 } 540 } 541 542 if (candidateTag == tagEnd) { 543 return NAME_NOT_FOUND; 544 } 545 } else if (vTags != NULL) { 546 // Match vendor tags (typically com.*) 547 const String8 sectionName(section); 548 const String8 tagName(nameTagName); 549 550 status_t res = OK; 551 if ((res = vTags->lookupTag(tagName, sectionName, &candidateTag)) != OK) { 552 return NAME_NOT_FOUND; 553 } 554 } 555 556 *tag = candidateTag; 557 return OK; 558 } 559 560 561 } // namespace helper 562 } // namespace V1_0 563 } // namespace common 564 } // namespace camera 565 } // namespace hardware 566 } // namespace android 567