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 <camera/CameraMetadata.h>
     24 #include <binder/Parcel.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() {
     78     mLocked = true;
     79     return mBuffer;
     80 }
     81 
     82 status_t CameraMetadata::unlock(const camera_metadata_t *buffer) {
     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_camera_metadata_tag_type(tag);
    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_camera_metadata_tag_name(tag), 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::updateImpl(uint32_t tag, const void *data,
    281         size_t data_count) {
    282     status_t res;
    283     if (mLocked) {
    284         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    285         return INVALID_OPERATION;
    286     }
    287     int type = get_camera_metadata_tag_type(tag);
    288     if (type == -1) {
    289         ALOGE("%s: Tag %d not found", __FUNCTION__, tag);
    290         return BAD_VALUE;
    291     }
    292     size_t data_size = calculate_camera_metadata_entry_data_size(type,
    293             data_count);
    294 
    295     res = resizeIfNeeded(1, data_size);
    296 
    297     if (res == OK) {
    298         camera_metadata_entry_t entry;
    299         res = find_camera_metadata_entry(mBuffer, tag, &entry);
    300         if (res == NAME_NOT_FOUND) {
    301             res = add_camera_metadata_entry(mBuffer,
    302                     tag, data, data_count);
    303         } else if (res == OK) {
    304             res = update_camera_metadata_entry(mBuffer,
    305                     entry.index, data, data_count, NULL);
    306         }
    307     }
    308 
    309     if (res != OK) {
    310         ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)",
    311                 __FUNCTION__, get_camera_metadata_section_name(tag),
    312                 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
    313     }
    314 
    315     IF_ALOGV() {
    316         ALOGE_IF(validate_camera_metadata_structure(mBuffer, /*size*/NULL) !=
    317                  OK,
    318 
    319                  "%s: Failed to validate metadata structure after update %p",
    320                  __FUNCTION__, mBuffer);
    321     }
    322 
    323     return res;
    324 }
    325 
    326 bool CameraMetadata::exists(uint32_t tag) const {
    327     camera_metadata_ro_entry entry;
    328     return find_camera_metadata_ro_entry(mBuffer, tag, &entry) == 0;
    329 }
    330 
    331 camera_metadata_entry_t CameraMetadata::find(uint32_t tag) {
    332     status_t res;
    333     camera_metadata_entry entry;
    334     if (mLocked) {
    335         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    336         entry.count = 0;
    337         return entry;
    338     }
    339     res = find_camera_metadata_entry(mBuffer, tag, &entry);
    340     if (CC_UNLIKELY( res != OK )) {
    341         entry.count = 0;
    342         entry.data.u8 = NULL;
    343     }
    344     return entry;
    345 }
    346 
    347 camera_metadata_ro_entry_t CameraMetadata::find(uint32_t tag) const {
    348     status_t res;
    349     camera_metadata_ro_entry entry;
    350     res = find_camera_metadata_ro_entry(mBuffer, tag, &entry);
    351     if (CC_UNLIKELY( res != OK )) {
    352         entry.count = 0;
    353         entry.data.u8 = NULL;
    354     }
    355     return entry;
    356 }
    357 
    358 status_t CameraMetadata::erase(uint32_t tag) {
    359     camera_metadata_entry_t entry;
    360     status_t res;
    361     if (mLocked) {
    362         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    363         return INVALID_OPERATION;
    364     }
    365     res = find_camera_metadata_entry(mBuffer, tag, &entry);
    366     if (res == NAME_NOT_FOUND) {
    367         return OK;
    368     } else if (res != OK) {
    369         ALOGE("%s: Error looking for entry %s.%s (%x): %s %d",
    370                 __FUNCTION__,
    371                 get_camera_metadata_section_name(tag),
    372                 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
    373         return res;
    374     }
    375     res = delete_camera_metadata_entry(mBuffer, entry.index);
    376     if (res != OK) {
    377         ALOGE("%s: Error deleting entry %s.%s (%x): %s %d",
    378                 __FUNCTION__,
    379                 get_camera_metadata_section_name(tag),
    380                 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
    381     }
    382     return res;
    383 }
    384 
    385 void CameraMetadata::dump(int fd, int verbosity, int indentation) const {
    386     dump_indented_camera_metadata(mBuffer, fd, verbosity, indentation);
    387 }
    388 
    389 status_t CameraMetadata::resizeIfNeeded(size_t extraEntries, size_t extraData) {
    390     if (mBuffer == NULL) {
    391         mBuffer = allocate_camera_metadata(extraEntries * 2, extraData * 2);
    392         if (mBuffer == NULL) {
    393             ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__);
    394             return NO_MEMORY;
    395         }
    396     } else {
    397         size_t currentEntryCount = get_camera_metadata_entry_count(mBuffer);
    398         size_t currentEntryCap = get_camera_metadata_entry_capacity(mBuffer);
    399         size_t newEntryCount = currentEntryCount +
    400                 extraEntries;
    401         newEntryCount = (newEntryCount > currentEntryCap) ?
    402                 newEntryCount * 2 : currentEntryCap;
    403 
    404         size_t currentDataCount = get_camera_metadata_data_count(mBuffer);
    405         size_t currentDataCap = get_camera_metadata_data_capacity(mBuffer);
    406         size_t newDataCount = currentDataCount +
    407                 extraData;
    408         newDataCount = (newDataCount > currentDataCap) ?
    409                 newDataCount * 2 : currentDataCap;
    410 
    411         if (newEntryCount > currentEntryCap ||
    412                 newDataCount > currentDataCap) {
    413             camera_metadata_t *oldBuffer = mBuffer;
    414             mBuffer = allocate_camera_metadata(newEntryCount,
    415                     newDataCount);
    416             if (mBuffer == NULL) {
    417                 ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__);
    418                 return NO_MEMORY;
    419             }
    420             append_camera_metadata(mBuffer, oldBuffer);
    421             free_camera_metadata(oldBuffer);
    422         }
    423     }
    424     return OK;
    425 }
    426 
    427 status_t CameraMetadata::readFromParcel(const Parcel& data,
    428                                         camera_metadata_t** out) {
    429 
    430     status_t err = OK;
    431 
    432     camera_metadata_t* metadata = NULL;
    433 
    434     if (out) {
    435         *out = NULL;
    436     }
    437 
    438     // See CameraMetadata::writeToParcel for parcel data layout diagram and explanation.
    439     // arg0 = blobSize (int32)
    440     int32_t blobSizeTmp = -1;
    441     if ((err = data.readInt32(&blobSizeTmp)) != OK) {
    442         ALOGE("%s: Failed to read metadata size (error %d %s)",
    443               __FUNCTION__, err, strerror(-err));
    444         return err;
    445     }
    446     const size_t blobSize = static_cast<size_t>(blobSizeTmp);
    447     const size_t alignment = get_camera_metadata_alignment();
    448 
    449     // Special case: zero blob size means zero sized (NULL) metadata.
    450     if (blobSize == 0) {
    451         ALOGV("%s: Read 0-sized metadata", __FUNCTION__);
    452         return OK;
    453     }
    454 
    455     if (blobSize <= alignment) {
    456         ALOGE("%s: metadata blob is malformed, blobSize(%zu) should be larger than alignment(%zu)",
    457                 __FUNCTION__, blobSize, alignment);
    458         return BAD_VALUE;
    459     }
    460 
    461     const size_t metadataSize = blobSize - alignment;
    462 
    463     // NOTE: this doesn't make sense to me. shouldn't the blob
    464     // know how big it is? why do we have to specify the size
    465     // to Parcel::readBlob ?
    466     ReadableBlob blob;
    467     // arg1 = metadata (blob)
    468     do {
    469         if ((err = data.readBlob(blobSize, &blob)) != OK) {
    470             ALOGE("%s: Failed to read metadata blob (sized %zu). Possible "
    471                   " serialization bug. Error %d %s",
    472                   __FUNCTION__, blobSize, err, strerror(-err));
    473             break;
    474         }
    475 
    476         // arg2 = offset (blob)
    477         // Must be after blob since we don't know offset until after writeBlob.
    478         int32_t offsetTmp;
    479         if ((err = data.readInt32(&offsetTmp)) != OK) {
    480             ALOGE("%s: Failed to read metadata offsetTmp (error %d %s)",
    481                   __FUNCTION__, err, strerror(-err));
    482             break;
    483         }
    484         const size_t offset = static_cast<size_t>(offsetTmp);
    485         if (offset >= alignment) {
    486             ALOGE("%s: metadata offset(%zu) should be less than alignment(%zu)",
    487                     __FUNCTION__, blobSize, alignment);
    488             err = BAD_VALUE;
    489             break;
    490         }
    491 
    492         const uintptr_t metadataStart = reinterpret_cast<uintptr_t>(blob.data()) + offset;
    493         const camera_metadata_t* tmp =
    494                        reinterpret_cast<const camera_metadata_t*>(metadataStart);
    495         ALOGV("%s: alignment is: %zu, metadata start: %p, offset: %zu",
    496                 __FUNCTION__, alignment, tmp, offset);
    497         metadata = allocate_copy_camera_metadata_checked(tmp, metadataSize);
    498         if (metadata == NULL) {
    499             // We consider that allocation only fails if the validation
    500             // also failed, therefore the readFromParcel was a failure.
    501             ALOGE("%s: metadata allocation and copy failed", __FUNCTION__);
    502             err = BAD_VALUE;
    503         }
    504     } while(0);
    505     blob.release();
    506 
    507     if (out) {
    508         ALOGV("%s: Set out metadata to %p", __FUNCTION__, metadata);
    509         *out = metadata;
    510     } else if (metadata != NULL) {
    511         ALOGV("%s: Freed camera metadata at %p", __FUNCTION__, metadata);
    512         free_camera_metadata(metadata);
    513     }
    514 
    515     return err;
    516 }
    517 
    518 status_t CameraMetadata::writeToParcel(Parcel& data,
    519                                        const camera_metadata_t* metadata) {
    520     status_t res = OK;
    521 
    522     /**
    523      * Below is the camera metadata parcel layout:
    524      *
    525      * |--------------------------------------------|
    526      * |             arg0: blobSize                 |
    527      * |              (length = 4)                  |
    528      * |--------------------------------------------|<--Skip the rest if blobSize == 0.
    529      * |                                            |
    530      * |                                            |
    531      * |              arg1: blob                    |
    532      * | (length = variable, see arg1 layout below) |
    533      * |                                            |
    534      * |                                            |
    535      * |--------------------------------------------|
    536      * |              arg2: offset                  |
    537      * |              (length = 4)                  |
    538      * |--------------------------------------------|
    539      */
    540 
    541     // arg0 = blobSize (int32)
    542     if (metadata == NULL) {
    543         // Write zero blobSize for null metadata.
    544         return data.writeInt32(0);
    545     }
    546 
    547     /**
    548      * Always make the blob size sufficiently larger, as we need put alignment
    549      * padding and metadata into the blob. Since we don't know the alignment
    550      * offset before writeBlob. Then write the metadata to aligned offset.
    551      */
    552     const size_t metadataSize = get_camera_metadata_compact_size(metadata);
    553     const size_t alignment = get_camera_metadata_alignment();
    554     const size_t blobSize = metadataSize + alignment;
    555     res = data.writeInt32(static_cast<int32_t>(blobSize));
    556     if (res != OK) {
    557         return res;
    558     }
    559 
    560     size_t offset = 0;
    561     /**
    562      * arg1 = metadata (blob).
    563      *
    564      * The blob size is the sum of front padding size, metadata size and back padding
    565      * size, which is equal to metadataSize + alignment.
    566      *
    567      * The blob layout is:
    568      * |------------------------------------|<----Start address of the blob (unaligned).
    569      * |           front padding            |
    570      * |          (size = offset)           |
    571      * |------------------------------------|<----Aligned start address of metadata.
    572      * |                                    |
    573      * |                                    |
    574      * |            metadata                |
    575      * |       (size = metadataSize)        |
    576      * |                                    |
    577      * |                                    |
    578      * |------------------------------------|
    579      * |           back padding             |
    580      * |     (size = alignment - offset)    |
    581      * |------------------------------------|<----End address of blob.
    582      *                                            (Blob start address + blob size).
    583      */
    584     WritableBlob blob;
    585     do {
    586         res = data.writeBlob(blobSize, &blob);
    587         if (res != OK) {
    588             break;
    589         }
    590         const uintptr_t metadataStart = ALIGN_TO(blob.data(), alignment);
    591         offset = metadataStart - reinterpret_cast<uintptr_t>(blob.data());
    592         ALOGV("%s: alignment is: %zu, metadata start: %p, offset: %zu",
    593                 __FUNCTION__, alignment,
    594                 reinterpret_cast<const void *>(metadataStart), offset);
    595         copy_camera_metadata(reinterpret_cast<void*>(metadataStart), metadataSize, metadata);
    596 
    597         // Not too big of a problem since receiving side does hard validation
    598         // Don't check the size since the compact size could be larger
    599         if (validate_camera_metadata_structure(metadata, /*size*/NULL) != OK) {
    600             ALOGW("%s: Failed to validate metadata %p before writing blob",
    601                    __FUNCTION__, metadata);
    602         }
    603 
    604     } while(false);
    605     blob.release();
    606 
    607     // arg2 = offset (int32)
    608     res = data.writeInt32(static_cast<int32_t>(offset));
    609 
    610     return res;
    611 }
    612 
    613 status_t CameraMetadata::readFromParcel(Parcel *parcel) {
    614 
    615     ALOGV("%s: parcel = %p", __FUNCTION__, parcel);
    616 
    617     status_t res = OK;
    618 
    619     if (parcel == NULL) {
    620         ALOGE("%s: parcel is null", __FUNCTION__);
    621         return BAD_VALUE;
    622     }
    623 
    624     if (mLocked) {
    625         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    626         return INVALID_OPERATION;
    627     }
    628 
    629     camera_metadata *buffer = NULL;
    630     // TODO: reading should return a status code, in case validation fails
    631     res = CameraMetadata::readFromParcel(*parcel, &buffer);
    632 
    633     if (res != NO_ERROR) {
    634         ALOGE("%s: Failed to read from parcel. Metadata is unchanged.",
    635               __FUNCTION__);
    636         return res;
    637     }
    638 
    639     clear();
    640     mBuffer = buffer;
    641 
    642     return OK;
    643 }
    644 
    645 status_t CameraMetadata::writeToParcel(Parcel *parcel) const {
    646 
    647     ALOGV("%s: parcel = %p", __FUNCTION__, parcel);
    648 
    649     if (parcel == NULL) {
    650         ALOGE("%s: parcel is null", __FUNCTION__);
    651         return BAD_VALUE;
    652     }
    653 
    654     return CameraMetadata::writeToParcel(*parcel, mBuffer);
    655 }
    656 
    657 void CameraMetadata::swap(CameraMetadata& other) {
    658     if (mLocked) {
    659         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    660         return;
    661     } else if (other.mLocked) {
    662         ALOGE("%s: Other CameraMetadata is locked", __FUNCTION__);
    663         return;
    664     }
    665 
    666     camera_metadata* thisBuf = mBuffer;
    667     camera_metadata* otherBuf = other.mBuffer;
    668 
    669     other.mBuffer = thisBuf;
    670     mBuffer = otherBuf;
    671 }
    672 
    673 }; // namespace android
    674