1cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala/*
2cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala * Copyright (C) 2012 The Android Open Source Project
3cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala *
4cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala * Licensed under the Apache License, Version 2.0 (the "License");
5cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala * you may not use this file except in compliance with the License.
6cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala * You may obtain a copy of the License at
7cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala *
8cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala *      http://www.apache.org/licenses/LICENSE-2.0
9cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala *
10cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala * Unless required by applicable law or agreed to in writing, software
11cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala * distributed under the License is distributed on an "AS IS" BASIS,
12cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala * See the License for the specific language governing permissions and
14cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala * limitations under the License.
15cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala */
16cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
17e2d1e3d0436aec645739c65e6d3131dd814f40a1Igor Murashkin// #define LOG_NDEBUG 0
18e2d1e3d0436aec645739c65e6d3131dd814f40a1Igor Murashkin
194bb8118816874c696d9f1adab48490df1da365f7Eino-Ville Talvala#define LOG_TAG "Camera2-Metadata"
20cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala#include <utils/Log.h>
21cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala#include <utils/Errors.h>
22cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
23e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin#include <binder/Parcel.h>
244d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala#include <camera/CameraMetadata.h>
254d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala#include <camera/VendorTagDescriptor.h>
26cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
27cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvalanamespace android {
28cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
29146aed1ec05579b8840a592c3654c641ab36065cZhijun He#define ALIGN_TO(val, alignment) \
30146aed1ec05579b8840a592c3654c641ab36065cZhijun He    (((uintptr_t)(val) + ((alignment) - 1)) & ~((alignment) - 1))
31146aed1ec05579b8840a592c3654c641ab36065cZhijun He
32e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkintypedef Parcel::WritableBlob WritableBlob;
33e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkintypedef Parcel::ReadableBlob ReadableBlob;
34e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
35cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville TalvalaCameraMetadata::CameraMetadata() :
363b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        mBuffer(NULL), mLocked(false) {
37cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala}
38cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
393b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville TalvalaCameraMetadata::CameraMetadata(size_t entryCapacity, size_t dataCapacity) :
403b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        mLocked(false)
41cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala{
42cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    mBuffer = allocate_camera_metadata(entryCapacity, dataCapacity);
43cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala}
44cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
453b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville TalvalaCameraMetadata::CameraMetadata(const CameraMetadata &other) :
463b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        mLocked(false) {
47cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    mBuffer = clone_camera_metadata(other.mBuffer);
48cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala}
49cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
503b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville TalvalaCameraMetadata::CameraMetadata(camera_metadata_t *buffer) :
513b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        mBuffer(NULL), mLocked(false) {
527efa520c76e6a1f6b3146404cc6aca5a8353583aIgor Murashkin    acquire(buffer);
537efa520c76e6a1f6b3146404cc6aca5a8353583aIgor Murashkin}
547efa520c76e6a1f6b3146404cc6aca5a8353583aIgor Murashkin
55cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville TalvalaCameraMetadata &CameraMetadata::operator=(const CameraMetadata &other) {
56cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    return operator=(other.mBuffer);
57cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala}
58cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
59cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville TalvalaCameraMetadata &CameraMetadata::operator=(const camera_metadata_t *buffer) {
603b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    if (mLocked) {
613b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        ALOGE("%s: Assignment to a locked CameraMetadata!", __FUNCTION__);
623b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        return *this;
633b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    }
643b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala
65cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    if (CC_LIKELY(buffer != mBuffer)) {
66cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        camera_metadata_t *newBuffer = clone_camera_metadata(buffer);
67cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        clear();
68cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        mBuffer = newBuffer;
69cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    }
70cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    return *this;
71cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala}
72cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
73cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville TalvalaCameraMetadata::~CameraMetadata() {
743b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    mLocked = false;
75cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    clear();
76cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala}
77cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
7854298b338cf9f782f2ac681a15e6cbbb99649350Yin-Chia Yehconst camera_metadata_t* CameraMetadata::getAndLock() const {
793b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    mLocked = true;
803b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    return mBuffer;
813b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala}
823b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala
838aac03f4d6c66749803d5708086ba5f509aa88c6Yin-Chia Yehstatus_t CameraMetadata::unlock(const camera_metadata_t *buffer) const {
843b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    if (!mLocked) {
853b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        ALOGE("%s: Can't unlock a non-locked CameraMetadata!", __FUNCTION__);
863b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        return INVALID_OPERATION;
873b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    }
883b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    if (buffer != mBuffer) {
893b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        ALOGE("%s: Can't unlock CameraMetadata with wrong pointer!",
903b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala                __FUNCTION__);
913b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        return BAD_VALUE;
923b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    }
933b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    mLocked = false;
943b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    return OK;
953b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala}
963b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala
97cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvalacamera_metadata_t* CameraMetadata::release() {
983b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    if (mLocked) {
993b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
1003b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        return NULL;
1013b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    }
102cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    camera_metadata_t *released = mBuffer;
103cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    mBuffer = NULL;
104cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    return released;
105cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala}
106cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
107cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvalavoid CameraMetadata::clear() {
1083b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    if (mLocked) {
1093b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
1103b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        return;
1113b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    }
112cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    if (mBuffer) {
113cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        free_camera_metadata(mBuffer);
114cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        mBuffer = NULL;
115cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    }
116cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala}
117cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
118cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvalavoid CameraMetadata::acquire(camera_metadata_t *buffer) {
1193b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    if (mLocked) {
1203b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
1213b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        return;
1223b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    }
123cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    clear();
124cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    mBuffer = buffer;
125e2d1e3d0436aec645739c65e6d3131dd814f40a1Igor Murashkin
126e2d1e3d0436aec645739c65e6d3131dd814f40a1Igor Murashkin    ALOGE_IF(validate_camera_metadata_structure(mBuffer, /*size*/NULL) != OK,
127e2d1e3d0436aec645739c65e6d3131dd814f40a1Igor Murashkin             "%s: Failed to validate metadata structure %p",
128e2d1e3d0436aec645739c65e6d3131dd814f40a1Igor Murashkin             __FUNCTION__, buffer);
129cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala}
130cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
131cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvalavoid CameraMetadata::acquire(CameraMetadata &other) {
1323b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    if (mLocked) {
1333b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
1343b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        return;
1353b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    }
136cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    acquire(other.release());
137cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala}
138cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
139cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvalastatus_t CameraMetadata::append(const CameraMetadata &other) {
140fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    return append(other.mBuffer);
141fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala}
142fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
143fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvalastatus_t CameraMetadata::append(const camera_metadata_t* other) {
1443b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    if (mLocked) {
1453b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
1463b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        return INVALID_OPERATION;
1473b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    }
148fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    size_t extraEntries = get_camera_metadata_entry_count(other);
149fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    size_t extraData = get_camera_metadata_data_count(other);
150fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    resizeIfNeeded(extraEntries, extraData);
151fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
152fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    return append_camera_metadata(mBuffer, other);
153cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala}
154cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
155cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvalasize_t CameraMetadata::entryCount() const {
156cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    return (mBuffer == NULL) ? 0 :
157cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala            get_camera_metadata_entry_count(mBuffer);
158cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala}
159cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
160da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvalabool CameraMetadata::isEmpty() const {
161da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala    return entryCount() == 0;
162da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala}
163da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala
164cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvalastatus_t CameraMetadata::sort() {
1653b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    if (mLocked) {
1663b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
1673b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        return INVALID_OPERATION;
1683b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    }
169cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    return sort_camera_metadata(mBuffer);
170cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala}
171cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
172cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvalastatus_t CameraMetadata::checkType(uint32_t tag, uint8_t expectedType) {
17371c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    int tagType = get_local_camera_metadata_tag_type(tag, mBuffer);
174cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    if ( CC_UNLIKELY(tagType == -1)) {
175cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        ALOGE("Update metadata entry: Unknown tag %d", tag);
176cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        return INVALID_OPERATION;
177cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    }
178cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    if ( CC_UNLIKELY(tagType != expectedType) ) {
179cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        ALOGE("Mismatched tag type when updating entry %s (%d) of type %s; "
180cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala                "got type %s data instead ",
18171c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                get_local_camera_metadata_tag_name(tag, mBuffer), tag,
182cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala                camera_metadata_type_names[tagType],
183cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala                camera_metadata_type_names[expectedType]);
184cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        return INVALID_OPERATION;
185cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    }
186cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    return OK;
187cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala}
188cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
189cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvalastatus_t CameraMetadata::update(uint32_t tag,
190cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        const int32_t *data, size_t data_count) {
191cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    status_t res;
1923b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    if (mLocked) {
1933b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
1943b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        return INVALID_OPERATION;
1953b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    }
196cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    if ( (res = checkType(tag, TYPE_INT32)) != OK) {
197cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        return res;
198cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    }
1993b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    return updateImpl(tag, (const void*)data, data_count);
200cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala}
201cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
202cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvalastatus_t CameraMetadata::update(uint32_t tag,
203cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        const uint8_t *data, size_t data_count) {
204cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    status_t res;
2053b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    if (mLocked) {
2063b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
2073b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        return INVALID_OPERATION;
2083b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    }
209cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    if ( (res = checkType(tag, TYPE_BYTE)) != OK) {
210cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        return res;
211cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    }
2123b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    return updateImpl(tag, (const void*)data, data_count);
213cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala}
214cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
215cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvalastatus_t CameraMetadata::update(uint32_t tag,
216cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        const float *data, size_t data_count) {
217cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    status_t res;
2183b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    if (mLocked) {
2193b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
2203b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        return INVALID_OPERATION;
2213b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    }
222cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    if ( (res = checkType(tag, TYPE_FLOAT)) != OK) {
223cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        return res;
224cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    }
2253b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    return updateImpl(tag, (const void*)data, data_count);
226cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala}
227cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
228cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvalastatus_t CameraMetadata::update(uint32_t tag,
229cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        const int64_t *data, size_t data_count) {
230cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    status_t res;
2313b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    if (mLocked) {
2323b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
2333b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        return INVALID_OPERATION;
2343b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    }
235cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    if ( (res = checkType(tag, TYPE_INT64)) != OK) {
236cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        return res;
237cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    }
2383b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    return updateImpl(tag, (const void*)data, data_count);
239cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala}
240cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
241cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvalastatus_t CameraMetadata::update(uint32_t tag,
242cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        const double *data, size_t data_count) {
243cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    status_t res;
2443b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    if (mLocked) {
2453b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
2463b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        return INVALID_OPERATION;
2473b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    }
248cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    if ( (res = checkType(tag, TYPE_DOUBLE)) != OK) {
249cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        return res;
250cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    }
2513b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    return updateImpl(tag, (const void*)data, data_count);
252cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala}
253cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
254cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvalastatus_t CameraMetadata::update(uint32_t tag,
255cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        const camera_metadata_rational_t *data, size_t data_count) {
256cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    status_t res;
2573b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    if (mLocked) {
2583b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
2593b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        return INVALID_OPERATION;
2603b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    }
261cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    if ( (res = checkType(tag, TYPE_RATIONAL)) != OK) {
262cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        return res;
263cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    }
2643b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    return updateImpl(tag, (const void*)data, data_count);
265cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala}
266cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
267cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvalastatus_t CameraMetadata::update(uint32_t tag,
268cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        const String8 &string) {
269cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    status_t res;
2703b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    if (mLocked) {
2713b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
2723b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        return INVALID_OPERATION;
2733b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    }
274cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    if ( (res = checkType(tag, TYPE_BYTE)) != OK) {
275cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        return res;
276cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    }
2777595c47b4842d76dba0fcf26ef3ab98d215efe1eZhijun He    // string.size() doesn't count the null termination character.
2787595c47b4842d76dba0fcf26ef3ab98d215efe1eZhijun He    return updateImpl(tag, (const void*)string.string(), string.size() + 1);
279cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala}
280cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
2814d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvalastatus_t CameraMetadata::update(const camera_metadata_ro_entry &entry) {
2824d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala    status_t res;
2834d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala    if (mLocked) {
2844d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
2854d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala        return INVALID_OPERATION;
2864d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala    }
2874d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala    if ( (res = checkType(entry.tag, entry.type)) != OK) {
2884d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala        return res;
2894d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala    }
2904d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala    return updateImpl(entry.tag, (const void*)entry.data.u8, entry.count);
2914d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala}
2924d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala
2933b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvalastatus_t CameraMetadata::updateImpl(uint32_t tag, const void *data,
294cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        size_t data_count) {
295cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    status_t res;
2963b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    if (mLocked) {
2973b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
2983b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        return INVALID_OPERATION;
2993b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    }
30071c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    int type = get_local_camera_metadata_tag_type(tag, mBuffer);
301cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    if (type == -1) {
302cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        ALOGE("%s: Tag %d not found", __FUNCTION__, tag);
303cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        return BAD_VALUE;
304cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    }
305e2b60c810282b7cd09af8544dd479ff5adba46f0Eino-Ville Talvala    // Safety check - ensure that data isn't pointing to this metadata, since
306e2b60c810282b7cd09af8544dd479ff5adba46f0Eino-Ville Talvala    // that would get invalidated if a resize is needed
307e2b60c810282b7cd09af8544dd479ff5adba46f0Eino-Ville Talvala    size_t bufferSize = get_camera_metadata_size(mBuffer);
308e2b60c810282b7cd09af8544dd479ff5adba46f0Eino-Ville Talvala    uintptr_t bufAddr = reinterpret_cast<uintptr_t>(mBuffer);
309e2b60c810282b7cd09af8544dd479ff5adba46f0Eino-Ville Talvala    uintptr_t dataAddr = reinterpret_cast<uintptr_t>(data);
310e2b60c810282b7cd09af8544dd479ff5adba46f0Eino-Ville Talvala    if (dataAddr > bufAddr && dataAddr < (bufAddr + bufferSize)) {
311e2b60c810282b7cd09af8544dd479ff5adba46f0Eino-Ville Talvala        ALOGE("%s: Update attempted with data from the same metadata buffer!",
312e2b60c810282b7cd09af8544dd479ff5adba46f0Eino-Ville Talvala                __FUNCTION__);
313e2b60c810282b7cd09af8544dd479ff5adba46f0Eino-Ville Talvala        return INVALID_OPERATION;
314e2b60c810282b7cd09af8544dd479ff5adba46f0Eino-Ville Talvala    }
315e2b60c810282b7cd09af8544dd479ff5adba46f0Eino-Ville Talvala
316cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    size_t data_size = calculate_camera_metadata_entry_data_size(type,
317cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala            data_count);
318cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
319cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    res = resizeIfNeeded(1, data_size);
320cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
321cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    if (res == OK) {
322cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        camera_metadata_entry_t entry;
323cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        res = find_camera_metadata_entry(mBuffer, tag, &entry);
324cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        if (res == NAME_NOT_FOUND) {
325cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala            res = add_camera_metadata_entry(mBuffer,
326cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala                    tag, data, data_count);
327cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        } else if (res == OK) {
328cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala            res = update_camera_metadata_entry(mBuffer,
329cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala                    entry.index, data, data_count, NULL);
330cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        }
331cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    }
332cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
333cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    if (res != OK) {
334cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)",
33571c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                __FUNCTION__, get_local_camera_metadata_section_name(tag, mBuffer),
33671c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                get_local_camera_metadata_tag_name(tag, mBuffer), tag,
33771c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                strerror(-res), res);
338cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    }
339e2d1e3d0436aec645739c65e6d3131dd814f40a1Igor Murashkin
340e2d1e3d0436aec645739c65e6d3131dd814f40a1Igor Murashkin    IF_ALOGV() {
341e2d1e3d0436aec645739c65e6d3131dd814f40a1Igor Murashkin        ALOGE_IF(validate_camera_metadata_structure(mBuffer, /*size*/NULL) !=
342e2d1e3d0436aec645739c65e6d3131dd814f40a1Igor Murashkin                 OK,
343e2d1e3d0436aec645739c65e6d3131dd814f40a1Igor Murashkin
344e2d1e3d0436aec645739c65e6d3131dd814f40a1Igor Murashkin                 "%s: Failed to validate metadata structure after update %p",
345e2d1e3d0436aec645739c65e6d3131dd814f40a1Igor Murashkin                 __FUNCTION__, mBuffer);
346e2d1e3d0436aec645739c65e6d3131dd814f40a1Igor Murashkin    }
347e2d1e3d0436aec645739c65e6d3131dd814f40a1Igor Murashkin
348cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    return res;
349cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala}
350cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
351fc42642ab78da5fe25bcbea7a568bf880268a9dcIgor Murashkinbool CameraMetadata::exists(uint32_t tag) const {
352fc42642ab78da5fe25bcbea7a568bf880268a9dcIgor Murashkin    camera_metadata_ro_entry entry;
353fc42642ab78da5fe25bcbea7a568bf880268a9dcIgor Murashkin    return find_camera_metadata_ro_entry(mBuffer, tag, &entry) == 0;
354fc42642ab78da5fe25bcbea7a568bf880268a9dcIgor Murashkin}
355fc42642ab78da5fe25bcbea7a568bf880268a9dcIgor Murashkin
356cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvalacamera_metadata_entry_t CameraMetadata::find(uint32_t tag) {
357cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    status_t res;
358cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    camera_metadata_entry entry;
3593b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    if (mLocked) {
3603b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
3613b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        entry.count = 0;
3623b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        return entry;
3633b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    }
364cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    res = find_camera_metadata_entry(mBuffer, tag, &entry);
365cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    if (CC_UNLIKELY( res != OK )) {
366cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        entry.count = 0;
367cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        entry.data.u8 = NULL;
368cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    }
369cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    return entry;
370cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala}
371cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
372cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvalacamera_metadata_ro_entry_t CameraMetadata::find(uint32_t tag) const {
373cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    status_t res;
374cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    camera_metadata_ro_entry entry;
375cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    res = find_camera_metadata_ro_entry(mBuffer, tag, &entry);
376cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    if (CC_UNLIKELY( res != OK )) {
377cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        entry.count = 0;
378cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        entry.data.u8 = NULL;
379cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    }
380cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    return entry;
381cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala}
382cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
383cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvalastatus_t CameraMetadata::erase(uint32_t tag) {
384cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    camera_metadata_entry_t entry;
385cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    status_t res;
3863b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    if (mLocked) {
3873b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
3883b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala        return INVALID_OPERATION;
3893b53bc9b41c262d22f094406e3751bc5a41ef2efEino-Ville Talvala    }
390cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    res = find_camera_metadata_entry(mBuffer, tag, &entry);
391cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    if (res == NAME_NOT_FOUND) {
392cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        return OK;
393cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    } else if (res != OK) {
394cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        ALOGE("%s: Error looking for entry %s.%s (%x): %s %d",
395cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala                __FUNCTION__,
39671c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                get_local_camera_metadata_section_name(tag, mBuffer),
39771c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                get_local_camera_metadata_tag_name(tag, mBuffer),
39871c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                tag, strerror(-res), res);
399cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        return res;
400cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    }
401cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    res = delete_camera_metadata_entry(mBuffer, entry.index);
402cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    if (res != OK) {
403cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        ALOGE("%s: Error deleting entry %s.%s (%x): %s %d",
404cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala                __FUNCTION__,
40571c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                get_local_camera_metadata_section_name(tag, mBuffer),
40671c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                get_local_camera_metadata_tag_name(tag, mBuffer),
40771c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                tag, strerror(-res), res);
408cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    }
409cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    return res;
410cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala}
411cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
412cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvalavoid CameraMetadata::dump(int fd, int verbosity, int indentation) const {
413cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    dump_indented_camera_metadata(mBuffer, fd, verbosity, indentation);
414cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala}
415cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
416cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvalastatus_t CameraMetadata::resizeIfNeeded(size_t extraEntries, size_t extraData) {
417cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    if (mBuffer == NULL) {
418cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        mBuffer = allocate_camera_metadata(extraEntries * 2, extraData * 2);
419cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        if (mBuffer == NULL) {
420cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala            ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__);
421cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala            return NO_MEMORY;
422cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        }
423cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    } else {
424cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        size_t currentEntryCount = get_camera_metadata_entry_count(mBuffer);
425cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        size_t currentEntryCap = get_camera_metadata_entry_capacity(mBuffer);
426cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        size_t newEntryCount = currentEntryCount +
427cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala                extraEntries;
428cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        newEntryCount = (newEntryCount > currentEntryCap) ?
429cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala                newEntryCount * 2 : currentEntryCap;
430cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
431cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        size_t currentDataCount = get_camera_metadata_data_count(mBuffer);
432cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        size_t currentDataCap = get_camera_metadata_data_capacity(mBuffer);
433cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        size_t newDataCount = currentDataCount +
434cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala                extraData;
435cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        newDataCount = (newDataCount > currentDataCap) ?
436cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala                newDataCount * 2 : currentDataCap;
437cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
438cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        if (newEntryCount > currentEntryCap ||
439cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala                newDataCount > currentDataCap) {
440cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala            camera_metadata_t *oldBuffer = mBuffer;
441cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala            mBuffer = allocate_camera_metadata(newEntryCount,
442cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala                    newDataCount);
443cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala            if (mBuffer == NULL) {
444cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala                ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__);
445cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala                return NO_MEMORY;
446cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala            }
447cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala            append_camera_metadata(mBuffer, oldBuffer);
448cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala            free_camera_metadata(oldBuffer);
449cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala        }
450cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    }
451cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala    return OK;
452cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala}
453cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala
454e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinstatus_t CameraMetadata::readFromParcel(const Parcel& data,
455e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                                        camera_metadata_t** out) {
456e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
457e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    status_t err = OK;
458e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
459e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    camera_metadata_t* metadata = NULL;
460e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
461e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (out) {
462e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        *out = NULL;
463e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
464e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
465146aed1ec05579b8840a592c3654c641ab36065cZhijun He    // See CameraMetadata::writeToParcel for parcel data layout diagram and explanation.
466146aed1ec05579b8840a592c3654c641ab36065cZhijun He    // arg0 = blobSize (int32)
467146aed1ec05579b8840a592c3654c641ab36065cZhijun He    int32_t blobSizeTmp = -1;
468146aed1ec05579b8840a592c3654c641ab36065cZhijun He    if ((err = data.readInt32(&blobSizeTmp)) != OK) {
469e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ALOGE("%s: Failed to read metadata size (error %d %s)",
470e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin              __FUNCTION__, err, strerror(-err));
471e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        return err;
472e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
473146aed1ec05579b8840a592c3654c641ab36065cZhijun He    const size_t blobSize = static_cast<size_t>(blobSizeTmp);
474146aed1ec05579b8840a592c3654c641ab36065cZhijun He    const size_t alignment = get_camera_metadata_alignment();
475e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
476146aed1ec05579b8840a592c3654c641ab36065cZhijun He    // Special case: zero blob size means zero sized (NULL) metadata.
477146aed1ec05579b8840a592c3654c641ab36065cZhijun He    if (blobSize == 0) {
478e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ALOGV("%s: Read 0-sized metadata", __FUNCTION__);
479e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        return OK;
480e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
481e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
482146aed1ec05579b8840a592c3654c641ab36065cZhijun He    if (blobSize <= alignment) {
483146aed1ec05579b8840a592c3654c641ab36065cZhijun He        ALOGE("%s: metadata blob is malformed, blobSize(%zu) should be larger than alignment(%zu)",
484146aed1ec05579b8840a592c3654c641ab36065cZhijun He                __FUNCTION__, blobSize, alignment);
485146aed1ec05579b8840a592c3654c641ab36065cZhijun He        return BAD_VALUE;
486146aed1ec05579b8840a592c3654c641ab36065cZhijun He    }
487146aed1ec05579b8840a592c3654c641ab36065cZhijun He
488146aed1ec05579b8840a592c3654c641ab36065cZhijun He    const size_t metadataSize = blobSize - alignment;
489146aed1ec05579b8840a592c3654c641ab36065cZhijun He
490146aed1ec05579b8840a592c3654c641ab36065cZhijun He    // NOTE: this doesn't make sense to me. shouldn't the blob
491e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    // know how big it is? why do we have to specify the size
492e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    // to Parcel::readBlob ?
493e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ReadableBlob blob;
494e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    // arg1 = metadata (blob)
495e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    do {
496146aed1ec05579b8840a592c3654c641ab36065cZhijun He        if ((err = data.readBlob(blobSize, &blob)) != OK) {
497146aed1ec05579b8840a592c3654c641ab36065cZhijun He            ALOGE("%s: Failed to read metadata blob (sized %zu). Possible "
498e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                  " serialization bug. Error %d %s",
499146aed1ec05579b8840a592c3654c641ab36065cZhijun He                  __FUNCTION__, blobSize, err, strerror(-err));
500e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            break;
501e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        }
502e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
503146aed1ec05579b8840a592c3654c641ab36065cZhijun He        // arg2 = offset (blob)
504146aed1ec05579b8840a592c3654c641ab36065cZhijun He        // Must be after blob since we don't know offset until after writeBlob.
505146aed1ec05579b8840a592c3654c641ab36065cZhijun He        int32_t offsetTmp;
506146aed1ec05579b8840a592c3654c641ab36065cZhijun He        if ((err = data.readInt32(&offsetTmp)) != OK) {
507146aed1ec05579b8840a592c3654c641ab36065cZhijun He            ALOGE("%s: Failed to read metadata offsetTmp (error %d %s)",
508146aed1ec05579b8840a592c3654c641ab36065cZhijun He                  __FUNCTION__, err, strerror(-err));
509146aed1ec05579b8840a592c3654c641ab36065cZhijun He            break;
510146aed1ec05579b8840a592c3654c641ab36065cZhijun He        }
511146aed1ec05579b8840a592c3654c641ab36065cZhijun He        const size_t offset = static_cast<size_t>(offsetTmp);
512146aed1ec05579b8840a592c3654c641ab36065cZhijun He        if (offset >= alignment) {
513146aed1ec05579b8840a592c3654c641ab36065cZhijun He            ALOGE("%s: metadata offset(%zu) should be less than alignment(%zu)",
514146aed1ec05579b8840a592c3654c641ab36065cZhijun He                    __FUNCTION__, blobSize, alignment);
515146aed1ec05579b8840a592c3654c641ab36065cZhijun He            err = BAD_VALUE;
516146aed1ec05579b8840a592c3654c641ab36065cZhijun He            break;
517146aed1ec05579b8840a592c3654c641ab36065cZhijun He        }
518146aed1ec05579b8840a592c3654c641ab36065cZhijun He
519146aed1ec05579b8840a592c3654c641ab36065cZhijun He        const uintptr_t metadataStart = reinterpret_cast<uintptr_t>(blob.data()) + offset;
520146aed1ec05579b8840a592c3654c641ab36065cZhijun He        const camera_metadata_t* tmp =
521146aed1ec05579b8840a592c3654c641ab36065cZhijun He                       reinterpret_cast<const camera_metadata_t*>(metadataStart);
522146aed1ec05579b8840a592c3654c641ab36065cZhijun He        ALOGV("%s: alignment is: %zu, metadata start: %p, offset: %zu",
523146aed1ec05579b8840a592c3654c641ab36065cZhijun He                __FUNCTION__, alignment, tmp, offset);
524e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        metadata = allocate_copy_camera_metadata_checked(tmp, metadataSize);
525e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        if (metadata == NULL) {
526e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            // We consider that allocation only fails if the validation
527e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            // also failed, therefore the readFromParcel was a failure.
528146aed1ec05579b8840a592c3654c641ab36065cZhijun He            ALOGE("%s: metadata allocation and copy failed", __FUNCTION__);
529e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            err = BAD_VALUE;
530e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        }
531e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    } while(0);
532e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    blob.release();
533e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
534e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (out) {
535e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ALOGV("%s: Set out metadata to %p", __FUNCTION__, metadata);
536e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        *out = metadata;
537e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    } else if (metadata != NULL) {
538e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ALOGV("%s: Freed camera metadata at %p", __FUNCTION__, metadata);
539e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        free_camera_metadata(metadata);
540e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
541e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
542e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    return err;
543e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
544e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
545e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinstatus_t CameraMetadata::writeToParcel(Parcel& data,
546e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                                       const camera_metadata_t* metadata) {
547e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    status_t res = OK;
548e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
549146aed1ec05579b8840a592c3654c641ab36065cZhijun He    /**
550146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * Below is the camera metadata parcel layout:
551146aed1ec05579b8840a592c3654c641ab36065cZhijun He     *
552146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * |--------------------------------------------|
553146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * |             arg0: blobSize                 |
554146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * |              (length = 4)                  |
555146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * |--------------------------------------------|<--Skip the rest if blobSize == 0.
556146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * |                                            |
557146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * |                                            |
558146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * |              arg1: blob                    |
559146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * | (length = variable, see arg1 layout below) |
560146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * |                                            |
561146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * |                                            |
562146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * |--------------------------------------------|
563146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * |              arg2: offset                  |
564146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * |              (length = 4)                  |
565146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * |--------------------------------------------|
566146aed1ec05579b8840a592c3654c641ab36065cZhijun He     */
567146aed1ec05579b8840a592c3654c641ab36065cZhijun He
568146aed1ec05579b8840a592c3654c641ab36065cZhijun He    // arg0 = blobSize (int32)
569e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (metadata == NULL) {
570146aed1ec05579b8840a592c3654c641ab36065cZhijun He        // Write zero blobSize for null metadata.
571e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        return data.writeInt32(0);
572e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
573e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
574146aed1ec05579b8840a592c3654c641ab36065cZhijun He    /**
575146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * Always make the blob size sufficiently larger, as we need put alignment
576146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * padding and metadata into the blob. Since we don't know the alignment
577146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * offset before writeBlob. Then write the metadata to aligned offset.
578146aed1ec05579b8840a592c3654c641ab36065cZhijun He     */
579e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    const size_t metadataSize = get_camera_metadata_compact_size(metadata);
580146aed1ec05579b8840a592c3654c641ab36065cZhijun He    const size_t alignment = get_camera_metadata_alignment();
581146aed1ec05579b8840a592c3654c641ab36065cZhijun He    const size_t blobSize = metadataSize + alignment;
582146aed1ec05579b8840a592c3654c641ab36065cZhijun He    res = data.writeInt32(static_cast<int32_t>(blobSize));
583e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (res != OK) {
584e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        return res;
585e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
586e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
587146aed1ec05579b8840a592c3654c641ab36065cZhijun He    size_t offset = 0;
588146aed1ec05579b8840a592c3654c641ab36065cZhijun He    /**
589146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * arg1 = metadata (blob).
590146aed1ec05579b8840a592c3654c641ab36065cZhijun He     *
591146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * The blob size is the sum of front padding size, metadata size and back padding
592146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * size, which is equal to metadataSize + alignment.
593146aed1ec05579b8840a592c3654c641ab36065cZhijun He     *
594146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * The blob layout is:
595146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * |------------------------------------|<----Start address of the blob (unaligned).
596146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * |           front padding            |
597146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * |          (size = offset)           |
598146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * |------------------------------------|<----Aligned start address of metadata.
599146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * |                                    |
600146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * |                                    |
601146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * |            metadata                |
602146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * |       (size = metadataSize)        |
603146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * |                                    |
604146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * |                                    |
605146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * |------------------------------------|
606146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * |           back padding             |
607146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * |     (size = alignment - offset)    |
608146aed1ec05579b8840a592c3654c641ab36065cZhijun He     * |------------------------------------|<----End address of blob.
609146aed1ec05579b8840a592c3654c641ab36065cZhijun He     *                                            (Blob start address + blob size).
610146aed1ec05579b8840a592c3654c641ab36065cZhijun He     */
611e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    WritableBlob blob;
612e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    do {
613e8df539988b307fa7d2ccd1a80be7553a502ae30Jeff Brown        res = data.writeBlob(blobSize, false, &blob);
614e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        if (res != OK) {
615e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            break;
616e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        }
617146aed1ec05579b8840a592c3654c641ab36065cZhijun He        const uintptr_t metadataStart = ALIGN_TO(blob.data(), alignment);
618146aed1ec05579b8840a592c3654c641ab36065cZhijun He        offset = metadataStart - reinterpret_cast<uintptr_t>(blob.data());
619146aed1ec05579b8840a592c3654c641ab36065cZhijun He        ALOGV("%s: alignment is: %zu, metadata start: %p, offset: %zu",
6201a93f0cbb99fc5a59c92bd913f29409022ae236dMark Salyzyn                __FUNCTION__, alignment,
6211a93f0cbb99fc5a59c92bd913f29409022ae236dMark Salyzyn                reinterpret_cast<const void *>(metadataStart), offset);
622146aed1ec05579b8840a592c3654c641ab36065cZhijun He        copy_camera_metadata(reinterpret_cast<void*>(metadataStart), metadataSize, metadata);
623e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
624e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        // Not too big of a problem since receiving side does hard validation
625e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        // Don't check the size since the compact size could be larger
626e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        if (validate_camera_metadata_structure(metadata, /*size*/NULL) != OK) {
627e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            ALOGW("%s: Failed to validate metadata %p before writing blob",
628e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                   __FUNCTION__, metadata);
629e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        }
630e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
631e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    } while(false);
632e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    blob.release();
633e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
634146aed1ec05579b8840a592c3654c641ab36065cZhijun He    // arg2 = offset (int32)
635146aed1ec05579b8840a592c3654c641ab36065cZhijun He    res = data.writeInt32(static_cast<int32_t>(offset));
636146aed1ec05579b8840a592c3654c641ab36065cZhijun He
637e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    return res;
638e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
639e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
640d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalastatus_t CameraMetadata::readFromParcel(const Parcel *parcel) {
641e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
642e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ALOGV("%s: parcel = %p", __FUNCTION__, parcel);
643e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
644e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    status_t res = OK;
645e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
646e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (parcel == NULL) {
647e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ALOGE("%s: parcel is null", __FUNCTION__);
648e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        return BAD_VALUE;
649e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
650e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
651e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (mLocked) {
652e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
653e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        return INVALID_OPERATION;
654e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
655e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
656e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    camera_metadata *buffer = NULL;
657e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    // TODO: reading should return a status code, in case validation fails
658e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    res = CameraMetadata::readFromParcel(*parcel, &buffer);
659e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
660e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (res != NO_ERROR) {
661e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ALOGE("%s: Failed to read from parcel. Metadata is unchanged.",
662e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin              __FUNCTION__);
663e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        return res;
664e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
665e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
666e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    clear();
667e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    mBuffer = buffer;
668e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
669e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    return OK;
670e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
671e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
672e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinstatus_t CameraMetadata::writeToParcel(Parcel *parcel) const {
673e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
674e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ALOGV("%s: parcel = %p", __FUNCTION__, parcel);
675e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
676e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (parcel == NULL) {
677e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ALOGE("%s: parcel is null", __FUNCTION__);
678e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        return BAD_VALUE;
679e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
680e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
681e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    return CameraMetadata::writeToParcel(*parcel, mBuffer);
682e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
683e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
684e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinvoid CameraMetadata::swap(CameraMetadata& other) {
685e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (mLocked) {
686e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
687e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        return;
688e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    } else if (other.mLocked) {
689e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ALOGE("%s: Other CameraMetadata is locked", __FUNCTION__);
690e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        return;
691e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
692e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
693e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    camera_metadata* thisBuf = mBuffer;
694e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    camera_metadata* otherBuf = other.mBuffer;
695e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
696e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    other.mBuffer = thisBuf;
697e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    mBuffer = otherBuf;
698e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
699e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
7004d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvalastatus_t CameraMetadata::getTagFromName(const char *name,
7014d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala        const VendorTagDescriptor* vTags, uint32_t *tag) {
7024d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala
7034d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala    if (name == nullptr || tag == nullptr) return BAD_VALUE;
7044d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala
7054d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala    size_t nameLength = strlen(name);
7064d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala
7074d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala    const SortedVector<String8> *vendorSections;
7084d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala    size_t vendorSectionCount = 0;
7094d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala
7104d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala    if (vTags != NULL) {
7114d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala        vendorSections = vTags->getAllSectionNames();
7124d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala        vendorSectionCount = vendorSections->size();
7134d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala    }
7144d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala
7154d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala    // First, find the section by the longest string match
7164d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala    const char *section = NULL;
7174d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala    size_t sectionIndex = 0;
7184d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala    size_t sectionLength = 0;
7194d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala    size_t totalSectionCount = ANDROID_SECTION_COUNT + vendorSectionCount;
7204d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala    for (size_t i = 0; i < totalSectionCount; ++i) {
7214d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala
7224d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala        const char *str = (i < ANDROID_SECTION_COUNT) ? camera_metadata_section_names[i] :
7234d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala                (*vendorSections)[i - ANDROID_SECTION_COUNT].string();
7244d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala
7254d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala        ALOGV("%s: Trying to match against section '%s'", __FUNCTION__, str);
7264d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala
7274d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala        if (strstr(name, str) == name) { // name begins with the section name
7284d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala            size_t strLength = strlen(str);
7294d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala
7304d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala            ALOGV("%s: Name begins with section name", __FUNCTION__);
7314d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala
7324d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala            // section name is the longest we've found so far
7334d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala            if (section == NULL || sectionLength < strLength) {
7344d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala                section = str;
7354d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala                sectionIndex = i;
7364d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala                sectionLength = strLength;
7374d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala
7384d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala                ALOGV("%s: Found new best section (%s)", __FUNCTION__, section);
7394d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala            }
7404d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala        }
7414d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala    }
7424d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala
7434d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala    // TODO: Make above get_camera_metadata_section_from_name ?
7444d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala
7454d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala    if (section == NULL) {
7464d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala        return NAME_NOT_FOUND;
7474d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala    } else {
7484d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala        ALOGV("%s: Found matched section '%s' (%zu)",
7494d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala              __FUNCTION__, section, sectionIndex);
7504d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala    }
7514d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala
7524d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala    // Get the tag name component of the name
7534d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala    const char *nameTagName = name + sectionLength + 1; // x.y.z -> z
7544d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala    if (sectionLength + 1 >= nameLength) {
7554d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala        return BAD_VALUE;
7564d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala    }
7574d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala
7584d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala    // Match rest of name against the tag names in that section only
7594d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala    uint32_t candidateTag = 0;
7604d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala    if (sectionIndex < ANDROID_SECTION_COUNT) {
7614d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala        // Match built-in tags (typically android.*)
7624d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala        uint32_t tagBegin, tagEnd; // [tagBegin, tagEnd)
7634d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala        tagBegin = camera_metadata_section_bounds[sectionIndex][0];
7644d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala        tagEnd = camera_metadata_section_bounds[sectionIndex][1];
7654d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala
7664d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala        for (candidateTag = tagBegin; candidateTag < tagEnd; ++candidateTag) {
7674d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala            const char *tagName = get_camera_metadata_tag_name(candidateTag);
7684d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala
7694d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala            if (strcmp(nameTagName, tagName) == 0) {
7704d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala                ALOGV("%s: Found matched tag '%s' (%d)",
7714d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala                      __FUNCTION__, tagName, candidateTag);
7724d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala                break;
7734d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala            }
7744d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala        }
7754d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala
7764d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala        if (candidateTag == tagEnd) {
7774d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala            return NAME_NOT_FOUND;
7784d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala        }
7794d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala    } else if (vTags != NULL) {
7804d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala        // Match vendor tags (typically com.*)
7814d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala        const String8 sectionName(section);
7824d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala        const String8 tagName(nameTagName);
7834d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala
7844d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala        status_t res = OK;
7854d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala        if ((res = vTags->lookupTag(tagName, sectionName, &candidateTag)) != OK) {
7864d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala            return NAME_NOT_FOUND;
7874d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala        }
7884d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala    }
7894d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala
7904d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala    *tag = candidateTag;
7914d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala    return OK;
7924d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala}
7934d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala
7944d453830b6a8fb7571a88a9a241eabd50a483c44Eino-Ville Talvala
795cab96a4a7a2900fa991ab77ae45ba8d4be97e054Eino-Ville Talvala}; // namespace android
796