Home | History | Annotate | Download | only in camera
      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 <binder/Parcel.h>
     24 #include <camera/CameraMetadata.h>
     25 
     26 namespace android {
     27 
     28 #define ALIGN_TO(val, alignment) \
     29     (((uintptr_t)(val) + ((alignment) - 1)) & ~((alignment) - 1))
     30 
     31 typedef Parcel::WritableBlob WritableBlob;
     32 typedef Parcel::ReadableBlob ReadableBlob;
     33 
     34 CameraMetadata::CameraMetadata() :
     35         mBuffer(NULL), mLocked(false) {
     36 }
     37 
     38 CameraMetadata::CameraMetadata(size_t entryCapacity, size_t dataCapacity) :
     39         mLocked(false)
     40 {
     41     mBuffer = allocate_camera_metadata(entryCapacity, dataCapacity);
     42 }
     43 
     44 CameraMetadata::CameraMetadata(const CameraMetadata &other) :
     45         mLocked(false) {
     46     mBuffer = clone_camera_metadata(other.mBuffer);
     47 }
     48 
     49 CameraMetadata::CameraMetadata(camera_metadata_t *buffer) :
     50         mBuffer(NULL), mLocked(false) {
     51     acquire(buffer);
     52 }
     53 
     54 CameraMetadata &CameraMetadata::operator=(const CameraMetadata &other) {
     55     return operator=(other.mBuffer);
     56 }
     57 
     58 CameraMetadata &CameraMetadata::operator=(const camera_metadata_t *buffer) {
     59     if (mLocked) {
     60         ALOGE("%s: Assignment to a locked CameraMetadata!", __FUNCTION__);
     61         return *this;
     62     }
     63 
     64     if (CC_LIKELY(buffer != mBuffer)) {
     65         camera_metadata_t *newBuffer = clone_camera_metadata(buffer);
     66         clear();
     67         mBuffer = newBuffer;
     68     }
     69     return *this;
     70 }
     71 
     72 CameraMetadata::~CameraMetadata() {
     73     mLocked = false;
     74     clear();
     75 }
     76 
     77 const camera_metadata_t* CameraMetadata::getAndLock() const {
     78     mLocked = true;
     79     return mBuffer;
     80 }
     81 
     82 status_t CameraMetadata::unlock(const camera_metadata_t *buffer) const {
     83     if (!mLocked) {
     84         ALOGE("%s: Can't unlock a non-locked CameraMetadata!", __FUNCTION__);
     85         return INVALID_OPERATION;
     86     }
     87     if (buffer != mBuffer) {
     88         ALOGE("%s: Can't unlock CameraMetadata with wrong pointer!",
     89                 __FUNCTION__);
     90         return BAD_VALUE;
     91     }
     92     mLocked = false;
     93     return OK;
     94 }
     95 
     96 camera_metadata_t* CameraMetadata::release() {
     97     if (mLocked) {
     98         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
     99         return NULL;
    100     }
    101     camera_metadata_t *released = mBuffer;
    102     mBuffer = NULL;
    103     return released;
    104 }
    105 
    106 void CameraMetadata::clear() {
    107     if (mLocked) {
    108         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    109         return;
    110     }
    111     if (mBuffer) {
    112         free_camera_metadata(mBuffer);
    113         mBuffer = NULL;
    114     }
    115 }
    116 
    117 void CameraMetadata::acquire(camera_metadata_t *buffer) {
    118     if (mLocked) {
    119         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    120         return;
    121     }
    122     clear();
    123     mBuffer = buffer;
    124 
    125     ALOGE_IF(validate_camera_metadata_structure(mBuffer, /*size*/NULL) != OK,
    126              "%s: Failed to validate metadata structure %p",
    127              __FUNCTION__, buffer);
    128 }
    129 
    130 void CameraMetadata::acquire(CameraMetadata &other) {
    131     if (mLocked) {
    132         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    133         return;
    134     }
    135     acquire(other.release());
    136 }
    137 
    138 status_t CameraMetadata::append(const CameraMetadata &other) {
    139     return append(other.mBuffer);
    140 }
    141 
    142 status_t CameraMetadata::append(const camera_metadata_t* other) {
    143     if (mLocked) {
    144         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    145         return INVALID_OPERATION;
    146     }
    147     size_t extraEntries = get_camera_metadata_entry_count(other);
    148     size_t extraData = get_camera_metadata_data_count(other);
    149     resizeIfNeeded(extraEntries, extraData);
    150 
    151     return append_camera_metadata(mBuffer, other);
    152 }
    153 
    154 size_t CameraMetadata::entryCount() const {
    155     return (mBuffer == NULL) ? 0 :
    156             get_camera_metadata_entry_count(mBuffer);
    157 }
    158 
    159 bool CameraMetadata::isEmpty() const {
    160     return entryCount() == 0;
    161 }
    162 
    163 status_t CameraMetadata::sort() {
    164     if (mLocked) {
    165         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    166         return INVALID_OPERATION;
    167     }
    168     return sort_camera_metadata(mBuffer);
    169 }
    170 
    171 status_t CameraMetadata::checkType(uint32_t tag, uint8_t expectedType) {
    172     int tagType = get_local_camera_metadata_tag_type(tag, mBuffer);
    173     if ( CC_UNLIKELY(tagType == -1)) {
    174         ALOGE("Update metadata entry: Unknown tag %d", tag);
    175         return INVALID_OPERATION;
    176     }
    177     if ( CC_UNLIKELY(tagType != expectedType) ) {
    178         ALOGE("Mismatched tag type when updating entry %s (%d) of type %s; "
    179                 "got type %s data instead ",
    180                 get_local_camera_metadata_tag_name(tag, mBuffer), tag,
    181                 camera_metadata_type_names[tagType],
    182                 camera_metadata_type_names[expectedType]);
    183         return INVALID_OPERATION;
    184     }
    185     return OK;
    186 }
    187 
    188 status_t CameraMetadata::update(uint32_t tag,
    189         const int32_t *data, size_t data_count) {
    190     status_t res;
    191     if (mLocked) {
    192         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    193         return INVALID_OPERATION;
    194     }
    195     if ( (res = checkType(tag, TYPE_INT32)) != OK) {
    196         return res;
    197     }
    198     return updateImpl(tag, (const void*)data, data_count);
    199 }
    200 
    201 status_t CameraMetadata::update(uint32_t tag,
    202         const uint8_t *data, size_t data_count) {
    203     status_t res;
    204     if (mLocked) {
    205         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    206         return INVALID_OPERATION;
    207     }
    208     if ( (res = checkType(tag, TYPE_BYTE)) != OK) {
    209         return res;
    210     }
    211     return updateImpl(tag, (const void*)data, data_count);
    212 }
    213 
    214 status_t CameraMetadata::update(uint32_t tag,
    215         const float *data, size_t data_count) {
    216     status_t res;
    217     if (mLocked) {
    218         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    219         return INVALID_OPERATION;
    220     }
    221     if ( (res = checkType(tag, TYPE_FLOAT)) != OK) {
    222         return res;
    223     }
    224     return updateImpl(tag, (const void*)data, data_count);
    225 }
    226 
    227 status_t CameraMetadata::update(uint32_t tag,
    228         const int64_t *data, size_t data_count) {
    229     status_t res;
    230     if (mLocked) {
    231         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    232         return INVALID_OPERATION;
    233     }
    234     if ( (res = checkType(tag, TYPE_INT64)) != OK) {
    235         return res;
    236     }
    237     return updateImpl(tag, (const void*)data, data_count);
    238 }
    239 
    240 status_t CameraMetadata::update(uint32_t tag,
    241         const double *data, size_t data_count) {
    242     status_t res;
    243     if (mLocked) {
    244         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    245         return INVALID_OPERATION;
    246     }
    247     if ( (res = checkType(tag, TYPE_DOUBLE)) != OK) {
    248         return res;
    249     }
    250     return updateImpl(tag, (const void*)data, data_count);
    251 }
    252 
    253 status_t CameraMetadata::update(uint32_t tag,
    254         const camera_metadata_rational_t *data, size_t data_count) {
    255     status_t res;
    256     if (mLocked) {
    257         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    258         return INVALID_OPERATION;
    259     }
    260     if ( (res = checkType(tag, TYPE_RATIONAL)) != OK) {
    261         return res;
    262     }
    263     return updateImpl(tag, (const void*)data, data_count);
    264 }
    265 
    266 status_t CameraMetadata::update(uint32_t tag,
    267         const String8 &string) {
    268     status_t res;
    269     if (mLocked) {
    270         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    271         return INVALID_OPERATION;
    272     }
    273     if ( (res = checkType(tag, TYPE_BYTE)) != OK) {
    274         return res;
    275     }
    276     // string.size() doesn't count the null termination character.
    277     return updateImpl(tag, (const void*)string.string(), string.size() + 1);
    278 }
    279 
    280 status_t CameraMetadata::update(const camera_metadata_ro_entry &entry) {
    281     status_t res;
    282     if (mLocked) {
    283         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    284         return INVALID_OPERATION;
    285     }
    286     if ( (res = checkType(entry.tag, entry.type)) != OK) {
    287         return res;
    288     }
    289     return updateImpl(entry.tag, (const void*)entry.data.u8, entry.count);
    290 }
    291 
    292 status_t CameraMetadata::updateImpl(uint32_t tag, const void *data,
    293         size_t data_count) {
    294     status_t res;
    295     if (mLocked) {
    296         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    297         return INVALID_OPERATION;
    298     }
    299     int type = get_local_camera_metadata_tag_type(tag, mBuffer);
    300     if (type == -1) {
    301         ALOGE("%s: Tag %d not found", __FUNCTION__, tag);
    302         return BAD_VALUE;
    303     }
    304     // Safety check - ensure that data isn't pointing to this metadata, since
    305     // that would get invalidated if a resize is needed
    306     size_t bufferSize = get_camera_metadata_size(mBuffer);
    307     uintptr_t bufAddr = reinterpret_cast<uintptr_t>(mBuffer);
    308     uintptr_t dataAddr = reinterpret_cast<uintptr_t>(data);
    309     if (dataAddr > bufAddr && dataAddr < (bufAddr + bufferSize)) {
    310         ALOGE("%s: Update attempted with data from the same metadata buffer!",
    311                 __FUNCTION__);
    312         return INVALID_OPERATION;
    313     }
    314 
    315     size_t data_size = calculate_camera_metadata_entry_data_size(type,
    316             data_count);
    317 
    318     res = resizeIfNeeded(1, data_size);
    319 
    320     if (res == OK) {
    321         camera_metadata_entry_t entry;
    322         res = find_camera_metadata_entry(mBuffer, tag, &entry);
    323         if (res == NAME_NOT_FOUND) {
    324             res = add_camera_metadata_entry(mBuffer,
    325                     tag, data, data_count);
    326         } else if (res == OK) {
    327             res = update_camera_metadata_entry(mBuffer,
    328                     entry.index, data, data_count, NULL);
    329         }
    330     }
    331 
    332     if (res != OK) {
    333         ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)",
    334                 __FUNCTION__, get_local_camera_metadata_section_name(tag, mBuffer),
    335                 get_local_camera_metadata_tag_name(tag, mBuffer), tag,
    336                 strerror(-res), res);
    337     }
    338 
    339     IF_ALOGV() {
    340         ALOGE_IF(validate_camera_metadata_structure(mBuffer, /*size*/NULL) !=
    341                  OK,
    342 
    343                  "%s: Failed to validate metadata structure after update %p",
    344                  __FUNCTION__, mBuffer);
    345     }
    346 
    347     return res;
    348 }
    349 
    350 bool CameraMetadata::exists(uint32_t tag) const {
    351     camera_metadata_ro_entry entry;
    352     return find_camera_metadata_ro_entry(mBuffer, tag, &entry) == 0;
    353 }
    354 
    355 camera_metadata_entry_t CameraMetadata::find(uint32_t tag) {
    356     status_t res;
    357     camera_metadata_entry entry;
    358     if (mLocked) {
    359         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    360         entry.count = 0;
    361         return entry;
    362     }
    363     res = find_camera_metadata_entry(mBuffer, tag, &entry);
    364     if (CC_UNLIKELY( res != OK )) {
    365         entry.count = 0;
    366         entry.data.u8 = NULL;
    367     }
    368     return entry;
    369 }
    370 
    371 camera_metadata_ro_entry_t CameraMetadata::find(uint32_t tag) const {
    372     status_t res;
    373     camera_metadata_ro_entry entry;
    374     res = find_camera_metadata_ro_entry(mBuffer, tag, &entry);
    375     if (CC_UNLIKELY( res != OK )) {
    376         entry.count = 0;
    377         entry.data.u8 = NULL;
    378     }
    379     return entry;
    380 }
    381 
    382 status_t CameraMetadata::erase(uint32_t tag) {
    383     camera_metadata_entry_t entry;
    384     status_t res;
    385     if (mLocked) {
    386         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    387         return INVALID_OPERATION;
    388     }
    389     res = find_camera_metadata_entry(mBuffer, tag, &entry);
    390     if (res == NAME_NOT_FOUND) {
    391         return OK;
    392     } else if (res != OK) {
    393         ALOGE("%s: Error looking for entry %s.%s (%x): %s %d",
    394                 __FUNCTION__,
    395                 get_local_camera_metadata_section_name(tag, mBuffer),
    396                 get_local_camera_metadata_tag_name(tag, mBuffer),
    397                 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_local_camera_metadata_section_name(tag, mBuffer),
    405                 get_local_camera_metadata_tag_name(tag, mBuffer),
    406                 tag, strerror(-res), res);
    407     }
    408     return res;
    409 }
    410 
    411 status_t CameraMetadata::removePermissionEntries(metadata_vendor_id_t vendorId,
    412         std::vector<int32_t> *tagsRemoved) {
    413     uint32_t tagCount = 0;
    414     std::vector<uint32_t> tagsToRemove;
    415 
    416     if (tagsRemoved == nullptr) {
    417         return BAD_VALUE;
    418     }
    419 
    420     sp<VendorTagDescriptor> vTags = VendorTagDescriptor::getGlobalVendorTagDescriptor();
    421     if ((nullptr == vTags.get()) || (0 >= vTags->getTagCount())) {
    422         sp<VendorTagDescriptorCache> cache =
    423             VendorTagDescriptorCache::getGlobalVendorTagCache();
    424         if (cache.get()) {
    425             cache->getVendorTagDescriptor(vendorId, &vTags);
    426         }
    427     }
    428 
    429     if ((nullptr != vTags.get()) && (vTags->getTagCount() > 0)) {
    430         tagCount = vTags->getTagCount();
    431         uint32_t *vendorTags = new uint32_t[tagCount];
    432         if (nullptr == vendorTags) {
    433             return NO_MEMORY;
    434         }
    435         vTags->getTagArray(vendorTags);
    436 
    437         tagsToRemove.reserve(tagCount);
    438         tagsToRemove.insert(tagsToRemove.begin(), vendorTags, vendorTags + tagCount);
    439 
    440         delete [] vendorTags;
    441         tagCount = 0;
    442     }
    443 
    444     auto tagsNeedingPermission = get_camera_metadata_permission_needed(&tagCount);
    445     if (tagCount > 0) {
    446         tagsToRemove.reserve(tagsToRemove.capacity() + tagCount);
    447         tagsToRemove.insert(tagsToRemove.end(), tagsNeedingPermission,
    448                 tagsNeedingPermission + tagCount);
    449     }
    450 
    451     tagsRemoved->reserve(tagsToRemove.size());
    452     for (const auto &it : tagsToRemove) {
    453         if (exists(it)) {
    454             auto rc = erase(it);
    455             if (NO_ERROR != rc) {
    456                 ALOGE("%s: Failed to erase tag: %x", __func__, it);
    457                 return rc;
    458             }
    459             tagsRemoved->push_back(it);
    460         }
    461     }
    462 
    463     // Update the available characterstics accordingly
    464     if (exists(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS)) {
    465         std::vector<uint32_t> currentKeys;
    466 
    467         std::sort(tagsRemoved->begin(), tagsRemoved->end());
    468         auto keys = find(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS);
    469         currentKeys.reserve(keys.count);
    470         currentKeys.insert(currentKeys.end(), keys.data.i32, keys.data.i32 + keys.count);
    471         std::sort(currentKeys.begin(), currentKeys.end());
    472 
    473         std::vector<int32_t> newKeys(keys.count);
    474         auto end = std::set_difference(currentKeys.begin(), currentKeys.end(), tagsRemoved->begin(),
    475                 tagsRemoved->end(), newKeys.begin());
    476         newKeys.resize(end - newKeys.begin());
    477 
    478         update(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, newKeys.data(), newKeys.size());
    479     }
    480 
    481     return NO_ERROR;
    482 }
    483 
    484 void CameraMetadata::dump(int fd, int verbosity, int indentation) const {
    485     dump_indented_camera_metadata(mBuffer, fd, verbosity, indentation);
    486 }
    487 
    488 status_t CameraMetadata::resizeIfNeeded(size_t extraEntries, size_t extraData) {
    489     if (mBuffer == NULL) {
    490         mBuffer = allocate_camera_metadata(extraEntries * 2, extraData * 2);
    491         if (mBuffer == NULL) {
    492             ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__);
    493             return NO_MEMORY;
    494         }
    495     } else {
    496         size_t currentEntryCount = get_camera_metadata_entry_count(mBuffer);
    497         size_t currentEntryCap = get_camera_metadata_entry_capacity(mBuffer);
    498         size_t newEntryCount = currentEntryCount +
    499                 extraEntries;
    500         newEntryCount = (newEntryCount > currentEntryCap) ?
    501                 newEntryCount * 2 : currentEntryCap;
    502 
    503         size_t currentDataCount = get_camera_metadata_data_count(mBuffer);
    504         size_t currentDataCap = get_camera_metadata_data_capacity(mBuffer);
    505         size_t newDataCount = currentDataCount +
    506                 extraData;
    507         newDataCount = (newDataCount > currentDataCap) ?
    508                 newDataCount * 2 : currentDataCap;
    509 
    510         if (newEntryCount > currentEntryCap ||
    511                 newDataCount > currentDataCap) {
    512             camera_metadata_t *oldBuffer = mBuffer;
    513             mBuffer = allocate_camera_metadata(newEntryCount,
    514                     newDataCount);
    515             if (mBuffer == NULL) {
    516                 ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__);
    517                 return NO_MEMORY;
    518             }
    519             append_camera_metadata(mBuffer, oldBuffer);
    520             free_camera_metadata(oldBuffer);
    521         }
    522     }
    523     return OK;
    524 }
    525 
    526 status_t CameraMetadata::readFromParcel(const Parcel& data,
    527                                         camera_metadata_t** out) {
    528 
    529     status_t err = OK;
    530 
    531     camera_metadata_t* metadata = NULL;
    532 
    533     if (out) {
    534         *out = NULL;
    535     }
    536 
    537     // See CameraMetadata::writeToParcel for parcel data layout diagram and explanation.
    538     // arg0 = blobSize (int32)
    539     int32_t blobSizeTmp = -1;
    540     if ((err = data.readInt32(&blobSizeTmp)) != OK) {
    541         ALOGE("%s: Failed to read metadata size (error %d %s)",
    542               __FUNCTION__, err, strerror(-err));
    543         return err;
    544     }
    545     const size_t blobSize = static_cast<size_t>(blobSizeTmp);
    546     const size_t alignment = get_camera_metadata_alignment();
    547 
    548     // Special case: zero blob size means zero sized (NULL) metadata.
    549     if (blobSize == 0) {
    550         ALOGV("%s: Read 0-sized metadata", __FUNCTION__);
    551         return OK;
    552     }
    553 
    554     if (blobSize <= alignment) {
    555         ALOGE("%s: metadata blob is malformed, blobSize(%zu) should be larger than alignment(%zu)",
    556                 __FUNCTION__, blobSize, alignment);
    557         return BAD_VALUE;
    558     }
    559 
    560     const size_t metadataSize = blobSize - alignment;
    561 
    562     // NOTE: this doesn't make sense to me. shouldn't the blob
    563     // know how big it is? why do we have to specify the size
    564     // to Parcel::readBlob ?
    565     ReadableBlob blob;
    566     // arg1 = metadata (blob)
    567     do {
    568         if ((err = data.readBlob(blobSize, &blob)) != OK) {
    569             ALOGE("%s: Failed to read metadata blob (sized %zu). Possible "
    570                   " serialization bug. Error %d %s",
    571                   __FUNCTION__, blobSize, err, strerror(-err));
    572             break;
    573         }
    574 
    575         // arg2 = offset (blob)
    576         // Must be after blob since we don't know offset until after writeBlob.
    577         int32_t offsetTmp;
    578         if ((err = data.readInt32(&offsetTmp)) != OK) {
    579             ALOGE("%s: Failed to read metadata offsetTmp (error %d %s)",
    580                   __FUNCTION__, err, strerror(-err));
    581             break;
    582         }
    583         const size_t offset = static_cast<size_t>(offsetTmp);
    584         if (offset >= alignment) {
    585             ALOGE("%s: metadata offset(%zu) should be less than alignment(%zu)",
    586                     __FUNCTION__, blobSize, alignment);
    587             err = BAD_VALUE;
    588             break;
    589         }
    590 
    591         const uintptr_t metadataStart = reinterpret_cast<uintptr_t>(blob.data()) + offset;
    592         const camera_metadata_t* tmp =
    593                        reinterpret_cast<const camera_metadata_t*>(metadataStart);
    594         ALOGV("%s: alignment is: %zu, metadata start: %p, offset: %zu",
    595                 __FUNCTION__, alignment, tmp, offset);
    596         metadata = allocate_copy_camera_metadata_checked(tmp, metadataSize);
    597         if (metadata == NULL) {
    598             // We consider that allocation only fails if the validation
    599             // also failed, therefore the readFromParcel was a failure.
    600             ALOGE("%s: metadata allocation and copy failed", __FUNCTION__);
    601             err = BAD_VALUE;
    602         }
    603     } while(0);
    604     blob.release();
    605 
    606     if (out) {
    607         ALOGV("%s: Set out metadata to %p", __FUNCTION__, metadata);
    608         *out = metadata;
    609     } else if (metadata != NULL) {
    610         ALOGV("%s: Freed camera metadata at %p", __FUNCTION__, metadata);
    611         free_camera_metadata(metadata);
    612     }
    613 
    614     return err;
    615 }
    616 
    617 status_t CameraMetadata::writeToParcel(Parcel& data,
    618                                        const camera_metadata_t* metadata) {
    619     status_t res = OK;
    620 
    621     /**
    622      * Below is the camera metadata parcel layout:
    623      *
    624      * |--------------------------------------------|
    625      * |             arg0: blobSize                 |
    626      * |              (length = 4)                  |
    627      * |--------------------------------------------|<--Skip the rest if blobSize == 0.
    628      * |                                            |
    629      * |                                            |
    630      * |              arg1: blob                    |
    631      * | (length = variable, see arg1 layout below) |
    632      * |                                            |
    633      * |                                            |
    634      * |--------------------------------------------|
    635      * |              arg2: offset                  |
    636      * |              (length = 4)                  |
    637      * |--------------------------------------------|
    638      */
    639 
    640     // arg0 = blobSize (int32)
    641     if (metadata == NULL) {
    642         // Write zero blobSize for null metadata.
    643         return data.writeInt32(0);
    644     }
    645 
    646     /**
    647      * Always make the blob size sufficiently larger, as we need put alignment
    648      * padding and metadata into the blob. Since we don't know the alignment
    649      * offset before writeBlob. Then write the metadata to aligned offset.
    650      */
    651     const size_t metadataSize = get_camera_metadata_compact_size(metadata);
    652     const size_t alignment = get_camera_metadata_alignment();
    653     const size_t blobSize = metadataSize + alignment;
    654     res = data.writeInt32(static_cast<int32_t>(blobSize));
    655     if (res != OK) {
    656         return res;
    657     }
    658 
    659     size_t offset = 0;
    660     /**
    661      * arg1 = metadata (blob).
    662      *
    663      * The blob size is the sum of front padding size, metadata size and back padding
    664      * size, which is equal to metadataSize + alignment.
    665      *
    666      * The blob layout is:
    667      * |------------------------------------|<----Start address of the blob (unaligned).
    668      * |           front padding            |
    669      * |          (size = offset)           |
    670      * |------------------------------------|<----Aligned start address of metadata.
    671      * |                                    |
    672      * |                                    |
    673      * |            metadata                |
    674      * |       (size = metadataSize)        |
    675      * |                                    |
    676      * |                                    |
    677      * |------------------------------------|
    678      * |           back padding             |
    679      * |     (size = alignment - offset)    |
    680      * |------------------------------------|<----End address of blob.
    681      *                                            (Blob start address + blob size).
    682      */
    683     WritableBlob blob;
    684     do {
    685         res = data.writeBlob(blobSize, false, &blob);
    686         if (res != OK) {
    687             break;
    688         }
    689         const uintptr_t metadataStart = ALIGN_TO(blob.data(), alignment);
    690         offset = metadataStart - reinterpret_cast<uintptr_t>(blob.data());
    691         ALOGV("%s: alignment is: %zu, metadata start: %p, offset: %zu",
    692                 __FUNCTION__, alignment,
    693                 reinterpret_cast<const void *>(metadataStart), offset);
    694         copy_camera_metadata(reinterpret_cast<void*>(metadataStart), metadataSize, metadata);
    695 
    696         // Not too big of a problem since receiving side does hard validation
    697         // Don't check the size since the compact size could be larger
    698         if (validate_camera_metadata_structure(metadata, /*size*/NULL) != OK) {
    699             ALOGW("%s: Failed to validate metadata %p before writing blob",
    700                    __FUNCTION__, metadata);
    701         }
    702 
    703     } while(false);
    704     blob.release();
    705 
    706     // arg2 = offset (int32)
    707     res = data.writeInt32(static_cast<int32_t>(offset));
    708 
    709     return res;
    710 }
    711 
    712 status_t CameraMetadata::readFromParcel(const Parcel *parcel) {
    713 
    714     ALOGV("%s: parcel = %p", __FUNCTION__, parcel);
    715 
    716     status_t res = OK;
    717 
    718     if (parcel == NULL) {
    719         ALOGE("%s: parcel is null", __FUNCTION__);
    720         return BAD_VALUE;
    721     }
    722 
    723     if (mLocked) {
    724         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    725         return INVALID_OPERATION;
    726     }
    727 
    728     camera_metadata *buffer = NULL;
    729     // TODO: reading should return a status code, in case validation fails
    730     res = CameraMetadata::readFromParcel(*parcel, &buffer);
    731 
    732     if (res != NO_ERROR) {
    733         ALOGE("%s: Failed to read from parcel. Metadata is unchanged.",
    734               __FUNCTION__);
    735         return res;
    736     }
    737 
    738     clear();
    739     mBuffer = buffer;
    740 
    741     return OK;
    742 }
    743 
    744 status_t CameraMetadata::writeToParcel(Parcel *parcel) const {
    745 
    746     ALOGV("%s: parcel = %p", __FUNCTION__, parcel);
    747 
    748     if (parcel == NULL) {
    749         ALOGE("%s: parcel is null", __FUNCTION__);
    750         return BAD_VALUE;
    751     }
    752 
    753     return CameraMetadata::writeToParcel(*parcel, mBuffer);
    754 }
    755 
    756 void CameraMetadata::swap(CameraMetadata& other) {
    757     if (mLocked) {
    758         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    759         return;
    760     } else if (other.mLocked) {
    761         ALOGE("%s: Other CameraMetadata is locked", __FUNCTION__);
    762         return;
    763     }
    764 
    765     camera_metadata* thisBuf = mBuffer;
    766     camera_metadata* otherBuf = other.mBuffer;
    767 
    768     other.mBuffer = thisBuf;
    769     mBuffer = otherBuf;
    770 }
    771 
    772 status_t CameraMetadata::getTagFromName(const char *name,
    773         const VendorTagDescriptor* vTags, uint32_t *tag) {
    774 
    775     if (name == nullptr || tag == nullptr) return BAD_VALUE;
    776 
    777     size_t nameLength = strlen(name);
    778 
    779     const SortedVector<String8> *vendorSections;
    780     size_t vendorSectionCount = 0;
    781 
    782     if (vTags != NULL) {
    783         vendorSections = vTags->getAllSectionNames();
    784         vendorSectionCount = vendorSections->size();
    785     }
    786 
    787     // First, find the section by the longest string match
    788     const char *section = NULL;
    789     size_t sectionIndex = 0;
    790     size_t sectionLength = 0;
    791     size_t totalSectionCount = ANDROID_SECTION_COUNT + vendorSectionCount;
    792     for (size_t i = 0; i < totalSectionCount; ++i) {
    793 
    794         const char *str = (i < ANDROID_SECTION_COUNT) ? camera_metadata_section_names[i] :
    795                 (*vendorSections)[i - ANDROID_SECTION_COUNT].string();
    796 
    797         ALOGV("%s: Trying to match against section '%s'", __FUNCTION__, str);
    798 
    799         if (strstr(name, str) == name) { // name begins with the section name
    800             size_t strLength = strlen(str);
    801 
    802             ALOGV("%s: Name begins with section name", __FUNCTION__);
    803 
    804             // section name is the longest we've found so far
    805             if (section == NULL || sectionLength < strLength) {
    806                 section = str;
    807                 sectionIndex = i;
    808                 sectionLength = strLength;
    809 
    810                 ALOGV("%s: Found new best section (%s)", __FUNCTION__, section);
    811             }
    812         }
    813     }
    814 
    815     // TODO: Make above get_camera_metadata_section_from_name ?
    816 
    817     if (section == NULL) {
    818         return NAME_NOT_FOUND;
    819     } else {
    820         ALOGV("%s: Found matched section '%s' (%zu)",
    821               __FUNCTION__, section, sectionIndex);
    822     }
    823 
    824     // Get the tag name component of the name
    825     const char *nameTagName = name + sectionLength + 1; // x.y.z -> z
    826     if (sectionLength + 1 >= nameLength) {
    827         return BAD_VALUE;
    828     }
    829 
    830     // Match rest of name against the tag names in that section only
    831     uint32_t candidateTag = 0;
    832     if (sectionIndex < ANDROID_SECTION_COUNT) {
    833         // Match built-in tags (typically android.*)
    834         uint32_t tagBegin, tagEnd; // [tagBegin, tagEnd)
    835         tagBegin = camera_metadata_section_bounds[sectionIndex][0];
    836         tagEnd = camera_metadata_section_bounds[sectionIndex][1];
    837 
    838         for (candidateTag = tagBegin; candidateTag < tagEnd; ++candidateTag) {
    839             const char *tagName = get_camera_metadata_tag_name(candidateTag);
    840 
    841             if (strcmp(nameTagName, tagName) == 0) {
    842                 ALOGV("%s: Found matched tag '%s' (%d)",
    843                       __FUNCTION__, tagName, candidateTag);
    844                 break;
    845             }
    846         }
    847 
    848         if (candidateTag == tagEnd) {
    849             return NAME_NOT_FOUND;
    850         }
    851     } else if (vTags != NULL) {
    852         // Match vendor tags (typically com.*)
    853         const String8 sectionName(section);
    854         const String8 tagName(nameTagName);
    855 
    856         status_t res = OK;
    857         if ((res = vTags->lookupTag(tagName, sectionName, &candidateTag)) != OK) {
    858             return NAME_NOT_FOUND;
    859         }
    860     }
    861 
    862     *tag = candidateTag;
    863     return OK;
    864 }
    865 
    866 
    867 }; // namespace android
    868