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