status_t CameraMetadata::erase(uint32_t tag) {
    camera_metadata_entry_t entry;
    status_t res;
    if (mLocked) {
        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
        return INVALID_OPERATION;
    }
    res = find_camera_metadata_entry(mBuffer, tag, &entry);
    if (res == NAME_NOT_FOUND) {
        return OK;
    } else if (res != OK) {
        ALOGE("%s: Error looking for entry %s.%s (%x): %s %d",
                __FUNCTION__,
                get_camera_metadata_section_name(tag),
                get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
        return res;
    }
    res = delete_camera_metadata_entry(mBuffer, entry.index);
    if (res != OK) {
        ALOGE("%s: Error deleting entry %s.%s (%x): %s %d",
                __FUNCTION__,
                get_camera_metadata_section_name(tag),
                get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
    }
    return res;
}
status_t CameraMetadata::update(uint32_t tag, const void *data,
        size_t data_count) {
    status_t res;
    int type = get_camera_metadata_tag_type(tag);
    if (type == -1) {
        ALOGE("%s: Tag %d not found", __FUNCTION__, tag);
        return BAD_VALUE;
    }
    size_t data_size = calculate_camera_metadata_entry_data_size(type,
            data_count);

    res = resizeIfNeeded(1, data_size);

    if (res == OK) {
        camera_metadata_entry_t entry;
        res = find_camera_metadata_entry(mBuffer, tag, &entry);
        if (res == NAME_NOT_FOUND) {
            res = add_camera_metadata_entry(mBuffer,
                    tag, data, data_count);
        } else if (res == OK) {
            res = update_camera_metadata_entry(mBuffer,
                    entry.index, data, data_count, NULL);
        }
    }

    if (res != OK) {
        ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)",
                __FUNCTION__, get_camera_metadata_section_name(tag),
                get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
    }
    return res;
}
status_t CameraMetadata::updateImpl(uint32_t tag, const void *data,
        size_t data_count) {
    status_t res;
    if (mLocked) {
        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
        return INVALID_OPERATION;
    }
    int type = get_camera_metadata_tag_type(tag);
    if (type == -1) {
        ALOGE("%s: Tag %d not found", __FUNCTION__, tag);
        return BAD_VALUE;
    }
    // Safety check - ensure that data isn't pointing to this metadata, since
    // that would get invalidated if a resize is needed
    size_t bufferSize = get_camera_metadata_size(mBuffer);
    uintptr_t bufAddr = reinterpret_cast<uintptr_t>(mBuffer);
    uintptr_t dataAddr = reinterpret_cast<uintptr_t>(data);
    if (dataAddr > bufAddr && dataAddr < (bufAddr + bufferSize)) {
        ALOGE("%s: Update attempted with data from the same metadata buffer!",
                __FUNCTION__);
        return INVALID_OPERATION;
    }

    size_t data_size = calculate_camera_metadata_entry_data_size(type,
            data_count);

    res = resizeIfNeeded(1, data_size);

    if (res == OK) {
        camera_metadata_entry_t entry;
        res = find_camera_metadata_entry(mBuffer, tag, &entry);
        if (res == NAME_NOT_FOUND) {
            res = add_camera_metadata_entry(mBuffer,
                    tag, data, data_count);
        } else if (res == OK) {
            res = update_camera_metadata_entry(mBuffer,
                    entry.index, data, data_count, NULL);
        }
    }

    if (res != OK) {
        ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)",
                __FUNCTION__, get_camera_metadata_section_name(tag),
                get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
    }

    IF_ALOGV() {
        ALOGE_IF(validate_camera_metadata_structure(mBuffer, /*size*/NULL) !=
                 OK,

                 "%s: Failed to validate metadata structure after update %p",
                 __FUNCTION__, mBuffer);
    }

    return res;
}
const void * getMetadataValues(const camera_metadata_t * metadata, uint32_t tag, int type, int * count)
{
    status_t res = NO_ERROR;
    camera_metadata_ro_entry entry;
    res = find_camera_metadata_ro_entry(metadata, tag, &entry);
    if (res != OK) {
        LOGE("Failed to find %s.%s",
            get_camera_metadata_section_name(tag),
            get_camera_metadata_tag_name(tag));
        return NULL;
    }
    if (entry.type != type) {
        LOGE("Bad type %d for tag %s.%s! Should be %d",
            type,
            get_camera_metadata_section_name(tag),
            get_camera_metadata_tag_name(tag),
            entry.type);
        return NULL;
    }
    if (count)
        * count = entry.count;

    return entry.data.u8;
}
const void * getMetadataValues(const CameraMetadata &metadata, uint32_t tag, int type, int * count)
{
    camera_metadata_ro_entry entry = metadata.find(tag);
    if (entry.type != type) {
        LOGE("Bad type %d for tag %s.%s! Should be %d",
            type,
            get_camera_metadata_section_name(tag),
            get_camera_metadata_tag_name(tag),
            entry.type);
        return NULL;
    }
    if (count)
        * count = entry.count;
    return entry.data.u8;
}
status_t CameraMetadata::updateImpl(uint32_t tag, const void *data,
        size_t data_count) {
    status_t res;
    if (mLocked) {
        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
        return INVALID_OPERATION;
    }
    int type = get_camera_metadata_tag_type(tag);
    if (type == -1) {
        ALOGE("%s: Tag %d not found", __FUNCTION__, tag);
        return BAD_VALUE;
    }
    size_t data_size = calculate_camera_metadata_entry_data_size(type,
            data_count);

    res = resizeIfNeeded(1, data_size);

    if (res == OK) {
        camera_metadata_entry_t entry;
        res = find_camera_metadata_entry(mBuffer, tag, &entry);
        if (res == NAME_NOT_FOUND) {
            res = add_camera_metadata_entry(mBuffer,
                    tag, data, data_count);
        } else if (res == OK) {
            res = update_camera_metadata_entry(mBuffer,
                    entry.index, data, data_count, NULL);
        }
    }

    if (res != OK) {
        ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)",
                __FUNCTION__, get_camera_metadata_section_name(tag),
                get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
    }

    IF_ALOGV() {
        ALOGE_IF(validate_camera_metadata_structure(mBuffer, /*size*/NULL) !=
                 OK,

                 "%s: Failed to validate metadata structure after update %p",
                 __FUNCTION__, mBuffer);
    }

    return res;
}
void dumpMetadata(const camera_metadata_t * meta)
{
    if (!meta)
        return;
    if ((gLogLevel & CAMERA_DEBUG_LOG_LEVEL2) != CAMERA_DEBUG_LOG_LEVEL2)
        return;

    int entryCount = get_camera_metadata_entry_count(meta);

    for (int i = 0; i < entryCount; i++) {
        camera_metadata_entry_t entry;
        if (get_camera_metadata_entry((camera_metadata_t *)meta, i, &entry)) {
            continue;
        }

        // Print tag & type
        const char *tagName, *tagSection;
        tagSection = get_camera_metadata_section_name(entry.tag);
        if (tagSection == NULL) {
            tagSection = "unknownSection";
        }
        tagName = get_camera_metadata_tag_name(entry.tag);
        if (tagName == NULL) {
            tagName = "unknownTag";
        }
        const char *typeName;
        if (entry.type >= NUM_TYPES) {
            typeName = "unknown";
        } else {
            typeName = camera_metadata_type_names[entry.type];
        }
        LOG2("(%d)%s.%s (%05x): %s[%d], type: %d\n",
             i,
             tagSection,
             tagName,
             entry.tag,
             typeName,
             entry.count,
             entry.type);

        // Print data
#define MAX_DATA_COUNT 512
        size_t j;
        int length = 0;
        char str[64 + 8 * (MAX_DATA_COUNT)] = {0};
        const uint8_t *u8;
        const int32_t *i32;
        const float   *f;
        const int64_t *i64;
        const double  *d;
        const camera_metadata_rational_t *r;
        length = sprintf(str+length,"[");
        if (length < 0) {
            LOGW("%s sprintf failed at %d", __FUNCTION__, __LINE__);
            return;
        }
        switch (entry.type) {
        case TYPE_BYTE:
            u8 = entry.data.u8;
            for (j = 0; j < entry.count; j++) {
                length += sprintf(str+length, "%d ", u8[j]);
            }
            break;
        case TYPE_INT32:
            i32 = entry.data.i32;
            for (j = 0; j < entry.count; j++)
                length += sprintf(str+length, " %d ", i32[j]);
            break;
        case TYPE_FLOAT:
            f = entry.data.f;
            for (j = 0; j < entry.count; j++)
                length += sprintf(str+length, " %0.2f ", f[j]);
            break;
        case TYPE_INT64:
            i64 = entry.data.i64;
            for (j = 0; j < entry.count; j++)
                length += sprintf(str+length, " %lld ", i64[j]);
            break;
        case TYPE_DOUBLE:
            d = entry.data.d;
            for (j = 0; j < entry.count; j++)
                length += sprintf(str+length, " %0.2f ", d[j]);
            break;
        case TYPE_RATIONAL:
            r = entry.data.r;
            for (j = 0; j < entry.count; j++)
                length += sprintf(str+length, " (%d, %d) ", r[j].numerator, r[j].denominator);
            break;
        }
        if (length < 0) {
            LOGW("%s sprintf failed at %d", __FUNCTION__, __LINE__);
            return;
        }
        length += sprintf(str+length, "]");
        LOG2("%s", str);
    }

}