1 /* 2 * Copyright (C) 2012 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 "Camera2-Metadata" 20 #include <utils/Log.h> 21 #include <utils/Errors.h> 22 23 #include <camera/CameraMetadata.h> 24 #include <binder/Parcel.h> 25 26 namespace android { 27 28 typedef Parcel::WritableBlob WritableBlob; 29 typedef Parcel::ReadableBlob ReadableBlob; 30 31 CameraMetadata::CameraMetadata() : 32 mBuffer(NULL), mLocked(false) { 33 } 34 35 CameraMetadata::CameraMetadata(size_t entryCapacity, size_t dataCapacity) : 36 mLocked(false) 37 { 38 mBuffer = allocate_camera_metadata(entryCapacity, dataCapacity); 39 } 40 41 CameraMetadata::CameraMetadata(const CameraMetadata &other) : 42 mLocked(false) { 43 mBuffer = clone_camera_metadata(other.mBuffer); 44 } 45 46 CameraMetadata::CameraMetadata(camera_metadata_t *buffer) : 47 mBuffer(NULL), mLocked(false) { 48 acquire(buffer); 49 } 50 51 CameraMetadata &CameraMetadata::operator=(const CameraMetadata &other) { 52 return operator=(other.mBuffer); 53 } 54 55 CameraMetadata &CameraMetadata::operator=(const camera_metadata_t *buffer) { 56 if (mLocked) { 57 ALOGE("%s: Assignment to a locked CameraMetadata!", __FUNCTION__); 58 return *this; 59 } 60 61 if (CC_LIKELY(buffer != mBuffer)) { 62 camera_metadata_t *newBuffer = clone_camera_metadata(buffer); 63 clear(); 64 mBuffer = newBuffer; 65 } 66 return *this; 67 } 68 69 CameraMetadata::~CameraMetadata() { 70 mLocked = false; 71 clear(); 72 } 73 74 const camera_metadata_t* CameraMetadata::getAndLock() { 75 mLocked = true; 76 return mBuffer; 77 } 78 79 status_t CameraMetadata::unlock(const camera_metadata_t *buffer) { 80 if (!mLocked) { 81 ALOGE("%s: Can't unlock a non-locked CameraMetadata!", __FUNCTION__); 82 return INVALID_OPERATION; 83 } 84 if (buffer != mBuffer) { 85 ALOGE("%s: Can't unlock CameraMetadata with wrong pointer!", 86 __FUNCTION__); 87 return BAD_VALUE; 88 } 89 mLocked = false; 90 return OK; 91 } 92 93 camera_metadata_t* CameraMetadata::release() { 94 if (mLocked) { 95 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 96 return NULL; 97 } 98 camera_metadata_t *released = mBuffer; 99 mBuffer = NULL; 100 return released; 101 } 102 103 void CameraMetadata::clear() { 104 if (mLocked) { 105 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 106 return; 107 } 108 if (mBuffer) { 109 free_camera_metadata(mBuffer); 110 mBuffer = NULL; 111 } 112 } 113 114 void CameraMetadata::acquire(camera_metadata_t *buffer) { 115 if (mLocked) { 116 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 117 return; 118 } 119 clear(); 120 mBuffer = buffer; 121 122 ALOGE_IF(validate_camera_metadata_structure(mBuffer, /*size*/NULL) != OK, 123 "%s: Failed to validate metadata structure %p", 124 __FUNCTION__, buffer); 125 } 126 127 void CameraMetadata::acquire(CameraMetadata &other) { 128 if (mLocked) { 129 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 130 return; 131 } 132 acquire(other.release()); 133 } 134 135 status_t CameraMetadata::append(const CameraMetadata &other) { 136 return append(other.mBuffer); 137 } 138 139 status_t CameraMetadata::append(const camera_metadata_t* other) { 140 if (mLocked) { 141 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 142 return INVALID_OPERATION; 143 } 144 size_t extraEntries = get_camera_metadata_entry_count(other); 145 size_t extraData = get_camera_metadata_data_count(other); 146 resizeIfNeeded(extraEntries, extraData); 147 148 return append_camera_metadata(mBuffer, other); 149 } 150 151 size_t CameraMetadata::entryCount() const { 152 return (mBuffer == NULL) ? 0 : 153 get_camera_metadata_entry_count(mBuffer); 154 } 155 156 bool CameraMetadata::isEmpty() const { 157 return entryCount() == 0; 158 } 159 160 status_t CameraMetadata::sort() { 161 if (mLocked) { 162 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 163 return INVALID_OPERATION; 164 } 165 return sort_camera_metadata(mBuffer); 166 } 167 168 status_t CameraMetadata::checkType(uint32_t tag, uint8_t expectedType) { 169 int tagType = get_camera_metadata_tag_type(tag); 170 if ( CC_UNLIKELY(tagType == -1)) { 171 ALOGE("Update metadata entry: Unknown tag %d", tag); 172 return INVALID_OPERATION; 173 } 174 if ( CC_UNLIKELY(tagType != expectedType) ) { 175 ALOGE("Mismatched tag type when updating entry %s (%d) of type %s; " 176 "got type %s data instead ", 177 get_camera_metadata_tag_name(tag), tag, 178 camera_metadata_type_names[tagType], 179 camera_metadata_type_names[expectedType]); 180 return INVALID_OPERATION; 181 } 182 return OK; 183 } 184 185 status_t CameraMetadata::update(uint32_t tag, 186 const int32_t *data, size_t data_count) { 187 status_t res; 188 if (mLocked) { 189 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 190 return INVALID_OPERATION; 191 } 192 if ( (res = checkType(tag, TYPE_INT32)) != OK) { 193 return res; 194 } 195 return updateImpl(tag, (const void*)data, data_count); 196 } 197 198 status_t CameraMetadata::update(uint32_t tag, 199 const uint8_t *data, size_t data_count) { 200 status_t res; 201 if (mLocked) { 202 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 203 return INVALID_OPERATION; 204 } 205 if ( (res = checkType(tag, TYPE_BYTE)) != OK) { 206 return res; 207 } 208 return updateImpl(tag, (const void*)data, data_count); 209 } 210 211 status_t CameraMetadata::update(uint32_t tag, 212 const float *data, size_t data_count) { 213 status_t res; 214 if (mLocked) { 215 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 216 return INVALID_OPERATION; 217 } 218 if ( (res = checkType(tag, TYPE_FLOAT)) != OK) { 219 return res; 220 } 221 return updateImpl(tag, (const void*)data, data_count); 222 } 223 224 status_t CameraMetadata::update(uint32_t tag, 225 const int64_t *data, size_t data_count) { 226 status_t res; 227 if (mLocked) { 228 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 229 return INVALID_OPERATION; 230 } 231 if ( (res = checkType(tag, TYPE_INT64)) != OK) { 232 return res; 233 } 234 return updateImpl(tag, (const void*)data, data_count); 235 } 236 237 status_t CameraMetadata::update(uint32_t tag, 238 const double *data, size_t data_count) { 239 status_t res; 240 if (mLocked) { 241 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 242 return INVALID_OPERATION; 243 } 244 if ( (res = checkType(tag, TYPE_DOUBLE)) != OK) { 245 return res; 246 } 247 return updateImpl(tag, (const void*)data, data_count); 248 } 249 250 status_t CameraMetadata::update(uint32_t tag, 251 const camera_metadata_rational_t *data, size_t data_count) { 252 status_t res; 253 if (mLocked) { 254 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 255 return INVALID_OPERATION; 256 } 257 if ( (res = checkType(tag, TYPE_RATIONAL)) != OK) { 258 return res; 259 } 260 return updateImpl(tag, (const void*)data, data_count); 261 } 262 263 status_t CameraMetadata::update(uint32_t tag, 264 const String8 &string) { 265 status_t res; 266 if (mLocked) { 267 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 268 return INVALID_OPERATION; 269 } 270 if ( (res = checkType(tag, TYPE_BYTE)) != OK) { 271 return res; 272 } 273 return updateImpl(tag, (const void*)string.string(), string.size()); 274 } 275 276 status_t CameraMetadata::updateImpl(uint32_t tag, const void *data, 277 size_t data_count) { 278 status_t res; 279 if (mLocked) { 280 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 281 return INVALID_OPERATION; 282 } 283 int type = get_camera_metadata_tag_type(tag); 284 if (type == -1) { 285 ALOGE("%s: Tag %d not found", __FUNCTION__, tag); 286 return BAD_VALUE; 287 } 288 size_t data_size = calculate_camera_metadata_entry_data_size(type, 289 data_count); 290 291 res = resizeIfNeeded(1, data_size); 292 293 if (res == OK) { 294 camera_metadata_entry_t entry; 295 res = find_camera_metadata_entry(mBuffer, tag, &entry); 296 if (res == NAME_NOT_FOUND) { 297 res = add_camera_metadata_entry(mBuffer, 298 tag, data, data_count); 299 } else if (res == OK) { 300 res = update_camera_metadata_entry(mBuffer, 301 entry.index, data, data_count, NULL); 302 } 303 } 304 305 if (res != OK) { 306 ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)", 307 __FUNCTION__, get_camera_metadata_section_name(tag), 308 get_camera_metadata_tag_name(tag), tag, strerror(-res), res); 309 } 310 311 IF_ALOGV() { 312 ALOGE_IF(validate_camera_metadata_structure(mBuffer, /*size*/NULL) != 313 OK, 314 315 "%s: Failed to validate metadata structure after update %p", 316 __FUNCTION__, mBuffer); 317 } 318 319 return res; 320 } 321 322 bool CameraMetadata::exists(uint32_t tag) const { 323 camera_metadata_ro_entry entry; 324 return find_camera_metadata_ro_entry(mBuffer, tag, &entry) == 0; 325 } 326 327 camera_metadata_entry_t CameraMetadata::find(uint32_t tag) { 328 status_t res; 329 camera_metadata_entry entry; 330 if (mLocked) { 331 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 332 entry.count = 0; 333 return entry; 334 } 335 res = find_camera_metadata_entry(mBuffer, tag, &entry); 336 if (CC_UNLIKELY( res != OK )) { 337 entry.count = 0; 338 entry.data.u8 = NULL; 339 } 340 return entry; 341 } 342 343 camera_metadata_ro_entry_t CameraMetadata::find(uint32_t tag) const { 344 status_t res; 345 camera_metadata_ro_entry entry; 346 res = find_camera_metadata_ro_entry(mBuffer, tag, &entry); 347 if (CC_UNLIKELY( res != OK )) { 348 entry.count = 0; 349 entry.data.u8 = NULL; 350 } 351 return entry; 352 } 353 354 status_t CameraMetadata::erase(uint32_t tag) { 355 camera_metadata_entry_t entry; 356 status_t res; 357 if (mLocked) { 358 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 359 return INVALID_OPERATION; 360 } 361 res = find_camera_metadata_entry(mBuffer, tag, &entry); 362 if (res == NAME_NOT_FOUND) { 363 return OK; 364 } else if (res != OK) { 365 ALOGE("%s: Error looking for entry %s.%s (%x): %s %d", 366 __FUNCTION__, 367 get_camera_metadata_section_name(tag), 368 get_camera_metadata_tag_name(tag), tag, strerror(-res), res); 369 return res; 370 } 371 res = delete_camera_metadata_entry(mBuffer, entry.index); 372 if (res != OK) { 373 ALOGE("%s: Error deleting entry %s.%s (%x): %s %d", 374 __FUNCTION__, 375 get_camera_metadata_section_name(tag), 376 get_camera_metadata_tag_name(tag), tag, strerror(-res), res); 377 } 378 return res; 379 } 380 381 void CameraMetadata::dump(int fd, int verbosity, int indentation) const { 382 dump_indented_camera_metadata(mBuffer, fd, verbosity, indentation); 383 } 384 385 status_t CameraMetadata::resizeIfNeeded(size_t extraEntries, size_t extraData) { 386 if (mBuffer == NULL) { 387 mBuffer = allocate_camera_metadata(extraEntries * 2, extraData * 2); 388 if (mBuffer == NULL) { 389 ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__); 390 return NO_MEMORY; 391 } 392 } else { 393 size_t currentEntryCount = get_camera_metadata_entry_count(mBuffer); 394 size_t currentEntryCap = get_camera_metadata_entry_capacity(mBuffer); 395 size_t newEntryCount = currentEntryCount + 396 extraEntries; 397 newEntryCount = (newEntryCount > currentEntryCap) ? 398 newEntryCount * 2 : currentEntryCap; 399 400 size_t currentDataCount = get_camera_metadata_data_count(mBuffer); 401 size_t currentDataCap = get_camera_metadata_data_capacity(mBuffer); 402 size_t newDataCount = currentDataCount + 403 extraData; 404 newDataCount = (newDataCount > currentDataCap) ? 405 newDataCount * 2 : currentDataCap; 406 407 if (newEntryCount > currentEntryCap || 408 newDataCount > currentDataCap) { 409 camera_metadata_t *oldBuffer = mBuffer; 410 mBuffer = allocate_camera_metadata(newEntryCount, 411 newDataCount); 412 if (mBuffer == NULL) { 413 ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__); 414 return NO_MEMORY; 415 } 416 append_camera_metadata(mBuffer, oldBuffer); 417 free_camera_metadata(oldBuffer); 418 } 419 } 420 return OK; 421 } 422 423 status_t CameraMetadata::readFromParcel(const Parcel& data, 424 camera_metadata_t** out) { 425 426 status_t err = OK; 427 428 camera_metadata_t* metadata = NULL; 429 430 if (out) { 431 *out = NULL; 432 } 433 434 // arg0 = metadataSize (int32) 435 int32_t metadataSizeTmp = -1; 436 if ((err = data.readInt32(&metadataSizeTmp)) != OK) { 437 ALOGE("%s: Failed to read metadata size (error %d %s)", 438 __FUNCTION__, err, strerror(-err)); 439 return err; 440 } 441 const size_t metadataSize = static_cast<size_t>(metadataSizeTmp); 442 443 if (metadataSize == 0) { 444 ALOGV("%s: Read 0-sized metadata", __FUNCTION__); 445 return OK; 446 } 447 448 // NOTE: this doesn't make sense to me. shouldnt the blob 449 // know how big it is? why do we have to specify the size 450 // to Parcel::readBlob ? 451 452 ReadableBlob blob; 453 // arg1 = metadata (blob) 454 do { 455 if ((err = data.readBlob(metadataSize, &blob)) != OK) { 456 ALOGE("%s: Failed to read metadata blob (sized %d). Possible " 457 " serialization bug. Error %d %s", 458 __FUNCTION__, metadataSize, err, strerror(-err)); 459 break; 460 } 461 const camera_metadata_t* tmp = 462 reinterpret_cast<const camera_metadata_t*>(blob.data()); 463 464 metadata = allocate_copy_camera_metadata_checked(tmp, metadataSize); 465 if (metadata == NULL) { 466 // We consider that allocation only fails if the validation 467 // also failed, therefore the readFromParcel was a failure. 468 err = BAD_VALUE; 469 } 470 } while(0); 471 blob.release(); 472 473 if (out) { 474 ALOGV("%s: Set out metadata to %p", __FUNCTION__, metadata); 475 *out = metadata; 476 } else if (metadata != NULL) { 477 ALOGV("%s: Freed camera metadata at %p", __FUNCTION__, metadata); 478 free_camera_metadata(metadata); 479 } 480 481 return err; 482 } 483 484 status_t CameraMetadata::writeToParcel(Parcel& data, 485 const camera_metadata_t* metadata) { 486 status_t res = OK; 487 488 // arg0 = metadataSize (int32) 489 490 if (metadata == NULL) { 491 return data.writeInt32(0); 492 } 493 494 const size_t metadataSize = get_camera_metadata_compact_size(metadata); 495 res = data.writeInt32(static_cast<int32_t>(metadataSize)); 496 if (res != OK) { 497 return res; 498 } 499 500 // arg1 = metadata (blob) 501 WritableBlob blob; 502 do { 503 res = data.writeBlob(metadataSize, &blob); 504 if (res != OK) { 505 break; 506 } 507 copy_camera_metadata(blob.data(), metadataSize, metadata); 508 509 IF_ALOGV() { 510 if (validate_camera_metadata_structure( 511 (const camera_metadata_t*)blob.data(), 512 &metadataSize) != OK) { 513 ALOGV("%s: Failed to validate metadata %p after writing blob", 514 __FUNCTION__, blob.data()); 515 } else { 516 ALOGV("%s: Metadata written to blob. Validation success", 517 __FUNCTION__); 518 } 519 } 520 521 // Not too big of a problem since receiving side does hard validation 522 // Don't check the size since the compact size could be larger 523 if (validate_camera_metadata_structure(metadata, /*size*/NULL) != OK) { 524 ALOGW("%s: Failed to validate metadata %p before writing blob", 525 __FUNCTION__, metadata); 526 } 527 528 } while(false); 529 blob.release(); 530 531 return res; 532 } 533 534 status_t CameraMetadata::readFromParcel(Parcel *parcel) { 535 536 ALOGV("%s: parcel = %p", __FUNCTION__, parcel); 537 538 status_t res = OK; 539 540 if (parcel == NULL) { 541 ALOGE("%s: parcel is null", __FUNCTION__); 542 return BAD_VALUE; 543 } 544 545 if (mLocked) { 546 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 547 return INVALID_OPERATION; 548 } 549 550 camera_metadata *buffer = NULL; 551 // TODO: reading should return a status code, in case validation fails 552 res = CameraMetadata::readFromParcel(*parcel, &buffer); 553 554 if (res != NO_ERROR) { 555 ALOGE("%s: Failed to read from parcel. Metadata is unchanged.", 556 __FUNCTION__); 557 return res; 558 } 559 560 clear(); 561 mBuffer = buffer; 562 563 return OK; 564 } 565 566 status_t CameraMetadata::writeToParcel(Parcel *parcel) const { 567 568 ALOGV("%s: parcel = %p", __FUNCTION__, parcel); 569 570 if (parcel == NULL) { 571 ALOGE("%s: parcel is null", __FUNCTION__); 572 return BAD_VALUE; 573 } 574 575 return CameraMetadata::writeToParcel(*parcel, mBuffer); 576 } 577 578 void CameraMetadata::swap(CameraMetadata& other) { 579 if (mLocked) { 580 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 581 return; 582 } else if (other.mLocked) { 583 ALOGE("%s: Other CameraMetadata is locked", __FUNCTION__); 584 return; 585 } 586 587 camera_metadata* thisBuf = mBuffer; 588 camera_metadata* otherBuf = other.mBuffer; 589 590 other.mBuffer = thisBuf; 591 mBuffer = otherBuf; 592 } 593 594 }; // namespace android 595